diff --git a/AutomatedTesting/AssetProcessorGamePlatformConfig.setreg b/AutomatedTesting/AssetProcessorGamePlatformConfig.setreg new file mode 100644 index 0000000000..5457b3f1ca --- /dev/null +++ b/AutomatedTesting/AssetProcessorGamePlatformConfig.setreg @@ -0,0 +1,19 @@ +{ + "Amazon": { + "AssetProcessor": { + "Settings": { + "RC cgf": { + "ignore": true + }, + "RC fbx": { + "ignore": true + }, + "ScanFolder AtomTestData": { + "watch": "@ENGINEROOT@/Gems/Atom/TestData", + "recursive": 1, + "order": 1000 + } + } + } + } +} diff --git a/AutomatedTesting/Gem/Code/CMakeLists.txt b/AutomatedTesting/Gem/Code/CMakeLists.txt index 76c0db3f5c..58ffd957d6 100644 --- a/AutomatedTesting/Gem/Code/CMakeLists.txt +++ b/AutomatedTesting/Gem/Code/CMakeLists.txt @@ -57,6 +57,12 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) TARGETS Editor VARIANTS Tools) + # The Material Editor needs the Lyshine "Tools" gem variant for the custom LyShine pass + ly_enable_gems( + PROJECT_NAME AutomatedTesting GEMS LyShine + TARGETS MaterialEditor + VARIANTS Tools) + # The pipeline tools use "Builders" gem variants: ly_enable_gems( PROJECT_NAME AutomatedTesting GEM_FILE enabled_gems.cmake diff --git a/AutomatedTesting/Gem/PythonTests/Blast/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/Blast/CMakeLists.txt index 7048a6bd46..172eded09a 100644 --- a/AutomatedTesting/Gem/PythonTests/Blast/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/Blast/CMakeLists.txt @@ -12,7 +12,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) TEST_SUITE main TEST_SERIAL TRUE PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Active.py - TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor AZ::AssetProcessor diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_editor_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_editor_utils.py index cec1b6456b..985e32ede5 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_editor_utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_editor_utils.py @@ -8,6 +8,7 @@ SPDX-License-Identifier: Apache-2.0 OR MIT import azlmbr.bus as bus import azlmbr.editor as editor import azlmbr.entity as entity +import azlmbr.legacy.general as general import azlmbr.object from typing import List @@ -428,3 +429,32 @@ def get_component_type_id_map(component_name_list): type_ids_by_component[component_names[i]] = typeId return type_ids_by_component + + +def attach_component_to_entity(entity_id, component_name): + # type: (azlmbr.entity.EntityId, str) -> azlmbr.entity.EntityComponentIdPair + """ + Adds the component if not added already. + :param entity_id: EntityId of the entity to attach the component to + :param component_name: name of the component + :return: If successful, returns the EntityComponentIdPair, otherwise returns None. + """ + type_ids_list = editor.EditorComponentAPIBus( + bus.Broadcast, 'FindComponentTypeIdsByEntityType', [component_name], 0) + general.log(f"Components found = {len(type_ids_list)}") + if len(type_ids_list) < 1: + general.log(f"ERROR: A component class with name {component_name} doesn't exist") + return None + elif len(type_ids_list) > 1: + general.log(f"ERROR: Found more than one component classes with same name: {component_name}") + return None + # Before adding the component let's check if it is already attached to the entity. + component_outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', entity_id, type_ids_list[0]) + if component_outcome.IsSuccess(): + return component_outcome.GetValue() # In this case the value is not a list. + component_outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', entity_id, type_ids_list) + if component_outcome.IsSuccess(): + general.log(f"{component_name} Component added to entity.") + return component_outcome.GetValue()[0] + general.log(f"ERROR: Failed to add component [{component_name}] to entity") + return None diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_test_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_test_utils.py index 3004b9ec7d..3d4d9ea419 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_test_utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_test_utils.py @@ -29,7 +29,7 @@ def teardown_editor(editor): def launch_and_validate_results(request, test_directory, editor, editor_script, expected_lines, unexpected_lines=[], halt_on_unexpected=False, run_python="--runpythontest", auto_test_mode=True, null_renderer=True, cfg_args=[], - timeout=300): + timeout=300, log_file_name="Editor.log"): """ Runs the Editor with the specified script, and monitors for expected log lines. :param request: Special fixture providing information of the requesting test function. @@ -44,6 +44,7 @@ def launch_and_validate_results(request, test_directory, editor, editor_script, :param null_renderer: Specifies the test does not require the renderer. Defaults to True. :param cfg_args: Additional arguments for CFG, such as LevelName. :param timeout: Length of time for test to run. Default is 60. + :param log_file_name: Name of the log file created by the editor. Defaults to 'Editor.log' """ test_case = os.path.join(test_directory, editor_script) request.addfinalizer(lambda: teardown_editor(editor)) @@ -58,7 +59,17 @@ def launch_and_validate_results(request, test_directory, editor, editor_script, with editor.start(): - editorlog_file = os.path.join(editor.workspace.paths.project_log(), 'Editor.log') + editorlog_file = os.path.join(editor.workspace.paths.project_log(), log_file_name) + + # Log monitor requires the file to exist. + logger.debug(f"Waiting until log file <{editorlog_file}> exists...") + waiter.wait_for( + lambda: os.path.exists(editorlog_file), + timeout=60, + exc=f"Log file '{editorlog_file}' was never created by another process.", + interval=1, + ) + logger.debug(f"Done! log file <{editorlog_file}> exists.") # Initialize the log monitor and set time to wait for log creation log_monitor = ly_test_tools.log.log_monitor.LogMonitor(launcher=editor, log_file_path=editorlog_file) diff --git a/AutomatedTesting/Gem/PythonTests/NvCloth/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/NvCloth/CMakeLists.txt index a39cdf04cf..3913041f88 100644 --- a/AutomatedTesting/Gem/PythonTests/NvCloth/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/NvCloth/CMakeLists.txt @@ -13,7 +13,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) TEST_REQUIRES gpu TEST_SERIAL PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Active.py - TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor AZ::AssetProcessor diff --git a/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/CMakeLists.txt index 9b6542b3e3..905470e08f 100644 --- a/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/CMakeLists.txt @@ -12,7 +12,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) TEST_SUITE periodic TEST_SERIAL PATH ${CMAKE_CURRENT_LIST_DIR} - TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor AZ::AssetProcessor diff --git a/AutomatedTesting/Gem/PythonTests/WhiteBox/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/WhiteBox/CMakeLists.txt index b5fcfcc44c..1c7a02862d 100644 --- a/AutomatedTesting/Gem/PythonTests/WhiteBox/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/WhiteBox/CMakeLists.txt @@ -12,7 +12,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) TEST_SUITE main TEST_SERIAL PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Active.py - TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor AZ::AssetProcessor diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt index 0170d73af0..3d7a9204e2 100644 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt @@ -92,17 +92,17 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) AZ::AssetProcessor ) - ly_add_pytest( - NAME AssetPipelineTests.AssetBundler - PATH ${CMAKE_CURRENT_LIST_DIR}/asset_bundler_batch_tests.py - EXCLUDE_TEST_RUN_TARGET_FROM_IDE - TEST_SERIAL - TIMEOUT 2400 - TEST_SUITE periodic - RUNTIME_DEPENDENCIES - AZ::AssetProcessor - AZ::AssetBundlerBatch - ) + # Issue #3017 + #ly_add_pytest( + # NAME AssetPipelineTests.AssetBundler + # PATH ${CMAKE_CURRENT_LIST_DIR}/asset_bundler_batch_tests.py + # EXCLUDE_TEST_RUN_TARGET_FROM_IDE + # TEST_SERIAL + # TEST_SUITE periodic + # RUNTIME_DEPENDENCIES + # AZ::AssetProcessor + # AZ::AssetBundlerBatch + #) ly_add_pytest( NAME AssetPipelineTests.AssetBundler_SandBox @@ -111,7 +111,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) PYTEST_MARKS "SUITE_sandbox" # run only sandbox tests in this file EXCLUDE_TEST_RUN_TARGET_FROM_IDE TEST_SERIAL - TIMEOUT 1500 RUNTIME_DEPENDENCIES AZ::AssetProcessor AZ::AssetBundlerBatch @@ -133,7 +132,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) PATH ${CMAKE_CURRENT_LIST_DIR}/missing_dependency_tests.py EXCLUDE_TEST_RUN_TARGET_FROM_IDE TEST_SERIAL - TIMEOUT 1500 TEST_SUITE periodic RUNTIME_DEPENDENCIES AZ::AssetProcessorBatch diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/atom_renderer/CMakeLists.txt index d4f036faeb..f056623ecd 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/CMakeLists.txt @@ -39,7 +39,7 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_BUILD_TESTS_SUPPORTED AND AutomatedT TEST_SUITE main TEST_REQUIRES gpu TEST_SERIAL - TIMEOUT 800 + TIMEOUT 1200 PATH ${CMAKE_CURRENT_LIST_DIR}/test_Atom_GPUTests.py RUNTIME_DEPENDENCIES AssetProcessor diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_LightComponent.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_LightComponent.py index ec8dc199ae..24866f3b19 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_LightComponent.py +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_LightComponent.py @@ -19,7 +19,7 @@ import azlmbr.legacy.general as general sys.path.append(os.path.join(azlmbr.paths.devassets, "Gem", "PythonTests")) import editor_python_test_tools.hydra_editor_utils as hydra -from atom_renderer.atom_utils.atom_component_helper import LIGHT_TYPES +from atom_renderer.atom_utils.atom_constants import LIGHT_TYPES LIGHT_TYPE_PROPERTY = 'Controller|Configuration|Light type' SPHERE_AND_SPOT_DISK_LIGHT_PROPERTIES = [ diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomMaterialEditor_BasicTests.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomMaterialEditor_BasicTests.py new file mode 100644 index 0000000000..b3c51ca912 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomMaterialEditor_BasicTests.py @@ -0,0 +1,183 @@ +""" +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 + +import azlmbr.materialeditor will fail with a ModuleNotFound error when using this script with Editor.exe +This is because azlmbr.materialeditor only binds to MaterialEditor.exe and not Editor.exe +You need to launch this script with MaterialEditor.exe in order for azlmbr.materialeditor to appear. +""" + +import os +import sys +import time + +import azlmbr.math as math +import azlmbr.paths + +sys.path.append(os.path.join(azlmbr.paths.devassets, "Gem", "PythonTests")) + +import atom_renderer.atom_utils.material_editor_utils as material_editor + +NEW_MATERIAL = "test_material.material" +NEW_MATERIAL_1 = "test_material_1.material" +NEW_MATERIAL_2 = "test_material_2.material" +TEST_MATERIAL_1 = "001_DefaultWhite.material" +TEST_MATERIAL_2 = "002_BaseColorLerp.material" +TEST_MATERIAL_3 = "003_MetalMatte.material" +TEST_DATA_PATH = os.path.join( + azlmbr.paths.devroot, "Gems", "Atom", "TestData", "TestData", "Materials", "StandardPbrTestCases" +) +MATERIAL_TYPE_PATH = os.path.join( + azlmbr.paths.devroot, "Gems", "Atom", "Feature", "Common", "Assets", + "Materials", "Types", "StandardPBR.materialtype", +) + + +def run(): + """ + Summary: + Material Editor basic tests including the below + 1. Opening an Existing Asset + 2. Creating a New Asset + 3. Closing Selected Material + 4. Closing All Materials + 5. Closing all but Selected Material + 6. Saving Material + 7. Saving as a New Material + 8. Saving as a Child Material + 9. Saving all Open Materials + + Expected Result: + All the above functions work as expected in Material Editor. + + :return: None + """ + + # 1) Test Case: Opening an Existing Asset + document_id = material_editor.open_material(MATERIAL_TYPE_PATH) + print(f"Material opened: {material_editor.is_open(document_id)}") + + # Verify if the test material exists initially + target_path = os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Materials", NEW_MATERIAL) + print(f"Test asset doesn't exist initially: {not os.path.exists(target_path)}") + + # 2) Test Case: Creating a New Material Using Existing One + material_editor.save_document_as_child(document_id, target_path) + material_editor.wait_for_condition(lambda: os.path.exists(target_path), 2.0) + print(f"New asset created: {os.path.exists(target_path)}") + + # Verify if the newly created document is open + new_document_id = material_editor.open_material(target_path) + material_editor.wait_for_condition(lambda: material_editor.is_open(new_document_id)) + print(f"New Material opened: {material_editor.is_open(new_document_id)}") + + # 3) Test Case: Closing Selected Material + print(f"Material closed: {material_editor.close_document(new_document_id)}") + + # Open materials initially + document1_id, document2_id, document3_id = ( + material_editor.open_material(os.path.join(TEST_DATA_PATH, material)) + for material in [TEST_MATERIAL_1, TEST_MATERIAL_2, TEST_MATERIAL_3] + ) + + # 4) Test Case: Closing All Materials + print(f"All documents closed: {material_editor.close_all_documents()}") + + # 5) Test Case: Closing all but Selected Material + document1_id, document2_id, document3_id = ( + material_editor.open_material(os.path.join(TEST_DATA_PATH, material)) + for material in [TEST_MATERIAL_1, TEST_MATERIAL_2, TEST_MATERIAL_3] + ) + result = material_editor.close_all_except_selected(document1_id) + print(f"Close All Except Selected worked as expected: {result and material_editor.is_open(document1_id)}") + + # 6) Test Case: Saving Material + document_id = material_editor.open_material(os.path.join(TEST_DATA_PATH, TEST_MATERIAL_1)) + property_name = azlmbr.name.Name("baseColor.color") + initial_color = material_editor.get_property(document_id, property_name) + # Assign new color to the material file and save the actual material + expected_color = math.Color(0.25, 0.25, 0.25, 1.0) + material_editor.set_property(document_id, property_name, expected_color) + material_editor.save_document(document_id) + + # 7) Test Case: Saving as a New Material + # Assign new color to the material file and save the document as copy + expected_color_1 = math.Color(0.5, 0.5, 0.5, 1.0) + material_editor.set_property(document_id, property_name, expected_color_1) + target_path_1 = os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Materials", NEW_MATERIAL_1) + material_editor.save_document_as_copy(document_id, target_path_1) + time.sleep(2.0) + + # 8) Test Case: Saving as a Child Material + # Assign new color to the material file save the document as child + expected_color_2 = math.Color(0.75, 0.75, 0.75, 1.0) + material_editor.set_property(document_id, property_name, expected_color_2) + target_path_2 = os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Materials", NEW_MATERIAL_2) + material_editor.save_document_as_child(document_id, target_path_2) + time.sleep(2.0) + + # Close/Reopen documents + material_editor.close_all_documents() + document_id = material_editor.open_material(os.path.join(TEST_DATA_PATH, TEST_MATERIAL_1)) + document1_id = material_editor.open_material(target_path_1) + document2_id = material_editor.open_material(target_path_2) + + # Verify if the changes are saved in the actual document + actual_color = material_editor.get_property(document_id, property_name) + print(f"Actual Document saved with changes: {material_editor.compare_colors(actual_color, expected_color)}") + + # Verify if the changes are saved in the document saved as copy + actual_color = material_editor.get_property(document1_id, property_name) + result_copy = material_editor.compare_colors(actual_color, expected_color_1) + print(f"Document saved as copy is saved with changes: {result_copy}") + + # Verify if the changes are saved in the document saved as child + actual_color = material_editor.get_property(document2_id, property_name) + result_child = material_editor.compare_colors(actual_color, expected_color_2) + print(f"Document saved as child is saved with changes: {result_child}") + + # Revert back the changes in the actual document + material_editor.set_property(document_id, property_name, initial_color) + material_editor.save_document(document_id) + material_editor.close_all_documents() + + # 9) Test Case: Saving all Open Materials + # Open first material and make change to the values + document1_id = material_editor.open_material(os.path.join(TEST_DATA_PATH, TEST_MATERIAL_1)) + property1_name = azlmbr.name.Name("metallic.factor") + initial_metallic_factor = material_editor.get_property(document1_id, property1_name) + expected_metallic_factor = 0.444 + material_editor.set_property(document1_id, property1_name, expected_metallic_factor) + + # Open second material and make change to the values + document2_id = material_editor.open_material(os.path.join(TEST_DATA_PATH, TEST_MATERIAL_2)) + property2_name = azlmbr.name.Name("baseColor.color") + initial_color = material_editor.get_property(document2_id, property2_name) + expected_color = math.Color(0.4156, 0.0196, 0.6862, 1.0) + material_editor.set_property(document2_id, property2_name, expected_color) + + # Save all and close all documents + material_editor.save_all() + material_editor.close_all_documents() + + # Reopen materials and verify values + document1_id = material_editor.open_material(os.path.join(TEST_DATA_PATH, TEST_MATERIAL_1)) + result = material_editor.is_close( + material_editor.get_property(document1_id, property1_name), expected_metallic_factor, 0.00001 + ) + document2_id = material_editor.open_material(os.path.join(TEST_DATA_PATH, TEST_MATERIAL_2)) + result = result and material_editor.compare_colors( + expected_color, material_editor.get_property(document2_id, property2_name)) + print(f"Save All worked as expected: {result}") + + # Revert the changes made + material_editor.set_property(document1_id, property1_name, initial_metallic_factor) + material_editor.set_property(document2_id, property2_name, initial_color) + material_editor.save_all() + material_editor.close_all_documents() + + +if __name__ == "__main__": + run() diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_GPUTest_LightComponent.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_GPUTest_LightComponent.py new file mode 100644 index 0000000000..08f921e68b --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_GPUTest_LightComponent.py @@ -0,0 +1,268 @@ +""" +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 + +Hydra script that is used to create an entity with a Light component attached. +It then updates the property values of the Light component and takes a screenshot. +The screenshot is compared against an expected golden image for test verification. + +See the run() function for more in-depth test info. +""" +import os +import sys + +import azlmbr.asset as asset +import azlmbr.bus as bus +import azlmbr.editor as editor +import azlmbr.math as math +import azlmbr.paths +import azlmbr.legacy.general as general + +sys.path.append(os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Gem", "PythonTests")) + +import editor_python_test_tools.hydra_editor_utils as hydra +from atom_renderer.atom_utils import screenshot_utils +from atom_renderer.atom_utils import atom_component_helper +from editor_python_test_tools.editor_test_helper import EditorTestHelper + +helper = EditorTestHelper(log_prefix="Atom_EditorTestHelper") + +LEVEL_NAME = "auto_test" +LIGHT_COMPONENT = "Light" +LIGHT_TYPE_PROPERTY = 'Controller|Configuration|Light type' +DEGREE_RADIAN_FACTOR = 0.0174533 + + +def run(): + """ + Sets up the tests by making sure the required level is created & setup correctly. + It then executes 2 test cases - see each associated test function's docstring for more info. + + Finally prints the string "Light component tests completed" after completion + + Tests will fail immediately if any of these log lines are found: + 1. Trace::Assert + 2. Trace::Error + 3. Traceback (most recent call last): + + :return: None + """ + atom_component_helper.create_basic_atom_level(level_name=LEVEL_NAME) + + # Run tests. + area_light_test() + spot_light_test() + general.log("Light component tests completed.") + + +def area_light_test(): + """ + Basic test for the "Light" component attached to an "area_light" entity. + + Test Case - Light Component: Capsule, Spot (disk), and Point (sphere): + 1. Creates "area_light" entity w/ a Light component that has a Capsule Light type w/ the color set to 255, 0, 0 + 2. Enters game mode to take a screenshot for comparison, then exits game mode. + 3. Sets the Light component Intensity Mode to Lumens (default). + 4. Ensures the Light component Mode is Automatic (default). + 5. Sets the Intensity value of the Light component to 0.0 + 6. Enters game mode again, takes another screenshot for comparison, then exits game mode. + 7. Updates the Intensity value of the Light component to 1000.0 + 8. Enters game mode again, takes another screenshot for comparison, then exits game mode. + 9. Swaps the Capsule light type option to Spot (disk) light type on the Light component + 10. Updates "area_light" entity Transform rotate value to x: 90.0, y:0.0, z:0.0 + 11. Enters game mode again, takes another screenshot for comparison, then exits game mode. + 12. Swaps the Spot (disk) light type for the Point (sphere) light type in the Light component. + 13. Enters game mode again, takes another screenshot for comparison, then exits game mode. + 14. Deletes the Light component from the "area_light" entity and verifies its successful. + """ + # Create an "area_light" entity with "Light" component using Light type of "Capsule" + area_light_entity_name = "area_light" + area_light = hydra.Entity(area_light_entity_name) + area_light.create_entity(math.Vector3(-1.0, -2.0, 3.0), [LIGHT_COMPONENT]) + general.log( + f"{area_light_entity_name}_test: Component added to the entity: " + f"{hydra.has_components(area_light.id, [LIGHT_COMPONENT])}") + light_component_id_pair = hydra.attach_component_to_entity(area_light.id, LIGHT_COMPONENT) + + # Select the "Capsule" light type option. + azlmbr.editor.EditorComponentAPIBus( + azlmbr.bus.Broadcast, + 'SetComponentProperty', + light_component_id_pair, + LIGHT_TYPE_PROPERTY, + atom_component_helper.LIGHT_TYPES['capsule'] + ) + + # Update color and take screenshot in game mode + color = math.Color(255.0, 0.0, 0.0, 0.0) + area_light.get_set_test(0, "Controller|Configuration|Color", color) + general.idle_wait(1.0) + screenshot_utils.take_screenshot_game_mode("AreaLight_1", area_light_entity_name) + + # Update intensity value to 0.0 and take screenshot in game mode + area_light.get_set_test(0, "Controller|Configuration|Attenuation Radius|Mode", 1) + area_light.get_set_test(0, "Controller|Configuration|Intensity", 0.0) + general.idle_wait(1.0) + screenshot_utils.take_screenshot_game_mode("AreaLight_2", area_light_entity_name) + + # Update intensity value to 1000.0 and take screenshot in game mode + area_light.get_set_test(0, "Controller|Configuration|Intensity", 1000.0) + general.idle_wait(1.0) + screenshot_utils.take_screenshot_game_mode("AreaLight_3", area_light_entity_name) + + # Swap the "Capsule" light type option to "Spot (disk)" light type + azlmbr.editor.EditorComponentAPIBus( + azlmbr.bus.Broadcast, + 'SetComponentProperty', + light_component_id_pair, + LIGHT_TYPE_PROPERTY, + atom_component_helper.LIGHT_TYPES['spot_disk'] + ) + area_light_rotation = math.Vector3(DEGREE_RADIAN_FACTOR * 90.0, 0.0, 0.0) + azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", area_light.id, area_light_rotation) + general.idle_wait(1.0) + screenshot_utils.take_screenshot_game_mode("AreaLight_4", area_light_entity_name) + + # Swap the "Spot (disk)" light type to the "Point (sphere)" light type and take screenshot. + azlmbr.editor.EditorComponentAPIBus( + azlmbr.bus.Broadcast, + 'SetComponentProperty', + light_component_id_pair, + LIGHT_TYPE_PROPERTY, + atom_component_helper.LIGHT_TYPES['sphere'] + ) + general.idle_wait(1.0) + screenshot_utils.take_screenshot_game_mode("AreaLight_5", area_light_entity_name) + + editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntityById", area_light.id) + + +def spot_light_test(): + """ + Basic test for the Light component attached to a "spot_light" entity. + + Test Case - Light Component: Spot (disk) with shadows & colors: + 1. Creates "spot_light" entity w/ a Light component attached to it. + 2. Selects the "directional_light" entity already present in the level and disables it. + 3. Selects the "global_skylight" entity already present in the level and disables the HDRi Skybox component, + as well as the Global Skylight (IBL) component. + 4. Enters game mode to take a screenshot for comparison, then exits game mode. + 5. Selects the "ground_plane" entity and changes updates the material to a new material. + 6. Enters game mode to take a screenshot for comparison, then exits game mode. + 7. Selects the "spot_light" entity and increases the Light component Intensity to 800 lm + 8. Enters game mode to take a screenshot for comparison, then exits game mode. + 9. Selects the "spot_light" entity and sets the Light component Color to 47, 75, 37 + 10. Enters game mode to take a screenshot for comparison, then exits game mode. + 11. Selects the "spot_light" entity and modifies the Shutter controls to the following values: + - Enable shutters: True + - Inner Angle: 60.0 + - Outer Angle: 75.0 + 12. Enters game mode to take a screenshot for comparison, then exits game mode. + 13. Selects the "spot_light" entity and modifies the Shadow controls to the following values: + - Enable Shadow: True + - ShadowmapSize: 256 + 14. Modifies the world translate position of the "spot_light" entity to 0.7, -2.0, 1.9 (for casting shadows better) + 15. Enters game mode to take a screenshot for comparison, then exits game mode. + """ + # Disable "Directional Light" component for the "directional_light" entity + # "directional_light" entity is created by the create_basic_atom_level() function by default. + directional_light_entity_id = hydra.find_entity_by_name("directional_light") + directional_light = hydra.Entity(name='directional_light', id=directional_light_entity_id) + directional_light_component_type = azlmbr.editor.EditorComponentAPIBus( + azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["Directional Light"], 0)[0] + directional_light_component = azlmbr.editor.EditorComponentAPIBus( + azlmbr.bus.Broadcast, 'GetComponentOfType', directional_light.id, directional_light_component_type + ).GetValue() + editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [directional_light_component]) + general.idle_wait(0.5) + + # Disable "Global Skylight (IBL)" and "HDRi Skybox" components for the "global_skylight" entity + global_skylight_entity_id = hydra.find_entity_by_name("global_skylight") + global_skylight = hydra.Entity(name='global_skylight', id=global_skylight_entity_id) + global_skylight_component_type = azlmbr.editor.EditorComponentAPIBus( + azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["Global Skylight (IBL)"], 0)[0] + global_skylight_component = azlmbr.editor.EditorComponentAPIBus( + azlmbr.bus.Broadcast, 'GetComponentOfType', global_skylight.id, global_skylight_component_type + ).GetValue() + editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [global_skylight_component]) + hdri_skybox_component_type = azlmbr.editor.EditorComponentAPIBus( + azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["HDRi Skybox"], 0)[0] + hdri_skybox_component = azlmbr.editor.EditorComponentAPIBus( + azlmbr.bus.Broadcast, 'GetComponentOfType', global_skylight.id, hdri_skybox_component_type + ).GetValue() + editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [hdri_skybox_component]) + general.idle_wait(0.5) + + # Create a "spot_light" entity with "Light" component using Light Type of "Spot (disk)" + spot_light_entity_name = "spot_light" + spot_light = hydra.Entity(spot_light_entity_name) + spot_light.create_entity(math.Vector3(0.7, -2.0, 1.0), [LIGHT_COMPONENT]) + general.log( + f"{spot_light_entity_name}_test: Component added to the entity: " + f"{hydra.has_components(spot_light.id, [LIGHT_COMPONENT])}") + rotation = math.Vector3(DEGREE_RADIAN_FACTOR * 300.0, 0.0, 0.0) + azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", spot_light.id, rotation) + light_component_type = hydra.attach_component_to_entity(spot_light.id, LIGHT_COMPONENT) + editor.EditorComponentAPIBus( + azlmbr.bus.Broadcast, + 'SetComponentProperty', + light_component_type, + LIGHT_TYPE_PROPERTY, + atom_component_helper.LIGHT_TYPES['spot_disk'] + ) + + general.idle_wait(1.0) + screenshot_utils.take_screenshot_game_mode("SpotLight_1", spot_light_entity_name) + + # Change default material of ground plane entity and take screenshot + ground_plane_entity_id = hydra.find_entity_by_name("ground_plane") + ground_plane = hydra.Entity(name='ground_plane', id=ground_plane_entity_id) + ground_plane_asset_path = os.path.join("Materials", "Presets", "MacBeth", "22_neutral_5-0_0-70d.azmaterial") + ground_plane_asset_value = asset.AssetCatalogRequestBus( + bus.Broadcast, "GetAssetIdByPath", ground_plane_asset_path, math.Uuid(), False) + material_property_path = "Default Material|Material Asset" + material_component_type = azlmbr.editor.EditorComponentAPIBus( + azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["Material"], 0)[0] + material_component = azlmbr.editor.EditorComponentAPIBus( + azlmbr.bus.Broadcast, 'GetComponentOfType', ground_plane.id, material_component_type).GetValue() + editor.EditorComponentAPIBus( + azlmbr.bus.Broadcast, + 'SetComponentProperty', + material_component, + material_property_path, + ground_plane_asset_value + ) + general.idle_wait(1.0) + screenshot_utils.take_screenshot_game_mode("SpotLight_2", spot_light_entity_name) + + # Increase intensity value of the Spot light and take screenshot in game mode + spot_light.get_set_test(0, "Controller|Configuration|Intensity", 800.0) + general.idle_wait(1.0) + screenshot_utils.take_screenshot_game_mode("SpotLight_3", spot_light_entity_name) + + # Update the Spot light color and take screenshot in game mode + color_value = math.Color(47.0 / 255.0, 75.0 / 255.0, 37.0 / 255.0, 255.0 / 255.0) + spot_light.get_set_test(0, "Controller|Configuration|Color", color_value) + general.idle_wait(1.0) + screenshot_utils.take_screenshot_game_mode("SpotLight_4", spot_light_entity_name) + + # Update the Shutter controls of the Light component and take screenshot + spot_light.get_set_test(0, "Controller|Configuration|Shutters|Enable shutters", True) + spot_light.get_set_test(0, "Controller|Configuration|Shutters|Inner angle", 60.0) + spot_light.get_set_test(0, "Controller|Configuration|Shutters|Outer angle", 75.0) + general.idle_wait(1.0) + screenshot_utils.take_screenshot_game_mode("SpotLight_5", spot_light_entity_name) + + # Update the Shadow controls, move the spot_light entity world translate position and take screenshot + spot_light.get_set_test(0, "Controller|Configuration|Shadows|Enable shadow", True) + spot_light.get_set_test(0, "Controller|Configuration|Shadows|Shadowmap size", 256.0) + azlmbr.components.TransformBus( + azlmbr.bus.Event, "SetWorldTranslation", spot_light.id, math.Vector3(0.7, -2.0, 1.9)) + general.idle_wait(1.0) + screenshot_utils.take_screenshot_game_mode("SpotLight_6", spot_light_entity_name) + + +if __name__ == "__main__": + run() diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_utils/atom_component_helper.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_utils/atom_component_helper.py index de4e28bb36..58b72ef01a 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_utils/atom_component_helper.py +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_utils/atom_component_helper.py @@ -3,17 +3,184 @@ Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright SPDX-License-Identifier: Apache-2.0 OR MIT -File to assist with common hydra component functions or constants used across various Atom tests. +File to assist with common hydra component functions used across various Atom tests. """ +import os -# Light type options for the Light component. -LIGHT_TYPES = { - 'unknown': 0, - 'sphere': 1, - 'spot_disk': 2, - 'capsule': 3, - 'quad': 4, - 'polygon': 5, - 'simple_point': 6, - 'simple_spot': 7, -} +from editor_python_test_tools.editor_test_helper import EditorTestHelper + +helper = EditorTestHelper(log_prefix="Atom_EditorTestHelper") + + +def create_basic_atom_level(level_name): + """ + Creates a new level inside the Editor matching level_name & adds the following: + 1. "default_level" entity to hold all other entities. + 2. Adds Grid, Global Skylight (IBL), ground Mesh, Directional Light, Sphere w/ material+mesh, & Camera components. + 3. Each of these components has its settings tweaked slightly to match the ideal scene to test Atom rendering. + :param level_name: name of the level to create and apply this basic setup to. + :return: None + """ + import azlmbr.asset as asset + import azlmbr.bus as bus + import azlmbr.camera as camera + import azlmbr.editor as editor + import azlmbr.entity as entity + import azlmbr.legacy.general as general + import azlmbr.math as math + import azlmbr.object + + import editor_python_test_tools.hydra_editor_utils as hydra + + # Create a new level. + new_level_name = level_name + heightmap_resolution = 512 + heightmap_meters_per_pixel = 1 + terrain_texture_resolution = 412 + use_terrain = False + + # Return codes are ECreateLevelResult defined in CryEdit.h + return_code = general.create_level_no_prompt( + new_level_name, heightmap_resolution, heightmap_meters_per_pixel, terrain_texture_resolution, use_terrain) + if return_code == 1: + general.log(f"{new_level_name} level already exists") + elif return_code == 2: + general.log("Failed to create directory") + elif return_code == 3: + general.log("Directory length is too long") + elif return_code != 0: + general.log("Unknown error, failed to create level") + else: + general.log(f"{new_level_name} level created successfully") + + # Enable idle and update viewport. + general.idle_enable(True) + general.idle_wait(1.0) + general.update_viewport() + general.idle_wait(0.5) # half a second is more than enough for updating the viewport. + + # Close out problematic windows, FPS meters, and anti-aliasing. + if general.is_helpers_shown(): # Turn off the helper gizmos if visible + general.toggle_helpers() + general.idle_wait(1.0) + if general.is_pane_visible("Error Report"): # Close Error Report windows that block focus. + general.close_pane("Error Report") + if general.is_pane_visible("Error Log"): # Close Error Log windows that block focus. + general.close_pane("Error Log") + general.idle_wait(1.0) + general.run_console("r_displayInfo=0") + general.run_console("r_antialiasingmode=0") + general.idle_wait(1.0) + + # Delete all existing entities & create default_level entity + search_filter = azlmbr.entity.SearchFilter() + all_entities = entity.SearchBus(azlmbr.bus.Broadcast, "SearchEntities", search_filter) + editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntities", all_entities) + default_level = hydra.Entity("default_level") + default_position = math.Vector3(0.0, 0.0, 0.0) + default_level.create_entity(default_position, ["Grid"]) + default_level.get_set_test(0, "Controller|Configuration|Secondary Grid Spacing", 1.0) + + # Set the viewport up correctly after adding the parent default_level entity. + screen_width = 1280 + screen_height = 720 + degree_radian_factor = 0.0174533 # Used by "Rotation" property for the Transform component. + general.set_viewport_size(screen_width, screen_height) + general.update_viewport() + helper.wait_for_condition( + function=lambda: helper.isclose(a=general.get_viewport_size().x, b=screen_width, rel_tol=0.1) + and helper.isclose(a=general.get_viewport_size().y, b=screen_height, rel_tol=0.1), + timeout_in_seconds=4.0 + ) + result = helper.isclose(a=general.get_viewport_size().x, b=screen_width, rel_tol=0.1) and helper.isclose( + a=general.get_viewport_size().y, b=screen_height, rel_tol=0.1) + general.log(general.get_viewport_size().x) + general.log(general.get_viewport_size().y) + general.log(general.get_viewport_size().z) + general.log(f"Viewport is set to the expected size: {result}") + general.log("Basic level created") + general.run_console("r_DisplayInfo = 0") + + # Create global_skylight entity and set the properties + global_skylight = hydra.Entity("global_skylight") + global_skylight.create_entity( + entity_position=default_position, + components=["HDRi Skybox", "Global Skylight (IBL)"], + parent_id=default_level.id) + global_skylight_asset_path = os.path.join( + "LightingPresets", "greenwich_park_02_4k_iblskyboxcm_iblspecular.exr.streamingimage") + global_skylight_asset_value = asset.AssetCatalogRequestBus( + bus.Broadcast, "GetAssetIdByPath", global_skylight_asset_path, math.Uuid(), False) + global_skylight.get_set_test(0, "Controller|Configuration|Cubemap Texture", global_skylight_asset_value) + global_skylight.get_set_test(1, "Controller|Configuration|Diffuse Image", global_skylight_asset_value) + global_skylight.get_set_test(1, "Controller|Configuration|Specular Image", global_skylight_asset_value) + + # Create ground_plane entity and set the properties + ground_plane = hydra.Entity("ground_plane") + ground_plane.create_entity( + entity_position=default_position, + components=["Material"], + parent_id=default_level.id) + azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalUniformScale", ground_plane.id, 32.0) + ground_plane_material_asset_path = os.path.join( + "Materials", "Presets", "PBR", "metal_chrome.azmaterial") + ground_plane_material_asset_value = asset.AssetCatalogRequestBus( + bus.Broadcast, "GetAssetIdByPath", ground_plane_material_asset_path, math.Uuid(), False) + ground_plane.get_set_test(0, "Default Material|Material Asset", ground_plane_material_asset_value) + + # Work around to add the correct Atom Mesh component + mesh_type_id = azlmbr.globals.property.EditorMeshComponentTypeId + ground_plane.components.append( + editor.EditorComponentAPIBus( + bus.Broadcast, "AddComponentsOfType", ground_plane.id, [mesh_type_id] + ).GetValue()[0] + ) + ground_plane_mesh_asset_path = os.path.join("Models", "plane.azmodel") + ground_plane_mesh_asset_value = asset.AssetCatalogRequestBus( + bus.Broadcast, "GetAssetIdByPath", ground_plane_mesh_asset_path, math.Uuid(), False) + ground_plane.get_set_test(1, "Controller|Configuration|Mesh Asset", ground_plane_mesh_asset_value) + + # Create directional_light entity and set the properties + directional_light = hydra.Entity("directional_light") + directional_light.create_entity( + entity_position=math.Vector3(0.0, 0.0, 10.0), + components=["Directional Light"], + parent_id=default_level.id) + directional_light_rotation = math.Vector3(degree_radian_factor * -90.0, 0.0, 0.0) + azlmbr.components.TransformBus( + azlmbr.bus.Event, "SetLocalRotation", directional_light.id, directional_light_rotation) + + # Create sphere entity and set the properties + sphere_entity = hydra.Entity("sphere") + sphere_entity.create_entity( + entity_position=math.Vector3(0.0, 0.0, 1.0), + components=["Material"], + parent_id=default_level.id) + sphere_material_asset_path = os.path.join("Materials", "Presets", "PBR", "metal_brass_polished.azmaterial") + sphere_material_asset_value = asset.AssetCatalogRequestBus( + bus.Broadcast, "GetAssetIdByPath", sphere_material_asset_path, math.Uuid(), False) + sphere_entity.get_set_test(0, "Default Material|Material Asset", sphere_material_asset_value) + + # Work around to add the correct Atom Mesh component + sphere_entity.components.append( + editor.EditorComponentAPIBus( + bus.Broadcast, "AddComponentsOfType", sphere_entity.id, [mesh_type_id] + ).GetValue()[0] + ) + sphere_mesh_asset_path = os.path.join("Models", "sphere.azmodel") + sphere_mesh_asset_value = asset.AssetCatalogRequestBus( + bus.Broadcast, "GetAssetIdByPath", sphere_mesh_asset_path, math.Uuid(), False) + sphere_entity.get_set_test(1, "Controller|Configuration|Mesh Asset", sphere_mesh_asset_value) + + # Create camera component and set the properties + camera_entity = hydra.Entity("camera") + camera_entity.create_entity( + entity_position=math.Vector3(5.5, -12.0, 9.0), + components=["Camera"], + parent_id=default_level.id) + rotation = math.Vector3( + degree_radian_factor * -27.0, degree_radian_factor * -12.0, degree_radian_factor * 25.0 + ) + azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", camera_entity.id, rotation) + camera_entity.get_set_test(0, "Controller|Configuration|Field of view", 60.0) + camera.EditorCameraViewRequestBus(azlmbr.bus.Event, "ToggleCameraAsActiveView", camera_entity.id) diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_utils/atom_constants.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_utils/atom_constants.py new file mode 100644 index 0000000000..88a959f198 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_utils/atom_constants.py @@ -0,0 +1,19 @@ +""" +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 + +Hold constants used across both hydra and non-hydra scripts. +""" + +# Light type options for the Light component. +LIGHT_TYPES = { + 'unknown': 0, + 'sphere': 1, + 'spot_disk': 2, + 'capsule': 3, + 'quad': 4, + 'polygon': 5, + 'simple_point': 6, + 'simple_spot': 7, +} diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_utils/material_editor_utils.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_utils/material_editor_utils.py new file mode 100644 index 0000000000..77d1285188 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_utils/material_editor_utils.py @@ -0,0 +1,274 @@ +""" +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 + +import azlmbr.materialeditor will fail with a ModuleNotFound error when using this script with Editor.exe +This is because azlmbr.materialeditor only binds to MaterialEditor.exe and not Editor.exe +You need to launch this script with MaterialEditor.exe in order for azlmbr.materialeditor to appear. +""" + +import os +import sys +import time +import azlmbr.atom +import azlmbr.materialeditor as materialeditor +import azlmbr.bus as bus +import azlmbr.atomtools.general as general + + +def is_close(actual, expected, buffer=sys.float_info.min): + """ + :param actual: actual value + :param expected: expected value + :param buffer: acceptable variation from expected + :return: bool + """ + return abs(actual - expected) < buffer + + +def compare_colors(color1, color2, buffer=0.00001): + """ + Compares the red, green and blue properties of a color allowing a slight variance of buffer + :param color1: first color to compare + :param color2: second color + :param buffer: allowed variance in individual color value + :return: bool + """ + return ( + is_close(color1.r, color2.r, buffer) + and is_close(color1.g, color2.g, buffer) + and is_close(color1.b, color2.b, buffer) + ) + + +def open_material(file_path): + """ + :return: uuid of material document opened + """ + return materialeditor.MaterialDocumentSystemRequestBus(bus.Broadcast, "OpenDocument", file_path) + + +def is_open(document_id): + """ + :return: bool + """ + return materialeditor.MaterialDocumentRequestBus(bus.Event, "IsOpen", document_id) + + +def save_document(document_id): + """ + :return: bool success + """ + return materialeditor.MaterialDocumentSystemRequestBus(bus.Broadcast, "SaveDocument", document_id) + + +def save_document_as_copy(document_id, target_path): + """ + :return: bool success + """ + return materialeditor.MaterialDocumentSystemRequestBus( + bus.Broadcast, "SaveDocumentAsCopy", document_id, target_path + ) + + +def save_document_as_child(document_id, target_path): + """ + :return: bool success + """ + return materialeditor.MaterialDocumentSystemRequestBus( + bus.Broadcast, "SaveDocumentAsChild", document_id, target_path + ) + + +def save_all(): + """ + :return: bool success + """ + return materialeditor.MaterialDocumentSystemRequestBus(bus.Broadcast, "SaveAllDocuments") + + +def close_document(document_id): + """ + :return: bool success + """ + return materialeditor.MaterialDocumentSystemRequestBus(bus.Broadcast, "CloseDocument", document_id) + + +def close_all_documents(): + """ + :return: bool success + """ + return materialeditor.MaterialDocumentSystemRequestBus(bus.Broadcast, "CloseAllDocuments") + + +def close_all_except_selected(document_id): + """ + :return: bool success + """ + return materialeditor.MaterialDocumentSystemRequestBus(bus.Broadcast, "CloseAllDocumentsExcept", document_id) + + +def get_property(document_id, property_name): + """ + :return: property value or invalid value if the document is not open or the property_name can't be found + """ + return materialeditor.MaterialDocumentRequestBus(bus.Event, "GetPropertyValue", document_id, property_name) + + +def set_property(document_id, property_name, value): + materialeditor.MaterialDocumentRequestBus(bus.Event, "SetPropertyValue", document_id, property_name, value) + + +def is_pane_visible(pane_name): + """ + :return: bool + """ + return materialeditor.MaterialEditorWindowRequestBus(bus.Broadcast, "IsDockWidgetVisible", pane_name) + + +def set_pane_visibility(pane_name, value): + materialeditor.MaterialEditorWindowRequestBus(bus.Broadcast, "SetDockWidgetVisible", pane_name, value) + + +def select_lighting_config(config_name): + azlmbr.materialeditor.MaterialViewportRequestBus(azlmbr.bus.Broadcast, "SelectLightingPresetByName", config_name) + + +def set_grid_enable_disable(value): + azlmbr.materialeditor.MaterialViewportRequestBus(azlmbr.bus.Broadcast, "SetGridEnabled", value) + + +def get_grid_enable_disable(): + """ + :return: bool + """ + return azlmbr.materialeditor.MaterialViewportRequestBus(azlmbr.bus.Broadcast, "GetGridEnabled") + + +def set_shadowcatcher_enable_disable(value): + azlmbr.materialeditor.MaterialViewportRequestBus(azlmbr.bus.Broadcast, "SetShadowCatcherEnabled", value) + + +def get_shadowcatcher_enable_disable(): + """ + :return: bool + """ + return azlmbr.materialeditor.MaterialViewportRequestBus(azlmbr.bus.Broadcast, "GetShadowCatcherEnabled") + + +def select_model_config(configname): + azlmbr.materialeditor.MaterialViewportRequestBus(azlmbr.bus.Broadcast, "SelectModelPresetByName", configname) + + +def wait_for_condition(function, timeout_in_seconds=1.0): + # type: (function, float) -> bool + """ + Function to run until it returns True or timeout is reached + the function can have no parameters and + waiting idle__wait_* is handled here not in the function + + :param function: a function that returns a boolean indicating a desired condition is achieved + :param timeout_in_seconds: when reached, function execution is abandoned and False is returned + """ + with Timeout(timeout_in_seconds) as t: + while True: + try: + general.idle_wait_frames(1) + except Exception: + print("WARNING: Couldn't wait for frame") + + if t.timed_out: + return False + + ret = function() + if not isinstance(ret, bool): + raise TypeError("return value for wait_for_condition function must be a bool") + if ret: + return True + + +class Timeout: + # type: (float) -> None + """ + contextual timeout + :param seconds: float seconds to allow before timed_out is True + """ + + def __init__(self, seconds): + self.seconds = seconds + + def __enter__(self): + self.die_after = time.time() + self.seconds + return self + + def __exit__(self, type, value, traceback): + pass + + @property + def timed_out(self): + return time.time() > self.die_after + + +screenshotsFolder = os.path.join(azlmbr.paths.devroot, "AtomTest", "Cache" "pc", "Screenshots") + + +class ScreenshotHelper: + """ + A helper to capture screenshots and wait for them. + """ + + def __init__(self, idle_wait_frames_callback): + super().__init__() + self.done = False + self.capturedScreenshot = False + self.max_frames_to_wait = 60 + + self.idle_wait_frames_callback = idle_wait_frames_callback + + def capture_screenshot_blocking(self, filename): + """ + Capture a screenshot and block the execution until the screenshot has been written to the disk. + """ + self.handler = azlmbr.atom.FrameCaptureNotificationBusHandler() + self.handler.connect() + self.handler.add_callback("OnCaptureFinished", self.on_screenshot_captured) + + self.done = False + self.capturedScreenshot = False + success = azlmbr.atom.FrameCaptureRequestBus(azlmbr.bus.Broadcast, "CaptureScreenshot", filename) + if success: + self.wait_until_screenshot() + print("Screenshot taken.") + else: + print("screenshot failed") + return self.capturedScreenshot + + def on_screenshot_captured(self, parameters): + # the parameters come in as a tuple + if parameters[0]: + print("screenshot saved: {}".format(parameters[1])) + self.capturedScreenshot = True + else: + print("screenshot failed: {}".format(parameters[1])) + self.done = True + self.handler.disconnect() + + def wait_until_screenshot(self): + frames_waited = 0 + while self.done == False: + self.idle_wait_frames_callback(1) + if frames_waited > self.max_frames_to_wait: + print("timeout while waiting for the screenshot to be written") + self.handler.disconnect() + break + else: + frames_waited = frames_waited + 1 + print("(waited {} frames)".format(frames_waited)) + + +def capture_screenshot(file_path): + return ScreenshotHelper(azlmbr.atomtools.general.idle_wait_frames).capture_screenshot_blocking( + os.path.join(file_path) + ) diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_utils/screenshot_utils.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_utils/screenshot_utils.py index 28a4037dcc..a7a02816ac 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_utils/screenshot_utils.py +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_utils/screenshot_utils.py @@ -91,3 +91,20 @@ class ScreenshotHelper(object): else: frames_waited = frames_waited + 1 general.log(f"(waited {frames_waited} frames)") + + +def take_screenshot_game_mode(screenshot_name, entity_name=None): + """ + Enters game mode & takes a screenshot, then exits game mode after. + :param screenshot_name: name to give the captured screenshot .ppm file. + :param entity_name: name of the entity being tested (for generating unique log lines). + :return: None + """ + general.enter_game_mode() + helper.wait_for_condition(lambda: general.is_in_game_mode(), 2.0) + general.log(f"{entity_name}_test: Entered game mode: {general.is_in_game_mode()}") + ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking(f"{screenshot_name}.ppm") + general.idle_wait(1.0) + general.exit_game_mode() + helper.wait_for_condition(lambda: not general.is_in_game_mode(), 2.0) + general.log(f"{entity_name}_test: Exit game mode: {not general.is_in_game_mode()}") diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/AreaLight_1.ppm b/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/AreaLight_1.ppm new file mode 100644 index 0000000000..0725999dcf --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/AreaLight_1.ppm @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:954d7d0df47c840a24e313893800eb3126d0c0d47c3380926776b51833778db7 +size 6220817 diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/AreaLight_2.ppm b/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/AreaLight_2.ppm new file mode 100644 index 0000000000..3a45bd31e3 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/AreaLight_2.ppm @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e81c19128f42ba362a2d5f3ccf159dfbc942d67ceeb1ac8c21f295a6fd9d2ce5 +size 6220817 diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/AreaLight_3.ppm b/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/AreaLight_3.ppm new file mode 100644 index 0000000000..15d679b784 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/AreaLight_3.ppm @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e20801213e065b6ea8c95ede81c23faa9b6dc70a2002dc5bced293e1bed989f +size 6220817 diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/AreaLight_4.ppm b/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/AreaLight_4.ppm new file mode 100644 index 0000000000..85c083a386 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/AreaLight_4.ppm @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e250f812e594e5152bf2d6f23caa8b53b78276bfdf344d7a8d355dd96cb995c0 +size 6220817 diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/AreaLight_5.ppm b/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/AreaLight_5.ppm new file mode 100644 index 0000000000..d575de761e --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/AreaLight_5.ppm @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:95be359041f8291c74b335297a4dfe9902a180510f24a181b15e1a5ba4d3b024 +size 6220817 diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/SpotLight_1.ppm b/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/SpotLight_1.ppm new file mode 100644 index 0000000000..bbbd127929 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/SpotLight_1.ppm @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:118e43e4b915e262726183467cc4b82f244565213fea5b6bfe02be07f0851ab1 +size 6220817 diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/SpotLight_2.ppm b/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/SpotLight_2.ppm new file mode 100644 index 0000000000..8e716fabcc --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/SpotLight_2.ppm @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dc2ce3256a6552975962c9e113c52c1a22bf3817d417151f6f60640dd568e0fa +size 6220817 diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/SpotLight_3.ppm b/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/SpotLight_3.ppm new file mode 100644 index 0000000000..6b6a5a5d6e --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/SpotLight_3.ppm @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:287d98890b35427688999760f9d066bcbff1a3bc9001534241dc212b32edabd8 +size 6220817 diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/SpotLight_4.ppm b/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/SpotLight_4.ppm new file mode 100644 index 0000000000..eb05228cc2 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/SpotLight_4.ppm @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:66e91c92c868167c850078cd91714db47e10a96e23cc30191994486bd79c353f +size 6220817 diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/SpotLight_5.ppm b/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/SpotLight_5.ppm new file mode 100644 index 0000000000..5e12edc46d --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/SpotLight_5.ppm @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d950d173f5101820c5e18205401ca08ce5feeff2302ac2920b292750d86a8fa4 +size 6220817 diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/SpotLight_6.ppm b/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/SpotLight_6.ppm new file mode 100644 index 0000000000..d442d90287 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/golden_images/SpotLight_6.ppm @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:72eddb7126eae0c839b933886e0fb69d78229f72d49ef13199de28df2b7879db +size 6220817 diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py index 9165bced90..7be1ed1b12 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py @@ -15,11 +15,11 @@ import pytest import ly_test_tools.environment.file_system as file_system from ly_test_tools.image.screenshot_compare_qssim import qssim as compare_screenshots from ly_test_tools.benchmark.data_aggregator import BenchmarkDataAggregator + import editor_python_test_tools.hydra_test_utils as hydra logger = logging.getLogger(__name__) DEFAULT_SUBFOLDER_PATH = 'user/PythonTests/Automated/Screenshots' -EDITOR_TIMEOUT = 600 TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "atom_hydra_scripts") @@ -67,6 +67,7 @@ class TestAllComponentsIndepthTests(object): "Trace::Assert", "Trace::Error", "Traceback (most recent call last):", + "Screenshot failed" ] hydra.launch_and_validate_results( @@ -74,7 +75,7 @@ class TestAllComponentsIndepthTests(object): TEST_DIRECTORY, editor, "hydra_GPUTest_BasicLevelSetup.py", - timeout=EDITOR_TIMEOUT, + timeout=180, expected_lines=level_creation_expected_lines, unexpected_lines=unexpected_lines, halt_on_unexpected=True, @@ -85,6 +86,60 @@ class TestAllComponentsIndepthTests(object): for test_screenshot, golden_screenshot in zip(test_screenshots, golden_images): compare_screenshots(test_screenshot, golden_screenshot) + def test_LightComponent_ScreenshotMatchesGoldenImage( + self, request, editor, workspace, project, launcher_platform, level): + """ + Please review the hydra script run by this test for more specific test info. + Tests that the Light component screenshots in a rendered level appear the same as the golden images. + """ + screenshot_names = [ + "AreaLight_1.ppm", + "AreaLight_2.ppm", + "AreaLight_3.ppm", + "AreaLight_4.ppm", + "AreaLight_5.ppm", + "SpotLight_1.ppm", + "SpotLight_2.ppm", + "SpotLight_3.ppm", + "SpotLight_4.ppm", + "SpotLight_5.ppm", + "SpotLight_6.ppm", + ] + test_screenshots = [] + for screenshot in screenshot_names: + screenshot_path = os.path.join(workspace.paths.project(), DEFAULT_SUBFOLDER_PATH, screenshot) + test_screenshots.append(screenshot_path) + file_system.delete(test_screenshots, True, True) + + golden_images = [] + for golden_image in screenshot_names: + golden_image_path = os.path.join(golden_images_directory(), golden_image) + golden_images.append(golden_image_path) + + expected_lines = ["Light component tests completed."] + unexpected_lines = [ + "Trace::Assert", + "Trace::Error", + "Traceback (most recent call last):", + "Screenshot failed", + ] + hydra.launch_and_validate_results( + request, + TEST_DIRECTORY, + editor, + "hydra_GPUTest_LightComponent.py", + timeout=180, + expected_lines=expected_lines, + unexpected_lines=unexpected_lines, + halt_on_unexpected=True, + cfg_args=[level], + null_renderer=False, + ) + + for test_screenshot, golden_screenshot in zip(test_screenshots, golden_images): + compare_screenshots(test_screenshot, golden_screenshot) + + @pytest.mark.parametrize('rhi', ['dx12', 'vulkan']) @pytest.mark.parametrize("project", ["AutomatedTesting"]) @pytest.mark.parametrize("launcher_platform", ["windows_editor"]) @@ -116,7 +171,7 @@ class TestPerformanceBenchmarkSuite(object): TEST_DIRECTORY, editor, "hydra_GPUTest_AtomFeatureIntegrationBenchmark.py", - timeout=EDITOR_TIMEOUT, + timeout=600, expected_lines=expected_lines, unexpected_lines=unexpected_lines, halt_on_unexpected=True, diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py index 98d2ba0632..be75801b63 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py @@ -11,8 +11,9 @@ import os import pytest +import ly_test_tools.environment.file_system as file_system import editor_python_test_tools.hydra_test_utils as hydra -from atom_renderer.atom_utils.atom_component_helper import LIGHT_TYPES +from atom_renderer.atom_utils.atom_constants import LIGHT_TYPES logger = logging.getLogger(__name__) EDITOR_TIMEOUT = 120 @@ -242,3 +243,65 @@ class TestAtomEditorComponentsMain(object): null_renderer=True, cfg_args=cfg_args, ) + + +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +@pytest.mark.parametrize("launcher_platform", ['windows_generic']) +@pytest.mark.system +class TestMaterialEditorBasicTests(object): + @pytest.fixture(autouse=True) + def setup_teardown(self, request, workspace, project): + def delete_files(): + file_system.delete( + [ + os.path.join(workspace.paths.project(), "Materials", "test_material.material"), + os.path.join(workspace.paths.project(), "Materials", "test_material_1.material"), + os.path.join(workspace.paths.project(), "Materials", "test_material_2.material"), + ], + True, + True, + ) + # Cleanup our newly created materials + delete_files() + + def teardown(): + # Cleanup our newly created materials + delete_files() + + request.addfinalizer(teardown) + + @pytest.mark.parametrize("exe_file_name", ["MaterialEditor"]) + def test_MaterialEditorBasicTests( + self, request, workspace, project, launcher_platform, generic_launcher, exe_file_name): + + expected_lines = [ + "Material opened: True", + "Test asset doesn't exist initially: True", + "New asset created: True", + "New Material opened: True", + "Material closed: True", + "All documents closed: True", + "Close All Except Selected worked as expected: True", + "Actual Document saved with changes: True", + "Document saved as copy is saved with changes: True", + "Document saved as child is saved with changes: True", + "Save All worked as expected: True", + ] + unexpected_lines = [ + # "Trace::Assert", + # "Trace::Error", + "Traceback (most recent call last):" + ] + + hydra.launch_and_validate_results( + request, + TEST_DIRECTORY, + generic_launcher, + "hydra_AtomMaterialEditor_BasicTests.py", + run_python="--runpython", + timeout=80, + expected_lines=expected_lines, + unexpected_lines=unexpected_lines, + halt_on_unexpected=True, + log_file_name="MaterialEditor.log", + ) diff --git a/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt index afde0a0d94..fa35bb25c6 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt @@ -13,7 +13,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ TEST_SERIAL PATH ${CMAKE_CURRENT_LIST_DIR} PYTEST_MARKS "SUITE_main and not REQUIRES_gpu" - TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor AZ::AssetProcessor @@ -28,7 +27,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ TEST_SERIAL PATH ${CMAKE_CURRENT_LIST_DIR} PYTEST_MARKS "SUITE_periodic and not REQUIRES_gpu" - TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor AZ::AssetProcessor @@ -44,7 +42,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ TEST_REQUIRES gpu PATH ${CMAKE_CURRENT_LIST_DIR} PYTEST_MARKS "SUITE_main and REQUIRES_gpu" - TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor AZ::AssetProcessor @@ -59,7 +56,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ TEST_SERIAL PATH ${CMAKE_CURRENT_LIST_DIR} PYTEST_MARKS "SUITE_sandbox" - TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor AZ::AssetProcessor diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt index 351ca19031..043485d869 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt @@ -16,7 +16,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ TEST_SUITE main PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg PYTEST_MARKS "not SUITE_sandbox and not SUITE_periodic and not SUITE_benchmark" - TIMEOUT 1500 RUNTIME_DEPENDENCIES AZ::AssetProcessor Legacy::Editor @@ -33,7 +32,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ TEST_SUITE sandbox PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg PYTEST_MARKS "SUITE_sandbox" - TIMEOUT 1500 RUNTIME_DEPENDENCIES AZ::AssetProcessor Legacy::Editor @@ -49,7 +47,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ TEST_SUITE periodic PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg PYTEST_MARKS "SUITE_periodic and dynveg_filter" - TIMEOUT 1500 RUNTIME_DEPENDENCIES AZ::AssetProcessor Legacy::Editor @@ -64,7 +61,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ TEST_SUITE periodic PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg PYTEST_MARKS "SUITE_periodic and dynveg_modifier" - TIMEOUT 1500 RUNTIME_DEPENDENCIES AZ::AssetProcessor Legacy::Editor @@ -79,7 +75,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ TEST_SUITE periodic PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg PYTEST_MARKS "SUITE_periodic and dynveg_regression" - TIMEOUT 1500 RUNTIME_DEPENDENCIES AZ::AssetProcessor Legacy::Editor @@ -94,7 +89,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ TEST_SUITE periodic PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg PYTEST_MARKS "SUITE_periodic and dynveg_area" - TIMEOUT 1500 RUNTIME_DEPENDENCIES AZ::AssetProcessor Legacy::Editor @@ -109,7 +103,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ TEST_SUITE periodic PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg PYTEST_MARKS "SUITE_periodic and dynveg_misc" - TIMEOUT 1500 RUNTIME_DEPENDENCIES AZ::AssetProcessor Legacy::Editor @@ -124,7 +117,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ TEST_SUITE periodic PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg PYTEST_MARKS "SUITE_periodic and dynveg_surfacetagemitter" - TIMEOUT 1500 RUNTIME_DEPENDENCIES AZ::AssetProcessor Legacy::Editor @@ -140,7 +132,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ TEST_SUITE main PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas PYTEST_MARKS "not SUITE_sandbox and not SUITE_periodic and not SUITE_benchmark" - TIMEOUT 1500 RUNTIME_DEPENDENCIES AZ::AssetProcessor Legacy::Editor @@ -155,7 +146,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ TEST_SUITE periodic PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas PYTEST_MARKS "SUITE_periodic" - TIMEOUT 1500 RUNTIME_DEPENDENCIES AZ::AssetProcessor Legacy::Editor @@ -170,7 +160,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ TEST_SERIAL TEST_SUITE periodic PATH ${CMAKE_CURRENT_LIST_DIR}/gradient_signal - TIMEOUT 1500 RUNTIME_DEPENDENCIES AZ::AssetProcessor Legacy::Editor diff --git a/AutomatedTesting/Gem/PythonTests/physics/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/physics/CMakeLists.txt index 248bf3fdc5..eb37db1943 100644 --- a/AutomatedTesting/Gem/PythonTests/physics/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/physics/CMakeLists.txt @@ -12,7 +12,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) TEST_SUITE main TEST_SERIAL PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py - TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor AZ::AssetProcessor @@ -25,7 +24,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) TEST_SUITE periodic TEST_SERIAL PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Periodic.py - TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor AZ::AssetProcessor @@ -38,7 +36,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) TEST_SUITE sandbox TEST_SERIAL PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Sandbox.py - TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor AZ::AssetProcessor diff --git a/AutomatedTesting/Gem/PythonTests/prefab/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/prefab/CMakeLists.txt index 1d9c54fa40..48c24d1ebf 100644 --- a/AutomatedTesting/Gem/PythonTests/prefab/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/prefab/CMakeLists.txt @@ -13,7 +13,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) TEST_SUITE main TEST_SERIAL PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py - TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor AZ::AssetProcessor diff --git a/AutomatedTesting/Gem/PythonTests/prefab/PrefabLevel_BasicWorkflow.py b/AutomatedTesting/Gem/PythonTests/prefab/PrefabLevel_BasicWorkflow.py new file mode 100644 index 0000000000..44b7dc2ee4 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/prefab/PrefabLevel_BasicWorkflow.py @@ -0,0 +1,66 @@ +""" +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 +""" + +# fmt:off +class Tests(): + create_new_entity = ("Entity: 'CreateNewEntity' passed", "Entity: 'CreateNewEntity' failed") + create_prefab = ("Prefab: 'CreatePrefab' passed", "Prefab: 'CreatePrefab' failed") + instantiate_prefab = ("Prefab: 'InstantiatePrefab' passed", "Prefab: 'InstantiatePrefab' failed") + new_prefab_position = ("Prefab: new prefab's position is at the expected position", "Prefab: new prefab's position is *not* at the expected position") +# fmt:on + +def PrefabLevel_BasicWorkflow(): + """ + This test will help verify if the following functions related to Prefab work as expected: + - CreatePrefab + - InstantiatePrefab + """ + + import os + import sys + + from editor_python_test_tools.utils import Report + from editor_python_test_tools.utils import TestHelper as helper + import editor_python_test_tools.hydra_editor_utils as hydra + + import azlmbr.bus as bus + import azlmbr.entity as entity + from azlmbr.entity import EntityId + import azlmbr.editor as editor + import azlmbr.prefab as prefab + from azlmbr.math import Vector3 + import azlmbr.legacy.general as general + + EXPECTED_NEW_PREFAB_POSITION = Vector3(10.00, 20.0, 30.0) + + helper.init_idle() + helper.open_level("Prefab", "Base") + +# Create a new Entity at the root level + new_entity_id = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', EntityId()) + Report.result(Tests.create_new_entity, new_entity_id.IsValid()) + +# Checks for prefab creation passed or not + new_prefab_file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'new_prefab.prefab') + create_prefab_result = prefab.PrefabPublicRequestBus(bus.Broadcast, 'CreatePrefabInMemory', [new_entity_id], new_prefab_file_path) + Report.result(Tests.create_prefab, create_prefab_result) + +# Checks for prefab instantiation passed or not + container_entity_id = prefab.PrefabPublicRequestBus(bus.Broadcast, 'InstantiatePrefab', new_prefab_file_path, EntityId(), EXPECTED_NEW_PREFAB_POSITION) + Report.result(Tests.instantiate_prefab, container_entity_id.IsValid()) + +# Checks if the new prefab is at the correct position and if it fails, it will provide the expected postion and the actual postion of the entity in the Editor log + new_prefab_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", container_entity_id) + is_at_position = new_prefab_position.IsClose(EXPECTED_NEW_PREFAB_POSITION) + Report.result(Tests.new_prefab_position, is_at_position) + if not is_at_position: + Report.info(f'Expected position: {EXPECTED_NEW_PREFAB_POSITION.ToString()}, actual position: {new_prefab_position.ToString()}') + + +if __name__ == "__main__": + from editor_python_test_tools.utils import Report + Report.start_test(PrefabLevel_BasicWorkflow) diff --git a/AutomatedTesting/Gem/PythonTests/prefab/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/prefab/TestSuite_Main.py index acd8f60b07..4e3d6ba77f 100644 --- a/AutomatedTesting/Gem/PythonTests/prefab/TestSuite_Main.py +++ b/AutomatedTesting/Gem/PythonTests/prefab/TestSuite_Main.py @@ -16,6 +16,7 @@ from ly_test_tools import LAUNCHERS sys.path.append (os.path.dirname (os.path.abspath (__file__)) + '/../automatedtesting_shared') +import ly_test_tools.environment.file_system as file_system from base import TestAutomationBase @pytest.mark.SUITE_main @@ -29,3 +30,8 @@ class TestAutomation(TestAutomationBase): def test_PrefabLevel_OpensLevelWithEntities(self, request, workspace, editor, launcher_platform): from . import PrefabLevel_OpensLevelWithEntities as test_module self._run_prefab_test(request, workspace, editor, test_module) + + def test_PrefabLevel_BasicWorkflow(self, request, workspace, editor, launcher_platform): + from . import PrefabLevel_BasicWorkflow as test_module + self._run_prefab_test(request, workspace, editor, test_module) + diff --git a/AutomatedTesting/Gem/PythonTests/scripting/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/scripting/CMakeLists.txt index 80b6e9a54e..25988216b2 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/scripting/CMakeLists.txt @@ -12,7 +12,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) TEST_SUITE periodic TEST_SERIAL PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Periodic.py - TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor AZ::AssetProcessor @@ -25,7 +24,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) TEST_SUITE sandbox TEST_SERIAL PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Sandbox.py - TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor AZ::AssetProcessor diff --git a/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt index 2c1d03b5a2..3fc4f3db0e 100644 --- a/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt @@ -18,7 +18,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) TEST_SERIAL PATH ${CMAKE_CURRENT_LIST_DIR} PYTEST_MARKS "SUITE_smoke" - TIMEOUT 1500 RUNTIME_DEPENDENCIES AZ::AssetProcessor AZ::PythonBindingsExample diff --git a/AutomatedTesting/Levels/Prefab/Base/Base.prefab b/AutomatedTesting/Levels/Prefab/Base/Base.prefab new file mode 100644 index 0000000000..f7e42e7731 --- /dev/null +++ b/AutomatedTesting/Levels/Prefab/Base/Base.prefab @@ -0,0 +1,53 @@ +{ + "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 + } + } + } +} \ No newline at end of file diff --git a/Code/Editor/Animation/SkeletonHierarchy.cpp b/Code/Editor/Animation/SkeletonHierarchy.cpp deleted file mode 100644 index d1cc44b31d..0000000000 --- a/Code/Editor/Animation/SkeletonHierarchy.cpp +++ /dev/null @@ -1,149 +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 "EditorDefs.h" -#include "SkeletonHierarchy.h" - -using namespace Skeleton; - -/* - - CHierarchy - -*/ - -CHierarchy::CHierarchy() -{ -} - -CHierarchy::~CHierarchy() -{ -} - -// - -uint32 CHierarchy::AddNode(const char* name, const QuatT& pose, int32 parent) -{ - int32 index = FindNodeIndexByName(name); - - if (index < 0) - { - m_nodes.push_back(SNode()); - index = int32(m_nodes.size() - 1); - } - - m_nodes[index].name = name; - m_nodes[index].pose = pose; - m_nodes[index].parent = parent; - return uint32(index); -} - -int32 CHierarchy::FindNodeIndexByName(const char* name) const -{ - uint32 count = uint32(m_nodes.size()); - for (uint32 i = 0; i < count; ++i) - { - if (::_stricmp(m_nodes[i].name, name)) - { - continue; - } - - return i; - } - - return -1; -} - -const CHierarchy::SNode* CHierarchy::FindNode(const char* name) const -{ - int32 index = FindNodeIndexByName(name); - return index < 0 ? nullptr : &m_nodes[index]; -} - -void CHierarchy::CreateFrom(IDefaultSkeleton* pIDefaultSkeleton) -{ - const uint32 jointCount = pIDefaultSkeleton->GetJointCount(); - - m_nodes.clear(); - m_nodes.reserve(jointCount); - for (uint32 i = 0; i < jointCount; ++i) - { - m_nodes.push_back(SNode()); - - m_nodes.back().name = pIDefaultSkeleton->GetJointNameByID(int32(i)); - m_nodes.back().pose = pIDefaultSkeleton->GetDefaultAbsJointByID(int32(i)); - - m_nodes.back().parent = pIDefaultSkeleton->GetJointParentIDByID(int32(i)); - } - - ValidateReferences(); -} - -void CHierarchy::ValidateReferences() -{ - uint32 nodeCount = m_nodes.size(); - if (!nodeCount) - { - return; - } - - for (uint32 i = 0; i < nodeCount; ++i) - { - if (m_nodes[i].parent < nodeCount) - { - continue; - } - - m_nodes[i].parent = -1; - } -} - -void CHierarchy::AbsoluteToRelative(const QuatT* pSource, QuatT* pDestination) -{ - uint32 count = uint32(m_nodes.size()); - std::vector absolutes(count); - for (uint32 i = 0; i < count; ++i) - { - absolutes[i] = pSource[i]; - } - - for (uint32 i = 0; i < count; ++i) - { - int32 parent = m_nodes[i].parent; - if (parent < 0) - { - pDestination[i] = absolutes[i]; - continue; - } - - pDestination[i].t = (absolutes[i].t - absolutes[parent].t) * absolutes[parent].q; - pDestination[i].q = absolutes[parent].q.GetInverted() * absolutes[i].q; - } -} - -bool CHierarchy::SerializeTo(XmlNodeRef& node) -{ - XmlNodeRef hierarchy = node->newChild("Hierarchy"); - - uint32 nodeCount = uint32(m_nodes.size()); - std::vector nodes(nodeCount); - for (uint32 i = 0; i < nodeCount; ++i) - { - XmlNodeRef parent = hierarchy; - if (m_nodes[i].parent > -1) - { - parent = nodes[m_nodes[i].parent]; - } - - nodes[i] = parent->newChild("Node"); - nodes[i]->setAttr("name", m_nodes[i].name); - } - - return true; -} diff --git a/Code/Editor/Animation/SkeletonHierarchy.h b/Code/Editor/Animation/SkeletonHierarchy.h deleted file mode 100644 index ad0d8fc7fc..0000000000 --- a/Code/Editor/Animation/SkeletonHierarchy.h +++ /dev/null @@ -1,57 +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 CRYINCLUDE_EDITOR_ANIMATION_SKELETONHIERARCHY_H -#define CRYINCLUDE_EDITOR_ANIMATION_SKELETONHIERARCHY_H -#pragma once - -namespace Skeleton { - class CHierarchy - : public _reference_target_t - { - public: - struct SNode - { - string name; - QuatT pose; - - int32 parent; - - /* TODO: Implement - uint32 childrenIndex; - uint32 childrenCount; - */ - }; - - public: - CHierarchy(); - ~CHierarchy(); - - public: - uint32 AddNode(const char* name, const QuatT& pose, int32 parent = -1); - uint32 GetNodeCount() const { return uint32(m_nodes.size()); } - SNode* GetNode(uint32 index) { return &m_nodes[index]; } - const SNode* GetNode(uint32 index) const { return &m_nodes[index]; } - int32 FindNodeIndexByName(const char* name) const; - const SNode* FindNode(const char* name) const; - void ClearNodes() { m_nodes.clear(); } - - void CreateFrom(IDefaultSkeleton* rIDefaultSkeleton); - void ValidateReferences(); - - void AbsoluteToRelative(const QuatT* pSource, QuatT* pDestination); - - bool SerializeTo(XmlNodeRef& node); - - private: - std::vector m_nodes; - }; -} // namespace Skeleton - -#endif // CRYINCLUDE_EDITOR_ANIMATION_SKELETONHIERARCHY_H diff --git a/Code/Editor/Animation/SkeletonMapper.cpp b/Code/Editor/Animation/SkeletonMapper.cpp deleted file mode 100644 index 24f01f56ad..0000000000 --- a/Code/Editor/Animation/SkeletonMapper.cpp +++ /dev/null @@ -1,368 +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 "EditorDefs.h" - -#include "SkeletonMapper.h" - -using namespace Skeleton; - -/* - - CMapper - -*/ - -CMapper::CMapper() -{ -} - -CMapper::~CMapper() -{ -} - -// - -void CMapper::CreateFromHierarchy() -{ - m_nodes.clear(); - - uint32 nodeCount = m_hierarchy.GetNodeCount(); - m_nodes.resize(nodeCount); -} - -// - -uint32 CMapper::CreateLocation(const char* name) -{ - int32 index = FindLocation(name); - if (index < 1) - { - CMapperLocation* pLocation = new CMapperLocation(); - pLocation->SetName(name); - m_locations.push_back(pLocation); - } - return uint32(m_locations.size() - 1); -} - -void CMapper::ClearLocations() -{ - uint32 count = uint32(m_nodes.size()); - for (uint32 i = 0; i < count; ++i) - { - m_nodes[i].position = nullptr; - m_nodes[i].orientation = nullptr; - } - - m_locations.clear(); -} - -int32 CMapper::FindLocation(const char* name) const -{ - uint32 count = uint32(m_locations.size()); - for (uint32 i = 0; i < count; ++i) - { - if (::_stricmp(m_locations[i]->GetName(), name)) - { - continue; - } - - return int32(i); - } - - return -1; -} - -void CMapper::SetLocation(CMapperLocation& location) -{ - int32 index = FindLocation(location.GetName()); - if (index < 0) - { - m_locations.push_back(&location); - return; - } - - m_locations[index] = &location; -} - -// - -bool CMapper::CreateLocationsHierarchy(uint32 index, CHierarchy& hierarchy, int32 hierarchyParent) -{ - if (NodeHasLocation(index)) - { - const CHierarchy::SNode* pNode = m_hierarchy.GetNode(index); - uint32 nodeIndex = hierarchy.AddNode(pNode->name, pNode->pose, hierarchyParent); - hierarchyParent = uint32(nodeIndex); - } - - std::vector children; - GetChildrenIndices(index, children); - uint32 childCount = uint32(children.size()); - for (uint32 i = 0; i < childCount; ++i) - { - CreateLocationsHierarchy(children[i], hierarchy, hierarchyParent); - } - - return hierarchy.GetNodeCount() != 0; -} - -bool CMapper::CreateLocationsHierarchy(CHierarchy& hierarchy) -{ - hierarchy.ClearNodes(); - if (!CreateLocationsHierarchy(0, hierarchy, -1)) - { - return false; - } - - hierarchy.ValidateReferences(); - return true; -} - -void CMapper::Map(QuatT* pResult) -{ - uint32 outputCount = m_hierarchy.GetNodeCount(); - std::vector absolutes(outputCount); - for (uint32 i = 0; i < outputCount; ++i) - { - pResult[i].SetIdentity(); - absolutes[i].SetIdentity(); - - CHierarchy::SNode* pNode = m_hierarchy.GetNode(i); - if (!pNode) - { - continue; - } - - CHierarchy::SNode* pParent = pNode->parent < 0 ? - nullptr : m_hierarchy.GetNode(pNode->parent); - if (pParent) - { - pResult[i].t = - (pNode->pose.t - pParent->pose.t) * pParent->pose.q; - } - - if (m_nodes[i].position) - { - pResult[i].t = m_nodes[i].position->Compute().t; - } - - if (m_nodes[i].orientation) - { - absolutes[i] = m_nodes[i].orientation->Compute().q; - } - else if (pParent) - { - Quat relative = pParent->pose.q.GetInverted() * pNode->pose.q; - absolutes[i] = absolutes[pNode->parent] * relative; - } - } - - for (uint32 i = 0; i < outputCount; ++i) - { - CHierarchy::SNode* pNode = m_hierarchy.GetNode(i); - if (!pNode) - { - continue; - } - - CHierarchy::SNode* pParent = pNode->parent < 0 ? - nullptr : m_hierarchy.GetNode(pNode->parent); - if (!pParent) - { - pResult[i].q = absolutes[i]; - continue; - } - - pResult[i].q = absolutes[i]; - if (!m_nodes[i].position) - { - pResult[i].t = pResult[pNode->parent].t + - pResult[i].t * absolutes[pNode->parent].GetInverted(); - } - } -} - -// - -bool CMapper::NodeHasLocation(uint32 index) -{ - if (CMapperOperator* pOperator = m_nodes[index].position) - { - if (pOperator->IsOfClass("Location")) - { - return true; - } - if (pOperator->HasLinksOfClass("Location")) - { - return true; - } - } - - if (CMapperOperator* pOperator = m_nodes[index].orientation) - { - if (pOperator->IsOfClass("Location")) - { - return true; - } - if (pOperator->HasLinksOfClass("Location")) - { - return true; - } - } - - return false; -} - -void CMapper::GetChildrenIndices(uint32 parent, std::vector& children) -{ - uint32 nodeCount = m_hierarchy.GetNodeCount(); - for (uint32 i = 0; i < nodeCount; ++i) - { - if (m_hierarchy.GetNode(i)->parent != parent) - { - continue; - } - - children.push_back(i); - } -} - -bool CMapper::ChildrenHaveLocation(uint32 index) -{ - std::vector children; - GetChildrenIndices(index, children); - - uint32 childrenCount = uint32(children.size()); - for (uint32 i = 0; i < childrenCount; ++i) - { - if (ChildrenHaveLocation(children[i])) - { - return true; - } - } - - return false; -} - -bool CMapper::NodeOrChildrenHaveLocation(uint32 index) -{ - if (NodeHasLocation(index)) - { - return true; - } - - std::vector children; - GetChildrenIndices(index, children); - - uint32 childrenCount = uint32(children.size()); - for (uint32 i = 0; i < childrenCount; ++i) - { - if (NodeOrChildrenHaveLocation(children[i])) - { - return true; - } - } - - return false; -} - -bool CMapper::SerializeTo(XmlNodeRef& node) -{ - XmlNodeRef hierarchy = node->newChild("Hierarchy"); - - uint32 nodeCount = GetNodeCount(); - std::vector nodes(nodeCount); - for (uint32 i = 0; i < nodeCount; ++i) - { - if (!NodeOrChildrenHaveLocation(i)) - { - continue; - } - - CHierarchy::SNode* pNode = m_hierarchy.GetNode(i); - if (!pNode) - { - return false; - } - - XmlNodeRef xmlParent = hierarchy; - int32 parent = pNode->parent; - if (parent > -1) - { - xmlParent = nodes[parent]; - } - - nodes[i] = xmlParent->newChild("Node"); - nodes[i]->setAttr("name", pNode->name); - - if (CMapperOperator* pOperator = m_nodes[i].position) - { - XmlNodeRef position = nodes[i]->newChild("Position"); - XmlNodeRef child = position->newChild("Operator"); - if (!pOperator->SerializeWithLinksTo(child)) - { - return false; - } - } - - if (CMapperOperator* pOperator = m_nodes[i].orientation) - { - XmlNodeRef orientation = nodes[i]->newChild("Orientation"); - XmlNodeRef child = orientation->newChild("Operator"); - if (!pOperator->SerializeWithLinksTo(child)) - { - return false; - } - } - } - - return true; -} - -bool CMapper::SerializeFrom(XmlNodeRef& node, int32 parent) -{ - int childCount = uint32(node->getChildCount()); - for (int i = 0; i < childCount; ++i) - { - XmlNodeRef child = node->getChild(i); - if (::_stricmp(child->getTag(), "Node")) - { - continue; - } - - uint32 index = m_hierarchy.AddNode(child->getAttr("name"), QuatT(IDENTITY), parent); - if (!SerializeFrom(child, int32(index))) - { - return false; - } - } - - return true; -} - -bool CMapper::SerializeFrom(XmlNodeRef& node) -{ - XmlNodeRef hierarchy = node->findChild("Hierarchy"); - if (!hierarchy) - { - return false; - } - - m_hierarchy.ClearNodes(); - - if (!SerializeFrom(hierarchy, -1)) - { - return false; - } - - m_nodes.resize(m_hierarchy.GetNodeCount()); - - return true; -} diff --git a/Code/Editor/Animation/SkeletonMapper.h b/Code/Editor/Animation/SkeletonMapper.h deleted file mode 100644 index 159b019396..0000000000 --- a/Code/Editor/Animation/SkeletonMapper.h +++ /dev/null @@ -1,76 +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 CRYINCLUDE_EDITOR_ANIMATION_SKELETONMAPPER_H -#define CRYINCLUDE_EDITOR_ANIMATION_SKELETONMAPPER_H -#pragma once - - -#include "SkeletonHierarchy.h" -#include "SkeletonMapperOperator.h" - -namespace Skeleton { - class CMapper - { - public: - struct SNode - { - _smart_ptr position; - _smart_ptr orientation; - }; - - public: - CMapper(); - ~CMapper(); - - public: - CHierarchy& GetHierarchy() { return m_hierarchy; } - void CreateFromHierarchy(); - - uint32 GetNodeCount() const { return uint32(m_nodes.size()); } - SNode* GetNode(uint32 index) { return &m_nodes[index]; } - const SNode* GetNode(uint32 index) const { return &m_nodes[index]; } - - uint32 CreateLocation(const char* name); - void ClearLocations(); - int32 FindLocation(const char* name) const; - - uint32 GetLocationCount() const { return uint32(m_locations.size()); } - void SetLocation(CMapperLocation& location); - CMapperLocation* GetLocation(uint32 index) { return m_locations[index]; } - const CMapperLocation* GetLocation(uint32 index) const { return m_locations[index]; } - - bool CreateLocationsHierarchy(CHierarchy& hierarchy); - - void Map(QuatT* pResult); - - bool SerializeTo(XmlNodeRef& node); - bool SerializeFrom(XmlNodeRef& node); - - private: - bool NodeHasLocation(uint32 index); - bool ChildrenHaveLocation(uint32 index); - bool NodeOrChildrenHaveLocation(uint32 index); - - bool SerializeFrom(XmlNodeRef& node, int32 parent); - - bool CreateLocationsHierarchy(uint32 index, CHierarchy& hierarchy, int32 hierarchyParent = -1); - - // TEMP - void GetChildrenIndices(uint32 parent, std::vector& children); - - private: - CHierarchy m_hierarchy; - std::vector<_smart_ptr > m_locations; - - std::vector m_nodes; - }; -} // namespace Skeleton - -#endif // CRYINCLUDE_EDITOR_ANIMATION_SKELETONMAPPER_H diff --git a/Code/Editor/Animation/SkeletonMapperOperator.cpp b/Code/Editor/Animation/SkeletonMapperOperator.cpp deleted file mode 100644 index cc53957115..0000000000 --- a/Code/Editor/Animation/SkeletonMapperOperator.cpp +++ /dev/null @@ -1,284 +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 "EditorDefs.h" - -#include "SkeletonMapperOperator.h" - -using namespace Skeleton; - -/* - - CMapperOperatorDesc - -*/ - -std::vector CMapperOperatorDesc::s_descs; - -// - -CMapperOperatorDesc::CMapperOperatorDesc(const char* name) -{ - s_descs.push_back(this); -} - -/* - - CMapperOperator - -*/ - -CMapperOperator::CMapperOperator(const char* className, uint32 positionCount, uint32 orientationCount) -{ - m_className = className; - m_position.resize(positionCount, nullptr); - m_orientation.resize(orientationCount, nullptr); -} - -CMapperOperator::~CMapperOperator() -{ -} - -// - -bool CMapperOperator::IsOfClass(const char* className) -{ - if (::_stricmp(m_className, className)) - { - return false; - } - - return true; -} - -uint32 CMapperOperator::HasLinksOfClass(const char* className) -{ - uint32 count = 0; - - uint32 positionCount = m_position.size(); - for (uint32 i = 0; i < positionCount; ++i) - { - CMapperOperator* pOperator = m_position[i]; - if (!pOperator) - { - continue; - } - - if (pOperator->IsOfClass(className)) - { - ++count; - } - } - - uint32 orientationCount = m_orientation.size(); - for (uint32 i = 0; i < orientationCount; ++i) - { - CMapperOperator* pOperator = m_orientation[i]; - if (!pOperator) - { - continue; - } - - if (pOperator->IsOfClass(className)) - { - ++count; - } - } - - return count; -} - -// - -bool CMapperOperator::SerializeTo(XmlNodeRef& node) -{ - node->setAttr("class", m_className); - - uint32 parameterCount = uint32(m_parameters.size()); - for (uint32 i = 0; i < parameterCount; ++i) - { - m_parameters[i]->Serialize(node, false); - } - - return true; -} - -bool CMapperOperator::SerializeFrom(XmlNodeRef& node) -{ - uint32 parameterCount = uint32(m_parameters.size()); - for (uint32 i = 0; i < parameterCount; ++i) - { - m_parameters[i]->Serialize(node, true); - } - - return true; -} - -bool CMapperOperator::SerializeWithLinksTo(XmlNodeRef& node) -{ - if (!SerializeTo(node)) - { - return false; - } - - uint32 positionCount = uint32(m_position.size()); - for (uint32 i = 0; i < positionCount; ++i) - { - CMapperOperator* pOperator = m_position[i]; - if (!pOperator) - { - continue; - } - - XmlNodeRef position = node->newChild("Position"); - position->setAttr("index", i); - - XmlNodeRef child = position->newChild("Operator"); - if (!pOperator->SerializeWithLinksTo(child)) - { - return false; - } - } - - uint32 orientationCount = uint32(m_orientation.size()); - for (uint32 i = 0; i < orientationCount; ++i) - { - CMapperOperator* pOperator = m_orientation[i]; - if (!pOperator) - { - continue; - } - - XmlNodeRef orientation = node->newChild("Orientation"); - orientation->setAttr("index", i); - - XmlNodeRef child = orientation->newChild("Operator"); - if (!pOperator->SerializeWithLinksTo(child)) - { - return false; - } - } - - return true; -} - -bool CMapperOperator::SerializeWithLinksFrom(XmlNodeRef& node) -{ - if (!SerializeFrom(node)) - { - return false; - } - - return true; -} -/* - - CMapperOperator_Transform - -*/ - -class CMapperOperator_Transform - : public CMapperOperator -{ -public: - CMapperOperator_Transform() - : CMapperOperator("Transform", 1, 1) - { - m_pAngles = new CVariable(); - m_pAngles->SetName("rotation"); - m_pAngles->Set(Vec3(0.0f, 0.0f, 0.0f)); - m_pAngles->SetLimits(-180.0f, 180.0f); - AddParameter(*m_pAngles); - - m_pVector = new CVariable(); - m_pVector->SetName("vector"); - m_pVector->Set(Vec3(0.0f, 0.0f, 0.0f)); - AddParameter(*m_pVector); - - m_pScale = new CVariable(); - m_pScale->SetName("scale"); - m_pScale->Set(Vec3(1.0f, 1.0f, 1.0f)); - AddParameter(*m_pScale); - } - - // CMapperOperator -public: - virtual QuatT CMapperOperator_Transform::Compute() - { - QuatT result(IDENTITY); - m_pVector->Get(result.t); - - Vec3 scale; - m_pScale->Get(scale); - - Vec3 angles; - m_pAngles->Get(angles); - - result.q = Quat::CreateRotationXYZ( - Ang3(DEG2RAD(angles.x), DEG2RAD(angles.y), DEG2RAD(angles.z))); - - if (CMapperOperator* pOperator = GetPosition(0)) - { - result.t = pOperator->Compute().t.CompMul(scale) + result.t; - } - if (CMapperOperator* pOperator = GetOrientation(0)) - { - result.q = pOperator->Compute().q * result.q; - } - return result; - } - -private: - CVariable* m_pVector; - CVariable* m_pAngles; - CVariable* m_pScale; -}; - -SkeletonMapperOperatorRegister(Transform, CMapperOperator_Transform) - -class CMapperOperator_PositionsToOrientation - : public CMapperOperator -{ -public: - CMapperOperator_PositionsToOrientation() - : CMapperOperator("PositionsToOrientation", 3, 0) - { - } - - // CMapperOperator -public: - virtual QuatT Compute() - { - CMapperOperator* pOperator0 = GetPosition(0); - CMapperOperator* pOperator1 = GetPosition(1); - CMapperOperator* pOperator2 = GetPosition(2); - if (!pOperator0 || !pOperator1 || !pOperator2) - { - return QuatT(IDENTITY); - } - - Vec3 p0 = pOperator0->Compute().t; - Vec3 p1 = pOperator1->Compute().t; - Vec3 p2 = pOperator2->Compute().t; - - Vec3 m = (p1 + p2) * 0.5f; - Vec3 y = (m - p0).GetNormalized(); - Vec3 z = (p1 - p2).GetNormalized(); - Vec3 x = y % z; - z = x % y; - - Matrix33 m33; - m33.SetFromVectors(x, y, z); - QuatT result(IDENTITY); - result.q = Quat(m33); - return result; - } -}; - -SkeletonMapperOperatorRegister(PositionsToOrientation, CMapperOperator_PositionsToOrientation) diff --git a/Code/Editor/Animation/SkeletonMapperOperator.h b/Code/Editor/Animation/SkeletonMapperOperator.h deleted file mode 100644 index 68bbb84ac7..0000000000 --- a/Code/Editor/Animation/SkeletonMapperOperator.h +++ /dev/null @@ -1,164 +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 CRYINCLUDE_EDITOR_ANIMATION_SKELETONMAPPEROPERATOR_H -#define CRYINCLUDE_EDITOR_ANIMATION_SKELETONMAPPEROPERATOR_H -#pragma once - - -#include "../Util/Variable.h" - -#undef GetClassName - -#define SkeletonMapperOperatorRegister(name, className) \ - class CMapperOperatorDesc_##name \ - : public CMapperOperatorDesc \ - { \ - public: \ - CMapperOperatorDesc_##name() \ - : CMapperOperatorDesc(#name) { } \ - protected: \ - virtual const char* GetName() { return #name; } \ - virtual CMapperOperator* Create() { return new className(); } \ - } mapperOperatorDesc__##name; - -namespace Skeleton { - class CMapperOperator; - - class CMapperOperatorDesc - { - public: - static uint32 GetCount() { return uint32(s_descs.size()); } - static const char* GetName(uint32 index) { return s_descs[index]->GetName(); } - static CMapperOperator* Create(uint32 index) { return s_descs[index]->Create(); } - - private: - static std::vector s_descs; - - public: - CMapperOperatorDesc(const char* name); - - protected: - virtual const char* GetName() = 0; - virtual CMapperOperator* Create() = 0; - }; - - class CMapperOperator - : public _reference_target_t - { - protected: - CMapperOperator(const char* className, uint32 positionCount, uint32 orientationCount); - ~CMapperOperator(); - - public: - const char* GetClassName() { return m_className; } - - uint32 GetPositionCount() const { return uint32(m_position.size()); } - void SetPosition(uint32 index, CMapperOperator* pOperator) { m_position[index] = pOperator; } - CMapperOperator* GetPosition(uint32 index) { return m_position[index]; } - - uint32 GetOrientationCount() const { return uint32(m_orientation.size()); } - void SetOrientation(uint32 index, CMapperOperator* pOperator) { m_orientation[index] = pOperator; } - CMapperOperator* GetOrientation(uint32 index) { return m_orientation[index]; } - - uint32 GetParameterCount() { return uint32(m_parameters.size()); } - IVariable* GetParameter(uint32 index) { return m_parameters[index]; } - - bool IsOfClass(const char* className); - uint32 HasLinksOfClass(const char* className); - - bool SerializeTo(XmlNodeRef& node); - bool SerializeFrom(XmlNodeRef& node); - - bool SerializeWithLinksTo(XmlNodeRef& node); - bool SerializeWithLinksFrom(XmlNodeRef& node); - - protected: - void AddParameter(IVariable& variable) { m_parameters.push_back(&variable); } - - public: - virtual QuatT Compute() = 0; - - private: - const char* m_className; - std::vector<_smart_ptr > m_position; - std::vector<_smart_ptr > m_orientation; - - std::vector m_parameters; - }; - - class CMapperLocation - : public CMapperOperator - { - public: - CMapperLocation() - : CMapperOperator("Location", 0, 0) - { - m_pName = new CVariable(); - m_pName->SetName("name"); - m_pName->SetFlags(m_pName->GetFlags() | IVariable::UI_INVISIBLE); - AddParameter(*m_pName); - - m_pAxis = new CVariable(); - m_pAxis->SetName("axis"); - m_pAxis->SetLimits(-3.0f, +3.0f); - m_pAxis->Set(Vec3(1.0f, 2.0f, 3.0f)); - AddParameter(*m_pAxis); - - m_location = QuatT(IDENTITY); - } - - public: - void SetName(const char* name) { m_pName->Set(name); } - CString GetName() const { CString s; m_pName->Get(s); return s; } - - void SetLocation(const QuatT& location) { m_location = location; } - const QuatT& GetLocation() const { return m_location; } - - // CMapperOperator - public: - virtual QuatT Compute() - { - Vec3 axis; - m_pAxis->Get(axis); - - uint32 x = fabs_tpl(axis.x); - uint32 y = fabs_tpl(axis.y); - uint32 z = fabs_tpl(axis.z); - if (x < 1 || y < 1 || z < 1 || - x > 3 || y > 3 || y > 3 || - x == y || x == z || y == z) - { - return QuatT(IDENTITY); - } - - Matrix33 matrix; - matrix.SetFromVectors( - m_location.q.GetColumn(x - 1) * f32(::sgn(axis.x)), - m_location.q.GetColumn(y - 1) * f32(::sgn(axis.y)), - m_location.q.GetColumn(z - 1) * f32(::sgn(axis.z))); - if (!matrix.IsOrthonormalRH(0.01f)) - { - return QuatT(IDENTITY); - } - - QuatT result = m_location; - result.q = Quat(matrix); - return result; - } - - private: - CVariable* m_pName; - CVariable* m_pAxis; - - QuatT m_location; - }; -} // namespace Skeleton - -#endif // CRYINCLUDE_EDITOR_ANIMATION_SKELETONMAPPEROPERATOR_H diff --git a/Code/Editor/BaseLibrary.cpp b/Code/Editor/BaseLibrary.cpp index 7c920a7f04..9f26630c2c 100644 --- a/Code/Editor/BaseLibrary.cpp +++ b/Code/Editor/BaseLibrary.cpp @@ -258,9 +258,8 @@ bool CBaseLibrary::SaveLibrary(const char* name, bool saveEmptyLibrary) } if (!bRes) { - string strMessage; QByteArray filenameUtf8 = fileName.toUtf8(); - strMessage.Format("The file %s is read-only and the save of the library couldn't be performed. Try to remove the \"read-only\" flag or check-out the file and then try again.", filenameUtf8.data()); + AZStd::string strMessage = AZStd::string::format("The file %s is read-only and the save of the library couldn't be performed. Try to remove the \"read-only\" flag or check-out the file and then try again.", filenameUtf8.data()); CryMessageBox(strMessage.c_str(), "Saving Error", MB_OK | MB_ICONWARNING); } return bRes; diff --git a/Code/Editor/BaseLibraryManager.cpp b/Code/Editor/BaseLibraryManager.cpp index 6dd7dc58a5..7346ffaf8c 100644 --- a/Code/Editor/BaseLibraryManager.cpp +++ b/Code/Editor/BaseLibraryManager.cpp @@ -526,7 +526,7 @@ void CBaseLibraryManager::Serialize(XmlNodeRef& node, bool bLoading) QString CBaseLibraryManager::MakeUniqueItemName(const QString& srcName, const QString& libName) { // unlikely we'll ever encounter more than 16 - std::vector possibleDuplicates; + std::vector possibleDuplicates; possibleDuplicates.reserve(16); // search for strings in the database that might have a similar name (ignore case) @@ -550,7 +550,7 @@ QString CBaseLibraryManager::MakeUniqueItemName(const QString& srcName, const QS const QString& name = pItem->GetName(); if (name.startsWith(srcName, Qt::CaseInsensitive)) { - possibleDuplicates.push_back(string(name.toUtf8().data())); + possibleDuplicates.push_back(AZStd::string(name.toUtf8().data())); } } pEnum->Release(); @@ -560,7 +560,7 @@ QString CBaseLibraryManager::MakeUniqueItemName(const QString& srcName, const QS return srcName; } - std::sort(possibleDuplicates.begin(), possibleDuplicates.end(), [](const string& strOne, const string& strTwo) + std::sort(possibleDuplicates.begin(), possibleDuplicates.end(), [](const AZStd::string& strOne, const AZStd::string& strTwo) { // I can assume size sorting since if the length is different, either one of the two strings doesn't // closely match the string we are trying to duplicate, or it's a bigger number (X1 vs X10) diff --git a/Code/Editor/Commands/CommandManager.cpp b/Code/Editor/Commands/CommandManager.cpp index 0712e35e79..f28ca96ac8 100644 --- a/Code/Editor/Commands/CommandManager.cpp +++ b/Code/Editor/Commands/CommandManager.cpp @@ -79,9 +79,9 @@ CEditorCommandManager::~CEditorCommandManager() m_uiCommands.clear(); } -string CEditorCommandManager::GetFullCommandName(const string& module, const string& name) +AZStd::string CEditorCommandManager::GetFullCommandName(const AZStd::string& module, const AZStd::string& name) { - string fullName = module; + AZStd::string fullName = module; fullName += "."; fullName += name; return fullName; @@ -91,10 +91,10 @@ bool CEditorCommandManager::AddCommand(CCommand* pCommand, TPfnDeleter deleter) { assert(pCommand); - string module = pCommand->GetModule(); - string name = pCommand->GetName(); + AZStd::string module = pCommand->GetModule(); + AZStd::string name = pCommand->GetName(); - if (IsRegistered(module, name) && m_bWarnDuplicate) + if (IsRegistered(module.c_str(), name.c_str()) && m_bWarnDuplicate) { QString errMsg; @@ -118,7 +118,7 @@ bool CEditorCommandManager::AddCommand(CCommand* pCommand, TPfnDeleter deleter) bool CEditorCommandManager::UnregisterCommand(const char* module, const char* name) { - string fullName = GetFullCommandName(module, name); + AZStd::string fullName = GetFullCommandName(module, name); CommandTable::iterator itr = m_commands.find(fullName); if (itr != m_commands.end()) @@ -154,7 +154,7 @@ bool CEditorCommandManager::RegisterUICommand( return false; } - return AttachUIInfo(GetFullCommandName(module, name), uiInfo); + return AttachUIInfo(GetFullCommandName(module, name).c_str(), uiInfo); } bool CEditorCommandManager::AttachUIInfo(const char* fullCmdName, const CCommand0::SUIInfo& uiInfo) @@ -190,14 +190,14 @@ bool CEditorCommandManager::AttachUIInfo(const char* fullCmdName, const CCommand return true; } -bool CEditorCommandManager::GetUIInfo(const string& module, const string& name, CCommand0::SUIInfo& uiInfo) const +bool CEditorCommandManager::GetUIInfo(const AZStd::string& module, const AZStd::string& name, CCommand0::SUIInfo& uiInfo) const { - string fullName = GetFullCommandName(module, name); + AZStd::string fullName = GetFullCommandName(module, name); return GetUIInfo(fullName, uiInfo); } -bool CEditorCommandManager::GetUIInfo(const string& fullCmdName, CCommand0::SUIInfo& uiInfo) const +bool CEditorCommandManager::GetUIInfo(const AZStd::string& fullCmdName, CCommand0::SUIInfo& uiInfo) const { CommandTable::const_iterator iter = m_commands.find(fullCmdName); @@ -223,9 +223,9 @@ int CEditorCommandManager::GenNewCommandId() return uniqueId++; } -QString CEditorCommandManager::Execute(const string& module, const string& name, const CCommand::CArgs& args) +QString CEditorCommandManager::Execute(const AZStd::string& module, const AZStd::string& name, const CCommand::CArgs& args) { - string fullName = GetFullCommandName(module, name); + AZStd::string fullName = GetFullCommandName(module, name); CommandTable::iterator iter = m_commands.find(fullName); if (iter != m_commands.end()) @@ -245,18 +245,18 @@ QString CEditorCommandManager::Execute(const string& module, const string& name, return ""; } -QString CEditorCommandManager::Execute(const string& cmdLine) +QString CEditorCommandManager::Execute(const AZStd::string& cmdLine) { - string cmdTxt, argsTxt; + AZStd::string cmdTxt, argsTxt; size_t argStart = cmdLine.find_first_of(' '); cmdTxt = cmdLine.substr(0, argStart); argsTxt = ""; - if (argStart != string::npos) + if (argStart != AZStd::string::npos) { argsTxt = cmdLine.substr(argStart + 1); - argsTxt.Trim(); + AZ::StringFunc::TrimWhiteSpace(argsTxt, true, true); } CommandTable::iterator itr = m_commands.find(cmdTxt); @@ -301,7 +301,7 @@ void CEditorCommandManager::Execute(int commandId) } } -void CEditorCommandManager::GetCommandList(std::vector& cmds) const +void CEditorCommandManager::GetCommandList(std::vector& cmds) const { cmds.clear(); cmds.reserve(m_commands.size()); @@ -315,9 +315,9 @@ void CEditorCommandManager::GetCommandList(std::vector& cmds) const std::sort(cmds.begin(), cmds.end()); } -string CEditorCommandManager::AutoComplete(const string& substr) const +AZStd::string CEditorCommandManager::AutoComplete(const AZStd::string& substr) const { - std::vector cmds; + std::vector cmds; GetCommandList(cmds); // If substring is empty return first command. @@ -358,7 +358,7 @@ string CEditorCommandManager::AutoComplete(const string& substr) const bool CEditorCommandManager::IsRegistered(const char* module, const char* name) const { - string fullName = GetFullCommandName(module, name); + AZStd::string fullName = GetFullCommandName(module, name); CommandTable::const_iterator iter = m_commands.find(fullName); if (iter != m_commands.end()) @@ -373,7 +373,7 @@ bool CEditorCommandManager::IsRegistered(const char* module, const char* name) c bool CEditorCommandManager::IsRegistered(const char* cmdLine_) const { - string cmdTxt, argsTxt, cmdLine(cmdLine_); + AZStd::string cmdTxt, argsTxt, cmdLine(cmdLine_); size_t argStart = cmdLine.find_first_of(' '); cmdTxt = cmdLine.substr(0, argStart); CommandTable::const_iterator iter = m_commands.find(cmdTxt); @@ -402,9 +402,9 @@ bool CEditorCommandManager::IsRegistered(int commandId) const return false; } -void CEditorCommandManager::SetCommandAvailableInScripting(const string& module, const string& name) +void CEditorCommandManager::SetCommandAvailableInScripting(const AZStd::string& module, const AZStd::string& name) { - string fullName = GetFullCommandName(module, name); + AZStd::string fullName = GetFullCommandName(module, name); CommandTable::iterator iter = m_commands.find(fullName); if (iter != m_commands.end()) @@ -413,7 +413,7 @@ void CEditorCommandManager::SetCommandAvailableInScripting(const string& module, } } -bool CEditorCommandManager::IsCommandAvailableInScripting(const string& fullCmdName) const +bool CEditorCommandManager::IsCommandAvailableInScripting(const AZStd::string& fullCmdName) const { CommandTable::const_iterator iter = m_commands.find(fullCmdName); @@ -425,16 +425,16 @@ bool CEditorCommandManager::IsCommandAvailableInScripting(const string& fullCmdN return false; } -bool CEditorCommandManager::IsCommandAvailableInScripting(const string& module, const string& name) const +bool CEditorCommandManager::IsCommandAvailableInScripting(const AZStd::string& module, const AZStd::string& name) const { - string fullName = GetFullCommandName(module, name); + AZStd::string fullName = GetFullCommandName(module, name); return IsCommandAvailableInScripting(fullName); } -void CEditorCommandManager::LogCommand(const string& fullCmdName, const CCommand::CArgs& args) const +void CEditorCommandManager::LogCommand(const AZStd::string& fullCmdName, const CCommand::CArgs& args) const { - string cmdLine = fullCmdName; + AZStd::string cmdLine = fullCmdName; for (int i = 0; i < args.GetArgCount(); ++i) { @@ -509,7 +509,7 @@ void CEditorCommandManager::LogCommand(const string& fullCmdName, const CCommand if (pScriptTermDialog) { - string text = "> "; + AZStd::string text = "> "; text += cmdLine; text += "\r\n"; pScriptTermDialog->AppendText(text.c_str()); @@ -526,14 +526,14 @@ QString CEditorCommandManager::ExecuteAndLogReturn(CCommand* pCommand, const CCo return result; } -void CEditorCommandManager::GetArgsFromString(const string& argsTxt, CCommand::CArgs& argList) +void CEditorCommandManager::GetArgsFromString(const AZStd::string& argsTxt, CCommand::CArgs& argList) { const char quoteSymbol = '\''; int curPos = 0; int prevPos = 0; - string arg = argsTxt.Tokenize(" ", curPos); - - while (!arg.empty()) + AZStd::vector tokens; + AZ::StringFunc::Tokenize(argsTxt, tokens, ' '); + for(AZStd::string& arg : tokens) { if (arg[0] == quoteSymbol) // A special consideration for a quoted string { @@ -542,11 +542,11 @@ void CEditorCommandManager::GetArgsFromString(const string& argsTxt, CCommand::C size_t openingQuotePos = argsTxt.find(quoteSymbol, prevPos); size_t closingQuotePos = argsTxt.find(quoteSymbol, curPos); - if (closingQuotePos != string::npos) + if (closingQuotePos != AZStd::string::npos) { arg = argsTxt.substr(openingQuotePos + 1, closingQuotePos - openingQuotePos - 1); size_t nextArgPos = argsTxt.find(' ', closingQuotePos + 1); - curPos = nextArgPos != string::npos ? nextArgPos + 1 : argsTxt.length(); + curPos = nextArgPos != AZStd::string::npos ? nextArgPos + 1 : argsTxt.length(); for (; curPos < argsTxt.length(); ++curPos) // Skip spaces. { @@ -565,6 +565,5 @@ void CEditorCommandManager::GetArgsFromString(const string& argsTxt, CCommand::C argList.Add(arg.c_str()); prevPos = curPos; - arg = argsTxt.Tokenize(" ", curPos); } } diff --git a/Code/Editor/Commands/CommandManager.h b/Code/Editor/Commands/CommandManager.h index 761c79f79c..599754c5d9 100644 --- a/Code/Editor/Commands/CommandManager.h +++ b/Code/Editor/Commands/CommandManager.h @@ -48,20 +48,20 @@ public: const AZStd::function& functor, const CCommand0::SUIInfo& uiInfo); bool AttachUIInfo(const char* fullCmdName, const CCommand0::SUIInfo& uiInfo); - bool GetUIInfo(const string& module, const string& name, CCommand0::SUIInfo& uiInfo) const; - bool GetUIInfo(const string& fullCmdName, CCommand0::SUIInfo& uiInfo) const; - QString Execute(const string& cmdLine); - QString Execute(const string& module, const string& name, const CCommand::CArgs& args); + bool GetUIInfo(const AZStd::string& module, const AZStd::string& name, CCommand0::SUIInfo& uiInfo) const; + bool GetUIInfo(const AZStd::string& fullCmdName, CCommand0::SUIInfo& uiInfo) const; + QString Execute(const AZStd::string& cmdLine); + QString Execute(const AZStd::string& module, const AZStd::string& name, const CCommand::CArgs& args); void Execute(int commandId); - void GetCommandList(std::vector& cmds) const; + void GetCommandList(std::vector& cmds) const; //! Used in the console dialog - string AutoComplete(const string& substr) const; + AZStd::string AutoComplete(const AZStd::string& substr) const; bool IsRegistered(const char* module, const char* name) const; bool IsRegistered(const char* cmdLine) const; bool IsRegistered(int commandId) const; - void SetCommandAvailableInScripting(const string& module, const string& name); - bool IsCommandAvailableInScripting(const string& module, const string& name) const; - bool IsCommandAvailableInScripting(const string& fullCmdName) const; + void SetCommandAvailableInScripting(const AZStd::string& module, const AZStd::string& name); + bool IsCommandAvailableInScripting(const AZStd::string& module, const AZStd::string& name) const; + bool IsCommandAvailableInScripting(const AZStd::string& fullCmdName) const; //! Turning off the warning is needed for reloading the ribbon bar. void TurnDuplicateWarningOn() { m_bWarnDuplicate = true; } void TurnDuplicateWarningOff() { m_bWarnDuplicate = false; } @@ -74,7 +74,7 @@ protected: }; //! A full command name to an actual command mapping - typedef std::map CommandTable; + typedef std::map CommandTable; AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING CommandTable m_commands; @@ -86,9 +86,9 @@ protected: bool m_bWarnDuplicate; static int GenNewCommandId(); - static string GetFullCommandName(const string& module, const string& name); - static void GetArgsFromString(const string& argsTxt, CCommand::CArgs& argList); - void LogCommand(const string& fullCmdName, const CCommand::CArgs& args) const; + static AZStd::string GetFullCommandName(const AZStd::string& module, const AZStd::string& name); + static void GetArgsFromString(const AZStd::string& argsTxt, CCommand::CArgs& argList); + void LogCommand(const AZStd::string& fullCmdName, const CCommand::CArgs& args) const; QString ExecuteAndLogReturn(CCommand* pCommand, const CCommand::CArgs& args); }; diff --git a/Code/Editor/ConfigGroup.cpp b/Code/Editor/ConfigGroup.cpp index c1e0abbf31..b18edf1142 100644 --- a/Code/Editor/ConfigGroup.cpp +++ b/Code/Editor/ConfigGroup.cpp @@ -127,9 +127,9 @@ namespace Config case IConfigVar::eType_STRING: { - string currentValue = nullptr; + AZStd::string currentValue; var->Get(¤tValue); - node->setAttr(szName, currentValue); + node->setAttr(szName, currentValue.c_str()); break; } } @@ -186,7 +186,7 @@ namespace Config case IConfigVar::eType_STRING: { - string currentValue = nullptr; + AZStd::string currentValue; var->GetDefault(¤tValue); QString readValue(currentValue.c_str()); if (node->getAttr(szName, readValue)) diff --git a/Code/Editor/ConfigGroup.h b/Code/Editor/ConfigGroup.h index f772823ad8..769a29ba8a 100644 --- a/Code/Editor/ConfigGroup.h +++ b/Code/Editor/ConfigGroup.h @@ -47,12 +47,12 @@ namespace Config return m_type; } - ILINE const string& GetName() const + ILINE const AZStd::string& GetName() const { return m_name; } - ILINE const string& GetDescription() const + ILINE const AZStd::string& GetDescription() const { return m_description; } @@ -71,13 +71,13 @@ namespace Config static EType TranslateType(const bool&) { return eType_BOOL; } static EType TranslateType(const int&) { return eType_INT; } static EType TranslateType(const float&) { return eType_FLOAT; } - static EType TranslateType(const string&) { return eType_STRING; } + static EType TranslateType(const AZStd::string&) { return eType_STRING; } protected: EType m_type; uint8 m_flags; - string m_name; - string m_description; + AZStd::string m_name; + AZStd::string m_description; void* m_ptr; ICVar* m_pCVar; }; diff --git a/Code/Editor/ControlMRU.cpp b/Code/Editor/ControlMRU.cpp deleted file mode 100644 index a721876624..0000000000 --- a/Code/Editor/ControlMRU.cpp +++ /dev/null @@ -1,135 +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 "EditorDefs.h" -#include "ControlMRU.h" - -IMPLEMENT_XTP_CONTROL(CControlMRU, CXTPControlRecentFileList) - -bool CControlMRU::DoesFileExist(CString& sFileName) -{ - return (_access(sFileName.GetBuffer(), 0) == 0); -} - -void CControlMRU::OnCalcDynamicSize(DWORD dwMode) -{ - CRecentFileList* pRecentFileList = GetRecentFileList(); - - if (!pRecentFileList) - { - return; - } - - CString* pArrNames = pRecentFileList->m_arrNames; - - assert(pArrNames != nullptr); - if (!pArrNames) - { - return; - } - - while (m_nIndex + 1 < m_pControls->GetCount()) - { - CXTPControl* pControl = m_pControls->GetAt(m_nIndex + 1); - assert(pControl); - if (pControl->GetID() >= GetFirstMruID() - && pControl->GetID() <= GetFirstMruID() + pRecentFileList->m_nSize) - { - m_pControls->Remove(pControl); - } - else - { - break; - } - } - - if (m_pParent->IsCustomizeMode()) - { - m_dwHideFlags = 0; - SetEnabled(true); - return; - } - - if (pArrNames[0].IsEmpty()) - { - SetCaption(CString(MAKEINTRESOURCE(IDS_NORECENTFILE_CAPTION))); - SetDescription("No recently opened files"); - m_dwHideFlags = 0; - SetEnabled(false); - - return; - } - else - { - SetCaption(CString(MAKEINTRESOURCE(IDS_RECENTFILE_CAPTION))); - SetDescription("Open this document"); - } - - m_dwHideFlags |= xtpHideGeneric; - - CString sCurDir = (Path::GetEditingGameDataFolder() + "\\").c_str(); - int nCurDir = sCurDir.GetLength(); - - CString strName; - CString strTemp; - int iLastValidMRU = 0; - - for (int iMRU = 0; iMRU < pRecentFileList->m_nSize; iMRU++) - { - if (!pRecentFileList->GetDisplayName(strName, iMRU, sCurDir.GetBuffer(), nCurDir)) - { - break; - } - - if (DoesFileExist(pArrNames[iMRU])) - { - CString sCurEntryDir = pArrNames[iMRU].Left(nCurDir); - - if (sCurEntryDir.CompareNoCase(sCurDir) != 0) - { - //unavailable entry (wrong directory) - continue; - } - } - else - { - //invalid entry (not existing) - continue; - } - - int nId = iMRU + GetFirstMruID(); - - CXTPControl* pControl = m_pControls->Add(xtpControlButton, nId, _T(""), m_nIndex + iLastValidMRU + 1, true); - assert(pControl); - - pControl->SetCaption(CXTPControlWindowList::ConstructCaption(strName, iLastValidMRU + 1)); - pControl->SetFlags(xtpFlagManualUpdate); - pControl->SetBeginGroup(iLastValidMRU == 0 && m_nIndex != 0); - pControl->SetParameter(pArrNames[iMRU]); - - CString sDescription = "Open file: " + pArrNames[iMRU]; - pControl->SetDescription(sDescription); - - if ((GetFlags() & xtpFlagWrapRow) && iMRU == 0) - { - pControl->SetFlags(pControl->GetFlags() | xtpFlagWrapRow); - } - - ++iLastValidMRU; - } - - //if no entry was valid, treat as none would exist - if (iLastValidMRU == 0) - { - SetCaption(CString(MAKEINTRESOURCE(IDS_NORECENTFILE_CAPTION))); - SetDescription("No recently opened files"); - m_dwHideFlags = 0; - SetEnabled(false); - } -} diff --git a/Code/Editor/ControlMRU.h b/Code/Editor/ControlMRU.h deleted file mode 100644 index 4ca6562589..0000000000 --- a/Code/Editor/ControlMRU.h +++ /dev/null @@ -1,24 +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 - * - */ - - -#pragma once -#ifndef CRYINCLUDE_EDITOR_CONTROLMRU_H -#define CRYINCLUDE_EDITOR_CONTROLMRU_H - -class CControlMRU - : public CXTPControlRecentFileList -{ -protected: - virtual void OnCalcDynamicSize(DWORD dwMode); - -private: - DECLARE_XTP_CONTROL(CControlMRU) - bool DoesFileExist(CString& sFileName); -}; -#endif // CRYINCLUDE_EDITOR_CONTROLMRU_H diff --git a/Code/Editor/Controls/ConsoleSCB.cpp b/Code/Editor/Controls/ConsoleSCB.cpp index 7f018e0286..093575d445 100644 --- a/Code/Editor/Controls/ConsoleSCB.cpp +++ b/Code/Editor/Controls/ConsoleSCB.cpp @@ -180,7 +180,7 @@ bool ConsoleLineEdit::event(QEvent* ev) if (newStr.isEmpty()) { - newStr = GetIEditor()->GetCommandManager()->AutoComplete(cstring.toUtf8().data()); + newStr = GetIEditor()->GetCommandManager()->AutoComplete(cstring.toUtf8().data()).c_str(); } } @@ -211,7 +211,7 @@ void ConsoleLineEdit::keyPressEvent(QKeyEvent* ev) { if (commandManager->IsRegistered(str.toUtf8().data())) { - commandManager->Execute(QtUtil::ToString(str)); + commandManager->Execute(str.toUtf8().data()); } else { @@ -566,15 +566,15 @@ static void OnVariableUpdated([[maybe_unused]] int row, ICVar* pCVar) static CVarBlock* VarBlockFromConsoleVars() { IConsole* console = GetIEditor()->GetSystem()->GetIConsole(); - std::vector cmds; + AZStd::vector cmds; cmds.resize(console->GetNumVars()); - size_t cmdCount = console->GetSortedVars(&cmds[0], cmds.size()); + size_t cmdCount = console->GetSortedVars(cmds); CVarBlock* vb = new CVarBlock; IVariable* pVariable = nullptr; for (int i = 0; i < cmdCount; i++) { - ICVar* pCVar = console->GetCVar(cmds[i]); + ICVar* pCVar = console->GetCVar(cmds[i].data()); if (!pCVar) { continue; @@ -606,7 +606,7 @@ static CVarBlock* VarBlockFromConsoleVars() pCVar->AddOnChangeFunctor(onChange); pVariable->SetDescription(pCVar->GetHelp()); - pVariable->SetName(cmds[i]); + pVariable->SetName(cmds[i].data()); // Transfer the custom limits have they have been set for this variable if (pCVar->HasCustomLimits()) diff --git a/Code/Editor/Controls/ConsoleSCBMFC.cpp b/Code/Editor/Controls/ConsoleSCBMFC.cpp deleted file mode 100644 index 3337997811..0000000000 --- a/Code/Editor/Controls/ConsoleSCBMFC.cpp +++ /dev/null @@ -1,543 +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 "EditorDefs.h" -#include "ConsoleSCBMFC.h" -#include "PropertiesDialog.h" -#include "QtViewPaneManager.h" -#include "Core/QtEditorApplication.h" - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace MFC -{ - -static CPropertiesDialog* gPropertiesDlg = nullptr; -static CString mfc_popup_helper(HWND hwnd, int x, int y); -static CConsoleSCB* s_consoleSCB = nullptr; - -static QString RemoveColorCode(const QString& text, int& iColorCode) -{ - QString cleanString; - cleanString.reserve(text.size()); - - const int textSize = text.size(); - for (int i = 0; i < textSize; ++i) - { - QChar c = text.at(i); - bool isLast = i == textSize - 1; - if (c == '$' && !isLast && text.at(i + 1).isDigit()) - { - if (iColorCode == 0) - { - iColorCode = text.at(i + 1).digitValue(); - } - ++i; - continue; - } - - if (c == '\r' || c == '\n') - { - ++i; - continue; - } - - cleanString.append(c); - } - - return cleanString; -} - -ConsoleLineEdit::ConsoleLineEdit(QWidget* parent) - : QLineEdit(parent) - , m_historyIndex(0) - , m_bReusedHistory(false) -{ -} - -void ConsoleLineEdit::mousePressEvent(QMouseEvent* ev) -{ - if (ev->type() == QEvent::MouseButtonPress && ev->button() & Qt::RightButton) - { - Q_EMIT variableEditorRequested(); - } - - QLineEdit::mousePressEvent(ev); -} - -void ConsoleLineEdit::mouseDoubleClickEvent(QMouseEvent* ev) -{ - Q_EMIT variableEditorRequested(); -} - -bool ConsoleLineEdit::event(QEvent* ev) -{ - // Tab key doesn't go to keyPressEvent(), must be processed here - - if (ev->type() != QEvent::KeyPress) - { - return QLineEdit::event(ev); - } - - QKeyEvent* ke = static_cast(ev); - if (ke->key() != Qt::Key_Tab) - { - return QLineEdit::event(ev); - } - - QString inputStr = text(); - QString newStr; - - QStringList tokens = inputStr.split(" "); - inputStr = tokens.isEmpty() ? QString() : tokens.first(); - IConsole* console = GetIEditor()->GetSystem()->GetIConsole(); - - const bool ctrlPressed = ke->modifiers() & Qt::ControlModifier; - CString cstring = QtUtil::ToCString(inputStr); // TODO: Use QString once the backend stops using QString - if (ctrlPressed) - { - newStr = QtUtil::ToString(console->AutoCompletePrev(cstring)); - } - else - { - newStr = QtUtil::ToString(console->ProcessCompletion(cstring)); - newStr = QtUtil::ToString(console->AutoComplete(cstring)); - - if (newStr.isEmpty()) - { - newStr = QtUtil::ToQString(GetIEditor()->GetCommandManager()->AutoComplete(QtUtil::ToString(newStr))); - } - } - - if (!newStr.isEmpty()) - { - newStr += " "; - setText(newStr); - } - - deselect(); - return true; -} - -void ConsoleLineEdit::keyPressEvent(QKeyEvent* ev) -{ - IConsole* console = GetIEditor()->GetSystem()->GetIConsole(); - auto commandManager = GetIEditor()->GetCommandManager(); - - console->ResetAutoCompletion(); - - switch (ev->key()) - { - case Qt::Key_Enter: - case Qt::Key_Return: - { - QString str = text().trimmed(); - if (!str.isEmpty()) - { - if (commandManager->IsRegistered(QtUtil::ToCString(str))) - { - commandManager->Execute(QtUtil::ToString(str)); - } - else - { - CLogFile::WriteLine(QtUtil::ToCString(str)); - GetIEditor()->GetSystem()->GetIConsole()->ExecuteString(QtUtil::ToCString(str)); - } - - // If a history command was reused directly via up arrow enter, do not reset history index - if (m_history.size() > 0 && m_historyIndex < m_history.size() && m_history[m_historyIndex] == str) - { - m_bReusedHistory = true; - } - else - { - m_historyIndex = m_history.size(); - } - - // Do not add the same string if it is the top of the stack, but allow duplicate entries otherwise - if (m_history.isEmpty() || m_history.back() != str) - { - m_history.push_back(str); - if (!m_bReusedHistory) - { - m_historyIndex = m_history.size(); - } - } - } - else - { - m_historyIndex = m_history.size(); - } - - setText(QString()); - break; - } - case Qt::Key_AsciiTilde: // ~ - case Qt::Key_Agrave: // ` - // disable log. - GetIEditor()->ShowConsole(false); - setText(QString()); - m_historyIndex = m_history.size(); - break; - case Qt::Key_Escape: - setText(QString()); - m_historyIndex = m_history.size(); - break; - case Qt::Key_Up: - DisplayHistory(false /*bForward*/); - break; - case Qt::Key_Down: - DisplayHistory(true /*bForward*/); - break; - default: - QLineEdit::keyPressEvent(ev); - } -} - -void ConsoleLineEdit::DisplayHistory(bool bForward) -{ - if (m_history.isEmpty()) - { - return; - } - - // Immediately after reusing a history entry, ensure up arrow re-displays command just used - if (!m_bReusedHistory || bForward) - { - m_historyIndex = static_cast(clamp_tpl(static_cast(m_historyIndex) + (bForward ? 1 : -1), 0, m_history.size() - 1)); - } - m_bReusedHistory = false; - - setText(m_history[m_historyIndex]); -} - -ConsoleTextEdit::ConsoleTextEdit(QWidget* parent) - : QTextEdit(parent) -{ -} - - -Lines CConsoleSCB::s_pendingLines; - -CConsoleSCB::CConsoleSCB(QWidget* parent) - : QWidget(parent) - , ui(new Ui::ConsoleMFC()) - , m_richEditTextLength(0) - , m_backgroundTheme(gSettings.consoleBackgroundColorTheme) -{ - m_lines = s_pendingLines; - s_pendingLines.clear(); - s_consoleSCB = this; - ui->setupUi(this); - setMinimumHeight(120); - - // Setup the color table for the default (light) theme - m_colorTable << QColor(0, 0, 0) - << QColor(0, 0, 0) - << QColor(0, 0, 200) // blue - << QColor(0, 200, 0) // green - << QColor(200, 0, 0) // red - << QColor(0, 200, 200) // cyan - << QColor(128, 112, 0) // yellow - << QColor(200, 0, 200) // red+blue - << QColor(0x000080ff) - << QColor(0x008f8f8f); - OnStyleSettingsChanged(); - - connect(ui->button, &QPushButton::clicked, this, &CConsoleSCB::showVariableEditor); - connect(ui->lineEdit, &MFC::ConsoleLineEdit::variableEditorRequested, this, &MFC::CConsoleSCB::showVariableEditor); - connect(Editor::EditorQtApplication::instance(), &Editor::EditorQtApplication::skinChanged, this, &MFC::CConsoleSCB::OnStyleSettingsChanged); - - if (GetIEditor()->IsInConsolewMode()) - { - // Attach / register edit box - //CLogFile::AttachEditBox(m_edit.GetSafeHwnd()); // FIXME - } -} - -CConsoleSCB::~CConsoleSCB() -{ - s_consoleSCB = nullptr; - delete gPropertiesDlg; - gPropertiesDlg = nullptr; - CLogFile::AttachEditBox(nullptr); -} - -void CConsoleSCB::RegisterViewClass() -{ - QtViewOptions opts; - opts.preferedDockingArea = Qt::BottomDockWidgetArea; - opts.isDeletable = false; - opts.isStandard = true; - opts.showInMenu = true; - opts.builtInActionId = ID_VIEW_CONSOLEWINDOW; - opts.sendViewPaneNameBackToAmazonAnalyticsServers = true; - RegisterQtViewPane(GetIEditor(), LyViewPane::Console, LyViewPane::CategoryTools, opts); -} - -void CConsoleSCB::OnStyleSettingsChanged() -{ - ui->button->setIcon(QIcon(QString(":/controls/img/cvar_dark.bmp"))); - - // Set the debug/warning text colors appropriately for the background theme - // (e.g. not have black text on black background) - QColor textColor = Qt::black; - m_backgroundTheme = gSettings.consoleBackgroundColorTheme; - if (m_backgroundTheme == SEditorSettings::ConsoleColorTheme::Dark) - { - textColor = Qt::white; - } - m_colorTable[0] = textColor; - m_colorTable[1] = textColor; - - QColor bgColor; - if (!GetIEditor()->IsInConsolewMode() && CConsoleSCB::GetCreatedInstance() && m_backgroundTheme == SEditorSettings::ConsoleColorTheme::Dark) - { - bgColor = Qt::black; - } - else - { - bgColor = Qt::white; - } - - ui->textEdit->setStyleSheet(QString("QTextEdit{ background: %1 }").arg(bgColor.name(QColor::HexRgb))); - - // Clear out the console text when we change our background color since - // some of the previous text colors may not be appropriate for the - // new background color - ui->textEdit->clear(); -} - -void CConsoleSCB::showVariableEditor() -{ - const QPoint cursorPos = QCursor::pos(); - CString str = mfc_popup_helper(0, cursorPos.x(), cursorPos.y()); - if (!str.IsEmpty()) - { - ui->lineEdit->setText(QtUtil::ToQString(str)); - } -} - -void CConsoleSCB::SetInputFocus() -{ - ui->lineEdit->setFocus(); - ui->lineEdit->setText(QString()); -} - -void CConsoleSCB::AddToConsole(const QString& text, bool bNewLine) -{ - m_lines.push_back({ text, bNewLine }); - FlushText(); -} - -void CConsoleSCB::FlushText() -{ - if (m_lines.empty()) - { - return; - } - - // Store our current cursor in case we need to restore it, and check if - // the user has scrolled the text edit away from the bottom - const QTextCursor oldCursor = ui->textEdit->textCursor(); - QScrollBar* scrollBar = ui->textEdit->verticalScrollBar(); - const int oldScrollValue = scrollBar->value(); - bool scrolledOffBottom = oldScrollValue != scrollBar->maximum(); - - ui->textEdit->moveCursor(QTextCursor::End); - QTextCursor textCursor = ui->textEdit->textCursor(); - - while (!m_lines.empty()) - { - ConsoleLine line = m_lines.front(); - m_lines.pop_front(); - - int iColor = 0; - QString text = MFC::RemoveColorCode(line.text, iColor); - if (iColor < 0 || iColor >= m_colorTable.size()) - { - iColor = 0; - } - - if (line.newLine) - { - text = QtUtil::trimRight(text); - text = "\r\n" + text; - } - - QTextCharFormat format; - const QColor color(m_colorTable[iColor]); - format.setForeground(color); - - if (iColor != 0) - { - format.setFontWeight(QFont::Bold); - } - - textCursor.setCharFormat(format); - textCursor.insertText(text); - } - - // If the user has selected some text in the text edit area or has scrolled - // away from the bottom, then restore the previous cursor and keep the scroll - // bar in the same location - if (oldCursor.hasSelection() || scrolledOffBottom) - { - ui->textEdit->setTextCursor(oldCursor); - scrollBar->setValue(oldScrollValue); - } - // Otherwise scroll to the bottom so the latest text can be seen - else - { - scrollBar->setValue(scrollBar->maximum()); - } -} - -QSize CConsoleSCB::minimumSizeHint() const -{ - return QSize(-1, -1); -} - -QSize CConsoleSCB::sizeHint() const -{ - return QSize(100, 100); -} - -/** static */ -void CConsoleSCB::AddToPendingLines(const QString& text, bool bNewLine) -{ - s_pendingLines.push_back({ text, bNewLine }); -} - -static CVarBlock* VarBlockFromConsoleVars() -{ - IConsole* console = GetIEditor()->GetSystem()->GetIConsole(); - std::vector cmds; - cmds.resize(console->GetNumVars()); - size_t cmdCount = console->GetSortedVars(&cmds[0], cmds.size()); - - CVarBlock* vb = new CVarBlock; - IVariable* pVariable = 0; - for (int i = 0; i < cmdCount; i++) - { - ICVar* pCVar = console->GetCVar(cmds[i]); - if (!pCVar) - { - continue; - } - int varType = pCVar->GetType(); - - switch (varType) - { - case CVAR_INT: - pVariable = new CVariable(); - pVariable->Set(pCVar->GetIVal()); - break; - case CVAR_FLOAT: - pVariable = new CVariable(); - pVariable->Set(pCVar->GetFVal()); - break; - case CVAR_STRING: - pVariable = new CVariable(); - pVariable->Set(pCVar->GetString()); - break; - default: - assert(0); - } - - pVariable->SetDescription(pCVar->GetHelp()); - pVariable->SetName(cmds[i]); - - if (pVariable) - { - vb->AddVariable(pVariable); - } - } - return vb; -} - -static void OnConsoleVariableUpdated(IVariable* pVar) -{ - if (!pVar) - { - return; - } - CString varName = pVar->GetName(); - ICVar* pCVar = GetIEditor()->GetSystem()->GetIConsole()->GetCVar(varName); - if (!pCVar) - { - return; - } - if (pVar->GetType() == IVariable::INT) - { - int val; - pVar->Get(val); - pCVar->Set(val); - } - else if (pVar->GetType() == IVariable::FLOAT) - { - float val; - pVar->Get(val); - pCVar->Set(val); - } - else if (pVar->GetType() == IVariable::STRING) - { - CString val; - pVar->Get(val); - pCVar->Set(val); - } -} - -static CString mfc_popup_helper(HWND hwnd, int x, int y) -{ - IConsole* console = GetIEditor()->GetSystem()->GetIConsole(); - - TSmartPtr vb = VarBlockFromConsoleVars(); - XmlNodeRef node; - if (!gPropertiesDlg) - { - gPropertiesDlg = new CPropertiesDialog("Console Variables", node, AfxGetMainWnd(), true); - } - if (!gPropertiesDlg->m_hWnd) - { - gPropertiesDlg->Create(CPropertiesDialog::IDD, AfxGetMainWnd()); - gPropertiesDlg->SetUpdateCallback(AZStd::bind(OnConsoleVariableUpdated, AZStd::placeholders::_1)); - } - gPropertiesDlg->ShowWindow(SW_SHOW); - gPropertiesDlg->BringWindowToTop(); - gPropertiesDlg->GetPropertyCtrl()->AddVarBlock(vb); - - return ""; -} - -CConsoleSCB* CConsoleSCB::GetCreatedInstance() -{ - return s_consoleSCB; -} - -} // namespace MFC - -#include diff --git a/Code/Editor/Controls/FolderTreeCtrl.cpp b/Code/Editor/Controls/FolderTreeCtrl.cpp index 17b6dccac7..b1cbb9414e 100644 --- a/Code/Editor/Controls/FolderTreeCtrl.cpp +++ b/Code/Editor/Controls/FolderTreeCtrl.cpp @@ -400,7 +400,7 @@ void CFolderTreeCtrl::RemoveEmptyFolderItems(const QString& folder) void CFolderTreeCtrl::Edit(const QString& path) { - CFileUtil::EditTextFile(QtUtil::ToString(path), 0, IFileUtil::FILE_TYPE_SCRIPT); + CFileUtil::EditTextFile(path.toUtf8().data(), 0, IFileUtil::FILE_TYPE_SCRIPT); } void CFolderTreeCtrl::ShowInExplorer(const QString& path) diff --git a/Code/Editor/Controls/ReflectedPropertyControl/PropertyGenericCtrl.cpp b/Code/Editor/Controls/ReflectedPropertyControl/PropertyGenericCtrl.cpp index 1916ce5e16..a2c66b8b10 100644 --- a/Code/Editor/Controls/ReflectedPropertyControl/PropertyGenericCtrl.cpp +++ b/Code/Editor/Controls/ReflectedPropertyControl/PropertyGenericCtrl.cpp @@ -132,7 +132,9 @@ void LocalStringPropertyEditor::onEditClicked() if (pMgr->GetLocalizedInfoByIndex(i, sInfo)) { item.desc = tr("English Text:\r\n"); - item.desc += QString::fromWCharArray(Unicode::Convert(sInfo.sUtf8TranslatedText).c_str()); + AZStd::wstring utf8TranslatedTextW; + AZStd::to_wstring(utf8TranslatedTextW, sInfo.sUtf8TranslatedText); + item.desc += QString::fromWCharArray(utf8TranslatedTextW.c_str()); item.name = sInfo.sKey; items.push_back(item); } diff --git a/Code/Editor/Controls/SplineCtrlEx.cpp b/Code/Editor/Controls/SplineCtrlEx.cpp index 36a9d8afef..5977aff105 100644 --- a/Code/Editor/Controls/SplineCtrlEx.cpp +++ b/Code/Editor/Controls/SplineCtrlEx.cpp @@ -127,7 +127,7 @@ private: std::vector keySelectionFlags; _smart_ptr undo; _smart_ptr redo; - string id; + AZStd::string id; ISplineInterpolator* pSpline; }; diff --git a/Code/Editor/Controls/SplineCtrlEx.h b/Code/Editor/Controls/SplineCtrlEx.h index 8592febf88..add4bcb0a9 100644 --- a/Code/Editor/Controls/SplineCtrlEx.h +++ b/Code/Editor/Controls/SplineCtrlEx.h @@ -53,8 +53,8 @@ class QRubberBand; class ISplineSet { public: - virtual ISplineInterpolator* GetSplineFromID(const string& id) = 0; - virtual string GetIDFromSpline(ISplineInterpolator* pSpline) = 0; + virtual ISplineInterpolator* GetSplineFromID(const AZStd::string& id) = 0; + virtual AZStd::string GetIDFromSpline(ISplineInterpolator* pSpline) = 0; virtual int GetSplineCount() const = 0; virtual int GetKeyCountAtTime(float time, float threshold) const = 0; }; diff --git a/Code/Editor/Core/QtEditorApplication.cpp b/Code/Editor/Core/QtEditorApplication.cpp index 0776a96a4d..dd784ce10d 100644 --- a/Code/Editor/Core/QtEditorApplication.cpp +++ b/Code/Editor/Core/QtEditorApplication.cpp @@ -206,11 +206,8 @@ namespace static void LogToDebug([[maybe_unused]] QtMsgType Type, [[maybe_unused]] const QMessageLogContext& Context, const QString& message) { -#if defined(WIN32) || defined(WIN64) - OutputDebugStringW(L"Qt: "); - OutputDebugStringW(reinterpret_cast(message.utf16())); - OutputDebugStringW(L"\n"); -#endif + AZ::Debug::Platform::OutputToDebugger("Qt", message.toUtf8().data()); + AZ::Debug::Platform::OutputToDebugger(nullptr, "\n"); } } diff --git a/Code/Editor/Core/Tests/test_Main.cpp b/Code/Editor/Core/Tests/test_Main.cpp index 6acedb6e57..3d3e286f18 100644 --- a/Code/Editor/Core/Tests/test_Main.cpp +++ b/Code/Editor/Core/Tests/test_Main.cpp @@ -52,7 +52,7 @@ protected: } private: - AZ::AllocatorScope m_allocatorScope; + AZ::AllocatorScope m_allocatorScope; SSystemGlobalEnvironment m_stubEnv; AZ::IO::LocalFileIO m_fileIO; NiceMock* m_cryPak; diff --git a/Code/Editor/CryEdit.cpp b/Code/Editor/CryEdit.cpp index 8cede89f8a..9f37830e6f 100644 --- a/Code/Editor/CryEdit.cpp +++ b/Code/Editor/CryEdit.cpp @@ -286,7 +286,7 @@ bool CCryDocManager::DoPromptFileName(QString& fileName, [[maybe_unused]] UINT n return false; } -CCryEditDoc* CCryDocManager::OpenDocumentFile(LPCTSTR lpszFileName, bool bAddToMRU) +CCryEditDoc* CCryDocManager::OpenDocumentFile(const char* lpszFileName, bool bAddToMRU) { assert(lpszFileName != nullptr); @@ -801,12 +801,12 @@ void CCryEditApp::InitDirectory() // Needed to work with custom memory manager. ////////////////////////////////////////////////////////////////////////// -CCryEditDoc* CCrySingleDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName, bool bMakeVisible /*= true*/) +CCryEditDoc* CCrySingleDocTemplate::OpenDocumentFile(const char* lpszPathName, bool bMakeVisible /*= true*/) { return OpenDocumentFile(lpszPathName, true, bMakeVisible); } -CCryEditDoc* CCrySingleDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName, bool bAddToMRU, [[maybe_unused]] bool bMakeVisible) +CCryEditDoc* CCrySingleDocTemplate::OpenDocumentFile(const char* lpszPathName, bool bAddToMRU, [[maybe_unused]] bool bMakeVisible) { CCryEditDoc* pCurDoc = GetIEditor()->GetDocument(); @@ -845,7 +845,7 @@ CCryEditDoc* CCrySingleDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName, bool return pCurDoc; } -CCrySingleDocTemplate::Confidence CCrySingleDocTemplate::MatchDocType(LPCTSTR lpszPathName, CCryEditDoc*& rpDocMatch) +CCrySingleDocTemplate::Confidence CCrySingleDocTemplate::MatchDocType(const char* lpszPathName, CCryEditDoc*& rpDocMatch) { assert(lpszPathName != nullptr); rpDocMatch = nullptr; @@ -1626,9 +1626,6 @@ bool CCryEditApp::InitInstance() ReflectedVarInit::setupReflection(serializeContext); RegisterReflectedVarHandlers(); - - QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedStates)); - CreateSplashScreen(); // Register the application's document templates. Document templates @@ -1867,11 +1864,6 @@ void CCryEditApp::UnregisterEventLoopHook(IEventLoopHook* pHookToRemove) ////////////////////////////////////////////////////////////////////////// void CCryEditApp::LoadFile(QString fileName) { - //CEditCommandLineInfo cmdLine; - //ProcessCommandLine(cmdinfo); - - //bool bBuilding = false; - //CString file = cmdLine.SpanExcluding() if (GetIEditor()->GetViewManager()->GetViewCount() == 0) { return; @@ -3196,7 +3188,7 @@ bool CCryEditApp::CreateLevel(bool& wasCreateLevelOperationCancelled) GetIEditor()->GetDocument()->DeleteTemporaryLevel(); } - if (levelName.length() == 0 || !CryStringUtils::IsValidFileName(levelName.toUtf8().data())) + if (levelName.length() == 0 || !AZ::StringFunc::Path::IsValid(levelName.toUtf8().data())) { QMessageBox::critical(AzToolsFramework::GetActiveWindow(), QString(), QObject::tr("Level name is invalid, please choose another name.")); return false; @@ -3229,13 +3221,16 @@ bool CCryEditApp::CreateLevel(bool& wasCreateLevelOperationCancelled) DWORD dw = GetLastError(); #ifdef WIN32 - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + wchar_t windowsErrorMessageW[ERROR_LEN]; + windowsErrorMessageW[0] = L'\0'; + FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - windowsErrorMessage.data(), - windowsErrorMessage.length(), nullptr); + windowsErrorMessageW, + ERROR_LEN, nullptr); _getcwd(cwd.data(), cwd.length()); + AZStd::to_string(windowsErrorMessage.data(), ERROR_LEN, windowsErrorMessageW); #else windowsErrorMessage = strerror(dw); cwd = QDir::currentPath().toUtf8(); @@ -3309,7 +3304,7 @@ void CCryEditApp::OnOpenSlice() } ////////////////////////////////////////////////////////////////////////// -CCryEditDoc* CCryEditApp::OpenDocumentFile(LPCTSTR lpszFileName) +CCryEditDoc* CCryEditApp::OpenDocumentFile(const char* lpszFileName) { if (m_openingLevel) { @@ -4004,15 +3999,12 @@ struct CryAllocatorsRAII CryAllocatorsRAII() { AZ_Assert(!AZ::AllocatorInstance::IsReady(), "Expected allocator to not be initialized, hunt down the static that is initializing it"); - AZ_Assert(!AZ::AllocatorInstance::IsReady(), "Expected allocator to not be initialized, hunt down the static that is initializing it"); AZ::AllocatorInstance::Create(); - AZ::AllocatorInstance::Create(); } ~CryAllocatorsRAII() { - AZ::AllocatorInstance::Destroy(); AZ::AllocatorInstance::Destroy(); } }; diff --git a/Code/Editor/CryEdit.h b/Code/Editor/CryEdit.h index 9e3dfc98ff..4ab37ac1e5 100644 --- a/Code/Editor/CryEdit.h +++ b/Code/Editor/CryEdit.h @@ -174,7 +174,7 @@ public: virtual bool InitInstance(); virtual int ExitInstance(int exitCode = 0); virtual bool OnIdle(LONG lCount); - virtual CCryEditDoc* OpenDocumentFile(LPCTSTR lpszFileName); + virtual CCryEditDoc* OpenDocumentFile(const char* lpszFileName); CCryDocManager* GetDocManager() { return m_pDocManager; } @@ -448,9 +448,9 @@ public: ~CCrySingleDocTemplate() {}; // avoid creating another CMainFrame // close other type docs before opening any things - virtual CCryEditDoc* OpenDocumentFile(LPCTSTR lpszPathName, bool bAddToMRU, bool bMakeVisible); - virtual CCryEditDoc* OpenDocumentFile(LPCTSTR lpszPathName, bool bMakeVisible = true); - virtual Confidence MatchDocType(LPCTSTR lpszPathName, CCryEditDoc*& rpDocMatch); + virtual CCryEditDoc* OpenDocumentFile(const char* lpszPathName, bool bAddToMRU, bool bMakeVisible); + virtual CCryEditDoc* OpenDocumentFile(const char* lpszPathName, bool bMakeVisible = TRUE); + virtual Confidence MatchDocType(const char* lpszPathName, CCryEditDoc*& rpDocMatch); private: const QMetaObject* m_documentClass = nullptr; @@ -467,7 +467,7 @@ public: virtual void OnFileNew(); virtual bool DoPromptFileName(QString& fileName, UINT nIDSTitle, DWORD lFlags, bool bOpenFileDialog, CDocTemplate* pTemplate); - virtual CCryEditDoc* OpenDocumentFile(LPCTSTR lpszFileName, bool bAddToMRU); + virtual CCryEditDoc* OpenDocumentFile(const char* lpszFileName, bool bAddToMRU); QVector m_templateList; }; diff --git a/Code/Editor/CryEditDoc.cpp b/Code/Editor/CryEditDoc.cpp index e372baf365..c720299ce8 100644 --- a/Code/Editor/CryEditDoc.cpp +++ b/Code/Editor/CryEditDoc.cpp @@ -418,8 +418,8 @@ void CCryEditDoc::Load(TDocMultiArchive& arrXmlAr, const QString& szFilename) Audio::AudioSystemRequestBus::BroadcastResult(controlsPath, &Audio::AudioSystemRequestBus::Events::GetControlsPath); QString sAudioLevelPath(controlsPath); sAudioLevelPath += "levels/"; - string const sLevelNameOnly = PathUtil::GetFileName(fileName.toUtf8().data()); - sAudioLevelPath += sLevelNameOnly; + AZStd::string const sLevelNameOnly = PathUtil::GetFileName(fileName.toUtf8().data()); + sAudioLevelPath += sLevelNameOnly.c_str(); QByteArray path = sAudioLevelPath.toUtf8(); Audio::SAudioManagerRequestData oAMData(path, Audio::eADS_LEVEL_SPECIFIC); Audio::SAudioRequest oAudioRequestData; @@ -1909,7 +1909,7 @@ void CCryEditDoc::LogLoadTime(int time) const CLogFile::FormatLine("[LevelLoadTime] Level %s loaded in %d seconds", level.toUtf8().data(), time / 1000); #if defined(AZ_PLATFORM_WINDOWS) - SetFileAttributes(filename.toUtf8().data(), FILE_ATTRIBUTE_ARCHIVE); + SetFileAttributesW(filename.toStdWString().c_str(), FILE_ATTRIBUTE_ARCHIVE); #endif QFile file(filename); @@ -2134,7 +2134,7 @@ void CCryEditDoc::OnEnvironmentPropertyChanged(IVariable* pVar) childNode->setAttr("value", childValue.toUtf8().data()); } -QString CCryEditDoc::GetCryIndexPath(const LPCTSTR levelFilePath) const +QString CCryEditDoc::GetCryIndexPath(const char* levelFilePath) const { QString levelPath = Path::GetPath(levelFilePath); QString levelName = Path::GetFileName(levelFilePath); diff --git a/Code/Editor/CryEditDoc.h b/Code/Editor/CryEditDoc.h index a5b3334818..a96e9428b6 100644 --- a/Code/Editor/CryEditDoc.h +++ b/Code/Editor/CryEditDoc.h @@ -180,7 +180,7 @@ protected: void OnStartLevelResourceList(); static void OnValidateSurfaceTypesChanged(ICVar*); - QString GetCryIndexPath(const LPCTSTR levelFilePath) const; + QString GetCryIndexPath(const char* levelFilePath) const; ////////////////////////////////////////////////////////////////////////// // SliceEditorEntityOwnershipServiceNotificationBus::Handler diff --git a/Code/Editor/CryEditPy.cpp b/Code/Editor/CryEditPy.cpp index 21d2dcced9..2477cd2f35 100644 --- a/Code/Editor/CryEditPy.cpp +++ b/Code/Editor/CryEditPy.cpp @@ -210,7 +210,7 @@ namespace const char* PyGetCurrentLevelName() { // Using static member to capture temporary data - static string tempLevelName; + static AZ::IO::FixedMaxPathString tempLevelName; tempLevelName = GetIEditor()->GetGameEngine()->GetLevelName().toUtf8().data(); return tempLevelName.c_str(); } @@ -218,7 +218,7 @@ namespace const char* PyGetCurrentLevelPath() { // Using static member to capture temporary data - static string tempLevelPath; + static AZ::IO::FixedMaxPathString tempLevelPath; tempLevelPath = GetIEditor()->GetGameEngine()->GetLevelPath().toUtf8().data(); return tempLevelPath.c_str(); } diff --git a/Code/Editor/EditorFileMonitor.cpp b/Code/Editor/EditorFileMonitor.cpp index 5e539f78a8..7feb9d32a8 100644 --- a/Code/Editor/EditorFileMonitor.cpp +++ b/Code/Editor/EditorFileMonitor.cpp @@ -55,10 +55,10 @@ bool CEditorFileMonitor::RegisterListener(IFileChangeListener* pListener, const ////////////////////////////////////////////////////////////////////////// -static string CanonicalizePath(const char* path) +static AZStd::string CanonicalizePath(const char* path) { auto canon = QFileInfo(path).canonicalFilePath(); - return canon.isEmpty() ? string(path) : string(canon.toUtf8()); + return canon.isEmpty() ? AZStd::string(path) : AZStd::string(canon.toUtf8()); } ////////////////////////////////////////////////////////////////////////// @@ -66,8 +66,8 @@ bool CEditorFileMonitor::RegisterListener(IFileChangeListener* pListener, const { bool success = true; - string gameFolder = Path::GetEditingGameDataFolder().c_str(); - string naivePath; + AZStd::string gameFolder = Path::GetEditingGameDataFolder().c_str(); + AZStd::string naivePath; CFileChangeMonitor* fileChangeMonitor = CFileChangeMonitor::Instance(); AZ_Assert(fileChangeMonitor, "CFileChangeMonitor singleton missing."); @@ -75,12 +75,12 @@ bool CEditorFileMonitor::RegisterListener(IFileChangeListener* pListener, const // Append slash in preparation for appending the second part. naivePath = PathUtil::AddSlash(naivePath); naivePath += sFolderRelativeToGame; - naivePath.replace('/', '\\'); + AZ::StringFunc::Replace(naivePath, '/', '\\'); // Remove the final slash if the given item is a folder so the file change monitor correctly picks up on it. naivePath = PathUtil::RemoveSlash(naivePath); - string canonicalizedPath = CanonicalizePath(naivePath.c_str()); + AZStd::string canonicalizedPath = CanonicalizePath(naivePath.c_str()); if (fileChangeMonitor->IsDirectory(canonicalizedPath.c_str()) || fileChangeMonitor->IsFile(canonicalizedPath.c_str())) { diff --git a/Code/Editor/Export/ExportManager.cpp b/Code/Editor/Export/ExportManager.cpp index 764cc7b6b3..5abd3ab5d0 100644 --- a/Code/Editor/Export/ExportManager.cpp +++ b/Code/Editor/Export/ExportManager.cpp @@ -45,7 +45,7 @@ namespace SEfResTexture* pTex = pRes->GetTextureResource(nSlot); if (pTex) { - cry_strcat(outName, Path::GamePathToFullPath(pTex->m_Name.c_str()).toUtf8().data()); + azstrcat(outName, AZ_ARRAY_SIZE(outName), Path::GamePathToFullPath(pTex->m_Name.c_str()).toUtf8().data()); } } @@ -87,7 +87,7 @@ Export::CObject::CObject(const char* pName) nParent = -1; - cry_strcpy(name, pName); + azstrcpy(name, AZ_ARRAY_SIZE(name), pName); materialName[0] = '\0'; @@ -101,7 +101,7 @@ Export::CObject::CObject(const char* pName) void Export::CObject::SetMaterialName(const char* pName) { - cry_strcpy(materialName, pName); + azstrcpy(materialName, AZ_ARRAY_SIZE(materialName), pName); } diff --git a/Code/Editor/GameExporter.cpp b/Code/Editor/GameExporter.cpp index feea94b34b..2b157c0e14 100644 --- a/Code/Editor/GameExporter.cpp +++ b/Code/Editor/GameExporter.cpp @@ -378,14 +378,14 @@ void CGameExporter::ExportFileList(const QString& path, const QString& levelName { // process the folder of the specified map name, producing a filelist.xml file // that can later be used for map downloads - string newpath; + AZStd::string newpath; - QString filename = levelName; - string mapname = (filename + ".dds").toUtf8().data(); - string metaname = (filename + ".xml").toUtf8().data(); + AZStd::string filename = levelName.toUtf8().data(); + AZStd::string mapname = (filename + ".dds"); + AZStd::string metaname = (filename + ".xml"); XmlNodeRef rootNode = gEnv->pSystem->CreateXmlNode("download"); - rootNode->setAttr("name", filename.toUtf8().data()); + rootNode->setAttr("name", filename.c_str()); rootNode->setAttr("type", "Map"); XmlNodeRef indexNode = rootNode->newChild("index"); if (indexNode) @@ -434,9 +434,9 @@ void CGameExporter::ExportFileList(const QString& path, const QString& levelName newFileNode->setAttr("size", handle.m_fileDesc.nSize); unsigned char md5[16]; - string filenameToHash = GetIEditor()->GetGameEngine()->GetLevelPath().toUtf8().data(); + AZStd::string filenameToHash = GetIEditor()->GetGameEngine()->GetLevelPath().toUtf8().data(); filenameToHash += "/"; - filenameToHash += string{ handle.m_filename.data(), handle.m_filename.size() }; + filenameToHash += AZStd::string{ handle.m_filename.data(), handle.m_filename.size() }; if (gEnv->pCryPak->ComputeMD5(filenameToHash.data(), md5)) { char md5string[33]; diff --git a/Code/Editor/GenericSelectItemDialog.cpp b/Code/Editor/GenericSelectItemDialog.cpp index 3c51b38d0a..06f66c52eb 100644 --- a/Code/Editor/GenericSelectItemDialog.cpp +++ b/Code/Editor/GenericSelectItemDialog.cpp @@ -91,20 +91,6 @@ void CGenericSelectItemDialog::ReloadTree() QTreeWidgetItem* hSelected = nullptr; - /* - std::vector::const_iterator iter = m_items.begin(); - while (iter != m_items.end()) - { - const CString& itemName = *iter; - HTREEITEM hItem = m_tree.InsertItem(itemName, 0, 0, TVI_ROOT, TVI_SORT); - if (!m_preselect.IsEmpty() && m_preselect.CompareNoCase(itemName) == 0) - { - hSelected = hItem; - } - ++iter; - } - */ - std::map items; QRegularExpression sep(QStringLiteral("[\\/.") + m_treeSeparator + QStringLiteral("]+")); diff --git a/Code/Editor/IEditorImpl.cpp b/Code/Editor/IEditorImpl.cpp index d9c3af64b0..2571e8542a 100644 --- a/Code/Editor/IEditorImpl.cpp +++ b/Code/Editor/IEditorImpl.cpp @@ -26,6 +26,7 @@ AZ_POP_DISABLE_WARNING #include #include #include +#include // AzFramework #include @@ -1107,16 +1108,18 @@ void CEditorImpl::DetectVersion() DWORD dwHandle; UINT len; - char ver[1024 * 8]; + wchar_t ver[1024 * 8]; - GetModuleFileName(nullptr, exe, _MAX_PATH); + AZ::Utils::GetExecutablePath(exe, _MAX_PATH); + AZStd::wstring exeW; + AZStd::to_wstring(exeW, exe); - int verSize = GetFileVersionInfoSize(exe, &dwHandle); + int verSize = GetFileVersionInfoSizeW(exeW.c_str(), &dwHandle); if (verSize > 0) { - GetFileVersionInfo(exe, dwHandle, 1024 * 8, ver); + GetFileVersionInfoW(exeW.c_str(), dwHandle, 1024 * 8, ver); VS_FIXEDFILEINFO* vinfo; - VerQueryValue(ver, "\\", (void**)&vinfo, &len); + VerQueryValueW(ver, L"\\", (void**)&vinfo, &len); m_fileVersion.v[0] = vinfo->dwFileVersionLS & 0xFFFF; m_fileVersion.v[1] = vinfo->dwFileVersionLS >> 16; @@ -1557,31 +1560,31 @@ IExportManager* CEditorImpl::GetExportManager() void CEditorImpl::AddUIEnums() { // Spec settings for shadow casting lights - string SpecString[4]; + AZStd::string SpecString[4]; QStringList types; types.push_back("Never=0"); - SpecString[0].Format("VeryHigh Spec=%d", CONFIG_VERYHIGH_SPEC); + SpecString[0] = AZStd::string::format("VeryHigh Spec=%d", CONFIG_VERYHIGH_SPEC); types.push_back(SpecString[0].c_str()); - SpecString[1].Format("High Spec=%d", CONFIG_HIGH_SPEC); + SpecString[1] = AZStd::string::format("High Spec=%d", CONFIG_HIGH_SPEC); types.push_back(SpecString[1].c_str()); - SpecString[2].Format("Medium Spec=%d", CONFIG_MEDIUM_SPEC); + SpecString[2] = AZStd::string::format("Medium Spec=%d", CONFIG_MEDIUM_SPEC); types.push_back(SpecString[2].c_str()); - SpecString[3].Format("Low Spec=%d", CONFIG_LOW_SPEC); + SpecString[3] = AZStd::string::format("Low Spec=%d", CONFIG_LOW_SPEC); types.push_back(SpecString[3].c_str()); m_pUIEnumsDatabase->SetEnumStrings("CastShadows", types); // Power-of-two percentages - string percentStringPOT[5]; + AZStd::string percentStringPOT[5]; types.clear(); - percentStringPOT[0].Format("Default=%d", 0); + percentStringPOT[0] = AZStd::string::format("Default=%d", 0); types.push_back(percentStringPOT[0].c_str()); - percentStringPOT[1].Format("12.5=%d", 1); + percentStringPOT[1] = AZStd::string::format("12.5=%d", 1); types.push_back(percentStringPOT[1].c_str()); - percentStringPOT[2].Format("25=%d", 2); + percentStringPOT[2] = AZStd::string::format("25=%d", 2); types.push_back(percentStringPOT[2].c_str()); - percentStringPOT[3].Format("50=%d", 3); + percentStringPOT[3] = AZStd::string::format("50=%d", 3); types.push_back(percentStringPOT[3].c_str()); - percentStringPOT[4].Format("100=%d", 4); + percentStringPOT[4] = AZStd::string::format("100=%d", 4); types.push_back(percentStringPOT[4].c_str()); m_pUIEnumsDatabase->SetEnumStrings("ShadowMinResPercent", types); } diff --git a/Code/Editor/Include/Command.h b/Code/Editor/Include/Command.h index 69853ddb4f..e4fea5a3e7 100644 --- a/Code/Editor/Include/Command.h +++ b/Code/Editor/Include/Command.h @@ -18,7 +18,7 @@ #include "Util/EditorUtils.h" -inline string ToString(const QString& s) +inline AZStd::string ToString(const QString& s) { return s.toUtf8().data(); } @@ -27,10 +27,10 @@ class CCommand { public: CCommand( - const string& module, - const string& name, - const string& description, - const string& example) + const AZStd::string& module, + const AZStd::string& name, + const AZStd::string& description, + const AZStd::string& example) : m_module(module) , m_name(name) , m_description(description) @@ -79,20 +79,20 @@ public: } int GetArgCount() const { return m_args.size(); } - const string& GetArg(int i) const + const AZStd::string& GetArg(int i) const { assert(0 <= i && i < GetArgCount()); return m_args[i]; } private: - DynArray m_args; + DynArray m_args; unsigned char m_stringFlags; // This is needed to quote string parameters when logging a command. }; - const string& GetName() const { return m_name; } - const string& GetModule() const { return m_module; } - const string& GetDescription() const { return m_description; } - const string& GetExample() const { return m_example; } + const AZStd::string& GetName() const { return m_name; } + const AZStd::string& GetModule() const { return m_module; } + const AZStd::string& GetDescription() const { return m_description; } + const AZStd::string& GetExample() const { return m_example; } void SetAvailableInScripting() { m_bAlsoAvailableInScripting = true; }; bool IsAvailableInScripting() const { return m_bAlsoAvailableInScripting; } @@ -104,15 +104,15 @@ public: protected: friend class CEditorCommandManager; - string m_module; - string m_name; - string m_description; - string m_example; + AZStd::string m_module; + AZStd::string m_name; + AZStd::string m_description; + AZStd::string m_example; bool m_bAlsoAvailableInScripting; template - static string ToString_(T t) { return ::ToString(t); } - static inline string ToString_(const char* val) + static AZStd::string ToString_(T t) { return ::ToString(t); } + static inline AZStd::string ToString_(const char* val) { return val; } template static bool FromString_(T& t, const char* s) { return ::FromString(t, s); } @@ -137,8 +137,8 @@ class CCommand0 : public CCommand { public: - CCommand0(const string& module, const string& name, - const string& description, const string& example, + CCommand0(const AZStd::string& module, const AZStd::string& name, + const AZStd::string& description, const AZStd::string& example, const AZStd::function& functor) : CCommand(module, name, description, example) , m_functor(functor) {} @@ -146,10 +146,10 @@ public: // UI metadata for this command, if any struct SUIInfo { - string caption; - string tooltip; - string description; - string iconFilename; + AZStd::string caption; + AZStd::string tooltip; + AZStd::string description; + AZStd::string iconFilename; int iconIndex; int commandId; // Windows command id @@ -179,8 +179,8 @@ class CCommand0wRet : public CCommand { public: - CCommand0wRet(const string& module, const string& name, - const string& description, const string& example, + CCommand0wRet(const AZStd::string& module, const AZStd::string& name, + const AZStd::string& description, const AZStd::string& example, const AZStd::function& functor); QString Execute(const CArgs& args); @@ -195,8 +195,8 @@ class CCommand1 : public CCommand { public: - CCommand1(const string& module, const string& name, - const string& description, const string& example, + CCommand1(const AZStd::string& module, const AZStd::string& name, + const AZStd::string& description, const AZStd::string& example, const AZStd::function& functor); QString Execute(const CArgs& args); @@ -211,8 +211,8 @@ class CCommand1wRet : public CCommand { public: - CCommand1wRet(const string& module, const string& name, - const string& description, const string& example, + CCommand1wRet(const AZStd::string& module, const AZStd::string& name, + const AZStd::string& description, const AZStd::string& example, const AZStd::function& functor); QString Execute(const CArgs& args); @@ -227,8 +227,8 @@ class CCommand2 : public CCommand { public: - CCommand2(const string& module, const string& name, - const string& description, const string& example, + CCommand2(const AZStd::string& module, const AZStd::string& name, + const AZStd::string& description, const AZStd::string& example, const AZStd::function& functor); QString Execute(const CArgs& args); @@ -243,8 +243,8 @@ class CCommand2wRet : public CCommand { public: - CCommand2wRet(const string& module, const string& name, - const string& description, const string& example, + CCommand2wRet(const AZStd::string& module, const AZStd::string& name, + const AZStd::string& description, const AZStd::string& example, const AZStd::function& functor); QString Execute(const CArgs& args); @@ -259,8 +259,8 @@ class CCommand3 : public CCommand { public: - CCommand3(const string& module, const string& name, - const string& description, const string& example, + CCommand3(const AZStd::string& module, const AZStd::string& name, + const AZStd::string& description, const AZStd::string& example, const AZStd::function& functor); QString Execute(const CArgs& args); @@ -275,8 +275,8 @@ class CCommand3wRet : public CCommand { public: - CCommand3wRet(const string& module, const string& name, - const string& description, const string& example, + CCommand3wRet(const AZStd::string& module, const AZStd::string& name, + const AZStd::string& description, const AZStd::string& example, const AZStd::function& functor); QString Execute(const CArgs& args); @@ -291,8 +291,8 @@ class CCommand4 : public CCommand { public: - CCommand4(const string& module, const string& name, - const string& description, const string& example, + CCommand4(const AZStd::string& module, const AZStd::string& name, + const AZStd::string& description, const AZStd::string& example, const AZStd::function& functor); QString Execute(const CArgs& args); @@ -307,8 +307,8 @@ class CCommand4wRet : public CCommand { public: - CCommand4wRet(const string& module, const string& name, - const string& description, const string& example, + CCommand4wRet(const AZStd::string& module, const AZStd::string& name, + const AZStd::string& description, const AZStd::string& example, const AZStd::function& functor); QString Execute(const CArgs& args); @@ -323,8 +323,8 @@ class CCommand5 : public CCommand { public: - CCommand5(const string& module, const string& name, - const string& description, const string& example, + CCommand5(const AZStd::string& module, const AZStd::string& name, + const AZStd::string& description, const AZStd::string& example, const AZStd::function& functor); QString Execute(const CArgs& args); @@ -339,8 +339,8 @@ class CCommand6 : public CCommand { public: - CCommand6(const string& module, const string& name, - const string& description, const string& example, + CCommand6(const AZStd::string& module, const AZStd::string& name, + const AZStd::string& description, const AZStd::string& example, const AZStd::function& functor); QString Execute(const CArgs& args); @@ -353,8 +353,8 @@ protected: ////////////////////////////////////////////////////////////////////////// template -CCommand0wRet::CCommand0wRet(const string& module, const string& name, - const string& description, const string& example, +CCommand0wRet::CCommand0wRet(const AZStd::string& module, const AZStd::string& name, + const AZStd::string& description, const AZStd::string& example, const AZStd::function& functor) : CCommand(module, name, description, example) , m_functor(functor) @@ -373,8 +373,8 @@ QString CCommand0wRet::Execute(const CCommand::CArgs& args) ////////////////////////////////////////////////////////////////////////// template -CCommand1::CCommand1(const string& module, const string& name, - const string& description, const string& example, +CCommand1::CCommand1(const AZStd::string& module, const AZStd::string& name, + const AZStd::string& description, const AZStd::string& example, const AZStd::function& functor) : CCommand(module, name, description, example) , m_functor(functor) @@ -410,8 +410,8 @@ QString CCommand1::Execute(const CCommand::CArgs& args) ////////////////////////////////////////////////////////////////////////// template -CCommand1wRet::CCommand1wRet(const string& module, const string& name, - const string& description, const string& example, +CCommand1wRet::CCommand1wRet(const AZStd::string& module, const AZStd::string& name, + const AZStd::string& description, const AZStd::string& example, const AZStd::function& functor) : CCommand(module, name, description, example) , m_functor(functor) @@ -448,8 +448,8 @@ QString CCommand1wRet::Execute(const CCommand::CArgs& args) ////////////////////////////////////////////////////////////////////////// template -CCommand2::CCommand2(const string& module, const string& name, - const string& description, const string& example, +CCommand2::CCommand2(const AZStd::string& module, const AZStd::string& name, + const AZStd::string& description, const AZStd::string& example, const AZStd::function& functor) : CCommand(module, name, description, example) , m_functor(functor) @@ -487,8 +487,8 @@ QString CCommand2::Execute(const CCommand::CArgs& args) ////////////////////////////////////////////////////////////////////////// template -CCommand2wRet::CCommand2wRet(const string& module, const string& name, - const string& description, const string& example, +CCommand2wRet::CCommand2wRet(const AZStd::string& module, const AZStd::string& name, + const AZStd::string& description, const AZStd::string& example, const AZStd::function& functor) : CCommand(module, name, description, example) , m_functor(functor) @@ -527,8 +527,8 @@ QString CCommand2wRet::Execute(const CCommand::CArgs& args) ////////////////////////////////////////////////////////////////////////// template -CCommand3::CCommand3(const string& module, const string& name, - const string& description, const string& example, +CCommand3::CCommand3(const AZStd::string& module, const AZStd::string& name, + const AZStd::string& description, const AZStd::string& example, const AZStd::function& functor) : CCommand(module, name, description, example) , m_functor(functor) @@ -568,8 +568,8 @@ QString CCommand3::Execute(const CCommand::CArgs& args) ////////////////////////////////////////////////////////////////////////// template -CCommand3wRet::CCommand3wRet(const string& module, const string& name, - const string& description, const string& example, +CCommand3wRet::CCommand3wRet(const AZStd::string& module, const AZStd::string& name, + const AZStd::string& description, const AZStd::string& example, const AZStd::function& functor) : CCommand(module, name, description, example) , m_functor(functor) @@ -610,8 +610,8 @@ QString CCommand3wRet::Execute(const CCommand::CArgs& args) ////////////////////////////////////////////////////////////////////////// template -CCommand4::CCommand4(const string& module, const string& name, - const string& description, const string& example, +CCommand4::CCommand4(const AZStd::string& module, const AZStd::string& name, + const AZStd::string& description, const AZStd::string& example, const AZStd::function& functor) : CCommand(module, name, description, example) , m_functor(functor) @@ -654,8 +654,8 @@ QString CCommand4::Execute(const CCommand::CArgs& args) ////////////////////////////////////////////////////////////////////////// template -CCommand4wRet::CCommand4wRet(const string& module, const string& name, - const string& description, const string& example, +CCommand4wRet::CCommand4wRet(const AZStd::string& module, const AZStd::string& name, + const AZStd::string& description, const AZStd::string& example, const AZStd::function& functor) : CCommand(module, name, description, example) , m_functor(functor) @@ -699,8 +699,8 @@ QString CCommand4wRet::Execute(const CCommand::CArgs& args) ////////////////////////////////////////////////////////////////////////// template -CCommand5::CCommand5(const string& module, const string& name, - const string& description, const string& example, +CCommand5::CCommand5(const AZStd::string& module, const AZStd::string& name, + const AZStd::string& description, const AZStd::string& example, const AZStd::function& functor) : CCommand(module, name, description, example) , m_functor(functor) @@ -745,8 +745,8 @@ QString CCommand5::Execute(const CCommand::CArgs& args) ////////////////////////////////////////////////////////////////////////// template -CCommand6::CCommand6(const string& module, const string& name, - const string& description, const string& example, +CCommand6::CCommand6(const AZStd::string& module, const AZStd::string& name, + const AZStd::string& description, const AZStd::string& example, const AZStd::function& functor) : CCommand(module, name, description, example) , m_functor(functor) diff --git a/Code/Editor/Include/IFileUtil.h b/Code/Editor/Include/IFileUtil.h index f83c7e0d59..746a81b87c 100644 --- a/Code/Editor/Include/IFileUtil.h +++ b/Code/Editor/Include/IFileUtil.h @@ -8,7 +8,6 @@ #pragma once -#include "StringUtils.h" #include "../Include/SandboxAPI.h" class QWidget; diff --git a/Code/Editor/LevelFileDialog.cpp b/Code/Editor/LevelFileDialog.cpp index 41bb4d6faa..cefa1330eb 100644 --- a/Code/Editor/LevelFileDialog.cpp +++ b/Code/Editor/LevelFileDialog.cpp @@ -98,7 +98,7 @@ CLevelFileDialog::CLevelFileDialog(bool openDialog, QWidget* parent) connect(ui->nameLineEdit, &QLineEdit::textChanged, this, &CLevelFileDialog::OnNameChanged); } - // reject invalid file names (see CryStringUtils::IsValidFileName) + // reject invalid file names ui->nameLineEdit->setValidator(new QRegExpValidator(QRegExp("^[a-zA-Z0-9_\\-./]*$"), ui->nameLineEdit)); ReloadTree(); @@ -315,7 +315,7 @@ void CLevelFileDialog::OnNewFolder() const QString newFolderName = inputDlg.textValue(); const QString newFolderPath = parentFullPath + "/" + newFolderName; - if (!CryStringUtils::IsValidFileName(newFolderName.toUtf8().data())) + if (!AZ::StringFunc::Path::IsValid(newFolderName.toUtf8().data())) { QMessageBox box(this); box.setText(tr("Please enter a single, valid folder name(standard English alphanumeric characters only)")); @@ -416,7 +416,7 @@ bool CLevelFileDialog::ValidateSaveLevelPath(QString& errorMessage) const const QString enteredPath = GetEnteredPath(); const QString levelPath = GetLevelPath(); - if (!CryStringUtils::IsValidFileName(Path::GetFileName(levelPath).toUtf8().data())) + if (!AZ::StringFunc::Path::IsValid(Path::GetFileName(levelPath).toUtf8().data())) { errorMessage = tr("Please enter a valid level name (standard English alphanumeric characters only)"); return false; diff --git a/Code/Editor/LogFile.cpp b/Code/Editor/LogFile.cpp index c768f5013b..2295e1897f 100644 --- a/Code/Editor/LogFile.cpp +++ b/Code/Editor/LogFile.cpp @@ -180,14 +180,14 @@ void CLogFile::FormatLineV(const char * format, va_list argList) void CLogFile::AboutSystem() { char szBuffer[MAX_LOGBUFFER_SIZE]; + wchar_t szBufferW[MAX_LOGBUFFER_SIZE]; #if defined(AZ_PLATFORM_WINDOWS) || defined(AZ_PLATFORM_LINUX) ////////////////////////////////////////////////////////////////////// // Write the system informations to the log ////////////////////////////////////////////////////////////////////// - char szProfileBuffer[128]; - char szLanguageBuffer[64]; - //char szCPUModel[64]; + wchar_t szLanguageBufferW[64]; + //wchar_t szCPUModel[64]; MEMORYSTATUS MemoryStatus; #endif // defined(AZ_PLATFORM_WINDOWS) || defined(AZ_PLATFORM_LINUX) @@ -201,11 +201,13 @@ void CLogFile::AboutSystem() ////////////////////////////////////////////////////////////////////// // Get system language - GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SENGLANGUAGE, - szLanguageBuffer, sizeof(szLanguageBuffer)); + GetLocaleInfoW(LOCALE_SYSTEM_DEFAULT, LOCALE_SENGLANGUAGE, + szLanguageBufferW, sizeof(szLanguageBufferW)); + AZStd::string szLanguageBuffer; + AZStd::to_string(szLanguageBuffer, szLanguageBufferW); // Format and send OS information line - azsnprintf(szBuffer, MAX_LOGBUFFER_SIZE, "Current Language: %s ", szLanguageBuffer); + azsnprintf(szBuffer, MAX_LOGBUFFER_SIZE, "Current Language: %s ", szLanguageBuffer.c_str()); CryLog("%s", szBuffer); #else QLocale locale; @@ -294,7 +296,8 @@ AZ_POP_DISABLE_WARNING ////////////////////////////////////////////////////////////////////// str += " ("; - GetWindowsDirectory(szBuffer, sizeof(szBuffer)); + GetWindowsDirectoryW(szBufferW, sizeof(szBufferW)); + AZStd::to_string(szBuffer, MAX_LOGBUFFER_SIZE, szBufferW); str += szBuffer; str += ")"; CryLog("%s", str.toUtf8().data()); @@ -381,12 +384,13 @@ AZ_POP_DISABLE_WARNING #if defined(AZ_PLATFORM_WINDOWS) EnumDisplaySettings(nullptr, ENUM_CURRENT_SETTINGS, &DisplayConfig); - GetPrivateProfileString("boot.description", "display.drv", - "(Unknown graphics card)", szProfileBuffer, sizeof(szProfileBuffer), - "system.ini"); + GetPrivateProfileStringW(L"boot.description", L"display.drv", + L"(Unknown graphics card)", szLanguageBufferW, sizeof(szLanguageBufferW), + L"system.ini"); + AZStd::to_string(szLanguageBuffer, szLanguageBufferW); azsnprintf(szBuffer, MAX_LOGBUFFER_SIZE, "Current display mode is %dx%dx%d, %s", DisplayConfig.dmPelsWidth, DisplayConfig.dmPelsHeight, - DisplayConfig.dmBitsPerPel, szProfileBuffer); + DisplayConfig.dmBitsPerPel, szLanguageBuffer.c_str()); CryLog("%s", szBuffer); #else auto screen = QGuiApplication::primaryScreen(); @@ -568,9 +572,6 @@ void CLogFile::OnWriteToConsole(const char* sText, bool bNewLine) } if (bNewLine) { - //str = CString("\r\n") + str.TrimLeft(); - //str = CString("\r\n") + str; - //str = CString("\r") + str; str = QString("\r\n") + str; str = str.trimmed(); } diff --git a/Code/Editor/MainWindow.cpp b/Code/Editor/MainWindow.cpp index cd023f3b42..bb246c2337 100644 --- a/Code/Editor/MainWindow.cpp +++ b/Code/Editor/MainWindow.cpp @@ -1687,7 +1687,7 @@ void MainWindow::OnUpdateConnectionStatus() status = tr("Pending Jobs : %1 Failed Jobs : %2").arg(m_connectionListener->GetJobsCount()).arg(failureCount); - statusBar->SetItem(QtUtil::ToQString("connection"), status, tooltip, icon); + statusBar->SetItem("connection", status, tooltip, icon); if (m_showAPDisconnectDialog && m_connectionListener->GetState() != EConnectionState::Connected) { diff --git a/Code/Editor/Platform/Windows/Util/Mailer_Windows.cpp b/Code/Editor/Platform/Windows/Util/Mailer_Windows.cpp index 7ac1181cdd..83cdba986b 100644 --- a/Code/Editor/Platform/Windows/Util/Mailer_Windows.cpp +++ b/Code/Editor/Platform/Windows/Util/Mailer_Windows.cpp @@ -28,7 +28,7 @@ bool CMailer::SendMail(const char* subject, GetCurrentDirectoryW(sizeof(dir), dir); // Load MAPI dll - HMODULE hMAPILib = LoadLibraryA("MAPI32.DLL"); + HMODULE hMAPILib = LoadLibraryW(L"MAPI32.DLL"); LPMAPISENDMAIL lpfnMAPISendMail = (LPMAPISENDMAIL) GetProcAddress(hMAPILib, "MAPISendMail"); int numRecipients = (int)_recipients.size(); @@ -60,11 +60,11 @@ bool CMailer::SendMail(const char* subject, // Handle Recipients MapiRecipDesc* recipients = new MapiRecipDesc[numRecipients]; - std::vector addresses; + std::vector addresses; addresses.resize(numRecipients); for (i = 0; i < numRecipients; i++) { - addresses[i] = string("SMTP:") + _recipients[i]; + addresses[i] = AZStd::string("SMTP:") + _recipients[i]; } for (i = 0; i < numRecipients; i++) diff --git a/Code/Editor/PluginManager.cpp b/Code/Editor/PluginManager.cpp index 5efd52a97e..350102ead2 100644 --- a/Code/Editor/PluginManager.cpp +++ b/Code/Editor/PluginManager.cpp @@ -17,9 +17,8 @@ // Editor #include "Include/IPlugin.h" - -using TPfnCreatePluginInstance = IPlugin *(*)(PLUGIN_INIT_PARAM *pInitParam); -using TPfnQueryPluginSettings = void (*)(SPluginSettings &); +using TPfnCreatePluginInstance = IPlugin* (*)(PLUGIN_INIT_PARAM* pInitParam); +using TPfnQueryPluginSettings = void (*)(SPluginSettings&); CPluginManager::CPluginManager() { @@ -126,8 +125,8 @@ namespace bool CPluginManager::LoadPlugins(const char* pPathWithMask) { - QString strPath = QtUtil::ToQString(PathUtil::GetPath(pPathWithMask)); - QString strMask = QString::fromUtf8(PathUtil::GetFile(pPathWithMask)); + QString strPath = PathUtil::GetPath(pPathWithMask).c_str(); + QString strMask = PathUtil::GetFile(pPathWithMask); CLogFile::WriteLine("[Plugin Manager] Loading plugins..."); @@ -155,7 +154,7 @@ bool CPluginManager::LoadPlugins(const char* pPathWithMask) } #endif } - if (plugins.size() == 0) + if (plugins.empty()) { CLogFile::FormatLine("[Plugin Manager] Cannot find any plugins in plugin directory '%s'", strPath.toUtf8().data()); return false; @@ -269,13 +268,13 @@ void CPluginManager::RegisterPlugin(QLibrary* dllHandle, IPlugin* pPlugin) IPlugin* CPluginManager::GetPluginByGUID(const char* pGUID) { - for (auto it = m_plugins.begin(); it != m_plugins.end(); ++it) + for (const SPluginEntry& pluginEntry : m_plugins) { - const char* pPluginGuid = it->pPlugin->GetPluginGUID(); + const char* pPluginGuid = pluginEntry.pPlugin->GetPluginGUID(); if (pPluginGuid && !strcmp(pPluginGuid, pGUID)) { - return it->pPlugin; + return pluginEntry.pPlugin; } } @@ -332,14 +331,11 @@ IUIEvent* CPluginManager::GetEventByIDAndPluginID(uint8 aPluginID, uint8 aEventI bool CPluginManager::CanAllPluginsExitNow() { - for (auto it = m_plugins.begin(); it != m_plugins.end(); ++it) + for (const SPluginEntry& pluginEntry : m_plugins) { - if (it->pPlugin) + if (pluginEntry.pPlugin && !pluginEntry.pPlugin->CanExitNow()) { - if (!it->pPlugin->CanExitNow()) - { - return false; - } + return false; } } diff --git a/Code/Editor/Plugins/EditorAssetImporter/AssetImporterPlugin.h b/Code/Editor/Plugins/EditorAssetImporter/AssetImporterPlugin.h index c5b6694af4..d78e6cab4e 100644 --- a/Code/Editor/Plugins/EditorAssetImporter/AssetImporterPlugin.h +++ b/Code/Editor/Plugins/EditorAssetImporter/AssetImporterPlugin.h @@ -41,7 +41,7 @@ public: return m_editor; } - const string& GetToolName() const + const AZStd::string& GetToolName() const { return m_toolName; } @@ -88,7 +88,7 @@ private: IEditor* const m_editor; // Tool name - string m_toolName; + AZStd::string m_toolName; // Context provider for the Asset Browser AZ::AssetBrowserContextProvider m_assetBrowserContextProvider; diff --git a/Code/Editor/Plugins/EditorCommon/DrawingPrimitives/Ruler.cpp b/Code/Editor/Plugins/EditorCommon/DrawingPrimitives/Ruler.cpp index 866a8206d6..1f0bd9ad88 100644 --- a/Code/Editor/Plugins/EditorCommon/DrawingPrimitives/Ruler.cpp +++ b/Code/Editor/Plugins/EditorCommon/DrawingPrimitives/Ruler.cpp @@ -12,6 +12,7 @@ #include #include #include +#include namespace DrawingPrimitives { diff --git a/Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin.cpp b/Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin.cpp index dd2a1d602a..630ab3eb8e 100644 --- a/Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin.cpp +++ b/Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin.cpp @@ -8,8 +8,6 @@ #include "FFMPEGPlugin.h" -#include "CryString.h" -typedef CryStringT string; #include "Include/ICommandManager.h" #include "Util/PathUtil.h" diff --git a/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsContainer.cpp b/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsContainer.cpp index a7a238d241..772469808b 100644 --- a/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsContainer.cpp +++ b/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsContainer.cpp @@ -8,6 +8,7 @@ #include "ProjectSettingsContainer.h" +#include #include #include #include diff --git a/Code/Editor/ProcessInfo.cpp b/Code/Editor/ProcessInfo.cpp index 87f4f23846..692e5d65ef 100644 --- a/Code/Editor/ProcessInfo.cpp +++ b/Code/Editor/ProcessInfo.cpp @@ -41,7 +41,7 @@ void LoadPSApi() { if (!g_hPSAPI) { - g_hPSAPI = LoadLibraryA("psapi.dll"); + g_hPSAPI = LoadLibraryW(L"psapi.dll"); if (g_hPSAPI) { diff --git a/Code/Editor/QtUtil.h b/Code/Editor/QtUtil.h index bb1f8ba427..380f4dfa4a 100644 --- a/Code/Editor/QtUtil.h +++ b/Code/Editor/QtUtil.h @@ -10,8 +10,6 @@ #pragma once #include -#include -#include "UnicodeFunctions.h" #include #include @@ -36,29 +34,6 @@ public: namespace QtUtil { - // From QString to CryString - inline CryStringT ToString(const QString& str) - { - return Unicode::Convert >(str); - } - - // From CryString to QString - inline QString ToQString(const CryStringT& str) - { - return Unicode::Convert(str); - } - - // From const char * to QString - inline QString ToQString(const char* str, size_t len = -1) - { - if (len == -1) - { - len = strlen(str); - } - return Unicode::Convert(str, str + len); - } - - // Replacement for CString::trimRight() inline QString trimRight(const QString& str) { // We prepend a char, so that the left doesn't get trimmed, then we remove it after trimming diff --git a/Code/Editor/QuickAccessBar.cpp b/Code/Editor/QuickAccessBar.cpp index 0379be027d..59b4418c4c 100644 --- a/Code/Editor/QuickAccessBar.cpp +++ b/Code/Editor/QuickAccessBar.cpp @@ -68,12 +68,12 @@ void CQuickAccessBar::OnInitDialog() // Add console variables & commands. IConsole* console = GetIEditor()->GetSystem()->GetIConsole(); - std::vector cmds; + AZStd::vector cmds; cmds.resize(console->GetNumVars()); - size_t cmdCount = console->GetSortedVars(&cmds[0], cmds.size()); + size_t cmdCount = console->GetSortedVars(cmds); for (int i = 0; i < cmdCount; ++i) { - m_model->setStringList(m_model->stringList() += cmds[i]); + m_model->setStringList(m_model->stringList() += cmds[i].data()); } } diff --git a/Code/Editor/ResourceSelectorHost.cpp b/Code/Editor/ResourceSelectorHost.cpp index af6c398fe7..eb82b57ab4 100644 --- a/Code/Editor/ResourceSelectorHost.cpp +++ b/Code/Editor/ResourceSelectorHost.cpp @@ -75,11 +75,7 @@ public: void SetGlobalSelection(const char* resourceType, const char* value) override { - if (!resourceType) - { - return; - } - if (!value) + if (!resourceType || !value) { return; } @@ -101,10 +97,10 @@ public: } private: - using TTypeMap = std::map>; + using TTypeMap = std::map>; TTypeMap m_typeMap; - std::map m_globallySelectedResources; + std::map m_globallySelectedResources; }; // --------------------------------------------------------------------------- diff --git a/Code/Editor/SelectSequenceDialog.cpp b/Code/Editor/SelectSequenceDialog.cpp index 2566a8be82..11e30b91d7 100644 --- a/Code/Editor/SelectSequenceDialog.cpp +++ b/Code/Editor/SelectSequenceDialog.cpp @@ -37,7 +37,7 @@ CSelectSequenceDialog::GetItems(std::vector& outItems) { IAnimSequence* pSeq = pMovieSys->GetSequence(i); SItem item; - string fullname = pSeq->GetName(); + AZStd::string fullname = pSeq->GetName(); item.name = fullname.c_str(); outItems.push_back(item); } diff --git a/Code/Editor/Settings.cpp b/Code/Editor/Settings.cpp index 06aae5b8f1..09b0d0f4f4 100644 --- a/Code/Editor/Settings.cpp +++ b/Code/Editor/Settings.cpp @@ -661,22 +661,6 @@ void SEditorSettings::Save() ////////////////////////////////////////////////////////////////////////// SaveValue("Settings\\Slices", "DynamicByDefault", sliceSettings.dynamicByDefault); - /* - ////////////////////////////////////////////////////////////////////////// - // Save paths. - ////////////////////////////////////////////////////////////////////////// - for (int id = 0; id < EDITOR_PATH_LAST; id++) - { - for (int i = 0; i < searchPaths[id].size(); i++) - { - CString path = searchPaths[id][i]; - CString key; - key.Format( "Paths","Path_%.2d_%.2d",id,i ); - SaveValue( "Paths",key,path ); - } - } - */ - s_editorSettings()->sync(); // --- Settings Registry values diff --git a/Code/Editor/SettingsManager.cpp b/Code/Editor/SettingsManager.cpp index 27031ca43e..d567da4c26 100644 --- a/Code/Editor/SettingsManager.cpp +++ b/Code/Editor/SettingsManager.cpp @@ -607,7 +607,7 @@ void CSettingsManager::SerializeCVars(XmlNodeRef& node, bool bLoad) int nCurrentVariable(0); IConsole* piConsole(nullptr); ICVar* piVariable(nullptr); - std::vector cszVariableNames; + AZStd::vector cszVariableNames; char* szKey(nullptr); char* szValue(nullptr); @@ -660,9 +660,9 @@ void CSettingsManager::SerializeCVars(XmlNodeRef& node, bool bLoad) XmlNodeRef cvarsNode = XmlHelpers::CreateXmlNode(CVARS_NODE); nNumberOfVariables = piConsole->GetNumVisibleVars(); - cszVariableNames.resize(nNumberOfVariables, nullptr); + cszVariableNames.resize(nNumberOfVariables); - if (piConsole->GetSortedVars((const char**)&cszVariableNames.front(), nNumberOfVariables, nullptr) != nNumberOfVariables) + if (piConsole->GetSortedVars(cszVariableNames) != nNumberOfVariables) { assert(false); return; @@ -670,12 +670,12 @@ void CSettingsManager::SerializeCVars(XmlNodeRef& node, bool bLoad) for (nCurrentVariable = 0; nCurrentVariable < cszVariableNames.size(); ++nCurrentVariable) { - if (_stricmp(cszVariableNames[nCurrentVariable], "_TestFormatMessage") == 0) + if (_stricmp(cszVariableNames[nCurrentVariable].data(), "_TestFormatMessage") == 0) { continue; } - piVariable = piConsole->GetCVar(cszVariableNames[nCurrentVariable]); + piVariable = piConsole->GetCVar(cszVariableNames[nCurrentVariable].data()); if (!piVariable) { assert(false); @@ -683,7 +683,7 @@ void CSettingsManager::SerializeCVars(XmlNodeRef& node, bool bLoad) } newCVarNode = XmlHelpers::CreateXmlNode(CVAR_NODE); - newCVarNode->setAttr(cszVariableNames[nCurrentVariable], piVariable->GetString()); + newCVarNode->setAttr(cszVariableNames[nCurrentVariable].data(), piVariable->GetString()); cvarsNode->addChild(newCVarNode); } diff --git a/Code/Editor/ToolBox.cpp b/Code/Editor/ToolBox.cpp index bac02d7460..d784bc2083 100644 --- a/Code/Editor/ToolBox.cpp +++ b/Code/Editor/ToolBox.cpp @@ -379,7 +379,7 @@ void CToolBoxManager::Load(QString xmlpath, AmazonToolbar* pToolbar, bool bToolb AZ::IO::FixedMaxPathString engineRoot = AZ::Utils::GetEnginePath(); QDir engineDir = !engineRoot.empty() ? QDir(QString(engineRoot.c_str())) : QDir::current(); - string enginePath = PathUtil::AddSlash(engineDir.absolutePath().toUtf8().data()); + AZStd::string enginePath = PathUtil::AddSlash(engineDir.absolutePath().toUtf8().data()); for (int i = 0; i < toolBoxNode->getChildCount(); ++i) { @@ -405,11 +405,11 @@ void CToolBoxManager::Load(QString xmlpath, AmazonToolbar* pToolbar, bool bToolb continue; } - string shelfPath = PathUtil::GetParentDirectory(xmlpath.toUtf8().data()); - string fullIconPath = enginePath + PathUtil::AddSlash(shelfPath.c_str()); + AZStd::string shelfPath = PathUtil::GetParentDirectory(xmlpath.toUtf8().data()); + AZStd::string fullIconPath = enginePath + PathUtil::AddSlash(shelfPath.c_str()); fullIconPath.append(iconPath.toUtf8().data()); - pMacro->SetIconPath(fullIconPath); + pMacro->SetIconPath(fullIconPath.c_str()); QString toolTip(macroNode->getAttr("tooltip")); pMacro->action()->setToolTip(toolTip); diff --git a/Code/Editor/ToolsConfigPage.cpp b/Code/Editor/ToolsConfigPage.cpp index bae70f0cfe..965c862554 100644 --- a/Code/Editor/ToolsConfigPage.cpp +++ b/Code/Editor/ToolsConfigPage.cpp @@ -818,12 +818,12 @@ void CToolsConfigPage::FillConsoleCmds() { QStringList commands; IConsole* console = GetIEditor()->GetSystem()->GetIConsole(); - std::vector cmds; + AZStd::vector cmds; cmds.resize(console->GetNumVars()); - size_t cmdCount = console->GetSortedVars(&cmds[0], cmds.size()); + size_t cmdCount = console->GetSortedVars(cmds); for (int i = 0; i < cmdCount; ++i) { - commands.push_back(cmds[i]); + commands.push_back(cmds[i].data()); } m_completionModel->setStringList(commands); } diff --git a/Code/Editor/TrackView/CommentKeyUIControls.cpp b/Code/Editor/TrackView/CommentKeyUIControls.cpp index b5a706c843..c7c5f83cbf 100644 --- a/Code/Editor/TrackView/CommentKeyUIControls.cpp +++ b/Code/Editor/TrackView/CommentKeyUIControls.cpp @@ -52,7 +52,7 @@ public: CFileUtil::ScanDirectory((Path::GetEditingGameDataFolder() + "/Fonts/").c_str(), "*.xml", fa, true); for (size_t i = 0; i < fa.size(); ++i) { - string name = fa[i].filename.toUtf8().data(); + AZStd::string name = fa[i].filename.toUtf8().data(); PathUtil::RemoveExtension(name); mv_font->AddEnumItem(name.c_str(), name.c_str()); } diff --git a/Code/Editor/TrackView/CommentNodeAnimator.cpp b/Code/Editor/TrackView/CommentNodeAnimator.cpp index bb60259203..2dd2cfbb22 100644 --- a/Code/Editor/TrackView/CommentNodeAnimator.cpp +++ b/Code/Editor/TrackView/CommentNodeAnimator.cpp @@ -92,7 +92,7 @@ void CCommentNodeAnimator::AnimateCommentTextTrack(CTrackViewTrack* pTrack, cons if (commentKey.m_duration > 0 && ac.time < keyHandle.GetTime() + commentKey.m_duration) { m_commentContext.m_strComment = commentKey.m_strComment; - cry_strcpy(m_commentContext.m_strFont, commentKey.m_strFont.c_str()); + azstrcpy(m_commentContext.m_strFont, AZ_ARRAY_SIZE(m_commentContext.m_strFont), commentKey.m_strFont.c_str()); m_commentContext.m_color = commentKey.m_color; m_commentContext.m_align = commentKey.m_align; m_commentContext.m_size = commentKey.m_size; diff --git a/Code/Editor/TrackView/SequenceKeyUIControls.cpp b/Code/Editor/TrackView/SequenceKeyUIControls.cpp index 7889b30848..c3bc39d65d 100644 --- a/Code/Editor/TrackView/SequenceKeyUIControls.cpp +++ b/Code/Editor/TrackView/SequenceKeyUIControls.cpp @@ -91,7 +91,7 @@ bool CSequenceKeyUIControls::OnKeySelectionChange(CTrackViewKeyBundle& selectedK bool bNotParent = !bNotMe || pCurrentSequence->IsAncestorOf(pSequence) == false; if (bNotMe && bNotParent) { - string seqName = pCurrentSequence->GetName(); + AZStd::string seqName = pCurrentSequence->GetName(); QString ownerIdString = CTrackViewDialog::GetEntityIdAsString(pCurrentSequence->GetSequenceComponentEntityId()); mv_sequence->AddEnumItem(seqName.c_str(), ownerIdString); diff --git a/Code/Editor/TrackView/TrackViewAnimNode.cpp b/Code/Editor/TrackView/TrackViewAnimNode.cpp index 685cdc528e..9edac32da0 100644 --- a/Code/Editor/TrackView/TrackViewAnimNode.cpp +++ b/Code/Editor/TrackView/TrackViewAnimNode.cpp @@ -1010,13 +1010,13 @@ bool CTrackViewAnimNode::SetName(const char* pName) } } - string oldName = GetName(); + AZStd::string oldName = GetName(); m_animNode->SetName(pName); CTrackViewSequence* sequence = GetSequence(); AZ_Assert(sequence, "Nodes should never have a null sequence."); - sequence->OnNodeRenamed(this, oldName); + sequence->OnNodeRenamed(this, oldName.c_str()); return true; } diff --git a/Code/Editor/TrackView/TrackViewDopeSheetBase.cpp b/Code/Editor/TrackView/TrackViewDopeSheetBase.cpp index accba34422..aa4ef94e9e 100644 --- a/Code/Editor/TrackView/TrackViewDopeSheetBase.cpp +++ b/Code/Editor/TrackView/TrackViewDopeSheetBase.cpp @@ -2808,10 +2808,10 @@ void CTrackViewDopeSheetBase::DrawKeys(CTrackViewTrack* pTrack, QPainter* painte } else { - cry_strcpy(keydesc, "{"); + azstrcpy(keydesc, AZ_ARRAY_SIZE(keydesc), "{"); } - cry_strcat(keydesc, pDescription); - cry_strcat(keydesc, "}"); + azstrcat(keydesc, AZ_ARRAY_SIZE(keydesc), pDescription); + azstrcat(keydesc, AZ_ARRAY_SIZE(keydesc), "}"); // Draw key description text. // Find next key. const QRect textRect(QPoint(x + 10, rect.top()), QPoint(x1, rect.bottom())); diff --git a/Code/Editor/TrackView/TrackViewFindDlg.cpp b/Code/Editor/TrackView/TrackViewFindDlg.cpp index 014618a62a..f67be3485e 100644 --- a/Code/Editor/TrackView/TrackViewFindDlg.cpp +++ b/Code/Editor/TrackView/TrackViewFindDlg.cpp @@ -61,7 +61,7 @@ void CTrackViewFindDlg::FillData() ObjName obj; obj.m_objName = pNode->GetName(); obj.m_directorName = pNode->HasDirectorAsParent() ? pNode->HasDirectorAsParent()->GetName() : ""; - string fullname = seq->GetName(); + AZStd::string fullname = seq->GetName(); obj.m_seqName = fullname.c_str(); m_objs.push_back(obj); } diff --git a/Code/Editor/TrackView/TrackViewNodes.cpp b/Code/Editor/TrackView/TrackViewNodes.cpp index daf99990a8..16baa72709 100644 --- a/Code/Editor/TrackView/TrackViewNodes.cpp +++ b/Code/Editor/TrackView/TrackViewNodes.cpp @@ -2516,7 +2516,7 @@ int CTrackViewNodesCtrl::GetMatNameAndSubMtlIndexFromName(QString& matName, cons if (const char* pCh = strstr(nodeName, ".[")) { char matPath[MAX_PATH]; - cry_strcpy(matPath, nodeName, (size_t)(pCh - nodeName)); + azstrncpy(matPath, AZ_ARRAY_SIZE(matPath), nodeName, (size_t)(pCh - nodeName)); matName = matPath; pCh += 2; if ((*pCh) != 0) diff --git a/Code/Editor/TrackView/TrackViewSequence.cpp b/Code/Editor/TrackView/TrackViewSequence.cpp index 7ccecd7292..3647c554dc 100644 --- a/Code/Editor/TrackView/TrackViewSequence.cpp +++ b/Code/Editor/TrackView/TrackViewSequence.cpp @@ -1073,7 +1073,7 @@ std::deque CTrackViewSequence::GetMatchingTracks(CTrackViewAni { std::deque matchingTracks; - const string trackName = trackNode->getAttr("name"); + const AZStd::string trackName = trackNode->getAttr("name"); CAnimParamType animParamType; animParamType.LoadFromXml(trackNode); @@ -1133,11 +1133,11 @@ void CTrackViewSequence::GetMatchedPasteLocationsRec(std::vectorgetChild(nodeIndex); - const string tagName = xmlChildNode->getTag(); + const AZStd::string tagName = xmlChildNode->getTag(); if (tagName == "Node") { - const string nodeName = xmlChildNode->getAttr("name"); + const AZStd::string nodeName = xmlChildNode->getAttr("name"); int nodeType = static_cast(AnimNodeType::Invalid); xmlChildNode->getAttr("type", nodeType); @@ -1159,7 +1159,7 @@ void CTrackViewSequence::GetMatchedPasteLocationsRec(std::vectorgetAttr("name"); + const AZStd::string trackName = xmlChildNode->getAttr("name"); CAnimParamType trackParamType; trackParamType.Serialize(xmlChildNode, true); diff --git a/Code/Editor/TrackViewNewSequenceDialog.cpp b/Code/Editor/TrackViewNewSequenceDialog.cpp index 30691b0215..0efc7a932e 100644 --- a/Code/Editor/TrackViewNewSequenceDialog.cpp +++ b/Code/Editor/TrackViewNewSequenceDialog.cpp @@ -81,7 +81,7 @@ void CTVNewSequenceDialog::OnOK() for (int k = 0; k < GetIEditor()->GetSequenceManager()->GetCount(); ++k) { CTrackViewSequence* pSequence = GetIEditor()->GetSequenceManager()->GetSequenceByIndex(k); - QString fullname = QtUtil::ToQString(pSequence->GetName()); + QString fullname = pSequence->GetName(); if (fullname.compare(m_sequenceName, Qt::CaseInsensitive) == 0) { diff --git a/Code/Editor/Util/AutoDirectoryRestoreFileDialog.cpp b/Code/Editor/Util/AutoDirectoryRestoreFileDialog.cpp index f5ba0c507d..a14303cd69 100644 --- a/Code/Editor/Util/AutoDirectoryRestoreFileDialog.cpp +++ b/Code/Editor/Util/AutoDirectoryRestoreFileDialog.cpp @@ -45,7 +45,7 @@ int CAutoDirectoryRestoreFileDialog::exec() foreach(const QString&fileName, selectedFiles()) { QFileInfo info(fileName); - if (!CryStringUtils::IsValidFileName(info.fileName().toStdString().c_str())) + if (!AZ::StringFunc::Path::IsValid(info.fileName().toStdString().c_str())) { QMessageBox::warning(this, tr("Error"), tr("Please select a valid file name (standard English alphanumeric characters only)")); problem = true; diff --git a/Code/Editor/Util/EditorUtils.cpp b/Code/Editor/Util/EditorUtils.cpp index 33c311ed76..de06a95a62 100644 --- a/Code/Editor/Util/EditorUtils.cpp +++ b/Code/Editor/Util/EditorUtils.cpp @@ -30,30 +30,6 @@ void HeapCheck::Check([[maybe_unused]] const char* file, [[maybe_unused]] int li _ASSERTE(_CrtCheckMemory()); #endif - /* - int heapstatus = _heapchk(); - switch( heapstatus ) - { - case _HEAPOK: - break; - case _HEAPEMPTY: - break; - case _HEAPBADBEGIN: - { - CString str; - str.Format( "Bad Start of Heap, at file %s line:%d",file,line ); - MessageBox( nullptr,str,"Heap Check",MB_OK ); - } - break; - case _HEAPBADNODE: - { - CString str; - str.Format( "Bad Node in Heap, at file %s line:%d",file,line ); - MessageBox( nullptr,str,"Heap Check",MB_OK ); - } - break; - } - */ #endif } diff --git a/Code/Editor/Util/EditorUtils.h b/Code/Editor/Util/EditorUtils.h index 355a1939c2..5008cbcc5c 100644 --- a/Code/Editor/Util/EditorUtils.h +++ b/Code/Editor/Util/EditorUtils.h @@ -18,6 +18,7 @@ #include #include "Util/FileUtil.h" #include +#include //! Typedef for quaternion. //typedef CryQuat Quat; diff --git a/Code/Editor/Util/FileUtil.cpp b/Code/Editor/Util/FileUtil.cpp index 93e854bf1a..f26ffa60ec 100644 --- a/Code/Editor/Util/FileUtil.cpp +++ b/Code/Editor/Util/FileUtil.cpp @@ -264,7 +264,7 @@ void CFileUtil::EditTextureFile(const char* textureFile, [[maybe_unused]] bool b } bool failedToLaunch = true; - QByteArray textureEditorPath = gSettings.textureEditor.toUtf8(); + const QString& textureEditorPath = gSettings.textureEditor; // Give the user a warning if they don't have a texture editor configured if (textureEditorPath.isEmpty()) @@ -278,8 +278,7 @@ void CFileUtil::EditTextureFile(const char* textureFile, [[maybe_unused]] bool b // Use the Win32 API calls to open the right editor; the OS knows how to do this even better than // Qt does. QString fullTexturePathFixedForWindows = QString(fullTexturePath.data()).replace('/', '\\'); - QByteArray fullTexturePathFixedForWindowsUtf8 = fullTexturePathFixedForWindows.toUtf8(); - HINSTANCE hInst = ShellExecute(nullptr, "open", textureEditorPath.data(), fullTexturePathFixedForWindowsUtf8.data(), nullptr, SW_SHOWNORMAL); + HINSTANCE hInst = ShellExecuteW(nullptr, L"open", textureEditorPath.toStdWString().c_str(), fullTexturePathFixedForWindows.toStdWString().c_str(), nullptr, SW_SHOWNORMAL); failedToLaunch = ((DWORD_PTR)hInst <= 32); #elif defined(AZ_PLATFORM_MAC) failedToLaunch = QProcess::execute(QString("/usr/bin/open"), {"-a", gSettings.textureEditor, QString(fullTexturePath.data()) }) != 0; @@ -298,7 +297,7 @@ void CFileUtil::EditTextureFile(const char* textureFile, [[maybe_unused]] bool b ////////////////////////////////////////////////////////////////////////// bool CFileUtil::EditMayaFile(const char* filepath, const bool bExtractFromPak, const bool bUseGameFolder) { - QString dosFilepath = QtUtil::ToQString(PathUtil::ToDosPath(filepath)); + QString dosFilepath = PathUtil::ToDosPath(filepath).c_str(); if (bExtractFromPak) { ExtractFile(dosFilepath); @@ -313,7 +312,7 @@ bool CFileUtil::EditMayaFile(const char* filepath, const bool bExtractFromPak, c dosFilepath = sGameFolder + '\\' + filepath; } - dosFilepath = PathUtil::ToDosPath(dosFilepath.toUtf8().data()); + dosFilepath = PathUtil::ToDosPath(dosFilepath.toUtf8().data()).c_str(); } const char* engineRoot; @@ -1304,7 +1303,7 @@ IFileUtil::ECopyTreeResult CFileUtil::CopyTree(const QString& strSourceDirectory // all with the same names and all with the same files names inside. If you would make a depth-first search // you could end up with the files from the deepest folder in ALL your folders. - std::vector ignoredPatterns; + std::vector ignoredPatterns; StringHelpers::Split(ignoreFilesAndFolders, "|", false, ignoredPatterns); QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags; @@ -1330,7 +1329,7 @@ IFileUtil::ECopyTreeResult CFileUtil::CopyTree(const QString& strSourceDirectory const QString fileName = QFileInfo(filePath).fileName(); bool ignored = false; - for (const string& ignoredFile : ignoredPatterns) + for (const AZStd::string& ignoredFile : ignoredPatterns) { if (StringHelpers::CompareIgnoreCase(fileName.toStdString().c_str(), ignoredFile.c_str()) == 0) { @@ -2159,13 +2158,14 @@ uint32 CFileUtil::GetAttributes(const char* filename, bool bUseSourceControl /*= return SCC_FILE_ATTRIBUTE_READONLY | SCC_FILE_ATTRIBUTE_INPAK; } - DWORD dwAttrib = ::GetFileAttributes(file.GetAdjustedFilename()); - if (dwAttrib == INVALID_FILE_ATTRIBUTES) + + const char* adjustedFile = file.GetAdjustedFilename(); + if (!AZ::IO::SystemFile::Exists(adjustedFile)) { return SCC_FILE_ATTRIBUTE_INVALID; } - if (dwAttrib & FILE_ATTRIBUTE_READONLY) + if (!AZ::IO::SystemFile::IsWritable(adjustedFile)) { return SCC_FILE_ATTRIBUTE_NORMAL | SCC_FILE_ATTRIBUTE_READONLY; } diff --git a/Code/Editor/Util/FileUtil.h b/Code/Editor/Util/FileUtil.h index 3be66d6e96..d4c9ebdd06 100644 --- a/Code/Editor/Util/FileUtil.h +++ b/Code/Editor/Util/FileUtil.h @@ -10,7 +10,6 @@ #pragma once #include "CryThread.h" -#include "StringUtils.h" #include "../Include/SandboxAPI.h" #include #include diff --git a/Code/Editor/Util/IXmlHistoryManager.h b/Code/Editor/Util/IXmlHistoryManager.h deleted file mode 100644 index 20f9dd4573..0000000000 --- a/Code/Editor/Util/IXmlHistoryManager.h +++ /dev/null @@ -1,73 +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 CRYINCLUDE_EDITOR_UTIL_IXMLHISTORYMANAGER_H -#define CRYINCLUDE_EDITOR_UTIL_IXMLHISTORYMANAGER_H -#pragma once - - -// Helper class to handle Redo/Undo on set of Xml nodes -struct IXmlUndoEventHandler -{ - virtual bool SaveToXml(XmlNodeRef& xmlNode) = 0; - virtual bool LoadFromXml(const XmlNodeRef& xmlNode) = 0; - virtual bool ReloadFromXml(const XmlNodeRef& xmlNode) = 0; -}; - -struct IXmlHistoryEventListener -{ - enum EHistoryEventType - { - eHET_HistoryDeleted, - eHET_HistoryCleared, - eHET_HistorySaved, - - eHET_VersionChanged, - eHET_VersionAdded, - - eHET_HistoryInvalidate, - - eHET_HistoryGroupChanged, - eHET_HistoryGroupAdded, - eHET_HistoryGroupRemoved, - }; - virtual void OnEvent(EHistoryEventType event, void* pData = nullptr) = 0; -}; - -struct IXmlHistoryView -{ - virtual bool LoadXml(int typeId, const XmlNodeRef& xmlNode, IXmlUndoEventHandler*& pUndoEventHandler, uint32 userindex) = 0; - virtual void UnloadXml(int typeId) = 0; -}; - -struct IXmlHistoryManager -{ - // Undo/Redo - virtual bool Undo() = 0; - virtual bool Redo() = 0; - virtual bool Goto(int historyNum) = 0; - virtual void RecordUndo(IXmlUndoEventHandler* pEventHandler, const char* desc) = 0; - virtual void UndoEventHandlerDestroyed(IXmlUndoEventHandler* pEventHandler, uint32 typeId = 0, bool destoryForever = false) = 0; - virtual void RestoreUndoEventHandler(IXmlUndoEventHandler* pEventHandler, uint32 typeId) = 0; - - virtual void RegisterEventListener(IXmlHistoryEventListener* pEventListener) = 0; - virtual void UnregisterEventListener(IXmlHistoryEventListener* pEventListener) = 0; - - // History - virtual void ClearHistory(bool flagAsSaved = false) = 0; - virtual int GetVersionCount() const = 0; - virtual const string& GetVersionDesc(int number) const = 0; - virtual int GetCurrentVersionNumber() const = 0; - - // Views - virtual void RegisterView(IXmlHistoryView* pView) = 0; - virtual void UnregisterView(IXmlHistoryView* pView) = 0; -}; - -#endif // CRYINCLUDE_EDITOR_UTIL_IXMLHISTORYMANAGER_H diff --git a/Code/Editor/Util/ImageASC.cpp b/Code/Editor/Util/ImageASC.cpp index c018018196..11dad7b696 100644 --- a/Code/Editor/Util/ImageASC.cpp +++ b/Code/Editor/Util/ImageASC.cpp @@ -24,8 +24,7 @@ bool CImageASC::Save(const QString& fileName, const CFloatImage& image) uint32 height = image.GetHeight(); float* pixels = image.GetData(); - string fileHeader; - fileHeader.Format( + AZStd::string fileHeader = AZStd::string::format( // Number of columns and rows in the data "ncols %d\n" "nrows %d\n" diff --git a/Code/Editor/Util/ImageTIF.cpp b/Code/Editor/Util/ImageTIF.cpp index c4f21855a4..25e4296154 100644 --- a/Code/Editor/Util/ImageTIF.cpp +++ b/Code/Editor/Util/ImageTIF.cpp @@ -399,8 +399,8 @@ bool CImageTIF::SaveRAW(const QString& fileName, const void* pData, int width, i if (preset && preset[0]) { - string tiffphotoshopdata, valueheader; - string presetkeyvalue = string("/preset=") + string(preset); + AZStd::string tiffphotoshopdata, valueheader; + AZStd::string presetkeyvalue = AZStd::string("/preset=") + AZStd::string(preset); valueheader.push_back('\x1C'); valueheader.push_back('\x02'); @@ -472,7 +472,7 @@ const char* CImageTIF::GetPreset(const QString& fileName) libtiffDummyWriteProc, libtiffDummySeekProc, libtiffDummyCloseProc, libtiffDummySizeProc, libtiffDummyMapFileProc, libtiffDummyUnmapFileProc); - string strReturn; + AZStd::string strReturn; char* preset = nullptr; int size; if (tif) diff --git a/Code/Editor/Util/ImageUtil.cpp b/Code/Editor/Util/ImageUtil.cpp index 3d121a1d47..5753e0a138 100644 --- a/Code/Editor/Util/ImageUtil.cpp +++ b/Code/Editor/Util/ImageUtil.cpp @@ -86,8 +86,7 @@ bool CImageUtil::SavePGM(const QString& fileName, const CImageEx& image) uint32* pixels = image.GetData(); // Create the file header. - string fileHeader; - fileHeader.Format( + AZStd::string fileHeader = AZStd::string::format( // P2 = PGM header for ASCII output. (P5 is PGM header for binary output) "P2\n" // width and height of the image diff --git a/Code/Editor/Util/PathUtil.cpp b/Code/Editor/Util/PathUtil.cpp index 2be09da06f..c9e6823824 100644 --- a/Code/Editor/Util/PathUtil.cpp +++ b/Code/Editor/Util/PathUtil.cpp @@ -15,24 +15,21 @@ #include // for ebus events #include #include +#include +#include #include -namespace -{ - string g_currentModName; // folder name only! -} - namespace Path { ////////////////////////////////////////////////////////////////////////// void SplitPath(const QString& rstrFullPathFilename, QString& rstrDriveLetter, QString& rstrDirectory, QString& rstrFilename, QString& rstrExtension) { - string strFullPathString(rstrFullPathFilename.toUtf8().data()); - string strDriveLetter; - string strDirectory; - string strFilename; - string strExtension; + AZStd::string strFullPathString(rstrFullPathFilename.toUtf8().data()); + AZStd::string strDriveLetter; + AZStd::string strDirectory; + AZStd::string strFilename; + AZStd::string strExtension; char* szPath((char*)strFullPathString.c_str()); char* pchLastPosition(szPath); @@ -81,16 +78,16 @@ namespace Path strFilename.assign(pchLastPosition, pchCurrentPosition); } - rstrDriveLetter = strDriveLetter; - rstrDirectory = strDirectory; - rstrFilename = strFilename; - rstrExtension = strExtension; + rstrDriveLetter = strDriveLetter.c_str(); + rstrDirectory = strDirectory.c_str(); + rstrFilename = strFilename.c_str(); + rstrExtension = strExtension.c_str(); } ////////////////////////////////////////////////////////////////////////// void GetDirectoryQueue(const QString& rstrSourceDirectory, QStringList& rcstrDirectoryTree) { - string strCurrentDirectoryName; - string strSourceDirectory(rstrSourceDirectory.toUtf8().data()); + AZStd::string strCurrentDirectoryName; + AZStd::string strSourceDirectory(rstrSourceDirectory.toUtf8().data()); const char* szSourceDirectory(strSourceDirectory.c_str()); const char* pchCurrentPosition(szSourceDirectory); const char* pchLastPosition(szSourceDirectory); @@ -207,14 +204,7 @@ namespace Path bool IsFolder(const char* pPath) { - DWORD attrs = GetFileAttributes(pPath); - - if (attrs == FILE_ATTRIBUTE_DIRECTORY) - { - return true; - } - - return false; + return AZ::IO::FileIOBase::GetInstance()->IsDirectory(pPath); } ////////////////////////////////////////////////////////////////////////// @@ -255,16 +245,16 @@ namespace Path /// Get the data folder AZStd::string GetEditingGameDataFolder() { - // query the editor root. The bus exists in case we want tools to be able to override this. + // Define here the mod name + static AZ::IO::FixedMaxPathString s_currentModName; - - if (g_currentModName.empty()) + if (s_currentModName.empty()) { return GetGameAssetsFolder(); } AZStd::string str(GetGameAssetsFolder()); str += "Mods\\"; - str += g_currentModName; + str += s_currentModName.c_str(); return str; } diff --git a/Code/Editor/Util/PathUtil.h b/Code/Editor/Util/PathUtil.h index 868d9843ab..2c49031155 100644 --- a/Code/Editor/Util/PathUtil.h +++ b/Code/Editor/Util/PathUtil.h @@ -93,7 +93,7 @@ namespace Path #endif file = path_buffer; } - inline void Split(const string& filepath, string& path, string& file) + inline void Split(const AZStd::string& filepath, AZStd::string& path, AZStd::string& file) { char path_buffer[_MAX_PATH]; char drive[_MAX_DRIVE]; @@ -101,12 +101,12 @@ namespace Path char fname[_MAX_FNAME]; char ext[_MAX_EXT]; #ifdef AZ_COMPILER_MSVC - _splitpath_s(filepath, drive, AZ_ARRAY_SIZE(drive), dir, AZ_ARRAY_SIZE(dir), 0, 0, 0, 0); + _splitpath_s(filepath.c_str(), drive, AZ_ARRAY_SIZE(drive), dir, AZ_ARRAY_SIZE(dir), 0, 0, 0, 0); _makepath_s(path_buffer, AZ_ARRAY_SIZE(path_buffer), drive, dir, 0, 0); path = path_buffer; _makepath_s(path_buffer, AZ_ARRAY_SIZE(path_buffer), 0, 0, fname, ext); #else - _splitpath(filepath, drive, dir, fname, ext); + _splitpath(filepath.c_str(), drive, dir, fname, ext); _makepath(path_buffer, drive, dir, 0, 0); path = path_buffer; _makepath(path_buffer, 0, 0, fname, ext); @@ -137,7 +137,7 @@ namespace Path filename = fname; fext = ext; } - inline void Split(const string& filepath, string& path, string& filename, string& fext) + inline void Split(const AZStd::string& filepath, AZStd::string& path, AZStd::string& filename, AZStd::string& fext) { char path_buffer[_MAX_PATH]; char drive[_MAX_DRIVE]; @@ -145,10 +145,10 @@ namespace Path char fname[_MAX_FNAME]; char ext[_MAX_EXT]; #ifdef AZ_COMPILER_MSVC - _splitpath_s(filepath, drive, AZ_ARRAY_SIZE(drive), dir, AZ_ARRAY_SIZE(dir), fname, AZ_ARRAY_SIZE(fname), ext, AZ_ARRAY_SIZE(ext)); + _splitpath_s(filepath.c_str(), drive, AZ_ARRAY_SIZE(drive), dir, AZ_ARRAY_SIZE(dir), fname, AZ_ARRAY_SIZE(fname), ext, AZ_ARRAY_SIZE(ext)); _makepath_s(path_buffer, AZ_ARRAY_SIZE(path_buffer), drive, dir, 0, 0); #else - _splitpath(filepath, drive, dir, fname, ext); + _splitpath(filepath.c_str(), drive, dir, fname, ext); _makepath(path_buffer, drive, dir, 0, 0); #endif path = path_buffer; @@ -230,7 +230,7 @@ namespace Path } template - inline bool EndsWithSlash(CryStackStringT* path) + inline bool EndsWithSlash(AZStd::fixed_string* path) { if ((!path) || (path->empty())) { @@ -271,7 +271,7 @@ namespace Path } template - inline void AddBackslash(CryStackStringT* path) + inline void AddBackslash(AZStd::fixed_string* path) { if (path->empty()) { @@ -284,7 +284,7 @@ namespace Path } template - inline void AddSlash(CryStackStringT* path) + inline void AddSlash(AZStd::fixed_string* path) { if (path->empty()) { @@ -357,7 +357,7 @@ namespace Path { return CaselessPaths(GetRelativePath(path, true)); } - inline string FullPathToGamePath(const char* path) + inline AZStd::string FullPathToGamePath(const char* path) { return CaselessPaths(GetRelativePath(path, true)).toUtf8().data(); } @@ -394,7 +394,7 @@ namespace Path inline QString GetAudioLocalizationFolder(bool returnAbsolutePath) { // Omit the trailing slash! - QString sLocalizationFolder(QString(PathUtil::GetLocalizationFolder()).left(static_cast(PathUtil::GetLocalizationFolder().size()) - 1)); + QString sLocalizationFolder(QString(PathUtil::GetLocalizationFolder().c_str()).left(static_cast(PathUtil::GetLocalizationFolder().size()) - 1)); if (!sLocalizationFolder.isEmpty()) { diff --git a/Code/Editor/Util/StringHelpers.cpp b/Code/Editor/Util/StringHelpers.cpp index 5d37dfef77..6c819270bd 100644 --- a/Code/Editor/Util/StringHelpers.cpp +++ b/Code/Editor/Util/StringHelpers.cpp @@ -7,87 +7,15 @@ */ -#include #include "StringHelpers.h" #include "Util.h" -#include "StringUtils.h" // From CryCommon -#include "UnicodeFunctions.h" -#include -#include -#include // WideCharToMultibyte(), CP_UTF8, etc. -#include +#include -static inline char ToLower(const char c) -{ - return tolower(c); -} - -static inline wchar_t ToLower(const wchar_t c) -{ - return towlower(c); -} - - -static inline char ToUpper(const char c) -{ - return toupper(c); -} - -static inline wchar_t ToUpper(const wchar_t c) -{ - return towupper(c); -} - - -static inline int Vscprintf(const char* format, va_list argList) -{ -#if defined(AZ_PLATFORM_WINDOWS) - return _vscprintf(format, argList); -#elif AZ_TRAIT_OS_PLATFORM_APPLE || defined(AZ_PLATFORM_LINUX) - int retval; - va_list argcopy; - va_copy(argcopy, argList); - retval = azvsnprintf(nullptr, 0, format, argcopy); - va_end(argcopy); - return retval; -#else - #error Not supported! -#endif -} - -static inline int Vscprintf(const wchar_t* format, va_list argList) -{ -#if defined(AZ_PLATFORM_WINDOWS) - return _vscwprintf(format, argList); -#elif AZ_TRAIT_OS_PLATFORM_APPLE || defined(AZ_PLATFORM_LINUX) - int retval; - va_list argcopy; - va_copy(argcopy, argList); - retval = azvsnwprintf(nullptr, 0, format, argcopy); - va_end(argcopy); - return retval; -#else - #error Not supported! -#endif -} - - -static inline int Vsnprintf_s(char* str, size_t sizeInBytes, [[maybe_unused]] size_t count, const char* format, va_list argList) -{ - return azvsnprintf(str, sizeInBytes, format, argList); -} - -static inline int Vsnprintf_s(wchar_t* str, size_t sizeInBytes, [[maybe_unused]] size_t count, const wchar_t* format, va_list argList) -{ - return azvsnwprintf(str, sizeInBytes, format, argList); -} - - -int StringHelpers::Compare(const string& str0, const string& str1) +int StringHelpers::CompareIgnoreCase(const AZStd::string& str0, const AZStd::string& str1) { const size_t minLength = Util::getMin(str0.length(), str1.length()); - const int result = std::memcmp(str0.c_str(), str1.c_str(), minLength); + const int result = azstrnicmp(str0.c_str(), str1.c_str(), minLength); if (result) { return result; @@ -100,42 +28,7 @@ int StringHelpers::Compare(const string& str0, const string& str1) } } -int StringHelpers::Compare(const wstring& str0, const wstring& str1) -{ - const size_t minLength = Util::getMin(str0.length(), str1.length()); - for (size_t i = 0; i < minLength; ++i) - { - const wchar_t c0 = str0[i]; - const wchar_t c1 = str1[i]; - if (c0 != c1) - { - return (c0 < c1) ? -1 : 1; - } - } - - return (str0.length() == str1.length()) - ? 0 - : ((str0.length() < str1.length()) ? -1 : +1); -} - - -int StringHelpers::CompareIgnoreCase(const string& str0, const string& str1) -{ - const size_t minLength = Util::getMin(str0.length(), str1.length()); - const int result = azmemicmp(str0.c_str(), str1.c_str(), minLength); - if (result) - { - return result; - } - else - { - return (str0.length() == str1.length()) - ? 0 - : ((str0.length() < str1.length()) ? -1 : +1); - } -} - -int StringHelpers::CompareIgnoreCase(const wstring& str0, const wstring& str1) +int StringHelpers::CompareIgnoreCase(const AZStd::wstring& str0, const AZStd::wstring& str1) { const size_t minLength = Util::getMin(str0.length(), str1.length()); for (size_t i = 0; i < minLength; ++i) @@ -153,522 +46,6 @@ int StringHelpers::CompareIgnoreCase(const wstring& str0, const wstring& str1) : ((str0.length() < str1.length()) ? -1 : +1); } - -bool StringHelpers::Equals(const string& str0, const string& str1) -{ - if (str0.length() != str1.length()) - { - return false; - } - return std::memcmp(str0.c_str(), str1.c_str(), str1.length()) == 0; -} - -bool StringHelpers::Equals(const wstring& str0, const wstring& str1) -{ - if (str0.length() != str1.length()) - { - return false; - } - return std::memcmp(str0.c_str(), str1.c_str(), str1.length() * sizeof(wstring::value_type)) == 0; -} - - -bool StringHelpers::EqualsIgnoreCase(const string& str0, const string& str1) -{ - if (str0.length() != str1.length()) - { - return false; - } - return azmemicmp(str0.c_str(), str1.c_str(), str1.length()) == 0; -} - -bool StringHelpers::EqualsIgnoreCase(const wstring& str0, const wstring& str1) -{ - const size_t str1Length = str1.length(); - if (str0.length() != str1Length) - { - return false; - } - for (size_t i = 0; i < str1Length; ++i) - { - if (towlower(str0[i]) != towlower(str1[i])) - { - return false; - } - } - return true; -} - - -bool StringHelpers::StartsWith(const string& str, const string& pattern) -{ - if (str.length() < pattern.length()) - { - return false; - } - return std::memcmp(str.c_str(), pattern.c_str(), pattern.length()) == 0; -} - -bool StringHelpers::StartsWith(const wstring& str, const wstring& pattern) -{ - if (str.length() < pattern.length()) - { - return false; - } - return std::memcmp(str.c_str(), pattern.c_str(), pattern.length() * sizeof(wstring::value_type)) == 0; -} - - -bool StringHelpers::StartsWithIgnoreCase(const string& str, const string& pattern) -{ - if (str.length() < pattern.length()) - { - return false; - } - return azmemicmp(str.c_str(), pattern.c_str(), pattern.length()) == 0; -} - -bool StringHelpers::StartsWithIgnoreCase(const wstring& str, const wstring& pattern) -{ - const size_t patternLength = pattern.length(); - if (str.length() < patternLength) - { - return false; - } - for (size_t i = 0; i < patternLength; ++i) - { - if (towlower(str[i]) != towlower(pattern[i])) - { - return false; - } - } - return true; -} - - -bool StringHelpers::EndsWith(const string& str, const string& pattern) -{ - if (str.length() < pattern.length()) - { - return false; - } - return std::memcmp(str.c_str() + str.length() - pattern.length(), pattern.c_str(), pattern.length()) == 0; -} - -bool StringHelpers::EndsWith(const wstring& str, const wstring& pattern) -{ - if (str.length() < pattern.length()) - { - return false; - } - return std::memcmp(str.c_str() + str.length() - pattern.length(), pattern.c_str(), pattern.length() * sizeof(wstring::value_type)) == 0; -} - - -bool StringHelpers::EndsWithIgnoreCase(const string& str, const string& pattern) -{ - if (str.length() < pattern.length()) - { - return false; - } - return azmemicmp(str.c_str() + str.length() - pattern.length(), pattern.c_str(), pattern.length()) == 0; -} - -bool StringHelpers::EndsWithIgnoreCase(const wstring& str, const wstring& pattern) -{ - const size_t patternLength = pattern.length(); - if (str.length() < patternLength) - { - return false; - } - for (size_t i = str.length() - patternLength, j = 0; i < patternLength; ++i, ++j) - { - if (towlower(str[i]) != towlower(pattern[j])) - { - return false; - } - } - return true; -} - - -bool StringHelpers::Contains(const string& str, const string& pattern) -{ - const size_t patternLength = pattern.length(); - if (str.length() < patternLength) - { - return false; - } - const size_t n = str.length() - patternLength + 1; - for (size_t i = 0; i < n; ++i) - { - if (std::memcmp(str.c_str() + i, pattern.c_str(), patternLength) == 0) - { - return true; - } - } - return false; -} - -bool StringHelpers::Contains(const wstring& str, const wstring& pattern) -{ - const size_t patternLength = pattern.length(); - if (str.length() < patternLength) - { - return false; - } - const size_t n = str.length() - patternLength + 1; - for (size_t i = 0; i < n; ++i) - { - if (std::memcmp(str.c_str() + i, pattern.c_str(), patternLength * sizeof(wstring::value_type)) == 0) - { - return true; - } - } - return false; -} - - -bool StringHelpers::ContainsIgnoreCase(const string& str, const string& pattern) -{ - const size_t patternLength = pattern.length(); - if (str.length() < patternLength) - { - return false; - } - const size_t n = str.length() - patternLength + 1; - for (size_t i = 0; i < n; ++i) - { - if (azmemicmp(str.c_str() + i, pattern.c_str(), patternLength) == 0) - { - return true; - } - } - return false; -} - -bool StringHelpers::ContainsIgnoreCase(const wstring& str, const wstring& pattern) -{ - const size_t patternLength = pattern.length(); - if (patternLength == 0) - { - return true; - } - if (str.length() < patternLength) - { - return false; - } - - const wstring::value_type firstPatternLetter = towlower(pattern[0]); - const size_t n = str.length() - patternLength + 1; - for (size_t i = 0; i < n; ++i) - { - bool match = true; - for (size_t j = 0; j < patternLength; ++j) - { - if (towlower(str[i + j]) != towlower(pattern[j])) - { - match = false; - break; - } - } - if (match) - { - return true; - } - } - return false; -} - -bool StringHelpers::MatchesWildcards(const string& str, const string& wildcards) -{ - using namespace CryStringUtils_Internal; - return MatchesWildcards_Tpl(str.c_str(), wildcards.c_str()); -} - -bool StringHelpers::MatchesWildcards(const wstring& str, const wstring& wildcards) -{ - using namespace CryStringUtils_Internal; - return MatchesWildcards_Tpl(str.c_str(), wildcards.c_str()); -} - -bool StringHelpers::MatchesWildcardsIgnoreCase(const string& str, const string& wildcards) -{ - using namespace CryStringUtils_Internal; - return MatchesWildcards_Tpl(str.c_str(), wildcards.c_str()); -} - -bool StringHelpers::MatchesWildcardsIgnoreCase(const wstring& str, const wstring& wildcards) -{ - using namespace CryStringUtils_Internal; - return MatchesWildcards_Tpl(str.c_str(), wildcards.c_str()); -} - - -template -static inline bool MatchesWildcardsIgnoreCaseExt_Tpl(const TS& str, const TS& wildcards, std::vector& wildcardMatches) -{ - const typename TS::value_type* savedStrBegin = nullptr; - const typename TS::value_type* savedStrEnd = nullptr; - const typename TS::value_type* savedWild = nullptr; - size_t savedWildCount = 0; - - const typename TS::value_type* pStr = str.c_str(); - const typename TS::value_type* pWild = wildcards.c_str(); - size_t wildCount = 0; - - while ((*pStr) && (*pWild != '*')) - { - if (*pWild == '?') - { - wildcardMatches.push_back(TS(pStr, pStr + 1)); - ++wildCount; - } - else if (ToLower(*pWild) != ToLower(*pStr)) - { - wildcardMatches.resize(wildcardMatches.size() - wildCount); - return false; - } - ++pWild; - ++pStr; - } - - while (*pStr) - { - if (*pWild == '*') - { - if (!pWild[1]) - { - wildcardMatches.push_back(TS(pStr)); - return true; - } - savedWild = pWild++; - savedStrBegin = pStr; - savedStrEnd = pStr; - savedWildCount = wildCount; - wildcardMatches.push_back(TS(savedStrBegin, savedStrEnd)); - ++wildCount; - } - else if (*pWild == '?') - { - wildcardMatches.push_back(TS(pStr, pStr + 1)); - ++wildCount; - ++pWild; - ++pStr; - } - else if (ToLower(*pWild) == ToLower(*pStr)) - { - ++pWild; - ++pStr; - } - else - { - wildcardMatches.resize(wildcardMatches.size() - (wildCount - savedWildCount)); - wildCount = savedWildCount; - ++savedStrEnd; - pWild = savedWild + 1; - pStr = savedStrEnd; - wildcardMatches.push_back(TS(savedStrBegin, savedStrEnd)); - ++wildCount; - } - } - - while (*pWild == '*') - { - ++pWild; - wildcardMatches.push_back(TS()); - ++wildCount; - } - - if (*pWild) - { - wildcardMatches.resize(wildcardMatches.size() - wildCount); - return false; - } - - return true; -} - -bool StringHelpers::MatchesWildcardsIgnoreCaseExt(const string& str, const string& wildcards, std::vector& wildcardMatches) -{ - return MatchesWildcardsIgnoreCaseExt_Tpl(str, wildcards, wildcardMatches); -} - -bool StringHelpers::MatchesWildcardsIgnoreCaseExt(const wstring& str, const wstring& wildcards, std::vector& wildcardMatches) -{ - return MatchesWildcardsIgnoreCaseExt_Tpl(str, wildcards, wildcardMatches); -} - - -string StringHelpers::TrimLeft(const string& s) -{ - const size_t first = s.find_first_not_of(" \r\t"); - return (first == s.npos) ? string() : s.substr(first); -} - -wstring StringHelpers::TrimLeft(const wstring& s) -{ - const size_t first = s.find_first_not_of(L" \r\t"); - return (first == s.npos) ? wstring() : s.substr(first); -} - - -string StringHelpers::TrimRight(const string& s) -{ - const size_t last = s.find_last_not_of(" \r\t"); - return (last == s.npos) ? s : s.substr(0, last + 1); -} - -wstring StringHelpers::TrimRight(const wstring& s) -{ - const size_t last = s.find_last_not_of(L" \r\t"); - return (last == s.npos) ? s : s.substr(0, last + 1); -} - - -string StringHelpers::Trim(const string& s) -{ - return TrimLeft(TrimRight(s)); -} - -wstring StringHelpers::Trim(const wstring& s) -{ - return TrimLeft(TrimRight(s)); -} - - -template -static inline TS RemoveDuplicateSpaces_Tpl(const TS& s) -{ - TS res; - bool spaceFound = false; - - for (size_t i = 0, n = s.length(); i < n; ++i) - { - if ((s[i] == ' ') || (s[i] == '\r') || (s[i] == '\t')) - { - spaceFound = true; - } - else - { - if (spaceFound) - { - res += ' '; - spaceFound = false; - } - res += s[i]; - } - } - - if (spaceFound) - { - res += ' '; - } - return res; -} - -string StringHelpers::RemoveDuplicateSpaces(const string& s) -{ - return RemoveDuplicateSpaces_Tpl(s); -} - -wstring StringHelpers::RemoveDuplicateSpaces(const wstring& s) -{ - return RemoveDuplicateSpaces_Tpl(s); -} - - -template -static inline TS MakeLowerCase_Tpl(const TS& s) -{ - TS copy; - copy.reserve(s.length()); - for (typename TS::const_iterator it = s.begin(), end = s.end(); it != end; ++it) - { - copy.append(1, ToLower(*it)); - } - return copy; -} - -string StringHelpers::MakeLowerCase(const string& s) -{ - return MakeLowerCase_Tpl(s); -} - -wstring StringHelpers::MakeLowerCase(const wstring& s) -{ - return MakeLowerCase_Tpl(s); -} - - -template -static inline TS MakeUpperCase_Tpl(const TS& s) -{ - TS copy; - copy.reserve(s.length()); - for (typename TS::const_iterator it = s.begin(), end = s.end(); it != end; ++it) - { - copy.append(1, ToUpper(*it)); - } - return copy; -} - -string StringHelpers::MakeUpperCase(const string& s) -{ - return MakeUpperCase_Tpl(s); -} - -wstring StringHelpers::MakeUpperCase(const wstring& s) -{ - return MakeUpperCase_Tpl(s); -} - - -template -static inline TS Replace_Tpl(const TS& s, const typename TS::value_type oldChar, const typename TS::value_type newChar) -{ - TS copy; - copy.reserve(s.length()); - for (typename TS::const_iterator it = s.begin(), end = s.end(); it != end; ++it) - { - const typename TS::value_type c = (*it); - copy.append(1, ((c == oldChar) ? newChar : c)); - } - return copy; -} - -string StringHelpers::Replace(const string& s, char oldChar, char newChar) -{ - return Replace_Tpl(s, oldChar, newChar); -} - -wstring StringHelpers::Replace(const wstring& s, wchar_t oldChar, wchar_t newChar) -{ - return Replace_Tpl(s, oldChar, newChar); -} - - -void StringHelpers::ConvertStringByRef(string& out, const string& in) -{ - out = in; -} - -void StringHelpers::ConvertStringByRef(wstring& out, const string& in) -{ - Unicode::Convert(out, in); -} - -void StringHelpers::ConvertStringByRef(string& out, const wstring& in) -{ - Unicode::Convert(out, in); -} - -void StringHelpers::ConvertStringByRef(wstring& out, const wstring& in) -{ - out = in; -} - - template static inline void Split_Tpl(const TS& str, const TS& separator, bool bReturnEmptyPartsToo, std::vector& outParts) { @@ -708,348 +85,12 @@ static inline void Split_Tpl(const TS& str, const TS& separator, bool bReturnEmp } } - -template -static inline void SplitByAnyOf_Tpl(const TS& str, const TS& separators, bool bReturnEmptyPartsToo, std::vector& outParts) -{ - if (str.empty()) - { - return; - } - - if (separators.empty()) - { - for (size_t i = 0; i < str.length(); ++i) - { - outParts.push_back(str.substr(i, 1)); - } - return; - } - - size_t partStart = 0; - - for (;; ) - { - const size_t pos = str.find_first_of(separators, partStart); - if (pos == TS::npos) - { - break; - } - if (bReturnEmptyPartsToo || (pos > partStart)) - { - outParts.push_back(str.substr(partStart, pos - partStart)); - } - partStart = pos + 1; - } - - if (bReturnEmptyPartsToo || (partStart < str.length())) - { - outParts.push_back(str.substr(partStart, str.length() - partStart)); - } -} - - - -void StringHelpers::Split(const string& str, const string& separator, bool bReturnEmptyPartsToo, std::vector& outParts) +void StringHelpers::Split(const AZStd::string& str, const AZStd::string& separator, bool bReturnEmptyPartsToo, std::vector& outParts) { Split_Tpl(str, separator, bReturnEmptyPartsToo, outParts); } -void StringHelpers::Split(const wstring& str, const wstring& separator, bool bReturnEmptyPartsToo, std::vector& outParts) +void StringHelpers::Split(const AZStd::wstring& str, const AZStd::wstring& separator, bool bReturnEmptyPartsToo, std::vector& outParts) { Split_Tpl(str, separator, bReturnEmptyPartsToo, outParts); } - - -void StringHelpers::SplitByAnyOf(const string& str, const string& separators, bool bReturnEmptyPartsToo, std::vector& outParts) -{ - SplitByAnyOf_Tpl(str, separators, bReturnEmptyPartsToo, outParts); -} - -void StringHelpers::SplitByAnyOf(const wstring& str, const wstring& separators, bool bReturnEmptyPartsToo, std::vector& outParts) -{ - SplitByAnyOf_Tpl(str, separators, bReturnEmptyPartsToo, outParts); -} - - -template -static inline TS FormatVA_Tpl(const typename TS::value_type* const format, va_list parg) -{ - if ((format == nullptr) || (format[0] == 0)) - { - return TS(); - } - - std::vector bf; - size_t capacity = 0; - - size_t wantedCapacity = Vscprintf(format, parg); - wantedCapacity += 2; // '+ 2' to prevent uncertainty when Vsnprintf_s() returns 'size - 1' - - for (;; ) - { - if (wantedCapacity > capacity) - { - capacity = wantedCapacity; - bf.resize(capacity + 1); - } - - const int countWritten = Vsnprintf_s(&bf[0], capacity + 1, _TRUNCATE, format, parg); - - if ((countWritten >= 0) && (capacity > (size_t)countWritten + 1)) - { - bf[countWritten] = 0; - return TS(&bf[0]); - } - - wantedCapacity = capacity * 2; - } -} - -string StringHelpers::FormatVA(const char* const format, va_list parg) -{ - return FormatVA_Tpl(format, parg); -} - -wstring StringHelpers::FormatVA(const wchar_t* const format, va_list parg) -{ - return FormatVA_Tpl(format, parg); -} - -////////////////////////////////////////////////////////////////////////// - -template -static inline void SafeCopy_Tpl(TC* const pDstBuffer, const size_t dstBufferSizeInBytes, const TC* const pSrc) -{ - if (dstBufferSizeInBytes >= sizeof(TC)) - { - const size_t n = dstBufferSizeInBytes / sizeof(TC) - 1; - size_t i; - for (i = 0; i < n && pSrc[i]; ++i) - { - pDstBuffer[i] = pSrc[i]; - } - pDstBuffer[i] = 0; - } -} - -template -static inline void SafeCopyPadZeros_Tpl(TC* const pDstBuffer, const size_t dstBufferSizeInBytes, const TC* const pSrc) -{ - if (dstBufferSizeInBytes > 0) - { - const size_t n = (dstBufferSizeInBytes < sizeof(TC)) ? 0 : dstBufferSizeInBytes / sizeof(TC) - 1; - size_t i; - for (i = 0; i < n && pSrc[i]; ++i) - { - pDstBuffer[i] = pSrc[i]; - } - memset(&pDstBuffer[i], 0, dstBufferSizeInBytes - i * sizeof(TC)); - } -} - - -void StringHelpers::SafeCopy(char* const pDstBuffer, const size_t dstBufferSizeInBytes, const char* const pSrc) -{ - SafeCopy_Tpl(pDstBuffer, dstBufferSizeInBytes, pSrc); -} - -void StringHelpers::SafeCopy(wchar_t* const pDstBuffer, const size_t dstBufferSizeInBytes, const wchar_t* const pSrc) -{ - SafeCopy_Tpl(pDstBuffer, dstBufferSizeInBytes, pSrc); -} - - -void StringHelpers::SafeCopyPadZeros(char* const pDstBuffer, const size_t dstBufferSizeInBytes, const char* const pSrc) -{ - SafeCopyPadZeros_Tpl(pDstBuffer, dstBufferSizeInBytes, pSrc); -} - -void StringHelpers::SafeCopyPadZeros(wchar_t* const pDstBuffer, const size_t dstBufferSizeInBytes, const wchar_t* const pSrc) -{ - SafeCopyPadZeros_Tpl(pDstBuffer, dstBufferSizeInBytes, pSrc); -} - -////////////////////////////////////////////////////////////////////////// - -bool StringHelpers::Utf16ContainsAsciiOnly(const wchar_t* wstr) -{ - while (*wstr) - { - if (*wstr > 127 || *wstr < 0) - { - return false; - } - ++wstr; - } - return true; -} - - -string StringHelpers::ConvertAsciiUtf16ToAscii(const wchar_t* wstr) -{ - const size_t len = wcslen(wstr); - - string result; - result.reserve(len); - - for (size_t i = 0; i < len; ++i) - { - result.push_back(wstr[i] & 0x7F); - } - - return result; -} - - -wstring StringHelpers::ConvertAsciiToUtf16(const char* str) -{ - const size_t len = strlen(str); - - wstring result; - result.reserve(len); - - for (size_t i = 0; i < len; ++i) - { - result.push_back(str[i] & 0x7F); - } - - return result; -} - -#if defined(AZ_PLATFORM_WINDOWS) -static string ConvertUtf16ToMultibyte(const wchar_t* wstr, uint codePage, char badChar) -{ - if (wstr[0] == 0) - { - return string(); - } - - const int len = aznumeric_caster(wcslen(wstr)); - - // Request needed buffer size, in bytes - int neededByteCount = WideCharToMultiByte( - codePage, - 0, - wstr, - len, - 0, - 0, - ((badChar && codePage != CP_UTF8) ? &badChar : nullptr), - nullptr); - if (neededByteCount <= 0) - { - return string(); - } - ++neededByteCount; // extra space for terminating zero - - std::vector buffer(neededByteCount); - - const int byteCount = WideCharToMultiByte( - codePage, - 0, - wstr, - len, - &buffer[0], // output buffer - neededByteCount - 1, // size of the output buffer in bytes - ((badChar && codePage != CP_UTF8) ? &badChar : nullptr), - nullptr); - if (byteCount != neededByteCount - 1) - { - return string(); - } - - buffer[byteCount] = 0; - - return string(&buffer[0]); -} - - -static wstring ConvertMultibyteToUtf16(const char* str, uint codePage) -{ - if (str[0] == 0) - { - return wstring(); - } - - const int len = aznumeric_caster(strlen(str)); - - // Request needed buffer size, in characters - int neededCharCount = MultiByteToWideChar( - codePage, - 0, - str, - len, - 0, - 0); - if (neededCharCount <= 0) - { - return wstring(); - } - ++neededCharCount; // extra space for terminating zero - - std::vector wbuffer(neededCharCount); - - const int charCount = MultiByteToWideChar( - codePage, - 0, - str, - len, - &wbuffer[0], // output buffer - neededCharCount - 1); // size of the output buffer in characters - if (charCount != neededCharCount - 1) - { - return wstring(); - } - - wbuffer[charCount] = 0; - - return wstring(&wbuffer[0]); -} - - -wstring StringHelpers::ConvertUtf8ToUtf16(const char* str) -{ - return ConvertMultibyteToUtf16(str, CP_UTF8); -} - - -string StringHelpers::ConvertUtf16ToUtf8(const wchar_t* wstr) -{ - return ConvertUtf16ToMultibyte(wstr, CP_UTF8, 0); -} - - -wstring StringHelpers::ConvertAnsiToUtf16(const char* str) -{ - return ConvertMultibyteToUtf16(str, CP_ACP); -} - - -string StringHelpers::ConvertUtf16ToAnsi(const wchar_t* wstr, char badChar) -{ - return ConvertUtf16ToMultibyte(wstr, CP_ACP, badChar); -} -#endif //AZ_PLATFORM_WINDOWS - -string StringHelpers::ConvertAnsiToAscii(const char* str, char badChar) -{ - const size_t len = strlen(str); - - string result; - result.reserve(len); - - for (size_t i = 0; i < len; ++i) - { - char c = str[i]; - if (c < 0 || c > 127) - { - c = badChar; - } - result.push_back(c); - } - - return result; -} - -// eof diff --git a/Code/Editor/Util/StringHelpers.h b/Code/Editor/Util/StringHelpers.h index c05063f207..b5c84d7fe3 100644 --- a/Code/Editor/Util/StringHelpers.h +++ b/Code/Editor/Util/StringHelpers.h @@ -11,210 +11,18 @@ #define CRYINCLUDE_CRYCOMMONTOOLS_STRINGHELPERS_H #pragma once -#include +#include +#include namespace StringHelpers { - // compares two strings to see if they are the same or different, case sensitive - // returns 0 if the strings are the same, a -1 if the first string is bigger, or a 1 if the second string is bigger - int Compare(const string& str0, const string& str1); - int Compare(const wstring& str0, const wstring& str1); - // compares two strings to see if they are the same or different, case is ignored // returns 0 if the strings are the same, a -1 if the first string is bigger, or a 1 if the second string is bigger - int CompareIgnoreCase(const string& str0, const string& str1); - int CompareIgnoreCase(const wstring& str0, const wstring& str1); + int CompareIgnoreCase(const AZStd::string& str0, const AZStd::string& str1); + int CompareIgnoreCase(const AZStd::wstring& str0, const AZStd::wstring& str1); + + void Split(const AZStd::string& str, const AZStd::string& separator, bool bReturnEmptyPartsToo, std::vector& outParts); + void Split(const AZStd::wstring& str, const AZStd::wstring& separator, bool bReturnEmptyPartsToo, std::vector& outParts); - // compares two strings to see if they are the same, case senstive - // returns true if they are the same or false if they are different - bool Equals(const string& str0, const string& str1); - bool Equals(const wstring& str0, const wstring& str1); - - // compares two strings to see if they are the same, case is ignored - // returns true if they are the same or false if they are different - bool EqualsIgnoreCase(const string& str0, const string& str1); - bool EqualsIgnoreCase(const wstring& str0, const wstring& str1); - - // checks to see if a string starts with a specified string, case sensitive - // returns true if the string does start with a specified string or false if it does not - bool StartsWith(const string& str, const string& pattern); - bool StartsWith(const wstring& str, const wstring& pattern); - - // checks to see if a string starts with a specified string, case is ignored - // returns true if the string does start with a specified string or false if it does not - bool StartsWithIgnoreCase(const string& str, const string& pattern); - bool StartsWithIgnoreCase(const wstring& str, const wstring& pattern); - - // checks to see if a string ends with a specified string, case sensitive - // returns true if the string does end with a specified string or false if it does not - bool EndsWith(const string& str, const string& pattern); - bool EndsWith(const wstring& str, const wstring& pattern); - - // checks to see if a string ends with a specified string, case is ignored - // returns true if the string does end with a specified string or false if it does not - bool EndsWithIgnoreCase(const string& str, const string& pattern); - bool EndsWithIgnoreCase(const wstring& str, const wstring& pattern); - - // checks to see if a string contains a specified string, case sensitive - // returns true if the string does contain the specified string or false if it does not - bool Contains(const string& str, const string& pattern); - bool Contains(const wstring& str, const wstring& pattern); - - // checks to see if a string contains a specified string, case is ignored - // returns true if the string does contain the specified string or false if it does not - bool ContainsIgnoreCase(const string& str, const string& pattern); - bool ContainsIgnoreCase(const wstring& str, const wstring& pattern); - - // checks to see if a string contains a wildcard string pattern, case sensitive - // returns true if the string does match the wildcard string pattern or false if it does not - bool MatchesWildcards(const string& str, const string& wildcards); - bool MatchesWildcards(const wstring& str, const wstring& wildcards); - - // checks to see if a string contains a wildcard string pattern, case is ignored - // returns true if the string does match the wildcard string pattern or false if it does not - bool MatchesWildcardsIgnoreCase(const string& str, const string& wildcards); - bool MatchesWildcardsIgnoreCase(const wstring& str, const wstring& wildcards); - - bool MatchesWildcardsIgnoreCaseExt(const string& str, const string& wildcards, std::vector& wildcardMatches); - bool MatchesWildcardsIgnoreCaseExt(const wstring& str, const wstring& wildcards, std::vector& wildcardMatches); - - string TrimLeft(const string& s); - wstring TrimLeft(const wstring& s); - - string TrimRight(const string& s); - wstring TrimRight(const wstring& s); - - string Trim(const string& s); - wstring Trim(const wstring& s); - - string RemoveDuplicateSpaces(const string& s); - wstring RemoveDuplicateSpaces(const wstring& s); - - // converts a string with upper case characters to be all lower case - // returns the string in all lower case - string MakeLowerCase(const string& s); - wstring MakeLowerCase(const wstring& s); - - // converts a string with lower case characters to be all upper case - // returns the string in all upper case - string MakeUpperCase(const string& s); - wstring MakeUpperCase(const wstring& s); - - // replace a specified character in a string with a specified replacement character - // returns string with specified character replaced - string Replace(const string& s, char oldChar, char newChar); - wstring Replace(const wstring& s, wchar_t oldChar, wchar_t newChar); - - void ConvertStringByRef(string& out, const string& in); - void ConvertStringByRef(wstring& out, const string& in); - void ConvertStringByRef(string& out, const wstring& in); - void ConvertStringByRef(wstring& out, const wstring& in); - - template - O ConvertString(const I& in) - { - O out; - ConvertStringByRef(out, in); - return out; - } - - void Split(const string& str, const string& separator, bool bReturnEmptyPartsToo, std::vector& outParts); - void Split(const wstring& str, const wstring& separator, bool bReturnEmptyPartsToo, std::vector& outParts); - - void SplitByAnyOf(const string& str, const string& separators, bool bReturnEmptyPartsToo, std::vector& outParts); - void SplitByAnyOf(const wstring& str, const wstring& separators, bool bReturnEmptyPartsToo, std::vector& outParts); - - string FormatVA(const char* const format, va_list parg); - wstring FormatVA(const wchar_t* const format, va_list parg); - - inline string Format(const char* const format, ...) - { - if ((format == 0) || (format[0] == 0)) - { - return string(); - } - va_list parg; - va_start(parg, format); - const string result = FormatVA(format, parg); - va_end(parg); - return result; - } - - inline wstring Format(const wchar_t* const format, ...) - { - if ((format == 0) || (format[0] == 0)) - { - return wstring(); - } - va_list parg; - va_start(parg, format); - const wstring result = FormatVA(format, parg); - va_end(parg); - return result; - } - - ////////////////////////////////////////////////////////////////////////// - - void SafeCopy(char* const pDstBuffer, const size_t dstBufferSizeInBytes, const char* const pSrc); - void SafeCopy(wchar_t* const pDstBuffer, const size_t dstBufferSizeInBytes, const wchar_t* const pSrc); - - void SafeCopyPadZeros(char* const pDstBuffer, const size_t dstBufferSizeInBytes, const char* const pSrc); - void SafeCopyPadZeros(wchar_t* const pDstBuffer, const size_t dstBufferSizeInBytes, const wchar_t* const pSrc); - - ////////////////////////////////////////////////////////////////////////// - - // ASCII - // ANSI (system default Windows ANSI code page) - // UTF-8 - // UTF-16 - - // ASCII -> UTF-16 - - bool Utf16ContainsAsciiOnly(const wchar_t* wstr); - string ConvertAsciiUtf16ToAscii(const wchar_t* wstr); - wstring ConvertAsciiToUtf16(const char* str); - - // UTF-8 <-> UTF-16 -#if defined(AZ_PLATFORM_WINDOWS) - wstring ConvertUtf8ToUtf16(const char* str); - string ConvertUtf16ToUtf8(const wchar_t* wstr); - - inline string ConvertUtfToUtf8(const char* str) - { - return string(str); - } - - inline string ConvertUtfToUtf8(const wchar_t* wstr) - { - return ConvertUtf16ToUtf8(wstr); - } - - inline wstring ConvertUtfToUtf16(const char* str) - { - return ConvertUtf8ToUtf16(str); - } - - inline wstring ConvertUtfToUtf16(const wchar_t* wstr) - { - return wstring(wstr); - } - - // ANSI <-> UTF-8, UTF-16 - - wstring ConvertAnsiToUtf16(const char* str); - string ConvertUtf16ToAnsi(const wchar_t* wstr, char badChar); - - inline string ConvertAnsiToUtf8(const char* str) - { - return ConvertUtf16ToUtf8(ConvertAnsiToUtf16(str).c_str()); - } - inline string ConvertUtf8ToAnsi(const char* str, char badChar) - { - return ConvertUtf16ToAnsi(ConvertUtf8ToUtf16(str).c_str(), badChar); - } -#endif - - // ANSI -> ASCII - string ConvertAnsiToAscii(const char* str, char badChar); } #endif // CRYINCLUDE_CRYCOMMONTOOLS_STRINGHELPERS_H diff --git a/Code/Editor/Util/StringNoCasePredicate.h b/Code/Editor/Util/StringNoCasePredicate.h deleted file mode 100644 index 4fb81cf7d6..0000000000 --- a/Code/Editor/Util/StringNoCasePredicate.h +++ /dev/null @@ -1,62 +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 - * - */ - - -// Description : Utility class to help in STL algorithms on containers with -// CStrings when intending to use case insensitive searches or sorting for -// example. - - -#ifndef CRYINCLUDE_EDITOR_UTIL_STRINGNOCASEPREDICATE_H -#define CRYINCLUDE_EDITOR_UTIL_STRINGNOCASEPREDICATE_H -#pragma once - -/* -Utility class to help in STL algorithms on containers with CStrings -when intending to use case insensitive searches or sorting for example. - -e.g. -std::vector< CString > v; -... -std::sort( v.begin(), v.end(), CStringNoCasePredicate::LessThan() ); -std::find_if( v.begin(), v.end(), CStringNoCasePredicate::Equal( stringImLookingFor ) ); -*/ -class CStringNoCasePredicate -{ -public: - ////////////////////////////////////////////////////////////////////////// - struct Equal - { - Equal(const QString& referenceString) - : m_referenceString(referenceString) - { - } - - bool operator() (const QString& arg) const - { - return (m_referenceString.compare(arg, Qt::CaseInsensitive) == 0); - } - - private: - const QString& m_referenceString; - }; - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - struct LessThan - { - bool operator() (const QString& arg1, const QString& arg2) const - { - return (arg1.CompareNoCase(arg2) < 0); - } - }; - ////////////////////////////////////////////////////////////////////////// -}; - - -#endif // CRYINCLUDE_EDITOR_UTIL_STRINGNOCASEPREDICATE_H diff --git a/Code/Editor/Util/XmlHistoryManager.cpp b/Code/Editor/Util/XmlHistoryManager.cpp deleted file mode 100644 index ed92700705..0000000000 --- a/Code/Editor/Util/XmlHistoryManager.cpp +++ /dev/null @@ -1,875 +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 "EditorDefs.h" - -#include "XmlHistoryManager.h" - -//////////////////////////////////////////////////////////////////////////// -SXmlHistory::SXmlHistory(CXmlHistoryManager* pManager, const XmlNodeRef& xmlBaseVersion, uint32 typeId) - : m_pManager(pManager) - , m_typeId(typeId) - , m_DeletedVersion(-1) - , m_SavedVersion(-1) -{ - int newVersionNumber = m_pManager->GetCurrentVersionNumber() + (m_pManager->IsPreparedForNextVersion() ? 1 : 0); - m_xmlVersionList[ newVersionNumber ] = xmlBaseVersion; -} - -//////////////////////////////////////////////////////////////////////////// -void SXmlHistory::AddToHistory(const XmlNodeRef& newXmlVersion) -{ - int newVersionNumber = m_pManager->IncrementVersion(this); - m_xmlVersionList[ newVersionNumber ] = newXmlVersion; -} - -//////////////////////////////////////////////////////////////////////////// -const XmlNodeRef& SXmlHistory::Undo(bool* bVersionExist) -{ - m_pManager->Undo(); - return GetCurrentVersion(bVersionExist); -} - -//////////////////////////////////////////////////////////////////////////// -const XmlNodeRef& SXmlHistory::Redo() -{ - m_pManager->Redo(); - return GetCurrentVersion(); -} - -//////////////////////////////////////////////////////////////////////////// -const XmlNodeRef& SXmlHistory::GetCurrentVersion(bool* bVersionExist, int* iVersionNumber) const -{ - int currentVersion = m_pManager->GetCurrentVersionNumber(); - - TXmlVersionMap::const_iterator it = m_xmlVersionList.begin(); - TXmlVersionMap::const_iterator previt = m_xmlVersionList.begin(); - while (it != m_xmlVersionList.end()) - { - if (it->first > currentVersion) - { - break; - } - previt = it; - ++it; - } - - if (bVersionExist) - { - *bVersionExist = currentVersion >= m_xmlVersionList.begin()->first; - } - if (iVersionNumber) - { - *iVersionNumber = previt->first; - } - - return previt->second; -} - -//////////////////////////////////////////////////////////////////////////// -bool SXmlHistory::IsModified() const -{ - int currVersion; - GetCurrentVersion(nullptr, &currVersion); - return m_SavedVersion != currVersion; -} - -//////////////////////////////////////////////////////////////////////////// -void SXmlHistory::FlagAsDeleted() -{ - assert(m_pManager->IsPreparedForNextVersion()); - m_DeletedVersion = m_pManager->GetCurrentVersionNumber() + 1; - m_SavedVersion = -1; -} - -//////////////////////////////////////////////////////////////////////////// -void SXmlHistory::FlagAsSaved() -{ - if (Exist()) - { - int currVersion; - GetCurrentVersion(nullptr, &currVersion); - m_SavedVersion = currVersion; - } -} - -//////////////////////////////////////////////////////////////////////////// -bool SXmlHistory::Exist() const -{ - // int currentVersion = m_pManager->GetCurrentVersionNumber(); - // bool deleted = m_DeletedVersion != -1 && currentVersion >= m_DeletedVersion; - // bool exist = currentVersion >= m_xmlVersionList.begin()->first; - // return !deleted && exist; - int currentVersion = m_pManager->GetCurrentVersionNumber(); - return currentVersion >= m_xmlVersionList.begin()->first && (m_DeletedVersion == -1 || currentVersion < m_DeletedVersion); -} - -//////////////////////////////////////////////////////////////////////////// -void SXmlHistory::ClearRedo() -{ - int currentVersion = m_pManager->GetCurrentVersionNumber(); - if (m_DeletedVersion > currentVersion + (m_pManager->IsPreparedForNextVersion() ? 1 : 0)) - { - m_DeletedVersion = -1; - } - TXmlVersionMap::iterator it = m_xmlVersionList.begin(); - for (; it != m_xmlVersionList.end(); ++it) - { - if (it->first > currentVersion) - { - break; - } - } - if (it != m_xmlVersionList.end()) - { - ++it; - while (it != m_xmlVersionList.end()) - { - m_xmlVersionList.erase(it++); - } - } -} - -//////////////////////////////////////////////////////////////////////////// -void SXmlHistory::ClearHistory(bool flagAsSaved) -{ - bool wasModified = !flagAsSaved && IsModified(); - m_DeletedVersion = Exist() ? -1 : 0; - ClearRedo(); - XmlNodeRef latest = m_xmlVersionList.rbegin()->second; - m_xmlVersionList.clear(); - m_xmlVersionList[ 0 ] = latest; - m_SavedVersion = wasModified ? -1 : 0; -} - -//////////////////////////////////////////////////////////////////////////// -SXmlHistoryGroup::SXmlHistoryGroup(CXmlHistoryManager* pManager, uint32 typeId) - : m_pManager(pManager) - , m_typeId(typeId) -{ -} - -//////////////////////////////////////////////////////////////////////////// -SXmlHistory* SXmlHistoryGroup::GetHistory(int index) const -{ - THistoryList::const_iterator it = m_List.begin(); - while (index > 0 && it != m_List.end()) - { - ++it; - if ((*it)->Exist()) - { - --index; - } - } - return it != m_List.end() ? *it : nullptr; -} - -//////////////////////////////////////////////////////////////////////////// -int SXmlHistoryGroup::GetHistoryCount() const -{ - int count = 0; - for (THistoryList::const_iterator it = m_List.begin(); it != m_List.end(); ++it) - { - if ((*it)->Exist()) - { - count++; - } - } - return count; -} - -//////////////////////////////////////////////////////////////////////////// -SXmlHistory* SXmlHistoryGroup::GetHistoryByTypeId(uint32 typeId, int index /*= 0*/) const -{ - for (int i = 0; i < GetHistoryCount(); ++i) - { - SXmlHistory* pHistory = GetHistory(i); - if (pHistory->GetTypeId() == typeId) - { - index--; - } - if (index == -1) - { - return pHistory; - } - } - return nullptr; -} - -//////////////////////////////////////////////////////////////////////////// -int SXmlHistoryGroup::GetHistoryCountByTypeId(uint32 typeId) const -{ - int res = 0; - for (int i = 0; i < GetHistoryCount(); ++i) - { - if (GetHistory(i)->GetTypeId() == typeId) - { - res++; - } - } - return res; -} - -//////////////////////////////////////////////////////////////////////////// -int SXmlHistoryGroup::CreateXmlHistory(uint32 typeId, const XmlNodeRef& xmlBaseVersion) -{ - if (m_pManager) - { - m_List.push_back(m_pManager->CreateXmlHistory(typeId, xmlBaseVersion)); - return m_List.size() - 1; - } - return -1; -} - -//////////////////////////////////////////////////////////////////////////// -int SXmlHistoryGroup::GetHistoryIndex(const SXmlHistory* pHistory) const -{ - int index = 0; - for (THistoryList::const_iterator it = m_List.begin(); it != m_List.end(); ++it) - { - if (*it == pHistory) - { - return index; - } - index++; - } - return -1; -} - -//////////////////////////////////////////////////////////////////////////// -CXmlHistoryManager::CXmlHistoryManager() - : m_CurrentVersion(0) - , m_LatestVersion(0) - , m_pExclusiveListener(nullptr) - , m_RecordNextVersion(false) - , m_pExActiveGroup(nullptr) - , m_bIsActiveGroupEx(false) -{ - m_pNullGroup = new SXmlHistoryGroup(this, (uint32) - 1); -} - -CXmlHistoryManager::~CXmlHistoryManager() -{ - delete m_pNullGroup; -} - -///////////////////////////////////////////////////////////////////////////// -bool CXmlHistoryManager::Undo() -{ - if (m_CurrentVersion > 0) - { - int prevVersion = m_CurrentVersion; - const SXmlHistoryGroup* pPrevCurrGroup = GetActiveGroup(); - m_CurrentVersion--; - ReloadCurrentVersion(pPrevCurrGroup, prevVersion); - return true; - } - return false; -} - -///////////////////////////////////////////////////////////////////////////// -bool CXmlHistoryManager::Redo() -{ - if (m_CurrentVersion < m_LatestVersion) - { - int prevVersion = m_CurrentVersion; - const SXmlHistoryGroup* pPrevCurrGroup = GetActiveGroup(); - m_CurrentVersion++; - ReloadCurrentVersion(pPrevCurrGroup, prevVersion); - return true; - } - return false; -} - -///////////////////////////////////////////////////////////////////////////// -bool CXmlHistoryManager::Goto(int historyNum) -{ - if (historyNum >= 0 && historyNum <= m_LatestVersion) - { - int prevVersion = m_CurrentVersion; - const SXmlHistoryGroup* pPrevCurrGroup = GetActiveGroup(); - m_CurrentVersion = historyNum; - ReloadCurrentVersion(pPrevCurrGroup, prevVersion); - return true; - } - return false; -} - -///////////////////////////////////////////////////////////////////////////// -void CXmlHistoryManager::RecordUndo(IXmlUndoEventHandler* pEventHandler, const char* desc) -{ - ClearRedo(); - SXmlHistory* pChangedXml = m_UndoEventHandlerMap[ pEventHandler ].CurrentData; - assert(pChangedXml); - - XmlNodeRef newData = gEnv->pSystem->CreateXmlNode(); -#if !defined(NDEBUG) - bool bRes = -#endif - pEventHandler->SaveToXml(newData); - assert(bRes); - - TXmlHistotyGroupPtrList activeGroups = m_HistoryInfoMap[ m_CurrentVersion ].ActiveGroups; - - pChangedXml->AddToHistory(newData); - m_UndoEventHandlerMap[ pEventHandler ].HistoryData[ m_CurrentVersion ] = pChangedXml; - m_HistoryInfoMap[ m_CurrentVersion ].HistoryDescription = desc; - m_HistoryInfoMap[ m_CurrentVersion ].IsNullUndo = false; - m_HistoryInfoMap[ m_CurrentVersion ].ActiveGroups = activeGroups; - m_HistoryInfoMap[ m_CurrentVersion ].HistoryInvalidated = false; - NotifyUndoEventListener(IXmlHistoryEventListener::eHET_VersionAdded); -} - -///////////////////////////////////////////////////////////////////////////// -void CXmlHistoryManager::UndoEventHandlerDestroyed(IXmlUndoEventHandler* pEventHandler, uint32 typeId /*= 0*/, bool destoryForever /*= false*/) -{ - if (destoryForever) - { - UnregisterUndoEventHandler(pEventHandler); - } - else - { - m_InvalidHandlerMap[typeId] = pEventHandler; - } -} - -///////////////////////////////////////////////////////////////////////////// -void CXmlHistoryManager::RestoreUndoEventHandler(IXmlUndoEventHandler* pEventHandler, uint32 typeId) -{ - TInvalidUndoEventListener::iterator it = m_InvalidHandlerMap.find(typeId); - if (it != m_InvalidHandlerMap.end()) - { - IXmlUndoEventHandler* pLastHandler = it->second; - TUndoEventHandlerMap::iterator lastit = m_UndoEventHandlerMap.find(pLastHandler); - if (lastit != m_UndoEventHandlerMap.end()) - { - m_UndoEventHandlerMap[pEventHandler] = lastit->second; - m_UndoEventHandlerMap.erase(lastit); - } - m_InvalidHandlerMap.erase(it); - } -} - -///////////////////////////////////////////////////////////////////////////// -void CXmlHistoryManager::RegisterEventListener(IXmlHistoryEventListener* pEventListener) -{ - stl::push_back_unique(m_EventListener, pEventListener); -} - -///////////////////////////////////////////////////////////////////////////// -void CXmlHistoryManager::UnregisterEventListener(IXmlHistoryEventListener* pEventListener) -{ - m_EventListener.remove(pEventListener); -} - -///////////////////////////////////////////////////////////////////////////// -void CXmlHistoryManager::PrepareForNextVersion() -{ - assert(!m_RecordNextVersion); - m_RecordNextVersion = true; -} - -///////////////////////////////////////////////////////////////////////////// -void CXmlHistoryManager::RecordNextVersion(SXmlHistory* pHistory, XmlNodeRef newData, const char* undoDesc /*= nullptr*/) -{ - assert(m_RecordNextVersion); - RegisterUndoEventHandler(this, pHistory); - m_newHistoryData = newData; - RecordUndo(this, undoDesc ? undoDesc : ""); - m_RecordNextVersion = false; - m_HistoryInfoMap[ m_CurrentVersion ].HistoryInvalidated = true; - UnregisterUndoEventHandler(this); - SetActiveGroupInt(GetActiveGroup()); - NotifyUndoEventListener(IXmlHistoryEventListener::eHET_HistoryInvalidate); -} - -///////////////////////////////////////////////////////////////////////////// -bool CXmlHistoryManager::SaveToXml(XmlNodeRef& xmlNode) -{ - assert(m_newHistoryData); - xmlNode = m_newHistoryData; - return true; -} -///////////////////////////////////////////////////////////////////////////// -void CXmlHistoryManager::ClearHistory(bool flagAsSaved) -{ - TXmlHistotyGroupPtrList activeGropus = m_HistoryInfoMap[ m_CurrentVersion ].ActiveGroups; - for (TXmlHistoryList::iterator it = m_XmlHistoryList.begin(); it != m_XmlHistoryList.end(); ++it) - { - it->ClearHistory(flagAsSaved); - } - - SetActiveGroup(nullptr); - - m_CurrentVersion = 0; - m_LatestVersion = 0; - - m_UndoEventHandlerMap.clear(); - m_HistoryInfoMap.clear(); - - m_HistoryInfoMap[ 0 ].HistoryDescription = "New History"; - m_HistoryInfoMap[ 0 ].ActiveGroups = activeGropus; - NotifyUndoEventListener(IXmlHistoryEventListener::eHET_HistoryCleared); -} - -///////////////////////////////////////////////////////////////////////////// -const string& CXmlHistoryManager::GetVersionDesc(int number) const -{ - THistoryInfoMap::const_iterator it = m_HistoryInfoMap.find(number); - if (it != m_HistoryInfoMap.end()) - { - return it->second.HistoryDescription; - } - - static string undef("UNDEFINED"); - return undef; -} - -///////////////////////////////////////////////////////////////////////////// -void CXmlHistoryManager::RegisterView(IXmlHistoryView* pView) -{ - stl::push_back_unique(m_Views, pView); -} - -///////////////////////////////////////////////////////////////////////////// -void CXmlHistoryManager::UnregisterView(IXmlHistoryView* pView) -{ - m_Views.remove(pView); -} - -///////////////////////////////////////////////////////////////////////////// -SXmlHistoryGroup* CXmlHistoryManager::CreateXmlGroup(uint32 typeId) -{ - m_Groups.push_back(SXmlHistoryGroup(this, typeId)); - return &(*m_Groups.rbegin()); -} - -///////////////////////////////////////////////////////////////////////////// -void CXmlHistoryManager::AddXmlGroup(const SXmlHistoryGroup* pGroup, const char* undoDesc /*= nullptr*/) -{ - RecordUndoInternal(undoDesc ? undoDesc : "New XML Group added"); - m_HistoryInfoMap[ m_CurrentVersion ].ActiveGroups.push_back(pGroup); - NotifyUndoEventListener(IXmlHistoryEventListener::eHET_HistoryGroupAdded, (void*)pGroup); -} -///////////////////////////////////////////////////////////////////////////// -void CXmlHistoryManager::RemoveXmlGroup(const SXmlHistoryGroup* pGroup, const char* undoDesc /*= nullptr*/) -{ - bool unload = m_HistoryInfoMap[ m_CurrentVersion ].CurrGroup == pGroup; - RecordUndoInternal(undoDesc ? undoDesc : "XML Group deleted"); - TXmlHistotyGroupPtrList& list = m_HistoryInfoMap[ m_CurrentVersion ].ActiveGroups; - stl::find_and_erase(list, pGroup); - if (unload) - { - SetActiveGroupInt(nullptr); - } - m_HistoryInfoMap[ m_CurrentVersion ].CurrGroup = m_pNullGroup; - NotifyUndoEventListener(IXmlHistoryEventListener::eHET_HistoryGroupRemoved, (void*)pGroup); -} - -///////////////////////////////////////////////////////////////////////////// -void CXmlHistoryManager::SetActiveGroup(const SXmlHistoryGroup* pGroup, const char* displayName /*= nullptr*/, const TGroupIndexMap& groupIndex /*= TGroupIndexMap()*/, bool setExternal /*= false*/) -{ - TGroupIndexMap userIndex; - const SXmlHistoryGroup* pActiveGroup = GetActiveGroup(userIndex); - if (pGroup != pActiveGroup || userIndex != groupIndex || setExternal) - { - const bool isEx = m_CurrentVersion != m_LatestVersion || setExternal; - m_pExActiveGroup = const_cast(pGroup); - m_ExCurrentIndex = groupIndex; - m_bIsActiveGroupEx = true; - SetActiveGroupInt(pGroup, displayName, !isEx, groupIndex); - m_bIsActiveGroupEx = isEx; - } -} - -void CXmlHistoryManager::SetActiveGroupInt(const SXmlHistoryGroup* pGroup, const char* displayName /*= nullptr*/, bool bRecordNullUndo /*= false*/, const TGroupIndexMap& groupIndex /*= TGroupIndexMap()*/) -{ - UnloadInt(); - - TEventHandlerList eventHandler; - string undoDesc; - - if (pGroup) - { - for (TViews::iterator it = m_Views.begin(); it != m_Views.end(); ++it) - { - IXmlHistoryView* pView = *it; - - std::map userIndexCount; - - for (SXmlHistoryGroup::THistoryList::const_iterator history = pGroup->m_List.begin(); history != pGroup->m_List.end(); ++history) - { - std::map::iterator it2 = userIndexCount.find((*history)->GetTypeId()); - if (it2 == userIndexCount.end()) - { - userIndexCount[ (*history)->GetTypeId() ] = 0; - } - uint32 userindex = userIndexCount[ (*history)->GetTypeId() ]; - IXmlUndoEventHandler* pEventHandler = nullptr; - TGroupIndexMap::const_iterator indexIter = groupIndex.find((*history)->GetTypeId()); - if (indexIter == groupIndex.end() || indexIter->second == userindex) - { - if ((*history)->Exist()) - { - if (pView->LoadXml((*history)->GetTypeId(), (*history)->GetCurrentVersion(), pEventHandler, userindex)) - { - if (pEventHandler) - { - m_UndoHandlerViewMap[ pEventHandler ] = pView; - RegisterUndoEventHandler(pEventHandler, *history); - eventHandler.push_back(pEventHandler); - } - } - } - } - if ((*history)->Exist()) - { - userIndexCount[ (*history)->GetTypeId() ]++; - } - } - } - undoDesc.Format("Changed View to \"%s\"", displayName ? displayName : "UNDEFINED"); - } - else - { - undoDesc = "Unloaded Views"; - for (TUndoEventHandlerMap::iterator it = m_UndoEventHandlerMap.begin(); it != m_UndoEventHandlerMap.end(); ++it) - { - eventHandler.push_back(it->first); - } - pGroup = m_pNullGroup; - } - - if (bRecordNullUndo) - { - RecordNullUndo(eventHandler, undoDesc.c_str()); - m_HistoryInfoMap[ m_CurrentVersion ].CurrGroup = pGroup; - m_HistoryInfoMap[ m_CurrentVersion ].CurrUserIndex = groupIndex; - } - NotifyUndoEventListener(IXmlHistoryEventListener::eHET_HistoryGroupChanged); -} - -///////////////////////////////////////////////////////////////////////////// -const SXmlHistoryGroup* CXmlHistoryManager::GetActiveGroup() const -{ - TGroupIndexMap userIndex; - return GetActiveGroup(userIndex); -} - -///////////////////////////////////////////////////////////////////////////// -const SXmlHistoryGroup* CXmlHistoryManager::GetActiveGroup(TGroupIndexMap& currUserIndex /*out*/) const -{ - if (m_bIsActiveGroupEx) - { - currUserIndex = m_ExCurrentIndex; - return m_pExActiveGroup; - } - - int currVersion = m_CurrentVersion; - do - { - THistoryInfoMap::const_iterator it = m_HistoryInfoMap.find(currVersion); - if (it != m_HistoryInfoMap.end()) - { - const SXmlHistoryGroup* pGroup = it->second.CurrGroup; - if (it != m_HistoryInfoMap.end() && pGroup) - { - currUserIndex = it->second.CurrUserIndex; - return pGroup == m_pNullGroup ? nullptr : pGroup; - } - } - currVersion--; - } while (currVersion >= 0); - return nullptr; -} - -///////////////////////////////////////////////////////////////////////////// -SXmlHistory* CXmlHistoryManager::CreateXmlHistory(uint32 typeId, const XmlNodeRef& xmlBaseVersion) -{ - m_XmlHistoryList.push_back(SXmlHistory(this, xmlBaseVersion, typeId)); - return &(*m_XmlHistoryList.rbegin()); -} - -///////////////////////////////////////////////////////////////////////////// -void CXmlHistoryManager::DeleteXmlHistory(const SXmlHistory* pXmlHistry) -{ - for (TXmlHistoryList::iterator it = m_XmlHistoryList.begin(); it != m_XmlHistoryList.end(); ++it) - { - if (&(*it) == pXmlHistry) - { - m_XmlHistoryList.erase(it); - return; - } - } -} - -///////////////////////////////////////////////////////////////////////////// -void CXmlHistoryManager::UnloadInt() -{ - for (TViews::iterator it = m_Views.begin(); it != m_Views.end(); ++it) - { - IXmlHistoryView* pView = *it; - pView->UnloadXml(-1); - } -} - -///////////////////////////////////////////////////////////////////////////// -namespace -{ - template< class T > - void ClearAfterVersion(T& container, int version) - { - auto foundit = container.end(); - do - { - auto it = container.find(version); - if (it != container.end()) - { - foundit = it; - break; - } - version--; - } while (version >= 0); - if (foundit != container.end()) - { - for (auto it = ++foundit; it != container.end(); ) - { - container.erase(it++); - } - } - } -} - -void CXmlHistoryManager::ClearRedo() -{ - ClearAfterVersion(m_HistoryInfoMap, m_CurrentVersion); - for (TUndoEventHandlerMap::iterator it = m_UndoEventHandlerMap.begin(); it != m_UndoEventHandlerMap.end(); ++it) - { - ClearAfterVersion(it->second.HistoryData, m_CurrentVersion); - } -} - -///////////////////////////////////////////////////////////////////////////// -void CXmlHistoryManager::DeleteAll() -{ - ClearHistory(); - m_Groups.clear(); - m_UndoEventHandlerMap.clear(); - NotifyUndoEventListener(IXmlHistoryEventListener::eHET_HistoryDeleted); -} - -///////////////////////////////////////////////////////////////////////////// -void CXmlHistoryManager::FlagHistoryAsSaved() -{ - for (TXmlHistoryList::iterator it = m_XmlHistoryList.begin(); it != m_XmlHistoryList.end(); ++it) - { - it->FlagAsSaved(); - } - NotifyUndoEventListener(IXmlHistoryEventListener::eHET_HistorySaved); -} - -///////////////////////////////////////////////////////////////////////////// -void CXmlHistoryManager::RecordNullUndo(const TEventHandlerList& eventHandler, const char* desc, bool isNull /*= true*/) -{ - TXmlHistotyGroupPtrList activeGroups = m_HistoryInfoMap[ m_CurrentVersion ].ActiveGroups; - - // if current version is already null undo, overwrite it instead of create a new version - if (m_HistoryInfoMap[ m_CurrentVersion ].IsNullUndo && isNull) - { - assert(m_CurrentVersion); - m_CurrentVersion--; - } - - ClearRedo(); - IncrementVersion(); - - for (TEventHandlerList::const_iterator it = eventHandler.begin(); it != eventHandler.end(); ++it) - { - SXmlHistory* pChangedXml = m_UndoEventHandlerMap[ *it ].CurrentData; - m_UndoEventHandlerMap[ *it ].HistoryData[ m_CurrentVersion ] = pChangedXml; - } - m_HistoryInfoMap[ m_CurrentVersion ].HistoryDescription = desc; - m_HistoryInfoMap[ m_CurrentVersion ].IsNullUndo = isNull; - m_HistoryInfoMap[ m_CurrentVersion ].ActiveGroups = activeGroups; - m_HistoryInfoMap[ m_CurrentVersion ].HistoryInvalidated = false; - NotifyUndoEventListener(IXmlHistoryEventListener::eHET_VersionAdded); -} - -///////////////////////////////////////////////////////////////////////////// -void CXmlHistoryManager::ReloadCurrentVersion(const SXmlHistoryGroup* pPrevGroup, int prevVersion) -{ - m_bIsActiveGroupEx = false; - const SXmlHistoryGroup* pActiveGroup = GetActiveGroup(); - - bool bInvalidated = false; - int start = min(prevVersion, m_CurrentVersion); - int end = max(prevVersion, m_CurrentVersion); - for (int i = start; i <= end; ++i) - { - if (m_HistoryInfoMap[i].HistoryInvalidated) - { - bInvalidated = true; - break; - } - } - - if (!bInvalidated && pPrevGroup == pActiveGroup) - { - for (TUndoEventHandlerMap::iterator it = m_UndoEventHandlerMap.begin(); it != m_UndoEventHandlerMap.end(); ++it) - { - IXmlUndoEventHandler* pEventHandler = it->first; - if (!IsEventHandlerValid(pEventHandler)) - { - assert(false); - continue; - } - SXmlHistory* pXmlHistory = GetLatestHistory(m_UndoEventHandlerMap[ pEventHandler ]); /*m_UndoEventHandlerMap[ pEventHandler ].HistoryData[ m_CurrentVersion ];*/ - if (pXmlHistory) - { - if (pXmlHistory->Exist()) - { - pEventHandler->ReloadFromXml(pXmlHistory->GetCurrentVersion()); - } - } - } - NotifyUndoEventListener(IXmlHistoryEventListener::eHET_VersionChanged); - } - else - { - SetActiveGroupInt(pActiveGroup); - } - - if (bInvalidated) - { - NotifyUndoEventListener(IXmlHistoryEventListener::eHET_HistoryInvalidate); - } - - TXmlHistotyGroupPtrList oldActiveGroups = m_HistoryInfoMap[ prevVersion ].ActiveGroups; - TXmlHistotyGroupPtrList newActiveGroups = m_HistoryInfoMap[ m_CurrentVersion ].ActiveGroups; - - RemoveListFromList(newActiveGroups, oldActiveGroups); - RemoveListFromList(oldActiveGroups, m_HistoryInfoMap[ m_CurrentVersion ].ActiveGroups); - - for (TXmlHistotyGroupPtrList::iterator it = newActiveGroups.begin(); it != newActiveGroups.end(); ++it) - { - NotifyUndoEventListener(IXmlHistoryEventListener::eHET_HistoryGroupAdded, (void*) *it); - } - - for (TXmlHistotyGroupPtrList::iterator it = oldActiveGroups.begin(); it != oldActiveGroups.end(); ++it) - { - NotifyUndoEventListener(IXmlHistoryEventListener::eHET_HistoryGroupRemoved, (void*) *it); - } -} - -///////////////////////////////////////////////////////////////////////////// -void CXmlHistoryManager::RemoveListFromList(TXmlHistotyGroupPtrList& list, const TXmlHistotyGroupPtrList& removeList) -{ - for (TXmlHistotyGroupPtrList::const_iterator rit = removeList.begin(); rit != removeList.end(); ++rit) - { - for (TXmlHistotyGroupPtrList::iterator it = list.begin(); it != list.end(); ++it) - { - if (*it == *rit) - { - list.erase(it); - break; - } - } - } -} - -///////////////////////////////////////////////////////////////////////////// -SXmlHistory* CXmlHistoryManager::GetLatestHistory(SUndoEventHandlerData& eventHandlerData) -{ - int currVersion = m_CurrentVersion; - do - { - THistoryVersionMap::iterator it = eventHandlerData.HistoryData.find(currVersion); - if (it != eventHandlerData.HistoryData.end()) - { - return it->second; - } - currVersion--; - } while (currVersion >= 0); - return nullptr; -} - - -///////////////////////////////////////////////////////////////////////////// -void CXmlHistoryManager::NotifyUndoEventListener(IXmlHistoryEventListener::EHistoryEventType event, void* pData) -{ - if (m_pExclusiveListener) - { - m_pExclusiveListener->OnEvent(event, pData); - } - else - { - for (TEventListener::iterator it = m_EventListener.begin(); it != m_EventListener.end(); ++it) - { - (*it)->OnEvent(event, pData); - } - } -} - -///////////////////////////////////////////////////////////////////////////// -int CXmlHistoryManager::IncrementVersion([[maybe_unused]] SXmlHistory* pXmlHistry) -{ - for (TXmlHistoryList::iterator it = m_XmlHistoryList.begin(); it != m_XmlHistoryList.end(); ++it) - { - it->ClearRedo(); - } - return IncrementVersion(); -} - -///////////////////////////////////////////////////////////////////////////// -int CXmlHistoryManager::IncrementVersion() -{ - m_CurrentVersion++; - m_LatestVersion = m_CurrentVersion; - return m_CurrentVersion; -} - -//////////////////////////////////////////////////////////////////////////// -void CXmlHistoryManager::RegisterUndoEventHandler(IXmlUndoEventHandler* pEventHandler, SXmlHistory* pXmlData) -{ - m_UndoEventHandlerMap[ pEventHandler ].CurrentData = pXmlData; -} - -///////////////////////////////////////////////////////////////////////////// -void CXmlHistoryManager::UnregisterUndoEventHandler(IXmlUndoEventHandler* pEventHandler) -{ - TUndoEventHandlerMap::iterator it = m_UndoEventHandlerMap.find(pEventHandler); - if (it != m_UndoEventHandlerMap.end()) - { - m_UndoEventHandlerMap.erase(it); - } -} - -///////////////////////////////////////////////////////////////////////////// -void CXmlHistoryManager::RecordUndoInternal(const char* desc) -{ - TEventHandlerList eventHandler; - for (TUndoEventHandlerMap::iterator it = m_UndoEventHandlerMap.begin(); it != m_UndoEventHandlerMap.end(); ++it) - { - eventHandler.push_back(it->first); - } - RecordNullUndo(eventHandler, desc, false); -} - -///////////////////////////////////////////////////////////////////////////// -bool CXmlHistoryManager::IsEventHandlerValid(IXmlUndoEventHandler* pEventHandler) -{ - for (TInvalidUndoEventListener::iterator it = m_InvalidHandlerMap.begin(); it != m_InvalidHandlerMap.end(); ++it) - { - if (it->second == pEventHandler) - { - return false; - } - } - return true; -} diff --git a/Code/Editor/Util/XmlHistoryManager.h b/Code/Editor/Util/XmlHistoryManager.h deleted file mode 100644 index d7aae71939..0000000000 --- a/Code/Editor/Util/XmlHistoryManager.h +++ /dev/null @@ -1,218 +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 CRYINCLUDE_EDITOR_UTIL_XMLHISTORYMANAGER_H -#define CRYINCLUDE_EDITOR_UTIL_XMLHISTORYMANAGER_H -#pragma once - - -#include "IXmlHistoryManager.h" - -class CXmlHistoryManager; - -struct SXmlHistory -{ -public: - SXmlHistory(CXmlHistoryManager* pManager, const XmlNodeRef& xmlBaseVersion, uint32 typeId); - - void AddToHistory(const XmlNodeRef& newXmlVersion); - - const XmlNodeRef& Undo(bool* bVersionExist = nullptr); - const XmlNodeRef& Redo(); - const XmlNodeRef& GetCurrentVersion(bool* bVersionExist = nullptr, int* iVersionNumber = nullptr) const; - bool IsModified() const; - uint32 GetTypeId() const {return m_typeId; } - void FlagAsDeleted(); - void FlagAsSaved(); - bool Exist() const; - -private: - friend class CXmlHistoryManager; - - void ClearRedo(); - void ClearHistory(bool flagAsSaved); - -private: - CXmlHistoryManager* m_pManager; - uint32 m_typeId; - int m_DeletedVersion; - int m_SavedVersion; - - typedef std::map< int, XmlNodeRef > TXmlVersionMap; - TXmlVersionMap m_xmlVersionList; -}; - - -struct SXmlHistoryGroup -{ - SXmlHistoryGroup(CXmlHistoryManager* pManager, uint32 typeId); - - SXmlHistory* GetHistory(int index) const; - int GetHistoryCount() const; - - SXmlHistory* GetHistoryByTypeId(uint32 typeId, int index = 0) const; - int GetHistoryCountByTypeId(uint32 typeId) const; - - int CreateXmlHistory(uint32 typeId, const XmlNodeRef& xmlBaseVersion); - uint32 GetTypeId() const {return m_typeId; } - - int GetHistoryIndex(const SXmlHistory* pHistory) const; - -private: - friend class CXmlHistoryManager; - CXmlHistoryManager* m_pManager; - uint32 m_typeId; - - typedef std::list< SXmlHistory* > THistoryList; - THistoryList m_List; -}; - -typedef std::map TGroupIndexMap; - - -class CXmlHistoryManager - : public IXmlHistoryManager - , public IXmlUndoEventHandler -{ -public: - CXmlHistoryManager(); - ~CXmlHistoryManager(); - - // Undo/Redo - bool Undo(); - bool Redo(); - bool Goto(int historyNum); - void RecordUndo(IXmlUndoEventHandler* pEventHandler, const char* desc); - void UndoEventHandlerDestroyed(IXmlUndoEventHandler* pEventHandler, uint32 typeId = 0, bool destoryForever = false); - void RestoreUndoEventHandler(IXmlUndoEventHandler* pEventHandler, uint32 typeId); - - void PrepareForNextVersion(); - void RecordNextVersion(SXmlHistory* pHistory, XmlNodeRef newData, const char* undoDesc = nullptr); - bool IsPreparedForNextVersion() const {return m_RecordNextVersion; } - - void RegisterEventListener(IXmlHistoryEventListener* pEventListener); - void UnregisterEventListener(IXmlHistoryEventListener* pEventListener); - void SetExclusiveListener(IXmlHistoryEventListener* pEventListener) { m_pExclusiveListener = pEventListener; } - - // History - void ClearHistory(bool flagAsSaved = false); - int GetVersionCount() const { return m_LatestVersion; } - const string& GetVersionDesc(int number) const; - int GetCurrentVersionNumber() const { return m_CurrentVersion; } - - // Views - void RegisterView(IXmlHistoryView* pView); - void UnregisterView(IXmlHistoryView* pView); - - // Xml History Groups - SXmlHistoryGroup* CreateXmlGroup(uint32 typeId); - void SetActiveGroup(const SXmlHistoryGroup* pGroup, const char* displayName = nullptr, const TGroupIndexMap& groupIndex = TGroupIndexMap(), bool setExternal = false); - const SXmlHistoryGroup* GetActiveGroup() const; - const SXmlHistoryGroup* GetActiveGroup(TGroupIndexMap& currUserIndex /*out*/) const; - void AddXmlGroup(const SXmlHistoryGroup* pGroup, const char* undoDesc = nullptr); - void RemoveXmlGroup(const SXmlHistoryGroup* pGroup, const char* undoDesc = nullptr); - - void DeleteAll(); - - void FlagHistoryAsSaved(); - - virtual bool SaveToXml(XmlNodeRef& xmlNode); - virtual bool LoadFromXml([[maybe_unused]] const XmlNodeRef& xmlNode) { return false; }; - virtual bool ReloadFromXml([[maybe_unused]] const XmlNodeRef& xmlNode) { return false; }; - -private: - typedef std::list< SXmlHistory > TXmlHistoryList; - TXmlHistoryList m_XmlHistoryList; - int m_CurrentVersion; - int m_LatestVersion; - SXmlHistoryGroup* m_pNullGroup; // hack for unload view ... - XmlNodeRef m_newHistoryData; - bool m_RecordNextVersion; - bool m_bIsActiveGroupEx; - SXmlHistoryGroup* m_pExActiveGroup; - TGroupIndexMap m_ExCurrentIndex; - - typedef std::list< SXmlHistoryGroup > TXmlHistotyGroupList; - TXmlHistotyGroupList m_Groups; - - // event listener - typedef std::list< IXmlHistoryEventListener* > TEventListener; - TEventListener m_EventListener; - IXmlHistoryEventListener* m_pExclusiveListener; - - // views - typedef std::list< IXmlHistoryView* > TViews; - TViews m_Views; - - typedef std::list< const SXmlHistoryGroup* > TXmlHistotyGroupPtrList; - // history - struct SHistoryInfo - { - SHistoryInfo() - : IsNullUndo(false) - , CurrGroup(nullptr) - , HistoryInvalidated(false) {} - - const SXmlHistoryGroup* CurrGroup; - TGroupIndexMap CurrUserIndex; - string HistoryDescription; - bool IsNullUndo; - bool HistoryInvalidated; - TXmlHistotyGroupPtrList ActiveGroups; - }; - typedef std::map< int, SHistoryInfo > THistoryInfoMap; - THistoryInfoMap m_HistoryInfoMap; - - // undo event handler - typedef std::map< int, SXmlHistory* > THistoryVersionMap; - struct SUndoEventHandlerData - { - SUndoEventHandlerData() - : CurrentData(nullptr) {} - - SXmlHistory* CurrentData; - THistoryVersionMap HistoryData; - }; - typedef std::map< IXmlUndoEventHandler*, SUndoEventHandlerData > TUndoEventHandlerMap; - TUndoEventHandlerMap m_UndoEventHandlerMap; - - typedef std::map< IXmlUndoEventHandler*, IXmlHistoryView* > TUndoHandlerViewMap; - TUndoHandlerViewMap m_UndoHandlerViewMap; - - typedef std::map< uint32, IXmlUndoEventHandler* > TInvalidUndoEventListener; - TInvalidUndoEventListener m_InvalidHandlerMap; - -private: - friend struct SXmlHistory; - friend struct SXmlHistoryGroup; - - int IncrementVersion(SXmlHistory* pXmlHistry); - int IncrementVersion(); - SXmlHistory* CreateXmlHistory(uint32 typeId, const XmlNodeRef& xmlBaseVersion); - void DeleteXmlHistory(const SXmlHistory* pXmlHistry); - - void RegisterUndoEventHandler(IXmlUndoEventHandler* pEventHandler, SXmlHistory* pXmlData); - void UnregisterUndoEventHandler(IXmlUndoEventHandler* pEventHandler); - typedef std::list< IXmlUndoEventHandler* > TEventHandlerList; - void RecordNullUndo(const TEventHandlerList& eventHandler, const char* desc, bool isNull = true); - void ReloadCurrentVersion(const SXmlHistoryGroup* pPrevGroup, int prevVersion); - SXmlHistory* GetLatestHistory(SUndoEventHandlerData& eventHandlerData); - void NotifyUndoEventListener(IXmlHistoryEventListener::EHistoryEventType event, void* pData = nullptr); - - void SetActiveGroupInt(const SXmlHistoryGroup* pGroup, const char* displayName = nullptr, bool bRecordNullUndo = false, const TGroupIndexMap& groupIndex = TGroupIndexMap()); - void UnloadInt(); - void ClearRedo(); - - void RecordUndoInternal(const char* desc); - void RemoveListFromList(TXmlHistotyGroupPtrList& list, const TXmlHistotyGroupPtrList& removeList); - - bool IsEventHandlerValid(IXmlUndoEventHandler* pEventHandler); -}; - -#endif // CRYINCLUDE_EDITOR_UTIL_XMLHISTORYMANAGER_H diff --git a/Code/Editor/ViewportTitleDlg.cpp b/Code/Editor/ViewportTitleDlg.cpp index 50479beee0..530e11b01b 100644 --- a/Code/Editor/ViewportTitleDlg.cpp +++ b/Code/Editor/ViewportTitleDlg.cpp @@ -449,21 +449,21 @@ void CViewportTitleDlg::AddFOVMenus(QMenu* menu, std::function call if (!customPresets.empty()) { - for (size_t i = 0; i < customPresets.size(); ++i) + for (const QString& customPreset : customPresets) { - if (customPresets[i].isEmpty()) + if (customPreset.isEmpty()) { break; } float fov = gSettings.viewports.fDefaultFov; bool ok; - float f = customPresets[i].toDouble(&ok); + float f = customPreset.toDouble(&ok); if (ok) { fov = std::max(1.0f, f); fov = std::min(120.0f, f); - QAction* action = menu->addAction(customPresets[i]); + QAction* action = menu->addAction(customPreset); connect(action, &QAction::triggered, action, [fov, callback](){ callback(fov); }); } } @@ -535,15 +535,15 @@ void CViewportTitleDlg::AddAspectRatioMenus(QMenu* menu, std::functionaddSeparator(); - for (size_t i = 0; i < customPresets.size(); ++i) + for (const QString& customPreset : customPresets) { - if (customPresets[i].isEmpty()) + if (customPreset.isEmpty()) { break; } static QRegularExpression regex(QStringLiteral("^(\\d+):(\\d+)$")); - QRegularExpressionMatch matches = regex.match(customPresets[i]); + QRegularExpressionMatch matches = regex.match(customPreset); if (matches.hasMatch()) { bool ok; @@ -551,7 +551,7 @@ void CViewportTitleDlg::AddAspectRatioMenus(QMenu* menu, std::functionaddAction(customPresets[i]); + QAction* action = menu->addAction(customPreset); connect(action, &QAction::triggered, action, [width, height, callback]() {callback(width, height); }); } } @@ -684,15 +684,15 @@ void CViewportTitleDlg::AddResolutionMenus(QMenu* menu, std::functionaddSeparator(); - for (size_t i = 0; i < customPresets.size(); ++i) + for (const QString& customPreset : customPresets) { - if (customPresets[i].isEmpty()) + if (customPreset.isEmpty()) { break; } static QRegularExpression regex(QStringLiteral("^(\\d+) x (\\d+)$")); - QRegularExpressionMatch matches = regex.match(customPresets[i]); + QRegularExpressionMatch matches = regex.match(customPreset); if (matches.hasMatch()) { bool ok; @@ -700,7 +700,7 @@ void CViewportTitleDlg::AddResolutionMenus(QMenu* menu, std::functionaddAction(customPresets[i]); + QAction* action = menu->addAction(customPreset); connect(action, &QAction::triggered, action, [width, height, callback](){ callback(width, height); }); } } diff --git a/Code/Editor/editor_lib_files.cmake b/Code/Editor/editor_lib_files.cmake index c1da19c3fd..4ad2ef23b9 100644 --- a/Code/Editor/editor_lib_files.cmake +++ b/Code/Editor/editor_lib_files.cmake @@ -498,9 +498,7 @@ set(FILES UndoViewPosition.h UndoViewRotation.h Util/GeometryUtil.h - Util/IXmlHistoryManager.h Util/KDTree.h - Util/XmlHistoryManager.h WipFeaturesDlg.h WipFeaturesDlg.ui WipFeaturesDlg.qrc @@ -735,14 +733,12 @@ set(FILES Util/PredefinedAspectRatios.h Util/StringHelpers.cpp Util/StringHelpers.h - Util/StringNoCasePredicate.h Util/TRefCountBase.h Util/Triangulate.cpp Util/Triangulate.h Util/Util.h Util/XmlArchive.cpp Util/XmlArchive.h - Util/XmlHistoryManager.cpp Util/XmlTemplate.cpp Util/XmlTemplate.h Util/bitarray.h diff --git a/Code/Framework/AtomCore/AtomCore/std/containers/fixed_vector_set.h b/Code/Framework/AtomCore/AtomCore/std/containers/fixed_vector_set.h index 1d5c9c2edd..c014f4b44e 100644 --- a/Code/Framework/AtomCore/AtomCore/std/containers/fixed_vector_set.h +++ b/Code/Framework/AtomCore/AtomCore/std/containers/fixed_vector_set.h @@ -8,6 +8,7 @@ #pragma once #include +#include namespace AZStd { diff --git a/Code/Framework/AzCore/AzCore/Component/ComponentExport.h b/Code/Framework/AzCore/AzCore/Component/ComponentExport.h index c31c739160..0b3f9ea617 100644 --- a/Code/Framework/AzCore/AzCore/Component/ComponentExport.h +++ b/Code/Framework/AzCore/AzCore/Component/ComponentExport.h @@ -9,7 +9,7 @@ #pragma once #include -#include +#include #include diff --git a/Code/Framework/AzCore/AzCore/Component/EntityId.h b/Code/Framework/AzCore/AzCore/Component/EntityId.h index 8e00cc70a9..e95813b388 100644 --- a/Code/Framework/AzCore/AzCore/Component/EntityId.h +++ b/Code/Framework/AzCore/AzCore/Component/EntityId.h @@ -9,7 +9,7 @@ #define AZCORE_ENTITY_ID_H #include -#include +#include #include /** @file diff --git a/Code/Framework/AzCore/AzCore/Debug/IEventLogger.h b/Code/Framework/AzCore/AzCore/Debug/IEventLogger.h index f04199e923..a11b411ded 100644 --- a/Code/Framework/AzCore/AzCore/Debug/IEventLogger.h +++ b/Code/Framework/AzCore/AzCore/Debug/IEventLogger.h @@ -10,7 +10,7 @@ #include #include -#include +#include #include #include diff --git a/Code/Framework/AzCore/AzCore/Debug/Trace.cpp b/Code/Framework/AzCore/AzCore/Debug/Trace.cpp index 6d491c97b8..bd3b12a3b8 100644 --- a/Code/Framework/AzCore/AzCore/Debug/Trace.cpp +++ b/Code/Framework/AzCore/AzCore/Debug/Trace.cpp @@ -38,7 +38,6 @@ namespace AZ void DebugBreak(); #endif void Terminate(int exitCode); - void OutputToDebugger(const char* window, const char* message); } } diff --git a/Code/Framework/AzCore/AzCore/Debug/Trace.h b/Code/Framework/AzCore/AzCore/Debug/Trace.h index a680cbdfed..bae074281c 100644 --- a/Code/Framework/AzCore/AzCore/Debug/Trace.h +++ b/Code/Framework/AzCore/AzCore/Debug/Trace.h @@ -15,6 +15,11 @@ namespace AZ { namespace Debug { + namespace Platform + { + void OutputToDebugger(const char* window, const char* message); + } + /// Global instance to the tracer. extern class Trace g_tracer; diff --git a/Code/Framework/AzCore/AzCore/EBus/OrderedEvent.inl b/Code/Framework/AzCore/AzCore/EBus/OrderedEvent.inl index 7c2e92d25b..aa3ac7d5ef 100644 --- a/Code/Framework/AzCore/AzCore/EBus/OrderedEvent.inl +++ b/Code/Framework/AzCore/AzCore/EBus/OrderedEvent.inl @@ -7,6 +7,7 @@ */ #pragma once +#include namespace AZ { diff --git a/Code/Framework/AzCore/AzCore/IO/Path/Path.h b/Code/Framework/AzCore/AzCore/IO/Path/Path.h index 6f7e995a74..36640e821d 100644 --- a/Code/Framework/AzCore/AzCore/IO/Path/Path.h +++ b/Code/Framework/AzCore/AzCore/IO/Path/Path.h @@ -9,6 +9,7 @@ #pragma once #include +#include #include #include diff --git a/Code/Framework/AzCore/AzCore/Interface/Interface.h b/Code/Framework/AzCore/AzCore/Interface/Interface.h index 8131f5b08f..8664e2905f 100644 --- a/Code/Framework/AzCore/AzCore/Interface/Interface.h +++ b/Code/Framework/AzCore/AzCore/Interface/Interface.h @@ -9,6 +9,7 @@ #pragma once #include +#include #include #include #include diff --git a/Code/Framework/AzCore/AzCore/Math/Crc.h b/Code/Framework/AzCore/AzCore/Math/Crc.h index e8e8414f72..9ba2a83139 100644 --- a/Code/Framework/AzCore/AzCore/Math/Crc.h +++ b/Code/Framework/AzCore/AzCore/Math/Crc.h @@ -8,7 +8,7 @@ #pragma once #include - +#include #include ////////////////////////////////////////////////////////////////////////// @@ -108,7 +108,7 @@ namespace AZ namespace AZStd { - template<> + template<> struct hash { size_t operator()(const AZ::Crc32& id) const diff --git a/Code/Framework/AzCore/AzCore/Math/PackedVector3.h b/Code/Framework/AzCore/AzCore/Math/PackedVector3.h index 88108350c8..9a9acacdf3 100644 --- a/Code/Framework/AzCore/AzCore/Math/PackedVector3.h +++ b/Code/Framework/AzCore/AzCore/Math/PackedVector3.h @@ -8,6 +8,7 @@ #pragma once #include +#include namespace AZ { diff --git a/Code/Framework/AzCore/AzCore/Math/Random.h b/Code/Framework/AzCore/AzCore/Math/Random.h index 3c87824b1d..4912d9ad29 100644 --- a/Code/Framework/AzCore/AzCore/Math/Random.h +++ b/Code/Framework/AzCore/AzCore/Math/Random.h @@ -9,8 +9,10 @@ #pragma once #include -#include +#include #include +#include +#include namespace AZ { diff --git a/Code/Framework/AzCore/AzCore/Math/Vector2.h b/Code/Framework/AzCore/AzCore/Math/Vector2.h index bd20618f06..c667f48010 100644 --- a/Code/Framework/AzCore/AzCore/Math/Vector2.h +++ b/Code/Framework/AzCore/AzCore/Math/Vector2.h @@ -9,7 +9,7 @@ #pragma once #include -#include +#include namespace AZ { diff --git a/Code/Framework/AzCore/AzCore/Math/Vector3.h b/Code/Framework/AzCore/AzCore/Math/Vector3.h index 4be70aa02e..6b7ded5641 100644 --- a/Code/Framework/AzCore/AzCore/Math/Vector3.h +++ b/Code/Framework/AzCore/AzCore/Math/Vector3.h @@ -9,7 +9,7 @@ #pragma once #include -#include +#include namespace AZ { diff --git a/Code/Framework/AzCore/AzCore/RTTI/TypeInfo.h b/Code/Framework/AzCore/AzCore/RTTI/TypeInfo.h index 8ec55274f5..022025a3df 100644 --- a/Code/Framework/AzCore/AzCore/RTTI/TypeInfo.h +++ b/Code/Framework/AzCore/AzCore/RTTI/TypeInfo.h @@ -1006,12 +1006,6 @@ namespace AZ AZ_TYPE_INFO_INTERNAL_FUNCTION_VARIATION_SPECIALIZATION(AZStd::function, "{C9F9C644-CCC3-4F77-A792-F5B5DBCA746E}"); } // namespace AZ -#define AZ_TYPE_INFO_INTERNAL_1(_ClassName) static_assert(false, "You must provide a ClassName,ClassUUID") -#define AZ_TYPE_INFO_INTERNAL_2(_ClassName, _ClassUuid) \ - void TYPEINFO_Enable(){} \ - static const char* TYPEINFO_Name() { return #_ClassName; } \ - static const AZ::TypeId& TYPEINFO_Uuid() { static AZ::TypeId s_uuid(_ClassUuid); return s_uuid; } - // Template class type info #define AZ_TYPE_INFO_INTERNAL_TEMPLATE(_ClassName, _ClassUuid, ...)\ void TYPEINFO_Enable() {}\ @@ -1050,39 +1044,11 @@ namespace AZ #define AZ_TYPE_INFO_INTERNAL_17 AZ_TYPE_INFO_INTERNAL_TEMPLATE #define AZ_TYPE_INFO_INTERNAL(...) AZ_MACRO_SPECIALIZE(AZ_TYPE_INFO_INTERNAL_, AZ_VA_NUM_ARGS(__VA_ARGS__), (__VA_ARGS__)) -#define AZ_TYPE_INFO_1 AZ_TYPE_INFO_INTERNAL_1 -#define AZ_TYPE_INFO_2 AZ_TYPE_INFO_INTERNAL_2 -#define AZ_TYPE_INFO_3 AZ_TYPE_INFO_INTERNAL_TEMPLATE_DEPRECATED -#define AZ_TYPE_INFO_4 AZ_TYPE_INFO_INTERNAL_TEMPLATE_DEPRECATED -#define AZ_TYPE_INFO_5 AZ_TYPE_INFO_INTERNAL_TEMPLATE_DEPRECATED -#define AZ_TYPE_INFO_6 AZ_TYPE_INFO_INTERNAL_TEMPLATE_DEPRECATED -#define AZ_TYPE_INFO_7 AZ_TYPE_INFO_INTERNAL_TEMPLATE_DEPRECATED -#define AZ_TYPE_INFO_8 AZ_TYPE_INFO_INTERNAL_TEMPLATE_DEPRECATED -#define AZ_TYPE_INFO_9 AZ_TYPE_INFO_INTERNAL_TEMPLATE_DEPRECATED -#define AZ_TYPE_INFO_10 AZ_TYPE_INFO_INTERNAL_TEMPLATE_DEPRECATED -#define AZ_TYPE_INFO_11 AZ_TYPE_INFO_INTERNAL_TEMPLATE_DEPRECATED -#define AZ_TYPE_INFO_12 AZ_TYPE_INFO_INTERNAL_TEMPLATE_DEPRECATED -#define AZ_TYPE_INFO_13 AZ_TYPE_INFO_INTERNAL_TEMPLATE_DEPRECATED -#define AZ_TYPE_INFO_14 AZ_TYPE_INFO_INTERNAL_TEMPLATE_DEPRECATED -#define AZ_TYPE_INFO_15 AZ_TYPE_INFO_INTERNAL_TEMPLATE_DEPRECATED -#define AZ_TYPE_INFO_16 AZ_TYPE_INFO_INTERNAL_TEMPLATE_DEPRECATED -#define AZ_TYPE_INFO_17 AZ_TYPE_INFO_INTERNAL_TEMPLATE_DEPRECATED - // Fall-back for the original version of AZ_TYPE_INFO that accepted template arguments. This should not be used, unless // to fix issues where AZ_TYPE_INFO was incorrectly used and the old UUID has to be maintained. #define AZ_TYPE_INFO_LEGACY AZ_TYPE_INFO_INTERNAL -/** -* Use this macro inside a class to allow it to be identified across modules and serialized (in different contexts). -* The expected input is the class and the assigned uuid as a string or an instance of a uuid. -* Example: -* class MyClass -* { -* public: -* AZ_TYPE_INFO(MyClass, "{BD5B1568-D232-4EBF-93BD-69DB66E3773F}"); -* ... -*/ -#define AZ_TYPE_INFO(...) AZ_MACRO_SPECIALIZE(AZ_TYPE_INFO_, AZ_VA_NUM_ARGS(__VA_ARGS__), (__VA_ARGS__)) +#include /** * Use this macro outside a class to allow it to be identified across modules and serialized (in different contexts). diff --git a/Code/Framework/AzCore/AzCore/RTTI/TypeInfoSimple.h b/Code/Framework/AzCore/AzCore/RTTI/TypeInfoSimple.h new file mode 100644 index 0000000000..4da514f931 --- /dev/null +++ b/Code/Framework/AzCore/AzCore/RTTI/TypeInfoSimple.h @@ -0,0 +1,38 @@ +/* + * 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 + * + */ +#pragma once + +#include +#include + +namespace AZ +{ + using TypeId = AZ::Uuid; +} + +#define AZ_TYPE_INFO_INTERNAL_1(_ClassName) static_assert(false, "You must provide a ClassName,ClassUUID") +#define AZ_TYPE_INFO_INTERNAL_2(_ClassName, _ClassUuid) \ + void TYPEINFO_Enable(){} \ + static const char* TYPEINFO_Name() { return #_ClassName; } \ + static const AZ::TypeId& TYPEINFO_Uuid() { static AZ::TypeId s_uuid(_ClassUuid); return s_uuid; } + +#define AZ_TYPE_INFO_1 AZ_TYPE_INFO_INTERNAL_1 +#define AZ_TYPE_INFO_2 AZ_TYPE_INFO_INTERNAL_2 + +/** +* Use this macro inside a class to allow it to be identified across modules and serialized (in different contexts). +* The expected input is the class and the assigned uuid as a string or an instance of a uuid. +* Example: +* class MyClass +* { +* public: +* AZ_TYPE_INFO(MyClass, "{BD5B1568-D232-4EBF-93BD-69DB66E3773F}"); +* ... +*/ +#define AZ_TYPE_INFO(...) AZ_MACRO_SPECIALIZE(AZ_TYPE_INFO_, AZ_VA_NUM_ARGS(__VA_ARGS__), (__VA_ARGS__)) + diff --git a/Code/Framework/AzCore/AzCore/Serialization/DataOverlay.h b/Code/Framework/AzCore/AzCore/Serialization/DataOverlay.h index 41f0b129e2..0fc4c5b362 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/DataOverlay.h +++ b/Code/Framework/AzCore/AzCore/Serialization/DataOverlay.h @@ -9,7 +9,7 @@ #define AZCORE_DATA_OVERLAY_H #include -#include +#include namespace AZ { diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.h index eb7fd250d0..084e46194b 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.h @@ -10,7 +10,7 @@ #include #include -#include +#include namespace AZ { diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.h index f3da5d6b1c..4ba5c2b011 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.h @@ -10,7 +10,7 @@ #include #include -#include +#include namespace AZ { diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.h index b7a1989c83..4a22e84bad 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.h @@ -10,7 +10,7 @@ #include #include -#include +#include namespace AZ { diff --git a/Code/Framework/AzCore/AzCore/azcore_files.cmake b/Code/Framework/AzCore/AzCore/azcore_files.cmake index c33d678730..0c95b9d592 100644 --- a/Code/Framework/AzCore/AzCore/azcore_files.cmake +++ b/Code/Framework/AzCore/AzCore/azcore_files.cmake @@ -434,6 +434,7 @@ set(FILES Preprocessor/Sequences.h RTTI/RTTI.h RTTI/TypeInfo.h + RTTI/TypeInfoSimple.h RTTI/ReflectContext.h RTTI/ReflectContext.cpp RTTI/ReflectionManager.h diff --git a/Code/Framework/AzCore/AzCore/base.h b/Code/Framework/AzCore/AzCore/base.h index 252133e781..20f5c17b27 100644 --- a/Code/Framework/AzCore/AzCore/base.h +++ b/Code/Framework/AzCore/AzCore/base.h @@ -51,88 +51,86 @@ # define azvscprintf(_format, _va_list) _vscprintf(_format, _va_list) # define azscwprintf _scwprintf # define azvscwprintf _vscwprintf -# define azstrtok(_buffer, _size, _delim, _context) strtok_s(_buffer, _delim, _context) -# define azstrcat strcat_s -# define azstrncat strncat_s -# define strtoll _strtoi64 -# define strtoull _strtoui64 -# define azsscanf sscanf_s -# define azstrcpy strcpy_s -# define azstrncpy strncpy_s -# define azstricmp _stricmp -# define azstrnicmp _strnicmp -# define azisfinite _finite -# define azltoa _ltoa_s -# define azitoa _itoa_s -# define azui64toa _ui64toa_s -# define azswscanf swscanf_s -# define azwcsicmp _wcsicmp -# define azwcsnicmp _wcsnicmp -# define azmemicmp _memicmp +# define azstrtok(_buffer, _size, _delim, _context) strtok_s(_buffer, _delim, _context) +# define azstrcat(_dest, _destSize, _src) strcat_s(_dest, _destSize, _src) +# define azstrncat(_dest, _destSize, _src, _count) strncat_s(_dest, _destSize, _src, _count) +# define strtoll _strtoi64 +# define strtoull _strtoui64 +# define azsscanf sscanf_s +# define azstrcpy(_dest, _destSize, _src) strcpy_s(_dest, _destSize, _src) +# define azstrncpy(_dest, _destSize, _src, _count) strncpy_s(_dest, _destSize, _src, _count) +# define azstricmp _stricmp +# define azstrnicmp _strnicmp +# define azisfinite _finite +# define azltoa _ltoa_s +# define azitoa _itoa_s +# define azui64toa _ui64toa_s +# define azswscanf swscanf_s +# define azwcsicmp _wcsicmp +# define azwcsnicmp _wcsnicmp // note: for cross-platform compatibility, do not use the return value of azfopen. On Windows, it's an errno_t and 0 indicates success. On other platforms, the return value is a FILE*, and a 0 value indicates failure. -# define azfopen fopen_s -# define azfscanf fscanf_s +# define azfopen(_fp, _filename, _attrib) fopen_s(_fp, _filename, _attrib) +# define azfscanf fscanf_s -# define azsprintf(_buffer, ...) sprintf_s(_buffer, AZ_ARRAY_SIZE(_buffer), __VA_ARGS__) -# define azstrlwr _strlwr_s -# define azvsprintf vsprintf_s -# define azwcscpy wcscpy_s -# define azstrtime _strtime_s -# define azstrdate _strdate_s -# define azlocaltime(time, result) localtime_s(result, time) +# define azsprintf(_buffer, ...) sprintf_s(_buffer, AZ_ARRAY_SIZE(_buffer), __VA_ARGS__) +# define azstrlwr _strlwr_s +# define azvsprintf vsprintf_s +# define azwcscpy wcscpy_s +# define azstrtime _strtime_s +# define azstrdate _strdate_s +# define azlocaltime(time, result) localtime_s(result, time) #else -# define azsnprintf snprintf -# define azvsnprintf vsnprintf +# define azsnprintf snprintf +# define azvsnprintf vsnprintf # if AZ_TRAIT_COMPILER_DEFINE_AZSWNPRINTF_AS_SWPRINTF -# define azsnwprintf swprintf -# define azvsnwprintf vswprintf +# define azsnwprintf swprintf +# define azvsnwprintf vswprintf # else -# define azsnwprintf snwprintf -# define azvsnwprintf vsnwprintf +# define azsnwprintf snwprintf +# define azvsnwprintf vsnwprintf # endif -# define azscprintf(...) azsnprintf(nullptr, static_cast(0), __VA_ARGS__); -# define azvscprintf(_format, _va_list) azvsnprintf(nullptr, static_cast(0), _format, _va_list); -# define azscwprintf(...) azsnwprintf(nullptr, static_cast(0), __VA_ARGS__); -# define azvscwprintf(_format, _va_list) azvsnwprintf(nullptr, static_cast(0), _format, _va_list); -# define azstrtok(_buffer, _size, _delim, _context) strtok(_buffer, _delim) -# define azstrcat(_dest, _destSize, _src) strcat(_dest, _src) -# define azstrncat(_dest, _destSize, _src, _count) strncat(_dest, _src, _count) -# define azsscanf sscanf -# define azstrcpy(_dest, _destSize, _src) strcpy(_dest, _src) -# define azstrncpy(_dest, _destSize, _src, _count) strncpy(_dest, _src, _count) -# define azstricmp strcasecmp -# define azstrnicmp strncasecmp +# define azscprintf(...) azsnprintf(nullptr, static_cast(0), __VA_ARGS__); +# define azvscprintf(_format, _va_list) azvsnprintf(nullptr, static_cast(0), _format, _va_list); +# define azscwprintf(...) azsnwprintf(nullptr, static_cast(0), __VA_ARGS__); +# define azvscwprintf(_format, _va_list) azvsnwprintf(nullptr, static_cast(0), _format, _va_list); +# define azstrtok(_buffer, _size, _delim, _context) strtok(_buffer, _delim) +# define azstrcat(_dest, _destSize, _src) strcat(_dest, _src) +# define azstrncat(_dest, _destSize, _src, _count) strncat(_dest, _src, _count) +# define azsscanf sscanf +# define azstrcpy(_dest, _destSize, _src) strcpy(_dest, _src) +# define azstrncpy(_dest, _destSize, _src, _count) strncpy(_dest, _src, _count) +# define azstricmp strcasecmp +# define azstrnicmp strncasecmp # if defined(NDK_REV_MAJOR) && NDK_REV_MAJOR < 16 -# define azisfinite __isfinitef +# define azisfinite __isfinitef # else -# define azisfinite isfinite +# define azisfinite isfinite # endif -# define azltoa(_value, _buffer, _size, _radix) ltoa(_value, _buffer, _radix) -# define azitoa(_value, _buffer, _size, _radix) itoa(_value, _buffer, _radix) -# define azui64toa(_value, _buffer, _size, _radix) _ui64toa(_value, _buffer, _radix) -# define azswscanf swscanf -# define azwcsicmp wcsicmp -# define azwcsnicmp wcsnicmp -# define azmemicmp memicmp +# define azltoa(_value, _buffer, _size, _radix) ltoa(_value, _buffer, _radix) +# define azitoa(_value, _buffer, _size, _radix) itoa(_value, _buffer, _radix) +# define azui64toa(_value, _buffer, _size, _radix) _ui64toa(_value, _buffer, _radix) +# define azswscanf swscanf +# define azwcsicmp wcscasecmp +# define azwcsnicmp wcsnicmp // note: for cross-platform compatibility, do not use the return value of azfopen. On Windows, it's an errno_t and 0 indicates success. On other platforms, the return value is a FILE*, and a 0 value indicates failure. -# define azfopen(_fp, _filename, _attrib) *(_fp) = fopen(_filename, _attrib) -# define azfscanf fscanf +# define azfopen(_fp, _filename, _attrib) *(_fp) = fopen(_filename, _attrib) +# define azfscanf fscanf -# define azsprintf sprintf -# define azstrlwr(_buffer, _size) strlwr(_buffer) -# define azvsprintf vsprintf -# define azwcscpy(_dest, _size, _buffer) wcscpy(_dest, _buffer) -# define azstrtime _strtime -# define azstrdate _strdate -# define azlocaltime localtime_r +# define azsprintf sprintf +# define azstrlwr(_buffer, _size) strlwr(_buffer) +# define azvsprintf vsprintf +# define azwcscpy(_dest, _size, _buffer) wcscpy(_dest, _buffer) +# define azstrtime _strtime +# define azstrdate _strdate +# define azlocaltime localtime_r #endif #if AZ_TRAIT_USE_POSIX_STRERROR_R -# define azstrerror_s(_dst, _num, _err) strerror_r(_err, _dst, _num) +# define azstrerror_s(_dst, _num, _err) strerror_r(_err, _dst, _num) #else -# define azstrerror_s strerror_s +# define azstrerror_s strerror_s #endif #define AZ_INVALID_POINTER reinterpret_cast(0x0badf00dul) diff --git a/Code/Framework/AzCore/AzCore/std/allocator.h b/Code/Framework/AzCore/AzCore/std/allocator.h index 0e024bbb5f..0fee5481e2 100644 --- a/Code/Framework/AzCore/AzCore/std/allocator.h +++ b/Code/Framework/AzCore/AzCore/std/allocator.h @@ -10,7 +10,7 @@ #include #include -#include +#include namespace AZStd { diff --git a/Code/Framework/AzCore/AzCore/std/allocator_traits.h b/Code/Framework/AzCore/AzCore/std/allocator_traits.h index 227727f694..95e64bbc49 100644 --- a/Code/Framework/AzCore/AzCore/std/allocator_traits.h +++ b/Code/Framework/AzCore/AzCore/std/allocator_traits.h @@ -11,6 +11,7 @@ #include #include #include +#include namespace AZStd { diff --git a/Code/Framework/AzCore/AzCore/std/chrono/types.h b/Code/Framework/AzCore/AzCore/std/chrono/types.h index 19ef2c8469..ce42482132 100644 --- a/Code/Framework/AzCore/AzCore/std/chrono/types.h +++ b/Code/Framework/AzCore/AzCore/std/chrono/types.h @@ -10,7 +10,6 @@ #include #include -#include #include #include #include diff --git a/Code/Framework/AzCore/AzCore/std/containers/deque.h b/Code/Framework/AzCore/AzCore/std/containers/deque.h index 170f3316f0..215845a8f4 100644 --- a/Code/Framework/AzCore/AzCore/std/containers/deque.h +++ b/Code/Framework/AzCore/AzCore/std/containers/deque.h @@ -5,14 +5,17 @@ * SPDX-License-Identifier: Apache-2.0 OR MIT * */ +#pragma once #ifndef AZSTD_DEQUE_H #define AZSTD_DEQUE_H 1 + #include #include #include #include #include +#include namespace AZStd { @@ -1242,4 +1245,3 @@ namespace AZStd } #endif // AZSTD_DEQUE_H -#pragma once diff --git a/Code/Framework/AzCore/AzCore/std/containers/list.h b/Code/Framework/AzCore/AzCore/std/containers/list.h index 4d78c01364..124d8b7d7c 100644 --- a/Code/Framework/AzCore/AzCore/std/containers/list.h +++ b/Code/Framework/AzCore/AzCore/std/containers/list.h @@ -7,12 +7,14 @@ */ #ifndef AZSTD_LIST_H #define AZSTD_LIST_H 1 +#pragma once #include #include #include #include #include +#include namespace AZStd { @@ -1346,4 +1348,3 @@ namespace AZStd } #endif // AZSTD_LIST_H -#pragma once diff --git a/Code/Framework/AzCore/AzCore/std/containers/ring_buffer.h b/Code/Framework/AzCore/AzCore/std/containers/ring_buffer.h index 31fbdd85e9..7e84124958 100644 --- a/Code/Framework/AzCore/AzCore/std/containers/ring_buffer.h +++ b/Code/Framework/AzCore/AzCore/std/containers/ring_buffer.h @@ -12,7 +12,6 @@ #include #include #include -//#include namespace AZStd { diff --git a/Code/Framework/AzCore/AzCore/std/containers/vector.h b/Code/Framework/AzCore/AzCore/std/containers/vector.h index 5c1c4da16c..bf02527d77 100644 --- a/Code/Framework/AzCore/AzCore/std/containers/vector.h +++ b/Code/Framework/AzCore/AzCore/std/containers/vector.h @@ -5,13 +5,13 @@ * SPDX-License-Identifier: Apache-2.0 OR MIT * */ -#ifndef AZSTD_VECTOR_H -#define AZSTD_VECTOR_H 1 +#pragma once #include #include #include #include +#include namespace AZStd { @@ -1395,6 +1395,3 @@ namespace AZStd return removedCount; } } - -#endif // AZSTD_VECTOR_H -#pragma once diff --git a/Code/Framework/AzCore/AzCore/std/createdestroy.h b/Code/Framework/AzCore/AzCore/std/createdestroy.h index 94b86a58e4..0fa6e4ed40 100644 --- a/Code/Framework/AzCore/AzCore/std/createdestroy.h +++ b/Code/Framework/AzCore/AzCore/std/createdestroy.h @@ -16,6 +16,7 @@ #include #include #include +#include // AZStd::addressof namespace AZStd { diff --git a/Code/Framework/AzCore/AzCore/std/function/function_base.h b/Code/Framework/AzCore/AzCore/std/function/function_base.h index 409c3824a4..c1dd669f51 100644 --- a/Code/Framework/AzCore/AzCore/std/function/function_base.h +++ b/Code/Framework/AzCore/AzCore/std/function/function_base.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/Code/Framework/AzCore/AzCore/std/function/function_template.h b/Code/Framework/AzCore/AzCore/std/function/function_template.h index 4f7d41dbd9..586b02e671 100644 --- a/Code/Framework/AzCore/AzCore/std/function/function_template.h +++ b/Code/Framework/AzCore/AzCore/std/function/function_template.h @@ -9,6 +9,7 @@ #include #include +#include #include #include diff --git a/Code/Framework/AzCore/AzCore/std/hash_table.h b/Code/Framework/AzCore/AzCore/std/hash_table.h index c364720b3b..9a31020c49 100644 --- a/Code/Framework/AzCore/AzCore/std/hash_table.h +++ b/Code/Framework/AzCore/AzCore/std/hash_table.h @@ -7,7 +7,6 @@ */ #pragma once -#include #include #include #include diff --git a/Code/Framework/AzCore/AzCore/std/iterator.h b/Code/Framework/AzCore/AzCore/std/iterator.h index 6135b6f450..8d0d49b649 100644 --- a/Code/Framework/AzCore/AzCore/std/iterator.h +++ b/Code/Framework/AzCore/AzCore/std/iterator.h @@ -8,8 +8,9 @@ #pragma once #include -#include #include +#include +#include #include // use by ConstIteratorCast #include diff --git a/Code/Framework/AzCore/AzCore/std/parallel/atomic.h b/Code/Framework/AzCore/AzCore/std/parallel/atomic.h index 09b6f68166..8516dd976a 100644 --- a/Code/Framework/AzCore/AzCore/std/parallel/atomic.h +++ b/Code/Framework/AzCore/AzCore/std/parallel/atomic.h @@ -8,8 +8,6 @@ #pragma once #include -#include -#include #include namespace AZStd diff --git a/Code/Framework/AzCore/AzCore/std/parallel/binary_semaphore.h b/Code/Framework/AzCore/AzCore/std/parallel/binary_semaphore.h index 797de5fceb..f9d0cdbe4d 100644 --- a/Code/Framework/AzCore/AzCore/std/parallel/binary_semaphore.h +++ b/Code/Framework/AzCore/AzCore/std/parallel/binary_semaphore.h @@ -38,13 +38,13 @@ namespace AZStd binary_semaphore(bool initialState = false) { - m_event = CreateEvent(nullptr, false, initialState, nullptr); + m_event = CreateEventW(nullptr, false, initialState, nullptr); AZ_Assert(m_event != NULL, "CreateEvent error: %d\n", GetLastError()); } binary_semaphore(const char* name, bool initialState = false) { (void)name; // name is used only for debug, if we pass it to the semaphore it will become named semaphore - m_event = CreateEvent(nullptr, false, initialState, nullptr); + m_event = CreateEventW(nullptr, false, initialState, nullptr); AZ_Assert(m_event != NULL, "CreateEvent error: %d\n", GetLastError()); } diff --git a/Code/Framework/AzCore/AzCore/std/smart_ptr/intrusive_ptr.h b/Code/Framework/AzCore/AzCore/std/smart_ptr/intrusive_ptr.h index 20bc51a18b..9ee9b94fd0 100644 --- a/Code/Framework/AzCore/AzCore/std/smart_ptr/intrusive_ptr.h +++ b/Code/Framework/AzCore/AzCore/std/smart_ptr/intrusive_ptr.h @@ -5,8 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 OR MIT * */ -#ifndef AZSTD_SMART_PTR_INTRUSIVE_PTR_H -#define AZSTD_SMART_PTR_INTRUSIVE_PTR_H +#pragma once // // intrusive_ptr.hpp @@ -19,10 +18,10 @@ // // See http://www.boost.org/libs/smart_ptr/intrusive_ptr.html for documentation. // - -#include #include +#include #include +#include namespace AZStd { @@ -112,7 +111,7 @@ namespace AZStd CountPolicy::add_ref(px); } } - + ~intrusive_ptr() { if (px != 0) @@ -120,7 +119,7 @@ namespace AZStd CountPolicy::release(px); } } - + template enable_if_t::value, intrusive_ptr&> operator=(intrusive_ptr const& rhs) { @@ -157,28 +156,28 @@ namespace AZStd this_type(rhs).swap(*this); return *this; } - + intrusive_ptr& operator=(T* rhs) { this_type(rhs).swap(*this); return *this; } - + void reset() { this_type().swap(*this); } - + void reset(T* rhs) { this_type(rhs).swap(*this); } - + T* get() const { return px; } - + T& operator*() const { AZ_Assert(px != 0, "You can't dereference a null pointer"); @@ -298,6 +297,3 @@ namespace AZStd // operator<< - not supported } // namespace AZStd - -#endif // #ifndef AZSTD_SMART_PTR_INTRUSIVE_PTR_H -#pragma once diff --git a/Code/Framework/AzCore/AzCore/std/string/conversions.h b/Code/Framework/AzCore/AzCore/std/string/conversions.h index 3e5a393cf8..be71e12275 100644 --- a/Code/Framework/AzCore/AzCore/std/string/conversions.h +++ b/Code/Framework/AzCore/AzCore/std/string/conversions.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include #include @@ -30,41 +31,93 @@ namespace AZStd template struct WCharTPlatformConverter { - template - static inline void to_string(AZStd::basic_string& dest, const wchar_t* first, const wchar_t* last) + static_assert(Size == size_t{ 2 } || Size == size_t{ 4 }, "only wchar_t types of size 2 or 4 can be converted to utf8"); + + template + static inline void to_string(AZStd::basic_string& dest, AZStd::wstring_view src) { if constexpr (Size == 2) { - Utf8::Unchecked::utf16to8(first, last, AZStd::back_inserter(dest)); + Utf8::Unchecked::utf16to8(src.begin(), src.end(), AZStd::back_inserter(dest), dest.max_size()); } else if constexpr (Size == 4) { - Utf8::Unchecked::utf32to8(first, last, AZStd::back_inserter(dest)); - } - else - { - // Workaround to defer static_assert evaluation until this function is invoked by using the template parameter - using StringType = AZStd::basic_string; - static_assert(!AZStd::is_same_v, "only wchar_t types of size 2 or 4 can be converted to utf8"); + Utf8::Unchecked::utf32to8(src.begin(), src.end(), AZStd::back_inserter(dest), dest.max_size()); } } - template - static inline void to_wstring(AZStd::basic_string& dest, const char* first, const char* last) + template + static inline void to_string(AZStd::basic_fixed_string& dest, AZStd::wstring_view src) { if constexpr (Size == 2) { - Utf8::Unchecked::utf8to16(first, last, AZStd::back_inserter(dest)); + Utf8::Unchecked::utf16to8(src.begin(), src.end(), AZStd::back_inserter(dest), dest.max_size()); } else if constexpr (Size == 4) { - Utf8::Unchecked::utf8to32(first, last, AZStd::back_inserter(dest)); + Utf8::Unchecked::utf32to8(src.begin(), src.end(), AZStd::back_inserter(dest), dest.max_size()); } - else + } + + static inline char* to_string(char* dest, size_t destSize, AZStd::wstring_view src) + { + if constexpr (Size == 2) { - // Workaround to defer static_assert evaluation until this function is invoked by using the template parameter - using StringType = AZStd::basic_string; - static_assert(!AZStd::is_same_v, "Cannot convert a utf8 string to a wchar_t that isn't size 2 or 4"); + return Utf8::Unchecked::utf16to8(src.begin(), src.end(), dest, destSize); + } + else if constexpr (Size == 4) + { + return Utf8::Unchecked::utf32to8(src.begin(), src.end(), dest, destSize); + } + } + + static inline size_t to_string_length(AZStd::wstring_view src) + { + if constexpr (Size == 2) + { + return Utf8::Unchecked::utf16ToUtf8BytesRequired(src.begin(), src.end()); + } + else if constexpr (Size == 4) + { + return Utf8::Unchecked::utf32ToUtf8BytesRequired(src.begin(), src.end()); + } + } + + template + static inline void to_wstring(AZStd::basic_string& dest, AZStd::string_view src) + { + if constexpr (Size == 2) + { + Utf8::Unchecked::utf8to16(src.begin(), src.end(), AZStd::back_inserter(dest), dest.max_size()); + } + else if constexpr (Size == 4) + { + Utf8::Unchecked::utf8to32(src.begin(), src.end(), AZStd::back_inserter(dest), dest.max_size()); + } + } + + template + static inline void to_wstring(AZStd::basic_fixed_string& dest, AZStd::string_view src) + { + if constexpr (Size == 2) + { + Utf8::Unchecked::utf8to16(src.begin(), src.end(), AZStd::back_inserter(dest), dest.max_size()); + } + else if constexpr (Size == 4) + { + Utf8::Unchecked::utf8to32(src.begin(), src.end(), AZStd::back_inserter(dest), dest.max_size()); + } + } + + static inline wchar_t* to_wstring(wchar_t* dest, size_t destSize, AZStd::string_view src) + { + if constexpr (Size == 2) + { + return Utf8::Unchecked::utf8to16(src.begin(), src.end(), dest, destSize); + } + else if constexpr (Size == 4) + { + return Utf8::Unchecked::utf8to32(src.begin(), src.end(), dest, destSize); } } }; @@ -244,26 +297,32 @@ namespace AZStd inline AZStd::string to_string(long double val) { AZStd::string str; to_string(str, val); return str; } // In our engine we assume AZStd::string is Utf8 encoded! - template - void to_string(AZStd::basic_string& dest, const wchar_t* str, size_t srcLen = 0) + template + void to_string(AZStd::basic_string& dest, AZStd::wstring_view src) { dest.clear(); + Internal::WCharTPlatformConverter<>::to_string(dest, src); + } - if (srcLen == 0) - { - srcLen = wcslen(str); - } + template + void to_string(AZStd::basic_fixed_string& dest, AZStd::wstring_view src) + { + dest.clear(); + Internal::WCharTPlatformConverter<>::to_string(dest, src); + } - if (srcLen > 0) + inline void to_string(char* dest, size_t destSize, AZStd::wstring_view src) + { + char* endStr = Internal::WCharTPlatformConverter<>::to_string(dest, destSize, src); + if (endStr < (dest + destSize)) { - Internal::WCharTPlatformConverter<>::to_string(dest, str, str + srcLen); + *endStr = '\0'; // null terminator } } - template - void to_string(AZStd::basic_string& dest, const AZStd::basic_string& src) + inline size_t to_string_length(AZStd::wstring_view src) { - return to_string(dest, src.c_str(), src.length()); + return Internal::WCharTPlatformConverter<>::to_string_length(src); } template @@ -362,26 +421,27 @@ namespace AZStd inline AZStd::wstring to_wstring(unsigned long long val) { AZStd::wstring wstr; to_wstring(wstr, val); return wstr; } inline AZStd::wstring to_wstring(long double val) { AZStd::wstring wstr; to_wstring(wstr, val); return wstr; } - template - void to_wstring(AZStd::basic_string& dest, const char* str, size_t strLen = 0) + template + void to_wstring(AZStd::basic_string& dest, AZStd::string_view src) { dest.clear(); - - if (strLen == 0) - { - strLen = strlen(str); - } - - if (strLen > 0) - { - Internal::WCharTPlatformConverter<>::to_wstring(dest, str, str + strLen); - } + Internal::WCharTPlatformConverter<>::to_wstring(dest, src); } - template - void to_wstring(AZStd::basic_string& dest, const AZStd::basic_string& src) + template + void to_wstring(AZStd::basic_fixed_string& dest, AZStd::string_view src) { - return to_wstring(dest, src.c_str(), src.length()); + dest.clear(); + Internal::WCharTPlatformConverter<>::to_wstring(dest, src); + } + + inline void to_wstring(wchar_t* dest, size_t destSize, AZStd::string_view src) + { + wchar_t* endWStr = Internal::WCharTPlatformConverter<>::to_wstring(dest, destSize, src); + if (endWStr < (dest + destSize)) + { + *endWStr = '\0'; // null terminator + } } // Convert a range of chars to lower case diff --git a/Code/Framework/AzCore/AzCore/std/string/string.h b/Code/Framework/AzCore/AzCore/std/string/string.h index 4d8fb0c5b5..ad3546ab09 100644 --- a/Code/Framework/AzCore/AzCore/std/string/string.h +++ b/Code/Framework/AzCore/AzCore/std/string/string.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/Code/Framework/AzCore/AzCore/std/string/string_view.h b/Code/Framework/AzCore/AzCore/std/string/string_view.h index a3d243dae7..9a98795554 100644 --- a/Code/Framework/AzCore/AzCore/std/string/string_view.h +++ b/Code/Framework/AzCore/AzCore/std/string/string_view.h @@ -8,15 +8,16 @@ #pragma once #include -#include #include #include -#include + namespace AZStd { namespace StringInternal { + constexpr size_t min_size(size_t left, size_t right) { return (left < right) ? left : right; } + template constexpr SizeT char_find(const CharT* s, size_t count, CharT ch, SizeT npos = static_cast(-1)) noexcept { @@ -83,7 +84,7 @@ namespace AZStd } // Add one to offset so that for loop condition can check against 0 as the breakout condition - size_t lastIndex = (AZStd::min)(offset, size - count) + 1; + size_t lastIndex = StringInternal::min_size(offset, size - count) + 1; for (; lastIndex; --lastIndex) { @@ -576,7 +577,7 @@ namespace AZStd { return 0; } - size_type rlen = AZStd::min(count, size() - pos); + size_type rlen = StringInternal::min_size(count, size() - pos); Traits::copy(dest, data() + pos, rlen); return rlen; } @@ -584,12 +585,12 @@ namespace AZStd constexpr basic_string_view substr(size_type pos = 0, size_type count = npos) const { AZ_Assert(pos <= size(), "Cannot create substring where position is larger than size"); - return pos > size() ? basic_string_view() : basic_string_view(data() + pos, AZStd::min(count, size() - pos)); + return pos > size() ? basic_string_view() : basic_string_view(data() + pos, StringInternal::min_size(count, size() - pos)); } constexpr int compare(basic_string_view other) const { - size_t cmpSize = AZStd::min(size(), other.size()); + size_t cmpSize = StringInternal::min_size(size(), other.size()); int cmpval = cmpSize == 0 ? 0 : Traits::compare(data(), other.data(), cmpSize); if (cmpval == 0) { @@ -891,6 +892,8 @@ namespace AZStd return hash; } + template + struct hash; template struct hash> { diff --git a/Code/Framework/AzCore/AzCore/std/string/utf8/unchecked.h b/Code/Framework/AzCore/AzCore/std/string/utf8/unchecked.h index 9608ff897b..7199c58d3e 100644 --- a/Code/Framework/AzCore/AzCore/std/string/utf8/unchecked.h +++ b/Code/Framework/AzCore/AzCore/std/string/utf8/unchecked.h @@ -92,33 +92,58 @@ namespace Utf8::Unchecked return temp; } - static Iterator to_utf8_sequence(AZ::u32 cp, Iterator result) + static Iterator to_utf8_sequence(AZ::u32 cp, Iterator& result, size_t& resultMaxSize) { if (cp < 0x80) { // one octet + resultMaxSize -= 1; // no need to check the calling function will exit the loop *(result++) = static_cast(cp); } else if (cp < 0x800) { // two octets - *(result++) = static_cast((cp >> 6) | 0xc0); - *(result++) = static_cast((cp & 0x3f) | 0x80); + if (resultMaxSize >= 2) + { + *(result++) = static_cast((cp >> 6) | 0xc0); + *(result++) = static_cast((cp & 0x3f) | 0x80); + resultMaxSize -= 2; + } + else + { + resultMaxSize = 0; + } } else if (cp < 0x10000) { // three octets - *(result++) = static_cast((cp >> 12) | 0xe0); - *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); - *(result++) = static_cast((cp & 0x3f) | 0x80); + if (resultMaxSize >= 3) + { + *(result++) = static_cast((cp >> 12) | 0xe0); + *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); + *(result++) = static_cast((cp & 0x3f) | 0x80); + resultMaxSize -= 3; + } + else + { + resultMaxSize = 0; + } } else { // four octets - *(result++) = static_cast((cp >> 18) | 0xf0); - *(result++) = static_cast(((cp >> 12) & 0x3f) | 0x80); - *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); - *(result++) = static_cast((cp & 0x3f) | 0x80); + if (resultMaxSize >= 4) + { + *(result++) = static_cast((cp >> 18) | 0xf0); + *(result++) = static_cast(((cp >> 12) & 0x3f) | 0x80); + *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); + *(result++) = static_cast((cp & 0x3f) | 0x80); + resultMaxSize -= 4; + } + else + { + resultMaxSize = 0; + } } return result; } @@ -155,8 +180,99 @@ namespace Utf8::Unchecked }; template - Utf8Iterator utf16to8(u16bit_iterator start, u16bit_iterator end, Utf8Iterator result) + Utf8Iterator utf16to8(u16bit_iterator start, u16bit_iterator end, Utf8Iterator result, size_t resultMaxSize) { + while (start != end && resultMaxSize > 0) + { + AZ::u32 cp = Utf8::Internal::mask16(*start++); + // Take care of surrogate pairs first + if (Utf8::Internal::is_lead_surrogate(cp)) + { + AZ::u32 trail_surrogate = Utf8::Internal::mask16(*start++); + cp = (cp << 10) + trail_surrogate + Internal::SURROGATE_OFFSET; + } + octet_iterator::to_utf8_sequence(cp, result, resultMaxSize); + } + return result; + } + + template + u16bit_iterator utf8to16(Utf8Iterator start, Utf8Iterator end, u16bit_iterator result, size_t resultMaxSize) + { + octet_iterator utf8Start(start); + octet_iterator utf8Last(end); + while (utf8Start != utf8Last && resultMaxSize > 0) + { + AZ::u32 cp = *utf8Start++; + if (cp > 0xffff) + { + //make a surrogate pair + if (resultMaxSize >= 2) + { + *result++ = static_cast((cp >> 10) + Internal::LEAD_OFFSET); + *result++ = static_cast((cp & 0x3ff) + Internal::TRAIL_SURROGATE_MIN); + resultMaxSize -= 2; + } + else + { + resultMaxSize = 0; + } + } + else + { + *result++ = static_cast(cp); + resultMaxSize -= 1; + } + } + return result; + } + + template + Utf8Iterator utf32to8(u32bit_iterator start, u32bit_iterator end, Utf8Iterator result, size_t resultMaxSize) + { + while (start != end && resultMaxSize > 0) + { + octet_iterator::to_utf8_sequence(*start++, result, resultMaxSize); + } + + return result; + } + + template + u32bit_iterator utf8to32(Utf8Iterator start, Utf8Iterator end, u32bit_iterator result, size_t resultMaxSize) + { + octet_iterator utf8Start(start); + octet_iterator utf8Last(end); + while (utf8Start != utf8Last && resultMaxSize > 0) + { + *result++ = *utf8Start++; + --resultMaxSize; + } + + return result; + } + + static constexpr size_t utf8_codepoint_length(AZ::u32 cp) + { + if (cp < 0x80) + { + return 1; + } + else if (cp < 0x800) + { + return 2; + } + else if (cp < 0x10000) + { + return 3; + } + return 4; + } + + template + size_t utf16ToUtf8BytesRequired(u16bit_iterator start, u16bit_iterator end) + { + size_t bytesRequired = 0; while (start != end) { AZ::u32 cp = Utf8::Internal::mask16(*start++); @@ -166,56 +282,23 @@ namespace Utf8::Unchecked AZ::u32 trail_surrogate = Utf8::Internal::mask16(*start++); cp = (cp << 10) + trail_surrogate + Internal::SURROGATE_OFFSET; } - octet_iterator::to_utf8_sequence(cp, result); + bytesRequired += utf8_codepoint_length(cp); } - return result; + return bytesRequired; } - template - u16bit_iterator utf8to16(Utf8Iterator start, Utf8Iterator end, u16bit_iterator result) - { - octet_iterator utf8Start(start); - octet_iterator utf8Last(end); - while (utf8Start != utf8Last) - { - AZ::u32 cp = *utf8Start++; - if (cp > 0xffff) - { - //make a surrogate pair - *result++ = static_cast((cp >> 10) + Internal::LEAD_OFFSET); - *result++ = static_cast((cp & 0x3ff) + Internal::TRAIL_SURROGATE_MIN); - } - else - { - *result++ = static_cast(cp); - } - } - return result; - } - - template - Utf8Iterator utf32to8(u32bit_iterator start, u32bit_iterator end, Utf8Iterator result) + template + size_t utf32ToUtf8BytesRequired(u32bit_iterator start, u32bit_iterator end) { + size_t bytesRequired = 0; while (start != end) { - octet_iterator::to_utf8_sequence(*start++, result); + bytesRequired += utf8_codepoint_length(*start++); } - - return result; + return bytesRequired; } - template - u32bit_iterator utf8to32(Utf8Iterator start, Utf8Iterator end, u32bit_iterator result) - { - octet_iterator utf8Start(start); - octet_iterator utf8Last(end); - while (utf8Start != utf8Last) - { - *result++ = *utf8Start++; - } - return result; - } } // namespace Utf8::Unchecked diff --git a/Code/Framework/AzCore/AzCore/std/typetraits/conjunction.h b/Code/Framework/AzCore/AzCore/std/typetraits/conjunction.h index c6084e020e..64f923a40e 100644 --- a/Code/Framework/AzCore/AzCore/std/typetraits/conjunction.h +++ b/Code/Framework/AzCore/AzCore/std/typetraits/conjunction.h @@ -8,6 +8,7 @@ #pragma once #include +#include // for true_type namespace AZStd { diff --git a/Code/Framework/AzCore/AzCore/std/typetraits/static_storage.h b/Code/Framework/AzCore/AzCore/std/typetraits/static_storage.h index 449c9d85c0..00a683b0a8 100644 --- a/Code/Framework/AzCore/AzCore/std/typetraits/static_storage.h +++ b/Code/Framework/AzCore/AzCore/std/typetraits/static_storage.h @@ -9,11 +9,12 @@ #include #include -#include +#include #include namespace AZStd { + using std::forward; // Extension: static_storage: Used to initialize statics in a thread-safe manner // These are similar to default_delete/no_delete, except they just invoke the destructor (or not) template diff --git a/Code/Framework/AzCore/AzCore/std/utils.h b/Code/Framework/AzCore/AzCore/std/utils.h index 0de56cedcb..4c918250de 100644 --- a/Code/Framework/AzCore/AzCore/std/utils.h +++ b/Code/Framework/AzCore/AzCore/std/utils.h @@ -23,7 +23,7 @@ #include #include -#include +#include namespace AZStd { diff --git a/Code/Framework/AzCore/Platform/Common/Apple/AzCore/Debug/Trace_Apple.cpp b/Code/Framework/AzCore/Platform/Common/Apple/AzCore/Debug/Trace_Apple.cpp index 62fe849c36..4ae25bfaf9 100644 --- a/Code/Framework/AzCore/Platform/Common/Apple/AzCore/Debug/Trace_Apple.cpp +++ b/Code/Framework/AzCore/Platform/Common/Apple/AzCore/Debug/Trace_Apple.cpp @@ -72,6 +72,7 @@ namespace AZ void OutputToDebugger(const char*, const char*) { + // std::cout << title << ": " << message; } } } diff --git a/Code/Framework/AzCore/Platform/Common/Default/AzCore/IO/Streamer/StreamerContext_Default.h b/Code/Framework/AzCore/Platform/Common/Default/AzCore/IO/Streamer/StreamerContext_Default.h index 1478f663fa..3052c3f874 100644 --- a/Code/Framework/AzCore/Platform/Common/Default/AzCore/IO/Streamer/StreamerContext_Default.h +++ b/Code/Framework/AzCore/Platform/Common/Default/AzCore/IO/Streamer/StreamerContext_Default.h @@ -11,6 +11,7 @@ #include #include #include +#include namespace AZ::Platform { diff --git a/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/Debug/Trace_WinAPI.cpp b/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/Debug/Trace_WinAPI.cpp index d4a0f52941..99ea10e4bc 100644 --- a/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/Debug/Trace_WinAPI.cpp +++ b/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/Debug/Trace_WinAPI.cpp @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include @@ -22,7 +24,7 @@ namespace AZ LPTOP_LEVEL_EXCEPTION_FILTER g_previousExceptionHandler = nullptr; #endif - const int g_maxMessageLength = 4096; + constexpr int g_maxMessageLength = 4096; namespace Debug { @@ -58,19 +60,18 @@ namespace AZ TerminateProcess(GetCurrentProcess(), exitCode); } - void OutputToDebugger(const char* window, const char* message) + void OutputToDebugger([[maybe_unused]] const char* window, const char* message) { - AZ_UNUSED(window); -#ifdef _UNICODE - wchar_t messageW[g_maxMessageLength]; - size_t numCharsConverted; - if (mbstowcs_s(&numCharsConverted, messageW, message, g_maxMessageLength - 1) == 0) + AZStd::fixed_wstring tmpW; + if(window) { - OutputDebugStringW(messageW); + AZStd::to_wstring(tmpW, window); + tmpW += L": "; + OutputDebugStringW(tmpW.c_str()); + tmpW.clear(); } -#else // !_UNICODE - OutputDebugString(message); -#endif // !_UNICODE + AZStd::to_wstring(tmpW, message); + OutputDebugStringW(tmpW.c_str()); } } } diff --git a/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/IO/SystemFile_WinAPI.cpp b/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/IO/SystemFile_WinAPI.cpp index 090e29a535..15d779017d 100644 --- a/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/IO/SystemFile_WinAPI.cpp +++ b/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/IO/SystemFile_WinAPI.cpp @@ -28,7 +28,6 @@ namespace //========================================================================= DWORD GetAttributes(const char* fileName) { -#ifdef _UNICODE wchar_t fileNameW[AZ_MAX_PATH_LEN]; size_t numCharsConverted; if (mbstowcs_s(&numCharsConverted, fileNameW, fileName, AZ_ARRAY_SIZE(fileNameW) - 1) == 0) @@ -39,9 +38,6 @@ namespace { return INVALID_FILE_ATTRIBUTES; } -#else //!_UNICODE - return GetFileAttributes(fileName); -#endif // !_UNICODE } //========================================================================= @@ -51,7 +47,6 @@ namespace //========================================================================= BOOL SetAttributes(const char* fileName, DWORD fileAttributes) { -#ifdef _UNICODE wchar_t fileNameW[AZ_MAX_PATH_LEN]; size_t numCharsConverted; if (mbstowcs_s(&numCharsConverted, fileNameW, fileName, AZ_ARRAY_SIZE(fileNameW) - 1) == 0) @@ -62,9 +57,6 @@ namespace { return FALSE; } -#else //!_UNICODE - return SetFileAttributes(fileName, fileAttributes); -#endif // !_UNICODE } //========================================================================= @@ -76,7 +68,6 @@ namespace // * GetLastError() on Windows-like platforms // * errno on Unix platforms //========================================================================= -#if defined(_UNICODE) bool CreateDirRecursive(wchar_t* dirPath) { if (CreateDirectoryW(dirPath, nullptr)) @@ -112,53 +103,6 @@ namespace } return false; } -#else - bool CreateDirRecursive(char* dirPath) - { - if (CreateDirectory(dirPath, nullptr)) - { - return true; // Created without error - } - DWORD error = GetLastError(); - if (error == ERROR_PATH_NOT_FOUND) - { - // try to create our parent hierarchy - for (size_t i = strlen(dirPath); i > 0; --i) - { - if (dirPath[i] == '/' || dirPath[i] == '\\') - { - char delimiter = dirPath[i]; - dirPath[i] = 0; // null-terminate at the previous slash - bool ret = CreateDirRecursive(dirPath); - dirPath[i] = delimiter; // restore slash - if (ret) - { - // now that our parent is created, try to create again - if (CreateDirectory(dirPath, nullptr)) - { - return true; - } - DWORD creationError = GetLastError(); - if (creationError == ERROR_ALREADY_EXISTS) - { - DWORD attributes = GetFileAttributes(dirPath); - return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; - } - return false; - } - return false; - } - } - // if we reach here then there was no parent folder to create, so we failed for other reasons - } - else if (error == ERROR_ALREADY_EXISTS) - { - DWORD attributes = GetFileAttributes(dirPath); - return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; - } - return false; - } -#endif static const SystemFile::FileHandleType PlatformSpecificInvalidHandle = INVALID_HANDLE_VALUE; } @@ -208,7 +152,6 @@ bool SystemFile::PlatformOpen(int mode, int platformFlags) CreatePath(m_fileName.c_str()); } -# ifdef _UNICODE wchar_t fileNameW[AZ_MAX_PATH_LEN]; size_t numCharsConverted; m_handle = INVALID_HANDLE_VALUE; @@ -216,9 +159,6 @@ bool SystemFile::PlatformOpen(int mode, int platformFlags) { m_handle = CreateFileW(fileNameW, dwDesiredAccess, dwShareMode, 0, dwCreationDisposition, dwFlagsAndAttributes, 0); } -# else //!_UNICODE - m_handle = CreateFile(m_fileName.c_str(), dwDesiredAccess, dwShareMode, 0, dwCreationDisposition, dwFlagsAndAttributes, 0); -# endif // !_UNICODE if (m_handle == INVALID_HANDLE_VALUE) { @@ -417,7 +357,6 @@ namespace Platform HANDLE hFile; int lastError; -#ifdef _UNICODE wchar_t filterW[AZ_MAX_PATH_LEN]; size_t numCharsConverted; hFile = INVALID_HANDLE_VALUE; @@ -425,39 +364,28 @@ namespace Platform { hFile = FindFirstFile(filterW, &fd); } -#else // !_UNICODE - hFile = FindFirstFile(filter, &fd); -#endif // !_UNICODE if (hFile != INVALID_HANDLE_VALUE) { const char* fileName; -#ifdef _UNICODE char fileNameA[AZ_MAX_PATH_LEN]; fileName = NULL; if (wcstombs_s(&numCharsConverted, fileNameA, fd.cFileName, AZ_ARRAY_SIZE(fileNameA) - 1) == 0) { fileName = fileNameA; } -#else // !_UNICODE - fileName = fd.cFileName; -#endif // !_UNICODE cb(fileName, (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0); // List all the other files in the directory. - while (FindNextFile(hFile, &fd) != 0) + while (FindNextFileW(hFile, &fd) != 0) { -#ifdef _UNICODE fileName = NULL; if (wcstombs_s(&numCharsConverted, fileNameA, fd.cFileName, AZ_ARRAY_SIZE(fileNameA) - 1) == 0) { fileName = fileNameA; } -#else // !_UNICODE - fileName = fd.cFileName; -#endif // !_UNICODE cb(fileName, (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0); } @@ -483,16 +411,12 @@ namespace Platform { HANDLE handle = nullptr; -#ifdef _UNICODE wchar_t fileNameW[AZ_MAX_PATH_LEN]; size_t numCharsConverted; if (mbstowcs_s(&numCharsConverted, fileNameW, fileName, AZ_ARRAY_SIZE(fileNameW) - 1) == 0) { handle = CreateFileW(fileNameW, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); } -#else // !_UNICODE - handle = CreateFileA(fileName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); -#endif // !_UNICODE if (handle == INVALID_HANDLE_VALUE) { @@ -524,16 +448,12 @@ namespace Platform WIN32_FILE_ATTRIBUTE_DATA data = { 0 }; BOOL result = FALSE; -#ifdef _UNICODE wchar_t fileNameW[AZ_MAX_PATH_LEN]; size_t numCharsConverted; if (mbstowcs_s(&numCharsConverted, fileNameW, fileName, AZ_ARRAY_SIZE(fileNameW) - 1) == 0) { result = GetFileAttributesExW(fileNameW, GetFileExInfoStandard, &data); } -#else // !_UNICODE - result = GetFileAttributesExA(fileName, GetFileExInfoStandard, &data); -#endif // !_UNICODE if (result) { @@ -553,7 +473,6 @@ namespace Platform bool Delete(const char* fileName) { -#ifdef _UNICODE wchar_t fileNameW[AZ_MAX_PATH_LEN]; size_t numCharsConverted; if (mbstowcs_s(&numCharsConverted, fileNameW, fileName, AZ_ARRAY_SIZE(fileNameW) - 1) == 0) @@ -568,20 +487,12 @@ namespace Platform { return false; } -#else // !_UNICODE - if (DeleteFile(fileName) == 0) - { - EBUS_EVENT(FileIOEventBus, OnError, nullptr, fileName, (int)GetLastError()); - return false; - } -#endif // !_UNICODE return true; } bool Rename(const char* sourceFileName, const char* targetFileName, bool overwrite) { -#ifdef _UNICODE wchar_t sourceFileNameW[AZ_MAX_PATH_LEN]; wchar_t targetFileNameW[AZ_MAX_PATH_LEN]; size_t numCharsConverted; @@ -598,13 +509,6 @@ namespace Platform { return false; } -#else // !_UNICODE - if (MoveFileEx(sourceFileName, targetFileName, overwrite ? MOVEFILE_REPLACE_EXISTING : 0) == 0) - { - EBUS_EVENT(FileIOEventBus, OnError, nullptr, sourceFileName, (int)GetLastError()); - return false; - } -#endif // !_UNICODE return true; } @@ -639,7 +543,6 @@ namespace Platform { if (dirName) { -#if defined(_UNICODE) wchar_t dirPath[AZ_MAX_PATH_LEN]; size_t numCharsConverted; if (mbstowcs_s(&numCharsConverted, dirPath, dirName, AZ_ARRAY_SIZE(dirPath) - 1) == 0) @@ -651,18 +554,6 @@ namespace Platform } return success; } -#else - char dirPath[AZ_MAX_PATH_LEN]; - if (azstrcpy(dirPath, AZ_ARRAY_SIZE(dirPath), dirName) == 0) - { - bool success = CreateDirRecursive(dirPath); - if (!success) - { - EBUS_EVENT(FileIOEventBus, OnError, nullptr, dirName, (int)GetLastError()); - } - return success; - } -#endif } return false; } @@ -671,16 +562,12 @@ namespace Platform { if (dirName) { -#if defined(_UNICODE) wchar_t dirNameW[AZ_MAX_PATH_LEN]; size_t numCharsConverted; if (mbstowcs_s(&numCharsConverted, dirNameW, dirName, AZ_ARRAY_SIZE(dirNameW) - 1) == 0) { return RemoveDirectory(dirNameW) != 0; } -#else - return RemoveDirectory(dirName) != 0; -#endif } return false; diff --git a/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/Module/DynamicModuleHandle_WinAPI.cpp b/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/Module/DynamicModuleHandle_WinAPI.cpp index cc04fb6bd5..659650d2e2 100644 --- a/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/Module/DynamicModuleHandle_WinAPI.cpp +++ b/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/Module/DynamicModuleHandle_WinAPI.cpp @@ -98,7 +98,6 @@ namespace AZ bool alreadyLoaded = false; -# ifdef _UNICODE wchar_t fileNameW[MAX_PATH]; size_t numCharsConverted; errno_t wcharResult = mbstowcs_s(&numCharsConverted, fileNameW, m_fileName.c_str(), AZ_ARRAY_SIZE(fileNameW) - 1); @@ -114,10 +113,6 @@ namespace AZ m_handle = NULL; return LoadStatus::LoadFailure; } -# else //!_UNICODE - alreadyLoaded = NULL != GetModuleHandleA(m_fileName.c_str()); - m_handle = LoadLibraryA(m_fileName.c_str()); -# endif // !_UNICODE if (m_handle) { diff --git a/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/Utils/Utils_WinAPI.cpp b/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/Utils/Utils_WinAPI.cpp index 66257735b4..bcba24b768 100644 --- a/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/Utils/Utils_WinAPI.cpp +++ b/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/Utils/Utils_WinAPI.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include @@ -29,7 +30,8 @@ namespace AZ result.m_pathIncludesFilename = true; // Platform specific get exe path: http://stackoverflow.com/a/1024937 // https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulefilenamea - const DWORD pathLen = GetModuleFileNameA(nullptr, exeStorageBuffer, static_cast(exeStorageSize)); + wchar_t pathBufferW[AZ::IO::MaxPathLength] = { 0 }; + const DWORD pathLen = GetModuleFileNameW(nullptr, pathBufferW, static_cast(AZStd::size(pathBufferW))); const DWORD errorCode = GetLastError(); if (pathLen == exeStorageSize && errorCode == ERROR_INSUFFICIENT_BUFFER) { @@ -39,6 +41,18 @@ namespace AZ { result.m_pathStored = ExecutablePathResult::GeneralError; } + else + { + size_t utf8PathSize = AZStd::to_string_length({ pathBufferW, pathLen }); + if (utf8PathSize >= exeStorageSize) + { + result.m_pathStored = ExecutablePathResult::BufferSizeNotLargeEnough; + } + else + { + AZStd::to_string(exeStorageBuffer, exeStorageSize, pathBufferW); + } + } return result; } diff --git a/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/std/parallel/config_WinAPI.h b/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/std/parallel/config_WinAPI.h index fe7620c173..86117c0539 100644 --- a/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/std/parallel/config_WinAPI.h +++ b/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/std/parallel/config_WinAPI.h @@ -71,27 +71,11 @@ extern "C" using LPSECURITY_ATTRIBUTES = SECURITY_ATTRIBUTES*; // Semaphore - AZ_DLL_IMPORT HANDLE _stdcall CreateSemaphoreA(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCSTR lpName); AZ_DLL_IMPORT HANDLE _stdcall CreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCWSTR lpName); AZ_DLL_IMPORT BOOL _stdcall ReleaseSemaphore(HANDLE hSemaphore, LONG lReleaseCount, LPLONG lpPreviousCount); - #ifndef CreateSemaphore - #ifdef UNICODE - #define CreateSemaphore CreateSemaphoreW - #else - #define CreateSemaphore CreateSemaphoreA - #endif - #endif // Event - AZ_DLL_IMPORT HANDLE _stdcall CreateEventA(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCSTR lpName); AZ_DLL_IMPORT HANDLE _stdcall CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCWSTR lpName); - #ifndef CreateEvent - #ifdef UNICODE - #define CreateEvent CreateEventW - #else - #define CreateEvent CreateEventA - #endif - #endif AZ_DLL_IMPORT BOOL _stdcall SetEvent(HANDLE); } diff --git a/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/std/parallel/internal/semaphore_WinAPI.h b/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/std/parallel/internal/semaphore_WinAPI.h index cca90787e6..cd6b216057 100644 --- a/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/std/parallel/internal/semaphore_WinAPI.h +++ b/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/std/parallel/internal/semaphore_WinAPI.h @@ -15,14 +15,14 @@ namespace AZStd { inline semaphore::semaphore(unsigned int initialCount, unsigned int maximumCount) { - m_semaphore = CreateSemaphore(NULL, initialCount, maximumCount, 0); + m_semaphore = CreateSemaphoreW(NULL, initialCount, maximumCount, 0); AZ_Assert(m_semaphore != NULL, "CreateSemaphore error: %d\n", GetLastError()); } inline semaphore::semaphore(const char* name, unsigned int initialCount, unsigned int maximumCount) { (void)name; // name is used only for debug, if we pass it to the semaphore it will become named semaphore - m_semaphore = CreateSemaphore(NULL, initialCount, maximumCount, 0); + m_semaphore = CreateSemaphoreW(NULL, initialCount, maximumCount, 0); AZ_Assert(m_semaphore != NULL, "CreateSemaphore error: %d\n", GetLastError()); } diff --git a/Code/Framework/AzCore/Platform/Linux/AzCore/Debug/Trace_Linux.cpp b/Code/Framework/AzCore/Platform/Linux/AzCore/Debug/Trace_Linux.cpp index 3f9e475153..1ca06fcf7f 100644 --- a/Code/Framework/AzCore/Platform/Linux/AzCore/Debug/Trace_Linux.cpp +++ b/Code/Framework/AzCore/Platform/Linux/AzCore/Debug/Trace_Linux.cpp @@ -7,6 +7,7 @@ */ #include +#include namespace AZ { @@ -14,8 +15,9 @@ namespace AZ { namespace Platform { - void OutputToDebugger(const char*, const char*) + void OutputToDebugger([[maybe_unused]] const char* title, [[maybe_unused]] const char* message) { + // std::cout << title << ": " << message; } } } diff --git a/Code/Framework/AzCore/Platform/Mac/AzCore/IPC/SharedMemory_Mac.cpp b/Code/Framework/AzCore/Platform/Mac/AzCore/IPC/SharedMemory_Mac.cpp index 7f13ec442a..5b2d2af34f 100644 --- a/Code/Framework/AzCore/Platform/Mac/AzCore/IPC/SharedMemory_Mac.cpp +++ b/Code/Framework/AzCore/Platform/Mac/AzCore/IPC/SharedMemory_Mac.cpp @@ -29,20 +29,19 @@ namespace AZ return errno; } - void SharedMemory_Mac::ComposeMutexName(char* dest, size_t length, const char* name) + void ComposeName(char* dest, size_t length, const char* name, const char* suffix) { - azstrncpy(m_name, AZ_ARRAY_SIZE(m_name), name, strlen(name)); - // sem_open doesn't support paths bigger than 31, so call it s_Mtx. // While this is enough for Profiler, maybe the code should be smarter // and trim the name instead - azsnprintf(dest, length, "/tmp/%s_Mtx", name); + azsnprintf(dest, length, "/tmp/%s_%s", name, suffix); } SharedMemory_Common::CreateResult SharedMemory_Mac::Create(const char* name, unsigned int size, bool openIfCreated) { char fullName[256]; - ComposeMutexName(fullName, AZ_ARRAY_SIZE(fullName), name); + azstrncpy(m_name, AZ_ARRAY_SIZE(m_name), name, strlen(name)); + ComposeName(fullName, AZ_ARRAY_SIZE(fullName), name, "Mtx"); m_globalMutex = sem_open(fullName, O_CREAT | O_EXCL, 0600, 1); int error = errno; @@ -59,7 +58,7 @@ namespace AZ } // Create the file mapping. - azsnprintf(fullName, AZ_ARRAY_SIZE(fullName), "%s_Data", name); + ComposeName(fullName, AZ_ARRAY_SIZE(fullName), name, "Data"); m_mapHandle = shm_open(fullName, O_RDWR | O_CREAT | O_EXCL, 0600); error = errno; if (error == EEXIST) @@ -80,7 +79,8 @@ namespace AZ bool SharedMemory_Mac::Open(const char* name) { char fullName[256]; - ComposeMutexName(fullName, AZ_ARRAY_SIZE(fullName), name); + azstrncpy(m_name, AZ_ARRAY_SIZE(m_name), name, strlen(name)); + ComposeName(fullName, AZ_ARRAY_SIZE(fullName), name, "Mtx"); m_globalMutex = sem_open(fullName, 0); AZ_Warning("AZSystem", m_globalMutex != nullptr, "Failed to open OS mutex [%s]\n", m_name); @@ -90,7 +90,7 @@ namespace AZ return false; } - azsnprintf(fullName, AZ_ARRAY_SIZE(fullName), "%s_Data", name); + ComposeName(fullName, AZ_ARRAY_SIZE(fullName), name, "Data"); m_mapHandle = shm_open(fullName, O_RDWR, 0600); if (m_mapHandle == -1) { diff --git a/Code/Framework/AzCore/Platform/Mac/AzCore/IPC/SharedMemory_Mac.h b/Code/Framework/AzCore/Platform/Mac/AzCore/IPC/SharedMemory_Mac.h index 8e172d920f..c0d5d7c2e9 100644 --- a/Code/Framework/AzCore/Platform/Mac/AzCore/IPC/SharedMemory_Mac.h +++ b/Code/Framework/AzCore/Platform/Mac/AzCore/IPC/SharedMemory_Mac.h @@ -29,7 +29,6 @@ namespace AZ static int GetLastError(); - void ComposeMutexName(char* dest, size_t length, const char* name); CreateResult Create(const char* name, unsigned int size, bool openIfCreated); bool Open(const char* name); void Close(); diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp index d2cdac84c7..c4a12730ad 100644 --- a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp +++ b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp @@ -7,6 +7,7 @@ */ #include #include +#include #include #include @@ -90,7 +91,7 @@ namespace AZ { { case CBA_EVENT: evt = (PIMAGEHLP_CBA_EVENT)CallbackData; - _tprintf(_T("%s"), (PTSTR)evt->desc); + printf("%s", evt->desc); break; default: @@ -300,7 +301,7 @@ namespace AZ { return; } - const HMODULE hNtDll = GetModuleHandle(_T("ntdll.dll")); + const HMODULE hNtDll = GetModuleHandleW(L"ntdll.dll"); m_LdrRegisterDllNotification = reinterpret_cast(GetProcAddress(hNtDll, "LdrRegisterDllNotification")); if (m_LdrRegisterDllNotification) @@ -324,7 +325,7 @@ namespace AZ { return; } - const HMODULE hNtDll = GetModuleHandle(_T("ntdll.dll")); + const HMODULE hNtDll = GetModuleHandleW(L"ntdll.dll"); m_LdrUnregisterDllNotification = reinterpret_cast(GetProcAddress(hNtDll, "LdrUnregisterDllNotification")); if (m_LdrUnregisterDllNotification) @@ -609,8 +610,8 @@ namespace AZ { if (GetFileVersionInfoA(szImg, dwHandle, dwSize, vData) != 0) { UINT len; - TCHAR szSubBlock[] = _T("\\"); - if (VerQueryValue(vData, szSubBlock, (LPVOID*) &fInfo, &len) == 0) + TCHAR szSubBlock[] = L"\\"; + if (VerQueryValueW(vData, szSubBlock, (LPVOID*) &fInfo, &len) == 0) { fInfo = NULL; } @@ -711,7 +712,7 @@ namespace AZ { typedef BOOL (__stdcall * tM32N)(HANDLE hSnapshot, LPMODULEENTRY32 lpme); // try both dlls... - const TCHAR* dllname[] = { _T("kernel32.dll"), _T("tlhelp32.dll") }; + const TCHAR* dllname[] = { L"kernel32.dll", L"tlhelp32.dll" }; HINSTANCE hToolhelp = NULL; tCT32S pCT32S = NULL; tM32F pM32F = NULL; @@ -822,7 +823,7 @@ namespace AZ { const SIZE_T TTBUFLEN = 8096; int cnt = 0; - hPsapi = LoadLibrary(_T("psapi.dll")); + hPsapi = LoadLibraryW(L"psapi.dll"); if (hPsapi == NULL) { return FALSE; @@ -956,10 +957,10 @@ cleanup: // In that scenario, we may try to load and older dbghelp.dll which could cause issues // To overcome this, we try to load dbghelp.dll from the Win 10 SDK folder, if that doesn't // work, load the default. - g_dbgHelpDll = LoadLibrary(_T(R"(C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\dbghelp.dll)")); + g_dbgHelpDll = LoadLibraryW(LR"(C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\dbghelp.dll)"); if (g_dbgHelpDll == NULL) { - g_dbgHelpDll = LoadLibrary(_T("dbghelp.dll")); + g_dbgHelpDll = LoadLibrary(L"dbghelp.dll"); } } if (g_dbgHelpDll == NULL) diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/IO/Streamer/StorageDrive_Windows.cpp b/Code/Framework/AzCore/Platform/Windows/AzCore/IO/Streamer/StorageDrive_Windows.cpp index 671cc99aac..2489749b51 100644 --- a/Code/Framework/AzCore/Platform/Windows/AzCore/IO/Streamer/StorageDrive_Windows.cpp +++ b/Code/Framework/AzCore/Platform/Windows/AzCore/IO/Streamer/StorageDrive_Windows.cpp @@ -16,6 +16,7 @@ #include #include #include +#include namespace AZ::IO { @@ -467,8 +468,10 @@ namespace AZ::IO DWORD createFlags = m_constructionOptions.m_enableUnbufferedReads ? (FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING) : FILE_FLAG_OVERLAPPED; DWORD shareMode = (m_constructionOptions.m_enableSharing || data.m_sharedRead) ? FILE_SHARE_READ: 0; - file = ::CreateFile( - data.m_path.GetAbsolutePath(), // file name + AZStd::wstring filenameW; + AZStd::to_wstring(filenameW, data.m_path.GetAbsolutePath()); + file = ::CreateFileW( + filenameW.c_str(), // file name FILE_GENERIC_READ, // desired access shareMode, // share mode nullptr, // security attributes @@ -806,7 +809,9 @@ namespace AZ::IO } WIN32_FILE_ATTRIBUTE_DATA attributes; - if (::GetFileAttributesEx(fileExists.m_path.GetAbsolutePath(), GetFileExInfoStandard, &attributes)) + AZStd::wstring filenameW; + AZStd::to_wstring(filenameW, fileExists.m_path.GetAbsolutePath()); + if (::GetFileAttributesExW(filenameW.c_str(), GetFileExInfoStandard, &attributes)) { if ((attributes.dwFileAttributes != INVALID_FILE_ATTRIBUTES) && ((attributes.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)) @@ -863,7 +868,9 @@ namespace AZ::IO else { WIN32_FILE_ATTRIBUTE_DATA attributes; - if (::GetFileAttributesEx(command.m_path.GetAbsolutePath(), GetFileExInfoStandard, &attributes) && + AZStd::wstring filenameW; + AZStd::to_wstring(filenameW, command.m_path.GetAbsolutePath()); + if (::GetFileAttributesExW(filenameW.c_str(), GetFileExInfoStandard, &attributes) && (attributes.dwFileAttributes != INVALID_FILE_ATTRIBUTES) && ((attributes.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)) { fileSize.LowPart = attributes.nFileSizeLow; diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/IO/Streamer/StreamerConfiguration_Windows.cpp b/Code/Framework/AzCore/Platform/Windows/AzCore/IO/Streamer/StreamerConfiguration_Windows.cpp index 35835c374c..0813d2d057 100644 --- a/Code/Framework/AzCore/Platform/Windows/AzCore/IO/Streamer/StreamerConfiguration_Windows.cpp +++ b/Code/Framework/AzCore/Platform/Windows/AzCore/IO/Streamer/StreamerConfiguration_Windows.cpp @@ -290,7 +290,7 @@ namespace AZ::IO static bool CollectHardwareInfo(HardwareInformation& hardwareInfo, bool addAllDrives, bool reportHardware) { char drives[512]; - if (::GetLogicalDriveStrings(sizeof(drives) - 1, drives)) + if (::GetLogicalDriveStringsA(sizeof(drives) - 1, drives)) { AZStd::unordered_map driveMappings; char* driveIt = drives; @@ -318,7 +318,7 @@ namespace AZ::IO deviceName += driveIt; deviceName.erase(deviceName.length() - 1); // Erase the slash. - HANDLE deviceHandle = ::CreateFile( + HANDLE deviceHandle = ::CreateFileA( deviceName.c_str(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); if (deviceHandle != INVALID_HANDLE_VALUE) { diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/IPC/SharedMemory_Windows.cpp b/Code/Framework/AzCore/Platform/Windows/AzCore/IPC/SharedMemory_Windows.cpp index 0797541652..d9149bdb44 100644 --- a/Code/Framework/AzCore/Platform/Windows/AzCore/IPC/SharedMemory_Windows.cpp +++ b/Code/Framework/AzCore/Platform/Windows/AzCore/IPC/SharedMemory_Windows.cpp @@ -10,6 +10,8 @@ #include #include +#include +#include namespace AZ { @@ -20,16 +22,18 @@ namespace AZ { } - void SharedMemory_Windows::ComposeMutexName(char* dest, size_t length, const char* name) + void ComposeName(AZStd::fixed_wstring<256>& dest, const char* name, const wchar_t* suffix) { - azstrncpy(m_name, AZ_ARRAY_SIZE(m_name), name, strlen(name)); - azsnprintf(dest, length, "%s_Mutex", name); + AZStd::to_wstring(dest, name); + dest += L"_"; + dest += suffix; } SharedMemory_Common::CreateResult SharedMemory_Windows::Create(const char* name, unsigned int size, bool openIfCreated) { - char fullName[256]; - ComposeMutexName(fullName, AZ_ARRAY_SIZE(fullName), name); + azstrncpy(m_name, AZ_ARRAY_SIZE(m_name), name, strlen(name)); + AZStd::fixed_wstring<256> fullName; + ComposeName(fullName, name, L"Mutex"); // Security attributes SECURITY_ATTRIBUTES secAttr; @@ -41,7 +45,7 @@ namespace AZ SetSecurityDescriptorDacl(secAttr.lpSecurityDescriptor, TRUE, 0, FALSE); // Obtain global mutex - m_globalMutex = CreateMutex(&secAttr, FALSE, fullName); + m_globalMutex = CreateMutexW(&secAttr, FALSE, fullName.c_str()); DWORD error = GetLastError(); if (m_globalMutex == NULL || (error == ERROR_ALREADY_EXISTS && openIfCreated == false)) { @@ -50,8 +54,8 @@ namespace AZ } // Create the file mapping. - azsnprintf(fullName, AZ_ARRAY_SIZE(fullName), "%s_Data", name); - m_mapHandle = CreateFileMapping(INVALID_HANDLE_VALUE, &secAttr, PAGE_READWRITE, 0, size, fullName); + ComposeName(fullName, name, L"Data"); + m_mapHandle = CreateFileMappingW(INVALID_HANDLE_VALUE, &secAttr, PAGE_READWRITE, 0, size, fullName.c_str()); error = GetLastError(); if (m_mapHandle == NULL || (error == ERROR_ALREADY_EXISTS && openIfCreated == false)) { @@ -64,10 +68,11 @@ namespace AZ bool SharedMemory_Windows::Open(const char* name) { - char fullName[256]; - ComposeMutexName(fullName, AZ_ARRAY_SIZE(fullName), name); + azstrncpy(m_name, AZ_ARRAY_SIZE(m_name), name, strlen(name)); + AZStd::fixed_wstring<256> fullName; + ComposeName(fullName, name, L"Mutex"); - m_globalMutex = OpenMutex(SYNCHRONIZE, TRUE, fullName); + m_globalMutex = OpenMutex(SYNCHRONIZE, TRUE, fullName.c_str()); AZ_Warning("AZSystem", m_globalMutex != NULL, "Failed to open OS mutex [%s]\n", m_name); if (m_globalMutex == NULL) { @@ -75,8 +80,8 @@ namespace AZ return false; } - azsnprintf(fullName, AZ_ARRAY_SIZE(fullName), "%s_Data", name); - m_mapHandle = OpenFileMapping(FILE_MAP_WRITE, false, fullName); + ComposeName(fullName, name, L"Data"); + m_mapHandle = OpenFileMapping(FILE_MAP_WRITE, false, fullName.c_str()); if (m_mapHandle == NULL) { AZ_TracePrintf("AZSystem", "OpenFileMapping %s failed with error %d\n", m_name, GetLastError()); diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/IPC/SharedMemory_Windows.h b/Code/Framework/AzCore/Platform/Windows/AzCore/IPC/SharedMemory_Windows.h index 7f206f5413..7b10b9163e 100644 --- a/Code/Framework/AzCore/Platform/Windows/AzCore/IPC/SharedMemory_Windows.h +++ b/Code/Framework/AzCore/Platform/Windows/AzCore/IPC/SharedMemory_Windows.h @@ -41,9 +41,6 @@ namespace AZ HANDLE m_mapHandle; HANDLE m_globalMutex; int m_lastLockResult; - - private: - void ComposeMutexName(char* dest, size_t length, const char* name); }; using SharedMemory_Platform = SharedMemory_Windows; diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/NativeUI/NativeUISystemComponent_Windows.cpp b/Code/Framework/AzCore/Platform/Windows/AzCore/NativeUI/NativeUISystemComponent_Windows.cpp index 568f727905..af2a629092 100644 --- a/Code/Framework/AzCore/Platform/Windows/AzCore/NativeUI/NativeUISystemComponent_Windows.cpp +++ b/Code/Framework/AzCore/Platform/Windows/AzCore/NativeUI/NativeUISystemComponent_Windows.cpp @@ -10,6 +10,7 @@ #include #include +#include namespace { @@ -105,11 +106,17 @@ namespace { // Set the text for window title, message, buttons. info = (DlgInfo*)lParam; - SetWindowText(hDlg, info->m_title.c_str()); - SetWindowText(GetDlgItem(hDlg, 0), info->m_message.c_str()); + AZStd::wstring titleW; + AZStd::to_wstring(titleW, info->m_title.c_str()); + SetWindowTextW(hDlg, titleW.c_str()); + AZStd::wstring messageW; + AZStd::to_wstring(messageW, info->m_message.c_str()); + SetWindowTextW(GetDlgItem(hDlg, 0), messageW.c_str()); for (int i = 0; i < info->m_options.size(); i++) { - SetWindowText(GetDlgItem(hDlg, i + 1), info->m_options[i].c_str()); + AZStd::wstring optionW; + AZStd::to_wstring(optionW, info->m_options[i].c_str()); + SetWindowTextW(GetDlgItem(hDlg, i + 1), optionW.c_str()); } } break; diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/PlatformIncl_Windows.h b/Code/Framework/AzCore/Platform/Windows/AzCore/PlatformIncl_Windows.h index 6adef282eb..f58e772155 100644 --- a/Code/Framework/AzCore/Platform/Windows/AzCore/PlatformIncl_Windows.h +++ b/Code/Framework/AzCore/Platform/Windows/AzCore/PlatformIncl_Windows.h @@ -9,6 +9,7 @@ #pragma once #define WIN32_LEAN_AND_MEAN +#define UNICODE //#define NOGDICAPMASKS //- CC_*, LC_*, PC_*, CP_*, TC_*, RC_ //#define NOVIRTUALKEYCODES //- VK_* //#define NOWINMESSAGES //- WM_*, EM_*, LB_*, CB_* diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/Platform_Windows.cpp b/Code/Framework/AzCore/Platform/Windows/AzCore/Platform_Windows.cpp index 27e0bd11e1..cc45b36c41 100644 --- a/Code/Framework/AzCore/Platform/Windows/AzCore/Platform_Windows.cpp +++ b/Code/Framework/AzCore/Platform/Windows/AzCore/Platform_Windows.cpp @@ -31,13 +31,13 @@ namespace AZ // Query the machine guid generated at install time by windows, which is generated from // hardware signatures. This guid is not enough, because images (AWS) may duplicate this, // so include the hostname/username as well - TCHAR machineInfo[MAX_COMPUTERNAME_LENGTH + 1024] = { 0 }; - ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Cryptography", 0, KEY_QUERY_VALUE, &key); + wchar_t machineInfo[MAX_COMPUTERNAME_LENGTH + 1024] = { 0 }; + ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Cryptography", 0, KEY_QUERY_VALUE, &key); if (ret == ERROR_SUCCESS) { DWORD dataType = REG_SZ; DWORD dataSize = sizeof(machineInfo); - ret = RegQueryValueEx(key, "MachineGuid", 0, &dataType, (LPBYTE)machineInfo, &dataSize); + ret = RegQueryValueExW(key, L"MachineGuid", 0, &dataType, (LPBYTE)machineInfo, &dataSize); RegCloseKey(key); } else @@ -45,24 +45,24 @@ namespace AZ AZ_Error("System", false, "Failed to open HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography\\MachineGuid!") } - TCHAR* hostname = machineInfo + _tcslen(machineInfo); + wchar_t* hostname = machineInfo + wcslen(machineInfo); // salt the guid time with ComputerName/UserName DWORD bufCharCount = DWORD(sizeof(machineInfo) - (hostname - machineInfo)); - if (!::GetComputerName(hostname, &bufCharCount)) + if (!::GetComputerNameW(hostname, &bufCharCount)) { AZ_Error("System", false, "GetComputerName filed with code %d", GetLastError()); } - TCHAR* username = hostname + _tcslen(hostname); + wchar_t* username = hostname + wcslen(hostname); bufCharCount = DWORD(sizeof(machineInfo) - (username - machineInfo)); - if( !GetUserName( username, &bufCharCount ) ) + if(!GetUserNameW(username, &bufCharCount)) { AZ_Error("System",false,"GetUserName filed with code %d",GetLastError()); } Sha1 hash; AZ::u32 digest[5] = { 0 }; - hash.ProcessBytes(machineInfo, _tcslen(machineInfo) * sizeof(TCHAR)); + hash.ProcessBytes(machineInfo, wcslen(machineInfo) * sizeof(TCHAR)); hash.GetDigest(digest); s_machineId = digest[0]; if (s_machineId == 0) diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/Utils/Utils_Windows.cpp b/Code/Framework/AzCore/Platform/Windows/AzCore/Utils/Utils_Windows.cpp index 749cf1ba82..fd8353b45f 100644 --- a/Code/Framework/AzCore/Platform/Windows/AzCore/Utils/Utils_Windows.cpp +++ b/Code/Framework/AzCore/Platform/Windows/AzCore/Utils/Utils_Windows.cpp @@ -8,6 +8,7 @@ #include #include +#include #include @@ -15,7 +16,11 @@ namespace AZ::Utils { void NativeErrorMessageBox(const char* title, const char* message) { - ::MessageBox(0, message, title, MB_OK | MB_ICONERROR); + AZStd::wstring wtitle; + AZStd::to_wstring(wtitle, title); + AZStd::wstring wmessage; + AZStd::to_wstring(wmessage, message); + ::MessageBoxW(0, wmessage.c_str(), wtitle.c_str(), MB_OK | MB_ICONERROR); } AZ::IO::FixedMaxPathString GetHomeDirectory() diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/std/parallel/internal/thread_Windows.cpp b/Code/Framework/AzCore/Platform/Windows/AzCore/std/parallel/internal/thread_Windows.cpp index ea92a16838..246181334a 100644 --- a/Code/Framework/AzCore/Platform/Windows/AzCore/std/parallel/internal/thread_Windows.cpp +++ b/Code/Framework/AzCore/Platform/Windows/AzCore/std/parallel/internal/thread_Windows.cpp @@ -8,6 +8,7 @@ #include #include +#include #include @@ -37,17 +38,20 @@ namespace AZStd // SetThreadDescription was added in 1607 (aka RS1). Since we can't guarantee the user is running 1607 or later, we need to ask for the function from the kernel. using SetThreadDescriptionFunc = HRESULT(WINAPI*)(_In_ HANDLE hThread, _In_ PCWSTR lpThreadDescription); - auto setThreadDescription = reinterpret_cast(::GetProcAddress(::GetModuleHandle("Kernel32.dll"), "SetThreadDescription")); - if (setThreadDescription) + HMODULE kernel32Handle = ::GetModuleHandleW(L"Kernel32.dll"); + if (kernel32Handle) { - // Convert the thread name to Unicode - wchar_t threadNameW[MAX_PATH]; - size_t numCharsConverted; - errno_t wcharResult = mbstowcs_s(&numCharsConverted, threadNameW, threadName, AZ_ARRAY_SIZE(threadNameW) - 1); - if (wcharResult == 0) + SetThreadDescriptionFunc setThreadDescription = reinterpret_cast(::GetProcAddress(kernel32Handle, "SetThreadDescription")); + if (setThreadDescription) { - setThreadDescription(hThread, threadNameW); - return true; + // Convert the thread name to Unicode + AZStd::wstring threadNameW; + AZStd::to_wstring(threadNameW, threadName); + if (!threadNameW.empty()) + { + setThreadDescription(hThread, threadNameW.c_str()); + return true; + } } } diff --git a/Code/Framework/AzCore/Tests/AZStd/SmartPtr.cpp b/Code/Framework/AzCore/Tests/AZStd/SmartPtr.cpp index 6fe55b5672..c852fd35bb 100644 --- a/Code/Framework/AzCore/Tests/AZStd/SmartPtr.cpp +++ b/Code/Framework/AzCore/Tests/AZStd/SmartPtr.cpp @@ -2051,10 +2051,11 @@ namespace UnitTest TEST_F(SmartPtr, IntrusivePtr_DynamicCast) { + AZStd::intrusive_ptr basePointer = new RefCountedSubclass; - AZStd::intrusive_ptr correctCast = dynamic_pointer_cast(basePointer); - AZStd::intrusive_ptr wrongCast = dynamic_pointer_cast(basePointer); + AZStd::intrusive_ptr correctCast = azdynamic_cast(basePointer); + AZStd::intrusive_ptr wrongCast = azdynamic_cast(basePointer); EXPECT_TRUE(correctCast.get() == basePointer.get()); EXPECT_TRUE(wrongCast.get() == nullptr); diff --git a/Code/Framework/AzCore/Tests/AZStd/String.cpp b/Code/Framework/AzCore/Tests/AZStd/String.cpp index 0e6ea4727c..9dae4a3d3f 100644 --- a/Code/Framework/AzCore/Tests/AZStd/String.cpp +++ b/Code/Framework/AzCore/Tests/AZStd/String.cpp @@ -628,10 +628,6 @@ namespace UnitTest } } -#if defined(AZ_COMPILER_MSVC) -# pragma warning(push) -# pragma warning( disable: 4428 ) // universal-character-name encountered in source -#endif // AZ_COMPILER_MSVC TEST_F(String, Algorithms) { string str = string::format("%s %d", "BlaBla", 5); @@ -678,6 +674,7 @@ namespace UnitTest string str1; to_string(str1, wstr); AZ_TEST_ASSERT(str1 == "BlaBla 5"); + EXPECT_EQ(8, to_string_length(wstr)); str1 = string::format("%ls", wstr.c_str()); AZ_TEST_ASSERT(str1 == "BlaBla 5"); @@ -690,6 +687,32 @@ namespace UnitTest wstr1 = wstring::format(L"%hs", str.c_str()); AZ_TEST_ASSERT(wstr1 == L"BLABLA 5"); + // wstring to char buffer + char strBuffer[9]; + to_string(strBuffer, 9, wstr1.c_str()); + AZ_TEST_ASSERT(0 == azstricmp(strBuffer, "BLABLA 5")); + EXPECT_EQ(8, to_string_length(wstr1)); + + // wstring to char with unicode + wstring ws1InfinityEscaped = L"Infinity: \u221E"; // escaped + EXPECT_EQ(13, to_string_length(ws1InfinityEscaped)); + + // wchar_t buffer to char buffer + wchar_t wstrBuffer[9] = L"BLABLA 5"; + memset(strBuffer, 0, AZ_ARRAY_SIZE(strBuffer)); + to_string(strBuffer, 9, wstrBuffer); + AZ_TEST_ASSERT(0 == azstricmp(strBuffer, "BLABLA 5")); + + // string to wchar_t buffer + memset(wstrBuffer, 0, AZ_ARRAY_SIZE(wstrBuffer)); + to_wstring(wstrBuffer, 9, str1.c_str()); + AZ_TEST_ASSERT(0 == azwcsicmp(wstrBuffer, L"BlaBla 5")); + + // char buffer to wchar_t buffer + memset(wstrBuffer, L' ', AZ_ARRAY_SIZE(wstrBuffer)); // to check that the null terminator is properly placed + to_wstring(wstrBuffer, 9, strBuffer); + AZ_TEST_ASSERT(0 == azwcsicmp(wstrBuffer, L"BLABLA 5")); + // wchar UTF16/UTF32 to/from Utf8 wstr1 = L"this is a \u20AC \u00A3 test"; // that's a euro and a pound sterling AZStd::to_string(str, wstr1); @@ -1114,11 +1137,6 @@ namespace UnitTest EXPECT_FALSE(other2.Valid()); } - // StringAlgorithmTest-End -#if defined(AZ_COMPILER_MSVC) -# pragma warning(pop) -#endif // AZ_COMPILER_MSVC - TEST_F(String, ConstString) { string_view cstr1; diff --git a/Code/Framework/AzCore/Tests/Debug.cpp b/Code/Framework/AzCore/Tests/Debug.cpp index 3d214ffc68..6181823737 100644 --- a/Code/Framework/AzCore/Tests/Debug.cpp +++ b/Code/Framework/AzCore/Tests/Debug.cpp @@ -56,7 +56,7 @@ namespace UnitTest int isFoundModule = 0; char expectedNameBuffer[AZ_ARRAY_SIZE(SymbolStorage::ModuleInfo::m_modName)]; #if defined(AZCORETEST_DLL_NAME) - azstrncpy(expectedNameBuffer, AZCORETEST_DLL_NAME, AZ_ARRAY_SIZE(expectedNameBuffer)); + azstrncpy(expectedNameBuffer, AZ_ARRAY_SIZE(expectedNameBuffer), AZCORETEST_DLL_NAME, AZ_ARRAY_SIZE(expectedNameBuffer)); #else azstrncpy(expectedNameBuffer, "azcoretests.dll", AZ_ARRAY_SIZE(expectedNameBuffer)); #endif @@ -65,7 +65,7 @@ namespace UnitTest for (u32 i = 0; i < SymbolStorage::GetNumLoadedModules(); ++i) { char nameBuffer[AZ_ARRAY_SIZE(SymbolStorage::ModuleInfo::m_modName)]; - azstrncpy(nameBuffer, SymbolStorage::GetModuleInfo(i)->m_fileName, AZ_ARRAY_SIZE(nameBuffer)); + azstrncpy(nameBuffer, AZ_ARRAY_SIZE(nameBuffer), SymbolStorage::GetModuleInfo(i)->m_fileName, AZ_ARRAY_SIZE(nameBuffer)); AZStd::to_lower(nameBuffer, nameBuffer + AZ_ARRAY_SIZE(nameBuffer)); if (strstr(nameBuffer, expectedNameBuffer)) diff --git a/Code/Framework/AzCore/Tests/IO/Path/PathTests.cpp b/Code/Framework/AzCore/Tests/IO/Path/PathTests.cpp index 79d9f8c302..41e0ac3f09 100644 --- a/Code/Framework/AzCore/Tests/IO/Path/PathTests.cpp +++ b/Code/Framework/AzCore/Tests/IO/Path/PathTests.cpp @@ -418,7 +418,7 @@ namespace UnitTest // Check each operator/= and append overload for success { - AZStd::fixed_string pathString{ "foo" }; + AZ::IO::FixedMaxPathString pathString{ "foo" }; AZ::IO::FixedMaxPath testPath('/'); testPath /= AZ::IO::PathView(pathString); testPath /= pathString; @@ -428,7 +428,7 @@ namespace UnitTest EXPECT_STREQ("foo/foo/foo/foo/f", testPath.c_str()); } { - AZStd::fixed_string pathString{ "foo" }; + AZ::IO::FixedMaxPathString pathString{ "foo" }; AZ::IO::FixedMaxPath testPath('/'); testPath.Append(AZ::IO::PathView(pathString)); testPath.Append(pathString); diff --git a/Code/Framework/AzFramework/AzFramework/Archive/Archive.cpp b/Code/Framework/AzFramework/AzFramework/Archive/Archive.cpp index 8c24250396..a3d2103650 100644 --- a/Code/Framework/AzFramework/AzFramework/Archive/Archive.cpp +++ b/Code/Framework/AzFramework/AzFramework/Archive/Archive.cpp @@ -94,7 +94,7 @@ namespace AZ::IO::ArchiveInternal } return convertedPath; } - return AZStd::make_optional>(sourcePath); + return AZStd::make_optional(sourcePath); } struct CCachedFileRawData @@ -614,7 +614,7 @@ namespace AZ::IO const char* Archive::AdjustFileName(AZStd::string_view src, char* dst, size_t dstSize, uint32_t, bool) { - AZStd::fixed_string srcPath{ src }; + AZ::IO::FixedMaxPathString srcPath{ src }; return AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath(srcPath.c_str(), dst, dstSize) ? dst : nullptr; } @@ -2407,14 +2407,14 @@ namespace AZ::IO ////////////////////////////////////////////////////////////////////////// bool Archive::RemoveFile(AZStd::string_view pName) { - AZStd::fixed_string szFullPath{ pName }; + AZ::IO::FixedMaxPathString szFullPath{ pName }; return AZ::IO::FileIOBase::GetDirectInstance()->Remove(szFullPath.c_str()) == AZ::IO::ResultCode::Success; } ////////////////////////////////////////////////////////////////////////// bool Archive::RemoveDir(AZStd::string_view pName) { - AZStd::fixed_string szFullPath{ pName }; + AZ::IO::FixedMaxPathString szFullPath{ pName }; if (AZ::IO::FileIOBase::GetDirectInstance()->IsDirectory(szFullPath.c_str())) { diff --git a/Code/Framework/AzFramework/AzFramework/Archive/IArchive.h b/Code/Framework/AzFramework/AzFramework/Archive/IArchive.h index 3de63169b2..14a810e2cf 100644 --- a/Code/Framework/AzFramework/AzFramework/Archive/IArchive.h +++ b/Code/Framework/AzFramework/AzFramework/Archive/IArchive.h @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -30,7 +31,7 @@ namespace AZ::IO struct INestedArchive; struct IArchive; - using PathString = AZStd::fixed_string; + using PathString = AZ::IO::FixedMaxPathString; using StackString = AZStd::fixed_string<512>; struct MemoryBlock; diff --git a/Code/Framework/AzFramework/AzFramework/Archive/NestedArchive.cpp b/Code/Framework/AzFramework/AzFramework/Archive/NestedArchive.cpp index 16548c6a39..dc1d4aa864 100644 --- a/Code/Framework/AzFramework/AzFramework/Archive/NestedArchive.cpp +++ b/Code/Framework/AzFramework/AzFramework/Archive/NestedArchive.cpp @@ -41,7 +41,7 @@ namespace AZ::IO return ZipDir::ZD_ERROR_INVALID_CALL; } - AZStd::fixed_string fullPath = AdjustPath(szRelativePath); + AZ::IO::FixedMaxPathString fullPath = AdjustPath(szRelativePath); if (fullPath.empty()) { return ZipDir::ZD_ERROR_INVALID_PATH; @@ -63,7 +63,7 @@ namespace AZ::IO return ZipDir::ZD_ERROR_INVALID_CALL; } - AZStd::fixed_string fullPath = AdjustPath(szRelativePath); + AZ::IO::FixedMaxPathString fullPath = AdjustPath(szRelativePath); if (fullPath.empty()) { return ZipDir::ZD_ERROR_INVALID_PATH; @@ -81,7 +81,7 @@ namespace AZ::IO return ZipDir::ZD_ERROR_INVALID_CALL; } - AZStd::fixed_string fullPath = AdjustPath(szRelativePath); + AZ::IO::FixedMaxPathString fullPath = AdjustPath(szRelativePath); if (fullPath.empty()) { return ZipDir::ZD_ERROR_INVALID_PATH; @@ -105,7 +105,7 @@ namespace AZ::IO return ZipDir::ZD_ERROR_INVALID_CALL; } - AZStd::fixed_string fullPath = AdjustPath(szRelativePath); + AZ::IO::FixedMaxPathString fullPath = AdjustPath(szRelativePath); if (fullPath.empty()) { return ZipDir::ZD_ERROR_INVALID_PATH; @@ -122,7 +122,7 @@ namespace AZ::IO return ZipDir::ZD_ERROR_INVALID_CALL; } - AZStd::fixed_string fullPath = AdjustPath(szRelativePath); + AZ::IO::FixedMaxPathString fullPath = AdjustPath(szRelativePath); if (fullPath.empty()) { return ZipDir::ZD_ERROR_INVALID_PATH; @@ -141,7 +141,7 @@ namespace AZ::IO return ZipDir::ZD_ERROR_INVALID_CALL; } - AZStd::fixed_string fullPath = AdjustPath(szRelativePath); + AZ::IO::FixedMaxPathString fullPath = AdjustPath(szRelativePath); if (fullPath.empty()) { return ZipDir::ZD_ERROR_INVALID_PATH; @@ -152,7 +152,7 @@ namespace AZ::IO // finds the file; you don't have to close the returned handle auto NestedArchive::FindFile(AZStd::string_view szRelativePath) -> Handle { - AZStd::fixed_string fullPath = AdjustPath(szRelativePath); + AZ::IO::FixedMaxPathString fullPath = AdjustPath(szRelativePath); if (fullPath.empty()) { return nullptr; @@ -249,7 +249,7 @@ namespace AZ::IO if (m_nFlags & FLAGS_RELATIVE_PATHS_ONLY) { - return AZStd::fixed_string{ szRelativePath }; + return AZ::IO::FixedMaxPathString{ szRelativePath }; } if ((szRelativePath.size() > 1 && szRelativePath[1] == ':') || (m_nFlags & FLAGS_ABSOLUTE_PATHS)) diff --git a/Code/Framework/AzFramework/AzFramework/Archive/ZipDirStructures.cpp b/Code/Framework/AzFramework/AzFramework/Archive/ZipDirStructures.cpp index 034d2f4029..445bba63f4 100644 --- a/Code/Framework/AzFramework/AzFramework/Archive/ZipDirStructures.cpp +++ b/Code/Framework/AzFramework/AzFramework/Archive/ZipDirStructures.cpp @@ -440,7 +440,7 @@ namespace AZ::IO::ZipDir azstrcpy(volume, AZ_ARRAY_SIZE(volume), filename); } - AZStd::fixed_string drive{ AZ::IO::PathView(volume).RootName().Native() }; + AZ::IO::FixedMaxPathString drive{ AZ::IO::PathView(volume).RootName().Native() }; if (drive.empty()) { return false; diff --git a/Code/Framework/AzFramework/AzFramework/Asset/CfgFileAsset.h b/Code/Framework/AzFramework/AzFramework/Asset/CfgFileAsset.h index aacf4303a7..2aadf9ae6c 100644 --- a/Code/Framework/AzFramework/AzFramework/Asset/CfgFileAsset.h +++ b/Code/Framework/AzFramework/AzFramework/Asset/CfgFileAsset.h @@ -7,7 +7,7 @@ */ #pragma once -#include +#include #include namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Network/AssetProcessorConnection.cpp b/Code/Framework/AzFramework/AzFramework/Network/AssetProcessorConnection.cpp index a65a3079a0..ebea29c2d9 100644 --- a/Code/Framework/AzFramework/AzFramework/Network/AssetProcessorConnection.cpp +++ b/Code/Framework/AzFramework/AzFramework/Network/AssetProcessorConnection.cpp @@ -136,7 +136,7 @@ namespace AzFramework AZStd::array buffer; azsnprintf(buffer.data(), buffer.size(), "(%p/%#" PRIxPTR "): %s\n", this, numericThreadId, msg.data()); - Platform::DebugOutput(buffer.data()); + AZ::Debug::Platform::OutputToDebugger("AssetProcessorConnection", buffer.data()); #else // ASSETPROCESORCONNECTION_VERBOSE_LOGGING is not defined (void)format; #endif diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.h b/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.h index f83a042577..5340a1a344 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.h @@ -8,7 +8,7 @@ #pragma once -#include +#include #include #include #include diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionLayers.h b/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionLayers.h index 25675e311a..6b5a4cd2a9 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionLayers.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionLayers.h @@ -8,7 +8,7 @@ #pragma once -#include +#include #include #include #include diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/CollisionConfiguration.h b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/CollisionConfiguration.h index e784c2339b..b6308e19e0 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/CollisionConfiguration.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/CollisionConfiguration.h @@ -8,7 +8,7 @@ #pragma once -#include +#include #include #include #include diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SceneConfiguration.h b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SceneConfiguration.h index 246059bde9..a6590d3702 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SceneConfiguration.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SceneConfiguration.h @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include diff --git a/Code/Framework/AzFramework/AzFramework/Slice/SliceInstantiationTicket.h b/Code/Framework/AzFramework/AzFramework/Slice/SliceInstantiationTicket.h index 092fcd7822..3097c18d60 100644 --- a/Code/Framework/AzFramework/AzFramework/Slice/SliceInstantiationTicket.h +++ b/Code/Framework/AzFramework/AzFramework/Slice/SliceInstantiationTicket.h @@ -10,7 +10,7 @@ #include #include -#include +#include #include #include diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/CameraState.h b/Code/Framework/AzFramework/AzFramework/Viewport/CameraState.h index 0887754bdf..e174771c3b 100644 --- a/Code/Framework/AzFramework/AzFramework/Viewport/CameraState.h +++ b/Code/Framework/AzFramework/AzFramework/Viewport/CameraState.h @@ -11,6 +11,11 @@ #include #include +namespace AZ +{ + class SerializeContext; +} // namespace AZ + namespace AzFramework { //! Represents the camera state populated by the viewport camera. diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/ScreenGeometry.h b/Code/Framework/AzFramework/AzFramework/Viewport/ScreenGeometry.h index 1063709343..c0fa1ad631 100644 --- a/Code/Framework/AzFramework/AzFramework/Viewport/ScreenGeometry.h +++ b/Code/Framework/AzFramework/AzFramework/Viewport/ScreenGeometry.h @@ -11,7 +11,8 @@ #include #include #include -#include +#include +#include namespace AZ { diff --git a/Code/Framework/AzFramework/Platform/Android/platform_android_files.cmake b/Code/Framework/AzFramework/Platform/Android/platform_android_files.cmake index 35b5a10151..c220bc1154 100644 --- a/Code/Framework/AzFramework/Platform/Android/platform_android_files.cmake +++ b/Code/Framework/AzFramework/Platform/Android/platform_android_files.cmake @@ -14,7 +14,6 @@ set(FILES AzFramework/Application/Application_Android.cpp ../Common/Unimplemented/AzFramework/Asset/AssetSystemComponentHelper_Unimplemented.cpp AzFramework/IO/LocalFileIO_Android.cpp - ../Common/Default/AzFramework/Network/AssetProcessorConnection_Default.cpp ../Common/Unimplemented/AzFramework/StreamingInstall/StreamingInstall_Unimplemented.cpp ../Common/Default/AzFramework/TargetManagement/TargetManagementComponent_Default.cpp AzFramework/Windowing/NativeWindow_Android.cpp diff --git a/Code/Framework/AzFramework/Platform/Common/Default/AzFramework/Network/AssetProcessorConnection_Default.cpp b/Code/Framework/AzFramework/Platform/Common/Default/AzFramework/Network/AssetProcessorConnection_Default.cpp deleted file mode 100644 index 5bc020a1d6..0000000000 --- a/Code/Framework/AzFramework/Platform/Common/Default/AzFramework/Network/AssetProcessorConnection_Default.cpp +++ /dev/null @@ -1,24 +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 - -namespace AzFramework -{ - namespace AssetSystem - { - namespace Platform - { - void DebugOutput(const char* message) - { - fputs("AssetProcessorConnection:", stdout); - fputs(message, stdout); - } - } - } -} diff --git a/Code/Framework/AzFramework/Platform/Common/WinAPI/AzFramework/IO/LocalFileIO_WinAPI.cpp b/Code/Framework/AzFramework/Platform/Common/WinAPI/AzFramework/IO/LocalFileIO_WinAPI.cpp index 4c7d84b511..61957fced0 100644 --- a/Code/Framework/AzFramework/Platform/Common/WinAPI/AzFramework/IO/LocalFileIO_WinAPI.cpp +++ b/Code/Framework/AzFramework/Platform/Common/WinAPI/AzFramework/IO/LocalFileIO_WinAPI.cpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace AZ { @@ -19,7 +20,9 @@ namespace AZ char resolvedPath[AZ_MAX_PATH_LEN]; ResolvePath(filePath, resolvedPath, AZ_MAX_PATH_LEN); - DWORD fileAttributes = GetFileAttributesA(resolvedPath); + wchar_t resolvedPathW[AZ_MAX_PATH_LEN]; + AZStd::to_wstring(resolvedPathW, AZ_MAX_PATH_LEN, resolvedPath); + DWORD fileAttributes = GetFileAttributesW(resolvedPathW); if (fileAttributes == INVALID_FILE_ATTRIBUTES) { return false; @@ -33,7 +36,7 @@ namespace AZ char resolvedPath[AZ_MAX_PATH_LEN]; ResolvePath(filePath, resolvedPath, AZ_MAX_PATH_LEN); - AZ::OSString searchPattern; + AZStd::string searchPattern; if ((resolvedPath[0] == 0) || (resolvedPath[1] == 0)) { return ResultCode::Error; // not a valid path. @@ -54,7 +57,9 @@ namespace AZ searchPattern += "\\*.*"; // use our own filtering function! WIN32_FIND_DATA findData; - HANDLE hFind = FindFirstFile(searchPattern.c_str(), &findData); + AZStd::wstring searchPatternW; + AZStd::to_wstring(searchPatternW, searchPattern.c_str()); + HANDLE hFind = FindFirstFileW(searchPatternW.c_str(), &findData); if (hFind != INVALID_HANDLE_VALUE) { @@ -63,15 +68,17 @@ namespace AZ char tempBuffer[AZ_MAX_PATH_LEN]; do { - AZStd::string_view filenameView = findData.cFileName; + AZStd::string fileName; + AZStd::to_string(fileName, findData.cFileName); + AZStd::string_view filenameView = fileName; // Skip over the current directory and parent directory paths to prevent infinite recursion - if (filenameView == "." || filenameView == ".." || !NameMatchesFilter(findData.cFileName, filter)) + if (filenameView == "." || filenameView == ".." || !NameMatchesFilter(fileName.c_str(), filter)) { continue; } - AZ::OSString foundFilePath = CheckForTrailingSlash(resolvedPath); - foundFilePath += findData.cFileName; + AZStd::string foundFilePath = CheckForTrailingSlash(resolvedPath); + foundFilePath += fileName; AZStd::replace(foundFilePath.begin(), foundFilePath.end(), '\\', '/'); // if aliased, de-alias! @@ -169,7 +176,7 @@ namespace AZ bool LocalFileIO::IsAbsolutePath(const char* path) const { - char drive[16]; + char drive[16] = { 0 }; _splitpath_s(path, drive, 16, nullptr, 0, nullptr, 0, nullptr, 0); return strlen(drive) > 0; } diff --git a/Code/Framework/AzFramework/Platform/Common/WinAPI/AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard_WinAPI.h b/Code/Framework/AzFramework/Platform/Common/WinAPI/AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard_WinAPI.h index 591f8421b9..4c90b83bc4 100644 --- a/Code/Framework/AzFramework/Platform/Common/WinAPI/AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard_WinAPI.h +++ b/Code/Framework/AzFramework/Platform/Common/WinAPI/AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard_WinAPI.h @@ -59,7 +59,7 @@ namespace AzFramework { // Convert the valid UTF-16 surrogate pair to a UTF-8 code point const wchar_t codePointUTF16[2] = { m_leadSurrogate, codeUnitUTF16 }; - AZStd::to_string(codePointUTF8, codePointUTF16, 2); + AZStd::to_string(codePointUTF8, { codePointUTF16, 2 }); m_leadSurrogate = 0; } else @@ -72,7 +72,7 @@ namespace AzFramework { // Convert the standalone UTF-16 code point to a UTF-8 code point const wchar_t codePointUTF16[1] = { codeUnitUTF16 }; - AZStd::to_string(codePointUTF8, codePointUTF16, 1); + AZStd::to_string(codePointUTF8, { codePointUTF16, 1 }); m_leadSurrogate = 0; } diff --git a/Code/Framework/AzFramework/Platform/Common/WinAPI/AzFramework/Network/AssetProcessorConnection_WinAPI.cpp b/Code/Framework/AzFramework/Platform/Common/WinAPI/AzFramework/Network/AssetProcessorConnection_WinAPI.cpp deleted file mode 100644 index a02e697df6..0000000000 --- a/Code/Framework/AzFramework/Platform/Common/WinAPI/AzFramework/Network/AssetProcessorConnection_WinAPI.cpp +++ /dev/null @@ -1,25 +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 -#include - -namespace AzFramework -{ - namespace AssetSystem - { - namespace Platform - { - void DebugOutput(const char* message) - { - OutputDebugString("AssetProcessorConnection:"); - OutputDebugString(message); - } - } - } -} diff --git a/Code/Framework/AzFramework/Platform/Linux/platform_linux_files.cmake b/Code/Framework/AzFramework/Platform/Linux/platform_linux_files.cmake index 60b16938a1..21201d954d 100644 --- a/Code/Framework/AzFramework/Platform/Linux/platform_linux_files.cmake +++ b/Code/Framework/AzFramework/Platform/Linux/platform_linux_files.cmake @@ -17,7 +17,6 @@ set(FILES AzFramework/Process/ProcessCommon.h AzFramework/Process/ProcessCommunicator_Linux.cpp ../Common/UnixLike/AzFramework/IO/LocalFileIO_UnixLike.cpp - ../Common/Default/AzFramework/Network/AssetProcessorConnection_Default.cpp ../Common/Unimplemented/AzFramework/StreamingInstall/StreamingInstall_Unimplemented.cpp ../Common/Default/AzFramework/TargetManagement/TargetManagementComponent_Default.cpp AzFramework/Windowing/NativeWindow_Linux.cpp diff --git a/Code/Framework/AzFramework/Platform/Mac/platform_mac_files.cmake b/Code/Framework/AzFramework/Platform/Mac/platform_mac_files.cmake index c428160892..78f11a65da 100644 --- a/Code/Framework/AzFramework/Platform/Mac/platform_mac_files.cmake +++ b/Code/Framework/AzFramework/Platform/Mac/platform_mac_files.cmake @@ -17,7 +17,6 @@ set(FILES AzFramework/Process/ProcessCommon.h AzFramework/Process/ProcessCommunicator_Mac.cpp ../Common/UnixLike/AzFramework/IO/LocalFileIO_UnixLike.cpp - ../Common/Default/AzFramework/Network/AssetProcessorConnection_Default.cpp ../Common/Unimplemented/AzFramework/StreamingInstall/StreamingInstall_Unimplemented.cpp AzFramework/TargetManagement/TargetManagementComponent_Mac.cpp AzFramework/Windowing/NativeWindow_Mac.mm diff --git a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Asset/AssetSystemComponentHelper_Windows.cpp b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Asset/AssetSystemComponentHelper_Windows.cpp index 4b685b25a3..a3782ae081 100644 --- a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Asset/AssetSystemComponentHelper_Windows.cpp +++ b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Asset/AssetSystemComponentHelper_Windows.cpp @@ -48,10 +48,10 @@ namespace AzFramework::AssetSystem::Platform // Get the first module, because that will be the executable if (EnumProcessModules(processHandle, &moduleHandle, sizeof(moduleHandle), &bytesNeededForAllProcessModules)) { - char processName[4096] = TEXT(""); - if (GetModuleBaseNameA(processHandle, moduleHandle, processName, AZ_ARRAY_SIZE(processName)) > 0) + wchar_t processName[4096] = L""; + if (GetModuleBaseName(processHandle, moduleHandle, processName, AZ_ARRAY_SIZE(processName)) > 0) { - if (azstricmp(processName, "AssetProcessor") == 0) + if (azwcsicmp(processName, L"AssetProcessor") == 0) { AllowSetForegroundWindow(processId); } @@ -126,7 +126,11 @@ namespace AzFramework::AssetSystem::Platform si.wShowWindow = SW_MINIMIZE; PROCESS_INFORMATION pi; - bool createResult = ::CreateProcessA(nullptr, fullLaunchCommand.data(), nullptr, nullptr, FALSE, 0, nullptr, AZ::IO::FixedMaxPathString{ executableDirectory }.c_str(), &si, &pi) != 0; + AZStd::wstring fullLaunchCommandW; + AZStd::to_wstring(fullLaunchCommandW, fullLaunchCommand.c_str()); + AZStd::wstring execututableDirectoryW; + AZStd::to_wstring(execututableDirectoryW, executableDirectory.data()); + bool createResult = ::CreateProcessW(nullptr, fullLaunchCommandW.data(), nullptr, nullptr, FALSE, 0, nullptr, execututableDirectoryW.c_str(), &si, &pi) != 0; if (ap_tether_lifetime && apJob && createResult) { diff --git a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard_Windows.cpp b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard_Windows.cpp index 78364fbd0d..f3112ab89c 100644 --- a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard_Windows.cpp +++ b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard_Windows.cpp @@ -253,7 +253,7 @@ namespace AzFramework if (stringLength != 0) { // Convert UTF-16 to UTF-8 - AZStd::to_string(o_keyOrButtonText, buffer, stringLength); + AZStd::to_string(o_keyOrButtonText, { buffer, aznumeric_cast(stringLength) }); } } diff --git a/Code/Framework/AzFramework/Platform/Windows/AzFramework/TargetManagement/TargetManagementComponent_Windows.cpp b/Code/Framework/AzFramework/Platform/Windows/AzFramework/TargetManagement/TargetManagementComponent_Windows.cpp index fbfb3778cb..e168968278 100644 --- a/Code/Framework/AzFramework/Platform/Windows/AzFramework/TargetManagement/TargetManagementComponent_Windows.cpp +++ b/Code/Framework/AzFramework/Platform/Windows/AzFramework/TargetManagement/TargetManagementComponent_Windows.cpp @@ -10,6 +10,7 @@ #include #include #include +#include namespace AzFramework { @@ -35,12 +36,12 @@ namespace AzFramework AZStd::string GetNeighborhoodName() { AZStd::string neighborhoodName; - - char localhost[MAX_COMPUTERNAME_LENGTH + 1]; + + wchar_t localhost[MAX_COMPUTERNAME_LENGTH + 1]; DWORD len = AZ_ARRAY_SIZE(localhost); - if (GetComputerName(localhost, &len)) + if (GetComputerNameW(localhost, &len)) { - neighborhoodName = localhost; + AZStd::to_string(neighborhoodName, localhost); } return neighborhoodName; diff --git a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Windowing/NativeWindow_Windows.cpp b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Windowing/NativeWindow_Windows.cpp index 0047929120..22a293891c 100644 --- a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Windowing/NativeWindow_Windows.cpp +++ b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Windowing/NativeWindow_Windows.cpp @@ -11,6 +11,7 @@ #include #include +#include namespace AzFramework { @@ -41,7 +42,7 @@ namespace AzFramework static DWORD ConvertToWin32WindowStyleMask(const WindowStyleMasks& styleMasks); static LRESULT CALLBACK WindowCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); - static const char* s_defaultClassName; + static const wchar_t* s_defaultClassName; void WindowSizeChanged(const uint32_t width, const uint32_t height); @@ -57,7 +58,7 @@ namespace AzFramework GetDpiForWindowType* m_getDpiFunction = nullptr; }; - const char* NativeWindowImpl_Win32::s_defaultClassName = "O3DEWin32Class"; + const wchar_t* NativeWindowImpl_Win32::s_defaultClassName = L"O3DEWin32Class"; NativeWindow::Implementation* NativeWindow::Implementation::Create() { @@ -88,7 +89,7 @@ namespace AzFramework // register window class if it does not exist WNDCLASSEX windowClass; - if (GetClassInfoEx(hInstance, s_defaultClassName, &windowClass) == false) + if (GetClassInfoExW(hInstance, s_defaultClassName, &windowClass) == false) { windowClass.cbSize = sizeof(WNDCLASSEX); windowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; @@ -127,8 +128,10 @@ namespace AzFramework m_height = geometry.m_height; // create main window - m_win32Handle = CreateWindow( - s_defaultClassName, title.c_str(), + AZStd::wstring titleW; + AZStd::to_wstring(titleW, title); + m_win32Handle = CreateWindowW( + s_defaultClassName, titleW.c_str(), windowStyle, geometry.m_posX, geometry.m_posY, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, NULL, NULL, hInstance, NULL); @@ -175,7 +178,9 @@ namespace AzFramework void NativeWindowImpl_Win32::SetWindowTitle(const AZStd::string& title) { - SetWindowText(m_win32Handle, title.c_str()); + AZStd::wstring titleW; + AZStd::to_wstring(titleW, title); + SetWindowTextW(m_win32Handle, titleW.c_str()); } DWORD NativeWindowImpl_Win32::ConvertToWin32WindowStyleMask(const WindowStyleMasks& styleMasks) diff --git a/Code/Framework/AzFramework/Platform/Windows/platform_windows_files.cmake b/Code/Framework/AzFramework/Platform/Windows/platform_windows_files.cmake index af43234bd0..b8f5b5f841 100644 --- a/Code/Framework/AzFramework/Platform/Windows/platform_windows_files.cmake +++ b/Code/Framework/AzFramework/Platform/Windows/platform_windows_files.cmake @@ -18,7 +18,6 @@ set(FILES AzFramework/Process/ProcessCommunicator_Win.cpp ../Common/WinAPI/AzFramework/IO/LocalFileIO_WinAPI.cpp AzFramework/IO/LocalFileIO_Windows.cpp - ../Common/WinAPI/AzFramework/Network/AssetProcessorConnection_WinAPI.cpp ../Common/Unimplemented/AzFramework/StreamingInstall/StreamingInstall_Unimplemented.cpp AzFramework/TargetManagement/TargetManagementComponent_Windows.cpp AzFramework/Windowing/NativeWindow_Windows.cpp diff --git a/Code/Framework/AzFramework/Platform/iOS/platform_ios_files.cmake b/Code/Framework/AzFramework/Platform/iOS/platform_ios_files.cmake index f47eb136be..7745f43ec9 100644 --- a/Code/Framework/AzFramework/Platform/iOS/platform_ios_files.cmake +++ b/Code/Framework/AzFramework/Platform/iOS/platform_ios_files.cmake @@ -14,7 +14,6 @@ set(FILES AzFramework/Application/Application_iOS.mm ../Common/Unimplemented/AzFramework/Asset/AssetSystemComponentHelper_Unimplemented.cpp ../Common/UnixLike/AzFramework/IO/LocalFileIO_UnixLike.cpp - ../Common/Default/AzFramework/Network/AssetProcessorConnection_Default.cpp ../Common/Unimplemented/AzFramework/StreamingInstall/StreamingInstall_Unimplemented.cpp ../Common/Default/AzFramework/TargetManagement/TargetManagementComponent_Default.cpp AzFramework/Windowing/NativeWindow_ios.mm diff --git a/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacket.h b/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacket.h index 021ca54cca..9962382f9f 100644 --- a/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacket.h +++ b/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacket.h @@ -8,7 +8,7 @@ #pragma once -#include +#include #include #include diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Application/AzQtApplication.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Application/AzQtApplication.cpp index 594a339448..9dece6e26a 100644 --- a/Code/Framework/AzQtComponents/AzQtComponents/Application/AzQtApplication.cpp +++ b/Code/Framework/AzQtComponents/AzQtComponents/Application/AzQtApplication.cpp @@ -22,8 +22,6 @@ namespace AzQtComponents QApplication::setApplicationName("O3DE Tools Application"); AzQtComponents::PrepareQtPaths(); - - QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedStates)); } void AzQtApplication::InitializeDpiScaling() diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Gallery/main.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Gallery/main.cpp index 51ca2b349f..629a8834eb 100644 --- a/Code/Framework/AzQtComponents/AzQtComponents/Gallery/main.cpp +++ b/Code/Framework/AzQtComponents/AzQtComponents/Gallery/main.cpp @@ -40,13 +40,8 @@ const QString g_ui_1_0_SettingKey = QStringLiteral("useUI_1_0"); static void LogToDebug([[maybe_unused]] QtMsgType Type, [[maybe_unused]] const QMessageLogContext& Context, const QString& message) { -#ifdef Q_OS_WIN - OutputDebugStringW(L"Qt: "); - OutputDebugStringW(reinterpret_cast(message.utf16())); - OutputDebugStringW(L"\n"); -#else - std::wcerr << L"Qt: " << message.toStdWString() << std::endl; -#endif + AZ::Debug::Platform::OutputToDebugger("Qt", message.toStdString().c_str()); + AZ::Debug::Platform::OutputToDebugger(nullptr, "\n"); } /* @@ -134,8 +129,6 @@ int main(int argc, char **argv) QApplication::setOrganizationDomain("o3de.org"); QApplication::setApplicationName("O3DEWidgetGallery"); - QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedStates)); - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Tests/FloatToStringConversionTests.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Tests/FloatToStringConversionTests.cpp index da4d8de4cd..39593a1c58 100644 --- a/Code/Framework/AzQtComponents/AzQtComponents/Tests/FloatToStringConversionTests.cpp +++ b/Code/Framework/AzQtComponents/AzQtComponents/Tests/FloatToStringConversionTests.cpp @@ -13,54 +13,94 @@ TEST(AzQtComponents, FloatToString_Truncate2Decimals) { - QLocale testLocal(QLocale::English, QLocale::UnitedStates); + QLocale testLocale(QLocale::English, QLocale::UnitedStates); const bool showThousandsSeparator = false; const int numDecimalPlaces = 2; - EXPECT_EQ(AzQtComponents::toString(0.1234, numDecimalPlaces, testLocal, showThousandsSeparator), "0.12"); + EXPECT_EQ(AzQtComponents::toString(0.1234, numDecimalPlaces, testLocale, showThousandsSeparator), "0.12"); } TEST(AzQtComponents, FloatToString_AllZerosButOne) { - QLocale testLocal(QLocale::English, QLocale::UnitedStates); + QLocale testLocale(QLocale::English, QLocale::UnitedStates); const bool showThousandsSeparator = false; int numDecimalPlaces = 2; - EXPECT_EQ(AzQtComponents::toString(1.0000, numDecimalPlaces, testLocal, showThousandsSeparator), "1.0"); + EXPECT_EQ(AzQtComponents::toString(1.0000, numDecimalPlaces, testLocale, showThousandsSeparator), "1.0"); } TEST(AzQtComponents, FloatToString_TruncateAllZerosButOne) { - QLocale testLocal(QLocale::English, QLocale::UnitedStates); + QLocale testLocale(QLocale::English, QLocale::UnitedStates); const bool showThousandsSeparator = false; int numDecimalPlaces = 2; - EXPECT_EQ(AzQtComponents::toString(1.0001, numDecimalPlaces, testLocal, showThousandsSeparator), "1.0"); + EXPECT_EQ(AzQtComponents::toString(1.0001, numDecimalPlaces, testLocale, showThousandsSeparator), "1.0"); } TEST(AzQtComponents, FloatToString_TruncateNotRound) { - QLocale testLocal(QLocale::English, QLocale::UnitedStates); + QLocale testLocale(QLocale::English, QLocale::UnitedStates); const bool showThousandsSeparator = false; int numDecimalPlaces = 3; - EXPECT_EQ(AzQtComponents::toString(0.1236, numDecimalPlaces, testLocal, showThousandsSeparator), "0.123"); + EXPECT_EQ(AzQtComponents::toString(0.1236, numDecimalPlaces, testLocale, showThousandsSeparator), "0.123"); } TEST(AzQtComponents, FloatToString_TruncateShowThousandsSeparatorTruncateNoRound) { - QLocale testLocal(QLocale::English, QLocale::UnitedStates); + QLocale testLocale(QLocale::English, QLocale::UnitedStates); const bool showThousandsSeparator = true; int numDecimalPlaces = 3; - EXPECT_EQ(AzQtComponents::toString(1000.1236, numDecimalPlaces, testLocal, showThousandsSeparator), "1,000.123"); + EXPECT_EQ(AzQtComponents::toString(1000.1236, numDecimalPlaces, testLocale, showThousandsSeparator), "1,000.123"); } TEST(AzQtComponents, FloatToString_TruncateShowThousandsSeparatorOnlyOneDecimal) { - QLocale testLocal(QLocale::English, QLocale::UnitedStates); + QLocale testLocale(QLocale::English, QLocale::UnitedStates); const bool showThousandsSeparator = true; int numDecimalPlaces = 2; - EXPECT_EQ(AzQtComponents::toString(1000.000, numDecimalPlaces, testLocal, showThousandsSeparator), "1,000.0"); + EXPECT_EQ(AzQtComponents::toString(1000.000, numDecimalPlaces, testLocale, showThousandsSeparator), "1,000.0"); +} + +TEST(AzQtComponents, FloatToString_Truncate2DecimalsWithLocale) +{ + QLocale testLocale{ QLocale() }; + + const bool showThousandsSeparator = false; + const int numDecimalPlaces = 2; + QString testString = "0" + QString(testLocale.decimalPoint()) + "12"; + EXPECT_EQ(testString, AzQtComponents::toString(0.1234, numDecimalPlaces, testLocale, showThousandsSeparator)); +} + +TEST(AzQtComponents, FloatToString_AllZerosButOneWithLocale) +{ + QLocale testLocale{ QLocale() }; + + const bool showThousandsSeparator = false; + const int numDecimalPlaces = 2; + QString testString = "1" + QString(testLocale.decimalPoint()) + "0"; + EXPECT_EQ(testString, AzQtComponents::toString(1.0000, numDecimalPlaces, testLocale, showThousandsSeparator)); +} + +TEST(AzQtComponents, FloatToString_TruncateShowThousandsSeparatorTruncateNoRoundWithLocale) +{ + QLocale testLocale{ QLocale() }; + + const bool showThousandsSeparator = true; + const int numDecimalPlaces = 3; + QString testString = "1" + QString(testLocale.groupSeparator()) + "000" + QString(testLocale.decimalPoint()) + "123"; + EXPECT_EQ(testString, AzQtComponents::toString(1000.1236, numDecimalPlaces, testLocale, showThousandsSeparator)); +} + +TEST(AzQtComponents, FloatToString_TruncateShowThousandsSeparatorOnlyOneDecimalWithLocale) +{ + QLocale testLocale{ QLocale() }; + + const bool showThousandsSeparator = true; + int numDecimalPlaces = 2; + QString testString = "1" + QString(testLocale.groupSeparator()) + "000" + QString(testLocale.decimalPoint()) + "0"; + EXPECT_EQ(testString, AzQtComponents::toString(1000.000, numDecimalPlaces, testLocale, showThousandsSeparator)); } diff --git a/Code/Framework/AzTest/AzTest/Platform/Windows/Platform_Windows.cpp b/Code/Framework/AzTest/AzTest/Platform/Windows/Platform_Windows.cpp index 08e86fdc16..777ba66c6d 100644 --- a/Code/Framework/AzTest/AzTest/Platform/Windows/Platform_Windows.cpp +++ b/Code/Framework/AzTest/AzTest/Platform/Windows/Platform_Windows.cpp @@ -9,6 +9,7 @@ #include #include #include +#include //------------------------------------------------------------------------------------------------- class ModuleHandle @@ -151,7 +152,7 @@ namespace AZ va_start(mark, format); azvsnprintf(message, MAX_PRINT_MSG, format, mark); va_end(mark); - OutputDebugString(message); + AZ::Debug::Platform::OutputToDebugger(nullptr, message); } AZ::EnvironmentInstance Platform::GetTestRunnerEnvironment() diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/API/ToolsApplicationAPI.h b/Code/Framework/AzToolsFramework/AzToolsFramework/API/ToolsApplicationAPI.h index 0ba10d7388..f6046b9f25 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/API/ToolsApplicationAPI.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/API/ToolsApplicationAPI.h @@ -600,8 +600,8 @@ namespace AzToolsFramework * Open 3D Engine Internal use only. * * Run a specific redo command separate from the undo/redo system. - * In many cases before a modifcation on an entity takes place, it is first packaged into - * undo/redo commands. Running the modification's redo command separete from the undo/redo + * In many cases before a modification on an entity takes place, it is first packaged into + * undo/redo commands. Running the modification's redo command separate from the undo/redo * system simulates its execution, and avoids some code duplication. */ virtual void RunRedoSeparately(UndoSystem::URSequencePoint* redoCommand) = 0; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/API/ViewPaneOptions.h b/Code/Framework/AzToolsFramework/AzToolsFramework/API/ViewPaneOptions.h index a05a57e138..be93e1af1a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/API/ViewPaneOptions.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/API/ViewPaneOptions.h @@ -8,7 +8,7 @@ #pragma once -#include +#include #include #include diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Application/ToolsApplication.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Application/ToolsApplication.cpp index 970f5aa28c..56ef749247 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Application/ToolsApplication.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Application/ToolsApplication.cpp @@ -1781,5 +1781,4 @@ namespace AzToolsFramework { appType.m_maskValue = AZ::ApplicationTypeQuery::Masks::Tool; }; - } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Asset/AssetDebugInfo.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Asset/AssetDebugInfo.h index 38bee8a1e5..56eaeb0f75 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Asset/AssetDebugInfo.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Asset/AssetDebugInfo.h @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp index 814c4e2a7f..36b39f3a72 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp @@ -46,7 +46,6 @@ namespace AzToolsFramework bool InstanceToTemplatePropagator::GenerateDomForEntity(PrefabDom& generatedEntityDom, const AZ::Entity& entity) { - //grab the owning instance so we can use the entityIdMapper in settings InstanceOptionalReference owningInstance = m_instanceEntityMapperInterface->FindOwningInstance(entity.GetId()); if (!owningInstance) @@ -54,19 +53,8 @@ namespace AzToolsFramework AZ_Error("Prefab", false, "Entity does not belong to an instance"); return false; } - - InstanceEntityIdMapper entityIdMapper; - entityIdMapper.SetStoringInstance(owningInstance->get()); - //create settings so that the serialized entity dom undergoes mapping from entity id to entity alias - AZ::JsonSerializerSettings settings; - settings.m_metadata.Add(static_cast(&entityIdMapper)); - - //generate PrefabDom using Json serialization system - AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::Store( - generatedEntityDom, generatedEntityDom.GetAllocator(), entity, settings); - - return result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success; + return PrefabDomUtils::StoreEntityInPrefabDomFormat(entity, owningInstance->get(), generatedEntityDom); } bool InstanceToTemplatePropagator::GenerateDomForInstance(PrefabDom& generatedInstanceDom, const Prefab::Instance& instance) @@ -185,8 +173,10 @@ namespace AzToolsFramework else { AZ_Error( - "Prefab", result.GetOutcome() != AZ::JsonSerializationResult::Outcomes::PartialSkip, - "Some of the patches are not successfully applied."); + "Prefab", + (result.GetOutcome() != AZ::JsonSerializationResult::Outcomes::Skipped) && + (result.GetOutcome() != AZ::JsonSerializationResult::Outcomes::PartialSkip), + "Some of the patches were not successfully applied."); m_prefabSystemComponentInterface->SetTemplateDirtyFlag(templateId, true); m_prefabSystemComponentInterface->PropagateTemplateChanges(templateId, instanceToExclude); return true; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Link/Link.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Link/Link.cpp index 3c7e5ff3f8..940a2787cb 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Link/Link.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Link/Link.cpp @@ -196,7 +196,8 @@ namespace AzToolsFramework m_sourceTemplateId, m_targetTemplateId); return false; } - if (applyPatchResult.GetOutcome() == AZ::JsonSerializationResult::Outcomes::PartialSkip) + if (applyPatchResult.GetOutcome() == AZ::JsonSerializationResult::Outcomes::PartialSkip || + applyPatchResult.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Skipped) { AZ_Error( "Prefab", false, diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp index 86983d7912..1ad88e53d2 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp @@ -26,6 +26,30 @@ namespace AzToolsFramework { namespace PrefabDomUtils { + namespace Internal + { + AZ::JsonSerializationResult::ResultCode JsonIssueReporter(AZStd::string& scratchBuffer, + AZStd::string_view message, AZ::JsonSerializationResult::ResultCode result, AZStd::string_view path) + { + namespace JSR = AZ::JsonSerializationResult; + + if (result.GetProcessing() == JSR::Processing::Halted) + { + scratchBuffer.append(message.begin(), message.end()); + scratchBuffer.append("\n Reason: "); + result.AppendToString(scratchBuffer, path); + scratchBuffer.append("."); + AZ_Warning("Prefab Serialization", false, "%s", scratchBuffer.c_str()); + + scratchBuffer.clear(); + + return JSR::ResultCode(result.GetTask(), JSR::Outcomes::Skipped); + } + + return result; + } + } + PrefabDomValueReference FindPrefabDomValue(PrefabDomValue& parentValue, const char* valueName) { PrefabDomValue::MemberIterator valueIterator = parentValue.FindMember(valueName); @@ -48,7 +72,7 @@ namespace AzToolsFramework return valueIterator->value; } - bool StoreInstanceInPrefabDom(const Instance& instance, PrefabDom& prefabDom, StoreInstanceFlags flags) + bool StoreInstanceInPrefabDom(const Instance& instance, PrefabDom& prefabDom, StoreFlags flags) { InstanceEntityIdMapper entityIdMapper; entityIdMapper.SetStoringInstance(instance); @@ -59,11 +83,21 @@ namespace AzToolsFramework settings.m_metadata.Add(static_cast(&entityIdMapper)); settings.m_metadata.Add(&entityIdMapper); - if ((flags & StoreInstanceFlags::StripDefaultValues) != StoreInstanceFlags::StripDefaultValues) + if ((flags & StoreFlags::StripDefaultValues) != StoreFlags::StripDefaultValues) { settings.m_keepDefaults = true; } + AZStd::string scratchBuffer; + auto issueReportingCallback = [&scratchBuffer] + (AZStd::string_view message, AZ::JsonSerializationResult::ResultCode result, + AZStd::string_view path) -> AZ::JsonSerializationResult::ResultCode + { + return Internal::JsonIssueReporter(scratchBuffer, message, result, path); + }; + + settings.m_reporting = AZStd::move(issueReportingCallback); + AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), instance, settings); @@ -80,7 +114,38 @@ namespace AzToolsFramework return true; } - bool LoadInstanceFromPrefabDom(Instance& instance, const PrefabDom& prefabDom, LoadInstanceFlags flags) + bool StoreEntityInPrefabDomFormat(const AZ::Entity& entity, Instance& owningInstance, PrefabDom& prefabDom, StoreFlags flags) + { + InstanceEntityIdMapper entityIdMapper; + entityIdMapper.SetStoringInstance(owningInstance); + + //create settings so that the serialized entity dom undergoes mapping from entity id to entity alias + AZ::JsonSerializerSettings settings; + settings.m_metadata.Add(static_cast(&entityIdMapper)); + + if ((flags & StoreFlags::StripDefaultValues) != StoreFlags::StripDefaultValues) + { + settings.m_keepDefaults = true; + } + + AZStd::string scratchBuffer; + auto issueReportingCallback = [&scratchBuffer] + (AZStd::string_view message, AZ::JsonSerializationResult::ResultCode result, + AZStd::string_view path) -> AZ::JsonSerializationResult::ResultCode + { + return Internal::JsonIssueReporter(scratchBuffer, message, result, path); + }; + + settings.m_reporting = AZStd::move(issueReportingCallback); + + //generate PrefabDom using Json serialization system + AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::Store( + prefabDom, prefabDom.GetAllocator(), entity, settings); + + return result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success; + } + + bool LoadInstanceFromPrefabDom(Instance& instance, const PrefabDom& prefabDom, LoadFlags flags) { // When entities are rebuilt they are first destroyed. As a result any assets they were exclusively holding on to will // be released and reloaded once the entities are built up again. By suspending asset release temporarily the asset reload @@ -89,7 +154,7 @@ namespace AzToolsFramework InstanceEntityIdMapper entityIdMapper; entityIdMapper.SetLoadingInstance(instance); - if ((flags & LoadInstanceFlags::AssignRandomEntityId) == LoadInstanceFlags::AssignRandomEntityId) + if ((flags & LoadFlags::AssignRandomEntityId) == LoadFlags::AssignRandomEntityId) { entityIdMapper.SetEntityIdGenerationApproach(InstanceEntityIdMapper::EntityIdGenerationApproach::Random); } @@ -119,7 +184,7 @@ namespace AzToolsFramework } bool LoadInstanceFromPrefabDom( - Instance& instance, const PrefabDom& prefabDom, AZStd::vector>& referencedAssets, LoadInstanceFlags flags) + Instance& instance, const PrefabDom& prefabDom, AZStd::vector>& referencedAssets, LoadFlags flags) { // When entities are rebuilt they are first destroyed. As a result any assets they were exclusively holding on to will // be released and reloaded once the entities are built up again. By suspending asset release temporarily the asset reload @@ -128,7 +193,7 @@ namespace AzToolsFramework InstanceEntityIdMapper entityIdMapper; entityIdMapper.SetLoadingInstance(instance); - if ((flags & LoadInstanceFlags::AssignRandomEntityId) == LoadInstanceFlags::AssignRandomEntityId) + if ((flags & LoadFlags::AssignRandomEntityId) == LoadFlags::AssignRandomEntityId) { entityIdMapper.SetEntityIdGenerationApproach(InstanceEntityIdMapper::EntityIdGenerationApproach::Random); } @@ -161,7 +226,7 @@ namespace AzToolsFramework } bool LoadInstanceFromPrefabDom( - Instance& instance, Instance::EntityList& newlyAddedEntities, const PrefabDom& prefabDom, LoadInstanceFlags flags) + Instance& instance, Instance::EntityList& newlyAddedEntities, const PrefabDom& prefabDom, LoadFlags flags) { // When entities are rebuilt they are first destroyed. As a result any assets they were exclusively holding on to will // be released and reloaded once the entities are built up again. By suspending asset release temporarily the asset reload @@ -170,7 +235,7 @@ namespace AzToolsFramework InstanceEntityIdMapper entityIdMapper; entityIdMapper.SetLoadingInstance(instance); - if ((flags & LoadInstanceFlags::AssignRandomEntityId) == LoadInstanceFlags::AssignRandomEntityId) + if ((flags & LoadFlags::AssignRandomEntityId) == LoadFlags::AssignRandomEntityId) { entityIdMapper.SetEntityIdGenerationApproach(InstanceEntityIdMapper::EntityIdGenerationApproach::Random); } @@ -240,15 +305,12 @@ namespace AzToolsFramework AZ::JsonSerializationResult::ResultCode ApplyPatches( PrefabDomValue& prefabDomToApplyPatchesOn, PrefabDom::AllocatorType& allocator, const PrefabDomValue& patches) { - auto issueReportingCallback = [](AZStd::string_view, AZ::JsonSerializationResult::ResultCode result, - AZStd::string_view) -> AZ::JsonSerializationResult::ResultCode + AZStd::string scratchBuffer; + auto issueReportingCallback = [&scratchBuffer] + (AZStd::string_view message, AZ::JsonSerializationResult::ResultCode result, + AZStd::string_view path) -> AZ::JsonSerializationResult::ResultCode { - using namespace AZ::JsonSerializationResult; - if (result.GetProcessing() == Processing::Halted) - { - return ResultCode(result.GetTask(), Outcomes::PartialSkip); - } - return result; + return Internal::JsonIssueReporter(scratchBuffer, message, result, path); }; AZ::JsonApplyPatchSettings applyPatchSettings; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h index e773b581dd..b04cf9f57d 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h @@ -38,7 +38,7 @@ namespace AzToolsFramework PrefabDomValueReference FindPrefabDomValue(PrefabDomValue& parentValue, const char* valueName); PrefabDomValueConstReference FindPrefabDomValue(const PrefabDomValue& parentValue, const char* valueName); - enum class StoreInstanceFlags : uint8_t + enum class StoreFlags : uint8_t { //! No flags used during the call to LoadInstanceFromPrefabDom. None = 0, @@ -47,7 +47,7 @@ namespace AzToolsFramework //! such as saving to disk, this flag will control that behavior. StripDefaultValues = 1 << 0 }; - AZ_DEFINE_ENUM_BITWISE_OPERATORS(StoreInstanceFlags); + AZ_DEFINE_ENUM_BITWISE_OPERATORS(StoreFlags); /** * Stores a valid Prefab Instance within a Prefab Dom. Useful for generating Templates @@ -56,9 +56,21 @@ namespace AzToolsFramework * @param flags Controls behavior such as whether to store default values * @return bool on whether the operation succeeded */ - bool StoreInstanceInPrefabDom(const Instance& instance, PrefabDom& prefabDom, StoreInstanceFlags flags = StoreInstanceFlags::None); + bool StoreInstanceInPrefabDom(const Instance& instance, PrefabDom& prefabDom, StoreFlags flags = StoreFlags::None); - enum class LoadInstanceFlags : uint8_t + /** + * Stores a valid entity in Prefab Dom format. + * @param entity The entity to store + * @param owningInstance The instance owning the passed in entity. + * Used for contextualizing the entity's place in a Prefab hierarchy. + * @param prefabDom The prefabDom that will be used to store the entity data + * @param flags controls behavior such as whether to store default values + * @return bool on whether the operation succeeded + */ + bool StoreEntityInPrefabDomFormat(const AZ::Entity& entity, Instance& owningInstance, PrefabDom& prefabDom, + StoreFlags flags = StoreFlags::None); + + enum class LoadFlags : uint8_t { //! No flags used during the call to LoadInstanceFromPrefabDom. None = 0, @@ -66,7 +78,7 @@ namespace AzToolsFramework //! unique, e.g. when they are duplicates of live entities, this flag will assign them a random new id. AssignRandomEntityId = 1 << 0 }; - AZ_DEFINE_ENUM_BITWISE_OPERATORS(LoadInstanceFlags); + AZ_DEFINE_ENUM_BITWISE_OPERATORS(LoadFlags); /** * Loads a valid Prefab Instance from a Prefab Dom. Useful for generating Instances. @@ -76,7 +88,7 @@ namespace AzToolsFramework * @return bool on whether the operation succeeded. */ bool LoadInstanceFromPrefabDom( - Instance& instance, const PrefabDom& prefabDom, LoadInstanceFlags flags = LoadInstanceFlags::None); + Instance& instance, const PrefabDom& prefabDom, LoadFlags flags = LoadFlags::None); /** * Loads a valid Prefab Instance from a Prefab Dom. Useful for generating Instances. @@ -88,7 +100,7 @@ namespace AzToolsFramework */ bool LoadInstanceFromPrefabDom( Instance& instance, const PrefabDom& prefabDom, AZStd::vector>& referencedAssets, - LoadInstanceFlags flags = LoadInstanceFlags::None); + LoadFlags flags = LoadFlags::None); /** * Loads a valid Prefab Instance from a Prefab Dom. Useful for generating Instances. @@ -101,7 +113,7 @@ namespace AzToolsFramework */ bool LoadInstanceFromPrefabDom( Instance& instance, Instance::EntityList& newlyAddedEntities, const PrefabDom& prefabDom, - LoadInstanceFlags flags = LoadInstanceFlags::None); + LoadFlags flags = LoadFlags::None); inline PrefabDomPath GetPrefabDomInstancePath(const char* instanceName) { diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabLoader.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabLoader.cpp index ea54c9d10c..5091a2d1bc 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabLoader.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabLoader.cpp @@ -328,7 +328,7 @@ namespace AzToolsFramework PrefabDom storedPrefabDom(&savingTemplateDom->get().GetAllocator()); if (!PrefabDomUtils::StoreInstanceInPrefabDom(savingPrefabInstance, storedPrefabDom, - PrefabDomUtils::StoreInstanceFlags::StripDefaultValues)) + PrefabDomUtils::StoreFlags::StripDefaultValues)) { return false; } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index 69efe33d72..7af953efca 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -61,7 +61,7 @@ namespace AzToolsFramework m_prefabUndoCache.Destroy(); } - PrefabOperationResult PrefabPublicHandler::CreatePrefab(const AZStd::vector& entityIds, AZ::IO::PathView absolutePath) + PrefabOperationResult PrefabPublicHandler::CreatePrefabInMemory(const AZStd::vector& entityIds, AZ::IO::PathView filePath) { EntityList inputEntityList, topLevelEntities; AZ::EntityId commonRootEntityId; @@ -73,8 +73,6 @@ namespace AzToolsFramework return findCommonRootOutcome; } - AZ_Assert(absolutePath.IsAbsolute(), "CreatePrefab requires an absolute path for saving the initial prefab file."); - InstanceOptionalReference instanceToCreate; { // Initialize Undo Batch object @@ -125,7 +123,7 @@ namespace AzToolsFramework PrefabDom linkPatchesCopy; linkPatchesCopy.CopyFrom(linkPatches->get(), linkPatchesCopy.GetAllocator()); nestedInstanceLinkPatchesMap.emplace(nestedInstance, AZStd::move(linkPatchesCopy)); - + RemoveLink(outInstance, commonRootEntityOwningInstance->get().GetTemplateId(), undoBatch.GetUndoBatch()); instancePtrs.emplace_back(AZStd::move(outInstance)); @@ -139,18 +137,20 @@ namespace AzToolsFramework if (!prefabEditorEntityOwnershipInterface) { return AZ::Failure(AZStd::string("Could not create a new prefab out of the entities provided - internal error " - "(PrefabEditorEntityOwnershipInterface unavailable).")); + "(PrefabEditorEntityOwnershipInterface unavailable).")); } // Create the Prefab + AZ_Assert(filePath.IsAbsolute(), "CreatePrefabInMemory requires an absolute file path."); + instanceToCreate = prefabEditorEntityOwnershipInterface->CreatePrefab( - entities, AZStd::move(instancePtrs), m_prefabLoaderInterface->GenerateRelativePath(absolutePath), + entities, AZStd::move(instancePtrs), m_prefabLoaderInterface->GenerateRelativePath(filePath), commonRootEntityOwningInstance); if (!instanceToCreate) { return AZ::Failure(AZStd::string("Could not create a new prefab out of the entities provided - internal error " - "(A null instance is returned).")); + "(A null instance is returned).")); } AZ::EntityId containerEntityId = instanceToCreate->get().GetContainerEntityId(); @@ -218,7 +218,7 @@ namespace AzToolsFramework linkUpdate.Redo(); } }); - + // Create a link between the templates of the newly created instance and the instance it's being parented under. CreateLink( instanceToCreate->get(), commonRootEntityOwningInstance->get().GetTemplateId(), undoBatch.GetUndoBatch(), @@ -255,18 +255,35 @@ namespace AzToolsFramework // Select Container Entity { - auto selectionUndo = aznew SelectionCommand({containerEntityId}, "Select Prefab Container Entity"); + auto selectionUndo = aznew SelectionCommand({ containerEntityId }, "Select Prefab Container Entity"); selectionUndo->SetParent(undoBatch.GetUndoBatch()); ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequestBus::Events::RunRedoSeparately, selectionUndo); } } - // Save Template to file - m_prefabLoaderInterface->SaveTemplateToFile(instanceToCreate->get().GetTemplateId(), absolutePath); - return AZ::Success(); } + PrefabOperationResult PrefabPublicHandler::CreatePrefabInDisk(const AZStd::vector& entityIds, AZ::IO::PathView filePath) + { + auto result = CreatePrefabInMemory(entityIds, filePath); + if (result.IsSuccess()) + { + // Save Template to file + auto relativePath = m_prefabLoaderInterface->GenerateRelativePath(filePath); + Prefab::TemplateId templateId = m_prefabSystemComponentInterface->GetTemplateIdFromFilePath(relativePath); + if (!m_prefabLoaderInterface->SaveTemplateToFile(templateId, filePath)) + { + AZStd::string_view filePathString(filePath); + return AZ::Failure(AZStd::string::format( + "Could not save the newly created prefab to file path %.*s - internal error ", + AZ_STRING_ARG(filePathString))); + } + } + + return result; + } + PrefabDom PrefabPublicHandler::ApplyContainerTransformAndGeneratePatch(AZ::EntityId containerEntityId, AZ::EntityId parentEntityId, const EntityList& childEntities) { AZ::Entity* containerEntity = GetEntityById(containerEntityId); @@ -301,7 +318,7 @@ namespace AzToolsFramework return AZStd::move(patch); } - PrefabOperationResult PrefabPublicHandler::InstantiatePrefab( + InstantiatePrefabResult PrefabPublicHandler::InstantiatePrefab( AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position) { auto prefabEditorEntityOwnershipInterface = AZ::Interface::Get(); @@ -347,6 +364,7 @@ namespace AzToolsFramework relativePath.Native().c_str(), instanceToParentUnder->get().GetTemplateSourcePath().Native().c_str())); } + AZ::EntityId containerEntityId; { // Initialize Undo Batch object ScopedUndoBatch undoBatch("Instantiate Prefab"); @@ -367,7 +385,7 @@ namespace AzToolsFramework instanceToParentUnder->get(), "Update prefab instance", instanceToParentUnderDomBeforeCreate, undoBatch.GetUndoBatch()); // Create Link with correct container patches - AZ::EntityId containerEntityId = instanceToCreate->get().GetContainerEntityId(); + containerEntityId = instanceToCreate->get().GetContainerEntityId(); AZ::Entity* containerEntity = GetEntityById(containerEntityId); AZ_Assert(containerEntity, "Invalid container entity detected in InstantiatePrefab."); @@ -394,7 +412,7 @@ namespace AzToolsFramework &AzToolsFramework::ToolsApplicationRequestBus::Events::ClearDirtyEntities); } - return AZ::Success(); + return AZ::Success(containerEntityId); } PrefabOperationResult PrefabPublicHandler::FindCommonRootOwningInstance( @@ -1727,6 +1745,7 @@ namespace AzToolsFramework AliasPath absoluteInstancePath = commonOwningInstance.GetAbsoluteInstanceAliasPath(); absoluteInstancePath.Append(newInstanceAlias); + absoluteInstancePath.Append(PrefabDomUtils::ContainerEntityName); AZ::EntityId newEntityId = InstanceEntityIdMapper::GenerateEntityIdForAliasPath(absoluteInstancePath); duplicatedEntityIds.push_back(newEntityId); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h index 0e24b0841d..8f124e8edd 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h @@ -42,8 +42,11 @@ namespace AzToolsFramework void UnregisterPrefabPublicHandlerInterface(); // PrefabPublicInterface... - PrefabOperationResult CreatePrefab(const AZStd::vector& entityIds, AZ::IO::PathView absolutePath) override; - PrefabOperationResult InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position) override; + PrefabOperationResult CreatePrefabInDisk( + const AZStd::vector& entityIds, AZ::IO::PathView filePath) override; + PrefabOperationResult CreatePrefabInMemory( + const AZStd::vector& entityIds, AZ::IO::PathView filePath) override; + InstantiatePrefabResult InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position) override; PrefabOperationResult SavePrefab(AZ::IO::Path filePath) override; PrefabEntityResult CreateEntity(AZ::EntityId parentId, const AZ::Vector3& position) override; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicInterface.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicInterface.h index 6b3fdcd391..67d65dfca6 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicInterface.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicInterface.h @@ -25,6 +25,7 @@ namespace AzToolsFramework namespace Prefab { typedef AZ::Outcome PrefabOperationResult; + typedef AZ::Outcome InstantiatePrefabResult; typedef AZ::Outcome PrefabRequestResult; typedef AZ::Outcome PrefabEntityResult; @@ -39,22 +40,34 @@ namespace AzToolsFramework AZ_RTTI(PrefabPublicInterface, "{931AAE9D-C775-4818-9070-A2DA69489CBE}"); /** - * Create a prefab out of the entities provided, at the path provided. + * Create a prefab out of the entities provided, at the path provided, and save it in disk immediately. * Automatically detects descendants of entities, and discerns between entities and child instances. * @param entityIds The entities that should form the new prefab (along with their descendants). * @param filePath The absolute path for the new prefab file. * @return An outcome object; on failure, it comes with an error message detailing the cause of the error. */ - virtual PrefabOperationResult CreatePrefab(const AZStd::vector& entityIds, AZ::IO::PathView absolutePath) = 0; + virtual PrefabOperationResult CreatePrefabInDisk( + const AZStd::vector& entityIds, AZ::IO::PathView filePath) = 0; + + /** + * Create a prefab out of the entities provided, at the path provided, and keep it in memory. + * Automatically detects descendants of entities, and discerns between entities and child instances. + * @param entityIds The entities that should form the new prefab (along with their descendants). + * @param filePath The absolute path for the new prefab file. + * @return An outcome object; on failure, it comes with an error message detailing the cause of the error. + */ + virtual PrefabOperationResult CreatePrefabInMemory( + const AZStd::vector& entityIds, AZ::IO::PathView filePath) = 0; /** * Instantiate a prefab from a prefab file. * @param filePath The path to the prefab file to instantiate. * @param parent The entity the prefab should be a child of in the transform hierarchy. * @param position The position in world space the prefab should be instantiated in. - * @return An outcome object; on failure, it comes with an error message detailing the cause of the error. + * @return An outcome object with an entityId of the new prefab's container entity; + * on failure, it comes with an error message detailing the cause of the error. */ - virtual PrefabOperationResult InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position) = 0; + virtual InstantiatePrefabResult InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position) = 0; /** * Saves changes to prefab to disk. diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicRequestBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicRequestBus.h new file mode 100644 index 0000000000..1b86d3cd4e --- /dev/null +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicRequestBus.h @@ -0,0 +1,56 @@ +/* + * 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 + * + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace AzToolsFramework +{ + namespace Prefab + { + /** + * The primary purpose of this bus is to facilitate writing automated tests for prefabs. + * It calls PrefabPublicInterface internally to talk to the prefab system. + * If you would like to integrate prefabs into your system, please call PrefabPublicInterface + * directly for better performance. + */ + class PrefabPublicRequests + : public AZ::EBusTraits + { + public: + using Bus = AZ::EBus; + + ////////////////////////////////////////////////////////////////////////// + // EBusTraits overrides + static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; + ////////////////////////////////////////////////////////////////////////// + + virtual ~PrefabPublicRequests() = default; + + /** + * Create a prefab out of the entities provided, at the path provided, and keep it in memory. + * Automatically detects descendants of entities, and discerns between entities and child instances. + */ + virtual bool CreatePrefabInMemory( + const AZStd::vector& entityIds, AZStd::string_view filePath) = 0; + + /** + * Instantiate a prefab from a prefab file. + */ + virtual AZ::EntityId InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position) = 0; + }; + + using PrefabPublicRequestBus = AZ::EBus; + + } // namespace Prefab +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicRequestHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicRequestHandler.cpp new file mode 100644 index 0000000000..0e68a286a6 --- /dev/null +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicRequestHandler.cpp @@ -0,0 +1,79 @@ +/* + * 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 + +#include + +namespace AzToolsFramework +{ + namespace Prefab + { + void PrefabPublicRequestHandler::Reflect(AZ::ReflectContext* context) + { + AZ::BehaviorContext* behaviorContext = azrtti_cast(context); + if (behaviorContext) + { + behaviorContext->EBus("PrefabPublicRequestBus") + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation) + ->Attribute(AZ::Script::Attributes::Category, "Prefab") + ->Attribute(AZ::Script::Attributes::Module, "prefab") + ->Event("CreatePrefabInMemory", &PrefabPublicRequests::CreatePrefabInMemory) + ->Event("InstantiatePrefab", &PrefabPublicRequests::InstantiatePrefab) + ; + } + } + + void PrefabPublicRequestHandler::Connect() + { + m_prefabPublicInterface = AZ::Interface::Get(); + AZ_Assert(m_prefabPublicInterface, "PrefabPublicRequestHandler - Could not retrieve instance of PrefabPublicInterface"); + + PrefabPublicRequestBus::Handler::BusConnect(); + } + + void PrefabPublicRequestHandler::Disconnect() + { + PrefabPublicRequestBus::Handler::BusDisconnect(); + + m_prefabPublicInterface = nullptr; + } + + bool PrefabPublicRequestHandler::CreatePrefabInMemory(const AZStd::vector& entityIds, AZStd::string_view filePath) + { + auto createPrefabOutcome = m_prefabPublicInterface->CreatePrefabInMemory(entityIds, filePath); + if (!createPrefabOutcome.IsSuccess()) + { + AZ_Error("CreatePrefabInMemory", false, + "Failed to create Prefab on file path '%.*s'. Error message: %s.", + AZ_STRING_ARG(filePath), + createPrefabOutcome.GetError().c_str()); + + return false; + } + + return true; + } + + AZ::EntityId PrefabPublicRequestHandler::InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position) + { + auto instantiatePrefabOutcome = m_prefabPublicInterface->InstantiatePrefab(filePath, parent, position); + if (!instantiatePrefabOutcome.IsSuccess()) + { + AZ_Error("InstantiatePrefab", false, + "Failed to instantiate Prefab on file path '%.*s'. Error message: %s.", + AZ_STRING_ARG(filePath), + instantiatePrefabOutcome.GetError().c_str()); + + return AZ::EntityId(); + } + + return instantiatePrefabOutcome.GetValue(); + } + } // namespace Prefab +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicRequestHandler.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicRequestHandler.h new file mode 100644 index 0000000000..548bc8e04a --- /dev/null +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicRequestHandler.h @@ -0,0 +1,41 @@ +/* + * 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 + * + */ + +#pragma once + +#include +#include + +#include + +namespace AzToolsFramework +{ + namespace Prefab + { + class PrefabPublicInterface; + + class PrefabPublicRequestHandler final + : public PrefabPublicRequestBus::Handler + { + public: + AZ_CLASS_ALLOCATOR(PrefabPublicRequestHandler, AZ::SystemAllocator, 0); + AZ_RTTI(PrefabPublicRequestHandler, "{83FBDDF9-10BE-4373-B1DC-44B47EE4805C}"); + + static void Reflect(AZ::ReflectContext* context); + + void Connect(); + void Disconnect(); + + bool CreatePrefabInMemory(const AZStd::vector& entityIds, AZStd::string_view filePath) override; + AZ::EntityId InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position) override; + + private: + PrefabPublicInterface* m_prefabPublicInterface = nullptr; + }; + } // namespace Prefab +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp index bfdb6b79f2..1051e530c8 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp @@ -35,12 +35,14 @@ namespace AzToolsFramework m_instanceUpdateExecutor.RegisterInstanceUpdateExecutorInterface(); m_instanceToTemplatePropagator.RegisterInstanceToTemplateInterface(); m_prefabPublicHandler.RegisterPrefabPublicHandlerInterface(); + m_prefabPublicRequestHandler.Connect(); AZ::SystemTickBus::Handler::BusConnect(); } void PrefabSystemComponent::Deactivate() { AZ::SystemTickBus::Handler::BusDisconnect(); + m_prefabPublicRequestHandler.Disconnect(); m_prefabPublicHandler.UnregisterPrefabPublicHandlerInterface(); m_instanceToTemplatePropagator.UnregisterInstanceToTemplateInterface(); m_instanceUpdateExecutor.UnregisterInstanceUpdateExecutorInterface(); @@ -54,6 +56,7 @@ namespace AzToolsFramework AzToolsFramework::Prefab::PrefabConversionUtils::PrefabConversionPipeline::Reflect(context); AzToolsFramework::Prefab::PrefabConversionUtils::PrefabCatchmentProcessor::Reflect(context); AzToolsFramework::Prefab::PrefabConversionUtils::EditorInfoRemover::Reflect(context); + PrefabPublicRequestHandler::Reflect(context); AZ::SerializeContext* serialize = azrtti_cast(context); if (serialize) @@ -62,7 +65,6 @@ namespace AzToolsFramework } AZ::JsonRegistrationContext* jsonRegistration = azrtti_cast(context); - if (jsonRegistration) { jsonRegistration->Serializer()->HandlesType(); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h index 04457b5a97..b07ccbada6 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -369,6 +370,9 @@ namespace AzToolsFramework // Used for updating Templates when Instances are modified InstanceToTemplatePropagator m_instanceToTemplatePropagator; + + // Handler of the public Prefab requests + PrefabPublicRequestHandler m_prefabPublicRequestHandler; }; } // namespace Prefab } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp index 955af18a66..fc64e0b5b3 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp @@ -266,8 +266,8 @@ namespace AzToolsFramework AZ_Error( "Prefab", - result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::PartialSkip || - result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success, + (result.GetOutcome() != AZ::JsonSerializationResult::Outcomes::Skipped) && + (result.GetOutcome() != AZ::JsonSerializationResult::Outcomes::PartialSkip), "Some of the patches are not successfully applied."); //remove the link id placed into the instance diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/EditorInfoRemover.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/EditorInfoRemover.cpp index 1d856fa395..dfba1d54ba 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/EditorInfoRemover.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/EditorInfoRemover.cpp @@ -513,7 +513,7 @@ exportComponent, prefabProcessorContext); // convert Prefab DOM into Prefab Instance. AZStd::unique_ptr instance(aznew Instance()); if (!Prefab::PrefabDomUtils::LoadInstanceFromPrefabDom(*instance, prefab, - Prefab::PrefabDomUtils::LoadInstanceFlags::AssignRandomEntityId)) + Prefab::PrefabDomUtils::LoadFlags::AssignRandomEntityId)) { PrefabDomValueReference sourceReference = PrefabDomUtils::FindPrefabDomValue(prefab, PrefabDomUtils::SourceName); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp index 1373d2fa75..902f439280 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp @@ -30,7 +30,7 @@ namespace AzToolsFramework::Prefab::SpawnableUtils { Instance instance; if (Prefab::PrefabDomUtils::LoadInstanceFromPrefabDom(instance, prefabDom, referencedAssets, - Prefab::PrefabDomUtils::LoadInstanceFlags::AssignRandomEntityId)) // Always assign random entity ids because the spawnable is + Prefab::PrefabDomUtils::LoadFlags::AssignRandomEntityId)) // Always assign random entity ids because the spawnable is // going to be used to create clones of the entities. { AzFramework::Spawnable::EntityList& entities = spawnable.GetEntities(); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp index 5bf9b15abe..eb9cf2b65f 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp @@ -256,11 +256,11 @@ namespace AzToolsFramework void PrefabIntegrationManager::HandleSourceFileType(AZStd::string_view sourceFilePath, AZ::EntityId parentId, AZ::Vector3 position) const { - auto createPrefabOutcome = s_prefabPublicInterface->InstantiatePrefab(sourceFilePath, parentId, position); + auto instantiatePrefabOutcome = s_prefabPublicInterface->InstantiatePrefab(sourceFilePath, parentId, position); - if (!createPrefabOutcome.IsSuccess()) + if (!instantiatePrefabOutcome.IsSuccess()) { - WarnUserOfError("Prefab Instantiation Error", createPrefabOutcome.GetError()); + WarnUserOfError("Prefab Instantiation Error", instantiatePrefabOutcome.GetError()); } } @@ -348,7 +348,7 @@ namespace AzToolsFramework } } - auto createPrefabOutcome = s_prefabPublicInterface->CreatePrefab(selectedEntities, prefabFilePath.data()); + auto createPrefabOutcome = s_prefabPublicInterface->CreatePrefabInDisk(selectedEntities, prefabFilePath.data()); if (!createPrefabOutcome.IsSuccess()) { diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp index 5ea36bb30e..05c04872e3 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp @@ -70,7 +70,7 @@ namespace AzToolsFramework m_leftAreaContainer = new QWidget(this); m_middleAreaContainer = new QWidget(this); - const int minimumControlWidth = 192; + const int minimumControlWidth = 142; m_middleAreaContainer->setMinimumWidth(minimumControlWidth); m_mainLayout->addWidget(m_leftAreaContainer, LabelColumnStretch, Qt::AlignLeft); m_mainLayout->addWidget(m_middleAreaContainer, ValueColumnStretch); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportTypes.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportTypes.h index 0ce80261ce..1cfb0dbe74 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportTypes.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportTypes.h @@ -19,6 +19,7 @@ namespace AZ { class ReflectContext; + class SerializeContext; } namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake index 53173f83af..14c5f34f90 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake @@ -657,6 +657,9 @@ set(FILES Prefab/PrefabPublicHandler.cpp Prefab/PrefabPublicInterface.h Prefab/PrefabPublicNotificationBus.h + Prefab/PrefabPublicRequestBus.h + Prefab/PrefabPublicRequestHandler.h + Prefab/PrefabPublicRequestHandler.cpp Prefab/PrefabUndo.h Prefab/PrefabUndo.cpp Prefab/PrefabUndoCache.cpp diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabBenchmarkFixture.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabBenchmarkFixture.cpp index 7e47fa9569..9925d5bff3 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabBenchmarkFixture.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabBenchmarkFixture.cpp @@ -85,7 +85,7 @@ namespace Benchmark void BM_Prefab::CreateEntities(const unsigned int entityCount, AZStd::vector& entities) { - for (int entityIndex = 0; entityIndex < entityCount; ++entityIndex) + for (unsigned int entityIndex = 0; entityIndex < entityCount; ++entityIndex) { AZStd::string entityName = "TestEntity"; entityName = entityName + AZStd::to_string(entityIndex); @@ -101,7 +101,7 @@ namespace Benchmark void BM_Prefab::CreateFakePaths(const unsigned int pathCount) { //setup fake paths - for (int number = 0; number < pathCount; ++number) + for (unsigned int number = 0; number < pathCount; ++number) { AZStd::string path = m_pathString; m_paths.push_back(path + AZStd::to_string(number) + "_" + AZStd::to_string(pathCount)); diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabCreateBenchmarks.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabCreateBenchmarks.cpp index b809a20944..12efea1cc8 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabCreateBenchmarks.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabCreateBenchmarks.cpp @@ -32,7 +32,7 @@ namespace Benchmark state.ResumeTiming(); - for (int instanceCounter = 0; instanceCounter < numInstances; ++instanceCounter) + for (unsigned int instanceCounter = 0; instanceCounter < numInstances; ++instanceCounter) { newInstances.push_back(m_prefabSystemComponent->CreatePrefab( { entities[instanceCounter] }, @@ -110,7 +110,7 @@ namespace Benchmark AZStd::vector> testInstances; testInstances.resize(numInstancesToAdd); - for (int instanceCounter = 0; instanceCounter < numInstancesToAdd; ++instanceCounter) + for (unsigned int instanceCounter = 0; instanceCounter < numInstancesToAdd; ++instanceCounter) { testInstances[instanceCounter] = (m_prefabSystemComponent->CreatePrefab( { entities[instanceCounter] } @@ -161,7 +161,7 @@ namespace Benchmark state.ResumeTiming(); - for (int instanceCounter = 0; instanceCounter < numInstances; ++instanceCounter) + for (unsigned int instanceCounter = 0; instanceCounter < numInstances; ++instanceCounter) { nestedInstanceRoot = m_prefabSystemComponent->CreatePrefab( {}, diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabInstantiateBenchmarks.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabInstantiateBenchmarks.cpp index 3e9f0ab08e..90ff30a30e 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabInstantiateBenchmarks.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabInstantiateBenchmarks.cpp @@ -33,7 +33,7 @@ namespace Benchmark state.ResumeTiming(); - for (int instanceCounter = 0; instanceCounter < numInstances; ++instanceCounter) + for (unsigned int instanceCounter = 0; instanceCounter < numInstances; ++instanceCounter) { newInstances[instanceCounter] = m_prefabSystemComponent->InstantiatePrefab(templateToInstantiateId); } diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabLoadBenchmarks.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabLoadBenchmarks.cpp index 7e64fa886c..a6c1e27caf 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabLoadBenchmarks.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabLoadBenchmarks.cpp @@ -29,7 +29,7 @@ namespace Benchmark state.ResumeTiming(); - for (int templateCounter = 0; templateCounter < numTemplates; ++templateCounter) + for (unsigned int templateCounter = 0; templateCounter < numTemplates; ++templateCounter) { m_prefabLoaderInterface->LoadTemplateFromFile(m_paths[templateCounter]); } diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/SpawnableCreateBenchmarks.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/SpawnableCreateBenchmarks.cpp index 9d35081895..54e53a6ebc 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/SpawnableCreateBenchmarks.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/SpawnableCreateBenchmarks.cpp @@ -33,7 +33,7 @@ namespace Benchmark AZStd::vector> spawnables; spawnables.reserve(numSpawnables); - for (int spwanableCounter = 0; spwanableCounter < numSpawnables; ++spwanableCounter) + for (unsigned int spwanableCounter = 0; spwanableCounter < numSpawnables; ++spwanableCounter) { AZStd::unique_ptr spawnable = AZStd::make_unique(); AzToolsFramework::Prefab::SpawnableUtils::CreateSpawnable(*spawnable, prefabDom); diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabInstanceToTemplatePropagatorTests.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabInstanceToTemplatePropagatorTests.cpp index 8379992553..ebe35a5402 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabInstanceToTemplatePropagatorTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabInstanceToTemplatePropagatorTests.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -18,6 +19,98 @@ namespace UnitTest { using PrefabInstanceToTemplateTests = PrefabTestFixture; + TEST_F(PrefabInstanceToTemplateTests, GenerateEntityDom_InvalidType_InvalidTypeSkipped) + { + const char* newEntityName = "New Entity"; + AZ::Entity* newEntity = CreateEntity(newEntityName, false); + ASSERT_TRUE(newEntity); + + // Add a component with a member that is missing reflection info + // and a member that is properly reflected + PrefabTestComponentWithUnReflectedTypeMember* newComponent = + newEntity->CreateComponent(); + + ASSERT_TRUE(newComponent); + + AZStd::unique_ptr prefabInstance = m_prefabSystemComponent->CreatePrefab({ newEntity }, {}, "test/path"); + ASSERT_TRUE(prefabInstance); + + PrefabDom entityDom; + m_instanceToTemplateInterface->GenerateDomForEntity(entityDom, *newEntity); + + auto componentListDom = entityDom.FindMember("Components"); + + // Confirm that there is only one component in the entityDom + ASSERT_NE(componentListDom, entityDom.MemberEnd()); + ASSERT_TRUE(componentListDom->value.IsObject()); + ASSERT_EQ(componentListDom->value.MemberCount(), 1); + + auto testComponentDom = componentListDom->value.MemberBegin(); + ASSERT_TRUE(testComponentDom->value.IsObject()); + + // Confirm that the componentDom does not contained the invalid UnReflectedType + // We want to skip over it and produce a best effort entityDom + auto unReflectedTypeDom = testComponentDom->value.FindMember("UnReflectedType"); + ASSERT_EQ(unReflectedTypeDom, testComponentDom->value.MemberEnd()); + + // Confirm the presence of the valid ReflectedType + auto reflectedTypeDom = testComponentDom->value.FindMember("ReflectedType"); + ASSERT_NE(reflectedTypeDom, testComponentDom->value.MemberEnd()); + + // Confirm the reflected type has the correct type and value + ASSERT_TRUE(reflectedTypeDom->value.IsInt()); + EXPECT_EQ(reflectedTypeDom->value.GetInt(), newComponent->m_reflectedType); + } + + TEST_F(PrefabInstanceToTemplateTests, GenerateInstanceDom_InvalidType_InvalidTypeSkipped) + { + const char* newEntityName = "New Entity"; + AZ::Entity* newEntity = CreateEntity(newEntityName, false); + ASSERT_TRUE(newEntity); + + // Add a component with a member that is missing reflection info + // and a member that is properly reflected + PrefabTestComponentWithUnReflectedTypeMember* newComponent = + newEntity->CreateComponent(); + + ASSERT_TRUE(newComponent); + + AZStd::unique_ptr prefabInstance = m_prefabSystemComponent->CreatePrefab({ newEntity }, {}, "test/path"); + ASSERT_TRUE(prefabInstance); + + PrefabDom instanceDom; + m_instanceToTemplateInterface->GenerateDomForInstance(instanceDom, *prefabInstance); + + // Acquire the entity out of the instanceDom + auto entitiesDom = instanceDom.FindMember(PrefabDomUtils::EntitiesName); + ASSERT_NE(entitiesDom, instanceDom.MemberEnd()); + ASSERT_EQ(entitiesDom->value.MemberCount(), 1); + + auto entityDom = entitiesDom->value.MemberBegin(); + auto componentListDom = entityDom->value.FindMember("Components"); + + // Confirm that there is only one component in the entityDom + ASSERT_NE(componentListDom, entityDom->value.MemberEnd()); + ASSERT_TRUE(componentListDom->value.IsObject()); + ASSERT_EQ(componentListDom->value.MemberCount(), 1); + + auto testComponentDom = componentListDom->value.MemberBegin(); + ASSERT_TRUE(testComponentDom->value.IsObject()); + + // Confirm that the componentDom does not contained the invalid UnReflectedType + // We want to skip over it and produce a best effort entityDom + auto unReflectedTypeDom = testComponentDom->value.FindMember("UnReflectedType"); + ASSERT_EQ(unReflectedTypeDom, testComponentDom->value.MemberEnd()); + + // Confirm the presence of the valid ReflectedType + auto reflectedTypeDom = testComponentDom->value.FindMember("ReflectedType"); + ASSERT_NE(reflectedTypeDom, testComponentDom->value.MemberEnd()); + + // Confirm the reflected type has the correct type and value + ASSERT_TRUE(reflectedTypeDom->value.IsInt()); + EXPECT_EQ(reflectedTypeDom->value.GetInt(), newComponent->m_reflectedType); + } + TEST_F(PrefabInstanceToTemplateTests, PrefabUpdateTemplate_UpdateEntityOnInstance) { //create template with single entity diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestComponent.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestComponent.cpp index 8f7ee398a0..5d29b179c4 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestComponent.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestComponent.cpp @@ -28,4 +28,18 @@ namespace UnitTest : m_boolProperty(boolProperty) { } + + void PrefabTestComponentWithUnReflectedTypeMember::Reflect(AZ::ReflectContext* reflection) + { + AZ::SerializeContext* serializeContext = AZ::RttiCast(reflection); + + // We reflect our member but not its type this will result in missing reflection data + // when we try to store or load this field + if (serializeContext) + { + serializeContext->Class() + ->Field("UnReflectedType", &PrefabTestComponentWithUnReflectedTypeMember::m_unReflectedType) + ->Field("ReflectedType", &PrefabTestComponentWithUnReflectedTypeMember::m_reflectedType); + } + } } diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestComponent.h b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestComponent.h index 0ed8f6d9c9..e0e986b7db 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestComponent.h +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestComponent.h @@ -27,4 +27,22 @@ namespace UnitTest int m_intProperty = 0; AZ::EntityId m_entityIdProperty; }; + + class UnReflectedType + { + public: + AZ_TYPE_INFO(UnReflectedType, "{FB65262C-CE9A-45CA-99EB-4DDCB19B32DB}"); + int m_unReflectedInt = 42; + }; + + class PrefabTestComponentWithUnReflectedTypeMember + : public AzToolsFramework::Components::EditorComponentBase + { + public: + AZ_EDITOR_COMPONENT(PrefabTestComponentWithUnReflectedTypeMember, "{726281E1-8E47-46AB-8018-D3F4BA823D74}"); + static void Reflect(AZ::ReflectContext* reflection); + + UnReflectedType m_unReflectedType; + int m_reflectedType = 52; + }; } diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestFixture.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestFixture.cpp index ded88d2da3..ed30de09c4 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestFixture.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestFixture.cpp @@ -49,6 +49,7 @@ namespace UnitTest EXPECT_TRUE(m_instanceToTemplateInterface); GetApplication()->RegisterComponentDescriptor(PrefabTestComponent::CreateDescriptor()); + GetApplication()->RegisterComponentDescriptor(PrefabTestComponentWithUnReflectedTypeMember::CreateDescriptor()); } AZStd::unique_ptr PrefabTestFixture::CreateTestApplication() diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUpdateWithPatchesTests.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUpdateWithPatchesTests.cpp index 72e88c6336..c17763f778 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUpdateWithPatchesTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUpdateWithPatchesTests.cpp @@ -136,7 +136,10 @@ namespace UnitTest PrefabDomValueReference wheelEntityComponentBoolPropertyValue = PrefabDomUtils::FindPrefabDomValue(wheelEntityComponentValue->get(), PrefabTestDomUtils::BoolPropertyName); - ASSERT_FALSE(wheelEntityComponentBoolPropertyValue.has_value()); + + ASSERT_TRUE(wheelEntityComponentBoolPropertyValue.has_value()); + ASSERT_TRUE(wheelEntityComponentBoolPropertyValue->get().IsBool()); + ASSERT_FALSE(wheelEntityComponentBoolPropertyValue->get().GetBool()); // Validate that the axles under the car have the same DOM as the axle template. PrefabTestDomUtils::ValidatePrefabDomInstances(axleInstanceAliasesUnderCar, carTemplateDom, axleTemplateDom); diff --git a/Code/Framework/AzToolsFramework/Tests/SpinBoxTests.cpp b/Code/Framework/AzToolsFramework/Tests/SpinBoxTests.cpp index eb09c68cee..a88cb68638 100644 --- a/Code/Framework/AzToolsFramework/Tests/SpinBoxTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/SpinBoxTests.cpp @@ -245,12 +245,15 @@ namespace UnitTest { using testing::StrEq; + QLocale testLocale{ QLocale() }; + QString testString = "10" + QString(testLocale.decimalPoint()) + "0"; + m_doubleSpinBox->setSuffix("m"); m_doubleSpinBox->setValue(10.0); // test internal logic (textFromValue() calls private StringValue()) QString value = m_doubleSpinBox->textFromValue(10.0); - EXPECT_THAT(value.toUtf8().constData(), StrEq("10.0")); + EXPECT_THAT(value.toUtf8().constData(), testString); m_doubleSpinBox->setFocus(); EXPECT_THAT(m_doubleSpinBox->suffix().toUtf8().constData(), StrEq("")); @@ -293,31 +296,44 @@ namespace UnitTest TEST_F(SpinBoxFixture, SpinBoxCheckHighValueTruncatesCorrectly) { - QString value = setupTruncationTest("0.9999999"); + QLocale testLocale{ QLocale() }; + QString testString = "0" + QString(testLocale.decimalPoint()) + "9999999"; + QString value = setupTruncationTest(testString); - EXPECT_TRUE(value == "0.999"); + testString = "0" + QString(testLocale.decimalPoint()) + "999"; + EXPECT_TRUE(value == testString); } TEST_F(SpinBoxFixture, SpinBoxCheckLowValueTruncatesCorrectly) { - QString value = setupTruncationTest("0.0000001"); + QLocale testLocale{ QLocale() }; + QString testString = "0" + QString(testLocale.decimalPoint()) + "0000001"; + QString value = setupTruncationTest(testString); - EXPECT_TRUE(value == "0.0"); + testString = "0" + QString(testLocale.decimalPoint()) + "0"; + EXPECT_TRUE(value == testString); } TEST_F(SpinBoxFixture, SpinBoxCheckBugValuesTruncatesCorrectly) { - QString value = setupTruncationTest("0.12395"); + QLocale testLocale{ QLocale() }; + QString testString = "0" + QString(testLocale.decimalPoint()) + "12395"; + QString value = setupTruncationTest(testString); - EXPECT_TRUE(value == "0.123"); + testString = "0" + QString(testLocale.decimalPoint()) + "123"; + EXPECT_TRUE(value == testString); - value = setupTruncationTest("0.94496"); + testString = "0" + QString(testLocale.decimalPoint()) + "94496"; + value = setupTruncationTest(testString); - EXPECT_TRUE(value == "0.944"); + testString = "0" + QString(testLocale.decimalPoint()) + "944"; + EXPECT_TRUE(value == testString); - value = setupTruncationTest("0.0009999"); + testString = "0" + QString(testLocale.decimalPoint()) + "0009999"; + value = setupTruncationTest(testString); - EXPECT_TRUE(value == "0.0"); + testString = "0" + QString(testLocale.decimalPoint()) + "0"; + EXPECT_TRUE(value == testString); } } // namespace UnitTest diff --git a/Code/Framework/Crcfix/crcfix.cpp b/Code/Framework/Crcfix/crcfix.cpp index ce599e9a63..778b9e2185 100644 --- a/Code/Framework/Crcfix/crcfix.cpp +++ b/Code/Framework/Crcfix/crcfix.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -23,11 +24,11 @@ int g_longestFixTimeMs = 0; class Filename { - char fullpath[MAX_PATH]; - char drive[_MAX_DRIVE]; - char dir[_MAX_DIR]; - char fname[_MAX_FNAME]; - char ext[_MAX_EXT]; + wchar_t fullpath[MAX_PATH]; + wchar_t drive[_MAX_DRIVE]; + wchar_t dir[_MAX_DIR]; + wchar_t fname[_MAX_FNAME]; + wchar_t ext[_MAX_EXT]; public: Filename() @@ -35,21 +36,21 @@ public: fullpath[0] = drive[0] = dir[0] = fname[0] = ext[0] = 0; } - Filename(const AZStd::string& filename) + Filename(const AZStd::wstring& filename) { - _splitpath(filename.c_str(), drive, dir, fname, ext); - strcpy(fullpath, filename.c_str()); + _wsplitpath(filename.c_str(), drive, dir, fname, ext); + wcscpy(fullpath, filename.c_str()); } - void SetExt(const char* pExt) { strcpy(ext, pExt); _makepath(fullpath, drive, dir, fname, pExt); } - const char* GetFullPath() const { return fullpath; } - bool Exists() const { return _access(fullpath, 0) == 0; } - bool IsReadOnly() const { return _access(fullpath, 6) == -1; } - bool SetReadOnly() const { return _chmod(fullpath, _S_IREAD) == 0; } - bool SetWritable() const { return _chmod(fullpath, _S_IREAD | _S_IWRITE) == 0; } - bool Delete() const { return remove(fullpath) == 0; } - bool Rename(const char* fn2) const { return MoveFileEx(fullpath, fn2, MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING) == 0; } - bool Copy(const char* dest) const { return ::CopyFileA(fullpath, dest, FALSE) == TRUE; } + void SetExt(const wchar_t* pExt) { wcscpy(ext, pExt); _wmakepath(fullpath, drive, dir, fname, pExt); } + const wchar_t* GetFullPath() const { return fullpath; } + bool Exists() const { return _waccess(fullpath, 0) == 0; } + bool IsReadOnly() const { return _waccess(fullpath, 6) == -1; } + bool SetReadOnly() const { return _wchmod(fullpath, _S_IREAD) == 0; } + bool SetWritable() const { return _wchmod(fullpath, _S_IREAD | _S_IWRITE) == 0; } + bool Delete() const { return _wremove(fullpath) == 0; } + bool Rename(const wchar_t* fn2) const{ return MoveFileEx(fullpath, fn2, MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING) == 0; } + bool Copy(const wchar_t* dest) const { return ::CopyFile(fullpath, dest, FALSE) == TRUE; } }; class CRCfix @@ -64,7 +65,7 @@ public: int Fix(Filename srce); }; -void FixFiles(const AZStd::string& dir, const AZStd::string& files, FILETIME* pLastRun, bool verbose, int& nFound, int& nProcessed, int& nFixed, int& nFailed) +void FixFiles(const AZStd::wstring& dir, const AZStd::wstring& files, FILETIME* pLastRun, bool verbose, int& nFound, int& nProcessed, int& nFixed, int& nFailed) { CRCfix fixer; WIN32_FIND_DATA wfd; @@ -78,14 +79,14 @@ void FixFiles(const AZStd::string& dir, const AZStd::string& files, FILETIME* pL { if (verbose) { - AZ_TracePrintf("CrcFix", "\tProcessing %s ...", wfd.cFileName); + AZ_TracePrintf("CrcFix", "\tProcessing %ls ...", wfd.cFileName); } nFound++; int n = 0; if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0 && (!pLastRun || CompareFileTime(pLastRun, &wfd.ftLastWriteTime) <= 0)) { - n = fixer.Fix(Filename(dir + "\\" + wfd.cFileName)); + n = fixer.Fix(Filename(dir + L"\\" + wfd.cFileName)); nProcessed++; } if (n < 0) @@ -110,11 +111,11 @@ void FixFiles(const AZStd::string& dir, const AZStd::string& files, FILETIME* pL FindClose(hFind); } -void FixDirectories(const AZStd::string& dirs, const AZStd::string& files, FILETIME* pLastRun, bool verbose, int& nFound, int& nProcessed, int& nFixed, int& nFailed) +void FixDirectories(const AZStd::wstring& dirs, const AZStd::wstring& files, FILETIME* pLastRun, bool verbose, int& nFound, int& nProcessed, int& nFixed, int& nFailed) { if (verbose) { - AZ_TracePrintf("CrcFix", "Processing %s ...\n", dirs.c_str()); + AZ_TracePrintf("CrcFix", "Processing %ls ...\n", dirs.c_str()); } // do files @@ -123,7 +124,7 @@ void FixDirectories(const AZStd::string& dirs, const AZStd::string& files, FILET // do folders WIN32_FIND_DATA wfd; HANDLE hFind; - hFind = FindFirstFile((dirs + "\\*").c_str(), &wfd); + hFind = FindFirstFile((dirs + L"\\*").c_str(), &wfd); if (hFind != INVALID_HANDLE_VALUE) { do @@ -134,7 +135,7 @@ void FixDirectories(const AZStd::string& dirs, const AZStd::string& files, FILET { continue; } - FixDirectories(AZStd::string(dirs + "\\" + wfd.cFileName), files, pLastRun, verbose, nFound, nProcessed, nFixed, nFailed); + FixDirectories(AZStd::wstring(dirs + L"\\" + wfd.cFileName), files, pLastRun, verbose, nFound, nProcessed, nFixed, nFailed); } } while (FindNextFile(hFind, &wfd)); } @@ -161,9 +162,9 @@ int main(int argc, char* argv[]) char root[MAX_PATH]; AZ::Utils::GetExecutableDirectory(root, MAX_PATH); - AZStd::vector entries; + AZStd::vector entries; - const char* logfilename = NULL; + AZStd::wstring logfilename; FILETIME lastRun; FILETIME* pLastRun = NULL; @@ -176,10 +177,12 @@ int main(int argc, char* argv[]) { continue; } + AZStd::wstring pArgW; + AZStd::to_wstring(pArgW, pArg); if (_strnicmp(pArg, "-log:", 5) == 0) { - logfilename = pArg + 5; - HANDLE hFile = CreateFile(logfilename, 0, 0, NULL, OPEN_EXISTING, 0, NULL); + logfilename.assign(pArgW.begin() + 5, pArgW.end()); + HANDLE hFile = CreateFile(logfilename.data(), 0, 0, NULL, OPEN_EXISTING, 0, NULL); if (hFile != INVALID_HANDLE_VALUE) { pLastRun = &lastRun; @@ -193,7 +196,7 @@ int main(int argc, char* argv[]) } else { - entries.push_back(AZStd::string(pArg)); + entries.emplace_back(AZStd::move(pArgW)); } } @@ -202,10 +205,10 @@ int main(int argc, char* argv[]) int nProcessed = 0; int nFixed = 0; int nFailed = 0; - for (AZStd::vector::const_iterator iEntry = entries.begin(); iEntry != entries.end(); ++iEntry) + for (AZStd::vector::const_iterator iEntry = entries.begin(); iEntry != entries.end(); ++iEntry) { - AZStd::string entry = (iEntry->at(0) == '\\' || iEntry->find(":") != iEntry->npos) ? *iEntry : AZStd::string(root) + "\\" + *iEntry; - AZStd::string::size_type split = entry.find("*\\"); + AZStd::wstring entry = (iEntry->at(0) == L'\\' || iEntry->find(L":") != iEntry->npos) ? *iEntry : AZStd::wstring(root) + L"\\" + *iEntry; + AZStd::wstring::size_type split = entry.find(L"*\\"); bool doSubdirs = split != entry.npos; if (doSubdirs) { @@ -213,7 +216,7 @@ int main(int argc, char* argv[]) } else { - split = entry.rfind("\\"); + split = entry.rfind(L"\\"); if (split == entry.npos) { split = 0; @@ -223,9 +226,9 @@ int main(int argc, char* argv[]) } // update timestamp - if (logfilename) + if (!logfilename.empty()) { - HANDLE hFile = CreateFile(logfilename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); + HANDLE hFile = CreateFile(logfilename.data(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); GetSystemTimeAsFileTime(&lastRun); SetFileTime(hFile, NULL, NULL, &lastRun); char log[1024]; @@ -383,12 +386,12 @@ int CRCfix::Fix(Filename srce) bool changed = false; Filename dest(srce); - dest.SetExt("xxx"); + dest.SetExt(L"xxx"); linenum = 0; - FILE* infile = fopen(srce.GetFullPath(), "r"); - FILE* outfile = fopen(dest.GetFullPath(), "w"); + FILE* infile = _wfopen(srce.GetFullPath(), L"r"); + FILE* outfile = _wfopen(dest.GetFullPath(), L"w"); if (!infile || !outfile) { @@ -475,7 +478,7 @@ int CRCfix::Fix(Filename srce) if (changed) { Filename backup(srce); - backup.SetExt("crcfix_old"); + backup.SetExt(L"crcfix_old"); if (backup.Exists()) { @@ -486,7 +489,7 @@ int CRCfix::Fix(Filename srce) if (!srce.Copy(backup.GetFullPath())) { - AZ_TracePrintf("CrcFix", "Failed to copy %s to %s\n", srce, backup); + AZ_TracePrintf("CrcFix", "Failed to copy %ls to %ls\n", srce, backup); int dt = static_cast(AZStd::chrono::milliseconds(AZStd::chrono::system_clock::now() - startTime).count()); g_totalFixTimeMs += dt; @@ -500,7 +503,7 @@ int CRCfix::Fix(Filename srce) if (!dest.Rename(srce.GetFullPath())) { - AZ_TracePrintf("CrcFix", "Failed to rename %s to %s\n", dest, srce); + AZ_TracePrintf("CrcFix", "Failed to rename %ls to %ls\n", dest, srce); int dt = static_cast(AZStd::chrono::milliseconds(AZStd::chrono::system_clock::now() - startTime).count()); g_totalFixTimeMs += dt; @@ -514,7 +517,7 @@ int CRCfix::Fix(Filename srce) if (!backup.Delete()) { - AZ_TracePrintf("CrcFix", "Failed to delete %s\n", backup); + AZ_TracePrintf("CrcFix", "Failed to delete %ls\n", backup); } } else diff --git a/Code/Framework/GridMate/GridMate/Carrier/Carrier.cpp b/Code/Framework/GridMate/GridMate/Carrier/Carrier.cpp index 3c3c1183e4..0285a7fc02 100644 --- a/Code/Framework/GridMate/GridMate/Carrier/Carrier.cpp +++ b/Code/Framework/GridMate/GridMate/Carrier/Carrier.cpp @@ -417,12 +417,12 @@ namespace GridMate { GM_CLASS_ALLOCATOR(Connection); // make a pool and use it... - Connection(CarrierThread* threadOwner, const string& address); + Connection(CarrierThread* threadOwner, const AZStd::string& address); ~Connection(); CarrierThread* m_threadOwner; ///< Pointer to the carrier thread that operates with this connection. AZStd::atomic m_threadConn; ///< Pointer to a thread connection. You can use it in the main thread only for a reference. - string m_fullAddress; ///< Connection full address. + AZStd::string m_fullAddress; ///< Connection full address. Carrier::ConnectionStates m_state; @@ -604,7 +604,7 @@ namespace GridMate Connection* m_connection; ThreadConnection* m_threadConnection; - string m_newConnectionAddress; + AZStd::string m_newConnectionAddress; CarrierErrorCode m_errorCode; AZ::u32 m_newRateBytesPerSec; ///< new send rate AZStd::vector > m_ackCallbacks; @@ -999,7 +999,7 @@ namespace GridMate /// Connect with host and port. This is ASync operation, the connection is active after OnConnectionEstablished is called. ConnectionID Connect(const char* hostAddress, unsigned int port) override; /// Connect with internal address format. This is ASync operation, the connection is active after OnConnectionEstablished is called. - ConnectionID Connect(const string& address) override; + ConnectionID Connect(const AZStd::string& address) override; /// Request a disconnect procedure. This is ASync operation, the connection is closed after OnDisconnect is called. void Disconnect(ConnectionID id) override; @@ -1007,7 +1007,7 @@ namespace GridMate unsigned int GetMessageMTU() override { return m_maxMsgDataSizeBytes; } - string ConnectionToAddress(ConnectionID id) override; + AZStd::string ConnectionToAddress(ConnectionID id) override; void SendWithCallback(const char* data, unsigned int dataSize, AZStd::unique_ptr ackCallback, ConnectionID target = AllConnections, DataReliability reliability = SEND_RELIABLE, DataPriority priority = PRIORITY_NORMAL, unsigned char channel = 0) override; void Send(const char* data, unsigned int dataSize, ConnectionID target = AllConnections, DataReliability reliability = SEND_RELIABLE, DataPriority priority = PRIORITY_NORMAL, unsigned char channel = 0) override @@ -1118,7 +1118,7 @@ using namespace GridMate; // Connection ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// -Connection::Connection(CarrierThread* threadOwner, const string& address) +Connection::Connection(CarrierThread* threadOwner, const AZStd::string& address) : m_threadOwner(threadOwner) , m_threadConn(NULL) , m_fullAddress(address) @@ -3740,7 +3740,7 @@ CarrierImpl::Connect(const char* hostAddress, unsigned int port) // [1/12/2011] //========================================================================= ConnectionID -CarrierImpl::Connect(const string& address) +CarrierImpl::Connect(const AZStd::string& address) { // check if we don't have it in the list. for(auto& i : m_connections) @@ -3902,10 +3902,10 @@ CarrierImpl::DeleteConnection(Connection* conn, CarrierDisconnectReason reason) // Carrier // [9/14/2010] //========================================================================= -string +AZStd::string CarrierImpl::ConnectionToAddress(ConnectionID id) { - string str; + AZStd::string str; AZ_Assert(id != InvalidConnectionID, "Invalid connection id!"); if (id != InvalidConnectionID) { @@ -4911,7 +4911,7 @@ DefaultCarrier::Create(const CarrierDesc& desc, IGridMate* gridMate) // ReasonToString // [4/11/2011] //========================================================================= -string +AZStd::string CarrierEventsBase::ReasonToString(CarrierDisconnectReason reason) { const char* reasonStr = 0; @@ -4951,5 +4951,5 @@ CarrierEventsBase::ReasonToString(CarrierDisconnectReason reason) reasonStr = "Unknown reason"; } - return string(reasonStr); + return AZStd::string(reasonStr); } diff --git a/Code/Framework/GridMate/GridMate/Carrier/Carrier.h b/Code/Framework/GridMate/GridMate/Carrier/Carrier.h index 5bfa621af1..94c31ed6d2 100644 --- a/Code/Framework/GridMate/GridMate/Carrier/Carrier.h +++ b/Code/Framework/GridMate/GridMate/Carrier/Carrier.h @@ -9,7 +9,6 @@ #define GM_CARRIER_H #include -#include #include #include #include @@ -88,7 +87,7 @@ namespace GridMate /// Connect with host and port. This is ASync operation, the connection is active after OnConnectionEstablished is called. virtual ConnectionID Connect(const char* hostAddress, unsigned int port) = 0; /// Connect with internal address format. This is ASync operation, the connection is active after OnConnectionEstablished is called. - virtual ConnectionID Connect(const string& address) = 0; + virtual ConnectionID Connect(const AZStd::string& address) = 0; /// Request a disconnect procedure. This is ASync operation, the connection is closed after OnDisconnect is called. virtual void Disconnect(ConnectionID id) = 0; @@ -100,7 +99,7 @@ namespace GridMate /// Returns maximum message size (with splitting or without). Splitting will make your message reliable, which might not be optimal for Unreliable messages. It's better to send two unreliable. //virtual unsigned int GetMaxMessageSize(bool withSplitting = true) = 0; - virtual string ConnectionToAddress(ConnectionID id) = 0; + virtual AZStd::string ConnectionToAddress(ConnectionID id) = 0; /** * Sends buffer with an ACK callback. When the transport layer recieves an ACK it will run the callback. @@ -401,7 +400,7 @@ namespace GridMate public: virtual ~CarrierEventsBase() {} - string ReasonToString(CarrierDisconnectReason reason); + AZStd::string ReasonToString(CarrierDisconnectReason reason); }; class CarrierEvents @@ -517,7 +516,7 @@ namespace GridMate // Traffic control /// Called every second when you update last second statistics - virtual void OnUpdateStatistics(const GridMate::string& address, const TrafficControl::Statistics& lastSecond, const TrafficControl::Statistics& lifeTime, const TrafficControl::Statistics& effectiveLastSecond, const TrafficControl::Statistics& effectiveLifeTime) = 0; + virtual void OnUpdateStatistics(const AZStd::string& address, const TrafficControl::Statistics& lastSecond, const TrafficControl::Statistics& lifeTime, const TrafficControl::Statistics& effectiveLastSecond, const TrafficControl::Statistics& effectiveLifeTime) = 0; // Simulator /// Enable/Disable diff --git a/Code/Framework/GridMate/GridMate/Carrier/DefaultHandshake.cpp b/Code/Framework/GridMate/GridMate/Carrier/DefaultHandshake.cpp index bc657becbc..58436bb757 100644 --- a/Code/Framework/GridMate/GridMate/Carrier/DefaultHandshake.cpp +++ b/Code/Framework/GridMate/GridMate/Carrier/DefaultHandshake.cpp @@ -98,7 +98,7 @@ DefaultHandshake::OnConfirmAck(ConnectionID id, ReadBuffer& rb) // [11/5/2010] //========================================================================= bool -DefaultHandshake::OnNewConnection(const string& address) +DefaultHandshake::OnNewConnection(const AZStd::string& address) { (void)address; return true; /// We don't have a ban list yet diff --git a/Code/Framework/GridMate/GridMate/Carrier/DefaultHandshake.h b/Code/Framework/GridMate/GridMate/Carrier/DefaultHandshake.h index 0b9240dfa3..9225cca8d7 100644 --- a/Code/Framework/GridMate/GridMate/Carrier/DefaultHandshake.h +++ b/Code/Framework/GridMate/GridMate/Carrier/DefaultHandshake.h @@ -9,6 +9,7 @@ #define GM_DEFAULT_HANDSHAKE_H #include +#include namespace GridMate { @@ -47,7 +48,7 @@ namespace GridMate */ virtual bool OnConfirmAck(ConnectionID id, ReadBuffer& rb); /// Return true if you want to reject early reject a connection. - virtual bool OnNewConnection(const string& address); + virtual bool OnNewConnection(const AZStd::string& address); /// Called when we close a connection. virtual void OnDisconnect(ConnectionID id); /// Return timeout in milliseconds of the handshake procedure. diff --git a/Code/Framework/GridMate/GridMate/Carrier/DefaultTrafficControl.cpp b/Code/Framework/GridMate/GridMate/Carrier/DefaultTrafficControl.cpp index 5da3c784ff..f9280d9918 100644 --- a/Code/Framework/GridMate/GridMate/Carrier/DefaultTrafficControl.cpp +++ b/Code/Framework/GridMate/GridMate/Carrier/DefaultTrafficControl.cpp @@ -12,6 +12,7 @@ #include #include +#include using namespace GridMate; diff --git a/Code/Framework/GridMate/GridMate/Carrier/DefaultTrafficControl.h b/Code/Framework/GridMate/GridMate/Carrier/DefaultTrafficControl.h index 525009b015..259c619f53 100644 --- a/Code/Framework/GridMate/GridMate/Carrier/DefaultTrafficControl.h +++ b/Code/Framework/GridMate/GridMate/Carrier/DefaultTrafficControl.h @@ -12,6 +12,8 @@ #include +#include + namespace GridMate { /** @@ -145,7 +147,7 @@ namespace GridMate StatisticData m_sdEffectiveLastSecond; ///< Last second statistics for effective data. StatisticData m_sdEffectiveCurrentSecond; ///< Elapsing second statistics for effective data. - string m_address; ///< Full address for this connection. (we need for debug only) + AZStd::string m_address; ///< Full address for this connection. (we need for debug only) unsigned int m_recvPacketAllowance; ///< Current allowance for number of incoming packets bool m_canReceiveData; ///< Able to receive data on this connection diff --git a/Code/Framework/GridMate/GridMate/Carrier/Driver.h b/Code/Framework/GridMate/GridMate/Carrier/Driver.h index 84e43b5acf..d6d47fc491 100644 --- a/Code/Framework/GridMate/GridMate/Carrier/Driver.h +++ b/Code/Framework/GridMate/GridMate/Carrier/Driver.h @@ -10,10 +10,9 @@ #include -#include - #include #include +#include namespace GridMate { @@ -139,8 +138,8 @@ namespace GridMate /// @{ Address conversion functionality. They MUST implemented thread safe. Generally this is not a problem since they just part local data. /// Create address from ip and port. If ip == NULL we will assign a broadcast address. - virtual string IPPortToAddress(const char* ip, unsigned int port) const = 0; - virtual bool AddressToIPPort(const string& address, string& ip, unsigned int& port) const = 0; + virtual AZStd::string IPPortToAddress(const char* ip, unsigned int port) const = 0; + virtual bool AddressToIPPort(const AZStd::string& address, AZStd::string& ip, unsigned int& port) const = 0; /// @} /** @@ -150,7 +149,7 @@ namespace GridMate * \note Driver address allocates internal resources, use it only when you intend to communicate. Otherwise operate with * the string address. */ - virtual AZStd::intrusive_ptr CreateDriverAddress(const string& address) = 0; + virtual AZStd::intrusive_ptr CreateDriverAddress(const AZStd::string& address) = 0; /** * Returns true if the driver can accept new data (ex, has buffer space). @@ -188,11 +187,11 @@ namespace GridMate virtual ~DriverAddress() {} - virtual string ToString() const = 0; + virtual AZStd::string ToString() const = 0; - virtual string ToAddress() const = 0; + virtual AZStd::string ToAddress() const = 0; - virtual string GetIP() const = 0; + virtual AZStd::string GetIP() const = 0; virtual unsigned int GetPort() const = 0; diff --git a/Code/Framework/GridMate/GridMate/Carrier/Handshake.h b/Code/Framework/GridMate/GridMate/Carrier/Handshake.h index 5d06f2f1b8..5f67b6637c 100644 --- a/Code/Framework/GridMate/GridMate/Carrier/Handshake.h +++ b/Code/Framework/GridMate/GridMate/Carrier/Handshake.h @@ -10,7 +10,7 @@ #include #include -#include +#include namespace GridMate { @@ -53,7 +53,7 @@ namespace GridMate */ virtual bool OnConfirmAck(ConnectionID id, ReadBuffer& rb) = 0; /// Return true if you want to reject early reject a connection. - virtual bool OnNewConnection(const string& address) = 0; + virtual bool OnNewConnection(const AZStd::string& address) = 0; /// Called when we close a connection. virtual void OnDisconnect(ConnectionID id) = 0; /// Return timeout in milliseconds of the handshake procedure. diff --git a/Code/Framework/GridMate/GridMate/Carrier/SecureSocketDriver.cpp b/Code/Framework/GridMate/GridMate/Carrier/SecureSocketDriver.cpp index 7d0d5644b3..031e8561ec 100644 --- a/Code/Framework/GridMate/GridMate/Carrier/SecureSocketDriver.cpp +++ b/Code/Framework/GridMate/GridMate/Carrier/SecureSocketDriver.cpp @@ -1712,7 +1712,7 @@ namespace GridMate } // Calculate HMAC of buffer using the secret and peer address - GridMate::string addrStr = endpoint->ToAddress(); + AZStd::string addrStr = endpoint->ToAddress(); unsigned char result[EVP_MAX_MD_SIZE]; unsigned int resultLen = 0; HMAC(EVP_sha1(), m_cookieSecret.m_currentSecret, sizeof(m_cookieSecret.m_currentSecret), @@ -1745,7 +1745,7 @@ namespace GridMate } // Calculate HMAC of buffer using the secret and peer address - GridMate::string addrStr = endpoint->ToAddress(); + AZStd::string addrStr = endpoint->ToAddress(); unsigned char result[EVP_MAX_MD_SIZE]; unsigned int resultLen = 0; HMAC(EVP_sha1(), m_cookieSecret.m_currentSecret, COOKIE_SECRET_LENGTH, @@ -1809,7 +1809,7 @@ namespace GridMate #ifdef AZ_DebugUseSocketDebugLog if (handshake) { - GridMate::string line = GridMate::string::format("%lld | [%08x] RawRecv %s size %d connection exists\n", AZStd::chrono::system_clock::now().time_since_epoch().count(), this, type, bytesReceived); + AZStd::string line = AZStd::string::format("%lld | [%08x] RawRecv %s size %d connection exists\n", AZStd::chrono::system_clock::now().time_since_epoch().count(), this, type, bytesReceived); connection->m_dbgLog += line; } #endif diff --git a/Code/Framework/GridMate/GridMate/Carrier/SecureSocketDriver.h b/Code/Framework/GridMate/GridMate/Carrier/SecureSocketDriver.h index 529ccea408..76b7958085 100644 --- a/Code/Framework/GridMate/GridMate/Carrier/SecureSocketDriver.h +++ b/Code/Framework/GridMate/GridMate/Carrier/SecureSocketDriver.h @@ -23,7 +23,7 @@ //#define AZ_DebugSecureSocket AZ_TracePrintf //#define AZ_DebugSecureSocketConnection(window, fmt, ...) \ //{\ -// GridMate::string line = GridMate::string::format(fmt, __VA_ARGS__);\ +// AZStd::string line = AZStd::string::format(fmt, __VA_ARGS__);\ // this->m_dbgLog += line;\ //} @@ -226,7 +226,7 @@ namespace GridMate int m_dbgDgramsReceived; int m_dbgPort; #ifdef AZ_DebugUseSocketDebugLog - GridMate::string m_dbgLog; + AZStd::string m_dbgLog; #endif }; @@ -262,7 +262,7 @@ namespace GridMate AZ::u32 m_maxTempBufferSize; AZStd::queue m_globalInQueue; AZStd::unordered_map m_connections; - AZStd::unordered_map m_ipToNumConnections; + AZStd::unordered_map m_ipToNumConnections; SecureSocketDesc m_desc; AZStd::chrono::system_clock::time_point m_lastTimerCheck; ///Time last timers were checked }; diff --git a/Code/Framework/GridMate/GridMate/Carrier/SocketDriver.cpp b/Code/Framework/GridMate/GridMate/Carrier/SocketDriver.cpp index b75de6f383..6acf778798 100644 --- a/Code/Framework/GridMate/GridMate/Carrier/SocketDriver.cpp +++ b/Code/Framework/GridMate/GridMate/Carrier/SocketDriver.cpp @@ -18,7 +18,6 @@ //#define AZ_LOG_UNBOUND_SEND_RECEIVE #include -#include #include #include @@ -498,7 +497,7 @@ namespace GridMate } } - SocketDriverAddress::SocketDriverAddress(Driver* driver, const string& ip, unsigned int port) + SocketDriverAddress::SocketDriverAddress(Driver* driver, const AZStd::string& ip, unsigned int port) : DriverAddress(driver) { AZ_Assert(!ip.empty(), "Invalid address string!"); @@ -575,7 +574,7 @@ namespace GridMate return !(*this == rhs); } - string SocketDriverAddress::ToString() const + AZStd::string SocketDriverAddress::ToString() const { char ip[64]; unsigned short port; @@ -590,15 +589,15 @@ namespace GridMate port = ntohs(m_sockAddr.sin_port); } - return string::format("%s|%d", ip, port); + return AZStd::string::format("%s|%d", ip, port); } - string SocketDriverAddress::ToAddress() const + AZStd::string SocketDriverAddress::ToAddress() const { return ToString(); } - string SocketDriverAddress::GetIP() const + AZStd::string SocketDriverAddress::GetIP() const { char ip[64]; if (m_sockAddr.sin_family == AF_INET6) @@ -609,7 +608,7 @@ namespace GridMate { inet_ntop(AF_INET, const_cast(reinterpret_cast(&m_sockAddr.sin_addr)), ip, AZ_ARRAY_SIZE(ip)); } - return string(ip); + return AZStd::string(ip); } unsigned int SocketDriverAddress::GetPort() const @@ -1144,11 +1143,11 @@ namespace GridMate // CreateSocketDriver // [3/4/2013] //========================================================================= - string + AZStd::string SocketDriverCommon::IPPortToAddressString(const char* ip, unsigned int port) { AZ_Assert(ip != nullptr, "Invalid address!"); - return string::format("%s|%d", ip, port); + return AZStd::string::format("%s|%d", ip, port); } //========================================================================= @@ -1156,17 +1155,17 @@ namespace GridMate // [3/4/2013] //========================================================================= bool - SocketDriverCommon::AddressStringToIPPort(const string& address, string& ip, unsigned int& port) + SocketDriverCommon::AddressStringToIPPort(const AZStd::string& address, AZStd::string& ip, unsigned int& port) { AZStd::size_t pos = address.find('|'); - AZ_Assert(pos != string::npos, "Invalid driver address!"); - if (pos == string::npos) + AZ_Assert(pos != AZStd::string::npos, "Invalid driver address!"); + if (pos == AZStd::string::npos) { return false; } - ip = string(address.begin(), address.begin() + pos); - port = AZStd::stoi(string(address.begin() + pos + 1, address.end())); + ip = AZStd::string(address.begin(), address.begin() + pos); + port = AZStd::stoi(AZStd::string(address.begin() + pos + 1, address.end())); return true; } @@ -1176,16 +1175,16 @@ namespace GridMate // [7/11/2013] //========================================================================= Driver::BSDSocketFamilyType - SocketDriverCommon::AddressFamilyType(const string& ip) + SocketDriverCommon::AddressFamilyType(const AZStd::string& ip) { // TODO: We can/should use inet_ntop() to detect the family type AZStd::size_t pos = ip.find("."); - if (pos != string::npos) + if (pos != AZStd::string::npos) { return BSD_AF_INET; } pos = ip.find("::"); - if (pos != string::npos) + if (pos != AZStd::string::npos) { return BSD_AF_INET6; } @@ -1198,13 +1197,13 @@ namespace GridMate ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// //========================================================================= - // CreateDriverAddress(const string&) + // CreateDriverAddress(const AZStd::string&) // [1/12/2011] //========================================================================= AZStd::intrusive_ptr - SocketDriver::CreateDriverAddress(const string& address) + SocketDriver::CreateDriverAddress(const AZStd::string& address) { - string ip; + AZStd::string ip; unsigned int port; if (!AddressToIPPort(address, ip, port)) { @@ -1243,7 +1242,7 @@ namespace GridMate namespace Utils { // \note function moved here to use addinfo when IPV6 is not in use, consider moving those definitions to a header file - bool GetIpByHostName(int familyType, const char* hostName, string& ip) + bool GetIpByHostName(int familyType, const char* hostName, AZStd::string& ip) { static const size_t kMaxLen = 64; // max length of ipv6 ip is 45 chars, so all ips should be able to fit in this buf char ipBuf[kMaxLen]; diff --git a/Code/Framework/GridMate/GridMate/Carrier/SocketDriver.h b/Code/Framework/GridMate/GridMate/Carrier/SocketDriver.h index bda135f532..835414b374 100644 --- a/Code/Framework/GridMate/GridMate/Carrier/SocketDriver.h +++ b/Code/Framework/GridMate/GridMate/Carrier/SocketDriver.h @@ -83,14 +83,14 @@ namespace GridMate SocketDriverAddress(Driver* driver); SocketDriverAddress(Driver* driver, const sockaddr* addr); - SocketDriverAddress(Driver* driver, const string& ip, unsigned int port); + SocketDriverAddress(Driver* driver, const AZStd::string& ip, unsigned int port); bool operator==(const SocketDriverAddress& rhs) const; bool operator!=(const SocketDriverAddress& rhs) const; - virtual string ToString() const; - virtual string ToAddress() const; - virtual string GetIP() const; + virtual AZStd::string ToString() const; + virtual AZStd::string ToAddress() const; + virtual AZStd::string GetIP() const; virtual unsigned int GetPort() const; virtual const void* GetTargetAddress(unsigned int& addressSize) const; @@ -163,18 +163,18 @@ namespace GridMate /// @{ Address conversion functionality. They MUST implemented thread safe. Generally this is not a problem since they just part local data. /// Create address from ip and port. If ip == NULL we will assign a broadcast address. - virtual string IPPortToAddress(const char* ip, unsigned int port) const { return IPPortToAddressString(ip, port); } - virtual bool AddressToIPPort(const string& address, string& ip, unsigned int& port) const { return AddressStringToIPPort(address, ip, port); } + virtual AZStd::string IPPortToAddress(const char* ip, unsigned int port) const { return IPPortToAddressString(ip, port); } + virtual bool AddressToIPPort(const AZStd::string& address, AZStd::string& ip, unsigned int& port) const { return AddressStringToIPPort(address, ip, port); } /// Create address for the socket driver from IP and port - static string IPPortToAddressString(const char* ip, unsigned int port); + static AZStd::string IPPortToAddressString(const char* ip, unsigned int port); /// Decompose an address to IP and port - static bool AddressStringToIPPort(const string& address, string& ip, unsigned int& port); + static bool AddressStringToIPPort(const AZStd::string& address, AZStd::string& ip, unsigned int& port); /// Return the family type of the address (AF_INET,AF_INET6 AF_UNSPEC) - static BSDSocketFamilyType AddressFamilyType(const string& ip); - static BSDSocketFamilyType AddressFamilyType(const char* ip) { return AddressFamilyType(string(ip)); } + static BSDSocketFamilyType AddressFamilyType(const AZStd::string& ip); + static BSDSocketFamilyType AddressFamilyType(const char* ip) { return AddressFamilyType(AZStd::string(ip)); } /// @} - virtual AZStd::intrusive_ptr CreateDriverAddress(const string& address) = 0; + virtual AZStd::intrusive_ptr CreateDriverAddress(const AZStd::string& address) = 0; /// Additional CreateDriverAddress function should be implemented. virtual AZStd::intrusive_ptr CreateDriverAddress(const sockaddr* sockAddr) = 0; @@ -352,7 +352,7 @@ namespace GridMate * \note Driver address allocates internal resources, use it only when you intend to communicate. Otherwise operate with * the string address. */ - virtual AZStd::intrusive_ptr CreateDriverAddress(const string& address); + virtual AZStd::intrusive_ptr CreateDriverAddress(const AZStd::string& address); virtual AZStd::intrusive_ptr CreateDriverAddress(const sockaddr* addr); /// Called only from the DriverAddress when the use count becomes 0 virtual void DestroyDriverAddress(DriverAddress* address); @@ -364,7 +364,7 @@ namespace GridMate namespace Utils { ///< Retrieves ip address corresponding to a host name. Blocks thread until dns resolving is happened. - bool GetIpByHostName(int familyType, const char* hostName, string& ip); + bool GetIpByHostName(int familyType, const char* hostName, AZStd::string& ip); } /** diff --git a/Code/Framework/GridMate/GridMate/Carrier/TrafficControl.h b/Code/Framework/GridMate/GridMate/Carrier/TrafficControl.h index 2b49f320b5..7b79124a73 100644 --- a/Code/Framework/GridMate/GridMate/Carrier/TrafficControl.h +++ b/Code/Framework/GridMate/GridMate/Carrier/TrafficControl.h @@ -9,7 +9,6 @@ #define GM_TRAFFIC_CONTROL_H #include -#include #include diff --git a/Code/Framework/GridMate/GridMate/Carrier/Utils.h b/Code/Framework/GridMate/GridMate/Carrier/Utils.h index 2b15696ac2..db58ec979e 100644 --- a/Code/Framework/GridMate/GridMate/Carrier/Utils.h +++ b/Code/Framework/GridMate/GridMate/Carrier/Utils.h @@ -8,14 +8,14 @@ #ifndef GM_CARRIER_UTILS_H #define GM_CARRIER_UTILS_H -#include +#include namespace GridMate { namespace Utils { ///< Returns the machines address(ip) in a string. familyType is platform dependent. - string GetMachineAddress(int familyType = 0); + AZStd::string GetMachineAddress(int familyType = 0); ///< Returns a broadcast address based on a family type. On ipv6 we emulate broadbast using the multicast on the all nodes address (FF02::1). familyType is platform dependent. const char* GetBroadcastAddress(int familyType = 0); } diff --git a/Code/Framework/GridMate/GridMate/Drillers/CarrierDriller.cpp b/Code/Framework/GridMate/GridMate/Drillers/CarrierDriller.cpp index 528afa6cce..38f029f0f5 100644 --- a/Code/Framework/GridMate/GridMate/Drillers/CarrierDriller.cpp +++ b/Code/Framework/GridMate/GridMate/Drillers/CarrierDriller.cpp @@ -64,7 +64,7 @@ namespace GridMate // OnUpdateStatistics // [4/14/2011] //========================================================================= - void CarrierDriller::OnUpdateStatistics(const GridMate::string& address, const TrafficControl::Statistics& lastSecond, const TrafficControl::Statistics& lifeTime, const TrafficControl::Statistics& effectiveLastSecond, const TrafficControl::Statistics& effectiveLifeTime) + void CarrierDriller::OnUpdateStatistics(const AZStd::string& address, const TrafficControl::Statistics& lastSecond, const TrafficControl::Statistics& lifeTime, const TrafficControl::Statistics& effectiveLastSecond, const TrafficControl::Statistics& effectiveLifeTime) { m_output->BeginTag(m_drillerTag); m_output->BeginTag(AZ_CRC("Statistics", 0xe2d38b22)); diff --git a/Code/Framework/GridMate/GridMate/Drillers/CarrierDriller.h b/Code/Framework/GridMate/GridMate/Drillers/CarrierDriller.h index bb3cb1e3b2..b12441e6fa 100644 --- a/Code/Framework/GridMate/GridMate/Drillers/CarrierDriller.h +++ b/Code/Framework/GridMate/GridMate/Drillers/CarrierDriller.h @@ -42,7 +42,7 @@ namespace GridMate ////////////////////////////////////////////////////////////////////////// // Carrier Driller Bus - void OnUpdateStatistics(const GridMate::string& address, const TrafficControl::Statistics& lastSecond, const TrafficControl::Statistics& lifeTime, const TrafficControl::Statistics& effectiveLastSecond, const TrafficControl::Statistics& effectiveLifeTime) override; + void OnUpdateStatistics(const AZStd::string& address, const TrafficControl::Statistics& lastSecond, const TrafficControl::Statistics& lifeTime, const TrafficControl::Statistics& effectiveLastSecond, const TrafficControl::Statistics& effectiveLifeTime) override; void OnConnectionStateChanged(Carrier* carrier, ConnectionID id, Carrier::ConnectionStates newState) override; ////////////////////////////////////////////////////////////////////////// diff --git a/Code/Framework/GridMate/GridMate/Drillers/ReplicaDriller.cpp b/Code/Framework/GridMate/GridMate/Drillers/ReplicaDriller.cpp index e70aceabc9..cb48578255 100644 --- a/Code/Framework/GridMate/GridMate/Drillers/ReplicaDriller.cpp +++ b/Code/Framework/GridMate/GridMate/Drillers/ReplicaDriller.cpp @@ -9,7 +9,6 @@ #include #include #include -#include using namespace AZ::Debug; diff --git a/Code/Framework/GridMate/GridMate/Drillers/SessionDriller.cpp b/Code/Framework/GridMate/GridMate/Drillers/SessionDriller.cpp index 5a34b70e74..a7130218f8 100644 --- a/Code/Framework/GridMate/GridMate/Drillers/SessionDriller.cpp +++ b/Code/Framework/GridMate/GridMate/Drillers/SessionDriller.cpp @@ -224,7 +224,7 @@ namespace GridMate // [4/15/2011] //========================================================================= void - SessionDriller::OnSessionError(GridSession* session, const string& errorMsg) + SessionDriller::OnSessionError(GridSession* session, const AZStd::string& errorMsg) { m_output->BeginTag(m_drillerTag); m_output->BeginTag(AZ_CRC("SessionError", 0xc689cc40)); diff --git a/Code/Framework/GridMate/GridMate/Drillers/SessionDriller.h b/Code/Framework/GridMate/GridMate/Drillers/SessionDriller.h index b89fae3d73..59f178976f 100644 --- a/Code/Framework/GridMate/GridMate/Drillers/SessionDriller.h +++ b/Code/Framework/GridMate/GridMate/Drillers/SessionDriller.h @@ -62,7 +62,7 @@ namespace GridMate /// Callback that notifies the title when a session will be left. session pointer is NOT valid after the callback returns. virtual void OnSessionDelete(GridSession* session); /// Called when a session error occurs. - virtual void OnSessionError(GridSession* session, const string& errorMsg); + virtual void OnSessionError(GridSession* session, const AZStd::string& errorMsg); /// Called when the actual game(match) starts virtual void OnSessionStart(GridSession* session); /// Called when the actual game(match) ends diff --git a/Code/Framework/GridMate/GridMate/Online/UserServiceTypes.h b/Code/Framework/GridMate/GridMate/Online/UserServiceTypes.h index 2617d98d73..c1753b3bb2 100644 --- a/Code/Framework/GridMate/GridMate/Online/UserServiceTypes.h +++ b/Code/Framework/GridMate/GridMate/Online/UserServiceTypes.h @@ -9,7 +9,6 @@ #define GM_USER_SERVICE_TYPES_H #include -#include namespace GridMate { diff --git a/Code/Framework/GridMate/GridMate/Replica/ReplicaStatus.h b/Code/Framework/GridMate/GridMate/Replica/ReplicaStatus.h index 019a595f6f..aeb5c1b2bb 100644 --- a/Code/Framework/GridMate/GridMate/Replica/ReplicaStatus.h +++ b/Code/Framework/GridMate/GridMate/Replica/ReplicaStatus.h @@ -12,7 +12,6 @@ #include #include #include -#include #include namespace GridMate @@ -102,7 +101,7 @@ namespace GridMate }; AZ::u8 m_flags; - string m_replicaName; + AZStd::string m_replicaName; }; DataSet m_options; // Flags and debug info diff --git a/Code/Framework/GridMate/GridMate/Session/LANSession.cpp b/Code/Framework/GridMate/GridMate/Session/LANSession.cpp index fca43c2709..e4e1c9e9b6 100644 --- a/Code/Framework/GridMate/GridMate/Session/LANSession.cpp +++ b/Code/Framework/GridMate/GridMate/Session/LANSession.cpp @@ -37,7 +37,7 @@ namespace GridMate { friend class LANMemberIDMarshaler; - static LANMemberID Create(MemberIDCompact id, const string& address) + static LANMemberID Create(MemberIDCompact id, const AZStd::string& address) { LANMemberID mid; mid.m_id = id; @@ -45,24 +45,24 @@ namespace GridMate return mid; } - void SetAddress(const string& address) + void SetAddress(const AZStd::string& address) { m_address = address; } MemberIDCompact GetID() const { return m_id; } - virtual string ToString() const + virtual AZStd::string ToString() const { - return string::format("%x", m_id); + return AZStd::string::format("%x", m_id); } - virtual string ToAddress() const { return m_address; } + virtual AZStd::string ToAddress() const { return m_address; } virtual MemberIDCompact Compact() const { return m_id; } virtual bool IsValid() const { return m_id != 0; } private: MemberIDCompact m_id; - string m_address; + AZStd::string m_address; }; class LANMemberIDMarshaler @@ -120,14 +120,14 @@ namespace GridMate /// Creates the local player. GridMember* CreateLocalMember(bool isHost, bool isInvited, RemotePeerMode peerMode); /// Creates remote player, when he wants to join. - GridMember* CreateRemoteMember(const string& address, ReadBuffer& data, RemotePeerMode peerMode, ConnectionID connId = InvalidConnectionID) override; + GridMember* CreateRemoteMember(const AZStd::string& address, ReadBuffer& data, RemotePeerMode peerMode, ConnectionID connId = InvalidConnectionID) override; /// Called when we receive the session replica. We create one and return the pointer. LANSessionReplica* OnSessionReplicaArrived(); /// Called when session parameters have changed. void OnSessionParamChanged(const GridSessionParam& param) override { (void)param; } - void OnSessionParamRemoved(const string& paramId) override { (void)paramId; } + void OnSessionParamRemoved(const AZStd::string& paramId) override { (void)paramId; } private: explicit LANSession(LANSessionService* service); @@ -141,7 +141,7 @@ namespace GridMate bool MatchMake(const LANSearchParams& sp); - string MakeSessionId(); + AZStd::string MakeSessionId(); Driver* m_driver; ///< Driver for network searches @@ -199,7 +199,7 @@ namespace GridMate : public CtorContextBase { CtorDataSet m_memberId; - CtorDataSet m_memberAddress; ///< As the server/host sees it! + CtorDataSet m_memberAddress; ///< As the server/host sees it! CtorDataSet m_peerMode; CtorDataSet m_isHost; }; @@ -232,7 +232,7 @@ namespace GridMate AZ_Assert(session, "We need to have a valid session!"); LANMember* member; MemberIDCompact memberId = ctorContext.m_memberId.Get(); - string memberAddress = ctorContext.m_memberAddress.Get(); + AZStd::string memberAddress = ctorContext.m_memberAddress.Get(); RemotePeerMode remotePeerMode = ctorContext.m_peerMode.Get(); bool isMemberHost = ctorContext.m_isHost.Get(); @@ -349,7 +349,7 @@ namespace GridMate { namespace Platform { - void AssignExtendedName(GridMate::string& extendedName); + void AssignExtendedName(AZStd::string& extendedName); } } @@ -364,7 +364,7 @@ LANMember::LANMember(const LANMemberID& id, LANSession* session) : GridMember(id.Compact()) , m_memberId(id) { - string extendedName; + AZStd::string extendedName; Platform::AssignExtendedName(extendedName); m_session = session; @@ -741,8 +741,8 @@ LANSession::CreateLocalMember(bool isHost, bool isInvited, RemotePeerMode peerMo { AZ_Assert(m_myMember == nullptr, "We already have added a local member!"); - string ip = Utils::GetMachineAddress(m_carrierDesc.m_familyType); - string address = SocketDriverCommon::IPPortToAddressString(ip.c_str(), m_carrierDesc.m_port); + AZStd::string ip = Utils::GetMachineAddress(m_carrierDesc.m_familyType); + AZStd::string address = SocketDriverCommon::IPPortToAddressString(ip.c_str(), m_carrierDesc.m_port); ///////////////////////////////////////////////////////////////////////////// // TODO: Use the UUID as an ID, we will need to add marshalers and so on AZ::Uuid uuid = AZ::Uuid::CreateRandom(); @@ -762,7 +762,7 @@ LANSession::CreateLocalMember(bool isHost, bool isInvited, RemotePeerMode peerMo // [2/2/2011] //========================================================================== GridMember* -LANSession::CreateRemoteMember(const string& address, ReadBuffer& data, RemotePeerMode peerMode, ConnectionID connId) +LANSession::CreateRemoteMember(const AZStd::string& address, ReadBuffer& data, RemotePeerMode peerMode, ConnectionID connId) { MemberIDCompact id; data.Read(id); @@ -803,7 +803,7 @@ LANSession::OnStateCreate(AZ::HSM& sm, const AZ::HSM::Event& e) { // patch the ID if we use implicit port AZ_Assert(m_carrier, "Carrier must be created!"); - string ip; + AZStd::string ip; unsigned int port; SocketDriverCommon::AddressStringToIPPort(m_myMember->GetId().ToAddress(), ip, port); AZ_Assert(port == 0 || port == m_carrier->GetPort(), "Carrier port missmatch! It should either be 0 (and patched here) in the implicit bind or the port number for explicit bind!"); @@ -881,7 +881,7 @@ LANSession::OnStateHostMigrateSession(AZ::HSM& sm, const AZ::HSM::Event& e) if (m_driver->Initialize(Driver::BSD_AF_INET, nullptr, hostPort, true) != Driver::EC_OK) { // check the output for more info - string errorMsg = string::format("Failed to initialize socket at port %d!", hostPort); + AZStd::string errorMsg = AZStd::string::format("Failed to initialize socket at port %d!", hostPort); EBUS_DBG_EVENT(Debug::SessionDrillerBus, OnSessionError, this, errorMsg); EBUS_EVENT_ID(m_gridMate, SessionEventBus, OnSessionError, this, errorMsg); // We can't be a real host if we failed to provide matching services. @@ -899,7 +899,7 @@ LANSession::OnStateHostMigrateSession(AZ::HSM& sm, const AZ::HSM::Event& e) // MakeSessionId // [3/7/2013] //========================================================================= -string +AZStd::string LANSession::MakeSessionId() { char temp[64]; @@ -990,7 +990,7 @@ LANSearch::Update() wb.Write(m_searchParams.m_params[i].m_type); } - string serverAddress = m_searchParams.m_serverAddress; + AZStd::string serverAddress = m_searchParams.m_serverAddress; if (serverAddress.empty()) { serverAddress = Utils::GetBroadcastAddress(m_searchParams.m_familyType); diff --git a/Code/Framework/GridMate/GridMate/Session/LANSessionServiceTypes.h b/Code/Framework/GridMate/GridMate/Session/LANSessionServiceTypes.h index ee4c0a8659..42524e034a 100644 --- a/Code/Framework/GridMate/GridMate/Session/LANSessionServiceTypes.h +++ b/Code/Framework/GridMate/GridMate/Session/LANSessionServiceTypes.h @@ -20,7 +20,7 @@ namespace GridMate : m_port (0) // by default session can't be found (searched for) {} - string m_address; /// empty to accept any address otherwise you can provide a specific bind address. + AZStd::string m_address; /// empty to accept any address otherwise you can provide a specific bind address. /** * Use 0 if you don't want you session to be searchable (default) * Port on which we will register the LAN session (it will be used for session communication and should be different than the game/carrier one). @@ -39,9 +39,9 @@ namespace GridMate {} int m_familyType; ///< Socket driver specific, by default 0. - string m_serverAddress; ///< Address of the server, we empty we create a broadcast address. + AZStd::string m_serverAddress; ///< Address of the server, we empty we create a broadcast address. int m_serverPort; ///< Server port (must be provided). - string m_listenAddress; ///< Address to bind for listening. By default is empty, which means we are listening to any address. + AZStd::string m_listenAddress; ///< Address to bind for listening. By default is empty, which means we are listening to any address. int m_listenPort; ///< Search listen port, if not set we will use ephimeral port. unsigned int m_broadcastFrequencyMs; ///< Time in MS between search broadcasts. }; @@ -52,7 +52,7 @@ namespace GridMate struct LANSearchInfo : public SearchInfo { - string m_serverIP; ///< server ID as we see it + AZStd::string m_serverIP; ///< server ID as we see it AZ::u16 m_serverPort; ///< server port for the session }; } diff --git a/Code/Framework/GridMate/GridMate/Session/Session.cpp b/Code/Framework/GridMate/GridMate/Session/Session.cpp index 5746a91c19..471e21127c 100644 --- a/Code/Framework/GridMate/GridMate/Session/Session.cpp +++ b/Code/Framework/GridMate/GridMate/Session/Session.cpp @@ -60,7 +60,7 @@ namespace GridMate typedef vector NewConnectionsType; typedef vector UserDataBufferType; - typedef unordered_set AddressSetType; + typedef unordered_set AddressSetType; GridSessionHandshake(unsigned int handshakeTimeoutMS, const VersionType& version); virtual ~GridSessionHandshake() {} @@ -92,19 +92,19 @@ namespace GridMate */ virtual bool OnConfirmAck(ConnectionID id, ReadBuffer& rb) { (void)id; (void)rb; return true; } // we don't do any further filtering /// Return true if you want to reject early reject a connection. - virtual bool OnNewConnection(const string& address); + virtual bool OnNewConnection(const AZStd::string& address); /// Called when we close a connection. virtual void OnDisconnect(ConnectionID id); /// Return timeout in milliseconds of the handshake procedure. virtual unsigned int GetHandshakeTimeOutMS() const { return m_handshakeTimeOutMS; } ////////////////////////////////////////////////////////////////////////// - void BanAddress(string address); + void BanAddress(AZStd::string address); void SetHost(bool isHost); void SetInvited(bool isInvited); void SetHostMigration(bool isMigrating); void SetUserData(const void* data, size_t dataSize); - void SetSessionId(string sessionId); + void SetSessionId(AZStd::string sessionId); bool IsNewConnections() { return !m_newConnections.empty(); } NewConnectionsType& AcquireNewConnections(); void ReleaseNewConnections(); @@ -117,7 +117,7 @@ namespace GridMate NewConnectionsType m_newConnections; AddressSetType m_banList; UserDataBufferType m_userData; - string m_sessionId; + AZStd::string m_sessionId; RemotePeerMode m_peerMode; VersionType m_version; @@ -165,7 +165,7 @@ void GridSessionParam::SetValue(AZ::s32* values, size_t numElements) if (numElements > 0) { AZ_Assert(values != nullptr, "Invalid values pointer!"); - string temp; + AZStd::string temp; for (size_t i = 0; i < numElements; ++i) { AZStd::to_string(temp, values[i]); @@ -183,7 +183,7 @@ void GridSessionParam::SetValue(AZ::s64* values, size_t numElements) if (numElements > 0) { AZ_Assert(values != nullptr, "Invalid values pointer!"); - string temp; + AZStd::string temp; for (size_t i = 0; i < numElements; ++i) { AZStd::to_string(temp, values[i]); @@ -201,7 +201,7 @@ void GridSessionParam::SetValue(float* values, size_t numElements) if (numElements > 0) { AZ_Assert(values != nullptr, "Invalid values pointer!"); - string temp; + AZStd::string temp; for (size_t i = 0; i < numElements; ++i) { AZStd::to_string(temp, values[i]); @@ -219,7 +219,7 @@ void GridSessionParam::SetValue(double* values, size_t numElements) if (numElements > 0) { AZ_Assert(values != nullptr, "Invalid values pointer!"); - string temp; + AZStd::string temp; for (size_t i = 0; i < numElements; ++i) { AZStd::to_string(temp, values[i]); @@ -684,7 +684,7 @@ GridSession::SetParam(const GridSessionParam& param) // RemoveParam //========================================================================= bool -GridSession::RemoveParam(const string& paramId) +GridSession::RemoveParam(const AZStd::string& paramId) { AZ_Assert(m_state, "Invalid session state replica. Session is not initialized."); @@ -726,7 +726,7 @@ GridSession::RemoveParam(unsigned int index) { const GridSessionReplica::ParamContainer& curParams = m_state->m_params.Get(); const GridSessionParam& foundParam = curParams.at(index); - string paramId = foundParam.m_id; + AZStd::string paramId = foundParam.m_id; m_state->m_params.Modify([=](Internal::GridSessionReplica::ParamContainer& params) { params.erase(¶ms.at(index)); @@ -970,7 +970,7 @@ GridSession::AddMember(GridMember* member) // IsAddressInMemberList //========================================================================= bool -GridSession::IsAddressInMemberList(const string& address) +GridSession::IsAddressInMemberList(const AZStd::string& address) { for (AZStd::size_t i = 0; i < m_members.size(); ++i) { @@ -1220,7 +1220,7 @@ GridSession::OnDriverError(Carrier* carrier, ConnectionID id, const DriverError& return; // not for us } uintptr_t idInt = reinterpret_cast(static_cast(id)); - string errorMsg = string::format("Carrier driver error ConnectionID: %" PRIuPTR "ErrorCode: 0x%08x", idInt, error.m_errorCode); + AZStd::string errorMsg = AZStd::string::format("Carrier driver error ConnectionID: %" PRIuPTR "ErrorCode: 0x%08x", idInt, error.m_errorCode); EBUS_DBG_EVENT(Debug::SessionDrillerBus, OnSessionError, this, errorMsg); EBUS_EVENT_ID(m_gridMate, SessionEventBus, OnSessionError, this, errorMsg); @@ -1248,7 +1248,7 @@ GridSession::OnSecurityError(Carrier* carrier, ConnectionID id, const SecurityEr return; // not for us } uintptr_t idInt = reinterpret_cast(static_cast(id)); - string errorMsg = string::format("Carrier security error ConnectionID: %" PRIuPTR " ErrorCode: 0x%08x", idInt, error.m_errorCode); + AZStd::string errorMsg = AZStd::string::format("Carrier security error ConnectionID: %" PRIuPTR " ErrorCode: 0x%08x", idInt, error.m_errorCode); EBUS_DBG_EVENT(Debug::SessionDrillerBus, OnSessionError, this, errorMsg); } @@ -1976,7 +1976,7 @@ GridMember::GetNatType() const //========================================================================= // GetName //========================================================================= -string +AZStd::string GridMember::GetName() const { return m_clientState ? m_clientState->m_name.Get().c_str() : "Unknown"; @@ -2244,7 +2244,7 @@ GridMember::GetProcessId() const //========================================================================= // GetMachineName //========================================================================= -string +AZStd::string GridMember::GetMachineName() const { if (m_clientState) @@ -2253,7 +2253,7 @@ GridMember::GetMachineName() const } else { - return string(); + return AZStd::string(); } } @@ -2688,7 +2688,7 @@ HandshakeErrorCode GridSessionHandshake::OnReceiveRequest(ConnectionID id, ReadB { (void)id; AZStd::lock_guard l(m_dataLock); - string sessionId; + AZStd::string sessionId; bool isInvited = false; RemotePeerMode peerMode; VersionType version; @@ -2761,7 +2761,7 @@ bool GridSessionHandshake::OnConfirmRequest(ConnectionID id, ReadBuffer& rb) (void)id; AZStd::lock_guard l(m_dataLock); - string sessionId; + AZStd::string sessionId; if (!rb.Read(sessionId)) { return false; @@ -2783,7 +2783,7 @@ bool GridSessionHandshake::OnConfirmRequest(ConnectionID id, ReadBuffer& rb) //========================================================================= // OnNewConnection //========================================================================= -bool GridSessionHandshake::OnNewConnection(const string& address) +bool GridSessionHandshake::OnNewConnection(const AZStd::string& address) { AZStd::lock_guard l(m_dataLock); @@ -2818,7 +2818,7 @@ void GridSessionHandshake::OnDisconnect(ConnectionID id) //========================================================================= // BanAddress //========================================================================= -void GridSessionHandshake::BanAddress(string address) +void GridSessionHandshake::BanAddress(AZStd::string address) { AZStd::lock_guard l(m_dataLock); m_banList.insert(address); @@ -2864,7 +2864,7 @@ void GridSessionHandshake::SetUserData(const void* data, size_t dataSize) //========================================================================= // SetSessionId //========================================================================= -void GridSessionHandshake::SetSessionId(string sessionId) +void GridSessionHandshake::SetSessionId(AZStd::string sessionId) { AZStd::lock_guard l(m_dataLock); m_sessionId = sessionId; diff --git a/Code/Framework/GridMate/GridMate/Session/Session.h b/Code/Framework/GridMate/GridMate/Session/Session.h index 63aa504a49..5080570373 100644 --- a/Code/Framework/GridMate/GridMate/Session/Session.h +++ b/Code/Framework/GridMate/GridMate/Session/Session.h @@ -39,8 +39,8 @@ namespace GridMate struct MemberID { virtual ~MemberID() {} - virtual string ToString() const = 0; - virtual string ToAddress() const = 0; + virtual AZStd::string ToString() const = 0; + virtual AZStd::string ToAddress() const = 0; virtual MemberIDCompact Compact() const = 0; virtual bool IsValid() const = 0; @@ -50,7 +50,7 @@ namespace GridMate AZ_FORCE_INLINE bool operator!=(const MemberIDCompact& rhs) const { return Compact() != rhs; } }; - typedef string SessionID; + typedef AZStd::string SessionID; struct SearchInfo; @@ -87,8 +87,8 @@ namespace GridMate void SetValue(float* values, size_t numElements); void SetValue(double* values, size_t numElements); - string m_id; - string m_value; + AZStd::string m_id; + AZStd::string m_value; AZ::u8 m_type; AZ_FORCE_INLINE bool operator==(const GridSessionParam& rhs) const { return m_type == rhs.m_type && m_id == rhs.m_id && m_value == rhs.m_value; } @@ -249,7 +249,7 @@ namespace GridMate /// Callback that notifies the title when a session will be left. session pointer is NOT valid after the callback returns. virtual void OnSessionDelete(GridSession* session) { (void)session; } /// Called when a session error occurs. - virtual void OnSessionError(GridSession* session, const string& errorMsg) { (void)session; (void)errorMsg; } + virtual void OnSessionError(GridSession* session, const AZStd::string& errorMsg) { (void)session; (void)errorMsg; } /// Called when the actual game(match) starts virtual void OnSessionStart(GridSession* session) { (void)session; } /// Called when the actual game(match) ends @@ -303,7 +303,7 @@ namespace GridMate virtual const PlayerId* GetPlayerId() const = 0; NatType GetNatType() const; - string GetName() const; + AZStd::string GetName() const; GridSession* GetSession() const { return m_session; } @@ -353,7 +353,7 @@ namespace GridMate //@{ Platform information AZ::PlatformID GetPlatformId() const; AZ::u32 GetProcessId() const; - string GetMachineName() const; + AZStd::string GetMachineName() const; //@} protected: @@ -484,7 +484,7 @@ namespace GridMate // Adds/updates a parameter. Returns false if parameter can not be added. bool SetParam(const GridSessionParam& param); // Removes a parameter by id. Returns false if parameter can not be removed. - bool RemoveParam(const string& paramId); + bool RemoveParam(const AZStd::string& paramId); // Removes a parameter by index. Returns false if parameter can not be removed. bool RemoveParam(unsigned int index); @@ -543,9 +543,9 @@ namespace GridMate /// Frees a slot based on a slot type. void FreeSlot(int slotType); /// Creates remote player, when he wants to join. - virtual GridMember* CreateRemoteMember(const string& address, ReadBuffer& data, RemotePeerMode peerMode, ConnectionID connId = InvalidConnectionID) = 0; + virtual GridMember* CreateRemoteMember(const AZStd::string& address, ReadBuffer& data, RemotePeerMode peerMode, ConnectionID connId = InvalidConnectionID) = 0; /// Returns true if this address belongs to a member in the list, otherwise false. - virtual bool IsAddressInMemberList(const string& address); + virtual bool IsAddressInMemberList(const AZStd::string& address); virtual bool IsConnectionIdInMemberList(const ConnectionID& connId); /// Adds a created member to the session. Return false if no free slow was found! virtual bool AddMember(GridMember* member); @@ -558,7 +558,7 @@ namespace GridMate /// Called when a session parameter is added/changed. virtual void OnSessionParamChanged(const GridSessionParam& param) = 0; /// Called when a session parameter is deleted. - virtual void OnSessionParamRemoved(const string& paramId) = 0; + virtual void OnSessionParamRemoved(const AZStd::string& paramId) = 0; ////////////////////////////////////////////////////////////////////////// SessionID m_sessionId; ///< Session id. Content of the string will vary based on session types and platforms. @@ -568,7 +568,7 @@ namespace GridMate Internal::GridSessionHandshake* m_handshake; typedef unordered_set ConnectionIDSet; ConnectionIDSet m_connections; - string m_hostAddress; + AZStd::string m_hostAddress; bool m_isShutdown; GridMember* m_myMember; ///< Created with the session and bound when the server replica arrives. @@ -923,14 +923,14 @@ namespace GridMate DataSet m_numConnections; DataSet m_natType; - DataSet m_name; + DataSet m_name; DataSet m_memberId; DataSet m_newHostVote; ///< Used when in host migration, to cast machine's vote. MuteDataSetType m_muteList; ///< List of all players we have muted. // Platform and application informational data DataSet > m_platformId; - DataSet m_machineName; + DataSet m_machineName; DataSet m_processId; DataSet m_isInvited; }; @@ -975,7 +975,7 @@ namespace GridMate /// Callback that notifies the title when a session will be left. session pointer is NOT valid after the callback returns. virtual void OnSessionDelete(GridSession* session) { (void)session; } /// Called when a session error occurs. - virtual void OnSessionError(GridSession* session, const string& errorMsg) { (void)session; (void)errorMsg; } + virtual void OnSessionError(GridSession* session, const AZStd::string& errorMsg) { (void)session; (void)errorMsg; } /// Called when the actual game(match) starts virtual void OnSessionStart(GridSession* session) { (void)session; } /// Called when the actual game(match) ends diff --git a/Code/Framework/GridMate/GridMate/String/StringUtils.h b/Code/Framework/GridMate/GridMate/String/StringUtils.h deleted file mode 100644 index 6f1ca89b0b..0000000000 --- a/Code/Framework/GridMate/GridMate/String/StringUtils.h +++ /dev/null @@ -1,10 +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 - * - */ -#pragma once - -#include diff --git a/Code/Framework/GridMate/GridMate/String/string.h b/Code/Framework/GridMate/GridMate/String/string.h deleted file mode 100644 index 779f5034c5..0000000000 --- a/Code/Framework/GridMate/GridMate/String/string.h +++ /dev/null @@ -1,26 +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 GM_CONTAINERS_STRING_H -#define GM_CONTAINERS_STRING_H - -#include -#include -#include // for getting from string->wstring and backwards - -namespace GridMate -{ - /** - * All libs should use specialized allocators - */ - typedef AZStd::basic_string, SysContAlloc > string; - typedef AZStd::basic_string, SysContAlloc > wstring; - - typedef AZStd::basic_string, GridMateStdAlloc > gridmate_string; - typedef AZStd::basic_string, GridMateStdAlloc > gridmate_wstring; -} -#endif // GM_CONTAINERS_STRING_H diff --git a/Code/Framework/GridMate/GridMate/VoiceChat/VoiceChatServiceBus.h b/Code/Framework/GridMate/GridMate/VoiceChat/VoiceChatServiceBus.h index 98fcd48b85..b5c09a411a 100644 --- a/Code/Framework/GridMate/GridMate/VoiceChat/VoiceChatServiceBus.h +++ b/Code/Framework/GridMate/GridMate/VoiceChat/VoiceChatServiceBus.h @@ -10,7 +10,6 @@ #include #include -#include namespace GridMate { diff --git a/Code/Framework/GridMate/GridMate/gridmate_files.cmake b/Code/Framework/GridMate/GridMate/gridmate_files.cmake index 8c94fe80ad..e318a8adcd 100644 --- a/Code/Framework/GridMate/GridMate/gridmate_files.cmake +++ b/Code/Framework/GridMate/GridMate/gridmate_files.cmake @@ -120,6 +120,5 @@ set(FILES Session/Session.cpp Session/Session.h Session/SessionServiceBus.h - String/string.h VoiceChat/VoiceChatServiceBus.h ) diff --git a/Code/Framework/GridMate/Platform/Android/GridMate/Carrier/Utils_Android.cpp b/Code/Framework/GridMate/Platform/Android/GridMate/Carrier/Utils_Android.cpp index 87bb0c3cda..75259fbe64 100644 --- a/Code/Framework/GridMate/Platform/Android/GridMate/Carrier/Utils_Android.cpp +++ b/Code/Framework/GridMate/Platform/Android/GridMate/Carrier/Utils_Android.cpp @@ -18,9 +18,9 @@ namespace GridMate { - string Utils::GetMachineAddress(int familyType) + AZStd::string Utils::GetMachineAddress(int familyType) { - string machineName; + AZStd::string machineName; struct RTMRequest { nlmsghdr m_msghdr; @@ -67,7 +67,7 @@ namespace GridMate char address[INET6_ADDRSTRLEN] = { 0 }; bool isLoopback = false; - string devname; + AZStd::string devname; for (int rtattrlen = IFA_PAYLOAD(nlmp); RTA_OK(rtatp, rtattrlen); rtatp = RTA_NEXT(rtatp, rtattrlen)) { if (rtatp->rta_type == IFA_ADDRESS) diff --git a/Code/Framework/GridMate/Platform/Android/GridMate/Session/LANSession_Android.cpp b/Code/Framework/GridMate/Platform/Android/GridMate/Session/LANSession_Android.cpp index e70e839d42..05fb56dfc1 100644 --- a/Code/Framework/GridMate/Platform/Android/GridMate/Session/LANSession_Android.cpp +++ b/Code/Framework/GridMate/Platform/Android/GridMate/Session/LANSession_Android.cpp @@ -6,19 +6,18 @@ * */ -#include #include namespace GridMate { namespace Platform { - void AssignExtendedName(GridMate::string& extendedName) + void AssignExtendedName(AZStd::string& extendedName) { char hostName[64]; gethostname(hostName, AZ_ARRAY_SIZE(hostName)); - extendedName = GridMate::string::format("%s", hostName); + extendedName = AZStd::string::format("%s", hostName); } } } diff --git a/Code/Framework/GridMate/Platform/Common/UnixLike/GridMate/Carrier/Utils_UnixLike.cpp b/Code/Framework/GridMate/Platform/Common/UnixLike/GridMate/Carrier/Utils_UnixLike.cpp index ea824e7564..7d04ff640b 100644 --- a/Code/Framework/GridMate/Platform/Common/UnixLike/GridMate/Carrier/Utils_UnixLike.cpp +++ b/Code/Framework/GridMate/Platform/Common/UnixLike/GridMate/Carrier/Utils_UnixLike.cpp @@ -18,9 +18,9 @@ namespace GridMate { - string Utils::GetMachineAddress(int familyType) + AZStd::string Utils::GetMachineAddress(int familyType) { - string machineName; + AZStd::string machineName; struct ifaddrs* ifAddrStruct = nullptr; struct ifaddrs* ifa = nullptr; diff --git a/Code/Framework/GridMate/Platform/Common/WinAPI/GridMate/Carrier/Utils_WinAPI.cpp b/Code/Framework/GridMate/Platform/Common/WinAPI/GridMate/Carrier/Utils_WinAPI.cpp index dd9b737180..095f8ba6c7 100644 --- a/Code/Framework/GridMate/Platform/Common/WinAPI/GridMate/Carrier/Utils_WinAPI.cpp +++ b/Code/Framework/GridMate/Platform/Common/WinAPI/GridMate/Carrier/Utils_WinAPI.cpp @@ -16,9 +16,9 @@ namespace GridMate { - string Utils::GetMachineAddress(int familyType) + AZStd::string Utils::GetMachineAddress(int familyType) { - string machineName; + AZStd::string machineName; char name[MAX_PATH]; int result = gethostname(name, sizeof(name)); AZ_Error("GridMate", result == 0, "Failed in gethostname with result=%d, WSAGetLastError=%d!", result, WSAGetLastError()); diff --git a/Code/Framework/GridMate/Platform/Linux/GridMate/Session/LANSession_Linux.cpp b/Code/Framework/GridMate/Platform/Linux/GridMate/Session/LANSession_Linux.cpp index e70e839d42..ac887bb624 100644 --- a/Code/Framework/GridMate/Platform/Linux/GridMate/Session/LANSession_Linux.cpp +++ b/Code/Framework/GridMate/Platform/Linux/GridMate/Session/LANSession_Linux.cpp @@ -6,19 +6,20 @@ * */ -#include #include +#include + namespace GridMate { namespace Platform { - void AssignExtendedName(GridMate::string& extendedName) + void AssignExtendedName(AZStd::string& extendedName) { char hostName[64]; gethostname(hostName, AZ_ARRAY_SIZE(hostName)); - extendedName = GridMate::string::format("%s", hostName); + extendedName = AZStd::string::format("%s", hostName); } } } diff --git a/Code/Framework/GridMate/Platform/Linux/GridMate/String/StringUtils_Platform.h b/Code/Framework/GridMate/Platform/Linux/GridMate/String/StringUtils_Platform.h deleted file mode 100644 index 03320d1dd8..0000000000 --- a/Code/Framework/GridMate/Platform/Linux/GridMate/String/StringUtils_Platform.h +++ /dev/null @@ -1,8 +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 - * - */ -#pragma once diff --git a/Code/Framework/GridMate/Platform/Mac/GridMate/Session/LANSession_Mac.cpp b/Code/Framework/GridMate/Platform/Mac/GridMate/Session/LANSession_Mac.cpp index e70e839d42..ac887bb624 100644 --- a/Code/Framework/GridMate/Platform/Mac/GridMate/Session/LANSession_Mac.cpp +++ b/Code/Framework/GridMate/Platform/Mac/GridMate/Session/LANSession_Mac.cpp @@ -6,19 +6,20 @@ * */ -#include #include +#include + namespace GridMate { namespace Platform { - void AssignExtendedName(GridMate::string& extendedName) + void AssignExtendedName(AZStd::string& extendedName) { char hostName[64]; gethostname(hostName, AZ_ARRAY_SIZE(hostName)); - extendedName = GridMate::string::format("%s", hostName); + extendedName = AZStd::string::format("%s", hostName); } } } diff --git a/Code/Framework/GridMate/Platform/Windows/GridMate/Session/LANSession_Windows.cpp b/Code/Framework/GridMate/Platform/Windows/GridMate/Session/LANSession_Windows.cpp index 4bf038a2cf..8925746a79 100644 --- a/Code/Framework/GridMate/Platform/Windows/GridMate/Session/LANSession_Windows.cpp +++ b/Code/Framework/GridMate/Platform/Windows/GridMate/Session/LANSession_Windows.cpp @@ -6,22 +6,22 @@ * */ -#include #include #include +#include namespace GridMate { namespace Platform { - void AssignExtendedName(GridMate::string& extendedName) + void AssignExtendedName(AZStd::string& extendedName) { char hostName[64]; gethostname(hostName, AZ_ARRAY_SIZE(hostName)); char procPath[256]; char procName[256]; - DWORD ret = GetModuleFileName(NULL, procPath, 256); + DWORD ret = GetModuleFileNameA(NULL, procPath, 256); if (ret > 0) { ::_splitpath_s(procPath, 0, 0, 0, 0, procName, 256, 0, 0); @@ -31,7 +31,7 @@ namespace GridMate azsnprintf(procName, AZ_ARRAY_SIZE(procName), "Unknown"); } - extendedName = GridMate::string::format("%s::%s", hostName, procName); + extendedName = AZStd::string::format("%s::%s", hostName, procName); } } } diff --git a/Code/Framework/GridMate/Platform/iOS/GridMate/Session/LANSession_iOS.cpp b/Code/Framework/GridMate/Platform/iOS/GridMate/Session/LANSession_iOS.cpp index e70e839d42..05fb56dfc1 100644 --- a/Code/Framework/GridMate/Platform/iOS/GridMate/Session/LANSession_iOS.cpp +++ b/Code/Framework/GridMate/Platform/iOS/GridMate/Session/LANSession_iOS.cpp @@ -6,19 +6,18 @@ * */ -#include #include namespace GridMate { namespace Platform { - void AssignExtendedName(GridMate::string& extendedName) + void AssignExtendedName(AZStd::string& extendedName) { char hostName[64]; gethostname(hostName, AZ_ARRAY_SIZE(hostName)); - extendedName = GridMate::string::format("%s", hostName); + extendedName = AZStd::string::format("%s", hostName); } } } diff --git a/Code/Framework/GridMate/Tests/Carrier.cpp b/Code/Framework/GridMate/Tests/Carrier.cpp index 45cb16dbb2..8d3ec4eef6 100644 --- a/Code/Framework/GridMate/Tests/Carrier.cpp +++ b/Code/Framework/GridMate/Tests/Carrier.cpp @@ -193,7 +193,7 @@ namespace UnitTest CarrierCallbacksHandler clientCB, serverCB; TestCarrierDesc serverCarrierDesc, clientCarrierDesc; - string str("Hello this is a carrier test!"); + AZStd::string str("Hello this is a carrier test!"); const char* targetAddress = "127.0.0.1"; @@ -377,7 +377,7 @@ namespace UnitTest CarrierCallbacksHandler clientCB, serverCB; TestCarrierDesc serverCarrierDesc, clientCarrierDesc; - string str("Hello this is a carrier test!"); + AZStd::string str("Hello this is a carrier test!"); clientCarrierDesc.m_driver = SocketProvider::CreateDriverForJoin(); serverCarrierDesc.m_driver = SocketProvider::CreateDriverForHost(); @@ -469,7 +469,7 @@ namespace UnitTest CarrierCallbacksHandler clientCB, serverCB; TestCarrierDesc serverCarrierDesc, clientCarrierDesc; - string str("Hello this is a carrier stress test!"); + AZStd::string str("Hello this is a carrier stress test!"); clientCarrierDesc.m_enableDisconnectDetection = false; serverCarrierDesc.m_enableDisconnectDetection = false; @@ -1401,7 +1401,7 @@ namespace UnitTest CarrierCallbacksHandler clientCB, serverCB; CarrierDesc serverCarrierDesc, clientCarrierDesc; - string str("Hello this is a carrier test!"); + AZStd::string str("Hello this is a carrier test!"); const char* targetAddress = "127.0.0.1"; diff --git a/Code/Framework/GridMate/Tests/CarrierStreamSocketDriverTests.cpp b/Code/Framework/GridMate/Tests/CarrierStreamSocketDriverTests.cpp index aac15562df..6af6a6ab87 100644 --- a/Code/Framework/GridMate/Tests/CarrierStreamSocketDriverTests.cpp +++ b/Code/Framework/GridMate/Tests/CarrierStreamSocketDriverTests.cpp @@ -188,7 +188,7 @@ namespace UnitTest CarrierStreamCallbacksHandler clientCB, serverCB; TestCarrierDesc serverCarrierDesc, clientCarrierDesc; - string str("Hello this is a carrier test!"); + AZStd::string str("Hello this is a carrier test!"); const char* targetAddress = "127.0.0.1"; @@ -374,7 +374,7 @@ namespace UnitTest CarrierStreamCallbacksHandler clientCB, serverCB; TestCarrierDesc serverCarrierDesc, clientCarrierDesc; - string str("Hello this is a carrier test!"); + AZStd::string str("Hello this is a carrier test!"); clientCarrierDesc.m_driver = CreateDriverForJoin(clientCarrierDesc); serverCarrierDesc.m_driver = CreateDriverForHost(serverCarrierDesc); @@ -475,7 +475,7 @@ namespace UnitTest CarrierStreamCallbacksHandler clientCB, serverCB; UnitTest::TestCarrierDesc serverCarrierDesc, clientCarrierDesc; - string str("Hello this is a carrier stress test!"); + AZStd::string str("Hello this is a carrier stress test!"); clientCarrierDesc.m_enableDisconnectDetection = /*false*/ true; serverCarrierDesc.m_enableDisconnectDetection = /*false*/ true; diff --git a/Code/Framework/GridMate/Tests/Replica.cpp b/Code/Framework/GridMate/Tests/Replica.cpp index 0b8fab10ce..83a3a1f5a1 100644 --- a/Code/Framework/GridMate/Tests/Replica.cpp +++ b/Code/Framework/GridMate/Tests/Replica.cpp @@ -3687,7 +3687,7 @@ public: void Touch() { - string randomStr; + AZStd::string randomStr; for (unsigned i = 0; i < k_strSize; ++i) { randomStr += 'a' + (rand() % 26); @@ -3698,7 +3698,7 @@ public: bool IsReplicaMigratable() override { return false; } static const unsigned k_strSize = 64; - DataSet m_value; + DataSet m_value; }; void run() diff --git a/Code/Framework/GridMate/Tests/Serialize.cpp b/Code/Framework/GridMate/Tests/Serialize.cpp index 4c74e9526a..9a681dc018 100644 --- a/Code/Framework/GridMate/Tests/Serialize.cpp +++ b/Code/Framework/GridMate/Tests/Serialize.cpp @@ -471,12 +471,12 @@ namespace UnitTest // ------------------------------------ // String { - string s = "hello"; + AZStd::string s = "hello"; wb.Write(s); AZ_TEST_ASSERT(wb.Size() == s.length() + sizeof(AZ::u16)); - string rs; + AZStd::string rs; rb = ReadBuffer(wb.GetEndianType(), wb.Get(), wb.Size()); rb.Read(rs); AZ_TEST_ASSERT(rs == s); diff --git a/Code/Framework/GridMate/Tests/Session.cpp b/Code/Framework/GridMate/Tests/Session.cpp index 9e10e84e98..0c5baef483 100644 --- a/Code/Framework/GridMate/Tests/Session.cpp +++ b/Code/Framework/GridMate/Tests/Session.cpp @@ -241,7 +241,7 @@ namespace UnitTest (void)reason; } - void OnSessionError(GridSession* session, const string& /*errorMsg*/) override + void OnSessionError(GridSession* session, const AZStd::string& /*errorMsg*/) override { (void)session; #ifndef AZ_LAN_TEST_MAIN_THREAD_BLOCKED // we will receive an error is we block for a long time @@ -599,7 +599,7 @@ namespace UnitTest (void)member; (void)reason; } - void OnSessionError(GridSession* session, const string& /*errorMsg*/) override + void OnSessionError(GridSession* session, const AZStd::string& /*errorMsg*/) override { (void)session; AZ_TEST_ASSERT(false); @@ -834,7 +834,7 @@ namespace UnitTest (void)member; (void)reason; } - void OnSessionError(GridSession* session, const string& /*errorMsg*/) override + void OnSessionError(GridSession* session, const AZStd::string& /*errorMsg*/) override { (void)session; #ifndef AZ_LAN_TEST_MAIN_THREAD_BLOCKED // we will receive an error is we block for a long time @@ -1207,7 +1207,7 @@ namespace UnitTest (void)member; (void)reason; } - void OnSessionError(GridSession* session, const string& /*errorMsg*/) override + void OnSessionError(GridSession* session, const AZStd::string& /*errorMsg*/) override { (void)session; AZ_TEST_ASSERT(false); @@ -1521,7 +1521,7 @@ namespace UnitTest (void)member; (void)reason; } - void OnSessionError(GridSession* session, const string& /*errorMsg*/) override + void OnSessionError(GridSession* session, const AZStd::string& /*errorMsg*/) override { (void)session; // On this test we will get a open port error because we have multiple hosts. This is ok, since we test migration here! @@ -1861,7 +1861,7 @@ namespace UnitTest (void)member; (void)reason; } - void OnSessionError(GridSession* session, const string& /*errorMsg*/) override + void OnSessionError(GridSession* session, const AZStd::string& /*errorMsg*/) override { (void)session; // On this test we will get a open port error because we have multiple hosts. This is ok, since we test migration here! diff --git a/Code/Framework/GridMate/Tests/TestProfiler.cpp b/Code/Framework/GridMate/Tests/TestProfiler.cpp index 428c1249ee..26e9312ecf 100644 --- a/Code/Framework/GridMate/Tests/TestProfiler.cpp +++ b/Code/Framework/GridMate/Tests/TestProfiler.cpp @@ -34,15 +34,15 @@ static bool CollectPerformanceCounters(const AZ::Debug::ProfilerRegister& reg, c return true; } -static string FormatString(const string& pre, const string& name, const string& post, AZ::u64 time, AZ::u64 calls) +static AZStd::string FormatString(const AZStd::string& pre, const AZStd::string& name, const AZStd::string& post, AZ::u64 time, AZ::u64 calls) { - string units = "us"; + AZStd::string units = "us"; if (AZ::u64 divtime = time / 1000) { time = divtime; units = "ms"; } - return string::format("%s%s %s %10llu%s (%llu calls)\n", pre.c_str(), name.c_str(), post.c_str(), time, units.c_str(), calls); + return AZStd::string::format("%s%s %s %10llu%s (%llu calls)\n", pre.c_str(), name.c_str(), post.c_str(), time, units.c_str(), calls); } struct TotalSortContainer @@ -56,28 +56,28 @@ struct TotalSortContainer { if (m_self && level >= 0) { - string levelIndent; + AZStd::string levelIndent; for (AZ::s32 i = 0; i < level; i++) { levelIndent += (i == level - 1) ? "+---" : "| "; } - string name = m_self->m_name ? m_self->m_name : m_self->m_function; - string outputTotal = FormatString(levelIndent, name, " Total:", m_self->m_timeData.m_time, m_self->m_timeData.m_calls); + AZStd::string name = m_self->m_name ? m_self->m_name : m_self->m_function; + AZStd::string outputTotal = FormatString(levelIndent, name, " Total:", m_self->m_timeData.m_time, m_self->m_timeData.m_calls); AZ_Printf(systemId, outputTotal.c_str()); if (m_self->m_timeData.m_childrenTime || m_self->m_timeData.m_childrenCalls) { - string childIndent = levelIndent; + AZStd::string childIndent = levelIndent; for (auto i = name.begin(); i != name.end(); ++i) { childIndent += " "; } childIndent[level * 4] = '|'; - string outputChild = FormatString(childIndent, "", "Child:", m_self->m_timeData.m_childrenTime, m_self->m_timeData.m_childrenCalls); + AZStd::string outputChild = FormatString(childIndent, "", "Child:", m_self->m_timeData.m_childrenTime, m_self->m_timeData.m_childrenCalls); AZ_Printf(systemId, outputChild.c_str()); - string outputSelf = FormatString(childIndent, "", "Self :", m_self->m_timeData.m_time - m_self->m_timeData.m_childrenTime, m_self->m_timeData.m_calls); + AZStd::string outputSelf = FormatString(childIndent, "", "Self :", m_self->m_timeData.m_time - m_self->m_timeData.m_childrenTime, m_self->m_timeData.m_calls); AZ_Printf(systemId, outputSelf.c_str()); } } @@ -237,7 +237,7 @@ void TestProfiler::PrintProfilingSelf(const char* systemId) AZ_Printf(systemId, "Profiling timers by exclusive execution time:\n"); for (auto profiler : selfSorted) { - string str = FormatString("", profiler->m_name ? profiler->m_name : profiler->m_function, "Self Time:", + AZStd::string str = FormatString("", profiler->m_name ? profiler->m_name : profiler->m_function, "Self Time:", profiler->m_timeData.m_time - profiler->m_timeData.m_childrenTime, profiler->m_timeData.m_calls); AZ_Printf(systemId, str.c_str()); } diff --git a/Code/LauncherUnified/Launcher.h b/Code/LauncherUnified/Launcher.h index e0b3abdf95..5ff6009e43 100644 --- a/Code/LauncherUnified/Launcher.h +++ b/Code/LauncherUnified/Launcher.h @@ -21,15 +21,12 @@ namespace O3DELauncher CryAllocatorsRAII() { AZ_Assert(!AZ::AllocatorInstance::IsReady(), "Expected allocator to not be initialized, hunt down the static that is initializing it"); - AZ_Assert(!AZ::AllocatorInstance::IsReady(), "Expected allocator to not be initialized, hunt down the static that is initializing it"); AZ::AllocatorInstance::Create(); - AZ::AllocatorInstance::Create(); } ~CryAllocatorsRAII() { - AZ::AllocatorInstance::Destroy(); AZ::AllocatorInstance::Destroy(); } }; diff --git a/Code/Legacy/CryCommon/AppleSpecific.h b/Code/Legacy/CryCommon/AppleSpecific.h index 4d17c18bac..caf85a8f44 100644 --- a/Code/Legacy/CryCommon/AppleSpecific.h +++ b/Code/Legacy/CryCommon/AppleSpecific.h @@ -192,13 +192,8 @@ typedef WCHAR* LPUWSTR, * PUWSTR; typedef const WCHAR* LPCWSTR, * PCWSTR; typedef const WCHAR* LPCUWSTR, * PCUWSTR; -#ifdef UNICODE typedef LPCWSTR LPCTSTR; typedef LPWSTR LPTSTR; -#else -typedef LPCSTR LPCTSTR; -typedef LPSTR LPTSTR; -#endif typedef DWORD COLORREF; #define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16))) diff --git a/Code/Legacy/CryCommon/CryArray.h b/Code/Legacy/CryCommon/CryArray.h index b304df28af..61224784a2 100644 --- a/Code/Legacy/CryCommon/CryArray.h +++ b/Code/Legacy/CryCommon/CryArray.h @@ -12,6 +12,7 @@ #pragma once #include +#include //--------------------------------------------------------------------------- // Convenient iteration macros @@ -58,18 +59,6 @@ struct fake_move_helper } }; -// Override for string to ensure proper construction -template <> -struct fake_move_helper -{ - static void move(string& dest, string& source) - { - ::new((void*)&dest) string(); - dest = source; - source.~string(); - } -}; - // Generic move function: transfer an existing source object to uninitialized dest address. // Addresses must not overlap (requirement on caller). // May be specialized for specific types, to provide a more optimal move. diff --git a/Code/Legacy/CryCommon/CryCustomTypes.h b/Code/Legacy/CryCommon/CryCustomTypes.h index 9594f5a333..74f3cbc9dc 100644 --- a/Code/Legacy/CryCommon/CryCustomTypes.h +++ b/Code/Legacy/CryCommon/CryCustomTypes.h @@ -16,10 +16,10 @@ #pragma once #include "CryTypeInfo.h" -#include "CryFixedString.h" #include #include #include +#include #define STATIC_CONST(T, name, val) \ static inline T name() { static T t = val; return t; } @@ -46,7 +46,7 @@ inline bool HasString(const T& val, FToString flags, const void* def_data = 0) float NumToFromString(float val, int digits, bool floating, char buffer[], int buf_size); template -string NumToString(T val, int min_digits, int max_digits, bool floating) +AZStd::string NumToString(T val, int min_digits, int max_digits, bool floating) { char buffer[64]; float f(val); @@ -68,7 +68,7 @@ struct CStructInfo { CStructInfo(cstr name, size_t size, size_t align, Array vars = Array(), Array templates = Array()); virtual bool IsType(CTypeInfo const& Info) const; - virtual string ToString(const void* data, FToString flags = 0, const void* def_data = 0) const; + virtual AZStd::string ToString(const void* data, FToString flags = 0, const void* def_data = 0) const; virtual bool FromString(void* data, cstr str, FFromString flags = 0) const; virtual bool ToValue(const void* data, void* value, const CTypeInfo& typeVal) const; virtual bool FromValue(void* data, const void* value, const CTypeInfo& typeVal) const; @@ -86,9 +86,9 @@ struct CStructInfo } protected: - Array Vars; - CryStackStringT EndianDesc; // Encodes instructions for endian swapping. - bool HasBitfields; + Array Vars; + AZStd::fixed_string<16> EndianDesc; // Encodes instructions for endian swapping. + bool HasBitfields; Array TemplateTypes; void MakeEndianDesc(); @@ -124,11 +124,11 @@ struct TTypeInfo return false; } - virtual string ToString(const void* data, FToString flags = 0, const void* def_data = 0) const + virtual AZStd::string ToString(const void* data, FToString flags = 0, const void* def_data = 0) const { if (!HasString(*(const T*)data, flags, def_data)) { - return string(); + return AZStd::string(); } return ::ToString(*(const T*)data); } @@ -193,7 +193,7 @@ struct TProxyTypeInfo return false; } - virtual string ToString(const void* data, FToString flags = 0, const void* def_data = 0) const + virtual AZStd::string ToString(const void* data, FToString flags = 0, const void* def_data = 0) const { T val = T(*(const S*)data); T def_val = def_data ? T(*(const S*)def_data) : T(); @@ -234,32 +234,32 @@ protected: // Customisation for string. template<> -inline string TTypeInfo::ToString(const void* data, FToString flags, const void* def_data) const +inline AZStd::string TTypeInfo::ToString(const void* data, FToString flags, const void* def_data) const { - const string& val = *(const string*)data; + const AZStd::string& val = *(const AZStd::string*)data; if (def_data && flags.SkipDefault) { - if (val == *(const string*)def_data) + if (val == *(const AZStd::string*)def_data) { - return string(); + return AZStd::string(); } } return val; } template<> -inline bool TTypeInfo::FromString(void* data, cstr str, FFromString flags) const +inline bool TTypeInfo::FromString(void* data, cstr str, FFromString flags) const { if (!*str && flags.SkipEmpty) { return true; } - *(string*)data = str; + *(AZStd::string*)data = str; return true; } template<> -void TTypeInfo::GetMemoryUsage(ICrySizer* pSizer, void const* data) const; +void TTypeInfo::GetMemoryUsage(ICrySizer* pSizer, void const* data) const; //--------------------------------------------------------------------------- // @@ -632,11 +632,11 @@ protected: } // Override ToString: Limit to significant digits. - virtual string ToString(const void* data, FToString flags = 0, const void* def_data = 0) const + virtual AZStd::string ToString(const void* data, FToString flags = 0, const void* def_data = 0) const { if (!HasString(*(const S*)data, flags, def_data)) { - return string(); + return AZStd::string(); } static int digits = int_ceil(log10f(float(nQUANT))); return NumToString(*(const TFixed*)data, 1, digits + 3, true); @@ -907,12 +907,12 @@ struct TEnumInfo return false; } - virtual string ToString(const void* data, FToString flags, const void* def_data) const + virtual AZStd::string ToString(const void* data, FToString flags, const void* def_data) const { TInt val = *(const TInt*)(data); if (flags.SkipDefault && val == (def_data ? *(const TInt*)def_data : TInt(0))) { - return string(); + return AZStd::string(); } if (cstr sName = TEnumDef::ToName(val)) @@ -1153,13 +1153,13 @@ struct CEnumDefUuid return false; } - string ToString(const void* data, FToString flags, const void* def_data) const override + AZStd::string ToString(const void* data, FToString flags, const void* def_data) const override { const AZ::Uuid& uuidData = *reinterpret_cast(data); const AZ::Uuid& defUuidData = *reinterpret_cast(def_data); if (flags.SkipDefault && uuidData == (def_data ? defUuidData : AZ::Uuid::CreateNull())) { - return string(); + return AZStd::string(); } if (cstr sName = ToName(uuidData)) @@ -1167,7 +1167,7 @@ struct CEnumDefUuid return sName; } - return string(); + return AZStd::string(); } bool FromString(void* data, cstr str, FFromString flags) const override diff --git a/Code/Legacy/CryCommon/CryFile.h b/Code/Legacy/CryCommon/CryFile.h index a043e4fa9b..0d2dac7c16 100644 --- a/Code/Legacy/CryCommon/CryFile.h +++ b/Code/Legacy/CryCommon/CryFile.h @@ -18,7 +18,6 @@ #include #include #include -#include "StringUtils.h" #include ////////////////////////////////////////////////////////////////////////// @@ -222,7 +221,7 @@ inline CCryFile::~CCryFile() inline bool CCryFile::Open(const char* filename, const char* mode, int nOpenFlagsEx) { char tempfilename[CRYFILE_MAX_PATH] = ""; - cry_strcpy(tempfilename, filename); + azstrcpy(tempfilename, CRYFILE_MAX_PATH, filename); #if !defined (_RELEASE) if (gEnv && gEnv->IsEditor() && gEnv->pConsole) @@ -233,8 +232,8 @@ inline bool CCryFile::Open(const char* filename, const char* mode, int nOpenFlag const int lowercasePaths = pCvar->GetIVal(); if (lowercasePaths) { - const string lowerString = PathUtil::ToLower(tempfilename); - cry_strcpy(tempfilename, lowerString.c_str()); + const AZStd::string lowerString = PathUtil::ToLower(tempfilename); + azstrcpy(tempfilename, CRYFILE_MAX_PATH, lowerString.c_str()); } } } @@ -243,7 +242,7 @@ inline bool CCryFile::Open(const char* filename, const char* mode, int nOpenFlag { Close(); } - cry_strcpy(m_filename, tempfilename); + azstrcpy(m_filename, CRYFILE_MAX_PATH, tempfilename); if (m_pIArchive) { @@ -430,7 +429,7 @@ inline const char* CCryFile::GetAdjustedFilename() const // Returns standard path otherwise. if (gameUrl != &szAdjustedFile[0]) { - cry_strcpy(szAdjustedFile, gameUrl); + azstrcpy(szAdjustedFile, AZ::IO::IArchive::MaxPath, gameUrl); } return szAdjustedFile; } diff --git a/Code/Legacy/CryCommon/CryFixedString.h b/Code/Legacy/CryCommon/CryFixedString.h deleted file mode 100644 index 299a5718a7..0000000000 --- a/Code/Legacy/CryCommon/CryFixedString.h +++ /dev/null @@ -1,2337 +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 - * - */ - - -// Description : Stack-based fixed-size String class, similar to CryString. -// will switch to heap-based allocation when string does no longer fit -// Can easily be substituted instead of CryString. - - -#ifndef CRYINCLUDE_CRYCOMMON_CRYFIXEDSTRING_H -#define CRYINCLUDE_CRYCOMMON_CRYFIXEDSTRING_H -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#include "CryString.h" - -#ifndef CRY_STRING_DEBUG -#define CRY_STRING_DEBUG(s) -#endif - -#define UNITTEST_CRYFIXEDSTRING (0) - -template -class CharTraits; - -// traits for char -template <> -class CharTraits -{ -public: - typedef size_t size_type; - typedef char value_type; - typedef const value_type* const_str; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef pointer iterator; - typedef const_pointer const_iterator; - - ILINE int _isspace(value_type c) const - { - return ::isspace((int)c); - } - - ILINE value_type _traits_toupper(value_type c) const - { - return static_cast(toupper(c)); - } - - ILINE value_type _traits_tolower(value_type c) const - { - return static_cast(tolower(c)); - } - - ILINE value_type _ascii_tolower(value_type c) const - { - return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; - } - - ILINE value_type _ascii_toupper(value_type c) const - { - return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; - } - - ILINE int _strcmp (const_str a, const_str b) const - { - return ::strcmp(a, b); - } - - ILINE int _strncmp (const_str a, const_str b, size_type n) const - { - return ::strncmp(a, b, n); - } - - ILINE int _stricmp (const_str a, const_str b) const - { - return ::azstricmp(a, b); - } - - ILINE int _strnicmp (const_str a, const_str b, size_type n) const - { - return ::azstrnicmp(a, b, n); - } - - ILINE size_type _strspn(const_str str, const_str strCharSet) const - { - return (str == NULL) ? 0 : (size_type)::strspn(str, strCharSet); - } - - ILINE size_type _strcspn(const_str str, const_str strCharSet) const - { - return (str == NULL) ? 0 : (size_type)::strcspn(str, strCharSet); - } - - static ILINE size_type _strlen(const_str str) - { - return (str == NULL) ? 0 : (size_type)::strlen(str); - } - - ILINE const_str _strchr(const_str str, value_type c) const - { - return (str == NULL) ? 0 : ::strchr(str, c); - } - - ILINE value_type* _strstr(value_type* str, const_str strSearch) const - { - return (str == NULL) ? 0 : (value_type*) ::strstr(str, strSearch); - } - - ILINE void _copy(value_type* dest, const value_type* src, size_type count) - { - memcpy(dest, src, count * sizeof(value_type)); - } - - ILINE void _move(value_type* dest, const value_type* src, size_type count) - { - memmove(dest, src, count * sizeof(value_type)); - } - - ILINE void _set(value_type* dest, value_type ch, size_type count) - { - memset(dest, ch, count * sizeof(value_type)); - } - - ILINE int _vsnprintf(value_type* str, size_type size, const_str format, va_list ap) - { - return ::azvsnprintf(str, size, format, ap); - } -}; - -// traits for wchar_t -template <> -class CharTraits -{ -public: - typedef size_t size_type; - typedef wchar_t value_type; - typedef const value_type* const_str; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef pointer iterator; - typedef const_pointer const_iterator; - - ILINE int _isspace(value_type c) const - { - return iswspace(c); - } - - ILINE value_type _traits_toupper(value_type c) const - { - return towupper(c); - } - - ILINE value_type _traits_tolower(value_type c) const - { - return towlower(c); - } - - ILINE value_type _ascii_tolower(value_type c) const - { - return ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c)); - } - - ILINE value_type _ascii_toupper(value_type c) const - { - return ((((c) >= 'a') && ((c) <= 'z')) ? ((c) - 'a' + 'A') : (c)); - } - - ILINE int _strcmp (const_str a, const_str b) const - { - return wcscmp (a, b); - } - - ILINE int _strncmp (const_str a, const_str b, size_type n) const - { - return wcsncmp (a, b, n); - } - - ILINE int _stricmp (const_str a, const_str b) const - { - return azwcsicmp(a, b); - } - - ILINE int _strnicmp (const_str a, const_str b, size_type n) const - { - return azwcsnicmp(a, b, n); - } - - ILINE size_type _strspn(const_str str, const_str strCharSet) const - { - return (str == NULL) ? 0 : (size_type)::wcsspn(str, strCharSet); - } - - ILINE size_type _strcspn(const_str str, const_str strCharSet) const - { - return (str == NULL) ? 0 : (size_type)::wcscspn(str, strCharSet); - } - - static ILINE size_type _strlen(const_str str) - { - return (str == NULL) ? 0 : (size_type)::wcslen(str); - } - - ILINE const_str _strchr(const_str str, value_type c) const - { - return (str == NULL) ? 0 : ::wcschr(str, c); - } - - ILINE value_type* _strstr(value_type* str, const_str strSearch) const - { - return (str == NULL) ? 0 : ::wcsstr(str, strSearch); - } - - ILINE void _copy(value_type* dest, const value_type* src, size_type count) - { - memcpy(dest, src, count * sizeof(value_type)); - } - - ILINE void _move(value_type* dest, const value_type* src, size_type count) - { - memmove(dest, src, count * sizeof(value_type)); - } - - ILINE void _set(value_type* dest, value_type ch, size_type count) - { - wmemset(dest, ch, count); - } - - ILINE int _vsnprintf(value_type* str, size_type size, const_str format, va_list ap) - { - return ::_vsnwprintf_s(str, size + 1, size, format, ap); - } -}; - -template -class CryStackStringT - : public CharTraits -{ -public: - ////////////////////////////////////////////////////////////////////////// - // Types compatible with STL string. - ////////////////////////////////////////////////////////////////////////// - typedef CryStackStringT _Self; - typedef size_t size_type; - typedef T value_type; - typedef const value_type* const_str; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef pointer iterator; - typedef const_pointer const_iterator; - static const size_type MAX_SIZE = S; - - enum _npos_type - { - npos = (size_type) ~0 - }; - - ////////////////////////////////////////////////////////////////////////// - // Constructors - ////////////////////////////////////////////////////////////////////////// - CryStackStringT(); - -public: - - CryStackStringT(const _Self& str); - CryStackStringT(const _Self& str, size_type nOff, size_type nCount); - CryStackStringT(size_type nRepeat, value_type ch); - - // The reason of making this constructor unavailable (for a while) is - // explained in comments in front of the declaration of - // CryStringT::CryStringT(size_type nRepeat, value_type ch) - // (see CryString.h). -private: - CryStackStringT(value_type ch, size_type nRepeat); - -public: - - CryStackStringT(const_str str); - CryStackStringT(const CryStringT& str); - CryStackStringT(const_str str, size_type nLength); - CryStackStringT(const_iterator _First, const_iterator _Last); - ~CryStackStringT(); - - ////////////////////////////////////////////////////////////////////////// - // STL string like interface. - ////////////////////////////////////////////////////////////////////////// - //! Operators. - size_type length() const; - size_type size() const; - bool empty() const; - void clear(); // free up the data - - //! Returns the storage currently allocated to hold the string, a value at least as large as length(). - // Also: capacity is always >= (MAX_SIZE-1) - size_type capacity() const; - - // Sets the capacity of the string to a number at least as great as a specified number. - // nCount = 0 is shrinking string to fit number of characters in it. - // Shrink to fit post-cond: capacity() >= (MAX_SIZE-1) - void reserve(size_type nCount = 0); - - _Self& append(const value_type* _Ptr); - _Self& append(const value_type* _Ptr, size_type nCount); - _Self& append(const _Self& _Str, size_type nOff, size_type nCount); - _Self& append(const _Self& _Str); - _Self& append(size_type nCount, value_type _Ch); - _Self& append(const_iterator _First, const_iterator _Last); - - _Self& assign(const_str _Ptr); - _Self& assign(const_str _Ptr, size_type nCount); - _Self& assign(const _Self& _Str, size_type off, size_type nCount); - _Self& assign(const _Self& _Str); - _Self& assign(size_type nCount, value_type _Ch); - _Self& assign(const_iterator _First, const_iterator _Last); - - value_type at(size_type index) const; - //value_type& at( size_type index ); - - const_iterator begin() const { return m_str; }; - const_iterator end() const { return m_str + length(); }; - - iterator begin() { return m_str; }; - iterator end() { return m_str + length(); }; - - //! cast to C string operator. - operator const_str() const { - return m_str; - } - - //! cast to C string. - const value_type* c_str() const { return m_str; } - const value_type* data() const { return m_str; }; - - ////////////////////////////////////////////////////////////////////////// - // string comparison. - ////////////////////////////////////////////////////////////////////////// - int compare(const _Self& _Str) const; - int compare(size_type _Pos1, size_type _Num1, const _Self& _Str) const; - int compare(size_type _Pos1, size_type _Num1, const _Self& _Str, size_type nOff, size_type nCount) const; - int compare(const value_type* _Ptr) const; - int compare(size_type _Pos1, size_type _Num1, const value_type* _Ptr, size_type _Num2 = npos) const; - - // Case insensitive comparison - int compareNoCase(const _Self& _Str) const; - int compareNoCase(size_type _Pos1, size_type _Num1, const _Self& _Str) const; - int compareNoCase(size_type _Pos1, size_type _Num1, const _Self& _Str, size_type nOff, size_type nCount) const; - int compareNoCase(const value_type* _Ptr) const; - int compareNoCase(size_type _Pos1, size_type _Num1, const value_type* _Ptr, size_type _Num2 = npos) const; - - // Copies at most a specified number of characters from an indexed position in a source string to a target character array. - size_type copy(value_type* _Ptr, size_type nCount, size_type nOff = 0) const; - - void push_back(value_type _Ch) { _ConcatenateInPlace(&_Ch, 1); } - void resize(size_type nCount, value_type _Ch = ' '); - - //! simple sub-string extraction - _Self substr(size_type pos, size_type count = npos) const; - - // replace part of string. - _Self& replace(value_type chOld, value_type chNew); - _Self& replace(const_str strOld, const_str strNew); - _Self& replace(size_type pos, size_type count, const_str strNew); - _Self& replace(size_type pos, size_type count, const_str strNew, size_type count2); - _Self& replace(size_type pos, size_type count, size_type nNumChars, value_type chNew); - - // insert new elements to string. - _Self& insert(size_type nIndex, value_type ch); - _Self& insert(size_type nIndex, size_type nCount, value_type ch); - _Self& insert(size_type nIndex, const_str pstr); - _Self& insert(size_type nIndex, const_str pstr, size_type nCount); - - //! delete count characters starting at zero-based index - _Self& erase(size_type nIndex, size_type count = npos); - - //! searching (return starting index, or -1 if not found) - //! look for a single character match - //! like "C" strchr - size_type find(value_type ch, size_type pos = 0) const; - //! look for a specific sub-string - //! like "C" strstr - size_type find(const_str subs, size_type pos = 0) const; - size_type rfind(value_type ch, size_type pos = npos) const; - - size_type find_first_of(value_type _Ch, size_type nOff = 0) const; - size_type find_first_of(const_str charSet, size_type nOff = 0) const; - //size_type find_first_of( const value_type* _Ptr,size_type _Off,size_type _Count ) const; - size_type find_first_of(const _Self& _Str, size_type _Off = 0) const; - - size_type find_first_not_of(value_type _Ch, size_type _Off = 0) const; - size_type find_first_not_of(const value_type* _Ptr, size_type _Off = 0) const; - size_type find_first_not_of(const value_type* _Ptr, size_type _Off, size_type _Count) const; - size_type find_first_not_of(const _Self& _Str, size_type _Off = 0) const; - - void swap(_Self& _Str); - - ////////////////////////////////////////////////////////////////////////// - // overloaded operators. - ////////////////////////////////////////////////////////////////////////// - // overloaded indexing. - value_type operator[](size_type index) const; - // value_type& operator[]( size_type index ); // same as at() - - // overloaded assignment - _Self& operator=(const _Self& str); - _Self& operator=(value_type ch); - _Self& operator=(const_str str); - _Self& operator=(const CryStringT& str); - - void move(_Self& src); - -#if defined(LINUX) || defined(APPLE) - template - _Self& operator=(const CryStackStringT& str) - { - _Assign(str.c_str(), str.size()); - return *this; - } -#endif - - // string concatenation - _Self& operator+=(const _Self& str); - _Self& operator+=(value_type ch); - _Self& operator+=(const_str str); - _Self& operator+=(const CryStringT& str); - - size_t GetAllocatedMemory() const - { - size_t size = sizeof(*this); - if (m_str != m_strBuf) - { - size += (m_nAllocSize + 1) * sizeof(value_type); - } - return size; - } - - ////////////////////////////////////////////////////////////////////////// - // Extended functions. - // This functions are not in the STL string. - // They have an ATL CString interface. - ////////////////////////////////////////////////////////////////////////// - //! Format string, use (sprintf) - _Self& Format(const value_type* format, ...); - - //! Format string fast, directly formats into string's buffer. - // Make sure there is enough space to hold the string - _Self& FormatFast (const value_type* format, ...); - - //! Converts the string to lower-case. - // This function uses the "C" locale for case-conversion (ie, A-Z only). - _Self& MakeLower(); - - //! Converts the string to upper-case. - // This function uses the "C" locale for case-conversion (ie, A-Z only). - _Self& MakeUpper(); - - _Self& Trim(); - _Self& Trim(value_type ch); - _Self& Trim(const value_type* sCharSet); - - _Self& TrimLeft(); - _Self& TrimLeft(value_type ch); - _Self& TrimLeft(const value_type* sCharSet); - - _Self& TrimRight(); - _Self& TrimRight(value_type ch); - _Self& TrimRight(const value_type* sCharSet); - - _Self SpanIncluding(const_str charSet) const; - _Self SpanExcluding(const_str charSet) const; - _Self Tokenize(const_str charSet, int& nStart) const; - _Self Mid(size_type nFirst, size_type nCount = npos) const { return substr(nFirst, nCount); }; - - _Self Left(size_type count) const; - _Self Right(size_type count) const; - ////////////////////////////////////////////////////////////////////////// - - // public utilities. - static bool _IsValidString(const_str str); - -public: - ////////////////////////////////////////////////////////////////////////// - // Only used for debugging statistics. - ////////////////////////////////////////////////////////////////////////// - static size_t _usedMemory(size_t size) - { - static size_t s_used_memory = 0; - s_used_memory += size; - return s_used_memory; - } - - //private: -public: - size_type m_nLength; - size_type m_nAllocSize; - value_type* m_str; // pointer to ref counted string data - value_type m_strBuf[MAX_SIZE]; - - // implementation helpers - void _AllocData(size_type nLen); - void _FreeData(value_type* pData); - void _Free(); - void _Initialize(); - - void _Concatenate(const_str sStr1, size_type nLen1, const_str sStr2, size_type nLen2); - void _ConcatenateInPlace(const_str sStr, size_type nLen); - void _Assign(const_str sStr, size_type nLen); - void _MakeUnique(); -}; - - -///////////////////////////////////////////////////////////////////////////// -// CryStackStringT Implementation -////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////////// -template -inline bool CryStackStringT::_IsValidString(const_str) -{ - return true; -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStackStringT::_Assign(const_str sStr, size_type nLen) -{ - // Check if this string is shared (reference count greater then 1) or not enough capacity to store new string. - // Then allocate new string buffer. - if (nLen > capacity()) - { - _Free(); - _AllocData(nLen); - } - // Copy characters from new string to this buffer. - CharTraits::_copy(m_str, sStr, nLen); - // Set new length. - m_nLength = nLen; - // Make null terminated string. - m_str[nLen] = 0; - CRY_STRING_DEBUG(m_str) -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStackStringT::_Concatenate(const_str sStr1, size_type nLen1, const_str sStr2, size_type nLen2) -{ - size_type nLen = nLen1 + nLen2; - if (nLen1 * 2 > nLen) - { - nLen = nLen1 * 2; - } - if (nLen != 0) - { - if (nLen < 8) - { - nLen = 8; - } - _AllocData(nLen); - CharTraits::_copy(m_str, sStr1, nLen1); - CharTraits::_copy(m_str + nLen1, sStr2, nLen2); - m_nLength = nLen1 + nLen2; - m_str[nLen1 + nLen2] = 0; - } - CRY_STRING_DEBUG(m_str) -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStackStringT::_ConcatenateInPlace(const_str sStr, size_type nLen) -{ - if (nLen != 0) - { - // Check if this string is shared (reference count greater then 1) or not enough capacity to store new string. - // Then allocate new string buffer. - if (length() + nLen > capacity()) - { - value_type* pOldData = m_str; - _Concatenate(m_str, length(), sStr, nLen); - _FreeData(pOldData); - } - else - { - CharTraits::_copy(m_str + length(), sStr, nLen); - m_nLength += nLen; - m_str[m_nLength] = 0; // Make null terminated string. - } - } -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStackStringT::_MakeUnique() -{ -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStackStringT::_Initialize() -{ - m_strBuf[0] = 0; - m_str = m_strBuf; - m_nLength = 0; - m_nAllocSize = MAX_SIZE - 1; // 0 termination not counted! -} - -// always allocate one extra character for '\0' termination -// assumes [optimistically] that data length will equal allocation length -template -inline void CryStackStringT::_AllocData(size_type nLen) -{ - assert(nLen >= 0); - assert(nLen <= INT_MAX - 1); // max size (enough room for 1 extra) - - if (nLen == 0) - { - _Initialize(); - } - else - { - size_type allocLen = (nLen + 1) * sizeof(value_type); - value_type* pData = m_strBuf; - if (allocLen > MAX_SIZE) - { - pData = (value_type*)CryModuleMalloc(allocLen); - _usedMemory(allocLen); // For statistics. - m_nAllocSize = nLen; - } - else - { - m_nAllocSize = MAX_SIZE - 1; - } - m_nLength = nLen; - m_str = pData; - m_str[nLen] = 0; // null terminated string. - } -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStackStringT::_Free() -{ - _FreeData(m_str); - _Initialize(); -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStackStringT::_FreeData(value_type* pData) -{ - if (pData != m_strBuf) - { - size_t allocLen = (m_nAllocSize + 1) * sizeof(value_type); - _usedMemory(-check_cast(allocLen)); // For statistics. - CryModuleFree(pData); - } -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT::CryStackStringT() -{ - _Initialize(); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT::CryStackStringT(const CryStackStringT& str) -{ - _Initialize(); - _Assign(str.c_str(), str.length()); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT::CryStackStringT(const CryStackStringT& str, size_type nOff, size_type nCount) -{ - _Initialize(); - assign(str, nOff, nCount); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT::CryStackStringT(const_str str) -{ - _Initialize(); - // Make a copy of C string. - size_type nLen = this->_strlen(str); - if (nLen != 0) - { - _AllocData(nLen); - CharTraits::_copy(m_str, str, nLen); - CRY_STRING_DEBUG(m_str) - } -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT::CryStackStringT(const CryStringT& str) -{ - _Initialize(); - size_t nLength = str.size(); - if (nLength > 0) - { - _AllocData(nLength); - CharTraits::_copy(m_str, str.c_str(), nLength); - CRY_STRING_DEBUG(m_str) - } -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT::CryStackStringT(const_str str, size_type nLength) -{ - _Initialize(); - if (nLength > 0) - { - _AllocData(nLength); - CharTraits::_copy(m_str, str, nLength); - CRY_STRING_DEBUG(m_str) - } -} - -////////////////////////////////////////////////////////////////////////// -// The reason of making this constructor unavailable (for a while) is -// explained in comments in front of the declaration of -// CryStringT::CryStringT(size_type nRepeat, value_type ch) -// (see CryString.h). -template -inline CryStackStringT::CryStackStringT(size_type nRepeat, value_type ch) -{ - _Initialize(); - if (nRepeat > 0) - { - _AllocData(nRepeat); - CharTraits::_set(m_str, ch, nRepeat); - CRY_STRING_DEBUG(m_str) - } -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT::CryStackStringT(const_iterator _First, const_iterator _Last) -{ - _Initialize(); - size_type nLength = (size_type)(_Last - _First); - if (nLength > 0) - { - _AllocData(nLength); - CharTraits::_copy(m_str, _First, nLength); - CRY_STRING_DEBUG(m_str) - } -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT::~CryStackStringT() -{ - _FreeData(m_str); -} - -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStackStringT::size_type CryStackStringT::length() const -{ - return m_nLength; -} -template -inline typename CryStackStringT::size_type CryStackStringT::size() const -{ - return m_nLength; -} -template -inline typename CryStackStringT::size_type CryStackStringT::capacity() const -{ - return m_nAllocSize; -} - -template -inline bool CryStackStringT::empty() const -{ - return length() == 0; -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStackStringT::clear() -{ - if (length() == 0) - { - return; - } - _Free(); - assert(length() == 0); -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStackStringT::reserve(size_type nCount) -{ - // Reserve of 0 is shrinking container to fit number of characters in it.. - if (nCount > capacity()) - { - value_type* pOldData = m_str; - size_type nOldLength = m_nLength; - _AllocData(nCount); - CharTraits::_copy(m_str, pOldData, nOldLength); - m_nLength = nOldLength; - m_str[m_nLength] = 0; - _FreeData(pOldData); - } - else if (nCount == 0) - { - if (length() != capacity()) - { - value_type* pOldData = m_str; - if (pOldData != m_strBuf) // in case we fit into our static buffer, we cannot shrink anyway - { - size_type nOldLength = m_nLength; - _AllocData(m_nLength); - // if (pOldData != m_strBuf || m_str != m_strBuf) // actually always true - // { - CharTraits::_copy(m_str, pOldData, nOldLength); // we can safely use CharTraits::_copy, as we never overlap here (in case of static buffer, we don't shrink anyway) - _FreeData(pOldData); - // } - } - } - } - CRY_STRING_DEBUG(m_str) -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::append(const_str _Ptr) -{ - *this += _Ptr; - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::append(const_str _Ptr, size_type nCount) -{ - _ConcatenateInPlace(_Ptr, nCount); - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::append(const CryStackStringT& _Str, size_type off, size_type nCount) -{ - size_type len = _Str.length(); - if (off > len) - { - return *this; - } - if (off + nCount > len) - { - nCount = len - off; - } - _ConcatenateInPlace(_Str.m_str + off, nCount); - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::append(const CryStackStringT& _Str) -{ - *this += _Str; - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::append(size_type nCount, value_type _Ch) -{ - if (nCount > 0) - { - if (length() + nCount >= capacity()) - { - value_type* pOldData = m_str; - size_type nOldLength = m_nLength; - _AllocData(length() + nCount); - CharTraits::_copy(m_str, pOldData, nOldLength); - CharTraits::_set(m_str + nOldLength, _Ch, nCount); - _FreeData(pOldData); - } - else - { - size_type nOldLength = length(); - CharTraits::_set(m_str + nOldLength, _Ch, nCount); - m_nLength = nOldLength + nCount; - m_str[length()] = 0; // Make null terminated string. - } - } - CRY_STRING_DEBUG(m_str) - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::append(const_iterator _First, const_iterator _Last) -{ - append(_First, (size_type)(_Last - _First)); - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::assign(const_str _Ptr) -{ - *this = _Ptr; - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::assign(const_str _Ptr, size_type nCount) -{ - size_type len = this->_strlen(_Ptr); - _Assign(_Ptr, (nCount < len) ? nCount : len); - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::assign(const CryStackStringT& _Str, size_type off, size_type nCount) -{ - size_type len = _Str.length(); - if (off > len) - { - return *this; - } - if (off + nCount > len) - { - nCount = len - off; - } - _Assign(_Str.m_str + off, nCount); - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::assign(const CryStackStringT& _Str) -{ - *this = _Str; - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::assign(size_type nCount, value_type _Ch) -{ - if (nCount >= 1) - { - _AllocData(nCount); - CharTraits::_set(m_str, _Ch, nCount); - CRY_STRING_DEBUG(m_str) - } - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::assign(const_iterator _First, const_iterator _Last) -{ - assign(_First, (size_type)(_Last - _First)); - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStackStringT::value_type CryStackStringT::at(size_type index) const -{ - assert(index >= 0 && index < length()); - return m_str[index]; -} - -/* -inline value_type& CryStackStringT::at( size_type index ) -{ -// same as GetAt -assert( index >= 0 && index < length() ); -return m_str[index]; -} -*/ - -template -inline typename CryStackStringT::value_type CryStackStringT::operator[](size_type index) const -{ - assert(index < length()); - return m_str[index]; -} - - -/* -inline value_type& CryStackStringT::operator[]( size_type index ) -{ -// same as GetAt -assert( index >= 0 && index < length() ); -return m_str[index]; -} -*/ - - -////////////////////////////////////////////////////////////////////////// -template -inline int CryStackStringT::compare(const CryStackStringT& _Str) const -{ - return CharTraits::_strcmp(m_str, _Str.m_str); -} - -template -inline int CryStackStringT::compare(size_type _Pos1, size_type _Num1, const CryStackStringT& _Str) const -{ - return compare(_Pos1, _Num1, _Str.m_str, npos); -} - -template -inline int CryStackStringT::compare(size_type _Pos1, size_type _Num1, const CryStackStringT& _Str, size_type nOff, size_type nCount) const -{ - assert(nOff < _Str.length()); - return compare(_Pos1, _Num1, _Str.m_str + nOff, nCount); -} - -template -inline int CryStackStringT::compare(const value_type* _Ptr) const -{ - return CharTraits::_strcmp(m_str, _Ptr); -} - -template -inline int CryStackStringT::compare(size_type _Pos1, size_type _Num1, const value_type* _Ptr, size_type _Num2) const -{ - assert(_Pos1 < length()); - if (length() - _Pos1 < _Num1) - { - _Num1 = length() - _Pos1; // trim to size - } - int res = _Num1 == 0 ? 0 : CharTraits::_strncmp(m_str + _Pos1, _Ptr, (_Num1 < _Num2) ? _Num1 : _Num2); - return (res != 0 ? res : _Num2 == npos && _Ptr[_Num1] == 0 ? 0 : _Num1 < _Num2 ? -1 : _Num1 == _Num2 ? 0 : +1); -} - -////////////////////////////////////////////////////////////////////////// -template -inline int CryStackStringT::compareNoCase(const CryStackStringT& _Str) const -{ - return CharTraits::_stricmp(m_str, _Str.m_str); -} - -template -inline int CryStackStringT::compareNoCase(size_type _Pos1, size_type _Num1, const CryStackStringT& _Str) const -{ - return compareNoCase(_Pos1, _Num1, _Str.m_str, npos); -} - -template -inline int CryStackStringT::compareNoCase(size_type _Pos1, size_type _Num1, const CryStackStringT& _Str, size_type nOff, size_type nCount) const -{ - assert(nOff < _Str.length()); - return compareNoCase(_Pos1, _Num1, _Str.m_str + nOff, nCount); -} - -template -inline int CryStackStringT::compareNoCase(const value_type* _Ptr) const -{ - return CharTraits::_stricmp(m_str, _Ptr); -} - -template -inline int CryStackStringT::compareNoCase(size_type _Pos1, size_type _Num1, const value_type* _Ptr, size_type _Num2) const -{ - assert(_Pos1 < length()); - if (length() - _Pos1 < _Num1) - { - _Num1 = length() - _Pos1; // trim to size - } - int res = _Num1 == 0 ? 0 : CharTraits::_strnicmp(m_str + _Pos1, _Ptr, (_Num1 < _Num2) ? _Num1 : _Num2); - return (res != 0 ? res : _Num2 == npos && _Ptr[_Num1] == 0 ? 0 : _Num1 < _Num2 ? -1 : _Num1 == _Num2 ? 0 : +1); -} - -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStackStringT::size_type CryStackStringT::copy(value_type* _Ptr, size_type nCount, size_type nOff) const -{ - assert(nOff < length()); - if (nCount < 0) - { - nCount = 0; - } - if (nOff + nCount > length()) // trim to offset. - { - nCount = length() - nOff; - } - - CharTraits::_copy(_Ptr, m_str + nOff, nCount); - return nCount; -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStackStringT::resize(size_type nCount, value_type _Ch) -{ - _MakeUnique(); - if (nCount > length()) - { - size_type numToAdd = nCount - length(); - append(numToAdd, _Ch); - } - else if (nCount < length()) - { - m_nLength = nCount; - m_str[length()] = 0; // Make null terminated string. - } -} - -////////////////////////////////////////////////////////////////////////// -//! compare helpers -template -inline bool operator==(const CryStackStringT& s1, const CryStackStringT& s2) -{ return s1.compare(s2) == 0; } -template -inline bool operator==(const CryStackStringT& s1, const typename CryStackStringT::value_type* s2) -{ return s1.compare(s2) == 0; } -template -inline bool operator==(const typename CryStackStringT::value_type* s1, const CryStackStringT& s2) -{ return s2.compare(s1) == 0; } -template -inline bool operator!=(const CryStackStringT& s1, const CryStackStringT& s2) -{ return s1.compare(s2) != 0; } -template -inline bool operator!=(const CryStackStringT& s1, const typename CryStackStringT::value_type* s2) -{ return s1.compare(s2) != 0; } -template -inline bool operator!=(const typename CryStackStringT::value_type* s1, const CryStackStringT& s2) -{ return s2.compare(s1) != 0; } -template -inline bool operator<(const CryStackStringT& s1, const CryStackStringT& s2) -{ return s1.compare(s2) < 0; } -template -inline bool operator<(const CryStackStringT& s1, const typename CryStackStringT::value_type* s2) -{ return s1.compare(s2) < 0; } -template -inline bool operator<(const typename CryStackStringT::value_type* s1, const CryStackStringT& s2) -{ return s2.compare(s1) > 0; } -template -inline bool operator>(const CryStackStringT& s1, const CryStackStringT& s2) -{ return s1.compare(s2) > 0; } -template -inline bool operator>(const CryStackStringT& s1, const typename CryStackStringT::value_type* s2) -{ return s1.compare(s2) > 0; } -template -inline bool operator>(const typename CryStackStringT::value_type* s1, const CryStackStringT& s2) -{ return s2.compare(s1) < 0; } -template -inline bool operator<=(const CryStackStringT& s1, const CryStackStringT& s2) -{ return s1.compare(s2) <= 0; } -template -inline bool operator<=(const CryStackStringT& s1, const typename CryStackStringT::value_type* s2) -{ return s1.compare(s2) <= 0; } -template -inline bool operator<=(const typename CryStackStringT::value_type* s1, const CryStackStringT& s2) -{ return s2.compare(s1) >= 0; } -template -inline bool operator>=(const CryStackStringT& s1, const CryStackStringT& s2) -{ return s1.compare(s2) >= 0; } -template -inline bool operator>=(const CryStackStringT& s1, const typename CryStackStringT::value_type* s2) -{ return s1.compare(s2) >= 0; } -template -inline bool operator>=(const typename CryStackStringT::value_type* s1, const CryStackStringT& s2) -{ return s2.compare(s1) <= 0; } - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::operator=(value_type ch) -{ - _Assign(&ch, 1); - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT operator+(const CryStackStringT& string1, typename CryStackStringT::value_type ch) -{ - CryStackStringT s(string1); - s.append(1, ch); - return s; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT operator+(typename CryStackStringT::value_type ch, const CryStackStringT& str) -{ - CryStackStringT s; - s.reserve(str.size() + 1); - s.append(1, ch); - s.append(str); - return s; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT operator+(const CryStackStringT& string1, const CryStackStringT& string2) -{ - CryStackStringT s(string1); - s.append(string2); - return s; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT operator+(const CryStackStringT& str1, const typename CryStackStringT::value_type* str2) -{ - CryStackStringT s(str1); - s.append(str2); - return s; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT operator+(const typename CryStackStringT::value_type* str1, const CryStackStringT& str2) -{ - assert(str1 == NULL || (CryStackStringT::_IsValidString(str1))); - CryStackStringT s; - s.reserve(CharTraits::_strlen(str1) + str2.size()); - s.append(str1); - s.append(str2); - return s; -} - -template -inline CryStackStringT& CryStackStringT::operator=(const CryStackStringT& str) -{ - _Assign (str.c_str(), str.length()); - return *this; -} - -template -inline CryStackStringT& CryStackStringT::operator=(const_str str) -{ - assert(str == NULL || _IsValidString(str)); - _Assign(str, this->_strlen(str)); - return *this; -} - -template -inline CryStackStringT& CryStackStringT::operator=(const CryStringT& str) -{ - _Assign(str.c_str(), str.size()); - return *this; -} - -template -inline CryStackStringT& CryStackStringT::operator+=(const CryStringT& str) -{ - _ConcatenateInPlace(str.c_str(), str.size()); - return *this; -} - -template -inline CryStackStringT& CryStackStringT::operator+=(const_str str) -{ - assert(str == NULL || _IsValidString(str)); - _ConcatenateInPlace(str, this->_strlen(str)); - return *this; -} - -template -inline CryStackStringT& CryStackStringT::operator+=(value_type ch) -{ - _ConcatenateInPlace(&ch, 1); - return *this; -} - -template -inline CryStackStringT& CryStackStringT::operator+=(const CryStackStringT& str) -{ - _ConcatenateInPlace(str.m_str, str.length()); - return *this; -} - -//! find first single character -template -inline typename CryStackStringT::size_type CryStackStringT::find(value_type ch, size_type pos) const -{ - if (!(/*pos >= 0 && */ pos <= length())) - { - return (typename CryStackStringT::size_type)npos; - } - const_str str = CharTraits::_strchr(m_str + pos, ch); - // return npos if not found and index otherwise - return (str == NULL) ? npos : (size_type)(str - m_str); -} - -//! find a sub-string (like strstr) -template -inline typename CryStackStringT::size_type CryStackStringT::find(const_str subs, size_type pos) const -{ - assert(_IsValidString(subs)); - if (!(pos >= 0 && pos <= length())) - { - return npos; - } - - // find first matching substring - const_str str = CharTraits::_strstr(m_str + pos, subs); - - // return npos for not found, distance from beginning otherwise - return (str == NULL) ? npos : (size_type)(str - m_str); -} - -//! find last single character -template -inline typename CryStackStringT::size_type CryStackStringT::rfind(value_type ch, size_type pos) const -{ - const_str str; - if (pos == npos) - { - // find last single character - str = strrchr(m_str, ch); - // return -1 if not found, distance from beginning otherwise - return (str == NULL) ? (size_type) - 1 : (size_type)(str - m_str); - } - else - { - if (pos == npos) - { - pos = length(); - } - if (!(pos >= 0 && pos <= length())) - { - return npos; - } - - value_type tmp = m_str[pos + 1]; - m_str[pos + 1] = 0; - str = strrchr(m_str, ch); - m_str[pos + 1] = tmp; - } - // return -1 if not found, distance from beginning otherwise - return (str == NULL) ? (size_type) - 1 : (size_type)(str - m_str); -} - -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStackStringT::size_type CryStackStringT::find_first_of(const CryStackStringT& _Str, size_type _Off) const -{ - return find_first_of(_Str.m_str, _Off); -} - -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStackStringT::size_type CryStackStringT::find_first_of(value_type _Ch, size_type nOff) const -{ - if (!(nOff >= 0 && nOff <= length())) - { - return npos; - } - value_type charSet[2] = { _Ch, 0 }; - const_str str = strpbrk(m_str + nOff, charSet); - return (str == NULL) ? -1 : (size_type)(str - m_str); -} - -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStackStringT::size_type CryStackStringT::find_first_of(const_str charSet, size_type nOff) const -{ - assert(_IsValidString(charSet)); - if (!(nOff >= 0 && nOff <= length())) - { - return npos; - } - const_str str = strpbrk(m_str + nOff, charSet); - return (str == NULL) ? (size_type) - 1 : (size_type)(str - m_str); -} - -//size_type find_first_not_of(const _Self& __s, size_type __pos = 0) const -//{ return find_first_not_of(__s._M_start, __pos, __s.size()); } - -//size_type find_first_not_of(const _CharT* __s, size_type __pos = 0) const -//{ _STLP_FIX_LITERAL_BUG(__s) return find_first_not_of(__s, __pos, _Traits::length(__s)); } - -//size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const; - -//size_type find_first_not_of(_CharT __c, size_type __pos = 0) const; - - -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStackStringT::size_type CryStackStringT::find_first_not_of(const value_type* _Ptr, size_type _Off) const -{ return find_first_not_of(_Ptr, _Off, this->_strlen(_Ptr)); } - -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStackStringT::size_type CryStackStringT::find_first_not_of(const CryStackStringT& _Str, size_type _Off) const -{ return find_first_not_of(_Str.m_str, _Off); } - -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStackStringT::size_type CryStackStringT::find_first_not_of(value_type _Ch, size_type _Off) const -{ - if (_Off > length()) - { - return npos; - } - else - { - for (const value_type* str = begin() + _Off; str != end(); ++str) - { - if (*str != _Ch) - { - return size_type(str - begin()); // Character found! - } - } - return npos; - } -} - -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStackStringT::size_type CryStackStringT::find_first_not_of(const value_type* _Ptr, size_type _Off, size_type _Count) const -{ - if (_Off > length()) - { - return npos; - } - else - { - const value_type* charsFirst = _Ptr, * charsLast = _Ptr + _Count; - for (const value_type* str = begin() + _Off; str != end(); ++str) - { - const value_type* c; - for (c = charsFirst; c != charsLast; ++c) - { - if (*c == *str) - { - break; - } - } - if (c == charsLast) - { - return size_type(str - begin());// Current character not in char set. - } - } - return npos; - } -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT CryStackStringT::substr(size_type pos, size_type count) const -{ - if (pos >= length()) - { - return CryStackStringT(); - } - if (count == npos) - { - count = length() - pos; - } - if (pos + count > length()) - { - count = length() - pos; - } - return CryStackStringT(m_str + pos, count); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::erase(size_type nIndex, size_type nCount) -{ - if (nIndex < 0) - { - nIndex = 0; - } - if (nCount < 0 || nCount > length() - nIndex) - { - nCount = length() - nIndex; - } - if (nCount > 0 && nIndex < length()) - { - _MakeUnique(); - size_type nNumToCopy = length() - (nIndex + nCount) + 1; - CharTraits::_move(m_str + nIndex, m_str + nIndex + nCount, nNumToCopy); - m_nLength = length() - nCount; - } - - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::insert(size_type nIndex, value_type ch) -{ - return insert(nIndex, 1, ch); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::insert(size_type nIndex, size_type nCount, value_type ch) -{ - _MakeUnique(); - - if (nIndex < 0) - { - nIndex = 0; - } - - size_type nNewLength = length(); - if (nIndex > nNewLength) - { - nIndex = nNewLength; - } - nNewLength += nCount; - - if (capacity() < nNewLength) - { - value_type* pOldData = m_str; - size_type nOldLength = m_nLength; - const_str pstr = m_str; - _AllocData(nNewLength); - CharTraits::_copy(m_str, pstr, nOldLength + 1); - _FreeData(pOldData); - } - - CharTraits::_move(m_str + nIndex + nCount, m_str + nIndex, (nNewLength - nIndex)); - CharTraits::_set(m_str + nIndex, ch, nCount); - m_nLength = nNewLength; - CRY_STRING_DEBUG(m_str) - - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::insert(size_type nIndex, const_str pstr, size_type nCount) -{ - if (nIndex < 0) - { - nIndex = 0; - } - - size_type nInsertLength = nCount; - size_type nNewLength = length(); - if (nInsertLength > 0) - { - _MakeUnique(); - if (nIndex > nNewLength) - { - nIndex = nNewLength; - } - nNewLength += nInsertLength; - - if (capacity() < nNewLength) - { - value_type* pOldData = m_str; - size_type nOldLength = m_nLength; - const_str pOldStr = m_str; - _AllocData(nNewLength); - CharTraits::_copy(m_str, pOldStr, (nOldLength + 1)); - _FreeData(pOldData); - } - - CharTraits::_move(m_str + nIndex + nInsertLength, m_str + nIndex, (nNewLength - nIndex - nInsertLength + 1)); - CharTraits::_copy(m_str + nIndex, pstr, nInsertLength); - m_nLength = nNewLength; - m_str[length()] = 0; - } - CRY_STRING_DEBUG(m_str) - - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::insert(size_type nIndex, const_str pstr) -{ - return insert(nIndex, pstr, this->_strlen(pstr)); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::replace(size_type pos, size_type count, const_str strNew) -{ - return replace(pos, count, strNew, this->_strlen(strNew)); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::replace(size_type pos, size_type count, const_str strNew, size_type count2) -{ - erase(pos, count); - insert(pos, strNew, count2); - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::replace(size_type pos, size_type count, size_type nNumChars, value_type chNew) -{ - erase(pos, count); - insert(pos, nNumChars, chNew); - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::replace(value_type chOld, value_type chNew) -{ - if (chOld != chNew) - { - _MakeUnique(); - value_type* strend = m_str + length(); - for (value_type* str = m_str; str != strend; ++str) - { - if (*str == chOld) - { - *str = chNew; - } - } - } - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::replace(const_str strOld, const_str strNew) -{ - size_type nSourceLen = this->_strlen(strOld); - if (nSourceLen == 0) - { - return *this; - } - size_type nReplacementLen = this->_strlen(strNew); - - size_type nCount = 0; - value_type* strStart = m_str; - value_type* strEnd = m_str + length(); - value_type* strTarget; - while (strStart < strEnd) - { - while ((strTarget = CharTraits::_strstr(strStart, strOld)) != NULL) - { - nCount++; - strStart = strTarget + nSourceLen; - } - strStart += this->_strlen(strStart) + 1; - } - - if (nCount > 0) - { - _MakeUnique(); - - size_type nOldLength = length(); - size_type nNewLength = nOldLength + (nReplacementLen - nSourceLen) * nCount; - if (capacity() < nNewLength) - { - value_type* pOldData = m_str; - size_type nPrevLength = m_nLength; - const_str pstr = m_str; - _AllocData(nNewLength); - CharTraits::_copy(m_str, pstr, nPrevLength); - _FreeData(pOldData); - } - strStart = m_str; - strEnd = m_str + length(); - - while (strStart < strEnd) - { - while ((strTarget = CharTraits::_strstr(strStart, strOld)) != NULL) - { - size_type nBalance = nOldLength - ((size_type)(strTarget - m_str) + nSourceLen); - CharTraits::_move(strTarget + nReplacementLen, strTarget + nSourceLen, nBalance); - CharTraits::_copy(strTarget, strNew, nReplacementLen); - strStart = strTarget + nReplacementLen; - strStart[nBalance] = 0; - nOldLength += (nReplacementLen - nSourceLen); - } - strStart += this->_strlen(strStart) + 1; - } - m_nLength = nNewLength; - } - CRY_STRING_DEBUG(m_str) - - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStackStringT::move(CryStackStringT& str) -{ - memcpy(this, &str, sizeof(*this)); - if (str.m_str == str.m_strBuf) - { - m_str = m_strBuf; - } -} - -template -inline void CryStackStringT::swap(CryStackStringT& _Str) -{ - CryStackStringT temp; - temp.move(*this); - move(_Str); - _Str.move(temp); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::Format(const_str format, ...) -{ - assert(_IsValidString(format)); - - value_type temp[4096]; // Limited to 4096 characters! - va_list argList; - va_start(argList, format); - this->_vsnprintf(temp, 4095, format, argList); - temp[4095] = '\0'; - va_end(argList); - *this = temp; - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::FormatFast(const_str format, ...) -{ - assert(_IsValidString(format)); - - va_list argList; - va_start(argList, format); - - int newLength = this->_vsnprintf(m_str, capacity(), format, argList); - if (newLength >= 0) - { - m_nLength = (size_type)newLength; - } - else - { - m_nLength = capacity(); - m_str[capacity()] = '\0'; - } - - va_end(argList); - - return *this; -} - - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::MakeLower() -{ - _MakeUnique(); - for (value_type* s = m_str; *s != 0; s++) - { - *s = this->_ascii_tolower(*s); - } - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::MakeUpper() -{ - _MakeUnique(); - for (value_type* s = m_str; *s != 0; s++) - { - *s = this->_ascii_toupper(*s); - } - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::Trim() -{ - return TrimRight().TrimLeft(); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::Trim(value_type ch) -{ - _MakeUnique(); - const value_type chset[2] = { ch, 0 }; - return TrimRight(chset).TrimLeft(chset); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::Trim(const value_type* sCharSet) -{ - _MakeUnique(); - return TrimRight(sCharSet).TrimLeft(sCharSet); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::TrimRight(value_type ch) -{ - const value_type chset[2] = { ch, 0 }; - return TrimRight(chset); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::TrimRight(const value_type* sCharSet) -{ - if (!sCharSet || !(*sCharSet) || length() < 1) - { - return *this; - } - - const value_type* last = m_str + length() - 1; - const value_type* str = last; - while ((str != m_str) && (CharTraits::_strchr(sCharSet, *str) != 0)) - { - str--; - } - - if (str != last) - { - // Just shrink length of the string. - size_type nNewLength = (size_type)(str - m_str) + 1; // m_str can change in _MakeUnique - _MakeUnique(); - m_nLength = nNewLength; - m_str[nNewLength] = 0; - } - - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::TrimRight() -{ - if (length() < 1) - { - return *this; - } - - const value_type* last = m_str + length() - 1; - const value_type* str = last; - while ((str != m_str) && (CharTraits::_isspace(*str) != 0)) - { - str--; - } - - if (str != last) // something changed? - { - // Just shrink length of the string. - size_type nNewLength = (size_type)(str - m_str) + 1; // m_str can change in _MakeUnique - _MakeUnique(); - m_nLength = nNewLength; - m_str[nNewLength] = 0; - } - - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::TrimLeft(value_type ch) -{ - const value_type chset[2] = { ch, 0 }; - return TrimLeft(chset); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::TrimLeft(const value_type* sCharSet) -{ - if (!sCharSet || !(*sCharSet)) - { - return *this; - } - - const value_type* str = m_str; - while ((*str != 0) && (CharTraits::_strchr(sCharSet, *str) != 0)) - { - str++; - } - - if (str != m_str) - { - size_type nOff = (size_type)(str - m_str); // m_str can change in _MakeUnique - _MakeUnique(); - size_type nNewLength = length() - nOff; - CharTraits::_move(m_str, m_str + nOff, nNewLength + 1); - m_nLength = nNewLength; - m_str[nNewLength] = 0; - } - - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT& CryStackStringT::TrimLeft() -{ - const value_type* str = m_str; - while ((*str != 0) && (CharTraits::_isspace(*str) != 0)) - { - str++; - } - - if (str != m_str) - { - size_type nOff = (size_type)(str - m_str); // m_str can change in _MakeUnique - _MakeUnique(); - size_type nNewLength = length() - nOff; - CharTraits::_move(m_str, m_str + nOff, nNewLength + 1); - m_nLength = nNewLength; - m_str[nNewLength] = 0; - } - - return *this; -} - -template -inline CryStackStringT CryStackStringT::Right(size_type count) const -{ - if (count == npos) - { - return CryStackStringT(); - } - else if (count > length()) - { - return *this; - } - - return CryStackStringT(m_str + length() - count, count); -} - -template -inline CryStackStringT CryStackStringT::Left(size_type count) const -{ - if (count == npos) - { - return CryStackStringT(); - } - else if (count > length()) - { - count = length(); - } - - return CryStackStringT(m_str, count); -} - -// strspn equivalent -template -inline CryStackStringT CryStackStringT::SpanIncluding(const_str charSet) const -{ - assert(_IsValidString(charSet)); - return Left((size_type)this->_strspn(m_str, charSet)); -} - -// strcspn equivalent -template -inline CryStackStringT CryStackStringT::SpanExcluding(const_str charSet) const -{ - assert(_IsValidString(charSet)); - return Left((size_type)this->_strcspn(m_str, charSet)); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStackStringT CryStackStringT::Tokenize(const_str charSet, int& nStart) const -{ - if (nStart < 0) - { - return CryStackStringT(); - } - - if (!charSet) - { - return *this; - } - - const_str sPlace = m_str + nStart; - const_str sEnd = m_str + length(); - if (sPlace < sEnd) - { - int nIncluding = (int)this->_strspn(sPlace, charSet); - - if ((sPlace + nIncluding) < sEnd) - { - sPlace += nIncluding; - int nExcluding = (int)this->_strcspn(sPlace, charSet); - int nFrom = nStart + nIncluding; - nStart = nFrom + nExcluding + 1; - - return substr(nFrom, nExcluding); - } - } - // Return empty string. - nStart = -1; - return CryStackStringT(); -} - -#if defined(_RELEASE) -#define ASSERT_LEN (void)(0) -#define ASSERT_WLEN (void)(0) -#else -#define ASSERT_LEN CRY_ASSERT_TRACE(this->length() <= S, ("String '%s' is %u character(s) longer than MAX_SIZE=%u", this->c_str(), this->length() - S, S)) -#define ASSERT_WLEN CRY_ASSERT_TRACE(this->length() <= S, ("Wide-char string '%ls' is %u character(s) longer than MAX_SIZE=%u", this->c_str(), this->length() - S, S)) -#endif - -// a template specialization for char -template -class CryFixedStringT - : public CryStackStringT -{ -public: - typedef CryStackStringT _parentType; - typedef CryFixedStringT _Self; - typedef size_t size_type; - typedef char value_type; - typedef const value_type* const_str; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef pointer iterator; - typedef const_pointer const_iterator; - static const size_type MAX_SIZE = S; - CryFixedStringT() - : _parentType() {} - CryFixedStringT(const _parentType& str) - : _parentType(str) {ASSERT_LEN; } - CryFixedStringT(const _parentType& str, size_type nOff, size_type nCount) - : _parentType(str, nOff, nCount) {ASSERT_LEN; } - CryFixedStringT(const _Self& str) - : _parentType(str) {ASSERT_LEN; } - CryFixedStringT(const _Self& str, size_type nOff, size_type nCount) - : _parentType(str, nOff, nCount) {ASSERT_LEN; } - CryFixedStringT(size_type nRepeat, value_type ch) - : _parentType(nRepeat, ch) {ASSERT_LEN; } - CryFixedStringT(const_str str) - : _parentType (str) {ASSERT_LEN; } - CryFixedStringT(const_str str, size_type nLength) - : _parentType(str, nLength) {ASSERT_LEN; } - CryFixedStringT(const_iterator _First, const_iterator _Last) - : _parentType(_First, _Last) {ASSERT_LEN; } - - template - _Self& operator=(const CryFixedStringT& str) - { - _parentType::operator = (str); - ASSERT_LEN; - return *this; - } - template - _Self& operator=(const CryStackStringT& str) - { - _parentType::operator = (str); - ASSERT_LEN; - return *this; - } - _Self& operator=(value_type ch) - { - _parentType::operator = (ch); - ASSERT_LEN; - return *this; - } - - void GetMemoryUsage(class ICrySizer* pSizer) const{} -}; - -// a template specialization for a fixed list of CryFixedString [Jan M.] -template -class CCryFixedStringListT -{ -public: - CCryFixedStringListT() - { Clear(); } - - void Clear() - { - m_currentAmount = -1; - for (int a = 0; a < NUM_MAX_ELEMENTS; ++a) - { - m_data[a] = ""; - } - } - - void Add(const char* name) - { - m_data[++m_currentAmount] = name; - if (m_currentAmount == NUM_MAX_ELEMENTS) - { - m_currentAmount = -1; - } - } - - const char* operator[](int index) - { - if (index <= m_currentAmount) - { - return m_data[index].c_str(); - } - return NULL; - } - - ILINE int Size() { return m_currentAmount + 1; } - - CryFixedStringT<32>* GetData(int& amount) - { - amount = m_currentAmount + 1; - return m_data; - } -private: - const static int NUM_MAX_ELEMENTS = maxElements; - CryFixedStringT m_data[NUM_MAX_ELEMENTS]; - int32 m_currentAmount; -}; - -// a template specialization for wchar_t -template -class CryFixedWStringT - : public CryStackStringT -{ -public: - typedef CryStackStringT _parentType; - typedef CryFixedWStringT _Self; - typedef size_t size_type; - typedef wchar_t value_type; - typedef const value_type* const_str; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef pointer iterator; - typedef const_pointer const_iterator; - static const size_type MAX_SIZE = S; - CryFixedWStringT() - : _parentType() {} - CryFixedWStringT(const _parentType& str) - : _parentType(str) {ASSERT_WLEN; } - CryFixedWStringT(const _parentType& str, size_type nOff, size_type nCount) - : _parentType(str, nOff, nCount) {ASSERT_WLEN; } - CryFixedWStringT(const _Self& str) - : _parentType(str) {ASSERT_WLEN; } - CryFixedWStringT(const _Self& str, size_type nOff, size_type nCount) - : _parentType(str, nOff, nCount) {ASSERT_WLEN; } - CryFixedWStringT(size_type nRepeat, value_type ch) - : _parentType(nRepeat, ch) {ASSERT_WLEN; } - CryFixedWStringT(const_str str) - : _parentType (str) {ASSERT_WLEN; } - CryFixedWStringT(const_str str, size_type nLength) - : _parentType(str, nLength) {ASSERT_WLEN; } - CryFixedWStringT(const_iterator _First, const_iterator _Last) - : _parentType(_First, _Last) {ASSERT_WLEN; } - - template - _Self& operator=(const CryFixedWStringT& str) - { - _parentType::operator = (str); - ASSERT_WLEN; - return *this; - } - template - _Self& operator=(const CryStackStringT& str) - { - _parentType::operator = (str); - ASSERT_WLEN; - return *this; - } -}; -#undef ASSERT_LEN -#undef ASSERT_WLEN -typedef CryStackStringT stack_string; - -// Special string type used for specifying file paths. -typedef CryStackStringT CryPathString; - - -#if UNITTEST_CRYFIXEDSTRING - -struct SUnitTest_FixedString -{ - bool UnitAssert(const char* message, const char* value, const char* refValue) - { - int res = strcmp(value, refValue); - CRY_ASSERT_MESSAGE(res == 0, message); - return res == 0; - } - - bool UnitAssert(const char* message, const wchar_t* value, const wchar_t* refValue) - { - int res = wcscmp(value, refValue); - CRY_ASSERT_MESSAGE(res == 0, message); - return res == 0; - } - - bool UnitAssert(const char* message, bool cond) - { - CRY_ASSERT_MESSAGE(cond, message); - return cond; - } - - bool UnitAssert(const char* message, size_t a, size_t b) - { - CRY_ASSERT_MESSAGE(a == b, message); - return a == b; - } - - int UnitTest() - { - CryStackStringT str1; - CryStackStringT str2; - CryStackStringT str3; - CryStackStringT str4; - CryStackStringT str5; - CryStackStringT wstr1; - CryStackStringT wstr2; - CryFixedStringT<100> fixedString100; - CryFixedStringT<200> fixedString200; - - typedef CryStackStringT T; - T* pStr = new T; - * pStr = "adads"; - delete pStr; - - str1 = "abcd"; - UnitAssert ("Assignment1-EnoughSpace", str1, "abcd"); - - str2 = "efg"; - UnitAssert ("Assignment2-EnoughSpace", str2, "efg"); - - str2 = str1; - UnitAssert ("Assignment3-EnoughSpace", str2, "abcd"); - - str3 = str1; - UnitAssert ("Assignment4-NotEnoughSpace", str3, "abcd"); - - str1 += "XY"; - UnitAssert ("Concatenate-EnoughSpace", str1, "abcdXY"); - - str2 += "efghijk"; - UnitAssert ("Concatenate-NotEnoughSpace", str2, "abcdefghijk"); - - str1.replace("bc", ""); - UnitAssert ("Replace-Shrink-EnoughSpace", str1, "adXY"); - - str1.replace("XY", "1234"); - UnitAssert ("Replace-Grow-EnoughSpace", str1, "ad1234"); - - str1.replace("1234", "1234567890"); - UnitAssert ("Replace-Grow-NotEnoughSpace", str1, "ad1234567890"); - - str1.reserve(200); - UnitAssert ("Reserve200-SameString", str1, "ad1234567890"); - UnitAssert ("Reserve200-Capacity", str1.capacity() == 200); - - str1.reserve(0); - UnitAssert ("Reserve0-SameString", str1, "ad1234567890"); - UnitAssert ("Reserve0-Capacity==Length", str1.capacity() == str1.length()); - - str1.erase(7); // doesn't change capacity - UnitAssert ("Erase-SameString", str1, "ad12345"); - - str4.assign("abc"); - UnitAssert ("Str4 Assignment", str4, "abc"); - str4.reserve(9); - UnitAssert ("Str4", str4.capacity() >= 9); // capacity is always >= MAX_SIZE-1 - str4.reserve(0); - UnitAssert ("Str4-Shrink", str4.capacity() >= 9); // capacity is always >= MAX_SIZE-1 - - size_t idx = str1.find("123"); - UnitAssert ("Str1-Find", idx == 2); - - idx = str1.find("123", 3); - UnitAssert ("Str1-Find", idx == str1.npos); - - wstr1 = L"abc"; - UnitAssert ("WStr1-Assign", wstr1, L"abc"); - UnitAssert ("WStr1-CompareCaseGT", wstr1.compare(L"aBc") > 0); - UnitAssert ("WStr1-CompareCaseLT", wstr1.compare(L"babc") < 0); - UnitAssert ("WStr1-CompareNoCase", wstr1.compareNoCase(L"aBc") == 0); - - str1.Format("This is a %s %S with %d params", "mixed", L"string", 3); - str2.Format("This is a %S %s with %d params", L"mixed", "string", 3); - UnitAssert ("Str1-Format1", str1, "This is a mixed string with 3 params"); - UnitAssert ("Str1-Format2", str1, str2); - - wstr1.Format(L"This is a %s %S with %d params", L"mixed", "string", 3); - wstr2.Format(L"This is a %S %s with %d params", "mixed", L"string", 3); - UnitAssert ("WStr1-Format1", wstr1, L"This is a mixed string with 3 params"); - UnitAssert ("WStr1-Format2", wstr1, wstr2); - - str5.FormatFast("%s", "12345"); - UnitAssert ("Str5-FormatFast", str5, "12345"); - - str5.FormatFast("%s", "012345"); - UnitAssert ("Str5-FormatFast-Truncate", str5, "01234"); - - fixedString100 = str5; - str2 = fixedString200; - fixedString200 = fixedString100; - UnitAssert ("FixedString-Test2", fixedString100, "01234"); - UnitAssert ("FixedString-Test1", fixedString100, fixedString200); - - CryStackStringT testStr; - CryFixedStringT<100> testStr2; - CryFixedWStringT<100> testWStr1; - string normalString; - wstring normalWString; - normalString = string(testStr); - normalString = string(testStr2); - normalString.assign(testStr2.c_str()); - // normalString = testStr; // <- must NOT compile, as we don't allow it! - // normalWString = testWStr1; // <- must NOT compile, as we don't allow it! - normalWString = wstring(testWStr1); - return 0; - } -}; -#endif // #if UNITTEST_CRYFIXEDSTRING - -#endif // CRYINCLUDE_CRYCOMMON_CRYFIXEDSTRING_H diff --git a/Code/Legacy/CryCommon/CryListenerSet.h b/Code/Legacy/CryCommon/CryListenerSet.h index 6addfa384e..e5be89aa9f 100644 --- a/Code/Legacy/CryCommon/CryListenerSet.h +++ b/Code/Legacy/CryCommon/CryListenerSet.h @@ -182,7 +182,7 @@ private: // DO NOT REMOVE - following methods only to be accessed only via CN }; typedef std::vector TListenerVec; - typedef std::vector TAllocatedNameVec; + typedef std::vector TAllocatedNameVec; inline void StartNotificationScope(); inline void EndNotificationScope(); @@ -418,7 +418,7 @@ inline size_t CListenerSet::MemSize() const size += sizeof(typename TAllocatedNameVec::value_type); for (typename TAllocatedNameVec::const_iterator iter(m_allocatedNames.begin()); iter != m_allocatedNames.end(); ++iter) { - size += iter->GetAllocatedMemory(); + size += iter->capacity() * sizeof(char) + sizeof(AZStd::string); } #endif diff --git a/Code/Legacy/CryCommon/CryName.h b/Code/Legacy/CryCommon/CryName.h index ce17d1f540..b9b3799dd7 100644 --- a/Code/Legacy/CryCommon/CryName.h +++ b/Code/Legacy/CryCommon/CryName.h @@ -395,13 +395,13 @@ inline bool CCryName::operator>(const CCryName& n) const return m_str > n.m_str; } -inline bool operator==(const string& s, const CCryName& n) +inline bool operator==(const AZStd::string& s, const CCryName& n) { - return n == s; + return s == n.c_str(); } -inline bool operator!=(const string& s, const CCryName& n) +inline bool operator!=(const AZStd::string& s, const CCryName& n) { - return n != s; + return s != n.c_str(); } inline bool operator==(const char* s, const CCryName& n) @@ -543,13 +543,13 @@ inline bool CCryNameCRC::operator>(const CCryNameCRC& n) const return m_nID > n.m_nID; } -inline bool operator==(const string& s, const CCryNameCRC& n) +inline bool operator==(const AZStd::string& s, const CCryNameCRC& n) { - return n == s; + return n == s.c_str(); } -inline bool operator!=(const string& s, const CCryNameCRC& n) +inline bool operator!=(const AZStd::string& s, const CCryNameCRC& n) { - return n != s; + return n != s.c_str(); } inline bool operator==(const char* s, const CCryNameCRC& n) diff --git a/Code/Legacy/CryCommon/CryPath.h b/Code/Legacy/CryCommon/CryPath.h index 32db308a85..046006f738 100644 --- a/Code/Legacy/CryCommon/CryPath.h +++ b/Code/Legacy/CryCommon/CryPath.h @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include "platform.h" @@ -31,26 +33,28 @@ #define CRY_NATIVE_PATH_SEPSTR DOS_PATH_SEP_STR #endif +typedef AZStd::fixed_string<512> stack_string; + namespace PathUtil { const static int maxAliasLength = 32; - inline string GetLocalizationFolder() + inline AZStd::string GetLocalizationFolder() { return gEnv->pCryPak->GetLocalizationFolder(); } - inline string GetLocalizationRoot() + inline AZStd::string GetLocalizationRoot() { return gEnv->pCryPak->GetLocalizationRoot(); } //! Convert a path to the uniform form. - inline string ToUnixPath(const string& strPath) + inline AZStd::string ToUnixPath(const AZStd::string& strPath) { - if (strPath.find(DOS_PATH_SEP_CHR) != string::npos) + if (strPath.find(DOS_PATH_SEP_CHR) != AZStd::string::npos) { - string path = strPath; - path.replace(DOS_PATH_SEP_CHR, UNIX_PATH_SEP_CHR); + AZStd::string path = strPath; + AZ::StringFunc::Replace(path, DOS_PATH_SEP_CHR, UNIX_PATH_SEP_CHR); return path; } return strPath; @@ -73,19 +77,19 @@ namespace PathUtil } //! Convert a path to the DOS form. - inline string ToDosPath(const string& strPath) + inline AZStd::string ToDosPath(const AZStd::string& strPath) { - if (strPath.find(UNIX_PATH_SEP_CHR) != string::npos) + if (strPath.find(UNIX_PATH_SEP_CHR) != AZStd::string::npos) { - string path = strPath; - path.replace(UNIX_PATH_SEP_CHR, DOS_PATH_SEP_CHR); + AZStd::string path = strPath; + AZ::StringFunc::Replace(path, UNIX_PATH_SEP_CHR, DOS_PATH_SEP_CHR); return path; } return strPath; } //! Convert a path to the Native form. - inline string ToNativePath(const string& strPath) + inline AZStd::string ToNativePath(const AZStd::string& strPath) { #if AZ_LEGACY_CRYCOMMON_TRAIT_USE_UNIX_PATHS return ToUnixPath(strPath); @@ -95,10 +99,10 @@ namespace PathUtil } //! Convert a path to lowercase form - inline string ToLower(const string& strPath) + inline AZStd::string ToLower(const AZStd::string& strPath) { - string path = strPath; - path.MakeLower(); + AZStd::string path = strPath; + AZStd::to_lower(path.begin(), path.end()); return path; } @@ -108,9 +112,9 @@ namespace PathUtil //! @param path [OUT] Extracted file path. //! @param filename [OUT] Extracted file (without extension). //! @param ext [OUT] Extracted files extension. - inline void Split(const string& filepath, string& path, string& filename, string& fext) + inline void Split(const AZStd::string& filepath, AZStd::string& path, AZStd::string& filename, AZStd::string& fext) { - path = filename = fext = string(); + path = filename = fext = AZStd::string(); if (filepath.empty()) { return; @@ -142,16 +146,16 @@ namespace PathUtil //! @param filepath [IN] Full file name inclusing path. //! @param path [OUT] Extracted file path. //! @param file [OUT] Extracted file (with extension). - inline void Split(const string& filepath, string& path, string& file) + inline void Split(const AZStd::string& filepath, AZStd::string& path, AZStd::string& file) { - string fext; + AZStd::string fext; Split(filepath, path, file, fext); file += fext; } // Extract extension from full specified file path // Returns - // pointer to the extension (without .) or pointer to an empty 0-terminated string + // pointer to the extension (without .) or pointer to an empty 0-terminated AZStd::string inline const char* GetExt(const char* filepath) { const char* str = filepath; @@ -174,7 +178,7 @@ namespace PathUtil } //! Extract path from full specified file path. - inline string GetPath(const string& filepath) + inline AZStd::string GetPath(const AZStd::string& filepath) { const char* str = filepath.c_str(); for (const char* p = str + filepath.length() - 1; p >= str; --p) @@ -191,9 +195,9 @@ namespace PathUtil } //! Extract path from full specified file path. - inline string GetPath(const char* filepath) + inline AZStd::string GetPath(const char* filepath) { - return GetPath(string(filepath)); + return GetPath(AZStd::string(filepath)); } //! Extract path from full specified file path. @@ -214,7 +218,7 @@ namespace PathUtil } //! Extract file name with extension from full specified file path. - inline string GetFile(const string& filepath) + inline AZStd::string GetFile(const AZStd::string& filepath) { const char* str = filepath.c_str(); for (const char* p = str + filepath.length() - 1; p >= str; --p) @@ -247,7 +251,7 @@ namespace PathUtil } //! Replace extension for given file. - inline void RemoveExtension(string& filepath) + inline void RemoveExtension(AZStd::string& filepath) { const char* str = filepath.c_str(); for (const char* p = str + filepath.length() - 1; p >= str; --p) @@ -291,15 +295,15 @@ namespace PathUtil } //! Extract file name without extension from full specified file path. - inline string GetFileName(const string& filepath) + inline AZStd::string GetFileName(const AZStd::string& filepath) { - string file = filepath; + AZStd::string file = filepath; RemoveExtension(file); return GetFile(file); } //! Removes the trailing slash or backslash from a given path. - inline string RemoveSlash(const string& path) + inline AZStd::string RemoveSlash(const AZStd::string& path) { if (path.empty() || (path[path.length() - 1] != '/' && path[path.length() - 1] != '\\')) { @@ -309,13 +313,13 @@ namespace PathUtil } //! get slash - inline string GetSlash() + inline AZStd::string GetSlash() { return CRY_NATIVE_PATH_SEPSTR; } //! add a backslash if needed - inline string AddSlash(const string& path) + inline AZStd::string AddSlash(const AZStd::string& path) { if (path.empty() || path[path.length() - 1] == '/') { @@ -343,9 +347,9 @@ namespace PathUtil } //! add a backslash if needed - inline string AddSlash(const char* path) + inline AZStd::string AddSlash(const char* path) { - return AddSlash(string(path)); + return AddSlash(AZStd::string(path)); } inline stack_string ReplaceExtension(const stack_string& filepath, const char* ext) @@ -364,9 +368,9 @@ namespace PathUtil } //! Replace extension for given file. - inline string ReplaceExtension(const string& filepath, const char* ext) + inline AZStd::string ReplaceExtension(const AZStd::string& filepath, const char* ext) { - string str = filepath; + AZStd::string str = filepath; if (ext != 0) { RemoveExtension(str); @@ -380,29 +384,30 @@ namespace PathUtil } //! Replace extension for given file. - inline string ReplaceExtension(const char* filepath, const char* ext) + inline AZStd::string ReplaceExtension(const char* filepath, const char* ext) { - return ReplaceExtension(string(filepath), ext); + return ReplaceExtension(AZStd::string(filepath), ext); } //! Makes a fully specified file path from path and file name. - inline string Make(const string& path, const string& file) + inline AZStd::string Make(const AZStd::string& path, const AZStd::string& file) { return AddSlash(path) + file; } //! Makes a fully specified file path from path and file name. - inline string Make(const string& dir, const string& filename, const string& ext) + inline AZStd::string Make(const AZStd::string& dir, const AZStd::string& filename, const AZStd::string& ext) { - string path = ReplaceExtension(filename, ext); + AZStd::string path = filename; + AZ::StringFunc::Path::ReplaceExtension(path, ext.c_str()); path = AddSlash(dir) + path; return path; } //! Makes a fully specified file path from path and file name. - inline string Make(const string& dir, const string& filename, const char* ext) + inline AZStd::string Make(const AZStd::string& dir, const AZStd::string& filename, const char* ext) { - return Make(dir, filename, string(ext)); + return Make(dir, filename, AZStd::string(ext)); } //! Makes a fully specified file path from path and file name. @@ -414,42 +419,43 @@ namespace PathUtil //! Makes a fully specified file path from path and file name. inline stack_string Make(const stack_string& dir, const stack_string& filename, const stack_string& ext) { - stack_string path = ReplaceExtension(filename, ext); - path = AddSlash(dir) + path; - return path; + AZStd::string path = filename.c_str(); + AZ::StringFunc::Path::ReplaceExtension(path, ext.c_str()); + path = AddSlash(dir.c_str()) + path; + return stack_string(path.c_str()); } //! Makes a fully specified file path from path and file name. - inline string Make(const char* path, const string& file) + inline AZStd::string Make(const char* path, const AZStd::string& file) { - return Make(string(path), file); + return Make(AZStd::string(path), file); } //! Makes a fully specified file path from path and file name. - inline string Make(const string& path, const char* file) + inline AZStd::string Make(const AZStd::string& path, const char* file) { - return Make(path, string(file)); + return Make(path, AZStd::string(file)); } //! Makes a fully specified file path from path and file name. - inline string Make(const char path[], const char file[]) + inline AZStd::string Make(const char path[], const char file[]) { - return Make(string(path), string(file)); + return Make(AZStd::string(path), AZStd::string(file)); } //! Makes a fully specified file path from path and file name. - inline string Make(const char* path, const char* file, const char* ext) + inline AZStd::string Make(const char* path, const char* file, const char* ext) { - return Make(string(path), string(file), string(ext)); + return Make(AZStd::string(path), AZStd::string(file), AZStd::string(ext)); } //! Makes a fully specified file path from path and file name. - inline string MakeFullPath(const string& relativePath) + inline AZStd::string MakeFullPath(const AZStd::string& relativePath) { return relativePath; } - inline string GetParentDirectory (const string& strFilePath, int nGeneration = 1) + inline AZStd::string GetParentDirectory (const AZStd::string& strFilePath, int nGeneration = 1) { for (const char* p = strFilePath.c_str() + strFilePath.length() - 2; // -2 is for the possible trailing slash: there always must be some trailing symbol which is the file/directory name for which we should get the parent p >= strFilePath.c_str(); @@ -458,23 +464,23 @@ namespace PathUtil switch (*p) { case ':': - return string (strFilePath.c_str(), p); + return AZStd::string(strFilePath.c_str(), p); case '/': case '\\': // we've reached a path separator - return everything before it. if (!--nGeneration) { - return string(strFilePath.c_str(), p); + return AZStd::string(strFilePath.c_str(), p); } break; } } // it seems the file name is a pure name, without path or extension - return string(); + return AZStd::string(); } template - inline CryStackStringT GetParentDirectoryStackString(const CryStackStringT& strFilePath, int nGeneration = 1) + inline AZStd::basic_fixed_string GetParentDirectoryStackString(const AZStd::basic_fixed_string& strFilePath, int nGeneration = 1) { for (const char* p = strFilePath.c_str() + strFilePath.length() - 2; // -2 is for the possible trailing slash: there always must be some trailing symbol which is the file/directory name for which we should get the parent p >= strFilePath.c_str(); @@ -483,19 +489,19 @@ namespace PathUtil switch (*p) { case ':': - return CryStackStringT (strFilePath.c_str(), p); + return AZStd::basic_fixed_string (strFilePath.c_str(), p); case '/': case '\\': // we've reached a path separator - return everything before it. if (!--nGeneration) { - return CryStackStringT(strFilePath.c_str(), p); + return AZStd::basic_fixed_string(strFilePath.c_str(), p); } break; } } // it seems the file name is a pure name, without path or extension - return CryStackStringT(); + return AZStd::basic_fixed_string(); } ////////////////////////////////////////////////////////////////////////// @@ -503,7 +509,8 @@ namespace PathUtil // Make a game correct path out of any input path. inline stack_string MakeGamePath(const stack_string& path) { - stack_string relativePath(ToUnixPath(path)); + stack_string relativePath = path; + ToUnixPath(relativePath); if ((!gEnv) || (!gEnv->pFileIO)) { @@ -512,7 +519,7 @@ namespace PathUtil unsigned int index = 0; if (relativePath.length() && relativePath[index] == '@') // already aliased { - if (relativePath.compareNoCase(0, 9, "@assets@/") == 0) + if (AZ::StringFunc::Equal(relativePath.c_str(), "@assets@/", false, 9)) { return relativePath.substr(9); // assets is assumed. } @@ -526,7 +533,7 @@ namespace PathUtil if ( (rootPath.size() > 0) && (rootPath.size() < relativePath.size()) && - (relativePath.compareNoCase(0, rootPath.size(), rootPath) == 0) + (AZ::StringFunc::Equal(relativePath.c_str(), rootPath.c_str(), false, rootPath.size())) ) { stack_string chopped_string = relativePath.substr(rootPath.size()); @@ -543,13 +550,13 @@ namespace PathUtil ////////////////////////////////////////////////////////////////////////// // Description: // Make a game correct path out of any input path. - inline string MakeGamePath(const string& path) + inline AZStd::string MakeGamePath(const AZStd::string& path) { stack_string stackPath(path.c_str()); return MakeGamePath(stackPath).c_str(); } - // returns true if the string matches the wildcard + // returns true if the AZStd::string matches the wildcard inline bool MatchWildcard (const char* szString, const char* szWildcard) { const char* pString = szString, * pWildcard = szWildcard; @@ -595,7 +602,7 @@ namespace PathUtil if (!*pWildcard) { - return true; // the rest of the string doesn't matter: the wildcard ends with * + return true; // the rest of the AZStd::string doesn't matter: the wildcard ends with * } for (; *pString; ++pString) { diff --git a/Code/Legacy/CryCommon/CrySizer.h b/Code/Legacy/CryCommon/CrySizer.h index 9301360bd5..add2cdd397 100644 --- a/Code/Legacy/CryCommon/CrySizer.h +++ b/Code/Legacy/CryCommon/CrySizer.h @@ -208,9 +208,7 @@ public: this->AddObject(rPair.first); this->AddObject(rPair.second); } - void AddObject(const string& rString) {this->AddObject(rString.c_str(), rString.capacity()); } - void AddObject(const CryStringT& rString) {this->AddObject(rString.c_str(), rString.capacity()); } - void AddObject(const CryFixedStringT<32>&){} + void AddObject(const AZStd::string& rString) {this->AddObject(rString.c_str(), rString.capacity()); } void AddObject(const wchar_t&) {} void AddObject(const char&) {} void AddObject(const unsigned char&) {} @@ -427,7 +425,7 @@ public: #endif #ifndef NOT_USE_CRY_STRING - bool Add (const string& strText) + bool Add (const AZStd::string& strText) { AddString(strText); return true; diff --git a/Code/Legacy/CryCommon/CryString.h b/Code/Legacy/CryCommon/CryString.h deleted file mode 100644 index 459e25b63c..0000000000 --- a/Code/Legacy/CryCommon/CryString.h +++ /dev/null @@ -1,2523 +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 - * - */ - - -// Description : Custom reference counted string class. -// Can easily be substituted instead of string - - -#ifndef CRYINCLUDE_CRYCOMMON_CRYSTRING_H -#define CRYINCLUDE_CRYCOMMON_CRYSTRING_H -#pragma once - -#include -#include - -#if !defined(NOT_USE_CRY_STRING) - -#include -#include -#include -#include -#include -#include "LegacyAllocator.h" - -#define CRY_STRING - -// forward declaration of CryStackString -template -class CryStackStringT; - - -class CConstCharWrapper; //forward declaration for special const char * without memory allocations - -//extern void CryDebugStr( const char *format,... ); -//#define CRY_STRING_DEBUG(s) { if (*s) CryDebugStr( "[%6d] %s",_usedMemory(0),(s) );} -#define CRY_STRING_DEBUG(s) - -class CryStringAllocator - : public AZ::SimpleSchemaAllocator -{ -public: - AZ_TYPE_INFO(CryStringAllocator, "{763DFC83-8A6E-4FD9-B6BC-BBF56E93E4EE}"); - - using Base = AZ::SimpleSchemaAllocator; - using Descriptor = Base::Descriptor; - - CryStringAllocator() - : Base("CryStringAllocator", "Allocator for CryString") - { - Descriptor desc; - desc.m_systemChunkSize = 4 * 1024 * 1024; // grow by 4 MB at a time - desc.m_subAllocator = &AZ::AllocatorInstance::Get(); - Create(desc); - } -}; - -////////////////////////////////////////////////////////////////////////// -// CryStringT class. -////////////////////////////////////////////////////////////////////////// -template -class CryStringT -{ -public: - ////////////////////////////////////////////////////////////////////////// - // Types compatible with STL string. - ////////////////////////////////////////////////////////////////////////// - typedef CryStringT _Self; - typedef size_t size_type; - typedef T value_type; - typedef const value_type* const_str; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef pointer iterator; - typedef const_pointer const_iterator; - - enum _npos_type - { - npos = (size_type) ~0 - }; - - ////////////////////////////////////////////////////////////////////////// - // Constructors - ////////////////////////////////////////////////////////////////////////// - CryStringT(); - -protected: - CryStringT(const CConstCharWrapper& str); //ctor for strings without memory allocations - friend class CConstCharWrapper; -public: - - CryStringT(const _Self& str); - CryStringT(const _Self& str, size_type nOff, size_type nCount); - - // Before September 2012 this constructor looked like this: - // explicit CryStringT( value_type ch, size_type nRepeat = 1 ); - // It was very error-prone, because the matching constructor - // std::string constructor is different: - // std::string( size_type nRepeat, value_type ch ); - // - // To prevent hard-to-catch bugs, we removed all calls of this - // constructor in the existing CryEngine code (in September 2012) - // and started using proper order of parameters (matching std::). - // - // To catch calls using the reversed arguments in other projects, - // we retain the previous function with reversed arguments, - // and declare it private. - CryStringT(size_type nRepeat, value_type ch); -private: - CryStringT(value_type ch, size_type nRepeat); - -public: - - CryStringT(const_str str); - CryStringT(const_str str, size_type nLength); - CryStringT(const_iterator _First, const_iterator _Last); - ~CryStringT(); - - ////////////////////////////////////////////////////////////////////////// - // STL string like interface. - ////////////////////////////////////////////////////////////////////////// - //! Operators. - size_type length() const; - size_type size() const; - bool empty() const; - void clear(); // free up the data - - //! Returns the storage currently allocated to hold the string, a value at least as large as length(). - size_type capacity() const; - - // Sets the capacity of the string to a number at least as great as a specified number. - // nCount = 0 is shrinking string to fit number of characters in it. - void reserve(size_type nCount = 0); - - _Self& append(const value_type* _Ptr); - _Self& append(const value_type* _Ptr, size_type nCount); - _Self& append(const _Self& _Str, size_type nOff, size_type nCount); - _Self& append(const _Self& _Str); - _Self& append(size_type nCount, value_type _Ch); - _Self& append(const_iterator _First, const_iterator _Last); - - _Self& assign(const_str _Ptr); - _Self& assign(const_str _Ptr, size_type nCount); - _Self& assign(const _Self& _Str, size_type off, size_type nCount); - _Self& assign(const _Self& _Str); - _Self& assign(size_type nCount, value_type _Ch); - _Self& assign(const_iterator _First, const_iterator _Last); - - value_type at(size_type index) const; - - const_iterator begin() const { return m_str; }; - const_iterator end() const { return m_str + length(); }; - - iterator begin() { return m_str; }; - iterator end() { return m_str + length(); }; - - // Following functions are commented out because they provide direct write access to - // the string and such access doesn't work properly with our current reference-count - // implementation. - // If you really need write access to your string's elements, please consider - // using CryStackStringT<> instead of CryString<>. Alternatively, you can modify - // your string by multiple calls of erase() and append(). - // Note: If you need *linear memory read* access to your string's elements, use data() - // or c_str(). If you need *linear memory write* access to your string's elements, - // use a non-string class (std::vector<>, DynArray<>, etc.) instead of CryString<>. - //value_type& at( size_type index ); - //iterator begin() { return m_str; }; - //iterator end() { return m_str+length(); }; - - //! cast to C string operator. - operator const_str() const { - return m_str; - } - - //! cast to C string. - const value_type* c_str() const { return m_str; } - const value_type* data() const { return m_str; }; - - ////////////////////////////////////////////////////////////////////////// - // string comparison. - ////////////////////////////////////////////////////////////////////////// - int compare(const _Self& _Str) const; - int compare(size_type _Pos1, size_type _Num1, const _Self& _Str) const; - int compare(size_type _Pos1, size_type _Num1, const _Self& _Str, size_type nOff, size_type nCount) const; - int compare(const char* _Ptr) const; - int compare(const wchar_t* _Ptr) const; - int compare(size_type _Pos1, size_type _Num1, const value_type* _Ptr, size_type _Num2 = npos) const; - - // Case insensitive comparison - int compareNoCase(const _Self& _Str) const; - int compareNoCase(size_type _Pos1, size_type _Num1, const _Self& _Str) const; - int compareNoCase(size_type _Pos1, size_type _Num1, const _Self& _Str, size_type nOff, size_type nCount) const; - int compareNoCase(const value_type* _Ptr) const; - int compareNoCase(size_type _Pos1, size_type _Num1, const value_type* _Ptr, size_type _Num2 = npos) const; - - // Copies at most a specified number of characters from an indexed position in a source string to a target character array. - size_type copy(value_type* _Ptr, size_type nCount, size_type nOff = 0) const; - - void push_back(value_type _Ch) { _ConcatenateInPlace(&_Ch, 1); } - void resize(size_type nCount, value_type _Ch = ' '); - - //! simple sub-string extraction - _Self substr(size_type pos, size_type count = npos) const; - - // replace part of string. - _Self& replace(value_type chOld, value_type chNew); - _Self& replace(const_str strOld, const_str strNew); - _Self& replace(size_type pos, size_type count, const_str strNew); - _Self& replace(size_type pos, size_type count, const_str strNew, size_type count2); - _Self& replace(size_type pos, size_type count, size_type nNumChars, value_type chNew); - - // insert new elements to string. - _Self& insert(size_type nIndex, value_type ch); - _Self& insert(size_type nIndex, size_type nCount, value_type ch); - _Self& insert(size_type nIndex, const_str pstr); - _Self& insert(size_type nIndex, const_str pstr, size_type nCount); - - //! delete count characters starting at zero-based index - _Self& erase(size_type nIndex, size_type count = npos); - - //! searching (return starting index, or -1 if not found) - //! look for a single character match - //! like "C" strchr - size_type find(value_type ch, size_type pos = 0) const; - //! look for a specific sub-string - //! like "C" strstr - size_type find(const_str subs, size_type pos = 0) const; - size_type rfind(value_type ch, size_type pos = npos) const; - size_type rfind(const _Self& subs, size_type pos = 0) const; - - size_type find_first_of(value_type _Ch, size_type nOff = 0) const; - size_type find_first_of(const_str charSet, size_type nOff = 0) const; - //size_type find_first_of( const value_type* _Ptr,size_type _Off,size_type _Count ) const; - size_type find_first_of(const _Self& _Str, size_type _Off = 0) const; - - size_type find_first_not_of(value_type _Ch, size_type _Off = 0) const; - size_type find_first_not_of(const value_type* _Ptr, size_type _Off = 0) const; - size_type find_first_not_of(const value_type* _Ptr, size_type _Off, size_type _Count) const; - size_type find_first_not_of(const _Self& _Str, size_type _Off = 0) const; - - size_type find_last_of(value_type _Ch, size_type _Off = npos) const; - size_type find_last_of(const value_type* _Ptr, size_type _Off = npos) const; - size_type find_last_of(const value_type* _Ptr, size_type _Off, size_type _Count) const; - size_type find_last_of(const _Self& _Str, size_type _Off = npos) const; - - size_type find_last_not_of(value_type _Ch, size_type _Off = npos) const; - size_type find_last_not_of(const value_type* _Ptr, size_type _Off = npos) const; - size_type find_last_not_of(const value_type* _Ptr, size_type _Off, size_type _Count) const; - size_type find_last_not_of(const _Self& _Str, size_type _Off = npos) const; - - - void swap(_Self& _Str); - - ////////////////////////////////////////////////////////////////////////// - // overloaded operators. - ////////////////////////////////////////////////////////////////////////// - // overloaded indexing. - //value_type operator[]( size_type index ) const; // same as at() - // value_type& operator[]( size_type index ); // same as at() - - // overloaded assignment - _Self& operator=(const _Self& str); - _Self& operator=(value_type ch); - _Self& operator=(const_str str); - - template - CryStringT(const CryStackStringT& str); - -protected: - // we prohibit an implicit conversion from CryStackString to make user aware of allocation! - // -> use string(stackedString) instead - // as the private statement seems to be ignored (VS C++), we add a compile time error, see below - template - _Self& operator=(const CryStackStringT& str) - { - // we add a compile-time error as the Visual C++ compiler seems to ignore the private statement? -#if defined(__clang__) - //CLANG_TODO: clang verifies things differently -#else - static_assert(false, "Use explicit string assignment when assigning from_StackString"); -#endif - // not reached, as above will generate a compile time error - _Assign(str.c_str(), str.length()); - return *this; - } - -public: - // string concatenation - _Self& operator+=(const _Self& str); - _Self& operator+=(value_type ch); - _Self& operator+=(const_str str); - - //template friend CryStringT operator+( const CryStringT& str1, const CryStringT& str2 ); - //template friend CryStringT operator+( const CryStringT& str, value_type ch ); - //template friend CryStringT operator+( value_type ch, const CryStringT& str ); - //template friend CryStringT operator+( const CryStringT& str1, const_str str2 ); - //template friend CryStringT operator+( const_str str1, const CryStringT& str2 ); - - size_t GetAllocatedMemory() const - { - StrHeader* header = _header(); - if (header == _emptyHeader()) - { - return 0; - } - return sizeof(StrHeader) + (header->nAllocSize + 1) * sizeof(value_type); - } - - ////////////////////////////////////////////////////////////////////////// - // Extended functions. - // This functions are not in the STL string. - // They have an ATL CString interface. - ////////////////////////////////////////////////////////////////////////// - //! Format string, use (sprintf) - _Self& Format(const value_type* format, ...); - - //! Converts the string to lower-case - // This function uses the "C" locale for case-conversion (ie, A-Z only) - _Self& MakeLower(); - - //! Converts the string to upper-case - // This function uses the "C" locale for case-conversion (ie, A-Z only) - _Self& MakeUpper(); - - _Self& Trim(); - _Self& Trim(value_type ch); - _Self& Trim(const value_type* sCharSet); - - _Self& TrimLeft(); - _Self& TrimLeft(value_type ch); - _Self& TrimLeft(const value_type* sCharSet); - - _Self& TrimRight(); - _Self& TrimRight(value_type ch); - _Self& TrimRight(const value_type* sCharSet); - - _Self SpanIncluding(const_str charSet) const; - _Self SpanExcluding(const_str charSet) const; - _Self Tokenize(const_str charSet, int& nStart) const; - _Self Mid(size_type nFirst, size_type nCount = npos) const { return substr(nFirst, nCount); }; - - _Self Left(size_type count) const; - _Self Right(size_type count) const; - ////////////////////////////////////////////////////////////////////////// - - // public utilities. - static size_type _strlen(const_str str); - static size_type _strnlen(const_str str, size_type maxLen); - static const_str _strchr(const_str str, value_type c); - static const_str _strrchr(const_str str, value_type c); - static value_type* _strstr(value_type* str, const_str strSearch); - static bool _IsValidString(const_str str); - -#if defined(WIN32) || defined(WIN64) - static int _vscpf(const_str format, va_list args); -#endif - static int _vsnpf(value_type* buf, int cnt, const_str format, va_list args); - - -public: - ////////////////////////////////////////////////////////////////////////// - // Only used for debugging statistics. - ////////////////////////////////////////////////////////////////////////// - static size_t _usedMemory(ptrdiff_t size) - { - static size_t s_used_memory = 0; - s_used_memory += size; - return s_used_memory; - } - -protected: - value_type* m_str; // pointer to ref counted string data - - // String header. Immediately after this header in memory starts actual string data. - struct StrHeader - { - int nRefCount; - int nLength; - int nAllocSize; // Size of memory allocated at the end of this class. - - value_type* GetChars() { return (value_type*)(this + 1); } - void AddRef() { nRefCount++; /*InterlockedIncrement(&_header()->nRefCount);*/}; - int Release() { return --nRefCount; }; - }; - static StrHeader* _emptyHeader() - { - // Define 2 static buffers in a row. The 2nd is a dummy object to hold a single empty char string. - static StrHeader sEmptyStringBuffer[2] = { - {-1, 0, 0}, {0, 0, 0} - }; - return &sEmptyStringBuffer[0]; - } - - // implementation helpers - StrHeader* _header() const; - - void _AllocData(size_type nLen); - static void _FreeData(StrHeader* pData); - void _Free(); - void _Initialize(); - - void _Concatenate(const_str sStr1, size_type nLen1, const_str sStr2, size_type nLen2); - void _ConcatenateInPlace(const_str sStr, size_type nLen); - void _Assign(const_str sStr, size_type nLen); - void _MakeUnique(); - - static void _copy(value_type* dest, const value_type* src, size_type count); - static void _move(value_type* dest, const value_type* src, size_type count); - static void _set(value_type* dest, value_type ch, size_type count); -}; - -// Variant of CryStringT which does not share memory with other strings. -template -class CryStringLocalT - : public CryStringT -{ -public: - typedef CryStringT BaseType; - typedef typename BaseType::const_str const_str; - typedef typename BaseType::value_type value_type; - typedef typename BaseType::size_type size_type; - typedef typename BaseType::iterator iterator; - - CryStringLocalT() - {} - CryStringLocalT(const CryStringLocalT& str) - : BaseType(str.c_str()) - {} - CryStringLocalT(const BaseType& str) - : BaseType(str.c_str()) - {} - template - CryStringLocalT(const CryStackStringT& str) - : BaseType(str.c_str()) - {} - CryStringLocalT(const_str str) - : BaseType(str) - {} - CryStringLocalT(const_str str, size_t len) - : BaseType(str, len) - {} - CryStringLocalT(const_str begin, const_str end) - : BaseType(begin, end) - {} - CryStringLocalT(size_type nRepeat, value_type ch) - : BaseType(nRepeat, ch) - {} - - CryStringLocalT(const typename CryStringT::_Self& str, size_type nOff, size_type nCount) - : BaseType(str, nOff, nCount) - {} - - CryStringLocalT& operator=(const BaseType& str) - { - BaseType::operator=(str.c_str()); - return *this; - } - CryStringLocalT& operator=(const CryStringLocalT& str) - { - BaseType::operator=(str.c_str()); - return *this; - } - CryStringLocalT& operator=(const_str str) - { - BaseType::operator=(str); - return *this; - } - iterator begin() { return BaseType::m_str; } - using BaseType::begin; // const version - iterator end() { return BaseType::m_str + BaseType::length(); } - using BaseType::end; // const version -}; - -typedef CryStringLocalT CryStringLocal; - - -// wrapper class for creation of strings without memory allocation -// it creates a string with pointer pointing to const char* location -// destructor sets the string to empty -// NOTE: never copy a string from it, just use it as function parameters instead of const char* itself -class CConstCharWrapper -{ -public: - //passing *this is safe since the char pointer is already set and therefore is the this-ptr constructed complete enough -#pragma warning (push) -#pragma warning (disable : 4355) - CConstCharWrapper(const char* const cpString) - : cpChar(cpString) - , str(*this){AZ_Assert(cpString, "c-string parameter cannot be nullptr"); } //create stack string -#pragma warning (pop) - ~CConstCharWrapper(){str.m_str = CryStringT::_emptyHeader()->GetChars(); }//reset string - operator const CryStringT&() const { - return str; - } //cast operator to const string reference -private: - const char* const cpChar; - CryStringT str; - - char* GetCharPointer() const {return const_cast(cpChar); } //access function for string ctor - - friend class CryStringT; //both are bidirectional friends to avoid any other accesses -}; - - -//macro needed because compiler somehow cannot find the cast operator when not invoked directly -#define CONST_TEMP_STRING(a) ((const string&)CConstCharWrapper(a)) - -///////////////////////////////////////////////////////////////////////////// -// CryStringT Implementation -////////////////////////////////////////////////////////////////////////// - -template -inline typename CryStringT::StrHeader * CryStringT::_header() const -{ - AZ_Assert(m_str != nullptr, "string header is nullptr"); - return ((StrHeader*)m_str) - 1; -} - -template -inline typename CryStringT::size_type CryStringT::_strlen(const_str str) -{ - return (str == NULL) ? 0 : (size_type)::strlen(str); -} - -template <> -inline CryStringT::size_type CryStringT::_strlen(const_str str) -{ - return (str == NULL) ? 0 : (size_type)::wcslen(str); -} - -template -inline typename CryStringT::size_type CryStringT::_strnlen(const_str str, size_type maxLen) -{ - size_type len = 0; - if (str) - { - while (len < maxLen && *str != '\0') - { - len++; - str++; - } - } - return len; -} - -template -inline typename CryStringT::const_str CryStringT::_strchr(const_str str, value_type c) -{ - return (str == NULL) ? 0 : ::strchr(str, c); -} - -template <> -inline CryStringT::const_str CryStringT::_strchr(const_str str, value_type c) -{ - return (str == NULL) ? 0 : ::wcschr(str, c); -} - -template -inline typename CryStringT::const_str CryStringT::_strrchr(const_str str, value_type c) -{ - return (str == NULL) ? 0 : ::strrchr(str, c); -} - -template <> -inline CryStringT::const_str CryStringT::_strrchr(const_str str, value_type c) -{ - return (str == NULL) ? 0 : ::wcsrchr(str, c); -} - -template -inline typename CryStringT::value_type * CryStringT::_strstr(value_type * str, const_str strSearch) -{ - return (str == NULL) ? 0 : (value_type*)::strstr(str, strSearch); -} - -template <> -inline CryStringT::value_type * CryStringT::_strstr(value_type * str, const_str strSearch) -{ - return (str == NULL) ? 0 : ::wcsstr(str, strSearch); -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStringT::_copy(value_type* dest, const value_type* src, size_type count) -{ - if (dest != src) - { - memcpy(dest, src, count * sizeof(value_type)); - } -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStringT::_move(value_type* dest, const value_type* src, size_type count) -{ - memmove(dest, src, count * sizeof(value_type)); -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStringT::_set(value_type* dest, value_type ch, size_type count) -{ - static_assert(sizeof(value_type) == sizeof(T)); - static_assert(sizeof(value_type) == 1); - memset(dest, ch, count); -} - -////////////////////////////////////////////////////////////////////////// -template <> -inline void CryStringT::_set(value_type* dest, value_type ch, size_type count) -{ - static_assert(sizeof(value_type) == sizeof(wchar_t)); - wmemset(dest, ch, count); -} - -#if defined(WIN32) || defined(WIN64) - -template<> -inline int CryStringT::_vscpf(const_str format, va_list args) -{ - return _vscprintf(format, args); -} - -template<> -inline int CryStringT::_vscpf(const_str format, va_list args) -{ - return _vscwprintf(format, args); -} - -template<> -inline int CryStringT::_vsnpf(value_type* buf, int cnt, const_str format, va_list args) -{ - return azvsnprintf(buf, cnt, format, args); -} - -template<> -inline int CryStringT::_vsnpf(value_type* buf, int cnt, const_str format, va_list args) -{ - return azvsnwprintf(buf, cnt, format, args); -} - -#else - -template<> -inline int CryStringT::_vsnpf(value_type* buf, int cnt, const_str format, va_list args) -{ - return vsnprintf(buf, cnt, format, args); -} - -template<> -inline int CryStringT::_vsnpf(value_type* buf, int cnt, const_str format, va_list args) -{ - return vswprintf(buf, cnt, format, args); -} - -#endif - -////////////////////////////////////////////////////////////////////////// -template -inline bool CryStringT::_IsValidString(const_str) -{ - /* - if (str == NULL) - return false; - int nLength = _strlen(str); - return !::IsBadStringPtrA(str, nLength); - */ - return true; -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStringT::_Assign(const_str sStr, size_type nLen) -{ - // Check if this string is shared (reference count greater then 1) or not enough capacity to store new string. - // Then allocate new string buffer. - if (_header()->nRefCount > 1 || nLen > capacity()) - { - _Free(); - _AllocData(nLen); - } - // Copy characters from new string to this buffer. - _copy(m_str, sStr, nLen); - // Set new length. - _header()->nLength = aznumeric_cast(nLen); - // Make null terminated string. - m_str[nLen] = 0; - CRY_STRING_DEBUG(m_str) -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStringT::_Concatenate(const_str sStr1, size_type nLen1, const_str sStr2, size_type nLen2) -{ - size_type nLen = nLen1 + nLen2; - - if (nLen1 * 2 > nLen) - { - nLen = nLen1 * 2; - } - - if (nLen != 0) - { - if (nLen < 8) - { - nLen = 8; - } - - _AllocData(nLen); - _copy(m_str, sStr1, nLen1); - _copy(m_str + nLen1, sStr2, nLen2); - _header()->nLength = aznumeric_cast(nLen1 + nLen2); - m_str[nLen1 + nLen2] = 0; - } - CRY_STRING_DEBUG(m_str) -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStringT::_ConcatenateInPlace(const_str sStr, size_type nLen) -{ - if (nLen != 0) - { - // Check if this string is shared (reference count greater then 1) or not enough capacity to store new string. - // Then allocate new string buffer. - if (_header()->nRefCount > 1 || length() + nLen > capacity()) - { - StrHeader* pOldData = _header(); - _Concatenate(m_str, length(), sStr, nLen); - _FreeData(pOldData); - } - else - { - _copy(m_str + length(), sStr, nLen); - _header()->nLength = aznumeric_cast(_header()->nLength + nLen); - m_str[_header()->nLength] = 0; // Make null terminated string. - } - } -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStringT::_MakeUnique() -{ - if (_header()->nRefCount > 1) - { - // If string is shared, make a copy of string buffer. - StrHeader* pOldData = _header(); - // This will not free header because reference count is greater then 1. - _Free(); - // Allocate a new string buffer. - _AllocData(pOldData->nLength); - // Full copy of null terminated string. - _copy(m_str, pOldData->GetChars(), pOldData->nLength + 1); - CRY_STRING_DEBUG(m_str) - } -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStringT::_Initialize() -{ - m_str = _emptyHeader()->GetChars(); -} - -// always allocate one extra character for '\0' termination -// assumes [optimistically] that data length will equal allocation length -template -inline void CryStringT::_AllocData(size_type nLen) -{ - AZ_Assert(nLen <= (std::numeric_limits::max)() - 1, "New string allocation size %zu is greater than the max allowed size of %d", - nLen, (std::numeric_limits::max)() - 1); // max size (enough room for 1 extra) - - if (nLen == 0) - { - _Initialize(); - } - else - { - size_type allocLen = sizeof(StrHeader) + (nLen + 1) * sizeof(value_type); - - StrHeader* pData = (StrHeader*)azmalloc(allocLen, 32, CryStringAllocator); - - _usedMemory(allocLen); // For statistics. - pData->nRefCount = 1; - m_str = pData->GetChars(); - pData->nLength = aznumeric_cast(nLen); - pData->nAllocSize = aznumeric_cast(nLen); - m_str[nLen] = 0; // null terminated string. - } -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStringT::_Free() -{ - if (_header()->nRefCount >= 0) // Not empty string. - { - _FreeData(_header()); - _Initialize(); - } -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStringT::_FreeData(StrHeader* pData) -{ - //Cry uses -1 to represent strings on the stack. - if (pData->nRefCount < 0) - { - return; - } - - if (pData->nRefCount == 0 || pData->Release() <= 0) - { - azfree((void*)pData, CryStringAllocator); - } -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT::CryStringT() -{ - _Initialize(); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT::CryStringT(const CryStringT& str) -{ - AZ_Assert(str._header()->nRefCount != 0, "Reference count input cry string should be greater than 0"); - if (str._header()->nRefCount >= 0) - { - m_str = str.m_str; - _header()->AddRef(); - } - else - { - _Initialize(); - } -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT::CryStringT(const CryStringT& str, size_type nOff, size_type nCount) -{ - _Initialize(); - assign(str, nOff, nCount); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT::CryStringT(const_str str) -{ - _Initialize(); - // Make a copy of C string. - size_type nLen = _strlen(str); - if (nLen != 0) - { - _AllocData(nLen); - _copy(m_str, str, nLen); - CRY_STRING_DEBUG(m_str) - } -} - -template -inline CryStringT::CryStringT(const CConstCharWrapper& str) -{ - _Initialize(); - m_str = const_cast(str.GetCharPointer()); -} - -template -template -inline CryStringT::CryStringT(const CryStackStringT& str) -{ - _Initialize(); - const size_type nLength = str.length(); - if (nLength > 0) - { - _AllocData(nLength); - _copy(m_str, str, nLength); - CRY_STRING_DEBUG(m_str) - } -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT::CryStringT(const_str str, size_type nLength) -{ - _Initialize(); - if (nLength > 0) - { - _AllocData(nLength); - _copy(m_str, str, nLength); - CRY_STRING_DEBUG(m_str) - } -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT::CryStringT(size_type nRepeat, value_type ch) -{ - _Initialize(); - if (nRepeat > 0) - { - _AllocData(nRepeat); - _set(m_str, ch, nRepeat); - CRY_STRING_DEBUG(m_str) - } -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT::CryStringT(const_iterator _First, const_iterator _Last) -{ - _Initialize(); - size_type nLength = (size_type)(_Last - _First); - if (nLength > 0) - { - _AllocData(nLength); - _copy(m_str, _First, nLength); - CRY_STRING_DEBUG(m_str) - } -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT::~CryStringT() -{ - _FreeData(_header()); -} - -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStringT::size_type CryStringT::length() const -{ - return _header()->nLength; -} -template -inline typename CryStringT::size_type CryStringT::size() const -{ - return _header()->nLength; -} -template -inline typename CryStringT::size_type CryStringT::capacity() const -{ - return _header()->nAllocSize; -} - -template -inline bool CryStringT::empty() const -{ - return length() == 0; -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStringT::clear() -{ - if (length() == 0) - { - return; - } - if (_header()->nRefCount >= 0) - { - _Free(); - } - else - { - resize(0); - } - AZ_Assert(length() == 0, "Cleared string should have a length of 0"); - AZ_Assert(_header()->nRefCount < 0 || capacity() == 0, - "Cleared string should have a reference count or capacity of 0"); -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStringT::reserve(size_type nCount) -{ - // Reserve of 0 is shrinking container to fit number of characters in it.. - if (nCount > capacity()) - { - StrHeader* pOldData = _header(); - _AllocData(nCount); - _copy(m_str, pOldData->GetChars(), pOldData->nLength); - _header()->nLength = pOldData->nLength; - m_str[pOldData->nLength] = 0; - _FreeData(pOldData); - } - else if (nCount == 0) - { - if (length() != capacity()) - { - StrHeader* pOldData = _header(); - _AllocData(length()); - _copy(m_str, pOldData->GetChars(), pOldData->nLength); - _FreeData(pOldData); - } - } - CRY_STRING_DEBUG(m_str) -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::append(const_str _Ptr) -{ - *this += _Ptr; - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::append(const_str _Ptr, size_type nCount) -{ - _ConcatenateInPlace(_Ptr, nCount); - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::append(const CryStringT& _Str, size_type off, size_type nCount) -{ - size_type len = _Str.length(); - if (off > len) - { - return *this; - } - if (off + nCount > len) - { - nCount = len - off; - } - _ConcatenateInPlace(_Str.m_str + off, nCount); - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::append(const CryStringT& _Str) -{ - *this += _Str; - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::append(size_type nCount, value_type _Ch) -{ - if (nCount > 0) - { - if (_header()->nRefCount > 1 || length() + nCount > capacity()) - { - StrHeader* pOldData = _header(); - _AllocData(length() + nCount); - _copy(m_str, pOldData->GetChars(), pOldData->nLength); - _set(m_str + pOldData->nLength, _Ch, nCount); - _FreeData(pOldData); - } - else - { - size_type nOldLength = length(); - _set(m_str + nOldLength, _Ch, nCount); - _header()->nLength = aznumeric_cast(nOldLength + nCount); - m_str[length()] = 0; // Make null terminated string. - } - } - CRY_STRING_DEBUG(m_str) - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::append(const_iterator _First, const_iterator _Last) -{ - append(_First, (size_type)(_Last - _First)); - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::assign(const_str _Ptr) -{ - *this = _Ptr; - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::assign(const_str _Ptr, size_type nCount) -{ - size_type len = _strnlen(_Ptr, nCount); - _Assign(_Ptr, len); - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::assign(const CryStringT& _Str, size_type off, size_type nCount) -{ - size_type len = _Str.length(); - if (off > len) - { - return *this; - } - if (off + nCount > len) - { - nCount = len - off; - } - _Assign(_Str.m_str + off, nCount); - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::assign(const CryStringT& _Str) -{ - *this = _Str; - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::assign(size_type nCount, value_type _Ch) -{ - if (nCount >= 1) - { - _AllocData(nCount); - _set(m_str, _Ch, nCount); - CRY_STRING_DEBUG(m_str) - } - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::assign(const_iterator _First, const_iterator _Last) -{ - assign(_First, (size_type)(_Last - _First)); - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStringT::value_type CryStringT::at(size_type index) const -{ - AZ_Assert(index >= 0 && index < length(), "index into CryString is out of range"); - return m_str[index]; -} - -////////////////////////////////////////////////////////////////////////// -template -inline int CryStringT::compare(const CryStringT& _Str) const -{ - return compare(_Str.m_str); -} - -template -inline int CryStringT::compare(size_type _Pos1, size_type _Num1, const CryStringT& _Str) const -{ - return compare(_Pos1, _Num1, _Str.m_str, npos); -} - -template -inline int CryStringT::compare(size_type _Pos1, size_type _Num1, const CryStringT& _Str, size_type nOff, size_type nCount) const -{ - AZ_Assert(nOff < _Str.length(), "Offset into input string is larger than the index range"); - return compare(_Pos1, _Num1, _Str.m_str + nOff, nCount); -} - -template -inline int CryStringT::compare(const char* _Ptr) const -{ - return strcmp(m_str, _Ptr); -} - -template -inline int CryStringT::compare(const wchar_t* _Ptr) const -{ - return wcscmp(m_str, _Ptr); -} - -template -inline int CryStringT::compare(size_type _Pos1, size_type _Num1, const value_type* _Ptr, size_type _Num2) const -{ - AZ_Assert(_Pos1 < length(), "position index to compare is larger than the length of this string"); - if (length() - _Pos1 < _Num1) - { - _Num1 = length() - _Pos1; // trim to size - } - int res = _Num1 == 0 ? 0 : strncmp(m_str + _Pos1, _Ptr, (_Num1 < _Num2) ? _Num1 : _Num2); - return (res != 0 ? res : _Num2 == npos && _Ptr[_Num1] == 0 ? 0 : _Num1 < _Num2 ? -1 : _Num1 == _Num2 ? 0 : +1); -} - -////////////////////////////////////////////////////////////////////////// -template -inline int CryStringT::compareNoCase(const CryStringT& _Str) const -{ - return _stricmp(m_str, _Str.m_str); -} - -template -inline int CryStringT::compareNoCase(size_type _Pos1, size_type _Num1, const CryStringT& _Str) const -{ - return compareNoCase(_Pos1, _Num1, _Str.m_str, npos); -} - -template -inline int CryStringT::compareNoCase(size_type _Pos1, size_type _Num1, const CryStringT& _Str, size_type nOff, size_type nCount) const -{ - AZ_Assert(nOff < _Str.length(), "offset to start comparison within input string is larger than the string index range"); - return compareNoCase(_Pos1, _Num1, _Str.m_str + nOff, nCount); -} - -template -inline int CryStringT::compareNoCase(const value_type* _Ptr) const -{ - return _stricmp(m_str, _Ptr); -} - -template -inline int CryStringT::compareNoCase(size_type _Pos1, size_type _Num1, const value_type* _Ptr, size_type _Num2) const -{ - AZ_Assert(_Pos1 < length(), "Position to start case-insensitive search is larger the indexable range"); - if (length() - _Pos1 < _Num1) - { - _Num1 = length() - _Pos1; // trim to size - } - int res = _Num1 == 0 ? 0 : _strnicmp(m_str + _Pos1, _Ptr, (_Num1 < _Num2) ? _Num1 : _Num2); - return (res != 0 ? res : _Num2 == npos && _Ptr[_Num1] == 0 ? 0 : _Num1 < _Num2 ? -1 : _Num1 == _Num2 ? 0 : +1); -} - -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStringT::size_type CryStringT::copy(value_type* _Ptr, size_type nCount, size_type nOff) const -{ - AZ_Assert(nOff < length(), "Offset to copy from string to output address is outside the indexable range"); - if (nCount < 0) - { - nCount = 0; - } - if (nOff + nCount > length()) // trim to offset. - { - nCount = length() - nOff; - } - - _copy(_Ptr, m_str + nOff, nCount); - return nCount; -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStringT::resize(size_type nCount, value_type _Ch) -{ - _MakeUnique(); - if (nCount > length()) - { - size_type numToAdd = nCount - length(); - append(numToAdd, _Ch); - } - else if (nCount < length()) - { - _header()->nLength = static_cast(nCount); - m_str[length()] = 0; // Make null terminated string. - } -} - -////////////////////////////////////////////////////////////////////////// -//! compare helpers -template -inline bool operator==(const CryStringT& s1, const CryStringT& s2) -{ return s1.compare(s2) == 0; } -template -inline bool operator==(const CryStringT& s1, const typename CryStringT::value_type* s2) -{ return s1.compare(s2) == 0; } -template -inline bool operator==(const typename CryStringT::value_type* s1, const CryStringT& s2) -{ return s2.compare(s1) == 0; } -template -inline bool operator!=(const CryStringT& s1, const CryStringT& s2) -{ return s1.compare(s2) != 0; } -template -inline bool operator!=(const CryStringT& s1, const typename CryStringT::value_type* s2) -{ return s1.compare(s2) != 0; } -template -inline bool operator!=(const typename CryStringT::value_type* s1, const CryStringT& s2) -{ return s2.compare(s1) != 0; } -template -inline bool operator<(const CryStringT& s1, const CryStringT& s2) -{ return s1.compare(s2) < 0; } -template -inline bool operator<(const CryStringT& s1, const typename CryStringT::value_type* s2) -{ return s1.compare(s2) < 0; } -template -inline bool operator<(const typename CryStringT::value_type* s1, const CryStringT& s2) -{ return s2.compare(s1) > 0; } -template -inline bool operator>(const CryStringT& s1, const CryStringT& s2) -{ return s1.compare(s2) > 0; } -template -inline bool operator>(const CryStringT& s1, const typename CryStringT::value_type* s2) -{ return s1.compare(s2) > 0; } -template -inline bool operator>(const typename CryStringT::value_type* s1, const CryStringT& s2) -{ return s2.compare(s1) < 0; } -template -inline bool operator<=(const CryStringT& s1, const CryStringT& s2) -{ return s1.compare(s2) <= 0; } -template -inline bool operator<=(const CryStringT& s1, const typename CryStringT::value_type* s2) -{ return s1.compare(s2) <= 0; } -template -inline bool operator<=(const typename CryStringT::value_type* s1, const CryStringT& s2) -{ return s2.compare(s1) >= 0; } -template -inline bool operator>=(const CryStringT& s1, const CryStringT& s2) -{ return s1.compare(s2) >= 0; } -template -inline bool operator>=(const CryStringT& s1, const typename CryStringT::value_type* s2) -{ return s1.compare(s2) >= 0; } -template -inline bool operator>=(const typename CryStringT::value_type* s1, const CryStringT& s2) -{ return s2.compare(s1) <= 0; } - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::operator=(value_type ch) -{ - _Assign(&ch, 1); - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT operator+(const CryStringT& string1, typename CryStringT::value_type ch) -{ - CryStringT s(string1); - s.append(1, ch); - return s; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT operator+(typename CryStringT::value_type ch, const CryStringT& str) -{ - CryStringT s; - s.reserve(str.size() + 1); - s.append(1, ch); - s.append(str); - return s; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT operator+(const CryStringT& string1, const CryStringT& string2) -{ - CryStringT s(string1); - s.append(string2); - return s; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT operator+(const CryStringT& str1, const typename CryStringT::value_type* str2) -{ - CryStringT s(str1); - s.append(str2); - return s; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT operator+(const typename CryStringT::value_type* str1, const CryStringT& str2) -{ - AZ_Assert(str1 == nullptr || CryStringT::_IsValidString(str1), "Input string is not valid"); - CryStringT s; - s.reserve(CryStringT::_strlen(str1) + str2.size()); - s.append(str1); - s.append(str2); - return s; -} - -template -inline CryStringT& CryStringT::operator=(const CryStringT& str) -{ - if (m_str != str.m_str) - { - if (_header()->nRefCount < 0) - { - // Empty string. - // _Assign( str.m_str,str.length() ); - if (str._header()->nRefCount < 0) - { - ; // two empty strings... - } - else - { - m_str = str.m_str; - _header()->AddRef(); - } - } - else if (str._header()->nRefCount < 0) - { - // If source string is empty. - _Free(); - m_str = str.m_str; - } - else - { - // Copy string reference. - _Free(); - m_str = str.m_str; - _header()->AddRef(); - } - } - return *this; -} - -template -inline CryStringT& CryStringT::operator=(const_str str) -{ - AZ_Assert(str == nullptr || _IsValidString(str), "Input string is not valid"); - _Assign(str, _strlen(str)); - return *this; -} - -template -inline CryStringT& CryStringT::operator+=(const_str str) -{ - AZ_Assert(str == nullptr || _IsValidString(str), "Input string is not valid"); - _ConcatenateInPlace(str, _strlen(str)); - return *this; -} - -template -inline CryStringT& CryStringT::operator+=(value_type ch) -{ - _ConcatenateInPlace(&ch, 1); - return *this; -} - -template -inline CryStringT& CryStringT::operator+=(const CryStringT& str) -{ - _ConcatenateInPlace(str.m_str, str.length()); - return *this; -} - -//! find first single character -template -inline typename CryStringT::size_type CryStringT::find(value_type ch, size_type pos) const -{ - if (!(pos >= 0 && pos <= length())) - { - return (typename CryStringT::size_type)npos; - } - const_str str = _strchr(m_str + pos, ch); - // return npos if not found and index otherwise - return (str == NULL) ? npos : (size_type)(str - m_str); -} - -//! find a sub-string (like strstr) -template -inline typename CryStringT::size_type CryStringT::find(const_str subs, size_type pos) const -{ - AZ_Assert(_IsValidString(subs), "Input string is not valid"); - if (!(pos >= 0 && pos <= length())) - { - return npos; - } - - // find first matching substring - const_str str = _strstr(m_str + pos, subs); - - // return npos for not found, distance from beginning otherwise - return (str == NULL) ? npos : (size_type)(str - m_str); -} - -//! find last single character -template -inline typename CryStringT::size_type CryStringT::rfind(value_type ch, size_type pos) const -{ - const_str str; - if (pos == npos) - { - // find last single character - str = _strrchr(m_str, ch); - // return -1 if not found, distance from beginning otherwise - return (str == NULL) ? (size_type) - 1 : (size_type)(str - m_str); - } - else - { - if (pos == npos) - { - pos = length(); - } - if (!(pos >= 0 && pos <= length())) - { - return npos; - } - - value_type tmp = m_str[pos + 1]; - m_str[pos + 1] = 0; - str = _strrchr(m_str, ch); - m_str[pos + 1] = tmp; - } - // return -1 if not found, distance from beginning otherwise - return (str == NULL) ? (size_type) - 1 : (size_type)(str - m_str); -} - -template -inline typename CryStringT::size_type CryStringT::rfind(const CryStringT& subs, size_type pos) const -{ - size_type res = npos; - for (int i = (int)size(); i >= (int)pos; --i) - { - size_type findRes = find(subs, i); - if (findRes != npos) - { - res = findRes; - break; - } - } - return res; -} - -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStringT::size_type CryStringT::find_first_of(const CryStringT& _Str, size_type _Off) const -{ - return find_first_of(_Str.m_str, _Off); -} - -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStringT::size_type CryStringT::find_first_of(value_type _Ch, size_type nOff) const -{ - if (!(nOff >= 0 && nOff <= length())) - { - return npos; - } - value_type charSet[2] = { _Ch, 0 }; - const_str str = strpbrk(m_str + nOff, charSet); - return (str == NULL) ? (size_type) - 1 : (size_type)(str - m_str); -} - -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStringT::size_type CryStringT::find_first_of(const_str charSet, size_type nOff) const -{ - AZ_Assert(_IsValidString(charSet), "input c-string must not be nullptr"); - if (!(nOff >= 0 && nOff <= length())) - { - return npos; - } - const_str str = strpbrk(m_str + nOff, charSet); - return (str == NULL) ? (size_type) - 1 : (size_type)(str - m_str); -} - -template <> -inline CryStringT::size_type CryStringT::find_first_of(const_str charSet, size_type nOff) const -{ - AZ_Assert(_IsValidString(charSet), "input c-string must not be nullptr"); - if (!(nOff >= 0 && nOff <= length())) - { - return npos; - } - const_str str = wcspbrk(m_str + nOff, charSet); - return (str == NULL) ? (size_type) - 1 : (size_type)(str - m_str); -} - -//size_type find_first_not_of(const _Self& __s, size_type __pos = 0) const -//{ return find_first_not_of(__s._M_start, __pos, __s.size()); } - -//size_type find_first_not_of(const _CharT* __s, size_type __pos = 0) const -//{ _STLP_FIX_LITERAL_BUG(__s) return find_first_not_of(__s, __pos, _Traits::length(__s)); } - -//size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const; - -//size_type find_first_not_of(_CharT __c, size_type __pos = 0) const; - - -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStringT::size_type CryStringT::find_first_not_of(const value_type* _Ptr, size_type _Off) const -{ return find_first_not_of(_Ptr, _Off, _strlen(_Ptr)); } - -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStringT::size_type CryStringT::find_first_not_of(const CryStringT& _Str, size_type _Off) const -{ return find_first_not_of(_Str.m_str, _Off); } - -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStringT::size_type CryStringT::find_first_not_of(value_type _Ch, size_type _Off) const -{ - if (_Off > length()) - { - return npos; - } - else - { - for (const value_type* str = begin() + _Off; str != end(); ++str) - { - if (*str != _Ch) - { - return size_type(str - begin()); // Character found! - } - } - return npos; - } -} - -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStringT::size_type CryStringT::find_first_not_of(const value_type* _Ptr, size_type _Off, size_type _Count) const -{ - if (_Off > length()) - { - return npos; - } - else - { - const value_type* charsFirst = _Ptr, * charsLast = _Ptr + _Count; - for (const value_type* str = begin() + _Off; str != end(); ++str) - { - const value_type* c; - for (c = charsFirst; c != charsLast; ++c) - { - if (*c == *str) - { - break; - } - } - if (c == charsLast) - { - return size_type(str - begin());// Current character not in char set. - } - } - return npos; - } -} -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStringT::size_type CryStringT::find_last_of(value_type _Ch, size_type _Off) const -{ - size_type nLenght(length()); - // Empty strings, always return npos (same semantic as std::string). - if (nLenght == 0) - { - return npos; - } - - // If the offset is is bigger than the size of the string - if (_Off >= nLenght) - { - // We set it to the size of the string -1, so we will not do bad pointer operations nor we will - // test the null terminating character. - _Off = nLenght - 1; - } - - // From the character at the offset position, going to to the direction of the first character. - for (const value_type* str = begin() + _Off; true; --str) - { - // We found a character in the string which matches the input character. - if (*str == _Ch) - { - return size_type(str - begin()); // Character found! - } - // If the next element will be begin()-1, then we should stop. - if (str == begin()) - { - break; - } - } - - // We found nothing. - return npos; -} -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStringT::size_type CryStringT::find_last_of(const value_type* _Ptr, size_type _Off) const -{ - // This function is actually a convenience alias... - // BTW: what will happeb if wchar_t is used here? - return find_last_of(_Ptr, _Off, _strlen(_Ptr)); -} -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStringT::size_type CryStringT::find_last_of(const value_type* _Ptr, size_type _Off, size_type _Count) const -{ - size_type nLenght(length()); - // Empty strings, always return npos (same semantic as std::string). - if (nLenght == 0) - { - return npos; - } - - // If the offset is is bigger than the size of the string - if (_Off >= nLenght) - { - // We set it to the size of the string -1, so we will not do bad pointer operations nor we will - // test the null terminating character. - _Off = nLenght - 1; - } - - // From the character at the offset position, going to to the direction of the first character. - const value_type* charsFirst = _Ptr, * charsLast = _Ptr + _Count; - for (const value_type* str = begin() + _Off; true; --str) - { - const value_type* c; - // For every character in the character set. - for (c = charsFirst; c != charsLast; ++c) - { - // If the current character matches any of the charcaters in the input string... - if (*c == *str) - { - // This is the value we must return. - return size_type(str - begin()); - } - } - - // If the next element will be begin()-1, then we should stop. - if (str == begin()) - { - break; - } - } - // We couldn't find any character of the input string in the current string. - return npos; -} -///////////////////////////////////////////////////////////////////////////// -template -inline typename CryStringT::size_type CryStringT::find_last_of(const _Self& strCharSet, size_type _Off) const -{ - size_type nLenght(length()); - // Empty strings, always return npos (same semantic as std::string). - if (nLenght == 0) - { - return npos; - } - - // If the offset is is bigger than the size of the string - if (_Off >= nLenght) - { - // We set it to the size of the string -1, so we will not do bad pointer operations nor we will - // test the null terminating character. - _Off = nLenght - 1; - } - - - // From the character at the offset position, going to to the direction of the first character. - for (const value_type* str = begin() + _Off; true; --str) - { - // We check every character of the input string. - for (const value_type* strInputCharacter = strCharSet.begin(); strInputCharacter != strCharSet.end(); ++strInputCharacter) - { - // If any character matches. - if (*str == *strInputCharacter) - { - // We return the position where we found it. - return size_type(str - begin()); // Character found! - } - } - // If the next element will be begin()-1, then we should stop. - if (str == begin()) - { - break; - } - } - - // As we couldn't find any matching character...we return the appropriate value. - return npos; -} -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStringT::size_type CryStringT::find_last_not_of(value_type _Ch, size_type _Off) const -{ - size_type nLenght(length()); - // Empty strings, always return npos (same semantic as std::string). - if (nLenght == 0) - { - return npos; - } - - // If the offset is is bigger than the size of the string - if (_Off >= nLenght) - { - // We set it to the size of the string -1, so we will not do bad pointer operations nor we will - // test the null terminating character. - _Off = nLenght - 1; - } - - - // From the character at the offset position, going to to the direction of the first character. - for (const value_type* str = begin() + _Off; true; --str) - { - // If the current character being analyzed is different of the input character. - if (*str != _Ch) - { - // We found the last item which is not the input character before the given offset. - return size_type(str - begin()); // Character found! - } - // If the next element will be begin()-1, then we should stop. - if (str == begin()) - { - break; - } - } - - // As we couldn't find any matching character...we return the appropriate value. - return npos; -} -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStringT::size_type CryStringT::find_last_not_of(const value_type* _Ptr, size_type _Off) const -{ - // This function is actually a convenience alias... - // BTW: what will happeb if wchar_t is used here? - return find_last_not_of(_Ptr, _Off, _strlen(_Ptr)); -} -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStringT::size_type CryStringT::find_last_not_of(const value_type* _Ptr, size_type _Off, size_type _Count) const -{ - size_type nLenght(length()); - // Empty strings, always return npos (same semantic as std::string). - if (nLenght == 0) - { - return npos; - } - - // If the offset is is bigger than the size of the string - if (_Off >= nLenght) - { - // We set it to the size of the string -1, so we will not do bad pointer operations nor we will - // test the null terminating character. - _Off = nLenght - 1; - } - - - // From the character at the offset position, going to to the direction of the first character. - const value_type* charsFirst = _Ptr, * charsLast = _Ptr + _Count; - for (const value_type* str = begin() + _Off; true; --str) - { - bool boFoundAny(false); - const value_type* c; - // For every character in the character set. - for (c = charsFirst; c != charsLast; ++c) - { - // If the current character matches any of the charcaters in the input string... - if (*c == *str) - { - // So we signal it was found and stop this search. - boFoundAny = true; - break; - } - } - - // Using a different solution of the other similar methods - // to make it easier to read. - // If the character being analyzed is not in the set... - if (!boFoundAny) - { - //.. we return the position where we found it. - return size_type(str - begin()); - } - - // If the next element will be begin()-1, then we should stop. - if (str == begin()) - { - break; - } - } - // We couldn't find any character of the input string not in the character set. - return npos; -} -////////////////////////////////////////////////////////////////////////// -template -inline typename CryStringT::size_type CryStringT::find_last_not_of(const _Self& _Str, size_type _Off) const -{ - size_type nLenght(length()); - // Empty strings, always return npos (same semantic as std::string). - if (nLenght == 0) - { - return npos; - } - - // If the offset is is bigger than the size of the string - if (_Off >= nLenght) - { - // We set it to the size of the string -1, so we will not do bad pointer operations nor we will - // test the null terminating character. - _Off = nLenght - 1; - } - - - // From the character at the offset position, going to to the direction of the first character. - for (const value_type* str = begin() + _Off; true; --str) - { - bool boFoundAny(false); - for (const value_type* strInputCharacter = _Str.begin(); strInputCharacter != _Str.end(); ++strInputCharacter) - { - // The character matched one of the character set... - if (*strInputCharacter == *str) - { - // So we signal it was found and stop this search. - boFoundAny = true; - break; - } - } - - // Using a different solution of the other similar methods - // to make it easier to read. - // If the character being analyzed is not in the set... - if (!boFoundAny) - { - //.. we return the position where we found it. - return size_type(str - begin()); - } - - // If the next element will be begin()-1, then we should stop. - if (str == begin()) - { - break; - } - } - - // As we couldn't find any matching character...we return the appropriate value. - return npos; -} -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT CryStringT::substr(size_type pos, size_type count) const -{ - if (pos >= length()) - { - return CryStringT(); - } - if (count == npos) - { - count = length() - pos; - } - if (pos + count > length()) - { - count = length() - pos; - } - return CryStringT(m_str + pos, count); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::erase(size_type nIndex, size_type nCount) -{ - if (nIndex < 0) - { - nIndex = 0; - } - if (nCount < 0 || nCount > length() - nIndex) - { - nCount = length() - nIndex; - } - if (nCount > 0 && nIndex < length()) - { - _MakeUnique(); - size_type nNumToCopy = length() - (nIndex + nCount) + 1; - _move(m_str + nIndex, m_str + nIndex + nCount, nNumToCopy); - _header()->nLength = static_cast(length() - nCount); - } - - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::insert(size_type nIndex, value_type ch) -{ - return insert(nIndex, 1, ch); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::insert(size_type nIndex, size_type nCount, value_type ch) -{ - _MakeUnique(); - - if (nIndex < 0) - { - nIndex = 0; - } - - size_type nNewLength = length(); - if (nIndex > nNewLength) - { - nIndex = nNewLength; - } - nNewLength += nCount; - - if (capacity() < nNewLength) - { - StrHeader* pOldData = _header(); - const_str pstr = m_str; - _AllocData(nNewLength); - _copy(m_str, pstr, pOldData->nLength + 1); - _FreeData(pOldData); - } - - _move(m_str + nIndex + nCount, m_str + nIndex, (nNewLength - nIndex - nCount) + 1); - _set(m_str + nIndex, ch, nCount); - _header()->nLength = static_cast(nNewLength); - CRY_STRING_DEBUG(m_str) - - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::insert(size_type nIndex, const_str pstr, size_type nCount) -{ - if (nIndex < 0) - { - nIndex = 0; - } - - size_type nInsertLength = nCount; - size_type nNewLength = length(); - if (nInsertLength > 0) - { - _MakeUnique(); - if (nIndex > nNewLength) - { - nIndex = nNewLength; - } - nNewLength += nInsertLength; - - if (capacity() < nNewLength) - { - StrHeader* pOldData = _header(); - const_str pOldStr = m_str; - _AllocData(nNewLength); - _copy(m_str, pOldStr, (pOldData->nLength + 1)); - _FreeData(pOldData); - } - - _move(m_str + nIndex + nInsertLength, m_str + nIndex, (nNewLength - nIndex - nInsertLength + 1)); - _copy(m_str + nIndex, pstr, nInsertLength); - _header()->nLength = static_cast(nNewLength); - m_str[length()] = 0; - } - CRY_STRING_DEBUG(m_str) - - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::insert(size_type nIndex, const_str pstr) -{ - return insert(nIndex, pstr, _strlen(pstr)); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::replace(size_type pos, size_type count, const_str strNew) -{ - return replace(pos, count, strNew, _strlen(strNew)); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::replace(size_type pos, size_type count, const_str strNew, size_type count2) -{ - erase(pos, count); - insert(pos, strNew, count2); - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::replace(size_type pos, size_type count, size_type nNumChars, value_type chNew) -{ - erase(pos, count); - insert(pos, nNumChars, chNew); - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::replace(value_type chOld, value_type chNew) -{ - if (chOld != chNew) - { - _MakeUnique(); - value_type* strend = m_str + length(); - for (value_type* str = m_str; str != strend; ++str) - { - if (*str == chOld) - { - *str = chNew; - } - } - } - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::replace(const_str strOld, const_str strNew) -{ - size_type nSourceLen = _strlen(strOld); - if (nSourceLen == 0) - { - return *this; - } - size_type nReplacementLen = _strlen(strNew); - - size_type nCount = 0; - value_type* strStart = m_str; - value_type* strEnd = m_str + length(); - value_type* strTarget; - while (strStart < strEnd) - { - while ((strTarget = _strstr(strStart, strOld)) != NULL) - { - nCount++; - strStart = strTarget + nSourceLen; - } - strStart += _strlen(strStart) + 1; - } - - if (nCount > 0) - { - _MakeUnique(); - - size_type nOldLength = length(); - size_type nNewLength = nOldLength + (nReplacementLen - nSourceLen) * nCount; - if (capacity() < nNewLength || _header()->nRefCount > 1) - { - StrHeader* pOldData = _header(); - const_str pstr = m_str; - _AllocData(nNewLength); - _copy(m_str, pstr, pOldData->nLength); - _FreeData(pOldData); - } - strStart = m_str; - strEnd = m_str + length(); - - while (strStart < strEnd) - { - while ((strTarget = _strstr(strStart, strOld)) != NULL) - { - size_type nBalance = nOldLength - ((size_type)(strTarget - m_str) + nSourceLen); - _move(strTarget + nReplacementLen, strTarget + nSourceLen, nBalance); - _copy(strTarget, strNew, nReplacementLen); - strStart = strTarget + nReplacementLen; - strStart[nBalance] = 0; - nOldLength += (nReplacementLen - nSourceLen); - } - strStart += _strlen(strStart) + 1; - } - _header()->nLength = static_cast(nNewLength); - } - CRY_STRING_DEBUG(m_str) - - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline void CryStringT::swap(CryStringT& _Str) -{ - value_type* temp = _Str.m_str; - _Str.m_str = m_str; - m_str = temp; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::Format(const_str format, ...) -{ - AZ_Assert(_IsValidString(format), "format c-string must not be nullptr"); - -#if defined(WIN32) || defined(WIN64) - va_list argList; - va_start(argList, format); - int n = _vscpf(format, argList); - if (n < 0) - { - n = 0; - } - resize(n); //this will actually allocate n+1 elements to accommodate the null terminator - _vsnpf(m_str, n, format, argList); - va_end(argList); - return *this; -#else - value_type temp[4096]; // Limited to 4096 characters! - va_list argList; - va_start(argList, format); - _vsnpf(temp, 4096, format, argList); - temp[4095] = '\0'; - va_end(argList); - *this = temp; - return *this; -#endif -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::MakeLower() -{ - _MakeUnique(); - for (value_type* s = m_str; *s != 0; s++) - { - const value_type c = *s; - *s = (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; // ASCII only, standard "C" locale - } - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::MakeUpper() -{ - _MakeUnique(); - for (value_type* s = m_str; *s != 0; s++) - { - const value_type c = *s; - *s = (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; // ASCII only, standard "C" locale - } - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::Trim() -{ - return TrimRight().TrimLeft(); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::Trim(value_type ch) -{ - _MakeUnique(); - const value_type chset[2] = { ch, 0 }; - return TrimRight(chset).TrimLeft(chset); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::Trim(const value_type* sCharSet) -{ - _MakeUnique(); - return TrimRight(sCharSet).TrimLeft(sCharSet); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::TrimRight(value_type ch) -{ - const value_type chset[2] = { ch, 0 }; - return TrimRight(chset); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::TrimRight(const value_type* sCharSet) -{ - if (!sCharSet || !(*sCharSet) || length() < 1) - { - return *this; - } - - const value_type* last = m_str + length() - 1; - const value_type* str = last; - while ((str != m_str) && (_strchr(sCharSet, *str) != 0)) - { - str--; - } - - if (str != last) - { - // Just shrink length of the string. - size_type nNewLength = (size_type)(str - m_str) + 1; // m_str can change in _MakeUnique - _MakeUnique(); - _header()->nLength = static_cast(nNewLength); - m_str[nNewLength] = 0; - } - - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::TrimRight() -{ - if (length() < 1) - { - return *this; - } - - const value_type* last = m_str + length() - 1; - const value_type* str = last; - while ((str != m_str) && (isspace((unsigned char)*str) != 0)) - { - str--; - } - - if (str != last) // something changed? - { - // Just shrink length of the string. - size_type nNewLength = (size_type)(str - m_str) + 1; // m_str can change in _MakeUnique - _MakeUnique(); - _header()->nLength = static_cast(nNewLength); - m_str[nNewLength] = 0; - } - - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::TrimLeft(value_type ch) -{ - const value_type chset[2] = { ch, 0 }; - return TrimLeft(chset); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::TrimLeft(const value_type* sCharSet) -{ - if (!sCharSet || !(*sCharSet)) - { - return *this; - } - - const value_type* str = m_str; - while ((*str != 0) && (_strchr(sCharSet, *str) != 0)) - { - str++; - } - - if (str != m_str) - { - size_type nOff = (size_type)(str - m_str); // m_str can change in _MakeUnique - _MakeUnique(); - size_type nNewLength = length() - nOff; - _move(m_str, m_str + nOff, nNewLength + 1); - _header()->nLength = static_cast(nNewLength); - m_str[nNewLength] = 0; - } - - return *this; -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT& CryStringT::TrimLeft() -{ - const value_type* str = m_str; - while ((*str != 0) && (isspace((unsigned char)*str) != 0)) - { - str++; - } - - if (str != m_str) - { - size_type nOff = (size_type)(str - m_str); // m_str can change in _MakeUnique - _MakeUnique(); - size_type nNewLength = length() - nOff; - _move(m_str, m_str + nOff, nNewLength + 1); - _header()->nLength = static_cast(nNewLength); - m_str[nNewLength] = 0; - } - - return *this; -} - -template -inline CryStringT CryStringT::Right(size_type count) const -{ - if (count == npos) - { - return CryStringT(); - } - else if (count > length()) - { - return *this; - } - - return CryStringT(m_str + length() - count, count); -} - -template -inline CryStringT CryStringT::Left(size_type count) const -{ - if (count == npos) - { - return CryStringT(); - } - else if (count > length()) - { - count = length(); - } - - return CryStringT(m_str, count); -} - -// strspn equivalent -template -inline CryStringT CryStringT::SpanIncluding(const_str charSet) const -{ - AZ_Assert(_IsValidString(charSet), "input c-string must not be nullptr"); - return Left((size_type)strspn(m_str, charSet)); -} - -// strcspn equivalent -template -inline CryStringT CryStringT::SpanExcluding(const_str charSet) const -{ - AZ_Assert(_IsValidString(charSet), "input c-string must not be nullptr"); - return Left((size_type)strcspn(m_str, charSet)); -} - -////////////////////////////////////////////////////////////////////////// -template -inline CryStringT CryStringT::Tokenize(const_str charSet, int& nStart) const -{ - if (nStart < 0) - { - return CryStringT(); - } - - if (!charSet) - { - return *this; - } - - const_str sPlace = m_str + nStart; - const_str sEnd = m_str + length(); - if (sPlace < sEnd) - { - int nIncluding = (int)strspn(sPlace, charSet); - - if ((sPlace + nIncluding) < sEnd) - { - sPlace += nIncluding; - int nExcluding = (int)strcspn(sPlace, charSet); - int nFrom = nStart + nIncluding; - nStart = nFrom + nExcluding + 1; - - return substr(nFrom, nExcluding); - } - } - // Return empty string. - nStart = -1; - return CryStringT(); -} - -////////////////////////////////////////////////////////////////////////// -// This code prevents std::string compiling in Win32 with STLPort -////////////////////////////////////////////////////////////////////////// -#if defined(WIN32) && !defined(WIN64) && defined(_STLP_BEGIN_NAMESPACE) && !defined(DONT_BAN_STD_STRING) -#define CRYINCLUDE_STLP_STRING_FWD_H -#define CRYINCLUDE_STLP_INTERNAL_STRING_H -namespace std -{ - //const char* __get_c_string( const CryStringT &str ) { return str.c_str(); }; - class string - { - // std::string must not be used if CryString included. - // Use string instead. - }; -} -////////////////////////////////////////////////////////////////////////// -#endif // WIN64 - -typedef CryStringT string; -typedef CryStringT wstring; - -#else // !defined(NOT_USE_CRY_STRING) - -#include // STL string -typedef std::string string; -typedef std::wstring wstring; - -#endif // !defined(NOT_USE_CRY_STRING) - -namespace AZStd -{ - template <> - struct hash<::string> - { - typedef ::string argument_type; - typedef size_t result_type; - inline result_type operator()(const argument_type& value) const - { - return hash_string(value.c_str(), value.length()); - } - - static size_t hash_string(const char* str, size_t length) - { - size_t hash = 14695981039346656037ULL; - const size_t fnvPrime = 1099511628211ULL; - const char* cptr = str; - for (; length; --length) - { - hash ^= static_cast(*cptr++); - hash *= fnvPrime; - } - return hash; - } - }; -} - -#endif // CRYINCLUDE_CRYCOMMON_CRYSTRING_H diff --git a/Code/Legacy/CryCommon/CryThread_windows.h b/Code/Legacy/CryCommon/CryThread_windows.h index cc09cc530b..dee99ee66f 100644 --- a/Code/Legacy/CryCommon/CryThread_windows.h +++ b/Code/Legacy/CryCommon/CryThread_windows.h @@ -225,7 +225,7 @@ private: volatile bool m_bIsStarted; volatile bool m_bIsRunning; volatile bool m_bCreatedThread; - string m_name; + AZStd::string m_name; protected: virtual void Terminate() diff --git a/Code/Legacy/CryCommon/CryTypeInfo.cpp b/Code/Legacy/CryCommon/CryTypeInfo.cpp index bd2bfb8bb2..82743f7eef 100644 --- a/Code/Legacy/CryCommon/CryTypeInfo.cpp +++ b/Code/Legacy/CryCommon/CryTypeInfo.cpp @@ -16,6 +16,7 @@ #include "CrySizer.h" #include "CryEndian.h" #include "TypeInfo_impl.h" +#include // Traits #if defined(AZ_RESTRICTED_PLATFORM) @@ -114,7 +115,7 @@ TYPE_INFO_INT(uint64) TYPE_INFO_BASIC(float) TYPE_INFO_BASIC(double) -TYPE_INFO_BASIC(string) +TYPE_INFO_BASIC(AZStd::string) const CTypeInfo&PtrTypeInfo() @@ -129,10 +130,9 @@ const CTypeInfo&PtrTypeInfo() // String conversion functions needed by TypeInfo. // bool -string ToString(bool const& val) +AZStd::string ToString(bool const& val) { - static string sTrue = "true", sFalse = "false"; - return val ? sTrue : sFalse; + return val ? "true" : "false"; } bool FromString(bool& val, cstr s) @@ -151,14 +151,14 @@ bool FromString(bool& val, cstr s) } // int64 -string ToString(int64 const& val) +AZStd::string ToString(int64 const& val) { char buffer[64]; _i64toa_s(val, buffer, sizeof(buffer), 10); return buffer; } // uint64 -string ToString(uint64 const& val) +AZStd::string ToString(uint64 const& val) { char buffer[64]; sprintf_s(buffer, "%" PRIu64, val); @@ -168,7 +168,7 @@ string ToString(uint64 const& val) // long -string ToString(long const& val) +AZStd::string ToString(long const& val) { char buffer[64]; _ltoa_s(val, buffer, sizeof(buffer), 10); @@ -176,7 +176,7 @@ string ToString(long const& val) } // ulong -string ToString(unsigned long const& val) +AZStd::string ToString(unsigned long const& val) { char buffer[64]; _ultoa_s(val, buffer, sizeof(buffer), 10); @@ -233,33 +233,33 @@ bool FromString(uint64& val, const char* s) { return Clamped bool FromString(long& val, const char* s) { return ClampedIntFromString(val, s); } bool FromString(unsigned long& val, const char* s) { return ClampedIntFromString(val, s); } -string ToString(int const& val) { return ToString(long(val)); } +AZStd::string ToString(int const& val) { return ToString(long(val)); } bool FromString(int& val, const char* s) { return ClampedIntFromString(val, s); } -string ToString(unsigned int const& val) { return ToString((unsigned long)(val)); } +AZStd::string ToString(unsigned int const& val) { return ToString((unsigned long)(val)); } bool FromString(unsigned int& val, const char* s) { return ClampedIntFromString(val, s); } -string ToString(short const& val) { return ToString(long(val)); } +AZStd::string ToString(short const& val) { return ToString(long(val)); } bool FromString(short& val, const char* s) { return ClampedIntFromString(val, s); } -string ToString(unsigned short const& val) { return ToString((unsigned long)(val)); } +AZStd::string ToString(unsigned short const& val) { return ToString((unsigned long)(val)); } bool FromString(unsigned short& val, const char* s) { return ClampedIntFromString(val, s); } -string ToString(char const& val) { return ToString(long(val)); } +AZStd::string ToString(char const& val) { return ToString(long(val)); } bool FromString(char& val, const char* s) { return ClampedIntFromString(val, s); } -string ToString(wchar_t const& val) { return ToString(long(val)); } +AZStd::string ToString(wchar_t const& val) { return ToString(long(val)); } bool FromString(wchar_t& val, const char* s) { return ClampedIntFromString(val, s); } -string ToString(signed char const& val) { return ToString(long(val)); } +AZStd::string ToString(signed char const& val) { return ToString(long(val)); } bool FromString(signed char& val, const char* s) { return ClampedIntFromString(val, s); } -string ToString(unsigned char const& val) { return ToString((unsigned long)(val)); } +AZStd::string ToString(unsigned char const& val) { return ToString((unsigned long)(val)); } bool FromString(unsigned char& val, const char* s) { return ClampedIntFromString(val, s); } -string ToString(const AZ::Uuid& val) +AZStd::string ToString(const AZ::Uuid& val) { - return val.ToString(); + return val.ToString(); } bool FromString(AZ::Uuid& val, const char* s) @@ -295,7 +295,7 @@ float NumToFromString(float val, int digits, bool floating, char buffer[], int b } // double -string ToString(double const& val) +AZStd::string ToString(double const& val) { char buffer[64]; sprintf_s(buffer, "%.16g", val); @@ -307,7 +307,7 @@ bool FromString(double& val, const char* s) } // float -string ToString(float const& val) +AZStd::string ToString(float const& val) { char buffer[64]; for (int digits = 7; digits < 10; digits++) @@ -329,11 +329,11 @@ bool FromString(float& val, const char* s) // string override. template <> -void TTypeInfo::GetMemoryUsage(ICrySizer* pSizer, void const* data) const +void TTypeInfo::GetMemoryUsage(ICrySizer* pSizer, void const* data) const { // CRAIG: just a temp hack to try and get things working #if !defined(LINUX) && !defined(APPLE) - pSizer->AddString(*(string*)data); + pSizer->AddString(*(AZStd::string*)data); #endif } @@ -343,7 +343,7 @@ struct STypeInfoTest { STypeInfoTest() { - TestType(string("well")); + TestType(AZStd::string("well")); TestType(true); @@ -435,7 +435,7 @@ bool CTypeInfo::CVarInfo::GetAttr(cstr name) const return FindAttr(Attrs, name) != 0; } -bool CTypeInfo::CVarInfo::GetAttr(cstr name, string& val) const +bool CTypeInfo::CVarInfo::GetAttr(cstr name, AZStd::string& val) const { cstr valstr = FindAttr(Attrs, name); if (!valstr) @@ -459,7 +459,7 @@ bool CTypeInfo::CVarInfo::GetAttr(cstr name, string& val) const end--; } } - val = string(valstr, end - valstr); + val = AZStd::string(valstr, end - valstr); return true; } @@ -735,7 +735,7 @@ bool CStructInfo::ToValue(const void* data, void* value, const CTypeInfo& typeVa Nameless , 1, ,2 1,2 ; */ -static void StripCommas(string& str) +static void StripCommas(AZStd::string& str) { size_t nLast = str.size(); while (nLast > 0 && str[nLast - 1] == ',') @@ -745,9 +745,9 @@ static void StripCommas(string& str) str.resize(nLast); } -string CStructInfo::ToString(const void* data, FToString flags, const void* def_data) const +AZStd::string CStructInfo::ToString(const void* data, FToString flags, const void* def_data) const { - string str; // Return str. + AZStd::string str; // Return str. for (int i = 0; i < Vars.size(); i++) { @@ -763,7 +763,7 @@ string CStructInfo::ToString(const void* data, FToString flags, const void* def_ str += ","; } - string substr = var.ToString(data, FToString(flags).Sub(0), def_data); + AZStd::string substr = var.ToString(data, FToString(flags).Sub(0), def_data); if (flags.SkipDefault && substr.empty()) { @@ -772,7 +772,7 @@ string CStructInfo::ToString(const void* data, FToString flags, const void* def_ if (flags.NamedFields) { - if (*str) + if (*str.c_str()) { str += ","; } @@ -782,7 +782,7 @@ string CStructInfo::ToString(const void* data, FToString flags, const void* def_ str += "="; } } - if (substr.find(',') != string::npos || substr.find('=') != string::npos) + if (substr.find(',') != AZStd::string::npos || substr.find('=') != AZStd::string::npos) { // Encase nested composite types in parens. str += "("; @@ -811,7 +811,7 @@ string CStructInfo::ToString(const void* data, FToString flags, const void* def_ // Retrieve and return one subelement from src, advancing the pointer. // Copy to tempstr if necessary. -typedef CryStackStringT CTempStr; +typedef AZStd::fixed_string<256> CTempStr; void ParseElement(cstr& src, cstr& varname, cstr& val, CTempStr& tempstr) { @@ -882,21 +882,24 @@ void ParseElement(cstr& src, cstr& varname, cstr& val, CTempStr& tempstr) if (*end) { // Must copy sub string to temp. - val = (cstr)tempstr + (val - varname); - eq = (cstr)tempstr + (eq - varname); - varname = tempstr.assign(varname, end); + val = tempstr.c_str() + (val - varname); + eq = tempstr.c_str() + (eq - varname); + tempstr.assign(varname, end); + varname = tempstr.c_str(); non_const(*eq) = 0; } else { // Copy just varname to temp, return val in place. - varname = tempstr.assign(varname, eq); + tempstr.assign(varname, eq); + varname = tempstr.c_str(); } } else if (*end) { // Must copy sub string to temp. - val = tempstr.assign(val, end); + tempstr.assign(val, end); + val = tempstr.c_str(); } // Else can return val without copying. @@ -963,7 +966,7 @@ void CStructInfo::SwapEndian(void* data, size_t nCount, bool bWriting) const { non_const(*this).MakeEndianDesc(); - if (EndianDesc.length() == 1 && !HasBitfields && EndianDescSize(EndianDesc) == Size) + if (EndianDesc.length() == 1 && !HasBitfields && EndianDescSize(EndianDesc.c_str()) == Size) { // Optimised array swap. size_t nElems = (EndianDesc[0u] & 0x3F) * nCount; @@ -989,7 +992,7 @@ void CStructInfo::SwapEndian(void* data, size_t nCount, bool bWriting) const // First swap bits. // Iterate the endian descriptor. void* step = data; - for (cstr desc = EndianDesc; *desc; desc++) + for (cstr desc = EndianDesc.c_str(); *desc; desc++) { size_t nElems = *desc & 0x3F; switch (*desc & 0xC0) @@ -1064,7 +1067,7 @@ void CStructInfo::MakeEndianDesc() // Struct-computed endian desc. CStructInfo const& infoSub = static_cast(var.Type); non_const(infoSub).MakeEndianDesc(); - subdesc = infoSub.EndianDesc; + subdesc = infoSub.EndianDesc.c_str(); if (!*subdesc) { // No swapping. diff --git a/Code/Legacy/CryCommon/CryTypeInfo.h b/Code/Legacy/CryCommon/CryTypeInfo.h index 43b9d3e5b9..0bd734492a 100644 --- a/Code/Legacy/CryCommon/CryTypeInfo.h +++ b/Code/Legacy/CryCommon/CryTypeInfo.h @@ -17,13 +17,12 @@ #include #include "CryArray.h" #include "Options.h" -#include "CryString.h" #include "TypeInfo_decl.h" class ICrySizer; class CCryName; -string ToString(CCryName const& val); +AZStd::string ToString(CCryName const& val); bool FromString(CCryName& val, const char* s); //--------------------------------------------------------------------------- @@ -85,7 +84,7 @@ struct CTypeInfo // // Convert value to string. - virtual string ToString([[maybe_unused]] const void* data, [[maybe_unused]] FToString flags = 0, [[maybe_unused]] const void* def_data = 0) const + virtual AZStd::string ToString([[maybe_unused]] const void* data, [[maybe_unused]] FToString flags = 0, [[maybe_unused]] const void* def_data = 0) const { return ""; } // Write value from string, return success. @@ -180,7 +179,7 @@ struct CTypeInfo assert(!bBitfield); return Type.FromString((char*)base + Offset, str, flags); } - string ToString(const void* base, FToString flags = 0, const void* def_base = 0) const + AZStd::string ToString(const void* base, FToString flags = 0, const void* def_base = 0) const { assert(!bBitfield); return Type.ToString((const char*)base + Offset, flags, def_base ? (const char*)def_base + Offset : 0); @@ -189,7 +188,7 @@ struct CTypeInfo // Attribute access. Not fast. bool GetAttr(cstr name) const; bool GetAttr(cstr name, float& val) const; - bool GetAttr(cstr name, string& val) const; + bool GetAttr(cstr name, AZStd::string& val) const; // Comment, excluding attributes. cstr GetComment() const; diff --git a/Code/Legacy/CryCommon/IConsole.h b/Code/Legacy/CryCommon/IConsole.h index 79bfc5b532..e03de35aa1 100644 --- a/Code/Legacy/CryCommon/IConsole.h +++ b/Code/Legacy/CryCommon/IConsole.h @@ -426,7 +426,7 @@ struct IConsole // szPrefix - 0 or prefix e.g. "sys_spec_" // Return // used size - virtual size_t GetSortedVars(const char** pszArray, size_t numItems, const char* szPrefix = 0) = 0; + virtual size_t GetSortedVars(AZStd::vector& pszArray, const char* szPrefix = 0) = 0; virtual const char* AutoComplete(const char* substr) = 0; virtual const char* AutoCompletePrev(const char* substr) = 0; virtual const char* ProcessCompletion(const char* szInputBuffer) = 0; diff --git a/Code/Legacy/CryCommon/IEntityRenderState.h b/Code/Legacy/CryCommon/IEntityRenderState.h index 9ee974b7fc..e9f041ba17 100644 --- a/Code/Legacy/CryCommon/IEntityRenderState.h +++ b/Code/Legacy/CryCommon/IEntityRenderState.h @@ -205,7 +205,7 @@ struct IRenderNode // Debug info about object. virtual const char* GetName() const = 0; virtual const char* GetEntityClassName() const = 0; - virtual string GetDebugString([[maybe_unused]] char type = 0) const { return ""; } + virtual AZStd::string GetDebugString([[maybe_unused]] char type = 0) const { return ""; } virtual float GetImportance() const { return 1.f; } // Description: diff --git a/Code/Legacy/CryCommon/IFont.h b/Code/Legacy/CryCommon/IFont.h index c95182abd7..41e9f5653a 100644 --- a/Code/Legacy/CryCommon/IFont.h +++ b/Code/Legacy/CryCommon/IFont.h @@ -16,7 +16,6 @@ #include #include -#include #include #include @@ -101,7 +100,7 @@ struct ICryFont // All font names separated by , // Example: // "console,default,hud" - virtual string GetLoadedFontNames() const = 0; + virtual AZStd::string GetLoadedFontNames() const = 0; //! \brief Called when the g_language (current language) setting changes. //! @@ -264,7 +263,7 @@ struct IFFont // Description: // Wraps text based on specified maximum line width (UTF-8) - virtual void WrapText(string& result, float maxWidth, const char* pStr, const STextDrawContext& ctx) = 0; + virtual void WrapText(AZStd::string& result, float maxWidth, const char* pStr, const STextDrawContext& ctx) = 0; // Description: // Puts the memory used by this font into the given sizer. @@ -338,7 +337,7 @@ struct FontFamily FontFamily& operator=(const FontFamily&) = delete; FontFamily& operator=(const FontFamily&&) = delete; - string familyName; + AZStd::string familyName; IFFont* normal; IFFont* bold; IFFont* italic; diff --git a/Code/Legacy/CryCommon/ILocalizationManager.h b/Code/Legacy/CryCommon/ILocalizationManager.h index de100152b3..2cba093f21 100644 --- a/Code/Legacy/CryCommon/ILocalizationManager.h +++ b/Code/Legacy/CryCommon/ILocalizationManager.h @@ -34,14 +34,14 @@ struct SLocalizedInfoGame } const char* szCharacterName; - string sUtf8TranslatedText; + AZStd::string sUtf8TranslatedText; bool bUseSubtitle; }; struct SLocalizedAdvancesSoundEntry { - string sName; + AZStd::string sName; float fValue; void GetMemoryUsage(ICrySizer* pSizer) const { @@ -178,12 +178,12 @@ struct ILocalizationManager // bEnglish - if true, translates the string into the always present English language. // Returns: // true if localization was successful, false otherwise - virtual bool LocalizeString_ch([[maybe_unused]] const char* sString, [[maybe_unused]] string& outLocalizedString, [[maybe_unused]] bool bEnglish = false) override { return false; } + virtual bool LocalizeString_ch([[maybe_unused]] const char* sString, [[maybe_unused]] AZStd::string& outLocalizedString, [[maybe_unused]] bool bEnglish = false) override { return false; } // Summary: - // Same as LocalizeString( const char* sString, string& outLocalizedString, bool bEnglish=false ) + // Same as LocalizeString( const char* sString, AZStd::string& outLocalizedString, bool bEnglish=false ) // but at the moment this is faster. - virtual bool LocalizeString_s([[maybe_unused]] const string& sString, [[maybe_unused]] string& outLocalizedString, [[maybe_unused]] bool bEnglish = false) override { return false; } + virtual bool LocalizeString_s([[maybe_unused]] const AZStd::string& sString, [[maybe_unused]] AZStd::string& outLocalizedString, [[maybe_unused]] bool bEnglish = false) override { return false; } // Summary: virtual void LocalizeAndSubstituteInternal([[maybe_unused]] AZStd::string& locString, [[maybe_unused]] const AZStd::vector& keys, [[maybe_unused]] const AZStd::vector& values) override {} @@ -196,7 +196,7 @@ struct ILocalizationManager // bEnglish - if true, returns the always present English version of the label. // Returns: // True if localization was successful, false otherwise. - virtual bool LocalizeLabel([[maybe_unused]] const char* sLabel, [[maybe_unused]] string& outLocalizedString, [[maybe_unused]] bool bEnglish = false) override { return false; } + virtual bool LocalizeLabel([[maybe_unused]] const char* sLabel, [[maybe_unused]] AZStd::string& outLocalizedString, [[maybe_unused]] bool bEnglish = false) override { return false; } virtual bool IsLocalizedInfoFound([[maybe_unused]] const char* sKey) { return false; } // Summary: @@ -251,7 +251,7 @@ struct ILocalizationManager // sLocalizedString - Corresponding english language string. // Returns: // True if successful, false otherwise (key not found). - virtual bool GetEnglishString([[maybe_unused]] const char* sKey, [[maybe_unused]] string& sLocalizedString) override { return false; } + virtual bool GetEnglishString([[maybe_unused]] const char* sKey, [[maybe_unused]] AZStd::string& sLocalizedString) override { return false; } // Summary: // Get Subtitle for Key or Label . @@ -261,21 +261,21 @@ struct ILocalizationManager // bForceSubtitle - If true, get subtitle (sLocalized or sEnglish) even if not specified in Data file. // Returns: // True if subtitle found (and outSubtitle filled in), false otherwise. - virtual bool GetSubtitle([[maybe_unused]] const char* sKeyOrLabel, [[maybe_unused]] string& outSubtitle, [[maybe_unused]] bool bForceSubtitle = false) override { return false; } + virtual bool GetSubtitle([[maybe_unused]] const char* sKeyOrLabel, [[maybe_unused]] AZStd::string& outSubtitle, [[maybe_unused]] bool bForceSubtitle = false) override { return false; } // Description: // These methods format outString depending on sString with ordered arguments // FormatStringMessage(outString, "This is %2 and this is %1", "second", "first"); // Arguments: // outString - This is first and this is second. - virtual void FormatStringMessage_List([[maybe_unused]] string& outString, [[maybe_unused]] const string& sString, [[maybe_unused]] const char** sParams, [[maybe_unused]] int nParams) override {} - virtual void FormatStringMessage([[maybe_unused]] string& outString, [[maybe_unused]] const string& sString, [[maybe_unused]] const char* param1, [[maybe_unused]] const char* param2 = 0, [[maybe_unused]] const char* param3 = 0, [[maybe_unused]] const char* param4 = 0) override {} + virtual void FormatStringMessage_List([[maybe_unused]] AZStd::string& outString, [[maybe_unused]] const AZStd::string& sString, [[maybe_unused]] const char** sParams, [[maybe_unused]] int nParams) override {} + virtual void FormatStringMessage([[maybe_unused]] AZStd::string& outString, [[maybe_unused]] const AZStd::string& sString, [[maybe_unused]] const char* param1, [[maybe_unused]] const char* param2 = 0, [[maybe_unused]] const char* param3 = 0, [[maybe_unused]] const char* param4 = 0) override {} - virtual void LocalizeTime([[maybe_unused]] time_t t, [[maybe_unused]] bool bMakeLocalTime, [[maybe_unused]] bool bShowSeconds, [[maybe_unused]] string& outTimeString) override {} - virtual void LocalizeDate([[maybe_unused]] time_t t, [[maybe_unused]] bool bMakeLocalTime, [[maybe_unused]] bool bShort, [[maybe_unused]] bool bIncludeWeekday, [[maybe_unused]] string& outDateString) override {} - virtual void LocalizeDuration([[maybe_unused]] int seconds, [[maybe_unused]] string& outDurationString) override {} - virtual void LocalizeNumber([[maybe_unused]] int number, [[maybe_unused]] string& outNumberString) override {} - virtual void LocalizeNumber_Decimal([[maybe_unused]] float number, [[maybe_unused]] int decimals, [[maybe_unused]] string& outNumberString) override {} + virtual void LocalizeTime([[maybe_unused]] time_t t, [[maybe_unused]] bool bMakeLocalTime, [[maybe_unused]] bool bShowSeconds, [[maybe_unused]] AZStd::string& outTimeString) override {} + virtual void LocalizeDate([[maybe_unused]] time_t t, [[maybe_unused]] bool bMakeLocalTime, [[maybe_unused]] bool bShort, [[maybe_unused]] bool bIncludeWeekday, [[maybe_unused]] AZStd::string& outDateString) override {} + virtual void LocalizeDuration([[maybe_unused]] int seconds, [[maybe_unused]] AZStd::string& outDurationString) override {} + virtual void LocalizeNumber([[maybe_unused]] int number, [[maybe_unused]] AZStd::string& outNumberString) override {} + virtual void LocalizeNumber_Decimal([[maybe_unused]] float number, [[maybe_unused]] int decimals, [[maybe_unused]] AZStd::string& outNumberString) override {} // Summary: // Returns true if the project has localization configured for use, false otherwise. diff --git a/Code/Legacy/CryCommon/ILog.h b/Code/Legacy/CryCommon/ILog.h index de60c1e9e0..e71e1f036d 100644 --- a/Code/Legacy/CryCommon/ILog.h +++ b/Code/Legacy/CryCommon/ILog.h @@ -145,9 +145,7 @@ struct ILog virtual void Unindent(class CLogIndenter* indenter) = 0; #endif -#if !defined(RESOURCE_COMPILER) virtual void FlushAndClose() = 0; -#endif }; #if !defined(SUPPORT_LOG_IDENTER) diff --git a/Code/Legacy/CryCommon/IMovieSystem.h b/Code/Legacy/CryCommon/IMovieSystem.h index 074c7ab01d..915dc925bf 100644 --- a/Code/Legacy/CryCommon/IMovieSystem.h +++ b/Code/Legacy/CryCommon/IMovieSystem.h @@ -112,7 +112,7 @@ public: CAnimParamType() : m_type(kAnimParamTypeInvalid) {} - CAnimParamType(const string& name) + CAnimParamType(const AZStd::string& name) { *this = name; } @@ -128,17 +128,12 @@ public: m_type = type; } - void operator =(const string& name) - { - m_type = kAnimParamTypeByString; - m_name = name; - } - void operator =(const AZStd::string& name) { m_type = kAnimParamTypeByString; m_name = name; } + // Convert to enum. This needs to be explicit, // otherwise operator== will be ambiguous AnimParamType GetType() const { return m_type; } @@ -1437,7 +1432,7 @@ inline void SAnimContext::Serialize(XmlNodeRef& xmlNode, bool bLoading) { if (sequence) { - string fullname = sequence->GetName(); + AZStd::string fullname = sequence->GetName(); xmlNode->setAttr("sequence", fullname.c_str()); } xmlNode->setAttr("dt", dt); diff --git a/Code/Legacy/CryCommon/IRenderer.h b/Code/Legacy/CryCommon/IRenderer.h index d3557129bf..254f1933de 100644 --- a/Code/Legacy/CryCommon/IRenderer.h +++ b/Code/Legacy/CryCommon/IRenderer.h @@ -17,7 +17,6 @@ #include "Cry_Matrix33.h" #include "Cry_Color.h" #include "smartptr.h" -#include "StringUtils.h" #include // <> required for Interfuscator #include "smartptr.h" #include @@ -1449,7 +1448,7 @@ struct IRenderer virtual const char* EF_GetShaderMissLogPath() = 0; ///////////////////////////////////////////////////////////////////////////////// - virtual string* EF_GetShaderNames(int& nNumShaders) = 0; + virtual AZStd::string* EF_GetShaderNames(int& nNumShaders) = 0; // Summary: // Reloads file virtual bool EF_ReloadFile (const char* szFileName) = 0; diff --git a/Code/Legacy/CryCommon/ISerialize.h b/Code/Legacy/CryCommon/ISerialize.h index 0476237903..d427e222bb 100644 --- a/Code/Legacy/CryCommon/ISerialize.h +++ b/Code/Legacy/CryCommon/ISerialize.h @@ -179,28 +179,16 @@ struct SSerializeString void resize(int sz) { m_str.resize(sz); } void reserve(int sz) { m_str.reserve(sz); } - void set_string(const string& s) + void set_string(const AZStd::string& s) { m_str.assign(s.begin(), s.size()); } -#if !defined(RESOURCE_COMPILER) - void set_string(const CryStringLocal& s) - { - m_str.assign(s.begin(), s.size()); - } -#endif - template - void set_string(const CryFixedStringT& s) - { - m_str.assign(s.begin(), s.size()); - } - - operator const string () const { + operator const AZStd::string() const { return m_str; } private: - string m_str; + AZStd::string m_str; }; // the ISerialize is intended to be implemented by objects that need @@ -308,7 +296,7 @@ public: m_pSerialize->Value(szName, value); } - void Value(const char* szName, string& value, int policy) + void Value(const char* szName, AZStd::string& value, int policy) { if (IsWriting()) { @@ -327,11 +315,11 @@ public: value = serializeString.c_str(); } } - ILINE void Value(const char* szName, string& value) + ILINE void Value(const char* szName, AZStd::string& value) { Value(szName, value, 0); } - void Value(const char* szName, const string& value, int policy) + void Value(const char* szName, const AZStd::string& value, int policy) { if (IsWriting()) { @@ -343,76 +331,7 @@ public: assert(0 && "This function can only be used for Writing"); } } - ILINE void Value(const char* szName, const string& value) - { - Value(szName, value, 0); - } - template - void Value(const char* szName, CryStringLocalT& value, int policy) - { - if (IsWriting()) - { - SSerializeString& serializeString = SetSharedSerializeString(value); - m_pSerialize->WriteStringValue(szName, serializeString, policy); - } - else - { - if (GetSerializationTarget() != eST_Script) - { - value = ""; - } - - SSerializeString& serializeString = SetSharedSerializeString(value); - m_pSerialize->ReadStringValue(szName, serializeString, policy); - value = serializeString.c_str(); - } - } - template - ILINE void Value(const char* szName, CryStringLocalT& value) - { - Value(szName, value, 0); - } - template - void Value(const char* szName, const CryStringLocalT& value, int policy) - { - if (IsWriting()) - { - SSerializeString& serializeString = SetSharedSerializeString(value); - m_pSerialize->WriteStringValue(szName, serializeString, policy); - } - else - { - assert(0 && "This function can only be used for Writing"); - } - } - template - ILINE void Value(const char* szName, const CryStringLocalT& value) - { - Value(szName, value, 0); - } - template - void Value(const char* szName, CryFixedStringT& value, int policy) - { - if (IsWriting()) - { - SSerializeString& serializeString = SetSharedSerializeString(value); - m_pSerialize->WriteStringValue(szName, serializeString, policy); - } - else - { - if (GetSerializationTarget() != eST_Script) - { - value = ""; - } - - SSerializeString& serializeString = SetSharedSerializeString(value); - m_pSerialize->ReadStringValue(szName, serializeString, policy); - assert(serializeString.length() <= S); - value = serializeString.c_str(); - } - } - template - ILINE void Value(const char* szName, CryFixedStringT& value) + ILINE void Value(const char* szName, const AZStd::string& value) { Value(szName, value, 0); } @@ -468,7 +387,7 @@ public: bool ValueChar(const char* name, char* buffer, int len) { - string temp; + AZStd::string temp; if (IsReading()) { Value(name, temp); @@ -481,7 +400,7 @@ public: } else { - temp = string(buffer, buffer + len); + temp = AZStd::string(buffer, buffer + len); Value(name, temp); } return true; @@ -493,7 +412,7 @@ public: m_pSerialize->ValueWithDefault(name, x, defaultValue); } - void ValueWithDefault(const char* szName, string& value, const string& defaultValue) + void ValueWithDefault(const char* szName, AZStd::string& value, const AZStd::string& defaultValue) { static SSerializeString defaultSerializeString; @@ -919,34 +838,13 @@ public: return CSerializeWrapper(m_pSerialize); } - SSerializeString& SetSharedSerializeString(const string& str) + SSerializeString& SetSharedSerializeString(const AZStd::string& str) { static SSerializeString serializeString; serializeString.set_string(str); return serializeString; } -#if !defined(RESOURCE_COMPILER) - SSerializeString& SetSharedSerializeString(const CryStringLocal& str) - { - - - static SSerializeString serializeString; - serializeString.set_string(str); - return serializeString; - } -#endif - - template - SSerializeString& SetSharedSerializeString(const CryFixedStringT& str) - { - - - static SSerializeString serializeString; - serializeString.set_string(str); - return serializeString; - } - private: TISerialize* m_pSerialize; }; diff --git a/Code/Legacy/CryCommon/IShader.h b/Code/Legacy/CryCommon/IShader.h index d445c21b1d..6ae3bd73df 100644 --- a/Code/Legacy/CryCommon/IShader.h +++ b/Code/Legacy/CryCommon/IShader.h @@ -25,7 +25,6 @@ #include "Cry_Matrix33.h" #include "Cry_Color.h" #include "smartptr.h" -#include "StringUtils.h" #include // <> required for Interfuscator #include "smartptr.h" #include "VertexFormats.h" @@ -1394,12 +1393,12 @@ struct IRenderTarget struct STexSamplerFX { #if SHADER_REFLECT_TEXTURE_SLOTS - string m_szUIName; - string m_szUIDescription; + AZStd::string m_szUIName; + AZStd::string m_szUIDescription; #endif - string m_szName; - string m_szTexture; + AZStd::string m_szName; + AZStd::string m_szTexture; union { @@ -1708,7 +1707,7 @@ struct SEfResTextureExt //------------------------------------------------------------------------------ struct SEfResTexture { - string m_Name; + AZStd::string m_Name; bool m_bUTile; bool m_bVTile; signed char m_Filter; @@ -1890,7 +1889,7 @@ struct SEfResTexture struct SBaseShaderResources { AZStd::vector m_ShaderParams; - string m_TexturePath; + AZStd::string m_TexturePath; const char* m_szMaterialName; float m_AlphaRef; @@ -2146,8 +2145,8 @@ struct SShaderTextureSlot m_TexType = eTT_MaxTexType; } - string m_Name; - string m_Description; + AZStd::string m_Name; + AZStd::string m_Description; byte m_TexType; // 2D, 3D, Cube etc.. void GetMemoryUsage(ICrySizer* pSizer) const @@ -2726,7 +2725,7 @@ protected: virtual ~ILightAnimWrapper() {} protected: - string m_name; + AZStd::string m_name; IAnimNode* m_pNode; }; @@ -3256,12 +3255,12 @@ enum EGrNodeIOSemantic struct SShaderGraphFunction { - string m_Data; - string m_Name; - std::vector inParams; - std::vector outParams; - std::vector szInTypes; - std::vector szOutTypes; + AZStd::string m_Data; + AZStd::string m_Name; + std::vector inParams; + std::vector outParams; + std::vector szInTypes; + std::vector szOutTypes; }; struct SShaderGraphNode @@ -3269,8 +3268,8 @@ struct SShaderGraphNode EGrNodeType m_eType; EGrNodeFormat m_eFormat; EGrNodeIOSemantic m_eSemantic; - string m_CustomSemantics; - string m_Name; + AZStd::string m_CustomSemantics; + AZStd::string m_Name; bool m_bEditable; bool m_bWasAdded; SShaderGraphFunction* m_pFunction; @@ -3296,7 +3295,7 @@ struct SShaderGraphBlock { EGrBlockType m_eType; EGrBlockSamplerType m_eSamplerType; - string m_ClassName; + AZStd::string m_ClassName; FXShaderGraphNodes m_Nodes; ~SShaderGraphBlock(); diff --git a/Code/Legacy/CryCommon/IStatObj.h b/Code/Legacy/CryCommon/IStatObj.h index ff3bbc41e3..4921ab3a25 100644 --- a/Code/Legacy/CryCommon/IStatObj.h +++ b/Code/Legacy/CryCommon/IStatObj.h @@ -201,7 +201,7 @@ struct IStreamable virtual void StartStreaming(bool bFinishNow, IReadStream_AutoPtr* ppStream) = 0; virtual int GetStreamableContentMemoryUsage(bool bJustForDebug = false) = 0; virtual void ReleaseStreamableContent() = 0; - virtual void GetStreamableName(string& sName) = 0; + virtual void GetStreamableName(AZStd::string& sName) = 0; virtual uint32 GetLastDrawMainFrameId() = 0; virtual bool IsUnloadable() const = 0; @@ -239,8 +239,8 @@ struct IStatObj SSubObject() { bShadowProxy = 0; } EStaticSubObjectType nType; - string name; - string properties; + AZStd::string name; + AZStd::string properties; int nParent; // Index of the parent sub object, if there`s hierarchy between them. Matrix34 tm; // Transformation matrix. Matrix34 localTM; // Local transformation matrix, relative to parent. @@ -510,10 +510,10 @@ struct IStatObj virtual bool IsUnloadable() const = 0; virtual void SetCanUnload(bool value) = 0; - virtual string& GetFileName() = 0; - virtual const string& GetFileName() const = 0; + virtual AZStd::string& GetFileName() = 0; + virtual const AZStd::string& GetFileName() const = 0; - virtual const string& GetCGFNodeName() const = 0; + virtual const AZStd::string& GetCGFNodeName() const = 0; // Summary: // Returns the filename of the object diff --git a/Code/Legacy/CryCommon/ISurfaceType.h b/Code/Legacy/CryCommon/ISurfaceType.h index db5ec4eed4..10bddbbe6c 100644 --- a/Code/Legacy/CryCommon/ISurfaceType.h +++ b/Code/Legacy/CryCommon/ISurfaceType.h @@ -85,7 +85,7 @@ struct ISurfaceType }; struct SBreakable2DParams { - string particle_effect; + AZStd::string particle_effect; float blast_radius; float blast_radius_first; float vert_size_spread; @@ -97,12 +97,12 @@ struct ISurfaceType float shard_density; int use_edge_alpha; float crack_decal_scale; - string crack_decal_mtl; + AZStd::string crack_decal_mtl; float max_fracture; - string full_fracture_fx; - string fracture_fx; + AZStd::string full_fracture_fx; + AZStd::string fracture_fx; int no_procedural_full_fracture; - string broken_mtl; + AZStd::string broken_mtl; float destroy_timeout; float destroy_timeout_spread; @@ -125,8 +125,8 @@ struct ISurfaceType }; struct SBreakageParticles { - string type; - string particle_effect; + AZStd::string type; + AZStd::string particle_effect; int count_per_unit; float count_scale; float scale; diff --git a/Code/Legacy/CryCommon/ISystem.h b/Code/Legacy/CryCommon/ISystem.h index 1e1aae99be..46c359730b 100644 --- a/Code/Legacy/CryCommon/ISystem.h +++ b/Code/Legacy/CryCommon/ISystem.h @@ -943,7 +943,7 @@ struct ISystem // If m_GraphicsSettingsMap is defined (in Graphics Settings Dialog box), fills in mapping based on sys_spec_Full // Arguments: // sPath - e.g. "Game/Config/CVarGroups" - virtual void AddCVarGroupDirectory(const string& sPath) = 0; + virtual void AddCVarGroupDirectory(const AZStd::string& sPath) = 0; // Summary: // Saves system configuration. diff --git a/Code/Legacy/CryCommon/IXml.h b/Code/Legacy/CryCommon/IXml.h index b722da78e3..80c2415f9c 100644 --- a/Code/Legacy/CryCommon/IXml.h +++ b/Code/Legacy/CryCommon/IXml.h @@ -94,14 +94,20 @@ void testXml(bool bReuseStrings) // Summary: // Special string wrapper for xml nodes. class XmlString - : public string + : public AZStd::string { public: XmlString() {}; XmlString(const char* str) - : string(str) {}; + : AZStd::string(str) {}; - operator const char*() const { + size_t GetAllocatedMemory() const + { + return sizeof(XmlString) + capacity() * sizeof(AZStd::string::value_type); + } + + operator const char*() const + { return c_str(); } }; @@ -147,13 +153,11 @@ public: XmlNodeRef& operator=(IXmlNode* newp); XmlNodeRef& operator=(const XmlNodeRef& newp); -#if !defined(RESOURCE_COMPILER) template void GetMemoryUsage(Sizer* pSizer) const { pSizer->AddObject(p); } -#endif //Support for range based for, and stl algorithms. class XmlNodeRefIterator begin(); @@ -399,7 +403,6 @@ public: // -#if !defined(RESOURCE_COMPILER) // // Summary: // Collect all allocated memory @@ -423,7 +426,6 @@ public: // Save in small memory chunks. virtual bool saveToFile(const char* fileName, size_t chunkSizeBytes, AZ::IO::HandleType fileHandle = AZ::IO::InvalidHandle) = 0; // -#endif //##@} @@ -792,12 +794,9 @@ struct IXmlSerializer virtual ISerialize* GetWriter(XmlNodeRef& node) = 0; virtual ISerialize* GetReader(XmlNodeRef& node) = 0; // -#if !defined(RESOURCE_COMPILER) virtual void GetMemoryUsage(ICrySizer* pSizer) const = 0; -#endif }; -#if !defined(RESOURCE_COMPILER) ////////////////////////////////////////////////////////////////////////// // Summary: // XML Parser interface. @@ -867,7 +866,6 @@ struct IXmlTableReader virtual float GetCurrentRowHeight() = 0; // }; -#endif ////////////////////////////////////////////////////////////////////////// // Summary: @@ -900,7 +898,6 @@ struct IXmlUtils virtual IXmlSerializer* CreateXmlSerializer() = 0; // -#if !defined(RESOURCE_COMPILER) // // Summary: // Creates XML Parser. @@ -945,7 +942,6 @@ struct IXmlUtils // Set to NULL to clear an existing transform and disable further patching virtual void SetXMLPatcher(XmlNodeRef* pPatcher) = 0; // -#endif }; #endif // CRYINCLUDE_CRYCOMMON_IXML_H diff --git a/Code/Legacy/CryCommon/LinuxSpecific.h b/Code/Legacy/CryCommon/LinuxSpecific.h index 5fc1f7b801..72673cafe3 100644 --- a/Code/Legacy/CryCommon/LinuxSpecific.h +++ b/Code/Legacy/CryCommon/LinuxSpecific.h @@ -156,13 +156,8 @@ typedef WCHAR* LPUWSTR, * PUWSTR; typedef const WCHAR* LPCWSTR, * PCWSTR; typedef const WCHAR* LPCUWSTR, * PCUWSTR; -#ifdef UNICODE typedef LPCWSTR LPCTSTR; typedef LPWSTR LPTSTR; -#else -typedef LPCSTR LPCTSTR; -typedef LPSTR LPTSTR; -#endif typedef char TCHAR; typedef DWORD COLORREF; diff --git a/Code/Legacy/CryCommon/Linux_Win32Wrapper.h b/Code/Legacy/CryCommon/Linux_Win32Wrapper.h index 23cd7faf7f..8a1004a066 100644 --- a/Code/Legacy/CryCommon/Linux_Win32Wrapper.h +++ b/Code/Legacy/CryCommon/Linux_Win32Wrapper.h @@ -14,6 +14,8 @@ #include #include #include +#include + /* Memory block identification */ #define _FREE_BLOCK 0 #define _NORMAL_BLOCK 1 @@ -326,9 +328,6 @@ inline uint32 GetTickCount() #define _wtof(str) wcstod(str, 0) -// Need to include this before using it's used in finddata, but after the strnicmp definition -#include "CryString.h" - typedef struct __finddata64_t { //!< atributes set by find request @@ -344,7 +343,7 @@ private: char m_DirectoryName[260]; //!< directory name, needed when getting file attributes on the fly char m_ToMatch[260]; //!< pattern to match with DIR* m_Dir; //!< directory handle - std::vector m_Entries; //!< all file entries in the current directories + std::vector m_Entries; //!< all file entries in the current directories public: inline __finddata64_t() @@ -376,7 +375,7 @@ typedef struct _finddata_t extern int _findnext64(intptr_t last, __finddata64_t* pFindData); extern intptr_t _findfirst64(const char* pFileName, __finddata64_t* pFindData); -extern DWORD GetFileAttributes(LPCSTR lpFileName); +extern DWORD GetFileAttributesW(LPCWSTR lpFileName); extern const bool GetFilenameNoCase(const char* file, char*, const bool cCreateNew = false); diff --git a/Code/Legacy/CryCommon/LocalizationManagerBus.h b/Code/Legacy/CryCommon/LocalizationManagerBus.h index 8daca5562a..1d818de111 100644 --- a/Code/Legacy/CryCommon/LocalizationManagerBus.h +++ b/Code/Legacy/CryCommon/LocalizationManagerBus.h @@ -99,12 +99,12 @@ public: // bEnglish - if true, translates the string into the always present English language. // Returns: // true if localization was successful, false otherwise - virtual bool LocalizeString_ch(const char* sString, string& outLocalizedString, bool bEnglish = false) = 0; + virtual bool LocalizeString_ch(const char* sString, AZStd::string& outLocalizedString, bool bEnglish = false) = 0; // Summary: - // Same as LocalizeString( const char* sString, string& outLocalizedString, bool bEnglish=false ) + // Same as LocalizeString( const char* sString, AZStd::string& outLocalizedString, bool bEnglish=false ) // but at the moment this is faster. - virtual bool LocalizeString_s(const string& sString, string& outLocalizedString, bool bEnglish = false) = 0; + virtual bool LocalizeString_s(const AZStd::string& sString, AZStd::string& outLocalizedString, bool bEnglish = false) = 0; // Set up system for passing in placeholder data for localized strings // Summary: @@ -138,7 +138,7 @@ public: // bEnglish - if true, returns the always present English version of the label. // Returns: // True if localization was successful, false otherwise. - virtual bool LocalizeLabel(const char* sLabel, string& outLocalizedString, bool bEnglish = false) = 0; + virtual bool LocalizeLabel(const char* sLabel, AZStd::string& outLocalizedString, bool bEnglish = false) = 0; // Summary: // Return number of localization entries. @@ -151,7 +151,7 @@ public: // sLocalizedString - Corresponding english language string. // Returns: // True if successful, false otherwise (key not found). - virtual bool GetEnglishString(const char* sKey, string& sLocalizedString) = 0; + virtual bool GetEnglishString(const char* sKey, AZStd::string& sLocalizedString) = 0; // Summary: // Get Subtitle for Key or Label . @@ -161,21 +161,21 @@ public: // bForceSubtitle - If true, get subtitle (sLocalized or sEnglish) even if not specified in Data file. // Returns: // True if subtitle found (and outSubtitle filled in), false otherwise. - virtual bool GetSubtitle(const char* sKeyOrLabel, string& outSubtitle, bool bForceSubtitle = false) = 0; + virtual bool GetSubtitle(const char* sKeyOrLabel, AZStd::string& outSubtitle, bool bForceSubtitle = false) = 0; // Description: // These methods format outString depending on sString with ordered arguments // FormatStringMessage(outString, "This is %2 and this is %1", "second", "first"); // Arguments: // outString - This is first and this is second. - virtual void FormatStringMessage_List(string& outString, const string& sString, const char** sParams, int nParams) = 0; - virtual void FormatStringMessage(string& outString, const string& sString, const char* param1, const char* param2 = 0, const char* param3 = 0, const char* param4 = 0) = 0; + virtual void FormatStringMessage_List(AZStd::string& outString, const AZStd::string& sString, const char** sParams, int nParams) = 0; + virtual void FormatStringMessage(AZStd::string& outString, const AZStd::string& sString, const char* param1, const char* param2 = 0, const char* param3 = 0, const char* param4 = 0) = 0; - virtual void LocalizeTime(time_t t, bool bMakeLocalTime, bool bShowSeconds, string& outTimeString) = 0; - virtual void LocalizeDate(time_t t, bool bMakeLocalTime, bool bShort, bool bIncludeWeekday, string& outDateString) = 0; - virtual void LocalizeDuration(int seconds, string& outDurationString) = 0; - virtual void LocalizeNumber(int number, string& outNumberString) = 0; - virtual void LocalizeNumber_Decimal(float number, int decimals, string& outNumberString) = 0; + virtual void LocalizeTime(time_t t, bool bMakeLocalTime, bool bShowSeconds, AZStd::string& outTimeString) = 0; + virtual void LocalizeDate(time_t t, bool bMakeLocalTime, bool bShort, bool bIncludeWeekday, AZStd::string& outDateString) = 0; + virtual void LocalizeDuration(int seconds, AZStd::string& outDurationString) = 0; + virtual void LocalizeNumber(int number, AZStd::string& outNumberString) = 0; + virtual void LocalizeNumber_Decimal(float number, int decimals, AZStd::string& outNumberString) = 0; // Summary: // Returns true if the project has localization configured for use, false otherwise. diff --git a/Code/Legacy/CryCommon/LyShine/Animation/IUiAnimation.h b/Code/Legacy/CryCommon/LyShine/Animation/IUiAnimation.h index 3515dab68e..e04fb6ada7 100644 --- a/Code/Legacy/CryCommon/LyShine/Animation/IUiAnimation.h +++ b/Code/Legacy/CryCommon/LyShine/Animation/IUiAnimation.h @@ -120,7 +120,7 @@ public: CUiAnimParamType() : m_type(eUiAnimParamType_Invalid) {} - CUiAnimParamType(const string& name) + CUiAnimParamType(const AZStd::string& name) { *this = name; } @@ -136,17 +136,12 @@ public: m_type = (EUiAnimParamType)type; } - void operator =(const string& name) - { - m_type = eUiAnimParamType_ByString; - m_name = name; - } - void operator =(const AZStd::string& name) { m_type = eUiAnimParamType_ByString; m_name = name.c_str(); } + // Convert to enum. This needs to be explicit, // otherwise operator== will be ambiguous EUiAnimParamType GetType() const { return m_type; } @@ -1301,7 +1296,7 @@ inline void SUiAnimContext::Serialize(IUiAnimationSystem* animationSystem, XmlNo { if (pSequence) { - string fullname = pSequence->GetName(); + AZStd::string fullname = pSequence->GetName(); xmlNode->setAttr("sequence", fullname.c_str()); } xmlNode->setAttr("dt", dt); diff --git a/Code/Legacy/CryCommon/LyShine/Bus/UiCanvasBus.h b/Code/Legacy/CryCommon/LyShine/Bus/UiCanvasBus.h index 44962ddb61..4702435b83 100644 --- a/Code/Legacy/CryCommon/LyShine/Bus/UiCanvasBus.h +++ b/Code/Legacy/CryCommon/LyShine/Bus/UiCanvasBus.h @@ -101,7 +101,7 @@ public: // member functions //! Save this canvas to the given path in XML //! \return true if no error - virtual bool SaveToXml(const string& assetIdPathname, const string& sourceAssetPathname) = 0; + virtual bool SaveToXml(const AZStd::string& assetIdPathname, const AZStd::string& sourceAssetPathname) = 0; //! Initialize a set of entities that have been added to the canvas //! Used when instantiating a slice or for undo/redo, copy/paste diff --git a/Code/Legacy/CryCommon/LyShine/ILyShine.h b/Code/Legacy/CryCommon/LyShine/ILyShine.h index 07bffda0fe..7832497d8c 100644 --- a/Code/Legacy/CryCommon/LyShine/ILyShine.h +++ b/Code/Legacy/CryCommon/LyShine/ILyShine.h @@ -46,7 +46,7 @@ public: virtual AZ::EntityId CreateCanvas() = 0; //! Load a UI Canvas from in-game - virtual AZ::EntityId LoadCanvas(const string& assetIdPathname) = 0; + virtual AZ::EntityId LoadCanvas(const AZStd::string& assetIdPathname) = 0; //! Create an empty UI Canvas (for the UI editor) // @@ -54,7 +54,7 @@ public: virtual AZ::EntityId CreateCanvasInEditor(UiEntityContext* entityContext) = 0; //! Load a UI Canvas from the UI editor - virtual AZ::EntityId LoadCanvasInEditor(const string& assetIdPathname, const string& sourceAssetPathname, UiEntityContext* entityContext) = 0; + virtual AZ::EntityId LoadCanvasInEditor(const AZStd::string& assetIdPathname, const AZStd::string& sourceAssetPathname, UiEntityContext* entityContext) = 0; //! Reload a UI Canvas from xml. For use in the editor for the undo system only virtual AZ::EntityId ReloadCanvasFromXml(const AZStd::string& xmlString, UiEntityContext* entityContext) = 0; @@ -65,7 +65,7 @@ public: //! Get a loaded canvas by path name //! NOTE: this only searches canvases loaded in the game (not the editor) - virtual AZ::EntityId FindLoadedCanvasByPathName(const string& assetIdPathname) = 0; + virtual AZ::EntityId FindLoadedCanvasByPathName(const AZStd::string& assetIdPathname) = 0; //! Release a canvas from use either in-game or in editor, destroy UI Canvas if no longer used in either virtual void ReleaseCanvas(AZ::EntityId canvas, bool forEditor = false) = 0; @@ -74,10 +74,10 @@ public: virtual void ReleaseCanvasDeferred(AZ::EntityId canvas) = 0; //! Load a sprite object. - virtual ISprite* LoadSprite(const string& pathname) = 0; + virtual ISprite* LoadSprite(const AZStd::string& pathname) = 0; //! Create a sprite that references the specified render target - virtual ISprite* CreateSprite(const string& renderTargetName) = 0; + virtual ISprite* CreateSprite(const AZStd::string& renderTargetName) = 0; //! Check if a sprite's texture asset exists. The .sprite sidecar file is optional and is not checked virtual bool DoesSpriteTextureAssetExist(const AZStd::string& pathname) = 0; diff --git a/Code/Legacy/CryCommon/LyShine/ISprite.h b/Code/Legacy/CryCommon/LyShine/ISprite.h index cd2b70ef25..373024d2db 100644 --- a/Code/Legacy/CryCommon/LyShine/ISprite.h +++ b/Code/Legacy/CryCommon/LyShine/ISprite.h @@ -59,10 +59,10 @@ public: // member functions virtual ~ISprite() {} //! Get the pathname of this sprite - virtual const string& GetPathname() const = 0; + virtual const AZStd::string& GetPathname() const = 0; //! Get the pathname of the texture of this sprite - virtual const string& GetTexturePathname() const = 0; + virtual const AZStd::string& GetTexturePathname() const = 0; //! Get the borders of this sprite virtual Borders GetBorders() const = 0; @@ -77,7 +77,7 @@ public: // member functions virtual void Serialize(TSerialize ser) = 0; //! Save this sprite data to disk - virtual bool SaveToXml(const string& pathname) = 0; + virtual bool SaveToXml(const AZStd::string& pathname) = 0; //! Test if this sprite has any borders virtual bool AreBordersZeroWidth() const = 0; @@ -136,4 +136,3 @@ public: // member functions //! Returns true if this sprite is configured as a sprite-sheet, false otherwise virtual bool IsSpriteSheet() const = 0; }; - diff --git a/Code/Legacy/CryCommon/LyShine/UiAssetTypes.h b/Code/Legacy/CryCommon/LyShine/UiAssetTypes.h index a9c810c025..fef5f4d348 100644 --- a/Code/Legacy/CryCommon/LyShine/UiAssetTypes.h +++ b/Code/Legacy/CryCommon/LyShine/UiAssetTypes.h @@ -7,7 +7,7 @@ */ #pragma once -#include +#include #include //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Code/Legacy/CryCommon/LyShine/UiBase.h b/Code/Legacy/CryCommon/LyShine/UiBase.h index 274618821e..af6314be2c 100644 --- a/Code/Legacy/CryCommon/LyShine/UiBase.h +++ b/Code/Legacy/CryCommon/LyShine/UiBase.h @@ -65,6 +65,5 @@ namespace AZ AZ_TYPE_INFO_SPECIALIZE(ColorF, "{63782551-A309-463B-A301-3A360800DF1E}"); AZ_TYPE_INFO_SPECIALIZE(ColorB, "{6F0CC2C0-0CC6-4DBF-9297-B043F270E6A4}"); AZ_TYPE_INFO_SPECIALIZE(Vec4, "{CAC9510C-8C00-41D4-BC4D-2C6A8136EB30}"); - AZ_TYPE_INFO_SPECIALIZE(CryStringT, "{835199FB-292B-4DB3-BC7C-366E356300FA}"); } // namespace AZ diff --git a/Code/Legacy/CryCommon/LyShine/UiSerializeHelpers.h b/Code/Legacy/CryCommon/LyShine/UiSerializeHelpers.h index 05289c6c50..3ad3de2d3d 100644 --- a/Code/Legacy/CryCommon/LyShine/UiSerializeHelpers.h +++ b/Code/Legacy/CryCommon/LyShine/UiSerializeHelpers.h @@ -22,154 +22,6 @@ namespace LyShine { - //////////////////////////////////////////////////////////////////////////////////////////////// - // Helper function to VersionConverter to convert a CryString field to an AZStd::String - // Inline to avoid DLL linkage issues - inline bool ConvertSubElementFromCryStringToAzString( - AZ::SerializeContext& context, - AZ::SerializeContext::DataElementNode& classElement, - const char* subElementName) - { - int index = classElement.FindElement(AZ_CRC(subElementName)); - if (index != -1) - { - AZ::SerializeContext::DataElementNode& elementNode = classElement.GetSubElement(index); - - CryStringT oldData; - - if (!elementNode.GetData(oldData)) - { - // Error, old subElement was not a string or not valid - AZ_Error("Serialization", false, "Cannot get string data for element %s.", subElementName); - return false; - } - - // Remove old version. - classElement.RemoveElement(index); - - // Add a new element for the new data. - int newElementIndex = classElement.AddElement(context, subElementName); - if (newElementIndex == -1) - { - // Error adding the new sub element - AZ_Error("Serialization", false, "AddElement failed for converted element %s", subElementName); - return false; - } - - AZStd::string newData(oldData.c_str()); - classElement.GetSubElement(newElementIndex).SetData(context, newData); - } - - // if the field did not exist then we do not report an error - return true; - } - - //////////////////////////////////////////////////////////////////////////////////////////////// - // Helper function to VersionConverter to convert a CryString field to a char - // Inline to avoid DLL linkage issues - inline bool ConvertSubElementFromCryStringToChar( - AZ::SerializeContext& context, - AZ::SerializeContext::DataElementNode& classElement, - const char* subElementName, - char defaultValue) - { - int index = classElement.FindElement(AZ_CRC(subElementName)); - if (index != -1) - { - AZ::SerializeContext::DataElementNode& elementNode = classElement.GetSubElement(index); - - CryStringT oldData; - - if (!elementNode.GetData(oldData)) - { - // Error, old subElement was not a CryString - AZ_Error("Serialization", false, "Element %s is not a CryString.", subElementName); - return false; - } - - // Remove old version. - classElement.RemoveElement(index); - - // Add a new element for the new data. - int newElementIndex = classElement.AddElement(context, subElementName); - if (newElementIndex == -1) - { - // Error adding the new sub element - AZ_Error("Serialization", false, "AddElement failed for converted element %s", subElementName); - return false; - } - - char newData = (oldData.empty()) ? defaultValue : oldData[0]; - classElement.GetSubElement(newElementIndex).SetData(context, newData); - } - - // if the field did not exist then we do not report an error - return true; - } - - //////////////////////////////////////////////////////////////////////////////////////////////// - // Helper function to VersionConverter to convert a CryString field to a simple asset reference - // Inline to avoid DLL linkage issues - template - inline bool ConvertSubElementFromCryStringToAssetRef( - AZ::SerializeContext& context, - AZ::SerializeContext::DataElementNode& classElement, - const char* subElementName) - { - int index = classElement.FindElement(AZ_CRC(subElementName)); - if (index != -1) - { - AZ::SerializeContext::DataElementNode& elementNode = classElement.GetSubElement(index); - - CryStringT oldData; - - if (!elementNode.GetData(oldData)) - { - // Error, old subElement was not a CryString - AZ_Error("Serialization", false, "Element %s is not a CryString.", subElementName); - return false; - } - - // Remove old version. - classElement.RemoveElement(index); - - // Add a new element for the new data. - int simpleAssetRefIndex = classElement.AddElement >(context, subElementName); - if (simpleAssetRefIndex == -1) - { - // Error adding the new sub element - AZ_Error("Serialization", false, "AddElement failed for simpleAssetRefIndex %s", subElementName); - return false; - } - - // add a sub element for the SimpleAssetReferenceBase within the SimpleAssetReference - AZ::SerializeContext::DataElementNode& simpleAssetRefNode = classElement.GetSubElement(simpleAssetRefIndex); - int simpleAssetRefBaseIndex = simpleAssetRefNode.AddElement(context, "BaseClass1"); - if (simpleAssetRefBaseIndex == -1) - { - // Error adding the new sub element - AZ_Error("Serialization", false, "AddElement failed for converted element BaseClass1"); - return false; - } - - // add a sub element for the AssetPath within the SimpleAssetReference - AZ::SerializeContext::DataElementNode& simpleAssetRefBaseNode = simpleAssetRefNode.GetSubElement(simpleAssetRefBaseIndex); - int assetPathElementIndex = simpleAssetRefBaseNode.AddElement(context, "AssetPath"); - if (assetPathElementIndex == -1) - { - // Error adding the new sub element - AZ_Error("Serialization", false, "AddElement failed for converted element AssetPath"); - return false; - } - - AZStd::string newData(oldData.c_str()); - simpleAssetRefBaseNode.GetSubElement(assetPathElementIndex).SetData(context, newData); - } - - // if the field did not exist then we do not report an error - return true; - } - //////////////////////////////////////////////////////////////////////////////////////////////// // Helper function to VersionConverter to convert an AZStd::string field to a simple asset reference // Inline to avoid DLL linkage issues diff --git a/Code/Legacy/CryCommon/Mocks/IConsoleMock.h b/Code/Legacy/CryCommon/Mocks/IConsoleMock.h index 1475e8e01e..b416aa5f11 100644 --- a/Code/Legacy/CryCommon/Mocks/IConsoleMock.h +++ b/Code/Legacy/CryCommon/Mocks/IConsoleMock.h @@ -56,7 +56,7 @@ public: MOCK_METHOD0(IsOpened, bool ()); MOCK_METHOD0(GetNumVars, int()); MOCK_METHOD0(GetNumVisibleVars, int()); - MOCK_METHOD3(GetSortedVars, size_t (const char** pszArray, size_t numItems, const char* szPrefix)); + MOCK_METHOD2(GetSortedVars, size_t (AZStd::vector& pszArray, const char* szPrefix)); MOCK_METHOD1(AutoComplete, const char*(const char* substr)); MOCK_METHOD1(AutoCompletePrev, const char*(const char* substr)); MOCK_METHOD1(ProcessCompletion, const char*(const char* szInputBuffer)); diff --git a/Code/Legacy/CryCommon/Mocks/IRendererMock.h b/Code/Legacy/CryCommon/Mocks/IRendererMock.h index ff3550a738..be9c1eec8b 100644 --- a/Code/Legacy/CryCommon/Mocks/IRendererMock.h +++ b/Code/Legacy/CryCommon/Mocks/IRendererMock.h @@ -283,7 +283,7 @@ public: MOCK_METHOD0(EF_GetShaderMissLogPath, const char*()); MOCK_METHOD1(EF_GetShaderNames, - string * (int& nNumShaders)); + AZStd::string * (int& nNumShaders)); MOCK_METHOD1(EF_ReloadFile, bool(const char* szFileName)); MOCK_METHOD1(EF_ReloadFile_Request, diff --git a/Code/Legacy/CryCommon/Mocks/ISystemMock.h b/Code/Legacy/CryCommon/Mocks/ISystemMock.h index e357af6d87..c4566537b1 100644 --- a/Code/Legacy/CryCommon/Mocks/ISystemMock.h +++ b/Code/Legacy/CryCommon/Mocks/ISystemMock.h @@ -118,7 +118,7 @@ public: const SFileVersion&()); MOCK_METHOD1(AddCVarGroupDirectory, - void(const string&)); + void(const AZStd::string&)); MOCK_METHOD0(SaveConfiguration, void()); MOCK_METHOD3(LoadConfiguration, diff --git a/Code/Legacy/CryCommon/ProjectDefines.h b/Code/Legacy/CryCommon/ProjectDefines.h index 3d635c491c..e359fe669b 100644 --- a/Code/Legacy/CryCommon/ProjectDefines.h +++ b/Code/Legacy/CryCommon/ProjectDefines.h @@ -42,10 +42,7 @@ // Type used for vertex indices // WARNING: If you change this typedef, you need to update AssetProcessorPlatformConfig.ini to convert cgf and abc files to the proper index format. -#if defined(RESOURCE_COMPILER) -typedef uint32 vtx_idx; -#define AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(MOBILE) +#if defined(MOBILE) typedef uint16 vtx_idx; #define AZ_RESTRICTED_SECTION_IMPLEMENTED #elif defined(AZ_RESTRICTED_PLATFORM) @@ -138,7 +135,7 @@ typedef uint32 vtx_idx; # define PHYSICS_STACK_SIZE (128U << 10) #endif -#if (!defined(_RELEASE) || defined(PERFORMANCE_BUILD)) && !defined(RESOURCE_COMPILER) +#if (!defined(_RELEASE) || defined(PERFORMANCE_BUILD)) #ifndef ENABLE_PROFILING_CODE #define ENABLE_PROFILING_CODE #endif diff --git a/Code/Legacy/CryCommon/StlUtils.h b/Code/Legacy/CryCommon/StlUtils.h index 2438ee9f7b..d7e5697593 100644 --- a/Code/Legacy/CryCommon/StlUtils.h +++ b/Code/Legacy/CryCommon/StlUtils.h @@ -494,7 +494,7 @@ namespace stl //! Specialization of string to const char cast. template <> - inline const char* constchar_cast(const string& type) + inline const char* constchar_cast(const AZStd::string& type) { return type.c_str(); } diff --git a/Code/Legacy/CryCommon/StringUtils.h b/Code/Legacy/CryCommon/StringUtils.h deleted file mode 100644 index ffd1001f95..0000000000 --- a/Code/Legacy/CryCommon/StringUtils.h +++ /dev/null @@ -1,1358 +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 _CRY_ENGINE_STRING_UTILS_HDR_ -#define _CRY_ENGINE_STRING_UTILS_HDR_ - -#pragma once - -#include "CryString.h" -#include -#include // std::replace, std::min -#include "UnicodeFunctions.h" -#include "UnicodeIterator.h" -#include - -#if !defined(RESOURCE_COMPILER) -# include "CryCrc32.h" -#endif - -#if defined(LINUX) || defined(APPLE) -# include -#endif - -namespace CryStringUtils -{ - // Convert a single ASCII character to lower case, this is compatible with the standard "C" locale (ie, only A-Z). - inline char toLowerAscii(char c) - { - return (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c; - } - - // Convert a single ASCII character to upper case, this is compatible with the standard "C" locale (ie, only A-Z). - inline char toUpperAscii(char c) - { - return (c >= 'a' && c <= 'z') ? (c - 'a' + 'A') : c; - } -} - -// cry_strXXX() and CryStringUtils_Internal::strXXX(): -// -// The functions copy characters from src to dst one by one until any of -// the following conditions is met: -// 1) the end of the destination buffer (minus one character) is reached. -// 2) the end of the source buffer is reached. -// 3) zero character is found in the source buffer. -// -// When any of 1), 2), 3) happens, the functions write the terminating zero -// character to the destination buffer and return. -// -// The functions guarantee writing the terminating zero character to the -// destination buffer (if the buffer can fit at least one character). -// -// The functions return false when a null pointer is passed or when -// clamping happened (i.e. when the end of the destination buffer is -// reached but the source has some characters left). - -namespace CryStringUtils_Internal -{ - template - inline bool strcpy_with_clamp(TChar* const dst, size_t const dst_size_in_bytes, const TChar* const src, size_t const src_size_in_bytes) - { - COMPILE_TIME_ASSERT(sizeof(TChar) == sizeof(char) || sizeof(TChar) == sizeof(wchar_t)); - - if (!dst || dst_size_in_bytes < sizeof(TChar)) - { - return false; - } - - if (!src || src_size_in_bytes < sizeof(TChar)) - { - dst[0] = 0; - return src != 0; // we return true for non-null src without characters - } - - const size_t src_n = src_size_in_bytes / sizeof(TChar); - const size_t n = (std::min)(dst_size_in_bytes / sizeof(TChar) - 1, src_n); - - for (size_t i = 0; i < n; ++i) - { - dst[i] = src[i]; - if (!src[i]) - { - return true; - } - } - - dst[n] = 0; - return n >= src_n || src[n] == 0; - } - - template - inline bool strcat_with_clamp(TChar* const dst, size_t const dst_size_in_bytes, const TChar* const src, size_t const src_size_in_bytes) - { - COMPILE_TIME_ASSERT(sizeof(TChar) == sizeof(char) || sizeof(TChar) == sizeof(wchar_t)); - - if (!dst || dst_size_in_bytes < sizeof(TChar)) - { - return false; - } - - const size_t dst_n = dst_size_in_bytes / sizeof(TChar) - 1; - - size_t dst_len = 0; - while (dst_len < dst_n && dst[dst_len]) - { - ++dst_len; - } - - if (!src || src_size_in_bytes < sizeof(TChar)) - { - dst[dst_len] = 0; - return src != 0; // we return true for non-null src without characters - } - - const size_t src_n = src_size_in_bytes / sizeof(TChar); - const size_t n = (std::min)(dst_n - dst_len, src_n); - TChar* dst_ptr = &dst[dst_len]; - - for (size_t i = 0; i < n; ++i) - { - *dst_ptr++ = src[i]; - if (!src[i]) - { - return true; - } - } - - *dst_ptr = 0; - return n >= src_n || src[n] == 0; - } - - // Compares characters as case-sensitive, locale agnostic. - template - struct SCharComparatorCaseSensitive - { - static bool IsEqual(CharType a, CharType b) - { - return a == b; - } - }; - - // Compares characters as case-insensitive, uses the standard "C" locale. - template - struct SCharComparatorCaseInsensitive - { - static bool IsEqual(CharType a, CharType b) - { - if (a < 0x80 && b < 0x80) - { - a = (CharType)CryStringUtils::toLowerAscii(char(a)); - b = (CharType)CryStringUtils::toLowerAscii(char(b)); - } - return a == b; - } - }; - - // Template for wildcard matching, UCS code-point aware. - // Can be used for ASCII and Unicode (UTF-8/UTF-16/UTF-32), but not for ANSI. - // ? will match exactly one code-point. - // * will match zero or more code-points. - template class CharComparator, class CharType> - inline bool MatchesWildcards_Tpl(const CharType* pStr, const CharType* pWild) - { - const CharType* savedStr = 0; - const CharType* savedWild = 0; - - while ((*pStr) && (*pWild != '*')) - { - if (!CharComparator::IsEqual(*pWild, *pStr) && (*pWild != '?')) - { - return false; - } - - // We need special handling of '?' for Unicode - if (*pWild == '?' && *pStr > 127) - { - Unicode::CIterator utf(pStr, pStr + 4); - if (utf.IsAtValidCodepoint()) - { - pStr = (++utf).GetPosition(); - --pStr; - } - } - - ++pWild; - ++pStr; - } - - while (*pStr) - { - if (*pWild == '*') - { - if (!*++pWild) - { - return true; - } - savedWild = pWild; - savedStr = pStr + 1; - } - else if (CharComparator::IsEqual(*pWild, *pStr) || (*pWild == '?')) - { - // We need special handling of '?' for Unicode - if (*pWild == '?' && *pStr > 127) - { - Unicode::CIterator utf(pStr, pStr + 4); - if (utf.IsAtValidCodepoint()) - { - pStr = (++utf).GetPosition(); - --pStr; - } - } - - ++pWild; - ++pStr; - } - else - { - pWild = savedWild; - pStr = savedStr++; - } - } - - while (*pWild == '*') - { - ++pWild; - } - - return *pWild == 0; - } -} // namespace CryStringUtils_Internal - - -inline bool cry_strcpy(char* const dst, size_t const dst_size_in_bytes, const char* const src) -{ - return CryStringUtils_Internal::strcpy_with_clamp(dst, dst_size_in_bytes, src, (size_t)-1); -} - -inline bool cry_strcpy(char* const dst, size_t const dst_size_in_bytes, const char* const src, size_t const src_size_in_bytes) -{ - return CryStringUtils_Internal::strcpy_with_clamp(dst, dst_size_in_bytes, src, src_size_in_bytes); -} - -template -inline bool cry_strcpy(char(&dst)[SIZE_IN_CHARS], const char* const src) -{ - return CryStringUtils_Internal::strcpy_with_clamp(dst, SIZE_IN_CHARS, src, (size_t)-1); -} - -template -inline bool cry_strcpy(char(&dst)[SIZE_IN_CHARS], const char* const src, size_t const src_size_in_bytes) -{ - return CryStringUtils_Internal::strcpy_with_clamp(dst, SIZE_IN_CHARS, src, src_size_in_bytes); -} - - -inline bool cry_wstrcpy(wchar_t* const dst, size_t const dst_size_in_bytes, const wchar_t* const src) -{ - return CryStringUtils_Internal::strcpy_with_clamp(dst, dst_size_in_bytes, src, (size_t)-1); -} - -inline bool cry_wstrcpy(wchar_t* const dst, size_t const dst_size_in_bytes, const wchar_t* const src, size_t const src_size_in_bytes) -{ - return CryStringUtils_Internal::strcpy_with_clamp(dst, dst_size_in_bytes, src, src_size_in_bytes); -} - -template -inline bool cry_wstrcpy(wchar_t(&dst)[SIZE_IN_WCHARS], const wchar_t* const src) -{ - return CryStringUtils_Internal::strcpy_with_clamp(dst, SIZE_IN_WCHARS * sizeof(wchar_t), src, (size_t)-1); -} - -template -inline bool cry_wstrcpy(wchar_t(&dst)[SIZE_IN_WCHARS], const wchar_t* const src, size_t const src_size_in_bytes) -{ - return CryStringUtils_Internal::strcpy_with_clamp(dst, SIZE_IN_WCHARS * sizeof(wchar_t), src, src_size_in_bytes); -} - - -inline bool cry_strcat(char* const dst, size_t const dst_size_in_bytes, const char* const src) -{ - return CryStringUtils_Internal::strcat_with_clamp(dst, dst_size_in_bytes, src, (size_t)-1); -} - -inline bool cry_strcat(char* const dst, size_t const dst_size_in_bytes, const char* const src, size_t const src_size_in_bytes) -{ - return CryStringUtils_Internal::strcat_with_clamp(dst, dst_size_in_bytes, src, src_size_in_bytes); -} - -template -inline bool cry_strcat(char(&dst)[SIZE_IN_CHARS], const char* const src) -{ - return CryStringUtils_Internal::strcat_with_clamp(dst, SIZE_IN_CHARS, src, (size_t)-1); -} - -template -inline bool cry_strcat(char(&dst)[SIZE_IN_CHARS], const char* const src, size_t const src_size_in_bytes) -{ - return CryStringUtils_Internal::strcat_with_clamp(dst, SIZE_IN_CHARS, src, src_size_in_bytes); -} - - -inline bool cry_wstrcat(wchar_t* const dst, size_t const dst_size_in_bytes, const wchar_t* const src) -{ - return CryStringUtils_Internal::strcat_with_clamp(dst, dst_size_in_bytes, src, (size_t)-1); -} - -inline bool cry_wstrcat(wchar_t* const dst, size_t const dst_size_in_bytes, const wchar_t* const src, size_t const src_size_in_bytes) -{ - return CryStringUtils_Internal::strcat_with_clamp(dst, dst_size_in_bytes, src, src_size_in_bytes); -} - -template -inline bool cry_wstrcat(wchar_t(&dst)[SIZE_IN_WCHARS], const wchar_t* const src) -{ - return CryStringUtils_Internal::strcat_with_clamp(dst, SIZE_IN_WCHARS * sizeof(wchar_t), src, (size_t)-1); -} - -template -inline bool cry_wstrcat(wchar_t(&dst)[SIZE_IN_WCHARS], const wchar_t* const src, size_t const src_size_in_bytes) -{ - return CryStringUtils_Internal::strcat_with_clamp(dst, SIZE_IN_WCHARS * sizeof(wchar_t), src, src_size_in_bytes); -} - - -namespace CryStringUtils -{ - enum - { - CRY_DEFAULT_HASH_SEED = 40503, // This is a large 16 bit prime number (perfect for seeding) - CRY_EMPTY_STR_HASH = 3350499166U, // HashString("") - }; - - // removes the extension from the file path - // \param szFilePath the source path - inline char* StripFileExtension(char* szFilePath) - { - for (char* p = szFilePath + (int)strlen(szFilePath) - 1; p >= szFilePath; --p) - { - switch (*p) - { - case ':': - case '/': - case '\\': - // we've reached a path separator - it means there's no extension in this name - return nullptr; - case '.': - // there's an extension in this file name - *p = '\0'; - return p + 1; - } - } - // it seems the file name is a pure name, without path or extension - return nullptr; - } - - - // returns the parent directory of the given file or directory. - // the returned path is WITHOUT the trailing slash - // if the input path has a trailing slash, it's ignored - // nGeneration - is the number of parents to scan up - // Note: A drive specifier (if any) will always be kept (Windows-specific). - template - StringCls GetParentDirectory(const StringCls& strFilePath, int nGeneration = 1) - { - for (const char* p = strFilePath.c_str() + strFilePath.length() - 2; // -2 is for the possible trailing slash: there always must be some trailing symbol which is the file/directory name for which we should get the parent - p >= strFilePath.c_str(); - --p) - { - switch (*p) - { - case ':': - return StringCls(strFilePath.c_str(), p); - break; - case '/': - case '\\': - // we've reached a path separator - return everything before it. - if (!--nGeneration) - { - return StringCls(strFilePath.c_str(), p); - } - break; - } - } - ; - // the file name is a pure name, without path or extension - return StringCls(); - } - - /*! - // converts all chars to lower case - */ - inline string ToLower(const string& str) - { - string temp = str; - -#ifndef NOT_USE_CRY_STRING - temp.MakeLower(); -#else - std::transform(temp.begin(), temp.end(), temp.begin(), toLowerAscii); // STL MakeLower -#endif - - return temp; - } - - /// Converts the single character to lower case. - /*! - \param c source character to convert to lower case if possible - \return the lower case character equivalent if possible - */ - inline char ToLower(char c) - { - return ((c <= 'Z') && (c >= 'A')) ? c + ('a' - 'A') : c; - } - - /// Converts the specified character into lowercase. - /*! - \param c the character to convert to lowercase - \return the lowercase character - */ - // Converts all ASCII characters to upper case. - // Note: Any non-ASCII characters are left unchanged. - // This function is ASCII-only and locale agnostic. - inline string toUpper (const string& str) - { - string temp = str; - -#ifndef NOT_USE_CRY_STRING - temp.MakeUpper(); -#else - std::transform(temp.begin(), temp.end(), temp.begin(), toUpperAscii); // STL MakeLower -#endif - - return temp; - } - - // searches and returns the pointer to the extension of the given file - /*! - \param szFileName source filename to search - // This function is Unicode agnostic and locale agnostic. - */ - inline const char* FindExtension(const char* szFileName) - { - const char* szEnd = szFileName + (int)strlen(szFileName); - for (const char* p = szEnd - 1; p >= szFileName; --p) - { - if (*p == '.') - { - return p + 1; - } - } - - return szEnd; - } - - // searches and returns the pointer to the file name in the given file path - /*! - \param szFilePath source path to search - */ - inline const char* FindFileNameInPath(const char* szFilePath) - { - for (const char* p = szFilePath + (int)strlen(szFilePath) - 1; p >= szFilePath; --p) - { - if (*p == '\\' || *p == '/') - { - return p + 1; - } - } - return szFilePath; - } - - // works like strstr, but is case-insensitive - /*! - \param szString the source string - \param szSubstring the sub-string to look for - */ - inline const char* stristr(const char* szString, const char* szSubstring) - { - int nSuperstringLength = (int)strlen(szString); - int nSubstringLength = (int)strlen(szSubstring); - - for (int nSubstringPos = 0; nSubstringPos <= nSuperstringLength - nSubstringLength; ++nSubstringPos) - { - if (_strnicmp(szString + nSubstringPos, szSubstring, nSubstringLength) == 0) - { - return szString + nSubstringPos; - } - } - return nullptr; - } - - -#ifndef NOT_USE_CRY_STRING - - /* - \param strPath the path to "unify" - */ - inline void UnifyFilePath(stack_string& strPath) - { - strPath.replace('\\', '/'); - strPath.MakeLower(); - } - - template - inline void UnifyFilePath(CryStackStringT& strPath) - { - strPath.replace('\\', '/'); - strPath.MakeLower(); - } - - /// Replaces backslashes with forward slashes and transforms string to lowercase. - /*! - \param strPath the path to "unify" - */ - inline void UnifyFilePath(string& strPath) - { - strPath.replace('\\', '/'); - strPath.MakeLower(); - } - -#endif - - // converts the number to a string - /* - \param nNumber an unsigned number - \return the unsigned number as a string - */ - inline string ToString(unsigned nNumber) - { - char szNumber[16]; - sprintf_s(szNumber, "%u", nNumber); - return szNumber; - } - - /// Converts the number to a string. - /*! - \param nNumber an signed integer - \return the signed integer as a string - */ - inline string ToString(signed int nNumber) - { - char szNumber[16]; - sprintf_s(szNumber, "%d", nNumber); - return szNumber; - } - - /// Converts the floating point number to a string. - /*! - \param nNumber a floating point number - \return the floating point number as a string - */ - inline string ToString(float nNumber) - { - char szNumber[128]; - sprintf_s(szNumber, "%f", nNumber); - return szNumber; - } - - /// Converts the boolean value to a string ("0" or "1"). - /*! - \param nNumber an unsigned number - \return the bool as a string (either "1" or "0") - */ - inline string ToString(bool nNumber) - { - char szNumber[4]; - sprintf_s(szNumber, "%i", (int)nNumber); - return szNumber; - } - -#ifdef CRYINCLUDE_CRYCOMMON_CRY_MATRIX44_H - /// Converts a Matrix44 to a string. - /*! - \param m A matrix of type Matrix44 - \return the matrix in the format {0,0,0,0}{0,0,0,0}{0,0,0,0}{0,0,0,0} - */ - inline string ToString(const Matrix44& m) - { - char szBuf[0x200]; - sprintf_s(szBuf, "{%g,%g,%g,%g}{%g,%g,%g,%g}{%g,%g,%g,%g}{%g,%g,%g,%g}", - m(0, 0), m(0, 1), m(0, 2), m(0, 3), - m(1, 0), m(1, 1), m(1, 2), m(1, 3), - m(2, 0), m(2, 1), m(2, 2), m(2, 3), - m(3, 0), m(3, 1), m(3, 2), m(3, 3)); - return szBuf; - } -#endif - -#ifdef CRYINCLUDE_CRYCOMMON_CRY_QUAT_H - /// Converts a CryQuat to a string. - /*! - \param m A quaternion of type CryQuat - \return the quaternion in the format {0,{0,0,0,0}} - */ - inline string ToString (const CryQuat& q) - { - char szBuf[0x100]; - sprintf_s(szBuf, "{%g,{%g,%g,%g}}", q.w, q.v.x, q.v.y, q.v.z); - return szBuf; - } -#endif - -#ifdef CRYINCLUDE_CRYCOMMON_CRY_VECTOR3_H - /// Converts a Vec3 to a string. - /*! - \param m A vector of type Vec3 - \return the vector in the format {0,0,0} - */ - inline string ToString (const Vec3& v) - { - char szBuf[0x80]; - sprintf_s(szBuf, "{%g,%g,%g}", v.x, v.y, v.z); - return szBuf; - } -#endif - - /// This function only exists to allow ToString to compile if it is ever used with an unsupported type. - /*! - \param unknownType - \return a string that reads "unknown" - */ - template - inline string ToString(T& unknownType) - { - char szValue[8]; - sprintf_s(szValue, "%s", "unknown"); - return szValue; - } - - // does the same as strstr, but the szString is allowed to be no more than the specified size - /*! - \param szString the source string - \param szSubstring the sub-string to look for - \param nSuperstringLength the maximum size of szString - */ - inline const char* strnstr(const char* szString, const char* szSubstring, int nSuperstringLength) - { - int nSubstringLength = (int)strlen(szSubstring); - if (!nSubstringLength) - { - return szString; - } - - for (int nSubstringPos = 0; szString[nSubstringPos] && nSubstringPos < nSuperstringLength - nSubstringLength; ++nSubstringPos) - { - if (strncmp(szString + nSubstringPos, szSubstring, nSubstringLength) == 0) - { - return szString + nSubstringPos; - } - } - return nullptr; - } - - - // Finds the string in the array of strings. - // Returns its 0-based index or -1 if not found. - // Comparison is case-sensitive. - // The string array end is demarked by the NULL value. - // This function is Unicode agnostic (but no Unicode collation is performed for equality test) and locale agnostic. - inline int findString(const char* szString, const char* arrStringList[]) - { - for (const char** p = arrStringList; *p; ++p) - { - if (0 == strcmp(*p, szString)) - { - return (int)(p - arrStringList); - } - } - return -1; // string was not found - } - - /// Finds the string in the array of strings. - /*! - \param szString the string to look for - \param arrStringList array of strings - \remark comparison is case-sensitive - \remark The string array end is delimited by the nullptr value - \return its 0-based index or -1 if not found - */ - inline int FindString(const char* szString, const char* arrStringList[]) - { - for (const char** p = arrStringList; *p; ++p) - { - if (0 == strcmp(*p, szString)) - { - return (int)(p - arrStringList); - } - } - return -1; // string was not found - } - - /// Used for printing out sets of objects of string type. - /*! - \remark just forms the comma-delimited string where each string in the set is presented as a formatted substring - \param setStrings set of strings to print - \return a formatted string - */ - inline string ToString(const std::set& setStrings) - { - string strResult; - if (!setStrings.empty()) - { - strResult += "{"; - for (std::set::const_iterator it = setStrings.begin(); it != setStrings.end(); ++it) - { - if (it != setStrings.begin()) - { - strResult += ", "; - } - strResult += "\""; - strResult += *it; - strResult += "\""; - } - strResult += "}"; - } - return strResult; - } - - // Cuts the string and adds leading ... if it's longer than specified maximum length. - // This function is ASCII-only and locale agnostic. - inline string cutString(const string& strPath, unsigned nMaxLength) - { - if (strPath.length() > nMaxLength && nMaxLength > 3) - { - return string("...") + string(strPath.c_str() + strPath.length() - (nMaxLength - 3)); - } - else - { - return strPath; - } - } - - /// Cuts the string and adds leading ... if it's longer than specified maximum length. - /*! - \param str the string to cut - \param nMaxLength the allowed length of the string before its cut. - \return a shortened string starting in ellipses or the source string if it's smaller than nMaxLength - */ - inline string CutString(const string& str, unsigned nMaxLength) - { - if (str.length() > nMaxLength && nMaxLength > 3) - { - return string("...") + string(str.c_str() + str.length() - (nMaxLength - 3)); - } - else - { - return str; - } - } - - /// Converts the given set of NUMBERS into the string. - /*! - \param setMtlms A numeric set to convert into a string - \param szFormat - \param szPostfix - */ - template - string ToString(const std::set& setMtls, const char* szFormat, const char* szPostfix = "") - { - string strResult; - char szBuffer[64]; - if (!setMtls.empty()) - { - strResult += strResult.empty() ? "(" : " ("; - for (typename std::set::const_iterator it = setMtls.begin(); it != setMtls.end(); ) - { - if (it != setMtls.begin()) - { - strResult += ", "; - } - sprintf_s(szBuffer, szFormat, *it); - strResult += szBuffer; - T nStart = *it; - - ++it; - - if (it != setMtls.end() && *it == nStart + 1) - { - T nPrev = *it; - // we've got a region - while (++it != setMtls.end() && *it == nPrev + 1) - { - nPrev = *it; - } - if (nPrev == nStart + 1) - { - // special case - range of length 1 - strResult += ","; - } - else - { - strResult += ".."; - } - sprintf_s(szBuffer, szFormat, nPrev); - strResult += szBuffer; - } - } - strResult += ")"; - } - return szPostfix[0] ? strResult + szPostfix : strResult; - } - - - // Attempts to find a matching wildcard in a string. - /*! - \param szString source string - \param szWildcard the wildcard, supports * and ? - // returns true if the string matches the wildcard - // Note: ANSI input is not supported, ASCII is fine since it's a subset of UTF-8. - */ - inline bool MatchWildcard(const char* szString, const char* szWildcard) - { - return CryStringUtils_Internal::MatchesWildcards_Tpl(szString, szWildcard); - } - - // Returns true if the string matches the wildcard. - // Supports wildcard ? (matches one code-point) and * (matches zero or more code-points). - // This function is Unicode aware and uses the "C" locale for case comparison. - // Note: ANSI input is not supported, ASCII is fine since it's a subset of UTF-8. - inline bool MatchWildcardIgnoreCase(const char* szString, const char* szWildcard) - { - return CryStringUtils_Internal::MatchesWildcards_Tpl(szString, szWildcard); - } - -#if !defined(RESOURCE_COMPILER) - - // calculates a hash value for a given string - inline uint32 CalculateHash(const char* str) - { - return CCrc32::Compute(str); - } - - // calculates a hash value for the lower case version of a given string - inline uint32 CalculateHashLowerCase(const char* str) - { - return CCrc32::ComputeLowercase(str); - } - - // This function is Unicode agnostic and locale agnostic. - inline uint32 HashStringSeed(const char* string, const uint32 seed) - { - // A string hash taken from the FRD/Crysis2 (game) code with low probability of clashes - // Recommend you use the CRY_DEFAULT_HASH_SEED (see HashString) - const char* p; - uint32 hash = seed; - for (p = string; *p != '\0'; p++) - { - hash += *p; - hash += (hash << 10); - hash ^= (hash >> 6); - } - hash += (hash << 3); - hash ^= (hash >> 11); - hash += (hash << 15); - return hash; - } - - // This function is ASCII-only and uses the standard "C" locale for case conversion. - inline uint32 HashStringLowerSeed(const char* string, const uint32 seed) - { - // computes the hash of 'string' converted to lower case - // also see the comment in HashStringSeed - const char* p; - uint32 hash = seed; - for (p = string; *p != '\0'; p++) - { - hash += toLowerAscii(*p); - hash += (hash << 10); - hash ^= (hash >> 6); - } - hash += (hash << 3); - hash ^= (hash >> 11); - hash += (hash << 15); - return hash; - } - - // This function is Unicode agnostic and locale agnostic. - inline uint32 HashString(const char* string) - { - return HashStringSeed(string, CRY_DEFAULT_HASH_SEED); - } - - // This function is ASCII-only and uses the standard "C" locale for case conversion. - inline uint32 HashStringLower(const char* string) - { - return HashStringLowerSeed(string, CRY_DEFAULT_HASH_SEED); - } -#endif - - // converts all chars to lower case - avoids memory allocation - /*! - \param str Reference to string to convert into lowercase. - */ - inline void ToLowerInplace(string& str) - { -#ifndef NOT_USE_CRY_STRING - str.MakeLower(); -#else - std::transform(str.begin(), str.end(), str.begin(), toLowerAscii); // STL MakeLower -#endif - } - - /// Converts all chars to lower case - avoids memory allocation - /*! - \param str Reference to string to convert into lowercase. - */ - inline void ToLowerInplace(char* str) - { - if (str == nullptr) - { - return; - } - - for (char* s = str; *s != '\0'; s++) - { - *s = toLowerAscii(*s); - } - } - - -#ifndef NOT_USE_CRY_STRING - - // Converts a wide string (can be UTF-16 or UTF-32 depending on platform) to UTF-8. - // This function is Unicode aware and locale agnostic. - /// Converts a wide string to a UTF8 string. - /*! - \param str The wide string to convert. - \return dstr The wide string converted into the specified UTF8 type. - */ - template - inline void WStrToUTF8(const wchar_t* str, T& dstr) - { - string utf8; - Unicode::Convert(utf8, str); - - // Note: This function expects T to have assign(ptr, len) function - dstr.assign(utf8.c_str(), utf8.length()); - } - - // Converts a wide string (can be UTF-16 or UTF-32 depending on platform) to UTF-8. - // This function is Unicode aware and locale agnostic. - /// Converts a wide string to UTF8. - /*! - \param str The wchar_t string to convert. - \return The UTF8 string. - */ - inline string WStrToUTF8(const wchar_t* str) - { - return Unicode::Convert(str); - } - - /// Converts a UTF8 string to a wide string. - /*! - \param str The UTF8 string to convert. - \return dstr The UTF8 string converted into the specified type. - */ - template - inline void UTF8ToWStr(const char* str, T& dstr) - { - wstring wide; - Unicode::Convert(wide, str); - - // Note: This function expects T to have assign(ptr, len) function - dstr.assign(wide.c_str(), wide.length()); - } - - // Converts an UTF-8 string to wide string (can be UTF-16 or UTF-32 depending on platform). - // This function is Unicode aware and locale agnostic. - /*! - \param str The UTF8 string to convert. - \return str as converted to wstring. - */ - inline wstring UTF8ToWStr(const char* str) - { - return Unicode::Convert(str); - } - - /// Converts a string to a wide character string - /*! - \param str Source string. - \param dstr Destination wstring. - */ - inline void StrToWstr(const char* str, wstring& dstr) - { - CryStackStringT tmp; - tmp.resize(strlen(str)); - tmp.clear(); - - while (const wchar_t c = (wchar_t)(*str++)) - { - tmp.append(1, c); - } - - dstr.assign(tmp.data(), tmp.length()); - } - -#endif // NOT_USE_CRY_STRING - - /// The type used to parse a yes/no string -#if defined(_DISALLOW_ENUM_CLASS) - enum YesNoType -#else - enum class YesNoType -#endif - { - Yes, - No, - Invalid - }; - - // parse the yes/no string - /*! - \param szString any of the following strings: yes, enable, true, 1, no, disable, false, 0 - \return YesNoType::Yes if szString is yes/enable/true/1, YesNoType::No if szString is no, disable, false, 0 and YesNoType::Invalid if the string is not one of the expected values. - */ - inline YesNoType ToYesNoType(const char* szString) - { - if (!_stricmp(szString, "yes") - || !_stricmp(szString, "enable") - || !_stricmp(szString, "true") - || !_stricmp(szString, "1")) -#if defined(_DISALLOW_ENUM_CLASS) - { - return Yes; - } -#else - { - return YesNoType::Yes; - } -#endif - if (!_stricmp(szString, "no") - || !_stricmp(szString, "disable") - || !_stricmp(szString, "false") - || !_stricmp(szString, "0")) -#if defined(_DISALLOW_ENUM_CLASS) - { - return No; - } -#else - { - return YesNoType::No; - } -#endif - -#if defined(_DISALLOW_ENUM_CLASS) - return Invalid; -#else - return YesNoType::Invalid; -#endif - } - - /// Verifies if the filename provided only contains the accepted characters. - /*! - \param fileName the filename to verify - \return true if the filename only contains alphanumeric values and/or dot, dash and underscores. - */ - inline bool IsValidFileName(const char* fileName) - { - size_t i = 0; - for (;; ) - { - const char c = fileName[i++]; - if (c == 0) - { - return true; - } - if (!((c >= '0' && c <= '9') - || (c >= 'A' && c <= 'Z') - || (c >= 'a' && c <= 'z') - || c == '.' || c == '-' || c == '_')) - { - return false; - } - } - } - - - /************************************************************************** - *void _makepath() - build path name from components - * - *Purpose: - * create a path name from its individual components - * - *Entry: - * char *path - pointer to buffer for constructed path - * char *drive - pointer to drive component, may or may not contain trailing ':' - * char *dir - pointer to subdirectory component, may or may not include leading and/or trailing '/' or '\' characters - * char *fname - pointer to file base name component - * char *ext - pointer to extension component, may or may not contain a leading '.'. - * - *Exit: - * path - pointer to constructed path name - * - *******************************************************************************/ - ILINE void portable_makepath(char path[_MAX_PATH], const char* drive, const char* dir, const char* fname, const char* ext) - { - const char* p; - - /* we assume that the arguments are in the following form (although we - * do not diagnose invalid arguments or illegal filenames (such as - * names longer than 8.3 or with illegal characters in them) - * - * drive: - * A ; or - * A: - * dir: - * \top\next\last\ ; or - * /top/next/last/ ; or - * either of the above forms with either/both the leading - * and trailing / or \ removed. Mixed use of '/' and '\' is - * also tolerated - * fname: - * any valid file name - * ext: - * any valid extension (none if empty or null ) - */ - - /* copy drive */ - - if (drive && *drive) - { - *path++ = *drive; - *path++ = (':'); - } - - /* copy dir */ - - if ((p = dir) && *p) - { - do - { - *path++ = *p++; - } while (*p); - if (*(p - 1) != '/' && *(p - 1) != ('\\')) - { - *path++ = ('\\'); - } - } - - /* copy fname */ - - if (p = fname) - { - while (*p) - { - *path++ = *p++; - } - } - - /* copy ext, including 0-terminator - check to see if a '.' needs - * to be inserted. - */ - - if (p = ext) - { - if (*p && *p != ('.')) - { - *path++ = ('.'); - } - while (*path++ = *p++) - { - ; - } - } - else - { - /* better add the 0-terminator */ - *path = ('\0'); - } - } - - /// Create a path name from its individual components. - /*! - \param char *path pointer to buffer for constructed path - \param char *drive pointer to drive component, may or may not contain trailing ':' - \param char *dir pointer to subdirectory component, may or may not include leading and/or trailing '/' or '\' characters - \param char *fname pointer to file base name component - \param char *ext pointer to extension component, may or may not contain a leading '.'. - \return path pointer to constructed path name - */ - inline void MakePath(char path[_MAX_PATH], const char* drive, const char* dir, const char* fname, const char* ext) - { - const char* p; - - // we assume that the arguments are in the following form (although we - // do not diagnose invalid arguments or illegal filenames (such as - // names longer than 8.3 or with illegal characters in them) - // - // drive: - // A ; or - // A: - // dir: - // \top\next\last\ ; or - // /top/next/last/ ; or - // either of the above forms with either/both the leading - // and trailing / or \ removed. Mixed use of '/' and '\' is - // also tolerated - // fname: - // any valid file name - // ext: - // any valid extension (none if empty or null ) - // - - // copy drive - if (drive && *drive) - { - *path++ = *drive; - *path++ = (':'); - } - - // copy dir - if ((p = dir) && *p) - { - do - { - *path++ = *p++; - } while (*p); - if (*(p - 1) != '/' && *(p - 1) != ('\\')) - { - *path++ = ('\\'); - } - } - - // copy fname - if (p = fname) - { - while (*p) - { - *path++ = *p++; - } - } - - // copy ext, including 0-terminator - check to see if a '.' needs - // to be inserted. - if (p = ext) - { - if (*p && *p != ('.')) - { - *path++ = ('.'); - } - while (*path++ = *p++) - { - ; - } - } - else - { - // better add the 0-terminator - *path = ('\0'); - } - } - - // Copies characters from a string. - /*! - \param destination Pointer to the destination array where the content is to be copied. - \param source C string to be copied. - \param num Maximum number of characters to be copied from source. - \remark Parameter order is the same as strncpy; Copies only up to num characters from source to destination. - \return true if entirety of source was copied into destination. - */ - inline bool strncpy(char* destination, const char* source, size_t num) - { - bool reply = false; - -#if CRY_STRING_ASSERTS && !defined(RESOURCE_COMPILER) - CRY_ASSERT(destination); - CRY_ASSERT(source); -#endif - - if (num) - { - size_t i; - for (i = 0; source[i] && (i + 1) < num; ++i) - { - destination[i] = source[i]; - } - destination[i] = '\0'; - reply = (source[i] == '\0'); - } - -#if CRY_STRING_ASSERTS && !defined(RESOURCE_COMPILER) - CRY_ASSERT_MESSAGE(reply, string().Format("String '%s' is too big to fit into a buffer of length %u", source, (unsigned int)num)); -#endif - return reply; - } - - // Copies wide characters from a wide string. - /*! - \param destination Pointer to the destination wchar_t array where the content is to be copied. - \param source C wide string to be copied. - \param num Maximum number of characters to be copied from source. - \remark Parameter order is the same as strncpy; Copies only up to num characters from source to destination. - \return true if entirety of source was copied into destination. - */ - inline bool wstrncpy(wchar_t* destination, const wchar_t* source, size_t bufferLength) - { - bool reply = false; - -#if CRY_STRING_ASSERTS && !defined(RESOURCE_COMPILER) - CRY_ASSERT(destination); - CRY_ASSERT(source); -#endif - - if (bufferLength) - { - size_t i; - for (i = 0; source[i] && (i + 1) < bufferLength; ++i) - { - destination[i] = source[i]; - } - destination[i] = '\0'; - reply = (source[i] == '\0'); - } - -#if CRY_STRING_ASSERTS && !defined(RESOURCE_COMPILER) - CRY_ASSERT_MESSAGE(reply, string().Format("String '%ls' is too big to fit into a buffer of length %u", source, (unsigned int)bufferLength)); -#endif - return reply; - } - - // Copies a C string into a destination buffer up to a specified delimiter or null terminator. - /*! - \param destination Pointer to a buffer where the resulting C-string is stored. - \param source C string to be copied. - \param num Maximum number of characters to be copied from source. - \param delimiter Delimiter character up to which the string will be copied. - \return Number of bytes written into destination (including null terminator) or 0 if delimiter is not found within the first num bytes of source. - */ - inline size_t CopyStringUntilFindChar(char* destination, const char* source, size_t num, char delimiter) - { - size_t reply = 0; - -#if CRY_STRING_ASSERTS && !defined(RESOURCE_COMPILER) - CRY_ASSERT(destination); - CRY_ASSERT(source); -#endif - - if (num) - { - size_t i; - for (i = 0; source[i] && source[i] != delimiter && (i + 1) < num; ++i) - { - destination[i] = source[i]; - } - destination[i] = '\0'; - reply = (source[i] == delimiter) ? (i + 1) : 0; - } - - return reply; - } -} // namespace CryStringUtils - -#endif // CRYINCLUDE_CRYCOMMON_STRINGUTILS_H diff --git a/Code/Legacy/CryCommon/TypeInfo_decl.h b/Code/Legacy/CryCommon/TypeInfo_decl.h index f763ec6ebb..28a0b370a9 100644 --- a/Code/Legacy/CryCommon/TypeInfo_decl.h +++ b/Code/Legacy/CryCommon/TypeInfo_decl.h @@ -15,6 +15,7 @@ #pragma once #include +#include ////////////////////////////////////////////////////////////////////////// // Meta-type support. @@ -55,7 +56,7 @@ inline const CTypeInfo& TypeInfo(const T* t) // Type info declaration, with additional prototypes for string conversions. #define BASIC_TYPE_INFO(Type) \ - string ToString(Type const & val); \ + AZStd::string ToString(Type const & val); \ bool FromString(Type & val, const char* s); \ DECLARE_TYPE_INFO(Type) @@ -105,7 +106,7 @@ BASIC_TYPE_INFO(double) BASIC_TYPE_INFO(AZ::Uuid) -DECLARE_TYPE_INFO(string) +DECLARE_TYPE_INFO(AZStd::string) // All pointers share same TypeInfo. const CTypeInfo&PtrTypeInfo(); diff --git a/Code/Legacy/CryCommon/UnicodeBinding.h b/Code/Legacy/CryCommon/UnicodeBinding.h deleted file mode 100644 index e6e82aaf49..0000000000 --- a/Code/Legacy/CryCommon/UnicodeBinding.h +++ /dev/null @@ -1,986 +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 - * - */ - - -// Note: The utilities in this file should typically not be used directly, -// consider including UnicodeFunctions.h or UnicodeIterator.h instead. -// -// (At least) the following string types can be bound with these helper functions: -// Types Input Output Null-Terminator -// CryStringT, (::string, ::wstring): yes yes implied by type (also Stack and Fixed variants) -// std::basic_string, std::string, std::wstring: yes yes implied by type -// QString: yes yes implied by type -// std::vector, std::list, std::deque: yes yes not present -// T[] (fixed-length buffer): yes yes guaranteed to be emitted on output, accepted on input -// T * and size_t (user-specified-size buffer): no yes guaranteed to be emitted on output -// const T * (null-terminated string): yes no expected -// const T[] (literal): yes no implied as the last item in the array -// pair of iterators over T: yes no should not be included in the range -// uint32 (single UCS code-point): yes no not present -// If some other string type is not listed, you can still use it for input easily by passing begin/end iterators. -// Note: For all types, T can be any 8-bit, 16-bit or 32-bit integral or character type. -// Further T types may be processed by explicitly passing InputEncoding and OutputEncoding. -// We never actively tested such scenario's, so no guarantees on floating and user-defined types as code-units. - - -#pragma once - -#ifndef assert -// Some tools use CRT's assert, most engine and game modules use CryAssert.h (via platform.h maybe). -// We don't want to force a choice upon all code that uses Unicode utilities, so we just assume assert is defined. -#error This header uses assert macro, please provide an applicable definition before including UnicodeXXX.h -#endif - -#include "UnicodeEncoding.h" -#include // For str(n)len and memcpy. -#include // For wcs(n)len. -#include // For size_t and ptrdiff_t. -#include // For std::iterator_traits. -#include // For std::basic_string. -#include // For std::vector. -#include // For std::list. -#include // For std::deque. -#include // ... standard type-traits (as of C++11). - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define UNICODEBINDING_H_SECTION_1 1 -#define UNICODEBINDING_H_SECTION_2 2 -#endif - -// Forward declare the supported types. -// Before actually instantiating a binding however, you need to have the full definition included. -// Also, this allows us to work with QChar/QString as declared names without a dependency on Qt. -template -class CryStackStringT; -template -class CryFixedStringT; -template -class CryFixedWStringT; -template -class CryStringLocalT; -template -class CryStringT; -class QChar; -class QString; -namespace Unicode -{ - namespace Detail - { - // Import standard type traits. - // This requires C++11 compiler support. - using std::add_const; - using std::conditional; - using std::extent; - using std::integral_constant; - using std::is_arithmetic; - using std::is_array; - using std::is_base_of; - using std::is_const; - using std::is_convertible; - using std::is_integral; - using std::is_pointer; - using std::is_same; - using std::make_unsigned; - using std::remove_cv; - using std::remove_extent; - using std::remove_pointer; - - // SVoid: - // Result type will be void if T is well-formed. - // Note: This is mostly used to test the presence of member types at compile-time. - template - struct SVoid - { - typedef void type; - }; - - // SValidChar: - // Determine if T is a valid character type in the given compile-time context. - // The InferEncoding flag is set if the encoding has to be detected automatically. - // The Input flag is set if the type is used for input (and not set if the type is used for output). - template - struct SValidChar - { - typedef typename remove_cv::type BaseType; - static const bool isArithmeticType = is_arithmetic::value; - static const bool isQChar = is_same::value; - static const bool isUsable = isArithmeticType || isQChar; - static const bool isValidQualified = !is_const::value || Input; - static const bool isKnownSize = sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4; - static const bool isValidInferred = isKnownSize || !InferEncoding; - static const bool value = isUsable && isValidQualified && isValidInferred; - }; - - // SPackedIterators: - // A pair of iterators over some range. - // Note: Packing iterators into a single object allows us to pass them as a single argument like all other types. - template - struct SPackedIterators - { - const T begin, end; - SPackedIterators(const T& _begin, const T& _end) - : begin(_begin) - , end(_end) {} - }; - - // SPackedBuffer: - // A buffer-pointer/length tuple. - // Note: Packing them into a single object allows us to pass them as a single argument like all other types. - template - struct SPackedBuffer - { - T buffer; - size_t size; - SPackedBuffer(T _buffer, size_t _size) - : buffer(_buffer) - , size(_size) {} - }; - - // SDependentType: - // Makes the name of type T dependent on X (which is otherwise meaningless). - // Note: This is used to force two-phase lookup so we don't need the definition of T until instantiation. - // This way we can convince standards-compliant compilers Clang and GCC to not require definition of forward-declared types. - // Specifically, we forward-declare Qt's QString and QChar, for which the definition will never be available outside Editor. - template - struct SDependentType - { - typedef T type; - }; - - // EBind: - // Methods of binding a type for input and/or output. - // Note: These are used for tag-dispatch by binding functions, and are private to the implementation. - enum EBind - { // Input Output Description - eBind_Impossible, // No No Can't bind this type. - eBind_Iterators, // Yes Yes Bind by using begin() and end() member functions. - eBind_Data, // Yes Yes Bind by using data() and size() member functions. - eBind_Literal, // Yes No Bind a fixed size buffer (const element, aka string literal). - eBind_Buffer, // Yes No Bind a fixed size buffer (non-const element) that may be null-terminated. - eBind_PackedBuffer, // No Yes Bind a user-specified size buffer (non-const element). - eBind_NullTerminated, // Yes No Bind a null-terminated buffer of unknown length (C string). - eBind_CodePoint, // Yes No Bind a single code-point value. - }; - - // SBindIterator: - // Find the EBind for input from iterator pair of type T at compile-time. - // If the type is not supported, the resulting value will be eBind_Impossible - template - struct SBindIterator - { - typedef const void CharType; - static const EBind value = eBind_Impossible; - }; - template - struct SBindIterator - { - typedef typename add_const::type CharType; - static const bool isValid = SValidChar::value; - static const EBind value = isValid ? eBind_Iterators : eBind_Impossible; - }; - template - struct SBindIterator::type, - typename SVoid::type - > - { - typedef typename add_const::type CharType; - typedef typename T::iterator_category IteratorCategory; - static const bool isInputIterator = is_base_of::value; - static const bool isValid = SValidChar::value; - static const EBind value = isValid && isInputIterator ? eBind_Iterators : eBind_Impossible; - }; - - // SBindObject: - // Find the EBind for input from object of type T at compile-time. - // If the type is not supported, the resulting value will be eBind_Impossible. - template - struct SBindObject - { - typedef typename add_const< - typename conditional< - is_array::value, - typename remove_extent::type, - typename remove_pointer::type - >::type - >::type CharType; - static const size_t FixedSize = extent::value; - COMPILE_TIME_ASSERT(!is_array::value || FixedSize > 0); - static const bool isConstArray = is_array::value && is_const::type>::value; - static const bool isBufferArray = is_array::value && !isConstArray; - static const bool isPointer = is_pointer::value; - static const bool isCodePoint = is_integral::value; - static const bool isValidChar = SValidChar::value; - static const EBind value = - !isValidChar ? eBind_Impossible : - isConstArray ? eBind_Literal : - isBufferArray ? eBind_Buffer : - isPointer ? eBind_NullTerminated : - isCodePoint ? eBind_CodePoint : - eBind_Impossible; - }; - template - struct SBindObject, InferEncoding> - { - typedef typename add_const::type CharType; - static const bool isValid = SValidChar::value; - static const EBind value = isValid ? eBind_Data : eBind_Impossible; - }; - template - struct SBindObject, InferEncoding> - { - typedef typename add_const::type CharType; - static const bool isValid = SValidChar::value; - static const EBind value = isValid ? eBind_Data : eBind_Impossible; - }; - template - struct SBindObject, InferEncoding> - { - typedef typename add_const::type CharType; - static const bool isValid = SValidChar::value; - static const EBind value = isValid ? eBind_Iterators : eBind_Impossible; - }; - template - struct SBindObject, InferEncoding> - { - typedef typename add_const::type CharType; - static const bool isValid = SValidChar::value; - static const EBind value = isValid ? eBind_Iterators : eBind_Impossible; - }; - template - struct SBindObject, InferEncoding> - { - typedef typename add_const::type CharType; - static const bool isValid = SValidChar::value; - static const EBind value = isValid ? eBind_Data : eBind_Impossible; - }; - template - struct SBindObject, InferEncoding> - { - typedef typename add_const::type CharType; - static const bool isValid = SValidChar::value; - static const EBind value = isValid ? eBind_Data : eBind_Impossible; - }; - template - struct SBindObject, InferEncoding> - { - typedef typename add_const::type CharType; - static const bool isValid = SValidChar::value; - static const EBind value = isValid ? eBind_Data : eBind_Impossible; - }; - template - struct SBindObject, InferEncoding> - { - typedef char CharType; - static const bool isValid = SValidChar::value; - static const EBind value = isValid ? eBind_Data : eBind_Impossible; - }; - template - struct SBindObject, InferEncoding> - { - typedef wchar_t CharType; - static const bool isValid = SValidChar::value; - static const EBind value = isValid ? eBind_Data : eBind_Impossible; - }; - template - struct SBindObject - { - typedef const QChar CharType; - static const EBind value = eBind_Data; - }; - template - struct SBindObject, InferEncoding> - { - typedef typename SBindIterator::CharType CharType; - static const EBind value = eBind_Iterators; - }; - - // SBindOutput: - // Find the EBind for output to object of type T at compile-time. - // If the type is not supported, the resulting value will be eBind_Impossible. - template - struct SBindOutput - { - typedef typename remove_extent::type CharType; - static const size_t FixedSize = extent::value; - static const bool isArray = is_array::value; - static const bool isValid = SValidChar::type, InferEncoding, false>::value; - static const EBind value = isArray && isValid ? eBind_Buffer : eBind_Impossible; - }; - template - struct SBindOutput, InferEncoding> - { - typedef OutputCharType CharType; - static const bool isValid = SValidChar::value; - static const EBind value = isValid ? eBind_PackedBuffer : eBind_Impossible; - }; - template - struct SBindOutput, InferEncoding> - { - typedef CharT CharType; - static const bool isValid = SValidChar::value; - static const EBind value = isValid ? eBind_Data : eBind_Impossible; - }; - template - struct SBindOutput, InferEncoding> - { - typedef T CharType; - static const bool isValid = SValidChar::value; - static const EBind value = isValid ? eBind_Data : eBind_Impossible; - }; - template - struct SBindOutput, InferEncoding> - { - typedef T CharType; - static const bool isValid = SValidChar::value; - static const EBind value = isValid ? eBind_Iterators : eBind_Impossible; - }; - template - struct SBindOutput, InferEncoding> - { - typedef T CharType; - static const bool isValid = SValidChar::value; - static const EBind value = isValid ? eBind_Iterators : eBind_Impossible; - }; - template - struct SBindOutput, InferEncoding> - { - typedef T CharType; - static const bool isValid = SValidChar::value; - static const EBind value = isValid ? eBind_Data : eBind_Impossible; - }; - template - struct SBindOutput, InferEncoding> - { - typedef T CharType; - static const bool isValid = SValidChar::value; - static const EBind value = isValid ? eBind_Data : eBind_Impossible; - }; - template - struct SBindOutput, InferEncoding> - { - typedef T CharType; - static const bool isValid = SValidChar::value; - static const EBind value = isValid ? eBind_Data : eBind_Impossible; - }; - template - struct SBindOutput - { - typedef QChar CharType; - static const EBind value = eBind_Data; - }; - - // SInferEncoding: - // Infers the encoding of the given character type. - // Note: This will always pick an UTF encoding type based on the size of the element type. - template - struct SInferEncoding - { - typedef SBindObject ObjectType; - typedef SBindIterator IteratorType; - typedef typename conditional< - IteratorType::value != eBind_Impossible, - typename IteratorType::CharType, - typename ObjectType::CharType - >::type CharType; - static const EEncoding value = - sizeof(CharType) == 1 ? eEncoding_UTF8 : - sizeof(CharType) == 2 ? eEncoding_UTF16 : - eEncoding_UTF32; - COMPILE_TIME_ASSERT(value != eEncoding_UTF32 || sizeof(CharType) == 4); - }; - - // SBindCharacter: - // Pick the base character type to use during input or output with this element type. - template::value, bool IsQChar = is_same::type>::value> - struct SBindCharacter - { - typedef typename make_unsigned::type BaseType; // The standard doesn't define if a character type is signed or unsigned. - typedef typename remove_cv::type UnqualifiedType; - typedef typename conditional::type type; - }; - template - struct SBindCharacter - { - COMPILE_TIME_ASSERT(is_arithmetic::value); - typedef typename remove_cv::type UnqualifiedType; - typedef typename conditional::type type; - }; - template - struct SBindCharacter - { - typedef typename conditional::type type; - typedef typename SDependentType::type ActuallyQChar; // Force two-phase name lookup on QChar. - COMPILE_TIME_ASSERT(sizeof(ActuallyQChar) == sizeof(type)); // In case Qt ever changes QChar. - }; - - // SBindPointer: - // Pick the pointer type to use during input or output with buffers (potentially inside string types). - template - struct SBindPointer - { - COMPILE_TIME_ASSERT(is_pointer::value || is_array::value); - typedef typename conditional< - is_pointer::value, - typename remove_pointer::type, - typename remove_extent::type - >::type UnboundCharType; - typedef typename SBindCharacter::type BoundCharType; - typedef BoundCharType* type; - }; - - // SAutomaticallyDeduced: - // Placeholder type that is never defined, used by SRequire for SFINAE overloading. - struct SAutomaticallyDeduced; - - // SRequire: - // Helper for SFINAE overloading. - // Similar to C++11's std::enable_if, which is not in boost (with that exact name anyway). - template - struct SRequire - { - typedef T type; - }; - template - struct SRequire {}; - - // SafeCast: - // Cast a pointer to type T, but only allowing safe casts. - // This guards against bad code in other functions since it prevents unintended casts. - template - inline T SafeCast(SourceChar* ptr, typename SRequire::value>::type* = 0) - { - // Allow casts from pointer-to-integral to unrelated pointer-to-integral, provided they are of the same size. - typedef typename remove_pointer::type TargetChar; - COMPILE_TIME_ASSERT(is_integral::value && is_integral::value); - COMPILE_TIME_ASSERT(sizeof(SourceChar) == sizeof(TargetChar)); - return reinterpret_cast(ptr); - } - template - inline T SafeCast(SourceChar* ptr, typename SRequire::type, QChar>::value>::type* = 0) - { - // Allow casts from pointer-to-QChar to unrelated pointer-to-integral, provided they are of the same size. - typedef typename remove_pointer::type TargetChar; - COMPILE_TIME_ASSERT(is_integral::value); - COMPILE_TIME_ASSERT(sizeof(SourceChar) == sizeof(TargetChar)); - return reinterpret_cast(ptr); - } - template - inline T SafeCast(SourceChar* ptr, typename SRequire::value&& !is_same::type, QChar>::value>::type* = 0) - { - // Any other casts that are allowed by C++. - return static_cast(ptr); - } - - // SCharacterTrait: - // Exposes some basic traits for a given character. - // Note: Map to (hopefully optimized) CRT functions where possible. - template::value> - struct SCharacterTrait - { - static size_t StrLen(const T* nts) // Fall-back strlen. - { - size_t result = 0; - while (*nts != 0) - { - ++nts; - ++result; - } - return result; - } - static size_t StrNLen(const T* ptr, size_t len) // Fall-back strnlen. - { - size_t result = 0; - while (*ptr != 0 && result != len) - { - ++ptr; - ++result; - } - return result; - } - }; - template - struct SCharacterTrait - { - static size_t StrLen(const T* nts) // Narrow CRT strlen. - { - return ::strlen(SafeCast(nts)); - } - static size_t StrNLen(const T* ptr, size_t len) // Narrow CRT strnlen. - { - return ::strnlen(SafeCast(ptr), len); - } - }; - template - struct SCharacterTrait - { - static size_t StrLen(const T* nts) // Wide CRT strlen. - { - return ::wcslen(SafeCast(nts)); - } - static size_t StrNLen(const T* ptr, size_t len) // Wide CRT strnlen. - { -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION UNICODEBINDING_H_SECTION_1 - #include AZ_RESTRICTED_FILE(UnicodeBinding_h) -#endif - return ::wcsnlen(SafeCast(ptr), len); -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION UNICODEBINDING_H_SECTION_2 - #include AZ_RESTRICTED_FILE(UnicodeBinding_h) -#endif - } - }; - - // void Feed(const SPackedIterators &its, Sink &out, tag): - // Feeds the provided sink from provided packed iterator-range. - template - inline void Feed(const SPackedIterators& its, Sink& out, integral_constant) - { - typedef typename std::iterator_traits::value_type UnboundCharType; - typedef typename SBindCharacter::type BoundCharType; - for (InputIteratorType it = its.begin; it != its.end; ++it) - { - const UnboundCharType unbound = *it; - const BoundCharType bound = static_cast(unbound); - const uint32 item = static_cast(bound); - out(item); - } - } - - // void Feed(const SPackedIterators &its, Sink &out, tag): - // Feeds the provided sink from provided packed pointer-range. - // This is slightly better code-generation than using generic iterators. - template - inline void Feed(const SPackedIterators& its, Sink& out, integral_constant) - { - typedef typename SBindPointer::type PointerType; - assert(reinterpret_cast(its.begin) <= reinterpret_cast(its.end) && "Invalid range specified"); - const size_t length = its.end - its.begin; - PointerType ptr = SafeCast(its.begin); - assert((ptr || !length) && "Passed a non-empty range containing a null-pointer"); - for (size_t i = 0; i < length; ++i, ++ptr) - { - const uint32 item = static_cast(*ptr); - out(item); - } - } - - // void Feed(const InputStringType &in, Sink &out, tag): - // Feeds the provided sink from a container, using it's iterators. - // Note: Dispatches to one of the packed-range overloads. - template - inline void Feed(const InputStringType& in, Sink& out, integral_constant tag) - { - typedef typename InputStringType::const_iterator IteratorType; - Detail::SPackedIterators its(in.begin(), in.end()); - Feed(its, out, tag); - } - - // void Feed(const InputStringType &in, Sink &out, tag): - // Feeds the provided sink from a string-object's buffer. - template - inline void Feed(const InputStringType& in, Sink& out, integral_constant) - { - typedef typename InputStringType::size_type SizeType; - typedef typename InputStringType::value_type ValueType; - typedef typename SBindPointer::type PointerType; - const SizeType length = in.size(); - if (length) - { - PointerType ptr = SafeCast(in.data()); - for (SizeType i = 0; i < length; ++i, ++ptr) - { - const uint32 item = static_cast(*ptr); - out(item); - } - } - } - - // void Feed(const InputStringType &in, Sink &out, tag): - // Feeds the provided sink from a string-literal. - // Note: The literal is assumed to be null-terminated. - // It's possible that a const-element fixed-size-buffer is mistaken as a literal. - // However, we expect no-one uses such buffers that are not null-terminated already. - // If somehow this use-case is desired, either terminate the buffer, or remove const from the buffer, or pass iterators. - template - inline void Feed(const InputStringType& in, Sink& out, integral_constant) - { - COMPILE_TIME_ASSERT(is_array::value && extent::value > 0); - typedef typename SBindPointer::type PointerType; - const size_t length = extent::value - 1; - PointerType ptr = SafeCast(in); - assert(ptr[length] == 0 && "Literal is not null-terminated"); - for (size_t i = 0; i < length; ++i, ++ptr) - { - const uint32 item = static_cast(*ptr); - out(item); - } - } - - // void Feed(const InputStringType &in, Sink &out, tag): - // Feeds the provided sink from a non-const-element fixed-size buffer. - // Note: The buffer is allowed to be null-terminated, but it's not required. - template - inline void Feed(const InputStringType& in, Sink& out, integral_constant) - { - COMPILE_TIME_ASSERT(is_array::value && extent::value > 0); - typedef typename SBindPointer::type PointerType; - typedef typename SBindPointer::BoundCharType CharType; - const size_t length = extent::value; - PointerType ptr = SafeCast(in); - for (size_t i = 0; i < length; ++i, ++ptr) - { - const CharType unbound = *ptr; - if (unbound == 0) - { - break; - } - const uint32 item = static_cast(unbound); - out(item); - } - } - - // void Feed(const InputStringType &in, Sink &out, tag): - // Feeds the provided sink from a null-terminated C-style string. - template - inline void Feed(const InputStringType& in, Sink& out, integral_constant) - { - COMPILE_TIME_ASSERT(is_pointer::value); - typedef typename SBindPointer::type PointerType; - typedef typename SBindPointer::BoundCharType CharType; - PointerType ptr = SafeCast(in); - if (ptr) - { - while (true) - { - const CharType unbound = *ptr; - ++ptr; - if (unbound == 0) - { - break; - } - const uint32 item = static_cast(unbound); - out(item); - } - } - } - - // void Feed(const InputCharType &in, Sink &out, tag): - // Feeds the provided sink from a single value (interpreted as an UCS code-point). - template - inline void Feed(const InputCharType& in, Sink& out, integral_constant) - { - COMPILE_TIME_ASSERT(is_arithmetic::value); - const uint32 item = static_cast(in); - out(item); - } - - // size_t EncodedLength(const SPackedIterators &its, tag): - // Determines the length of the input sequence in a range of iterators. - template - inline size_t EncodedLength(const SPackedIterators& its, integral_constant) - { - return std::distance(its.begin, its.end); // std::distance will pick optimal implementation depending on iterator category. - } - - // size_t EncodedLength(const InputStringType &in, tag): - // Determines the length of an input container, which would otherwise be enumerated with iterators. - template - inline size_t EncodedLength(const InputStringType& in, integral_constant) - { - return in.size(); // Can there be a container without size()? At the very least, not in the supported types. - } - - // size_t EncodedLength(const InputStringType &in, tag): - // Determines the length of the input container. The container uses contiguous element layout. - template - inline size_t EncodedLength(const InputStringType& in, integral_constant) - { - return in.size(); - } - - // size_t EncodedLength(const InputStringType &in, tag): - // Determines the length of the input string-literal. This is a compile-time constant. - template - inline size_t EncodedLength(const InputStringType& in, integral_constant) - { - COMPILE_TIME_ASSERT(is_array::value && extent::value > 0); - return extent::value - 1; - } - - // size_t EncodedLength(const InputStringType &in, tag): - // Determines the length of the input fixed-size-buffer. We look for an (optional) null-terminator in the buffer. - template - inline size_t EncodedLength(const InputStringType& in, integral_constant) - { - COMPILE_TIME_ASSERT(is_array::value && extent::value > 0); - typedef typename remove_extent::type CharType; - return SCharacterTrait::StrNLen(in, extent::value); - } - - // size_t EncodedLength(const InputStringType &in, tag): - // Determines the length of the input used-specified buffer. We look for an (optional) null-terminator in the buffer. - template - inline size_t EncodedLength(const SPackedBuffer& in, integral_constant) - { - return in.buffer ? SCharacterTrait::StrNLen(in.buffer, in.size) : 0; - } - - // size_t EncodedLength(const InputStringType &in, tag): - // Determines the length of the input null-terminated c-style string. We just use strlen() if available. - template - inline size_t EncodedLength(const InputStringType& in, integral_constant) - { - COMPILE_TIME_ASSERT(is_pointer::value); - typedef typename remove_pointer::type CharType; - return in ? SCharacterTrait::StrLen(in) : 0; - } - - // size_t EncodedLength(const InputCharType &in, tag): - // Determines the length of a single UCS code-point. This is always 1. - template - inline size_t EncodedLength([[maybe_unused]] const InputCharType& in, integral_constant) - { - COMPILE_TIME_ASSERT(is_arithmetic::value); - return 1; - } - - // const void *EncodedPointer(const SPackedIterators &its, tag): - // Get a pointer to contiguous storage for an iterator range. - // Note: This can only work if the iterators are pointers, or the storage won't be guaranteed contiguous. - template - inline const void* EncodedPointer(const SPackedIterators& its, integral_constant) - { - return its.begin; - } - - // const void *EncodedPointer(const InputStringType &in, tag): - // Get a pointer to contiguous storage for string/vector object. - // Note: This can only work for containers that actually use contiguous storage, which is determined by the SBindXXX helpers. - template - inline const void* EncodedPointer(const InputStringType& in, integral_constant) - { - return in.data(); - } - - // const void *EncodedPointer(const InputStringType &in, tag): - // Get a pointer to contiguous storage for a string-literal. - template - inline const void* EncodedPointer(const InputStringType& in, integral_constant) - { - COMPILE_TIME_ASSERT(is_array::value && extent::value > 0); - return in; // We can just let the array type decay to a pointer. - } - - // const void *EncodedPointer(const InputStringType &in, tag): - // Get a pointer to contiguous storage for a fixed-size-buffer. - template - inline const void* EncodedPointer(const InputStringType& in, integral_constant) - { - COMPILE_TIME_ASSERT(is_array::value && extent::value > 0); - return in; // We can just let the array type decay to a pointer. - } - - // const void *EncodedPointer(const InputStringType &in, tag): - // Get a pointer to contiguous storage for a null-terminated c-style-string. - template - inline const void* EncodedPointer(const InputStringType& in, integral_constant) - { - COMPILE_TIME_ASSERT(is_pointer::value); - return in; // Implied - } - - // const void *EncodedPointer(const InputCharType &in, tag): - // Get a pointer to contiguous storage for a single UCS code-point. - template - inline const void* EncodedPointer(const InputCharType& in, integral_constant) - { - COMPILE_TIME_ASSERT(is_arithmetic::value); - return ∈ // Take the address of the parameter (which is kept on the stack of the caller). - } - - // SWriteSink: - // A helper that performs writing to the type T and can be passed as Sink type to a trans-coder helper. - template - struct SWriteSink; - template - struct SWriteSink - { - typedef typename T::value_type OutputCharType; - T& out; - SWriteSink(T& _out, size_t) - : out(_out) - { - if (!Append) - { - // If not appending, clear the object beforehand. - out.clear(); - } - } - void operator()(uint32 item) - { - const OutputCharType bound = static_cast(item); - out.push_back(bound); // We assume this can't fail and STL container takes care of memory. - } - void operator()(const void*, size_t); // Not implemented. - void HintSequence(uint32 length) {} // Don't care about sequences. - bool CanWrite() const { return true; } // Always writable - }; - template - struct SWriteSink - { - typedef SBindPointer BindHelper; - typedef typename BindHelper::UnboundCharType CharType; - CharType* ptr; - SWriteSink(T& out, size_t length) - { - const size_t offset = Append ? out.size() : 0; - length += offset; - out.resize(static_cast(length)); // resize() can't fail without exceptions, so assert instead. - assert((out.size() == length) && "Buffer resize failed (out-of-memory?)"); - const CharType* base = length ? out.data() : 0; - ptr = const_cast(base + offset); - } - void operator()(uint32 item) - { - *SafeCast(ptr) = static_cast(item); - ++ptr; - } - void operator()(const void* src, size_t length) - { - ::memcpy(ptr, src, length * sizeof(CharType)); - ptr += length; - } - void HintSequence([[maybe_unused]] uint32 length) {} // Don't care about sequences. - bool CanWrite() const { return true; } // Always writable - }; - template - struct SWriteSink, Append, eBind_PackedBuffer> - { - typedef typename remove_pointer

::type ElementType; - typedef SBindPointer BindHelper; - typedef typename BindHelper::UnboundCharType CharType; - CharType* ptr; - CharType* const terminator; - SWriteSink(CharType* _terminator) - : terminator(_terminator) {} - SWriteSink(SPackedBuffer

& out, size_t) - : terminator(out.size && out.buffer ? out.buffer + out.size - 1 : 0) - { - const size_t offset = Append - ? EncodedLength(out, integral_constant()) - : 0; - const size_t fixedOffset = Append && offset >= out.size - ? out.size - 1 // In case the buffer is already full and not terminated. - : offset; - CharType* base = static_cast(out.buffer); - ptr = terminator ? base + fixedOffset : 0; - } - ~SWriteSink() - { - if (ptr) - { - *ptr = 0; // Guarantees that the output is null-terminated. - } - } - void operator()(uint32 item) - { - if (ptr != terminator) // Guarantees we don't overflow the buffer. - { - *SafeCast(ptr) = static_cast(item); - ++ptr; - } - } - void operator()(const void* src, size_t length) - { - const size_t maxLength = terminator - ptr; - if (length > maxLength) - { - length = maxLength; - } - ::memcpy(ptr, src, length * sizeof(CharType)); - ptr += length; - } - void HintSequence(uint32 length) - { - if (terminator && (ptr + length >= terminator)) - { - // This sequence will overflow the buffer. - // In this case, we prefer to not generate any part of the sequence. - // Terminate at the current position and flag as full. - *ptr = 0; - ptr = terminator; - } - } - bool CanWrite() const - { - return terminator != ptr; - } - }; - template - struct SWriteSink // Uses above implementation with specialized constructor - : SWriteSink::type*>, Append, eBind_PackedBuffer> - { - typedef typename remove_extent::type ElementType; - typedef SWriteSink, Append, eBind_PackedBuffer> Super; - typedef SBindPointer BindHelper; - typedef typename BindHelper::UnboundCharType CharType; - SWriteSink(T& out, size_t) - : Super(out + extent::value - 1) - { - const size_t offset = Append - ? EncodedLength(out, integral_constant()) - : 0; - const size_t fixedOffset = Append && offset >= extent::value - ? extent::value - 1 // In case the buffer is already full and not terminated. - : offset; - Super::ptr = out + fixedOffset; // Qualification for Super required for two-phase lookup. - } - }; - - // SIsBlockCopyable: - // Check if block-copy optimization is possible for these types. - // InputType should be an instantiation of SBindObject or SBindIterator. - // OutputType should be an instantiation of SBindOutput. - // Note: This doesn't take into account safe/unsafe conversions, just if the underlying storage types are compatible. - template - struct SIsBlockCopyable - { - template - struct SIsContiguous - { - static const bool value = - M == eBind_Data || - M == eBind_Literal || - M == eBind_Buffer || - M == eBind_PackedBuffer || - M == eBind_NullTerminated || - M == eBind_CodePoint; - }; - template - struct SIsPointers - { - static const bool value = false; - }; - template - struct SIsPointers > - { - static const bool value = true; - }; - typedef typename SBindCharacter::type InputCharType; - typedef typename SBindCharacter::type OutputCharType; - static const bool isIntegral = is_integral::value && is_integral::value; - static const bool isSameSize = sizeof(InputCharType) == sizeof(OutputCharType); - static const bool isInputContiguous = (SIsContiguous::value || SIsPointers::value); - static const bool isOutputContiguous = (SIsContiguous::value || SIsPointers::value); - static const bool value = isIntegral && isSameSize && isInputContiguous && isOutputContiguous; - }; - } -} diff --git a/Code/Legacy/CryCommon/UnicodeEncoding.h b/Code/Legacy/CryCommon/UnicodeEncoding.h deleted file mode 100644 index a3e20b639c..0000000000 --- a/Code/Legacy/CryCommon/UnicodeEncoding.h +++ /dev/null @@ -1,767 +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 - * - */ - - -// Description : Generic Unicode encoding helpers. -// -// Defines encoding and decoding functions used by the higher-level functions. -// These are used by the various conversion functions in UnicodeFunctions.h and UnicodeIterator.h. -// Note: You can use these functions manually for low-level functionality, but we don't recommend that. -// In that case, you probably want to check inside the nested Detail namespace for the elementary bits. - - -#pragma once -#include "BaseTypes.h" // For uint8, uint16, uint32 -#include "CompileTimeAssert.h" // For COMPILE_TIME_ASSERT macro -namespace Unicode -{ - // Supported encoding/conversion types. - enum EEncoding - { - // UTF-8 encoding, see http://www.unicode.org/resources/utf8.html. - // Input and output are supported. - // Note: This format maps the entire UCS, where each code-point can take [1, 4] 8-bit code-units. - // Note: This is a strict super-set of Latin1/ISO-885901 as well as ASCII. - eEncoding_UTF8, - - // UTF-16 encoding, see http://tools.ietf.org/html/rfc2781. - // Input and output are supported. - // Note: This format maps the entire UCS, where each code-point can take [1, 2] 16-bit code-units. - eEncoding_UTF16, - - // UTF-32 encoding, see http://www.unicode.org/reports/tr17/. - // Input and output are supported. - // Note: This format maps the entire UCS, each code-point is stored in a single 32-bit code-unit. - eEncoding_UTF32, - - // ASCII encoding, see http://en.wikipedia.org/wiki/ASCII. - // Input and output are supported (any output UCS values out of supported range are mapped to question mark). - // Note: Only values [U+0000, U+007F] can be mapped. - eEncoding_ASCII, - - // Latin1, aka ISO-8859-1 encoding, see http://en.wikipedia.org/wiki/ISO/IEC_8859-1. - // Only input is supported. - // Note: This is a strict super-set of ASCII, it additionally maps [U+00A0, U+00FF]. - eEncoding_Latin1, - - // Windows ANSI codepage 1252, see http://en.wikipedia.org/wiki/Windows-1252. - // Only input is supported. - // Note: This is a strict super-set of ASCII and Latin1/ISO-8859-1, it maps some code-units from [0x80, 0x9F]. - eEncoding_Win1252, - }; - - // Methods of recovery from invalid encoded sequences. - enum EErrorRecovery - { - // No attempt to detect invalid encoding is performed, the input is assumed to be valid. - // If the input is not valid, the output is undefined (in debug, this condition will cause an assert to trigger). - eErrorRecovery_None, - - // When an invalidly encoded sequence is detected, the sequence is discarded (will not be part of the output). - // Typically used for logic/hashing purposes when the input is almost certainly valid. - eErrorRecovery_Discard, - - // When an invalidly encoded sequence is detected, the sequence is replaced with the replacement-character (U+FFFD). - // Typically used when the output sequence is used for UI display purposes. - eErrorRecovery_Replace, - - // When an invalidly encoded sequence is detected, the sequence is replaced with the eEncoding_Latin1 equivalent. - // If the sequence is also not valid Latin1 encoded, the sequence is discarded. - // Typically used when reading generic text files with 1-byte code-units. - // Note: This recovery method can only be used when decoding UTF-8. - eErrorRecovery_FallbackLatin1ThenDiscard, - - // When an invalidly encoded sequence is detected, the sequence is replaced with the eEncoding_Win1252 equivalent. - // If the sequence is also not valid codepage 1252 encoded, the sequence is discarded. - // Typically used when reading text files generated on Windows with 1-byte code-units. - // Note: This recovery method can only be used when decoding UTF-8. - eErrorRecovery_FallbackWin1252ThenDiscard, - - // When an invalidly encoded sequence is detected, the sequence is replaced with the eEncoding_Latin1 equivalent. - // If the sequence is also not valid Latin1 encoded, it is replaced with the replacement-character (U+FFFD). - // Typically used when reading generic text files with 1-byte code-units. - // Note: This recovery method can only be used when decoding UTF-8. - eErrorRecovery_FallbackLatin1ThenReplace, - - // When an invalidly encoded sequence is detected, the sequence is replaced with the eEncoding_Win1252 equivalent. - // If the sequence is also not valid codepage 1252 encoded, it is replaced with the replacement-character (U+FFFD). - // Typically used when reading text files generated on Windows with 1-byte code-units. - // Note: This recovery method can only be used when decoding UTF-8. - eErrorRecovery_FallbackWin1252ThenReplace, - }; - - namespace Detail - { - // Decode(state, unit): Decodes a single code-unit of an encoding into an UCS code-point. - // When Safe flag is set, encoding errors are detected so a fall-back encoding or other recovery method can be used. - // Interpret return value as follows: - // < 0x001FFFFF: Decoded codepoint (== return value), call again with next code-unit and clear state. - // < 0x80000000: Intermediate state returned, call again with next code-unit and the returned state. - // >= 0x80000000: Bad encoding detected, up to 16 bits (UTF-16) or 24 bits (UTF-8, last in lower bits) - // contain previous consumed values (does not happen if Safe == false). - template - inline uint32 Decode(uint32 state, uint32 unit); - - // Some constant values used when encoding/decoding. - enum - { - cDecodeShiftRemaining = 26, // Where to store the remaining count in the state. - cDecodeOneRemaining = 1 << cDecodeShiftRemaining, // Remaining value of one. - cDecodeMaskRemaining = 3 << cDecodeShiftRemaining, // All possible remaining bits that can be used. - cDecodeLeadBit = 1 << 22, // All bits up to and including this one are reserved. - cDecodeErrorBit = 1 << 31, // Set if an error occurs during decoding. - cDecodeOverlongBit = 1 << 30, // Set if overlong sequence was used. - cDecodeSurrogateBit = 1 << 29, // Set if surrogate code-point decoded in UTF-8. - cDecodeInvalidBit = 1 << 28, // Set if invalid code-point decoded (U+FFFE/FFFF). - cDecodeSuccess = 0, // Placeholder to indicate no error occurred. - cCodepointMax = 0x10FFFF, // The maximum value of an UCS code-point. - cLeadSurrogateFirst = 0xD800, // The first valid UTF-16 lead-surrogate value. - cLeadSurrogateLast = 0xDBFF, // The last valid UTF-16 lead-surrogate value. - cTrailSurrogateFirst = 0xDC00, // The first valid UTF-16 trail-surrogate value. - cTrailSurrogateLast = 0xDFFF, // The last valid UTF-16 trail-surrogate value. - cReplacementCharacter = 0xFFFD, // The default replacement character. - }; - - // Validate the UTF-8 state of a multi-byte sequence. - // The safe decoder of UTF-8 will call this function when a full potential code-point has been decoded. - // This function is (at most) called for 50% of the decoded UTF-8 code-units, but likely at much lower frequency. - inline uint32 DecodeValidate8(uint32 state) - { - uint32 errorbits = (state >> 8) | cDecodeErrorBit; - state ^= (state & 0x400000) >> 1; // For 3-byte sequences, bit 5 of the lead byte needs to be cleared. - const uint32 cp = - (state & 0x3F) | - ((state & 0x3F00) >> 2) | - ((state & 0x3F0000) >> 4) | - ((state & 0x07000000) >> 6); - if (cp <= cCodepointMax) - { - if (cp >= cLeadSurrogateFirst && cp <= cTrailSurrogateLast) - { - errorbits += cDecodeSurrogateBit; // CESU-8 encoding might have been used. - } - else - { - uint32 minval = 0x80; - minval += (0x00400000 & state) ? 0x800 - 0x80 : 0; - minval += (0x40000000 & state) ? 0x10000 - 0x80 : 0; - if (cp >= minval) - { - if ((cp & 0xFFFFFFFEU) != 0xFFFEU) - { - return cp; // Valid code-point. - } - errorbits += cDecodeInvalidBit; // Invalid character used. - } - errorbits += cDecodeOverlongBit; // Overlong encoding used. - } - } - return errorbits; - } - - // Decode UTF-8, unsafe. - template<> - inline uint32 Decode(uint32 state, uint32 unit) - { - if (state == 0) // First byte. - { - unit = unit & 0xFF; - if (unit < 0xC0) - { - return unit; // Single-unit (ASCII). - } - uint32 remaining = (unit >> 4) - 0xC; - remaining += (remaining == 0); - return (unit & 0x1F) + (remaining << cDecodeShiftRemaining); // Lead byte of multi-byte. - } - state = (state << 6) + (unit & 0x3F) + (state & cDecodeMaskRemaining) - cDecodeOneRemaining; // Apply c-byte. - return state & ~cDecodeLeadBit; // Mask off the lead bits of a 4-byte sequence. - } - - // Decode UTF-8, safe - template<> - inline uint32 Decode(uint32 state, uint32 unit) - { - if (unit <= 0xF4) // Discard out-of-range values immediately. - { - if (state == 0) // First byte. - { - if (unit < 0x80) - { - return unit; // Single-byte. - } - if (unit < 0xC2) - { - return cDecodeErrorBit; // Invalid continuation byte (or illegal 0xC0/0xC1). - } - uint32 remaining = (unit >> 4) - 0xC; - remaining += (remaining == 0); - return unit + (remaining << cDecodeShiftRemaining); // Multi-byte. - } - if ((unit & 0xC0) == 0x80) - { - const uint32 remaining = (state & cDecodeMaskRemaining) - cDecodeOneRemaining; - state = (state << 8) + unit; - if (remaining != 0) - { - return state | remaining; // Intermediate byte of a multi-byte sequence. - } - return DecodeValidate8(state); // Final byte of a multi-byte sequence. - } - } - return cDecodeErrorBit | state; - } - - // Decode UTF-16, unsafe. - template<> - inline uint32 Decode(uint32 state, uint32 unit) - { - const bool bLead = (unit >= cLeadSurrogateFirst) && (unit <= cLeadSurrogateLast); - const uint32 initial = unit + (bLead << cDecodeShiftRemaining); - const uint32 pair = 0x10000 + ((state & 0x3FF) << 10) + (unit & 0x3FF); - return state == 0 ? initial : pair; - } - - // Decode UTF-16, safe. - template<> - inline uint32 Decode(uint32 state, uint32 unit) - { - const bool bTrail = (unit >= cTrailSurrogateFirst) && (unit <= cTrailSurrogateLast); - if (state != 0 && !bTrail) - { - return cDecodeErrorBit + (state & 0xFFFF); // Lead surrogate without trail surrogate - } - uint32 result = Decode(state, unit); - bool bValid = (result & 0xFFFFFFFEU) != 0xFFFEU; - return bValid ? result : result + cDecodeErrorBit + cDecodeInvalidBit; - } - - // Decode UTF-32, unsafe. - template<> - inline uint32 Decode([[maybe_unused]] uint32 state, uint32 unit) - { - return unit; - } - - // Decode UTF-32, safe. - template<> - inline uint32 Decode([[maybe_unused]] uint32 state, uint32 unit) - { - if (unit > cCodepointMax) - { - return cDecodeErrorBit; - } - if (unit >= cLeadSurrogateFirst && unit <= cTrailSurrogateLast) - { - return cDecodeErrorBit | cDecodeSurrogateBit; - } - if ((unit & 0xFFFEU) == 0xFFFEU) - { - return cDecodeErrorBit | cDecodeInvalidBit; - } - return unit; - } - - // Decode ASCII, unsafe. - template<> - inline uint32 Decode([[maybe_unused]] uint32 state, uint32 unit) - { - return unit; - } - - // Decode ASCII, safe. - template<> - inline uint32 Decode([[maybe_unused]] uint32 state, uint32 unit) - { - if (unit > 0x7F) - { - return cDecodeErrorBit; - } - return unit; - } - - // Decode Latin1, unsafe. - template<> - inline uint32 Decode([[maybe_unused]] uint32 state, uint32 unit) - { - return unit; - } - - // Decode Latin1, safe. - template<> - inline uint32 Decode([[maybe_unused]] uint32 state, uint32 unit) - { - if ((unit >= 0x80 && unit <= 0x9F) || (unit > 0xFF)) - { - return cDecodeErrorBit; - } - return unit; - } - - // Decode Windows CP-1252, unsafe. - template<> - inline uint32 Decode([[maybe_unused]] uint32 state, uint32 unit) - { - static const uint16 cp1252[] = - { - 0x20AC, 0x0081, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, - 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x008D, 0x017D, 0x008F, - 0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, - 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x009D, 0x017E, 0x0178, - }; - return (unit < 0x80 || unit > 0x9F) ? unit : cp1252[unit - 0x80]; - } - - // Decode Windows CP-1252, safe. - template<> - inline uint32 Decode(uint32 state, uint32 unit) - { - if (unit > 0xFF) - { - return cDecodeErrorBit; - } - uint32 result = Decode(state, unit); - if (!(unit < 0x80 || unit > 0x9F) && (result == unit)) - { - return cDecodeErrorBit; // Not defined in codepage 1252. - } - return result; - } - - // SBase: - // Utility to apply empty-base-optimization on type T. - // Will fall back to a member if T is a reference type. - template - struct SBase - : T - { - SBase(T base) - : T(base) {} - T& GetBase() { return *this; } - const T& GetBase() const { return *this; } - }; - template - struct SBase - { - T& base; - SBase(T& b) - : base(b) {} - T& GetBase() { return base; } - const T& GetBase() const { return base; } - }; - - // SDecoder: - // Functor to decode UCS code-points from an input range. - // Recovery functor will be invoked as a fall-back if decoding fails. - // This allows ensuring all the output is valid (even if the input isn't). - // Note: The destructor will automatically flush any remaining (erroneous) state, you can also call Finalize(). - template - struct SDecoder - : SBase - , SBase - { - uint32 state; - SDecoder(Sink sink, Recovery recovery = Recovery()) - : SBase(sink) - , SBase(recovery) - , state(0) {} - SDecoder() { Finalize(); } - Recovery& recovery() { return SBase::GetBase(); } - Sink& sink() { return SBase::GetBase(); } - void operator()(uint32 unit) - { - state = Detail::Decode(state, unit); - if (state <= 0x1FFFFF) - { - sink()(state); - state = 0; - } - else if (state & Detail::cDecodeErrorBit) - { - recovery()(sink(), state, unit); - state = 0; - } - } - void Finalize() - { - if (state) - { - recovery()(sink(), state, 0); - state = 0; - } - } - }; - - // SDecoder: - // Functor to decode to UCS code-points from an input range. - // No attempt to discover or recover from encoding errors is made, can only safely be used with known-valid input. - template - struct SDecoder - : SBase - { - uint32 state; - SDecoder(Sink sink) - : SBase(sink) - , state(0) {} - Sink& sink() { return SBase::GetBase(); } - void operator()(uint32 unit) - { - state = Detail::Decode(state, unit); - if (state <= 0x1FFFFF) - { - sink()(state); - state = 0; - } - } - void Finalize() {} - }; - - // SEncoder: - // Generic Unicode encoder functor. - // Encoding must be one an encoding type for which output is supported. - // The Sink type must have HintSequence member for UTF-8 and UTF-16 (although it may be a no-op). - // In general, you feed operator() with UCS code-points and it will emit code-units. - template - struct SEncoder - { - static const bool value = false; - }; - - // SEncoder: - // Specialization of ASCII encoder functor. - // Note: Any out-of-range character is mapped to question mark. - template - struct SEncoder - : SBase - { - static const bool value = true; - typedef uint8 value_type; - SEncoder(Sink sink) - : SBase(sink) {} - void operator()(uint32 cp) - { - cp = cp < 0x80 ? cp : (uint32)'?'; - SBase::GetBase()(value_type(cp)); - } - }; - - // SEncoder: - // Specialization of UTF-8 encoder functor. - template - struct SEncoder - : SBase - { - static const bool value = true; - typedef uint8 value_type; - SEncoder(Sink sink) - : SBase(sink) {} - Sink& sink() { return SBase::GetBase(); } - void operator()(uint32 cp) - { - if (cp < 0x80) - { - // Single byte sequence. - sink()(value_type(cp)); - } - else - { - // Expand 21-bit value to 32-bit. - uint32 bits = - (cp & 0x00003F) + - ((cp & 0x000FC0) << 2) + - ((cp & 0x03F000) << 4) + - ((cp & 0x1C0000) << 6); - - // Type of sequence. - const bool bSeq4 = (cp >= 0x10000); - const bool bSeq3 = (cp >= 0x800); - - // Mask lead-bytes and continuation-bytes. - uint32 mask = 0xEFE0C080; - mask ^= (bSeq3 << 14); - mask += (bSeq4 ? 0xA00000 : 0); - bits |= mask; - - // Length of the sequence. - const uint32 length = (uint32)bSeq4 + (uint32)bSeq3 + 1; - sink().HintSequence(length); - - // Sink the multi-byte sequence. - if (bSeq4) - { - sink()(value_type(bits >> 24)); - } - if (bSeq3) - { - sink()(value_type(bits >> 16)); - } - sink()(value_type(bits >> 8)); - sink()(value_type(bits)); - } - } - }; - - // SEncoder: - // Specialization of UTF-16 encoder functor. - template - struct SEncoder - : SBase - { - static const bool value = true; - typedef uint16 value_type; - SEncoder(Sink sink) - : SBase(sink) {} - Sink& sink() { return SBase::GetBase(); } - void operator()(uint32 cp) - { - if (cp < 0x10000) - { - // Single unit - sink()(value_type(cp)); - } - else - { - // We will generate two-element sequence - sink().HintSequence(2); - - // Surrogate pair - cp -= 0x10000; - uint32 lead = ((cp >> 10) & 0x3FF) + Detail::cLeadSurrogateFirst; - uint32 trail = (cp & 0x3FF) + Detail::cTrailSurrogateFirst; - sink()(value_type(lead)); - sink()(value_type(trail)); - } - } - }; - - // SEncoder: - // Specialization of UTF-32 encoder functor. - // Note: This is a no-op, but we want to be able to express UTF-32 just like the other encodings. - template - struct SEncoder - : SBase - { - static const bool value = true; - typedef uint32 value_type; - SEncoder(Sink sink) - : SBase(sink) {} - void operator()(uint32 cp) - { - SBase::GetBase()(value_type(cp)); - } - }; - - // SDecoder, void>: - // Specialization for unsafe no-op trans-coding. - // Since the conversion is a no-op, no need to keep any state or do any computation. - // Note: For a decoding with a fallback, this is not possible since we can't guarantee the input is valid. - template - struct SDecoder, void> - { - Sink sink; - SDecoder(Sink s) - : sink(s) {} - void operator()(uint32 unit) - { - sink(unit); - } - void Finalize() {} - }; - - // SRecoveryDiscard: - // Recovery handler that, on encoding error, discards the offending sequence. - template - struct SRecoveryDiscard - { - SRecoveryDiscard() {} - void operator()([[maybe_unused]] Sink& sink, [[maybe_unused]] uint32 error, [[maybe_unused]] uint32 unit) {} - }; - - // SRecoveryReplace: - // Recovery handler that, on encoding error, replaces the sequence with replacement-character (U+FFFD). - // Note: This implementation matches a whole invalid sequence, it could be changed to emit for every code-unit. - template - struct SRecoveryReplace - { - SRecoveryReplace() {} - void operator()(Sink& sink, uint32 error, uint32 unit) { sink(cReplacementCharacter); } - }; - - // SRecoveryFallback: - // Recovery handler that, on encoding error, falls back to another encoding. - // The fallback encoding must be stateless (ie: ASCII, Latin1 or Win1252). - // This type assumes an 8-bit primary encoding since the only viable fallback encodings are 8-bit. - template - struct SRecoveryFallback - : NextFallback - { - SRecoveryFallback() - : NextFallback() {} - void operator()(Sink& sink, uint32 error, uint32 unit) - { - SDecoder fallback(sink, *static_cast(this)); - uint8 byte1(error >> 16); - uint8 byte2(error >> 8); - uint8 byte3(error); - uint8 byte4(unit); - if (byte1) - { - fallback(byte1); - } - if (byte1 | byte2) - { - fallback(byte2); - } - if (byte1 | byte2 | byte3) - { - fallback(byte3); - } - fallback(byte4); - } - }; - - // SRecoveryFallbackHelper: - // Helper to pick a SRecoveryFallback instantiation based on RecoveryMethod. - template - struct SRecoveryFallbackHelper - { - // A compilation error here means RecoveryMethod value was unexpected here - COMPILE_TIME_ASSERT( - RecoveryMethod == eErrorRecovery_FallbackLatin1ThenDiscard || - RecoveryMethod == eErrorRecovery_FallbackLatin1ThenReplace || - RecoveryMethod == eErrorRecovery_FallbackWin1252ThenDiscard || - RecoveryMethod == eErrorRecovery_FallbackWin1252ThenReplace); - typedef SEncoder SinkType; - static const EEncoding FallbackEncoding = - RecoveryMethod == eErrorRecovery_FallbackLatin1ThenDiscard || - RecoveryMethod == eErrorRecovery_FallbackLatin1ThenReplace - ? eEncoding_Latin1 : eEncoding_Win1252; - template - struct Pick - { - typedef SRecoveryDiscard type; - }; - template - struct Pick - { - typedef SRecoveryReplace type; - }; - typedef typename Pick::type NextFallback; - typedef SRecoveryFallback RecoveryType; - typedef SDecoder FullType; - }; - - // STranscoderSelect: - // Derives a chained decoder/encoder pair that performs code-unit -> code-unit transform. - // The RecoveryMethod template parameter determines the behavior during encoding. - // This is the basic way to perform trans-coding, and is the type instantiated by the higher-level functions. - template - struct STranscoderSelect; - template - struct STranscoderSelect - : SDecoder, void> - { - typedef SDecoder, void> TranscoderType; - STranscoderSelect(Sink sink) - : TranscoderType(sink) {} - }; - template - struct STranscoderSelect - : SDecoder, SRecoveryDiscard > > - { - typedef SRecoveryDiscard > RecoveryType; - typedef SDecoder, RecoveryType> TranscoderType; - STranscoderSelect(Sink sink) - : TranscoderType(sink) {} - }; - template - struct STranscoderSelect - : SDecoder, SRecoveryReplace > > - { - typedef SRecoveryReplace > RecoveryType; - typedef SDecoder, RecoveryType> TranscoderType; - STranscoderSelect(Sink sink) - : TranscoderType(sink) {} - }; - template - struct STranscoderSelect - : SRecoveryFallbackHelper::FullType - { - static const EErrorRecovery RecoveryMethod = eErrorRecovery_FallbackLatin1ThenDiscard; - typedef typename SRecoveryFallbackHelper::RecoveryType RecoveryType; - typedef typename SRecoveryFallbackHelper::FullType TranscoderType; - STranscoderSelect(Sink sink) - : TranscoderType(sink) {} - }; - template - struct STranscoderSelect - : SRecoveryFallbackHelper::FullType - { - static const EErrorRecovery RecoveryMethod = eErrorRecovery_FallbackLatin1ThenReplace; - typedef typename SRecoveryFallbackHelper::RecoveryType RecoveryType; - typedef typename SRecoveryFallbackHelper::FullType TranscoderType; - STranscoderSelect(Sink sink) - : TranscoderType(sink) {} - }; - template - struct STranscoderSelect - : SRecoveryFallbackHelper::FullType - { - static const EErrorRecovery RecoveryMethod = eErrorRecovery_FallbackWin1252ThenDiscard; - typedef typename SRecoveryFallbackHelper::RecoveryType RecoveryType; - typedef typename SRecoveryFallbackHelper::FullType TranscoderType; - STranscoderSelect(Sink sink) - : TranscoderType(sink) {} - }; - template - struct STranscoderSelect - : SRecoveryFallbackHelper::FullType - { - static const EErrorRecovery RecoveryMethod = eErrorRecovery_FallbackWin1252ThenReplace; - typedef typename SRecoveryFallbackHelper::RecoveryType RecoveryType; - typedef typename SRecoveryFallbackHelper::FullType TranscoderType; - STranscoderSelect(Sink sink) - : TranscoderType(sink) {} - }; - - // SIsSafeEncoding: - // Check if the given recovery mode is safe. - // This is used for SFINAE checks in higher-level functions. - template - struct SIsSafeEncoding - { - static const bool value = - R == eErrorRecovery_Discard || - R == eErrorRecovery_Replace || - R == eErrorRecovery_FallbackLatin1ThenDiscard || - R == eErrorRecovery_FallbackLatin1ThenReplace || - R == eErrorRecovery_FallbackWin1252ThenDiscard || - R == eErrorRecovery_FallbackWin1252ThenReplace; - }; - - // SIsCopyableEncoding: - // Check if data in one encoding can be copied directly to another encoding. - // This is the basis for block-copy and string-assign optimizations in un-safe conversion functions. - // Note: There are more valid combinations, they are left out since those can't occur with the output encodings supported. - // Note: Only used for un-safe functions since it doesn't account for potential invalid sequences (they would be copied over). - template - struct SIsCopyableEncoding - { - static const bool value = - InputEncoding == eEncoding_ASCII || // ASCII and Latin1 values don't change in any encoding. - (InputEncoding == eEncoding_Latin1 && OutputEncoding != eEncoding_ASCII); // Except Latin1 -> ASCII is lossy. - }; - template - struct SIsCopyableEncoding - { - static const bool value = true; // If the input and output encodings are the same, then it's copyable. - }; - } -} diff --git a/Code/Legacy/CryCommon/UnicodeFunctions.h b/Code/Legacy/CryCommon/UnicodeFunctions.h deleted file mode 100644 index 48debe9706..0000000000 --- a/Code/Legacy/CryCommon/UnicodeFunctions.h +++ /dev/null @@ -1,1265 +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 - * - */ - - -// Generic Unicode string functions. -// -// Implements the following functions: -// Analyze: Reports all information on the input string, (length for all encodings, validity- and non-ASCII flags). -// Validate: Checks if the input string is valid encoded. -// Length: Reports the encoded length of some known-valid input, as-if it was encoded in the given output encoding. -// LengthSafe: Reports the encoded length of some input, as-if it was encoded in the given output encoding/recovery. -// Convert: Converts input from a known-valid string type/encoding to another string type/encoding. -// ConvertSafe: Converts and recovers encoding errors from one string type/encoding to another string type/encoding. -// Append: Appends input from a known-valid string type/encoding to another string type/encoding. -// AppendSafe: Appends and recovers encoding errors from one string type/encoding to another string type/encoding. -// -// Note: Ideally the safe functions should be used only once when accepting input from the user or from a file. -// Afterwards, the content is known-safe and the unsafe functions can be used for optimal performance. -// Using ConvertSafe once with a reasonable fall-back (depending on the where the input is from) should be the goal. -// -// Each function has several overloads: -// - One variant to handle a string object / buffer / pointer (1 arg), and one to handle iterators (2 args). -// - One variant with automatic encoding (picks UTF encoding depending on character size), and one for specific encoding. -// - One variant that returns a new string, and one that takes an existing string to overwrite (Convert(Safe) only). -// Each function takes one default argument that employs SFINAE to pick the correct overload depending on the arguments. - - -#pragma once -#include "UnicodeBinding.h" -namespace Unicode -{ - // Results of analysis of an input range of code-units (in any encoding). - // This is returned by calling Analyze() function. - struct SAnalysisResult - { - // The type to use for counting units. - // Can be changed to uint64_t for dealing with 4GB+ of string data. - typedef uint32 size_type; - - size_type inputUnits; // The number of input units analyzed. - size_type outputUnits8; // The number of output units when encoded with UTF-8. - size_type outputUnits16; // The number of output units when encoded with UTF-16. - size_type outputUnits32; // The number of output units when encoded with UTF-32 (aka number of UCS code-points). - size_type cpNonAscii; // The number of non-ASCII UCS code-points encountered. - size_type cpInvalid; // The number of invalid UCS code-point encountered (or 0xFFFFFFFF if not available). - - // Default constructor, initialize everything to zero. - SAnalysisResult() - : inputUnits(0) - , outputUnits8(0) - , outputUnits16(0) - , outputUnits32(0) - , cpInvalid(0) - , cpNonAscii(0) {} - - // Check if the input range was empty. - bool IsEmpty() const { return inputUnits == 0; } - - // Check if the input range only contained ASCII characters. - bool IsAscii() const { return cpNonAscii == 0; } - - // Check if the input range was valid (has no encoding errors). - // Note: This returns false if an unsafe decoder was used for analysis. - bool IsValid() const { return cpInvalid == 0; } - - // Get the length of the input range, in source code-units. - size_type LengthInSourceUnits() const { return inputUnits; } - - // Get the length of the input range, in UCS code-points. - size_type LengthInUCS() const { return outputUnits32; } - - // Get the length of the input range when encoded with the given encoding, in code-units. - // Note: If the encoding is not supported for output, the function returns 0. - size_type LengthInEncodingUnits(EEncoding encoding) const - { - switch (encoding) - { - case eEncoding_ASCII: - case eEncoding_UTF32: - return outputUnits32; - case eEncoding_UTF16: - return outputUnits16; - case eEncoding_UTF8: - return outputUnits8; - default: - return 0; - } - } - - // Get the length of the input range when encoded with the given encoding, in bytes. - // Note: If the encoding is not supported for output, the function returns 0. - size_type LengthInEncodingBytes(EEncoding encoding) const - { - size_type units = LengthInEncodingUnits(encoding); - switch (encoding) - { - case eEncoding_UTF32: - return units << 2; - case eEncoding_UTF16: - return units << 1; - default: - return units; - } - } - }; - - namespace Detail - { - // SDummySink: - // A sink implementation that does nothing. - struct SDummySink - { - void operator()([[maybe_unused]] uint32 unit) {} - void HintSequence([[maybe_unused]] uint32 length) {} - }; - - // SCountingSink: - // A sink that counts the number of units of output. - struct SCountingSink - { - size_t result; - - SCountingSink() - : result(0) {} - void operator()([[maybe_unused]] uint32 unit) { ++result; } - void HintSequence([[maybe_unused]] uint32 length) {} - }; - - // SAnalysisSink: - // A sink that updates analysis statistics. - struct SAnalysisSink - { - SAnalysisResult& result; - - SAnalysisSink(SAnalysisResult& _result) - : result(_result) {} - void operator()(uint32 cp) - { - const bool isCat2 = cp >= 0x80; - const bool isCat3 = cp >= 0x800; - const bool isCat4 = cp >= 0x10000; - result.outputUnits32 += 1; - result.outputUnits16 += (1 + isCat4); - result.outputUnits8 += (1 + isCat4 + isCat3 + isCat2); - result.cpNonAscii += isCat2; - } - void HintSequence([[maybe_unused]] uint32 length) {} - }; - - // SAnalysisRecovery: - // A recovery helper for analysis that counts invalid sequences. - struct SAnalysisRecovery - { - SAnalysisRecovery() {} - void operator()(SAnalysisSink& sink, [[maybe_unused]] uint32 error, [[maybe_unused]] uint32 unit) - { - sink.result.cpInvalid += 1; - } - }; - - // SValidationRecovery: - // A recovery helper for validation, it tracks if there is any invalid sequence. - struct SValidationRecovery - { - bool isValid; - - SValidationRecovery() - : isValid(true) {} - void operator()([[maybe_unused]] SDummySink& sink, [[maybe_unused]] uint32 error, [[maybe_unused]] uint32 unit) - { - isValid = false; - } - }; - - // SAnalyzer: - // Helper to perform analysis, counts the input for a given encoding. - template - struct SAnalyzer - { - SDecoder decoder; - - SAnalyzer(SAnalysisResult& result) - : decoder(result) {} - void operator()(uint32 item) - { - decoder.sink().result.inputUnits += 1; - decoder(item); - } - }; - - // Analyze(target, source): - // Analyze string and store analysis result. - // This is the generic function called by other Analyze overloads. - template - inline void Analyze(SAnalysisResult& target, const InputStringType& source) - { - // Bind methods. - const EBind bindMethod = SBindObject::value; - integral_constant tag; - - // Analyze using helper. - SAnalyzer analyzer(target); - Feed(source, analyzer, tag); - } - - // Validate(source): - // Tests that the string is valid encoding. - // This is the generic function called by other Validate overloads. - template - inline bool Validate(const InputStringType& source) - { - // Bind methods. - const EBind bindMethod = SBindObject::value; - integral_constant tag; - - // Validate using helper. - SDummySink sink; - SDecoder validator(sink); - Feed(source, validator, tag); - return validator.recovery().isValid; - } - - // Length(str): - // Find length of a string (in code-units) after trans-coding from InputEncoding to OutputEncoding. - // This is the generic function called by the other Length overloads. - template - inline size_t Length(const InputStringType& source) - { - // If this assert hits, consider using LengthSafe. - assert((Detail::Validate(source)) && "Length was used with non-safe input"); - - // Bind methods. - const EBind bindMethod = SBindObject::value; - integral_constant tag; - - // All copyable encodings have the property that the number of input encoding units equals the output units. - // In addition, this also holds for UTF-32 (always 1) -> ASCII (always 1), even though it's lossy. - const bool isCopyable = SIsCopyableEncoding::value; - const bool isCountable = isCopyable || (InputEncoding == eEncoding_UTF32 && OutputEncoding == eEncoding_ASCII); - - if (isCountable) - { - // Optimization: The number of input units is equal to the number of output units. - return EncodedLength(source, tag); - } - else - { - // We need to perform the conversion. - SCountingSink sink; - STranscoderSelect transcoder(sink); - Feed(source, transcoder, tag); - return sink.result; - } - } - - // LengthSafe(str): - // Find length of a string (in code-units) after trans-coding from InputEncoding to OutputEncoding. - // Note: The Recovery type used during conversion may influence the result, so this needs to match if you use the length information. - // This is the generic function called by the other LengthSafe overloads. - template - inline size_t LengthSafe(const InputStringType& source) - { - // SRequire a safe recovery method. - COMPILE_TIME_ASSERT(SIsSafeEncoding::value); - - // Bind methods. - const EBind bindMethod = SBindObject::value; - integral_constant tag; - - // We can't optimize here, since we cannot assume the input is validly encoded - SCountingSink sink; - STranscoderSelect transcoder(sink); - Feed(source, transcoder, tag); - return sink.result; - } - - // SBlockCopy: - // Helper for block-copying entire string at once (as an optimization) - // This optimization will effectively try to memcpy or assign the whole string at once. - // Note: We need to do some partial specialization here to find out if the optimization is valid, so we can't use a function in C++98. - template - struct SBlockCopy - { - static const EBind bindMethod = SBindObject::value; - typedef integral_constant TagType; - size_t operator()(OutputStringType& target, const InputStringType& source) - { - // Optimization: Use block copying for these types. - TagType tag; - const size_t length = EncodedLength(source, tag); - SinkType sink(target, length); - if (sink.CanWrite()) - { - const void* const dataPtr = EncodedPointer(source, tag); - sink(dataPtr, length); - } - return length; - } - }; - - // SBlockCopy: - // Specialization that will use direct string assignment. - // Note: This optimization is not selected when appending, this could be a future optimization if this is common. - // Reason for this is that the += operator is not present on all supported types (ie, std::vector) - template - struct SBlockCopy - { - size_t operator()(SameStringType& target, const SameStringType& source) - { - // Optimization: Use copy assignment. - target = source; - return source.size(); - } - }; - - // SBlockCopy: - // Fall-back specialization for Enable == false. - // Note: This specialization has to exist for the linker, but should never be called (and optimized away). - template - struct SBlockCopy - { - size_t operator()([[maybe_unused]] OutputStringType& target, [[maybe_unused]] const InputStringType& source) - { - assert(false && "Should never be called"); - return 0; - } - }; - - // Convert(target, source): - // Trans-code a string from InputEncoding to OutputEncoding. - // This is the generic function that is called by Convert and Append overloads. - // Returns the number of code-units required for full output (excluding any terminators) - template - inline size_t Convert(OutputStringType& target, const InputStringType& source) - { - // If this assert hits, consider using ConvertSafe. - assert((Detail::Validate(source)) && "Convert was used with non-safe input"); - - // Bind methods. - const EBind inputBindMethod = SBindObject::value; - const EBind outputBindMethod = SBindOutput::value; - integral_constant tag; - typedef SWriteSink SinkType; - - // Check if we can optimize this. - const bool isCopyable = SIsCopyableEncoding::value; - const bool isBlocks = SIsBlockCopyable, SBindOutput >::value; - const bool useBlockCopy = isCopyable && isBlocks; - size_t length; - if (useBlockCopy) - { - // Use optimized path. - SBlockCopy blockCopy; - length = blockCopy(target, source); - } - else - { - // We need to perform the conversion code-unit by code-unit. - length = Detail::Length(source); - SinkType sink(target, length); - if (sink.CanWrite()) - { - STranscoderSelect transcoder(sink); - Feed(source, transcoder, tag); - } - } - return length; - } - - // ConvertSafe(target, source): - // Safely trans-code a string from InputEncoding to OutputEncoding using the specified Recovery to handle encoding errors. - // This is the generic function called by ConvertSafe and AppendSafe overloads. - template - inline size_t ConvertSafe(OutputStringType& target, const InputStringType& source) - { - // SRequire a safe recovery method. - COMPILE_TIME_ASSERT(SIsSafeEncoding::value); - - // Bind methods. - const EBind inputBindMethod = SBindObject::value; - const EBind outputBindMethod = SBindOutput::value; - integral_constant tag; - typedef SWriteSink SinkType; - - // We can't optimize with block-copy here, since we cannot assume the input is validly encoded. - const size_t length = Detail::LengthSafe(source); - SinkType sink(target, length); - if (sink.CanWrite()) - { - STranscoderSelect transcoder(sink); - Feed(source, transcoder, tag); - } - return length; - } - - // SReqAutoObj: - // Require that T is usable as input object, with automatic encoding. - // This is used as a SFINAE argument for overload resolution of the main functions. - template - struct SReqAutoObj - : SRequire< - SBindObject::value != eBind_Impossible&& - SEncoder::value&& - SIsSafeEncoding::value - > {}; - - // SReqAutoIts: - // Require that T is usable as input iterator, with automatic encoding. - // This is used as a SFINAE argument for overload resolution of the main functions. - template - struct SReqAutoIts - : SRequire< - SBindIterator::value != eBind_Impossible&& - SEncoder::value&& - SIsSafeEncoding::value - > {}; - - // SReqAnyObj: - // Require that T is usable as input object, with user-specified encoding. - // This is used as a SFINAE argument for overload resolution of the main functions. - template - struct SReqAnyObj - : SRequire< - SBindObject::value != eBind_Impossible&& - SEncoder::value&& - SIsSafeEncoding::value - > {}; - - // SReqAnyIts: - // Require that T is usable as input iterator, with user-specified encoding. - // This is used as a SFINAE argument for overload resolution of the main functions. - template - struct SReqAnyIts - : SRequire< - SBindIterator::value != eBind_Impossible&& - SEncoder::value&& - SIsSafeEncoding::value - > {}; - - // SReqAutoObjOut: - // Require that I is usable as input object, and O as output object, with automatic encoding. - // This is used as a SFINAE argument for overload resolution of the main functions. - template - struct SReqAutoObjOut - : SRequire< - SBindObject::value != eBind_Impossible&& - SBindOutput, O>::type, true>::value != eBind_Impossible&& - SEncoder::value&& - SIsSafeEncoding::value - > {}; - - // SReqAutoItsOut: - // Require that I is usable as input iterator, and O as output object, with automatic encoding. - // This is used as a SFINAE argument for overload resolution of the main functions. - template - struct SReqAutoItsOut - : SRequire< - SBindIterator::value != eBind_Impossible&& - SBindOutput, O>::type, true>::value != eBind_Impossible&& - SEncoder::value&& - SIsSafeEncoding::value - > {}; - - // SReqAnyObjOut: - // Require that I is usable as input object, and O as output object, with user-specified encoding. - // This is used as a SFINAE argument for overload resolution of the main functions. - template - struct SReqAnyObjOut - : SRequire< - SBindObject::value != eBind_Impossible&& - SBindOutput, O>::type, false>::value != eBind_Impossible&& - SEncoder::value&& - SIsSafeEncoding::value - > {}; - - // SReqAnyItsOut: - // Require that I is usable as input object, and O as output object, with user-specified encoding. - // This is used as a SFINAE argument for overload resolution of the main functions. - template - struct SReqAnyItsOut - : SRequire< - SBindIterator::value != eBind_Impossible&& - SBindOutput, O>::type, false>::value != eBind_Impossible&& - SEncoder::value&& - SIsSafeEncoding::value - > {}; - } - - // SAnalysisResult Analyze(str): - // Analyze the given string with the given encoding, providing information on validity and encoding length. - template - inline SAnalysisResult Analyze(const InputStringType& str, - typename Detail::SReqAnyObj::type* = 0) - { - SAnalysisResult result; - Detail::Analyze(result, str); - return result; - } - - // SAnalysisResult Analyze(str): - // Analyze the (assumed) Unicode string input, providing information on validity and encoding length. - // The Unicode encoding is picked automatically depending on the input type. - template - inline SAnalysisResult Analyze(const InputStringType& str, - typename Detail::SReqAutoObj::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - SAnalysisResult result; - Detail::Analyze(result, str); - return result; - } - - // SAnalysisResult Analyze(begin, end): - // Analyze the given range with the given encoding, providing information on validity and encoding length. - template - inline SAnalysisResult Analyze(InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAnyIts::type* = 0) - { - typedef Detail::SPackedIterators InputStringType; - const InputStringType its(begin, end); - SAnalysisResult result; - Detail::Analyze(result, its); - return result; - } - - // SAnalysisResult Analyze(begin, end): - // Analyze the given (assumed) Unicode range, providing information on validity and encoding length. - // The Unicode encoding is picked automatically depending on the input type. - template - inline SAnalysisResult Analyze(InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAutoIts::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - typedef Detail::SPackedIterators InputStringType; - const InputStringType its(begin, end); - SAnalysisResult result; - Detail::Analyze(result, its); - return result; - } - - // bool Validate(str): - // Checks if the given string is valid in the given encoding. - template - inline bool Validate(const InputStringType& str, - typename Detail::SReqAnyObj::type* = 0) - { - return Detail::Validate(str); - } - - // bool Validate(str): - // Checks if the given string is a valid Unicode string. - // The Unicode encoding is picked automatically depending on the input type. - template - inline bool Validate(const InputStringType& str, - typename Detail::SReqAutoObj::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - return Detail::Validate(str); - } - - // bool Validate(begin, end): - // Checks if the given range is valid in the given encoding. - template - inline bool Validate(InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAnyIts::type* = 0) - { - typedef Detail::SPackedIterators InputStringType; - const InputStringType its(begin, end); - return Detail::Validate(its); - } - - // bool Validate(begin, end): - // Checks if the given range is valid Unicode. - // The Unicode encoding is picked automatically depending on the input type. - template - inline bool Validate(InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAutoIts::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - typedef Detail::SPackedIterators InputStringType; - const InputStringType its(begin, end); - return Detail::Validate(its); - } - - // size_t Length(str): - // Get the length (in OutputEncoding) of the given known-valid string with the given InputEncoding. - // Note: Length assumes the input is valid encoded, if this is not guaranteed (ie, user-input), use LengthSafe. - template - inline size_t Length(const InputStringType& str, - typename Detail::SReqAnyObj::type* = 0) - { - return Detail::Length(str); - } - - // size_t Length(str): - // Get the length (in OutputEncoding) of the given known-valid Unicode string. - // The Unicode encoding is picked automatically depending on the input type. - // Note: Length assumes the input is valid encoded, if this is not guaranteed (ie, user-input), use LengthSafe. - template - inline size_t Length(const InputStringType& str, - typename Detail::SReqAutoObj::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - return Detail::Length(str); - } - - // size_t Length(begin, end): - // Get the length (in OutputEncoding) of the known-valid range with the given InputEncoding. - // Note: Length assumes the input is valid encoded, if this is not guaranteed (ie, user-input), use LengthSafe. - template - inline size_t Length(InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAnyIts::type* = 0) - { - typedef Detail::SPackedIterators InputStringType; - const InputStringType its(begin, end); - return Detail::Length(its); - } - - // size_t Length(begin, end): - // Get the length (in OutputEncoding) of the known-valid Unicode range. - // The Unicode encoding is picked automatically depending on the input type. - // Note: Length assumes the input is valid encoded, if this is not guaranteed (ie, user-input), use LengthSafe. - template - inline size_t Length(InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAutoIts::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - typedef Detail::SPackedIterators InputStringType; - const InputStringType its(begin, end); - return Detail::Length(its); - } - - // size_t LengthSafe(str): - // Get the length (in OutputEncoding) of the given string with the given InputEncoding. - // Note: LengthSafe uses the specified Recovery parameter to fix encoding errors, if the input is known-valid, use Length. - template - inline size_t LengthSafe(const InputStringType& str, - typename Detail::SReqAnyObj::type* = 0) - { - return Detail::LengthSafe(str); - } - - // size_t LengthSafe(str): - // Get the length (in OutputEncoding) of the given Unicode string. - // The Unicode encoding is picked automatically depending on the input type. - // Note: LengthSafe uses the specified Recovery parameter to fix encoding errors, if the input is known-valid, use Length. - template - inline size_t LengthSafe(const InputStringType& str, - typename Detail::SReqAutoObj::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - return Detail::LengthSafe(str); - } - - // size_t LengthSafe(begin, end): - // Get the length (in OutputEncoding) of the range with the given InputEncoding. - // Note: LengthSafe uses the specified Recovery parameter to fix encoding errors, if the input is known-valid, use Length. - template - inline size_t LengthSafe(InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAnyIts::type* = 0) - { - typedef Detail::SPackedIterators InputStringType; - const InputStringType its(begin, end); - return Detail::LengthSafe(its); - } - - // size_t LengthSafe(begin, end): - // Get the length (in OutputEncoding) of the Unicode range. - // The Unicode encoding is picked automatically depending on the input type. - // Note: LengthSafe uses the specified Recovery parameter to fix encoding errors, if the input is known-valid, use Length. - template - inline size_t LengthSafe(InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAutoIts::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - typedef Detail::SPackedIterators InputStringType; - const InputStringType its(begin, end); - return Detail::LengthSafe(its); - } - - // OutputStringType &Convert(result, str): - // Converts the given string in the given input encoding and stores into the result string with the given output encoding. - // Note: Convert assumes the input is valid encoded, if this is not guaranteed (ie, user-input), use ConvertSafe. - template - inline OutputStringType& Convert(OutputStringType& result, const InputStringType& str, - typename Detail::SReqAnyObjOut::type* = 0) - { - Detail::Convert(result, str); - return result; - } - - // OutputStringType &Convert(result, str): - // Converts the (assumed) Unicode string input and stores into the result Unicode string. - // The Unicode encodings are picked automatically depending on the input type and output type. - // Note: Convert assumes the input is valid encoded, if this is not guaranteed (ie, user-input), use ConvertSafe. - template - inline OutputStringType& Convert(OutputStringType& result, const InputStringType& str, - typename Detail::SReqAutoObjOut::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - const EEncoding OutputEncoding = Detail::SInferEncoding::value; - Detail::Convert(result, str); - return result; - } - - // OutputStringType &Convert(result, begin, end): - // Converts the given range in the given input encoding and stores into the result string with the given output encoding. - // Note: Convert assumes the input is valid encoded, if this is not guaranteed (ie, user-input), use ConvertSafe. - template - inline OutputStringType& Convert(OutputStringType& result, InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAnyItsOut::type* = 0) - { - typedef Detail::SPackedIterators InputStringType; - const InputStringType its(begin, end); - Detail::Convert(result, its); - return result; - } - - // OutputStringType &Convert(result, begin, end): - // Converts the (assumed) Unicode range and stores into the result Unicode string. - // The Unicode encodings are picked automatically depending on the range type and output type. - // Note: Convert assumes the input is valid encoded, if this is not guaranteed (ie, user-input), use ConvertSafe. - template - inline OutputStringType& Convert(OutputStringType& result, InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAutoItsOut::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - const EEncoding OutputEncoding = Detail::SInferEncoding::value; - typedef Detail::SPackedIterators InputStringType; - const InputStringType its(begin, end); - Detail::Convert(result, its); - return result; - } - - // size_t Convert(buffer, length, str): - // Converts the given string in the given input encoding and stores into the result buffer with the given output encoding. - // Returns the required length of the output buffer, in code-units, including the null-terminator. - // Note: Convert assumes the input is valid encoded, if this is not guaranteed (ie, user-input), use ConvertSafe. - template - inline size_t Convert(OutputCharType* buffer, size_t length, const InputStringType& str, - typename Detail::SReqAnyObjOut::type* = 0) - { - typedef Detail::SPackedBuffer OutputStringType; - OutputStringType result(buffer, length); - return Detail::Convert(result, str) + 1; - } - - // size_t Convert(buffer, length, str): - // Converts the (assumed) Unicode string input and stores into the result Unicode buffer. - // The Unicode encodings are picked automatically depending on the buffer type and output type. - // Returns the required length of the output buffer, in code-units, including the null-terminator. - // Note: Convert assumes the input is valid encoded, if this is not guaranteed (ie, user-input), use ConvertSafe. - template - inline size_t Convert(OutputCharType* buffer, size_t length, const InputStringType& str, - typename Detail::SReqAutoObjOut::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - const EEncoding OutputEncoding = Detail::SInferEncoding::value; - typedef Detail::SPackedBuffer OutputStringType; - OutputStringType result(buffer, length); - return Detail::Convert(result, str) + 1; - } - - // size_t Convert(buffer, length, begin, end): - // Converts the given range in the given input encoding and stores into the result buffer with the given output encoding. - // Returns the required length of the output buffer, in code-units, including the null-terminator. - // Note: Convert assumes the input is valid encoded, if this is not guaranteed (ie, user-input), use ConvertSafe. - template - inline size_t Convert(OutputCharType* buffer, size_t length, InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAnyItsOut::type* = 0) - { - typedef Detail::SPackedIterators InputStringType; - typedef Detail::SPackedBuffer OutputStringType; - const InputStringType its(begin, end); - OutputStringType result(buffer, length); - return Detail::Convert(result, its) + 1; - } - - // size_t Convert(buffer, length, begin, end): - // Converts the (assumed) Unicode range and stores into the result Unicode buffer. - // The Unicode encodings are picked automatically depending on the range type and output type. - // Returns the required length of the output buffer, in code-units, including the null-terminator. - // Note: Convert assumes the input is valid encoded, if this is not guaranteed (ie, user-input), use ConvertSafe. - template - inline size_t Convert(OutputCharType* buffer, size_t length, InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAutoItsOut::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - const EEncoding OutputEncoding = Detail::SInferEncoding::value; - typedef Detail::SPackedIterators InputStringType; - typedef Detail::SPackedBuffer OutputStringType; - const InputStringType its(begin, end); - OutputStringType result(buffer, length); - return Detail::Convert(result, its) + 1; - } - - // OutputStringType Convert(str): - // Converts the given string in the given input encoding to a new string of the given type and output encoding. - // Note: Convert assumes the input is valid encoded, if this is not guaranteed (ie, user-input), use ConvertSafe. - template - inline OutputStringType Convert(const InputStringType& str, - typename Detail::SReqAnyObjOut::type* = 0) - { - OutputStringType result; - Detail::Convert(result, str); - return result; - } - - // OutputStringType Convert(str): - // Converts the (assumed) Unicode string input to a new Unicode string of the given type. - // The Unicode encodings are picked automatically depending on the input type and output type. - // Note: Convert assumes the input is valid encoded, if this is not guaranteed (ie, user-input), use ConvertSafe. - template - inline OutputStringType Convert(const InputStringType& str, - typename Detail::SReqAutoObjOut::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - const EEncoding OutputEncoding = Detail::SInferEncoding::value; - OutputStringType result; - Detail::Convert(result, str); - return result; - } - - // OutputStringType Convert(begin, end): - // Converts the given range in the given input encoding to a new string of the given type and output encoding. - // Note: Convert assumes the input is valid encoded, if this is not guaranteed (ie, user-input), use ConvertSafe. - template - inline OutputStringType Convert(InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAnyItsOut::type* = 0) - { - typedef Detail::SPackedIterators InputStringType; - const InputStringType its(begin, end); - OutputStringType result; - Detail::Convert(result, its); - return result; - } - - // OutputStringType Convert(begin, end): - // Converts the (assumed) Unicode range to a new Unicode string of the given type. - // The Unicode encodings are picked automatically depending on the range type and output type. - // Note: Convert assumes the input is valid encoded, if this is not guaranteed (ie, user-input), use ConvertSafe. - template - inline OutputStringType Convert(InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAutoItsOut::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - const EEncoding OutputEncoding = Detail::SInferEncoding::value; - typedef Detail::SPackedIterators InputStringType; - const InputStringType its(begin, end); - OutputStringType result; - Detail::Convert(result, its); - return result; - } - - // OutputStringType &ConvertSafe(result, str): - // Converts the given string in the given input encoding and stores into the result string with the given output encoding. - // Note: ConvertSafe uses the specified Recovery parameter to fix encoding errors, if the input is known-valid, use Convert. - template - inline OutputStringType& ConvertSafe(OutputStringType& result, const InputStringType& str, - typename Detail::SReqAnyObjOut::type* = 0) - { - Detail::ConvertSafe(result, str); - return result; - } - - // OutputStringType &ConvertSafe(result, str): - // Converts the (assumed) Unicode string input and stores into the result Unicode string. - // The Unicode encodings are picked automatically depending on the input type and output type. - // Note: ConvertSafe uses the specified Recovery parameter to fix encoding errors, if the input is known-valid, use Convert. - template - inline OutputStringType& ConvertSafe(OutputStringType& result, const InputStringType& str, - typename Detail::SReqAutoObjOut::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - const EEncoding OutputEncoding = Detail::SInferEncoding::value; - Detail::ConvertSafe(result, str); - return result; - } - - // OutputStringType &ConvertSafe(result, begin, end): - // Converts the given range in the given input encoding and stores into the result string with the given output encoding. - // Note: ConvertSafe uses the specified Recovery parameter to fix encoding errors, if the input is known-valid, use Convert. - template - inline OutputStringType& ConvertSafe(OutputStringType& result, InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAnyItsOut::type* = 0) - { - typedef Detail::SPackedIterators InputStringType; - const InputStringType its(begin, end); - Detail::ConvertSafe(result, its); - return result; - } - - // OutputStringType &ConvertSafe(result, begin, end): - // Converts the (assumed) Unicode range and stores into the result Unicode string. - // The Unicode encodings are picked automatically depending on the range type and output type. - // Note: ConvertSafe uses the specified Recovery parameter to fix encoding errors, if the input is known-valid, use Convert. - template - inline OutputStringType& ConvertSafe(OutputStringType& result, InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAutoItsOut::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - const EEncoding OutputEncoding = Detail::SInferEncoding::value; - typedef Detail::SPackedIterators InputStringType; - const InputStringType its(begin, end); - Detail::ConvertSafe(result, its); - return result; - } - - // size_t ConvertSafe(buffer, length, str): - // Converts the given string in the given input encoding and stores into the result buffer with the given output encoding. - // Returns the required length of the output buffer, in code-units, including the null-terminator. - // Note: ConvertSafe uses the specified Recovery parameter to fix encoding errors, if the input is known-valid, use Convert. - template - inline size_t ConvertSafe(OutputCharType* buffer, size_t length, const InputStringType& str, - typename Detail::SReqAnyObjOut::type* = 0) - { - typedef Detail::SPackedBuffer OutputStringType; - OutputStringType result(buffer, length); - return Detail::ConvertSafe(result, str) + 1; - } - - // size_t ConvertSafe(buffer, length, str): - // Converts the (assumed) Unicode string input and stores into the result Unicode buffer. - // The Unicode encodings are picked automatically depending on the buffer type and output type. - // Returns the required length of the output buffer, in code-units, including the null-terminator. - // Note: ConvertSafe uses the specified Recovery parameter to fix encoding errors, if the input is known-valid, use Convert. - template - inline size_t ConvertSafe(OutputCharType* buffer, size_t length, const InputStringType& str, - typename Detail::SReqAutoObjOut::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - const EEncoding OutputEncoding = Detail::SInferEncoding::value; - typedef Detail::SPackedBuffer OutputStringType; - OutputStringType result(buffer, length); - return Detail::ConvertSafe(result, str) + 1; - } - - // size_t ConvertSafe(buffer, length, begin, end): - // Converts the given range in the given input encoding and stores into the result buffer with the given output encoding. - // Returns the required length of the output buffer, in code-units, including the null-terminator. - // Note: ConvertSafe uses the specified Recovery parameter to fix encoding errors, if the input is known-valid, use Convert. - template - inline size_t ConvertSafe(OutputCharType* buffer, size_t length, InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAnyItsOut::type* = 0) - { - typedef Detail::SPackedIterators InputStringType; - typedef Detail::SPackedBuffer OutputStringType; - const InputStringType its(begin, end); - OutputStringType result(buffer, length); - return Detail::ConvertSafe(result, its) + 1; - } - - // size_t ConvertSafe(buffer, length, begin, end): - // Converts the (assumed) Unicode range and stores into the result Unicode buffer. - // The Unicode encodings are picked automatically depending on the range type and output type. - // Returns the required length of the output buffer, in code-units, including the null-terminator. - // Note: ConvertSafe uses the specified Recovery parameter to fix encoding errors, if the input is known-valid, use Convert. - template - inline size_t ConvertSafe(OutputCharType* buffer, size_t length, InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAutoItsOut::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - const EEncoding OutputEncoding = Detail::SInferEncoding::value; - typedef Detail::SPackedIterators InputStringType; - typedef Detail::SPackedBuffer OutputStringType; - const InputStringType its(begin, end); - OutputStringType result(buffer, length); - return Detail::Convert(result, its) + 1; - } - - // OutputStringType ConvertSafe(str): - // Converts the given string in the given input encoding to a new string of the given type and output encoding. - // Note: ConvertSafe uses the specified Recovery parameter to fix encoding errors, if the input is known-valid, use Convert. - template - inline OutputStringType ConvertSafe(const InputStringType& str, - typename Detail::SReqAnyObjOut::type* = 0) - { - OutputStringType result; - Detail::ConvertSafe(result, str); - return result; - } - - // OutputStringType ConvertSafe(str): - // Converts the (assumed) Unicode string input to a new Unicode string of the given type. - // The Unicode encodings are picked automatically depending on the input type and output type. - // Note: ConvertSafe uses the specified Recovery parameter to fix encoding errors, if the input is known-valid, use Convert. - template - inline OutputStringType ConvertSafe(const InputStringType& str, - typename Detail::SReqAutoObjOut::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - const EEncoding OutputEncoding = Detail::SInferEncoding::value; - OutputStringType result; - Detail::ConvertSafe(result, str); - return result; - } - - // OutputStringType ConvertSafe(begin, end): - // Converts the given range in the given input encoding to a new string of the given type and output encoding. - // Note: ConvertSafe uses the specified Recovery parameter to fix encoding errors, if the input is known-valid, use Convert. - template - inline OutputStringType ConvertSafe(InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAnyItsOut::type* = 0) - { - typedef Detail::SPackedIterators InputStringType; - const InputStringType its(begin, end); - OutputStringType result; - Detail::ConvertSafe(result, its); - return result; - } - - // OutputStringType ConvertSafe(begin, end): - // Converts the (assumed) Unicode range to a new Unicode string of the given type. - // The Unicode encodings are picked automatically depending on the range type and output type. - // Note: ConvertSafe uses the specified Recovery parameter to fix encoding errors, if the input is known-valid, use Convert. - template - inline OutputStringType ConvertSafe(InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAutoItsOut::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - const EEncoding OutputEncoding = Detail::SInferEncoding::value; - typedef Detail::SPackedIterators InputStringType; - const InputStringType its(begin, end); - OutputStringType result; - Detail::ConvertSafe(result, its); - return result; - } - - // OutputStringType &Append(result, str): - // Appends the given string in the given input encoding and stores at the end of the result string with the given output encoding. - // Note: Append assumes the input is valid encoded, if this is not guaranteed (ie, user-input), use AppendSafe. - template - inline OutputStringType& Append(OutputStringType& result, const InputStringType& str, - typename Detail::SReqAnyObjOut::type* = 0) - { - Detail::Convert(result, str); - return result; - } - - // OutputStringType &Append(result, str): - // Appends the (assumed) Unicode string input and stores at the end of the result Unicode string. - // The Unicode encodings are picked automatically depending on the input type and output type. - // Note: Append assumes the input is valid encoded, if this is not guaranteed (ie, user-input), use AppendSafe. - template - inline OutputStringType& Append(OutputStringType& result, const InputStringType& str, - typename Detail::SReqAutoObjOut::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - const EEncoding OutputEncoding = Detail::SInferEncoding::value; - Detail::Convert(result, str); - return result; - } - - // OutputStringType &Append(result, begin, end): - // Appends the given range in the given input encoding and stores at the end of the result string with the given output encoding. - // Note: Append assumes the input is valid encoded, if this is not guaranteed (ie, user-input), use AppendSafe. - template - inline OutputStringType& Append(OutputStringType& result, InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAnyItsOut::type* = 0) - { - typedef Detail::SPackedIterators InputStringType; - const InputStringType its(begin, end); - Detail::Convert(result, its); - return result; - } - - // OutputStringType &Append(result, begin, end): - // Appends the (assumed) Unicode range and stores at the end of the result Unicode string. - // The Unicode encodings are picked automatically depending on the range type and output type. - // Note: Append assumes the input is valid encoded, if this is not guaranteed (ie, user-input), use AppendSafe. - template - inline OutputStringType& Append(OutputStringType& result, InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAutoItsOut::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - const EEncoding OutputEncoding = Detail::SInferEncoding::value; - typedef Detail::SPackedIterators InputStringType; - const InputStringType its(begin, end); - Detail::Convert(result, its); - return result; - } - - // size_t Append(buffer, length, str): - // Appends the given string in the given input encoding to the result buffer with the given output encoding. - // Returns the required length of the output buffer, in code-units, including the null-terminator. - // Note: Append assumes the input is valid encoded, if this is not guaranteed (ie, user-input), use AppendSafe. - template - inline size_t Append(OutputCharType* buffer, size_t length, const InputStringType& str, - typename Detail::SReqAnyObjOut::type* = 0) - { - typedef Detail::SPackedBuffer OutputStringType; - OutputStringType result(buffer, length); - return Detail::Convert(result, str) + 1; - } - - // size_t Append(buffer, length, str): - // Appends the (assumed) Unicode string input to the result Unicode buffer. - // The Unicode encodings are picked automatically depending on the buffer type and output type. - // Returns the required length of the output buffer, in code-units, including the null-terminator. - // Note: Append assumes the input is valid encoded, if this is not guaranteed (ie, user-input), use AppendSafe. - template - inline size_t Append(OutputCharType* buffer, size_t length, const InputStringType& str, - typename Detail::SReqAutoObjOut::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - const EEncoding OutputEncoding = Detail::SInferEncoding::value; - typedef Detail::SPackedBuffer OutputStringType; - OutputStringType result(buffer, length); - return Detail::Convert(result, str) + 1; - } - - // size_t Append(buffer, length, begin, end): - // Appends the given range in the given input encoding to the result buffer with the given output encoding. - // Returns the required length of the output buffer, in code-units, including the null-terminator. - // Note: Append assumes the input is valid encoded, if this is not guaranteed (ie, user-input), use AppendSafe. - template - inline size_t Append(OutputCharType* buffer, size_t length, InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAnyItsOut::type* = 0) - { - typedef Detail::SPackedIterators InputStringType; - typedef Detail::SPackedBuffer OutputStringType; - const InputStringType its(begin, end); - OutputStringType result(buffer, length); - return Detail::Convert(result, its) + 1; - } - - // size_t Append(buffer, length, begin, end): - // Appends the (assumed) Unicode range to the result Unicode buffer. - // The Unicode encodings are picked automatically depending on the range type and output type. - // Returns the required length of the output buffer, in code-units, including the null-terminator. - // Note: Append assumes the input is valid encoded, if this is not guaranteed (ie, user-input), use AppendSafe. - template - inline size_t Append(OutputCharType* buffer, size_t length, InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAutoItsOut::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - const EEncoding OutputEncoding = Detail::SInferEncoding::value; - typedef Detail::SPackedIterators InputStringType; - typedef Detail::SPackedBuffer OutputStringType; - const InputStringType its(begin, end); - OutputStringType result(buffer, length); - return Detail::Convert(result, its) + 1; - } - - // OutputStringType &AppendSafe(result, str): - // Appends the given string in the given input encoding and stores at the end of the result string with the given output encoding. - // Note: AppendSafe uses the specified Recovery parameter to fix encoding errors, if the input is known-valid, use Append. - template - inline OutputStringType& AppendSafe(OutputStringType& result, const InputStringType& str, - typename Detail::SReqAnyObjOut::type* = 0) - { - Detail::ConvertSafe(result, str); - return result; - } - - // OutputStringType &AppendSafe(result, str): - // Appends the (assumed) Unicode string input and stores at the end of the result Unicode string. - // The Unicode encodings are picked automatically depending on the input type and output type. - // Note: AppendSafe uses the specified Recovery parameter to fix encoding errors, if the input is known-valid, use Append. - template - inline OutputStringType& AppendSafe(OutputStringType& result, const InputStringType& str, - typename Detail::SReqAutoObjOut::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - const EEncoding OutputEncoding = Detail::SInferEncoding::value; - Detail::ConvertSafe(result, str); - return result; - } - - // OutputStringType &AppendSafe(result, begin, end): - // Appends the given range in the given input encoding and stores at the end of the result string with the given output encoding. - // Note: AppendSafe uses the specified Recovery parameter to fix encoding errors, if the input is known-valid, use Append. - template - inline OutputStringType& AppendSafe(OutputStringType& result, InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAnyItsOut::type* = 0) - { - typedef Detail::SPackedIterators InputStringType; - const InputStringType its(begin, end); - Detail::ConvertSafe(result, its); - return result; - } - - // OutputStringType &AppendSafe(result, begin, end): - // Appends the (assumed) Unicode range and stores at the end of the result Unicode string. - // The Unicode encodings are picked automatically depending on the range type and output type. - // Note: AppendSafe uses the specified Recovery parameter to fix encoding errors, if the input is known-valid, use Append. - template - inline OutputStringType& AppendSafe(OutputStringType& result, InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAutoItsOut::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - const EEncoding OutputEncoding = Detail::SInferEncoding::value; - typedef Detail::SPackedIterators InputStringType; - const InputStringType its(begin, end); - Detail::ConvertSafe(result, its); - return result; - } - - // size_t AppendSafe(buffer, length, str): - // Appends the given string in the given input encoding to the result buffer with the given output encoding. - // Returns the required length of the output buffer, in code-units, including the null-terminator. - // Note: AppendSafe uses the specified Recovery parameter to fix encoding errors, if the input is known-valid, use Append. - template - inline size_t AppendSafe(OutputCharType* buffer, size_t length, const InputStringType& str, - typename Detail::SReqAnyObjOut::type* = 0) - { - typedef Detail::SPackedBuffer OutputStringType; - OutputStringType result(buffer, length); - return Detail::ConvertSafe(result, str) + 1; - } - - // size_t AppendSafe(buffer, length, str): - // Appends the (assumed) Unicode string input to the result Unicode buffer. - // The Unicode encodings are picked automatically depending on the buffer type and output type. - // Returns the required length of the output buffer, in code-units, including the null-terminator. - // Note: AppendSafe uses the specified Recovery parameter to fix encoding errors, if the input is known-valid, use Append. - template - inline size_t AppendSafe(OutputCharType* buffer, size_t length, const InputStringType& str, - typename Detail::SReqAutoObjOut::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - const EEncoding OutputEncoding = Detail::SInferEncoding::value; - typedef Detail::SPackedBuffer OutputStringType; - OutputStringType result(buffer, length); - return Detail::ConvertSafe(result, str) + 1; - } - - // size_t AppendSafe(buffer, length, begin, end): - // Appends the given range in the given input encoding to the result buffer with the given output encoding. - // Returns the required length of the output buffer, in code-units, including the null-terminator. - // Note: AppendSafe uses the specified Recovery parameter to fix encoding errors, if the input is known-valid, use Append. - template - inline size_t AppendSafe(OutputCharType* buffer, size_t length, InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAnyItsOut::type* = 0) - { - typedef Detail::SPackedIterators InputStringType; - typedef Detail::SPackedBuffer OutputStringType; - const InputStringType its(begin, end); - OutputStringType result(buffer, length); - return Detail::ConvertSafe(result, its) + 1; - } - - // size_t AppendSafe(buffer, length, begin, end): - // Appends the (assumed) Unicode range to the result Unicode buffer. - // The Unicode encodings are picked automatically depending on the range type and output type. - // Returns the required length of the output buffer, in code-units, including the null-terminator. - // Note: AppendSafe uses the specified Recovery parameter to fix encoding errors, if the input is known-valid, use Append. - template - inline size_t AppendSafe(OutputCharType* buffer, size_t length, InputIteratorType begin, InputIteratorType end, - typename Detail::SReqAutoItsOut::type* = 0) - { - const EEncoding InputEncoding = Detail::SInferEncoding::value; - const EEncoding OutputEncoding = Detail::SInferEncoding::value; - typedef Detail::SPackedIterators InputStringType; - typedef Detail::SPackedBuffer OutputStringType; - const InputStringType its(begin, end); - OutputStringType result(buffer, length); - return Detail::Convert(result, its) + 1; - } -} diff --git a/Code/Legacy/CryCommon/UnicodeIterator.h b/Code/Legacy/CryCommon/UnicodeIterator.h deleted file mode 100644 index d939eaa721..0000000000 --- a/Code/Legacy/CryCommon/UnicodeIterator.h +++ /dev/null @@ -1,615 +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 - * - */ - - -// Description : Encoded Unicode sequence iteration. -// -// For lower level accessing of encoded text, an STL compatible iterator wrapper is provided. -// This iterator will decode the underlying sequence, abstracting it to a sequence of UCS code-points. -// Using the iterator wrapper, you can find where in an encoded string code-points (or encoding errors) are located. -// Note: The iterator is an input-only iterator, you cannot write to the underlying sequence. - - -#pragma once -#include "UnicodeBinding.h" -namespace Unicode -{ - namespace Detail - { - // MoveNext(it, checker, tag): - // Moves the iterator to the next UCS code-point in the encoded sequence. - // Non-specialized version (for 1:1 code-unit to code-point). - template - inline void MoveNext(BaseIterator& it, const BoundsChecker& checker, const integral_constant) - { - COMPILE_TIME_ASSERT( - Encoding == eEncoding_ASCII || - Encoding == eEncoding_UTF32 || - Encoding == eEncoding_Latin1 || - Encoding == eEncoding_Win1252); - assert(!checker.IsEnd(it) && "Attempt to iterate past the end of the sequence"); - - // All of these encodings use a single code-unit for each code-point. - ++it; - } - - // MoveNext(it, checker, tag): - // Moves the iterator to the next UCS code-point in the encoded sequence. - // Specialized for UTF-8. - template - inline void MoveNext(BaseIterator& it, const BoundsChecker& checker, integral_constant) - { - assert(!checker.IsEnd(it) && "Attempt to iterate past the end of the sequence"); - - // UTF-8: just need to skip up to 3 continuation bytes. - for (int i = 0; i < 4; ++i) - { - ++it; - if (checker.IsEnd(it)) // :WARN: always returns false if "safe" bool is false! - { - break; - } - uint32 val = static_cast(*it); - if ((val & 0xC0) != 0x80) - { - break; - } - } - } - - // MoveNext(it, checker, tag): - // Moves the iterator to the next UCS code-point in the encoded sequence. - // Specialized for UTF-16. - template - inline void MoveNext(BaseIterator& it, const BoundsChecker& checker, integral_constant) - { - assert(!checker.IsEnd(it) && "Attempt to iterate past the end of the sequence"); - - // UTF-16: just need to skip one lead surrogate. - ++it; - uint32 val = static_cast(*it); - if (val >= cLeadSurrogateFirst && val <= cLeadSurrogateLast) - { - if (!checker.IsEnd(it)) - { - ++it; - } - } - } - - // MovePrev(it, checker, tag): - // Moves the iterator to the previous UCS code-point in the encoded sequence. - // Non-specialized version (for 1:1 code-unit to code-point). - template - inline void MovePrev(BaseIterator& it, const BoundsChecker& checker, const integral_constant) - { - COMPILE_TIME_ASSERT( - Encoding == eEncoding_ASCII || - Encoding == eEncoding_UTF32 || - Encoding == eEncoding_Latin1 || - Encoding == eEncoding_Win1252); - assert(!checker.IsBegin(it) && "Attempt to iterate past the beginning of the sequence"); - - // All of these encodings use a single code-unit for each code-point. - --it; - } - - // MovePrev(it, checker, tag): - // Moves the iterator to the previous UCS code-point in the encoded sequence. - // Specialized for UTF-8. - template - inline void MovePrev(BaseIterator& it, const BoundsChecker& checker, integral_constant) - { - assert(!checker.IsBegin(it) && "Attempt to iterate past the beginning of the sequence"); - - // UTF-8: just need to skip up to 3 continuation bytes. - for (int i = 0; i < 4; ++i) - { - --it; - if (checker.IsBegin(it)) - { - break; - } - uint32 val = static_cast(*it); - if ((val & 0xC0) != 0x80) - { - break; - } - } - } - - // MovePrev(it, checker, tag): - // Moves the iterator to the previous UCS code-point in the encoded sequence. - // Specialized for UTF-16. - template - inline void MovePrev(BaseIterator& it, const BoundsChecker& checker, integral_constant) - { - assert(!checker.IsBegin(it) && "Attempt to iterate past the beginning of the sequence"); - - // UTF-16: just need to skip one lead surrogate. - --it; - uint32 val = static_cast(*it); - if (val >= cLeadSurrogateFirst && val <= cLeadSurrogateLast) - { - if (!checker.IsBegin(it)) - { - --it; - } - } - } - - // SBaseIterators: - // Utility to access base iterators properties from CIterator. - // This is the bounds-checked specialization, the range information is kept to defend against malformed sequences. - template - struct SBaseIterators - { - typedef BaseIterator type; - type begin, end; - type it; - - SBaseIterators(const BaseIterator& _begin, const BaseIterator& _end) - : begin(_begin) - , end(_end) - , it(_begin) {} - - SBaseIterators(const SBaseIterators& other) - : begin(other.begin) - , end(other.end) - , it(other.it) {} - - SBaseIterators& operator =(const SBaseIterators& other) - { - begin = other.begin; - end = other.end; - it = other.it; - return *this; - } - - bool IsBegin(const BaseIterator& _it) const - { - return begin == _it; - } - - bool IsEnd(const BaseIterator& _it) const - { - return end == _it; - } - - bool IsEqual(const SBaseIterators& other) const - { - return it == other.it - && begin == other.begin - && end == other.end; - } - - // Note: Only called inside assert. - // O(N) version; works with any forward-iterator (or better) - bool IsInRange(const BaseIterator& _it, std::forward_iterator_tag) const - { - for (BaseIterator i = begin; i != end; ++i) - { - if (_it == i) - { - return true; - } - } - return false; - } - - // Note: Only called inside assert. - // O(1) version; requires random-access-iterator. - bool IsInRange(const BaseIterator& _it, std::random_access_iterator_tag) const - { - return (begin <= _it && _it < end); - } - - // Note: Only called inside assert. - // Dispatches to the O(1) version if a random-access iterator is used (common case). - bool IsInRange(const BaseIterator& _it) const - { - return IsInRange(_it, typename std::iterator_traits::iterator_category()); - } - }; - - // SBaseIterators: - // Utility to access base iterators properties from CIterator. - // This is the un-checked specialization for known-safe sequences. - template - struct SBaseIterators - { - typedef BaseIterator type; - type it; - - explicit SBaseIterators(const BaseIterator& begin) - : it(begin) {} - - SBaseIterators(const BaseIterator& begin, const BaseIterator& end) - : it(begin) {} - - SBaseIterators(const SBaseIterators& other) - : it(other.it) {} - - SBaseIterators& operator =(const SBaseIterators& other) - { - it = other.it; - return *this; - } - - bool IsBegin(const BaseIterator&) const - { - return false; - } - - bool IsEnd(const BaseIterator&) const - { - return false; - } - - bool IsEqual(const SBaseIterators& other) const - { - return it == other.it; - } - - bool IsInRange(const BaseIterator&) const - { - return true; - } - }; - - // SIteratorSink: - // Helper to store the last code-point and error bit that was decoded. - // This is the safe specialization for potentially malformed sequences. - template - struct SIteratorSink - { - static const uint32 cEmpty = 0xFFFFFFFFU; - uint32 value; - bool error; - - void Clear() - { - value = cEmpty; - error = false; - } - - bool IsEmpty() const - { - return value == cEmpty; - } - - bool IsError() const - { - return error; - } - - const uint32& GetValue() const - { - return value; - } - - void MarkDecodingError() - { - value = cReplacementCharacter; - error = true; - } - - template - void Decode(const SBaseIterators& its, integral_constant) - { - typedef SDecoder DecoderType; - DecoderType decoder(*this, *this); - Clear(); - for (BaseIterator it = its.it; IsEmpty(); ++it) - { - uint32 val = static_cast(*it); - decoder(val); - if (its.IsEnd(it)) - { - break; - } - } - if (IsEmpty()) - { - // If we still have neither a new value or an error flag, just treat as error. - // This can happen if we reached the end of the sequence, but it ends in an incomplete code-sequence. - MarkDecodingError(); - } - } - - template - void DecodeIfEmpty(const SBaseIterators& its, integral_constant tag) - { - if (IsEmpty()) - { - Decode(its, tag); - } - } - - void operator()(uint32 unit) - { - value = unit; - } - - void operator()(SIteratorSink&, uint32, uint32) - { - MarkDecodingError(); - } - }; - - // SIteratorSink: - // Helper to store the last code-point that was decoded. - // This is the un-safe specialization for known-valid sequences. - // Note: No error-state is tracked since we won't handle that regardless for un-safe CIterator. - template<> - struct SIteratorSink - { - static const uint32 cEmpty = 0xFFFFFFFFU; - uint32 value; - - void Clear() - { - value = cEmpty; - } - - bool IsEmpty() const - { - return value == cEmpty; - } - - bool IsError() const - { - return false; - } - - const uint32& GetValue() const - { - return value; - } - - template - void Decode(const SBaseIterators& its, integral_constant) - { - typedef SDecoder DecoderType; - DecoderType decoder(*this); - for (BaseIterator it = its.it; IsEmpty(); ++it) - { - uint32 val = static_cast(*it); - decoder(val); - } - } - - template - void DecodeIfEmpty(const SBaseIterators& its, integral_constant tag) - { - if (IsEmpty()) - { - Decode(its, tag); - } - } - - void operator()(uint32 unit) - { - value = unit; - } - }; - } - - // CIterator: - // Helper class that can iterate over an encoded text sequence and read the underlying UCS code-points. - // If the Safe flag is set, bounds checking is performed inside multi-unit sequences to guard against decoding errors. - // This requires the user to know where the sequence ends (use the constructor taking two parameters). - // Note: The BaseIterator must be forward-iterator or better when Safe flag is set. - // If the Safe flag is not set, you must guarantee the sequence is validly encoded, and allows the use of the single argument constructor. - // In the case of unsafe iterator used for C-style string pointer, look for a U+0000 dereferenced value to end the iteration. - // Regardless of the Safe flag, the user must ensure that the iterator is never moved past the beginning or end of the range (just like any other STL iterator). - // Example of typical usage: - // string utf8 = "foo"; // UTF-8 - // for (Unicode::CIterator it(utf8.begin(), utf8.end()); it != utf8.end(); ++it) - // { - // uint32 codepoint = *it; // 32-bit UCS code-point - // } - // Example unsafe usage: (for known-valid encoded C-style strings): - // const char *pValid = "foo"; // UTF-8 - // for (Unicode::CIterator it = pValid; *it != 0; ++it) - // { - // uint32 codepoint = *it; // 32-bit UCS code-point - // } - template::value> - class CIterator - { - // The iterator value in the encoded sequence. - // Optionally provides bounds-checking. - Detail::SBaseIterators its; - - // The cached UCS code-point at the current position. - // Mutable because dereferencing is conceptually const, but does cache some state in this case. - mutable Detail::SIteratorSink sink; - - public: - // Types for compatibility with STL bidirectional iterator requirements. - typedef const uint32 value_type; - typedef const uint32& reference; - typedef const uint32* pointer; - typedef const ptrdiff_t difference_type; - typedef std::bidirectional_iterator_tag iterator_category; - - // Construct an iterator for the given range. - // The initial position of the iterator as at the beginning of the range. - CIterator(const BaseIterator& begin, const BaseIterator& end) - : its(begin, end) - { - sink.Clear(); - } - - // Construct an iterator from a single iterator (typically C-style string pointer). - // This can only be used for unsafe iterators. - template - CIterator(const IteratorType& it, typename Detail::SRequire::value, IteratorType>::type* = 0) - : its(static_cast(it)) - { - sink.Clear(); - } - - // Copy-construct an iterator. - CIterator(const CIterator& other) - : its(other.its) - , sink(other.sink) {} - - // Copy-assign an iterator. - CIterator& operator =(const CIterator& other) - { - its = other.its; - sink = other.sink; - return *this; - } - - // Test if the iterator points at an encoding error in the underlying encoded sequence. - // If so, the function returns false. - // When using an un-safe iterator, this function always returns true, if a sequence can contain encoding errors, you must use the safe variant. - // Note: This requires the underlying iterator to be dereferenced, so you cannot use it only while the iterator is inside the valid range. - bool IsAtValidCodepoint() const - { - assert(!its.IsEnd(its.it) && "Attempt to dereference the past-the-end iterator"); - Detail::integral_constant tag; - sink.DecodeIfEmpty(its, tag); - return !sink.IsError(); - } - - // Gets the current position in the underlying encoded sequence. - // If the iterator points to an invalidly encoded sequence (ie, IsError() returns true), the direction of iteration is significant. - // In that case the returned position is approximated; to work around this: move all iterators of which the position is compared in the same direction. - const BaseIterator& GetPosition() const - { - return its.it; - } - - // Sets the current position in the underlying encoded sequence. - // You may not set the position outside the range for which this iterator was constructed. - void SetPosition(const BaseIterator& it) - { - assert(its.IsInRange(it) && "Attempt to set the underlying iterator outside of the supported range"); - its.it = it; - } - - // Test if this iterator is equal to another iterator instance. - // Note: In the presence of an invalidly encoded sequence (ie, IsError() returns true), the direction of iteration is significant. - // To work around this, you can either: - // 1) Move all iterators that will be compared in the same direction; or - // 2) Compare the dereferenced iterator value(s) instead (if applicable). - bool operator ==(const CIterator& other) const - { - return its.IsEqual(other.its); - } - - // Test if this iterator is equal to another base iterator. - // Note: If the provided iterator does not point to the the first code-unit of an UCS code-point, the behavior is undefined. - bool operator ==(const BaseIterator& other) const - { - return its.it == other; - } - - // Test if this iterator is equal to another iterator instance. - // Note: In the presence of an invalidly encoded sequence (ie, IsError() returns true), the direction of iteration is significant. - // To work around this, you can either: - // 1) Move all iterators that will be compared in the same direction; or - // 2) Compare the dereferenced iterator value(s) instead (if applicable). - bool operator !=(const CIterator& other) const - { - return !its.IsEqual(other.its); - } - - // Test if this iterator is equal to another base iterator. - // Note: If the provided iterator does not point to the the first code-unit of an UCS code-point, the behavior is undefined. - bool operator !=(const BaseIterator& other) const - { - return its.it != other; - } - - // Get the decoded UCS code-point at the current position in the sequence. - // If the iterator points to an invalidly encoded sequence (ie, IsError() returns true) the function returns U+FFFD (replacement character). - reference operator *() const - { - assert(!its.IsEnd(its.it) && "Attempt to dereference the past-the-end iterator"); - Detail::integral_constant tag; - sink.DecodeIfEmpty(its, tag); - return sink.GetValue(); - } - - // Advance the iterator to the next UCS code-point. - // Note: You must make sure the iterator is not at the end of the sequence, even in Safe mode. - // However, in Safe mode, the iterator will never move past the end of the sequence in the presence of encoding errors. - CIterator& operator ++() - { - Detail::integral_constant tag; - Detail::MoveNext(its.it, its, tag); - sink.Clear(); - return *this; - } - - // Go back to the previous UCS code-point. - // Note: You must make sure the iterator is not at the beginning of the sequence, even in Safe mode. - // However, in Safe mode, the iterators will never move past the beginning of the sequence in the presence of encoding errors. - CIterator& operator --() - { - Detail::integral_constant tag; - Detail::MovePrev(its.it, its, tag); - sink.Clear(); - return *this; - } - - // Advance the iterator to the next UCS code-point, return a copy of the iterator position before advancing. - // Note: You must make sure the iterator is not at the end of the sequence, even in Safe mode. - // However, in Safe mode, the iterator will never move past the end of the sequence in the presence of encoding errors. - CIterator operator ++(int) - { - CIterator result = *this; - ++*this; - return result; - } - - // Go back to the previous UCS code-point, return a copy of the iterator position before going back. - // Note: You must make sure the iterator is not at the beginning of the sequence, even in Safe mode. - // However, in Safe mode, the iterators will never move past the beginning of the sequence in the presence of encoding errors. - CIterator operator --(int) - { - CIterator result = *this; - --*this; - return result; - } - }; - - namespace Detail - { - // SIteratorSpecializer: - // Specializes the CIterator template to use for a given string type. - // Note: The reason we use this is because MSVC doesn't want to deduce this on the MakeIterator declaration. - template - struct SIteratorSpecializer - { - typedef CIterator type; - }; - } - - // MakeIterator(const StringType &str): - // Helper function to make an UCS code-point iterator given an Unicode string. - // Example usage: - // string utf8 = "foo"; // UTF-8 - // auto it = Unicode::MakeIterator(utf8); - // while (it != utf8.end()) - // { - // uint32 codepoint = *it; // 32-bit UCS code-point - // } - // Or, in a for-loop: - // for (auto it = Unicode::MakeIterator(utf8); it != utf8.end(); ++it) {} - template - inline typename Detail::SIteratorSpecializer::type MakeIterator(const StringType& str) - { - return typename Detail::SIteratorSpecializer::type(str.begin(), str.end()); - } -} diff --git a/Code/Legacy/CryCommon/WinBase.cpp b/Code/Legacy/CryCommon/WinBase.cpp index 15146fbac1..d1b2d370a0 100644 --- a/Code/Legacy/CryCommon/WinBase.cpp +++ b/Code/Legacy/CryCommon/WinBase.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #ifdef APPLE #include @@ -77,8 +78,6 @@ unsigned int g_EnableMultipleAssert = 0;//set to something else than 0 if to ena #include #endif -#include "StringUtils.h" - #if AZ_TRAIT_COMPILER_DEFINE_FS_ERRNO_TYPE typedef int FS_ERRNO_TYPE; #if AZ_TRAIT_COMPILER_DEFINE_FS_STAT_TYPE @@ -349,23 +348,23 @@ void _makepath(char* path, const char* drive, const char* dir, const char* filen } if (dir && dir[0]) { - cry_strcat(tmp, dir); + azstrcat(tmp, MAX_PATH, dir); ch = tmp[strlen(tmp) - 1]; if (ch != '/' && ch != '\\') { - cry_strcat(tmp, "\\"); + azstrcat(tmp, MAX_PATH, "\\"); } } if (filename && filename[0]) { - cry_strcat(tmp, filename); + azstrcat(tmp, MAX_PATH, filename); if (ext && ext[0]) { if (ext[0] != '.') { - cry_strcat(tmp, "."); + azstrcat(tmp, MAX_PATH, "."); } - cry_strcat(tmp, ext); + azstrcat(tmp, MAX_PATH, ext); } } azstrcpy(path, strlen(tmp) + 1, tmp); @@ -486,12 +485,12 @@ void _splitpath(const char* inpath, char* drv, char* dir, char* fname, char* ext drv[0] = 0; } - typedef CryStackStringT path_stack_string; + typedef AZStd::fixed_string path_stack_string; const path_stack_string inPath(inpath); - string::size_type s = inPath.rfind('/', inPath.size());//position of last / + AZStd::string::size_type s = inPath.rfind('/', inPath.size());//position of last / path_stack_string fName; - if (s == string::npos) + if (s == AZStd::string::npos) { if (dir) { @@ -503,9 +502,9 @@ void _splitpath(const char* inpath, char* drv, char* dir, char* fname, char* ext { if (dir) { - azstrcpy(dir, AZ_MAX_PATH_LEN, (inPath.substr((string::size_type)0, (string::size_type)(s + 1))).c_str()); //assign directory + azstrcpy(dir, AZ_MAX_PATH_LEN, (inPath.substr((AZStd::string::size_type)0, (AZStd::string::size_type)(s + 1))).c_str()); //assign directory } - fName = inPath.substr((string::size_type)(s + 1)); //assign remaining string as rest + fName = inPath.substr((AZStd::string::size_type)(s + 1)); //assign remaining string as rest } if (fName.size() == 0) { @@ -521,8 +520,8 @@ void _splitpath(const char* inpath, char* drv, char* dir, char* fname, char* ext else { //dir and drive are now set - s = fName.find(".", (string::size_type)0);//position of first . - if (s == string::npos) + s = fName.find(".", (AZStd::string::size_type)0);//position of first . + if (s == AZStd::string::npos) { if (ext) { @@ -547,7 +546,7 @@ void _splitpath(const char* inpath, char* drv, char* dir, char* fname, char* ext } else { - azstrcpy(fname, AZ_MAX_PATH_LEN, (fName.substr((string::size_type)0, s)).c_str()); //assign filename + azstrcpy(fname, AZ_MAX_PATH_LEN, (fName.substr((AZStd::string::size_type)0, s)).c_str()); //assign filename } } } @@ -779,17 +778,17 @@ BOOL SystemTimeToFileTime(const SYSTEMTIME* syst, LPFILETIME ft) return TRUE; } -void adaptFilenameToLinux(string& rAdjustedFilename) +void adaptFilenameToLinux(AZStd::string& rAdjustedFilename) { //first replace all \\ by / - string::size_type loc = 0; - while ((loc = rAdjustedFilename.find("\\", loc)) != string::npos) + AZStd::string::size_type loc = 0; + while ((loc = rAdjustedFilename.find("\\", loc)) != AZStd::string::npos) { rAdjustedFilename.replace(loc, 1, "/"); } loc = 0; //remove /./ - while ((loc = rAdjustedFilename.find("/./", loc)) != string::npos) + while ((loc = rAdjustedFilename.find("/./", loc)) != AZStd::string::npos) { rAdjustedFilename.replace(loc, 3, "/"); } @@ -798,16 +797,16 @@ void adaptFilenameToLinux(string& rAdjustedFilename) void replaceDoublePathFilename(char* szFileName) { //replace "\.\" by "\" - string s(szFileName); - string::size_type loc = 0; + AZStd::string s(szFileName); + AZStd::string::size_type loc = 0; //remove /./ - while ((loc = s.find("/./", loc)) != string::npos) + while ((loc = s.find("/./", loc)) != AZStd::string::npos) { s.replace(loc, 3, "/"); } loc = 0; //remove "\.\" - while ((loc = s.find("\\.\\", loc)) != string::npos) + while ((loc = s.find("\\.\\", loc)) != AZStd::string::npos) { s.replace(loc, 3, "\\"); } @@ -817,8 +816,8 @@ void replaceDoublePathFilename(char* szFileName) const int comparePathNames(const char* cpFirst, const char* cpSecond, unsigned int len) { //create two strings and replace the \\ by / and /./ by / - string first(cpFirst); - string second(cpSecond); + AZStd::string first(cpFirst); + AZStd::string second(cpSecond); adaptFilenameToLinux(first); adaptFilenameToLinux(second); if (strlen(cpFirst) < len || strlen(cpSecond) < len) @@ -1599,14 +1598,16 @@ const bool GetFilenameNoCase return true; } -DWORD GetFileAttributes(LPCSTR lpFileName) +DWORD GetFileAttributes(LPCWSTR lpFileNameW) { + AZStd::string lpFileName; + AZStd::to_string(lpFileName, lpFileNameW); struct stat fileStats; - const int success = stat(lpFileName, &fileStats); + const int success = stat(lpFileName.c_str(), &fileStats); if (success == -1) { char adjustedFilename[MAX_PATH]; - GetFilenameNoCase(lpFileName, adjustedFilename); + GetFilenameNoCase(lpFileName.c_str(), adjustedFilename); if (stat(adjustedFilename, &fileStats) == -1) { return (DWORD)INVALID_FILE_ATTRIBUTES; @@ -1628,12 +1629,33 @@ DWORD GetFileAttributes(LPCSTR lpFileName) uint32 CryGetFileAttributes(const char* lpFileName) { - - string fn = lpFileName; + AZStd::string fn = lpFileName; adaptFilenameToLinux(fn); const char* buffer = fn.c_str(); - return GetFileAttributes(buffer); + struct stat fileStats; + const int success = stat(buffer, &fileStats); + if (success == -1) + { + char adjustedFilename[MAX_PATH]; + GetFilenameNoCase(buffer, adjustedFilename); + if (stat(adjustedFilename, &fileStats) == -1) + { + return (DWORD)INVALID_FILE_ATTRIBUTES; + } + } + DWORD ret = 0; + + const int acc = (fileStats.st_mode & S_IWRITE); + + if (acc != 0) + { + if (S_ISDIR(fileStats.st_mode) != 0) + { + ret |= FILE_ATTRIBUTE_DIRECTORY; + } + } + return (ret == 0) ? FILE_ATTRIBUTE_NORMAL : ret;//return file attribute normal as the default value, must only be set if no other attributes have been found } __finddata64_t::~__finddata64_t() diff --git a/Code/Legacy/CryCommon/crycommon_files.cmake b/Code/Legacy/CryCommon/crycommon_files.cmake index 0392f11c89..c78a6a4df0 100644 --- a/Code/Legacy/CryCommon/crycommon_files.cmake +++ b/Code/Legacy/CryCommon/crycommon_files.cmake @@ -78,7 +78,6 @@ set(FILES CryCrc32.h CryCustomTypes.h CryFile.h - CryFixedString.h CryHeaders.h CryHeaders_info.cpp CryListenerSet.h @@ -87,7 +86,6 @@ set(FILES CryPath.h CryPodArray.h CrySizer.h - CryString.h CrySystemBus.h CryThread.h CryThreadImpl.h @@ -111,7 +109,6 @@ set(FILES SimpleSerialize.h smartptr.h StlUtils.h - StringUtils.h Synchronization.h Tarray.h Timer.h @@ -119,10 +116,6 @@ set(FILES TimeValue_info.h TypeInfo_decl.h TypeInfo_impl.h - UnicodeBinding.h - UnicodeEncoding.h - UnicodeFunctions.h - UnicodeIterator.h VectorMap.h VectorSet.h VertexFormats.h diff --git a/Code/Legacy/CryCommon/platform.h b/Code/Legacy/CryCommon/platform.h index 6aad8dd043..12f732a729 100644 --- a/Code/Legacy/CryCommon/platform.h +++ b/Code/Legacy/CryCommon/platform.h @@ -176,7 +176,7 @@ // In Win32 Release we use static linkage #ifdef WIN32 - #if !defined(_RELEASE) || defined(RESOURCE_COMPILER) || defined(EDITOR) || defined(_FORCEDLL) + #if !defined(_RELEASE) || defined(EDITOR) || defined(_FORCEDLL) // All windows targets not in Release built as DLLs. #ifndef _USRDLL #define _USRDLL @@ -687,9 +687,6 @@ void SetFlags(T& dest, U flags, bool b) #include AZ_RESTRICTED_FILE(platform_h) #endif -// Platform wrappers must be included before CryString.h -# include "CryString.h" - // Include support for meta-type data. #include "TypeInfo_decl.h" @@ -699,12 +696,6 @@ void SetFlags(T& dest, U flags, bool b) bool CrySetFileAttributes(const char* lpFileName, uint32 dwFileAttributes); threadID CryGetCurrentThreadId(); -#if !defined(NOT_USE_CRY_STRING) -// Fixed-Sized (stack based string) -// put after the platform wrappers because of missing wcsicmp/wcsnicmp functions - #include "CryFixedString.h" -#endif - // need this in a common header file and any other file would be too misleading enum ETriState { diff --git a/Code/Legacy/CryCommon/platform_impl.cpp b/Code/Legacy/CryCommon/platform_impl.cpp index a677ba30b6..3d23d8783e 100644 --- a/Code/Legacy/CryCommon/platform_impl.cpp +++ b/Code/Legacy/CryCommon/platform_impl.cpp @@ -8,16 +8,16 @@ #include -#include #include #include -#include #include #include #include #include #include +#include +#include // Section dictionary #if defined(AZ_RESTRICTED_PLATFORM) @@ -241,28 +241,28 @@ void CryLowLatencySleep(unsigned int dwMilliseconds) int CryMessageBox([[maybe_unused]] const char* lpText, [[maybe_unused]] const char* lpCaption, [[maybe_unused]] unsigned int uType) { #ifdef WIN32 -#if !defined(RESOURCE_COMPILER) ICVar* const pCVar = gEnv && gEnv->pConsole ? gEnv->pConsole->GetCVar("sys_no_crash_dialog") : NULL; if ((pCVar && pCVar->GetIVal() != 0) || (gEnv && gEnv->bNoAssertDialog)) { return 0; } -#endif - wstring wideText, wideCaption; - Unicode::Convert(wideText, lpText); - Unicode::Convert(wideCaption, lpCaption); - return MessageBoxW(NULL, wideText.c_str(), wideCaption.c_str(), uType); + AZStd::wstring lpTextW; + AZStd::to_wstring(lpTextW, lpText); + AZStd::wstring lpCaptionW; + AZStd::to_wstring(lpCaptionW, lpCaption); + return MessageBoxW(NULL, lpTextW.c_str(), lpCaptionW.c_str(), uType); #else return 0; #endif } // Initializes root folder of the game, optionally returns exe and path name. -void InitRootDir(char szExeFileName[], uint nExeSize, char szExeRootName[], [[maybe_unused]] uint nRootSize) +void InitRootDir(char szExeFileName[], uint nExeSize, char szExeRootName[], uint nRootSize) { - WCHAR szPath[_MAX_PATH]; - size_t nLen = GetModuleFileNameW(GetModuleHandle(NULL), szPath, _MAX_PATH); - assert(nLen < _MAX_PATH && "The path to the current executable exceeds the expected length"); + char szPath[_MAX_PATH]; + AZ::Utils::GetExecutablePathReturnType ret = AZ::Utils::GetExecutablePath(szPath, _MAX_PATH); + AZ_Assert(ret.m_pathStored == AZ::Utils::ExecutablePathResult::Success, "The path to the current executable exceeds the expected length"); + const size_t nLen = strnlen(szPath, _MAX_PATH); // Find path above exe name and deepest folder. bool firstIteration = true; @@ -277,25 +277,27 @@ void InitRootDir(char szExeFileName[], uint nExeSize, char szExeRootName[], [[ma // Return exe path if (szExeRootName) { - Unicode::Convert(szExeRootName, n+1, szPath); + azstrncpy(szExeRootName, nRootSize, szPath + n + 1, nLen - n - 1); } // Return exe name if (szExeFileName) { - Unicode::Convert(szExeFileName, nExeSize, szPath + n); + azstrncpy(szExeFileName, nExeSize, szPath + n, nLen - n); } firstIteration = false; } // Check if the engineroot exists - wcscat_s(szPath, L"\\engine.json"); + azstrcat(szPath, AZ_ARRAY_SIZE(szPath), "\\engine.json"); WIN32_FILE_ATTRIBUTE_DATA data; - BOOL res = GetFileAttributesExW(szPath, GetFileExInfoStandard, &data); + wchar_t szPathW[_MAX_PATH]; + AZStd::to_wstring(szPathW, _MAX_PATH, szPath); + BOOL res = GetFileAttributesExW(szPathW, GetFileExInfoStandard, &data); if (res != 0 && data.dwFileAttributes != INVALID_FILE_ATTRIBUTES) { // Found file szPath[n] = 0; - SetCurrentDirectoryW(szPath); + SetCurrentDirectoryW(szPathW); break; } } @@ -429,7 +431,9 @@ uint32 CryGetFileAttributes(const char* lpFileName) #if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) #undef AZ_RESTRICTED_SECTION_IMPLEMENTED #else - res = GetFileAttributesEx(lpFileName, GetFileExInfoStandard, &data); + AZStd::wstring lpFileNameW; + AZStd::to_wstring(lpFileNameW, lpFileName); + res = GetFileAttributesExW(lpFileNameW.c_str(), GetFileExInfoStandard, &data); #endif return res ? data.dwFileAttributes : -1; } @@ -444,7 +448,9 @@ bool CrySetFileAttributes(const char* lpFileName, uint32 dwFileAttributes) #if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) #undef AZ_RESTRICTED_SECTION_IMPLEMENTED #else - return SetFileAttributes(lpFileName, dwFileAttributes) != 0; + AZStd::wstring lpFileNameW; + AZStd::to_wstring(lpFileNameW, lpFileName); + return SetFileAttributes(lpFileNameW.c_str(), dwFileAttributes) != 0; #endif } @@ -493,7 +499,7 @@ inline void CryDebugStr([[maybe_unused]] const char* format, ...) va_start(ArgList, format); azvsnprintf(szBuffer,sizeof(szBuffer)-1, format, ArgList); va_end(ArgList); - cry_strcat(szBuffer,"\n"); + azstrcat(szBuffer,"\n"); OutputDebugString(szBuffer); #endif */ diff --git a/Code/Legacy/CrySystem/CmdLine.cpp b/Code/Legacy/CrySystem/CmdLine.cpp index cb805b6990..50b8b2c092 100644 --- a/Code/Legacy/CrySystem/CmdLine.cpp +++ b/Code/Legacy/CrySystem/CmdLine.cpp @@ -11,7 +11,7 @@ #include "CmdLine.h" -void CCmdLine::PushCommand(const string& sCommand, const string& sParameter) +void CCmdLine::PushCommand(const AZStd::string& sCommand, const AZStd::string& sParameter) { if (sCommand.empty()) { @@ -47,7 +47,7 @@ CCmdLine::CCmdLine(const char* commandLine) char* src = (char*)commandLine; - string command, parameter; + AZStd::string command, parameter; for (;; ) { @@ -56,12 +56,12 @@ CCmdLine::CCmdLine(const char* commandLine) break; } - string arg = Next(src); + AZStd::string arg = Next(src); if (m_args.empty()) { // this is the filename, convert backslash to forward slash - arg.replace('\\', '/'); + AZ::StringFunc::Replace(arg, '\\', '/'); m_args.push_back(CCmdLineArg("filename", arg.c_str(), eCLAT_Executable)); } else @@ -90,7 +90,7 @@ CCmdLine::CCmdLine(const char* commandLine) } else { - parameter += string(" ") + arg; + parameter += AZStd::string(" ") + arg; } } } @@ -151,7 +151,7 @@ const ICmdLineArg* CCmdLine::FindArg(const ECmdLineArgType ArgType, const char* } -string CCmdLine::Next(char*& src) +AZStd::string CCmdLine::Next(char*& src) { char ch = 0; char* org = src; @@ -170,7 +170,7 @@ string CCmdLine::Next(char*& src) ; } - return string(org, src - 1); + return AZStd::string(org, src - 1); case '[': org = src; @@ -178,7 +178,7 @@ string CCmdLine::Next(char*& src) { ; } - return string(org, src - 1); + return AZStd::string(org, src - 1); case ' ': ch = *src++; @@ -190,12 +190,12 @@ string CCmdLine::Next(char*& src) ; } - return string(org, src); + return AZStd::string(org, src); } ch = *src++; } - return string(); + return AZStd::string(); } diff --git a/Code/Legacy/CrySystem/CmdLine.h b/Code/Legacy/CrySystem/CmdLine.h index 9ad7effebd..5e5c6466f1 100644 --- a/Code/Legacy/CrySystem/CmdLine.h +++ b/Code/Legacy/CrySystem/CmdLine.h @@ -29,13 +29,13 @@ public: virtual const ICmdLineArg* GetArg(int n) const; virtual int GetArgCount() const; virtual const ICmdLineArg* FindArg(const ECmdLineArgType ArgType, const char* name, bool caseSensitive = false) const; - virtual const char* GetCommandLine() const { return m_sCmdLine; }; + virtual const char* GetCommandLine() const { return m_sCmdLine.c_str(); }; private: - void PushCommand(const string& sCommand, const string& sParameter); - string Next(char*& str); + void PushCommand(const AZStd::string& sCommand, const AZStd::string& sParameter); + AZStd::string Next(char*& str); - string m_sCmdLine; + AZStd::string m_sCmdLine; std::vector m_args; }; diff --git a/Code/Legacy/CrySystem/CmdLineArg.h b/Code/Legacy/CrySystem/CmdLineArg.h index cc79981a72..5e3a629e7c 100644 --- a/Code/Legacy/CrySystem/CmdLineArg.h +++ b/Code/Legacy/CrySystem/CmdLineArg.h @@ -34,8 +34,8 @@ public: private: ECmdLineArgType m_type; - string m_name; - string m_value; + AZStd::string m_name; + AZStd::string m_value; }; #endif // CRYINCLUDE_CRYSYSTEM_CMDLINEARG_H diff --git a/Code/Legacy/CrySystem/ConsoleBatchFile.cpp b/Code/Legacy/CrySystem/ConsoleBatchFile.cpp index 69bbfc281d..3d46716873 100644 --- a/Code/Legacy/CrySystem/ConsoleBatchFile.cpp +++ b/Code/Legacy/CrySystem/ConsoleBatchFile.cpp @@ -57,7 +57,7 @@ bool CConsoleBatchFile::ExecuteConfigFile(const char* sFilename) Init(); } - string filename; + AZStd::string filename; if (sFilename[0] != '@') // console config files are actually by default in @root@ instead of @assets@ { @@ -78,7 +78,7 @@ bool CConsoleBatchFile::ExecuteConfigFile(const char* sFilename) filename = sFilename; } - if (strlen(PathUtil::GetExt(filename)) == 0) + if (strlen(PathUtil::GetExt(filename.c_str())) == 0) { filename = PathUtil::ReplaceExtension(filename, "cfg"); } @@ -88,20 +88,20 @@ bool CConsoleBatchFile::ExecuteConfigFile(const char* sFilename) { const char* szLog = "Executing console batch file (try game,config,root):"; - string filenameLog; - string sfn = PathUtil::GetFile(filename); + AZStd::string filenameLog; + AZStd::string sfn = PathUtil::GetFile(filename); - if (file.Open(filename, "rb", AZ::IO::IArchive::FOPEN_HINT_QUIET | AZ::IO::IArchive::FOPEN_ONDISK)) + if (file.Open(filename.c_str(), "rb", AZ::IO::IArchive::FOPEN_HINT_QUIET | AZ::IO::IArchive::FOPEN_ONDISK)) { - filenameLog = string("game/") + sfn; + filenameLog = AZStd::string("game/") + sfn; } - else if (file.Open(string("config/") + sfn, "rb", AZ::IO::IArchive::FOPEN_HINT_QUIET | AZ::IO::IArchive::FOPEN_ONDISK)) + else if (file.Open((AZStd::string("config/") + sfn).c_str(), "rb", AZ::IO::IArchive::FOPEN_HINT_QUIET | AZ::IO::IArchive::FOPEN_ONDISK)) { - filenameLog = string("game/config/") + sfn; + filenameLog = AZStd::string("game/config/") + sfn; } - else if (file.Open(string("./") + sfn, "rb", AZ::IO::IArchive::FOPEN_HINT_QUIET | AZ::IO::IArchive::FOPEN_ONDISK)) + else if (file.Open((AZStd::string("./") + sfn).c_str(), "rb", AZ::IO::IArchive::FOPEN_HINT_QUIET | AZ::IO::IArchive::FOPEN_ONDISK)) { - filenameLog = string("./") + sfn; + filenameLog = AZStd::string("./") + sfn; } else { @@ -142,11 +142,11 @@ bool CConsoleBatchFile::ExecuteConfigFile(const char* sFilename) str++; } - string strLine = s; + AZStd::string strLine = s; //trim all whitespace characters at the beginning and the end of the current line and store its size - strLine.Trim(); + AZ::StringFunc::TrimWhiteSpace(strLine, true, true); size_t strLineSize = strLine.size(); //skip comments, comments start with ";" or "--" but may have preceding whitespace characters @@ -168,7 +168,7 @@ bool CConsoleBatchFile::ExecuteConfigFile(const char* sFilename) } { - m_pConsole->ExecuteString(strLine); + m_pConsole->ExecuteString(strLine.c_str()); } } // See above diff --git a/Code/Legacy/CrySystem/ConsoleHelpGen.cpp b/Code/Legacy/CrySystem/ConsoleHelpGen.cpp index 0740e3a0f7..661487a299 100644 --- a/Code/Legacy/CrySystem/ConsoleHelpGen.cpp +++ b/Code/Legacy/CrySystem/ConsoleHelpGen.cpp @@ -6,20 +6,20 @@ * */ +#if defined(WIN32) || defined(WIN64) #include "CrySystem_precompiled.h" -#if defined(WIN32) || defined(WIN64) - #include "ConsoleHelpGen.h" #include "System.h" +#include // remove bad characters, toupper, not very fast -string CConsoleHelpGen::FixAnchorName(const char* szName) +AZStd::string CConsoleHelpGen::FixAnchorName(const char* szName) { - string ret; + AZStd::string ret; const char* p = szName; @@ -45,9 +45,9 @@ string CConsoleHelpGen::FixAnchorName(const char* szName) return ret; } -string CConsoleHelpGen::GetCleanPrefix(const char* p) +AZStd::string CConsoleHelpGen::GetCleanPrefix(const char* p) { - string sRet; + AZStd::string sRet; while (*p != '_' && *p != 0) { @@ -58,9 +58,9 @@ string CConsoleHelpGen::GetCleanPrefix(const char* p) } -string CConsoleHelpGen::SplitPrefixString_Part1(const char* p) +AZStd::string CConsoleHelpGen::SplitPrefixString_Part1(const char* p) { - string sRet; + AZStd::string sRet; while (*p != 10 && *p != 13 && *p != 0) { @@ -132,7 +132,7 @@ void CConsoleHelpGen::LogVersion(FILE* f) const char s[1024]; { - GetModuleFileName(NULL, s, sizeof(s)); + AZ::Utils::GetExecutablePath(s, 1024); char fdir[_MAX_PATH]; char fdrive[_MAX_PATH]; @@ -140,7 +140,7 @@ void CConsoleHelpGen::LogVersion(FILE* f) const char fext[_MAX_PATH]; _splitpath_s(s, fdrive, fdir, file, fext); - KeyValue(f, "Executable", (string(file) + fext).c_str()); + KeyValue(f, "Executable", (AZStd::string(file) + fext).c_str()); } { @@ -273,11 +273,11 @@ void CConsoleHelpGen::SingleLinePrefix(FILE* f, const char* szPrefix, const char } else if (m_eWorkMode == eWM_Confluence) { - string sPrefix; + AZStd::string sPrefix; if (*szPrefix) { - sPrefix = string(szPrefix) + "_"; + sPrefix = AZStd::string(szPrefix) + "_"; } // fprintf(f,"| %s | [%s|%s] |\n",sPrefix.c_str(),szPrefixDesc,szLink); // e.g. "" "CL_" "CC_" "I_" "T_" @@ -406,7 +406,7 @@ void CConsoleHelpGen::InsertConsoleCommands(std::setsecond; - if (_strnicmp(cmd.m_sName, szLocalPrefix, strlen(szLocalPrefix)) == 0) + if (_strnicmp(cmd.m_sName.c_str(), szLocalPrefix, strlen(szLocalPrefix)) == 0) { setCmdAndVars.insert(cmd.m_sName.c_str()); } @@ -415,7 +415,7 @@ void CConsoleHelpGen::InsertConsoleCommands(std::set& setCmdAndVars, std::map mapPrefix) const +void CConsoleHelpGen::InsertConsoleVars(std::set& setCmdAndVars, std::map mapPrefix) const { CXConsole::ConsoleVariablesMap::const_iterator itrVar, itrVarEnd = m_rParent.m_mapVariables.end(); @@ -425,11 +425,11 @@ void CConsoleHelpGen::InsertConsoleVars(std::set& bool bInsert = true; { - std::map::const_iterator it2, end = mapPrefix.end(); + std::map::const_iterator it2, end = mapPrefix.end(); for (it2 = mapPrefix.begin(); it2 != end; ++it2) { - if (it2->first != "___" && _strnicmp(var->GetName(), it2->first, it2->first.size()) == 0) + if (it2->first != "___" && _strnicmp(var->GetName(), it2->first.c_str(), it2->first.size()) == 0) { bInsert = false; break; @@ -446,7 +446,7 @@ void CConsoleHelpGen::InsertConsoleVars(std::set& -void CConsoleHelpGen::InsertConsoleCommands(std::set& setCmdAndVars, std::map mapPrefix) const +void CConsoleHelpGen::InsertConsoleCommands(std::set& setCmdAndVars, std::map mapPrefix) const { CXConsole::ConsoleCommandsMap::const_iterator itrCmd, itrCmdEnd = m_rParent.m_mapCommands.end(); @@ -456,11 +456,11 @@ void CConsoleHelpGen::InsertConsoleCommands(std::set::const_iterator it2, end = mapPrefix.end(); + std::map::const_iterator it2, end = mapPrefix.end(); for (it2 = mapPrefix.begin(); it2 != end; ++it2) { - if (it2->first != "___" && _strnicmp(cmd.m_sName, it2->first, it2->first.size()) == 0) + if (it2->first != "___" && _strnicmp(cmd.m_sName.c_str(), it2->first.c_str(), it2->first.size()) == 0) { bInsert = false; break; @@ -480,7 +480,7 @@ void CConsoleHelpGen::CreateSingleEntryFile(const char* szName) const assert(m_eWorkMode == eWM_Confluence); // only needed for confluence FILE* f3 = nullptr; - azfopen(&f3, (string(GetFolderName()) + GetFileExtension() + "/" + FixAnchorName(szName)).c_str(), "w"); + azfopen(&f3, (AZStd::string(GetFolderName()) + GetFileExtension() + "/" + FixAnchorName(szName)).c_str(), "w"); if (!f3) { @@ -582,7 +582,7 @@ void CConsoleHelpGen::IncludeSingleEntry(FILE* f, const char* szName) const { fprintf(f, "

\n");
 
-            string sHelp = szHelp;
+            AZStd::string sHelp = szHelp;
 
             // currently not required as the {noformat} is used
             //          sHelp.replace("[","\\[");       sHelp.replace("]","\\]");
@@ -604,7 +604,7 @@ void CConsoleHelpGen::IncludeSingleEntry(FILE* f, const char* szName) const
 
 void CConsoleHelpGen::Work()
 {
-    //  string sEngineFolder = string("@user@/")+GetFolderName();
+    //  AZStd::string sEngineFolder = AZStd::string("@user@/")+GetFolderName();
     //  gEnv->pCryPak->RemoveDir(sEngineFolder.c_str());            // todo: check if that works
     //  gEnv->pFileIO->CreatePath(sEngineFolder.c_str());
 
@@ -653,7 +653,7 @@ void CConsoleHelpGen::CreateMainPages()
 {
     gEnv->pFileIO->CreatePath(GetFolderName());
 
-    std::map mapPrefix;
+    std::map mapPrefix;
 
     // order here doesn't matter, after the name some help can be added (after the first return)
     mapPrefix[     "AI_"] = "Artificial Intelligence";
@@ -701,7 +701,7 @@ void CConsoleHelpGen::CreateMainPages()
     mapPrefix[     "___"] = "Remaining";            // key defined to get it sorted in the end
 
     FILE* f1 = nullptr;
-    azfopen(&f1, (string(GetFolderName()) + "/index" + GetFileExtension()).c_str(), "w");
+    azfopen(&f1, (AZStd::string(GetFolderName()) + "/index" + GetFileExtension()).c_str(), "w");
     if (!f1)
     {
         return;
@@ -729,17 +729,17 @@ void CConsoleHelpGen::CreateMainPages()
 
     // show all registered Prefix with one line
     {
-        std::map::const_iterator it, end = mapPrefix.end();
+        std::map::const_iterator it, end = mapPrefix.end();
 
         StartH3(f1, "Registered Prefixes");
 
         for (it = mapPrefix.begin(); it != end; ++it)
         {
             const char* szLocalPrefix = it->first.c_str();      // can be 0 for remaining ones
-            string sCleanPrefix = GetCleanPrefix(szLocalPrefix);
-            string sPrefixName = SplitPrefixString_Part1(it->second);
+            AZStd::string sCleanPrefix = GetCleanPrefix(szLocalPrefix);
+            AZStd::string sPrefixName = SplitPrefixString_Part1(it->second);
 
-            SingleLinePrefix(f1, sCleanPrefix.c_str(), sPrefixName.c_str(), (string("CONSOLEPREFIX") + FixAnchorName(sCleanPrefix.c_str()) + GetFileExtension()).c_str());
+            SingleLinePrefix(f1, sCleanPrefix.c_str(), sPrefixName.c_str(), (AZStd::string("CONSOLEPREFIX") + FixAnchorName(sCleanPrefix.c_str()) + GetFileExtension()).c_str());
             //          fprintf(f1,"   * [[CONSOLEPREFIX%s][%s_ %s]]\n",FixAnchorName(sCleanPrefix.c_str()).c_str(),sCleanPrefix.c_str(),sPrefixName.c_str());
         }
 
@@ -750,15 +750,15 @@ void CConsoleHelpGen::CreateMainPages()
 
 
     {
-        std::map::const_iterator it, it2, end = mapPrefix.end();
+        std::map::const_iterator it, it2, end = mapPrefix.end();
 
         StartH3(f1, "Console Commands and Variables Sorted by Prefix");
 
         for (it = mapPrefix.begin(); it != end; ++it)
         {
             const char* szLocalPrefix = it->first.c_str();      // can be 0 for remaining ones
-            string sCleanPrefix = GetCleanPrefix(szLocalPrefix);
-            string sPrefixName = SplitPrefixString_Part1(it->second);
+            AZStd::string sCleanPrefix = GetCleanPrefix(szLocalPrefix);
+            AZStd::string sPrefixName = SplitPrefixString_Part1(it->second);
 
             std::set setCmdAndVars;      // to get console variables and commands sorted together
 
@@ -777,11 +777,11 @@ void CConsoleHelpGen::CreateMainPages()
 
             // -------------------------------
 
-            string sSubName = string("CONSOLEPREFIX") + sCleanPrefix;
+            AZStd::string sSubName = AZStd::string("CONSOLEPREFIX") + sCleanPrefix;
 
             StartPrefix(f1, sCleanPrefix.c_str(), sPrefixName.c_str(), (sSubName + GetFileExtension()).c_str());
 
-            string sFileOut = string(GetFolderName()) + "/" + sSubName + GetFileExtension();
+            AZStd::string sFileOut = AZStd::string(GetFolderName()) + "/" + sSubName + GetFileExtension();
             FILE* f2 = nullptr;
             azfopen(&f2, sFileOut.c_str(), "w");
             if (!f2)
@@ -792,7 +792,7 @@ void CConsoleHelpGen::CreateMainPages()
 
             // headline
             {
-                string sHeadline;
+                AZStd::string sHeadline;
 
                 if (sCleanPrefix.empty())
                 {
@@ -800,7 +800,7 @@ void CConsoleHelpGen::CreateMainPages()
                 }
                 else
                 {
-                    sHeadline = string("Console Commands and Variables with Prefix ") + sCleanPrefix + "_";
+                    sHeadline = AZStd::string("Console Commands and Variables with Prefix ") + sCleanPrefix + "_";
                 }
 
                 StartH1(f2, sHeadline.c_str());
@@ -821,7 +821,7 @@ void CConsoleHelpGen::CreateMainPages()
                 for (itI = setCmdAndVars.begin(); itI != endI; ++itI)
                 {
                     SingleLineEntry_InGlobal(f1, *itI, (sSubName + GetFileExtension() + "#Anchor" + FixAnchorName(*itI)).c_str());
-                    SingleLineEntry_InGroup(f2, *itI, (string("#Anchor") + FixAnchorName(*itI)).c_str());
+                    SingleLineEntry_InGroup(f2, *itI, (AZStd::string("#Anchor") + FixAnchorName(*itI)).c_str());
                 }
 
                 EndH3(f2);
@@ -842,7 +842,7 @@ void CConsoleHelpGen::CreateMainPages()
                         }
                         bFirst = false;
 
-                        Anchor(f2, (string("Anchor") + FixAnchorName(*itI)).c_str());      // anchor
+                        Anchor(f2, (AZStd::string("Anchor") + FixAnchorName(*itI)).c_str());      // anchor
 
                         IncludeSingleEntry(f2, *itI);
                     }
diff --git a/Code/Legacy/CrySystem/ConsoleHelpGen.h b/Code/Legacy/CrySystem/ConsoleHelpGen.h
index 9ff797ca07..576232fe7a 100644
--- a/Code/Legacy/CrySystem/ConsoleHelpGen.h
+++ b/Code/Legacy/CrySystem/ConsoleHelpGen.h
@@ -59,19 +59,19 @@ private: // --------------------------------------------------------
     // insert if the name starts with the with prefix
     void InsertConsoleCommands(std::set& setCmdAndVars, const char* szPrefix) const;
     // insert if the name does not start with any of the prefix in the map
-    void InsertConsoleVars(std::set& setCmdAndVars, std::map mapPrefix) const;
+    void InsertConsoleVars(std::set& setCmdAndVars, std::map mapPrefix) const;
     // insert if the name does not start with any of the prefix in the map
-    void InsertConsoleCommands(std::set& setCmdAndVars, std::map mapPrefix) const;
+    void InsertConsoleCommands(std::set& setCmdAndVars, std::map mapPrefix) const;
 
     // a single file for the entry is generate
     void CreateSingleEntryFile(const char* szName) const;
 
     void IncludeSingleEntry(FILE* f, const char* szName) const;
 
-    static string FixAnchorName(const char* szName);
-    static string GetCleanPrefix(const char* p);
+    static AZStd::string FixAnchorName(const char* szName);
+    static AZStd::string GetCleanPrefix(const char* p);
     // split before "|" (to get the prefix itself)
-    static string SplitPrefixString_Part1(const char* p);
+    static AZStd::string SplitPrefixString_Part1(const char* p);
     // split string after "|" (to get the optional help)
     static const char* SplitPrefixString_Part2(const char* p);
 
diff --git a/Code/Legacy/CrySystem/DebugCallStack.cpp b/Code/Legacy/CrySystem/DebugCallStack.cpp
index 576c3ee9fb..ef27ef2c59 100644
--- a/Code/Legacy/CrySystem/DebugCallStack.cpp
+++ b/Code/Legacy/CrySystem/DebugCallStack.cpp
@@ -18,6 +18,7 @@
 
 #include 
 #include 
+#include 
 
 #define VS_VERSION_INFO                 1
 #define IDD_CRITICAL_ERROR              101
@@ -348,7 +349,7 @@ void DebugCallStack::ReportBug(const char* szErrorMessage)
     m_szBugMessage = NULL;
 }
 
-void DebugCallStack::dumpCallStack(std::vector& funcs)
+void DebugCallStack::dumpCallStack(std::vector& funcs)
 {
     WriteLineToLog("=============================================================================");
     int len = (int)funcs.size();
@@ -364,7 +365,7 @@ void DebugCallStack::dumpCallStack(std::vector& funcs)
 //////////////////////////////////////////////////////////////////////////
 void DebugCallStack::LogExceptionInfo(EXCEPTION_POINTERS* pex)
 {
-    string path("");
+    AZStd::string path("");
     if ((gEnv) && (gEnv->pFileIO))
     {
         const char* logAlias = gEnv->pFileIO->GetAlias("@log@");
@@ -379,12 +380,12 @@ void DebugCallStack::LogExceptionInfo(EXCEPTION_POINTERS* pex)
         }
     }
 
-    string fileName = path;
+    AZStd::string fileName = path;
     fileName += "error.log";
 
     struct stat fileInfo;
-    string timeStamp;
-    string backupPath;
+    AZStd::string timeStamp;
+    AZStd::string backupPath;
     if (gEnv->IsDedicated())
     {
         backupPath = PathUtil::ToUnixPath(PathUtil::AddSlash(path + "DumpBackups"));
@@ -399,8 +400,12 @@ void DebugCallStack::LogExceptionInfo(EXCEPTION_POINTERS* pex)
             strftime(tempBuffer, sizeof(tempBuffer), "%d %b %Y (%H %M %S)", &creationTime);
             timeStamp = tempBuffer;
 
-            string backupFileName = backupPath + timeStamp + " error.log";
-            CopyFile(fileName.c_str(), backupFileName.c_str(), true);
+            AZStd::string backupFileName = backupPath + timeStamp + " error.log";
+            AZStd::wstring fileNameW;
+            AZStd::to_wstring(fileNameW, fileName.c_str());
+            AZStd::wstring backupFileNameW;
+            AZStd::to_wstring(backupFileNameW, backupFileName.c_str());
+            CopyFileW(fileNameW.c_str(), backupFileNameW.c_str(), true);
         }
     }
 
@@ -414,8 +419,8 @@ void DebugCallStack::LogExceptionInfo(EXCEPTION_POINTERS* pex)
     char versionbuf[1024];
     azstrcpy(versionbuf, AZ_ARRAY_SIZE(versionbuf), "");
     PutVersion(versionbuf, AZ_ARRAY_SIZE(versionbuf));
-    cry_strcat(errorString, versionbuf);
-    cry_strcat(errorString, "\n");
+    azstrcat(errorString, AZ_ARRAY_SIZE(errorString), versionbuf);
+    azstrcat(errorString, AZ_ARRAY_SIZE(errorString), "\n");
 
     char excCode[MAX_WARNING_LENGTH];
     char excAddr[80];
@@ -430,18 +435,18 @@ void DebugCallStack::LogExceptionInfo(EXCEPTION_POINTERS* pex)
     {
         const char* const szMessage = m_bIsFatalError ? s_szFatalErrorCode : m_szBugMessage;
         excName = szMessage;
-        cry_strcpy(excCode, szMessage);
-        cry_strcpy(excAddr, "");
-        cry_strcpy(desc, "");
-        cry_strcpy(m_excModule, "");
-        cry_strcpy(excDesc, szMessage);
+        azstrcpy(excCode, AZ_ARRAY_SIZE(excCode), szMessage);
+        azstrcpy(excAddr, AZ_ARRAY_SIZE(excAddr), "");
+        azstrcpy(desc, AZ_ARRAY_SIZE(desc), "");
+        azstrcpy(m_excModule, AZ_ARRAY_SIZE(m_excModule), "");
+        azstrcpy(excDesc, AZ_ARRAY_SIZE(excDesc), szMessage);
     }
     else
     {
         sprintf_s(excAddr, "0x%04X:0x%p", pex->ContextRecord->SegCs, pex->ExceptionRecord->ExceptionAddress);
         sprintf_s(excCode, "0x%08X", pex->ExceptionRecord->ExceptionCode);
         excName = TranslateExceptionCode(pex->ExceptionRecord->ExceptionCode);
-        cry_strcpy(desc, "");
+        azstrcpy(desc, AZ_ARRAY_SIZE(desc), "");
         sprintf_s(excDesc, "%s\r\n%s", excName, desc);
 
 
@@ -471,9 +476,9 @@ void DebugCallStack::LogExceptionInfo(EXCEPTION_POINTERS* pex)
     WriteLineToLog("Exception Description: %s", desc);
 
 
-    cry_strcpy(m_excDesc, excDesc);
-    cry_strcpy(m_excAddr, excAddr);
-    cry_strcpy(m_excCode, excCode);
+    azstrcpy(m_excDesc, AZ_ARRAY_SIZE(m_excDesc), excDesc);
+    azstrcpy(m_excAddr, AZ_ARRAY_SIZE(m_excAddr), excAddr);
+    azstrcpy(m_excCode, AZ_ARRAY_SIZE(m_excCode), excCode);
 
 
     char errs[32768];
@@ -481,9 +486,9 @@ void DebugCallStack::LogExceptionInfo(EXCEPTION_POINTERS* pex)
         excCode, excAddr, m_excModule, excName, desc);
 
 
-    cry_strcat(errs, "\nCall Stack Trace:\n");
+    azstrcat(errs, AZ_ARRAY_SIZE(errs), "\nCall Stack Trace:\n");
 
-    std::vector funcs;
+    std::vector funcs;
     {
         AZ::Debug::StackFrame frames[25];
         AZ::Debug::SymbolStorage::StackLine lines[AZ_ARRAY_SIZE(frames)];
@@ -499,20 +504,20 @@ void DebugCallStack::LogExceptionInfo(EXCEPTION_POINTERS* pex)
         dumpCallStack(funcs);
         // Fill call stack.
         char str[s_iCallStackSize];
-        cry_strcpy(str, "");
+        azstrcpy(str, AZ_ARRAY_SIZE(str), "");
         for (unsigned int i = 0; i < funcs.size(); i++)
         {
             char temp[s_iCallStackSize];
             sprintf_s(temp, "%2zd) %s", funcs.size() - i, (const char*)funcs[i].c_str());
-            cry_strcat(str, temp);
-            cry_strcat(str, "\r\n");
-            cry_strcat(errs, temp);
-            cry_strcat(errs, "\n");
+            azstrcat(str, AZ_ARRAY_SIZE(str), temp);
+            azstrcat(str, AZ_ARRAY_SIZE(str), "\r\n");
+            azstrcat(errs, AZ_ARRAY_SIZE(errs), temp);
+            azstrcat(errs, AZ_ARRAY_SIZE(errs), "\n");
         }
-        cry_strcpy(m_excCallstack, str);
+        azstrcpy(m_excCallstack, AZ_ARRAY_SIZE(m_excCallstack), str);
     }
 
-    cry_strcat(errorString, errs);
+    azstrcat(errorString, AZ_ARRAY_SIZE(errorString), errs);
 
     if (f)
     {
@@ -593,8 +598,12 @@ void DebugCallStack::LogExceptionInfo(EXCEPTION_POINTERS* pex)
                     timeStamp = tempBuffer;
                 }
 
-                string backupFileName = backupPath + timeStamp + " error.dmp";
-                CopyFile(fileName.c_str(), backupFileName.c_str(), true);
+                AZStd::string backupFileName = backupPath + timeStamp + " error.dmp";
+                AZStd::wstring fileNameW;
+                AZStd::to_wstring(fileNameW, fileName.c_str());
+                AZStd::wstring backupFileNameW;
+                AZStd::to_wstring(backupFileNameW, backupFileName.c_str());
+                CopyFileW(fileNameW.c_str(), backupFileNameW.c_str(), true);
             }
 
             CryEngineExceptionFilterMiniDump(pex, fileName.c_str(), mdumpValue);
@@ -635,11 +644,11 @@ void DebugCallStack::LogExceptionInfo(EXCEPTION_POINTERS* pex)
         {
             if (SaveCurrentLevel())
             {
-                MessageBox(NULL, "Level has been successfully saved!\r\nPress Ok to terminate Editor.", "Save", MB_OK);
+                MessageBoxW(NULL, L"Level has been successfully saved!\r\nPress Ok to terminate Editor.", L"Save", MB_OK);
             }
             else
             {
-                MessageBox(NULL, "Error saving level.\r\nPress Ok to terminate Editor.", "Save", MB_OK | MB_ICONWARNING);
+                MessageBoxW(NULL, L"Error saving level.\r\nPress Ok to terminate Editor.", L"Save", MB_OK | MB_ICONWARNING);
             }
         }
     }
@@ -818,7 +827,7 @@ void DebugCallStack::ResetFPU(EXCEPTION_POINTERS* pex)
     }
 }
 
-string DebugCallStack::GetModuleNameForAddr(void* addr)
+AZStd::string DebugCallStack::GetModuleNameForAddr(void* addr)
 {
     if (m_modules.empty())
     {
@@ -844,7 +853,7 @@ string DebugCallStack::GetModuleNameForAddr(void* addr)
     return m_modules.rbegin()->second;
 }
 
-void DebugCallStack::GetProcNameForAddr(void* addr, string& procName, void*& baseAddr, string& filename, int& line)
+void DebugCallStack::GetProcNameForAddr(void* addr, AZStd::string& procName, void*& baseAddr, AZStd::string& filename, int& line)
 {
     AZ::Debug::SymbolStorage::StackLine func, file, module;
     AZ::Debug::SymbolStorage::FindFunctionFromIP(addr, &func, &file, &module, line, baseAddr);
@@ -852,10 +861,10 @@ void DebugCallStack::GetProcNameForAddr(void* addr, string& procName, void*& bas
     filename = file;
 }
 
-string DebugCallStack::GetCurrentFilename()
+AZStd::string DebugCallStack::GetCurrentFilename()
 {
     char fullpath[MAX_PATH_LENGTH + 1];
-    GetModuleFileName(NULL, fullpath, MAX_PATH_LENGTH);
+    AZ::Utils::GetExecutablePath(fullpath, MAX_PATH_LENGTH);
     return fullpath;
 }
 
diff --git a/Code/Legacy/CrySystem/DebugCallStack.h b/Code/Legacy/CrySystem/DebugCallStack.h
index f0c708a2b5..28f587011e 100644
--- a/Code/Legacy/CrySystem/DebugCallStack.h
+++ b/Code/Legacy/CrySystem/DebugCallStack.h
@@ -35,20 +35,20 @@ public:
 
     ISystem* GetSystem() { return m_pSystem; };
 
-    virtual string GetModuleNameForAddr(void* addr);
-    virtual void GetProcNameForAddr(void* addr, string& procName, void*& baseAddr, string& filename, int& line);
-    virtual string GetCurrentFilename();
+    virtual AZStd::string GetModuleNameForAddr(void* addr);
+    virtual void GetProcNameForAddr(void* addr, AZStd::string& procName, void*& baseAddr, AZStd::string& filename, int& line);
+    virtual AZStd::string GetCurrentFilename();
 
     void installErrorHandler(ISystem* pSystem);
     virtual int handleException(EXCEPTION_POINTERS* exception_pointer);
 
     virtual void ReportBug(const char*);
 
-    void dumpCallStack(std::vector& functions);
+    void dumpCallStack(std::vector& functions);
 
     void SetUserDialogEnable(const bool bUserDialogEnable);
 
-    typedef std::map TModules;
+    typedef std::map TModules;
 protected:
     static void RemoveOldFiles();
     static void RemoveFile(const char* szFileName);
diff --git a/Code/Legacy/CrySystem/IDebugCallStack.cpp b/Code/Legacy/CrySystem/IDebugCallStack.cpp
index 4ca481be88..1176c15f0e 100644
--- a/Code/Legacy/CrySystem/IDebugCallStack.cpp
+++ b/Code/Legacy/CrySystem/IDebugCallStack.cpp
@@ -187,7 +187,7 @@ AZ_PUSH_DISABLE_WARNING(4996, "-Wunknown-warning-option")
     azstrcat(str, length, "\n");
 
 #if AZ_LEGACY_CRYSYSTEM_TRAIT_DEBUGCALLSTACK_APPEND_MODULENAME
-    GetModuleFileNameA(NULL, s, sizeof(s));
+    AZ::Utils::GetExecutablePath(s, sizeof(s));
     
     // Log EXE filename only if possible (not full EXE path which could contain sensitive info)
     AZStd::string exeName;
@@ -237,7 +237,7 @@ void IDebugCallStack::WriteLineToLog(const char* format, ...)
     char        szBuffer[MAX_WARNING_LENGTH];
     va_start(ArgList, format);
     vsnprintf_s(szBuffer, sizeof(szBuffer), sizeof(szBuffer) - 1, format, ArgList);
-    cry_strcat(szBuffer, "\n");
+    azstrcat(szBuffer, MAX_WARNING_LENGTH, "\n");
     szBuffer[sizeof(szBuffer) - 1] = '\0';
     va_end(ArgList);
 
diff --git a/Code/Legacy/CrySystem/IDebugCallStack.h b/Code/Legacy/CrySystem/IDebugCallStack.h
index c05d0827b0..1a65fbbdb7 100644
--- a/Code/Legacy/CrySystem/IDebugCallStack.h
+++ b/Code/Legacy/CrySystem/IDebugCallStack.h
@@ -33,23 +33,19 @@ public:
     virtual int handleException([[maybe_unused]] EXCEPTION_POINTERS* exception_pointer){return 0; }
 
     // returns the module name of a given address
-    virtual string GetModuleNameForAddr([[maybe_unused]] void* addr) { return "[unknown]"; }
+    virtual AZStd::string GetModuleNameForAddr([[maybe_unused]] void* addr) { return "[unknown]"; }
 
     // returns the function name of a given address together with source file and line number (if available) of a given address
-    virtual void GetProcNameForAddr(void* addr, string& procName, void*& baseAddr, string& filename, int& line)
+    virtual void GetProcNameForAddr(void* addr, AZStd::string& procName, void*& baseAddr, AZStd::string& filename, int& line)
     {
         filename = "[unknown]";
         line = 0;
         baseAddr = addr;
-#if defined(PLATFORM_64BIT)
-        procName.Format("[%016llX]", addr);
-#else
-        procName.Format("[%08X]", addr);
-#endif
+        procName = AZStd::string::format("[%p]", addr);
     }
 
     // returns current filename
-    virtual string GetCurrentFilename()  { return "[unknown]"; }
+    virtual AZStd::string GetCurrentFilename()  { return "[unknown]"; }
 
     //! Dumps Current Call Stack to log.
     virtual void LogCallstack();
diff --git a/Code/Legacy/CrySystem/LevelSystem/LevelSystem.cpp b/Code/Legacy/CrySystem/LevelSystem/LevelSystem.cpp
index e2ddc324bb..d816fa4980 100644
--- a/Code/Legacy/CrySystem/LevelSystem/LevelSystem.cpp
+++ b/Code/Legacy/CrySystem/LevelSystem/LevelSystem.cpp
@@ -480,7 +480,7 @@ CLevelInfo* CLevelSystem::GetLevelInfoInternal(const AZStd::string& levelName)
     for (AZStd::vector::iterator it = m_levelInfos.begin(); it != m_levelInfos.end(); ++it)
     {
         {
-            if (!azstricmp(PathUtil::GetFileName(it->GetName()), levelName.c_str()))
+            if (!azstricmp(PathUtil::GetFileName(it->GetName()).c_str(), levelName.c_str()))
             {
                 return &(*it);
             }
@@ -567,7 +567,7 @@ ILevel* CLevelSystem::LoadLevelInternal(const char* _levelName)
     INDENT_LOG_DURING_SCOPE();
 
     char levelName[256];
-    cry_strcpy(levelName, _levelName);
+    azstrcpy(levelName, AZ_ARRAY_SIZE(levelName), _levelName);
 
     // Not remove a scope!!!
     {
diff --git a/Code/Legacy/CrySystem/LocalizedStringManager.cpp b/Code/Legacy/CrySystem/LocalizedStringManager.cpp
index 38f8ffc5b6..68a8a6659b 100644
--- a/Code/Legacy/CrySystem/LocalizedStringManager.cpp
+++ b/Code/Legacy/CrySystem/LocalizedStringManager.cpp
@@ -20,12 +20,12 @@
 #include "System.h" // to access InitLocalization()
 #include 
 #include 
-#include 
 #include 
 #include 
 
 #include 
 #include 
+#include 
 
 #define MAX_CELL_COUNT 32
 
@@ -146,9 +146,9 @@ static void ReloadDialogData([[maybe_unused]] IConsoleCmdArgs* pArgs)
 #if !defined(_RELEASE)
 static void TestFormatMessage ([[maybe_unused]] IConsoleCmdArgs* pArgs)
 {
-    string fmt1 ("abc %1 def % gh%2i %");
-    string fmt2 ("abc %[action:abc] %2 def % gh%1i %1");
-    string out1, out2;
+    AZStd::string fmt1 ("abc %1 def % gh%2i %");
+    AZStd::string fmt2 ("abc %[action:abc] %2 def % gh%1i %1");
+    AZStd::string out1, out2;
     LocalizationManagerRequestBus::Broadcast(&LocalizationManagerRequestBus::Events::FormatStringMessage, out1, fmt1, "first", "second", "third", nullptr);
     CryLogAlways("%s", out1.c_str());
     LocalizationManagerRequestBus::Broadcast(&LocalizationManagerRequestBus::Events::FormatStringMessage, out2, fmt2, "second", nullptr, nullptr, nullptr);
@@ -206,18 +206,18 @@ CLocalizedStringsManager::CLocalizedStringsManager(ISystem* pSystem)
 
     // Populate available languages by scanning the localization directory for paks
     // Default to US English if language is not supported
-    string sPath;
-    const string sLocalizationFolder(PathUtil::GetLocalizationFolder());
+    AZStd::string sPath;
+    const AZStd::string sLocalizationFolder(PathUtil::GetLocalizationFolder());
     ILocalizationManager::TLocalizationBitfield availableLanguages = 0;
     
     AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
     // test language name against supported languages
     for (int i = 0; i < ILocalizationManager::ePILID_MAX_OR_INVALID; i++)
     {
-        string sCurrentLanguage = LangNameFromPILID((ILocalizationManager::EPlatformIndependentLanguageID)i);  
+        AZStd::string sCurrentLanguage = LangNameFromPILID((ILocalizationManager::EPlatformIndependentLanguageID)i);
         sPath = sLocalizationFolder.c_str() + sCurrentLanguage;
-        sPath.MakeLower();
-        if (fileIO && fileIO->IsDirectory(sPath))
+        AZStd::to_lower(sPath.begin(), sPath.end());
+        if (fileIO && fileIO->IsDirectory(sPath.c_str()))
         {
             availableLanguages |= ILocalizationManager::LocalizationBitfieldFromPILID((ILocalizationManager::EPlatformIndependentLanguageID)i);
             if (m_cvarLocalizationDebug >= 2)
@@ -366,7 +366,7 @@ bool CLocalizedStringsManager::SetLanguage(const char* sLanguage)
     // Check if already language loaded.
     for (uint32 i = 0; i < m_languages.size(); i++)
     {
-        if (_stricmp(sLanguage, m_languages[i]->sLanguage) == 0)
+        if (_stricmp(sLanguage, m_languages[i]->sLanguage.c_str()) == 0)
         {
             InternalSetCurrentLanguage(m_languages[i]);
             return true;
@@ -441,9 +441,9 @@ void CLocalizedStringsManager::AddControl([[maybe_unused]] int nKey)
 }
 
 //////////////////////////////////////////////////////////////////////////
-void CLocalizedStringsManager::ParseFirstLine(IXmlTableReader* pXmlTableReader, char* nCellIndexToType, std::map& SoundMoodIndex, std::map& EventParameterIndex)
+void CLocalizedStringsManager::ParseFirstLine(IXmlTableReader* pXmlTableReader, char* nCellIndexToType, std::map& SoundMoodIndex, std::map& EventParameterIndex)
 {
-    string sCellContent;
+    AZStd::string sCellContent;
 
     for (;; )
     {
@@ -466,7 +466,7 @@ void CLocalizedStringsManager::ParseFirstLine(IXmlTableReader* pXmlTableReader,
         }
 
         sCellContent.assign(pContent, contentSize);
-        sCellContent.MakeLower();
+        AZStd::to_lower(sCellContent.begin(), sCellContent.end());
 
         for (int i = 0; i < sizeof(sLocalizedColumnNames) / sizeof(sLocalizedColumnNames[0]); ++i)
         {
@@ -528,15 +528,15 @@ static void CopyLowercase(char* dst, size_t dstSize, const char* src, size_t src
 }
 
 //////////////////////////////////////////////////////////////////////////
-static void ReplaceEndOfLine(CryFixedStringT& s)
+static void ReplaceEndOfLine(AZStd::fixed_string& s)
 {
-    const string oldSubstr("\\n");
-    const string newSubstr(" \n");
+    const AZStd::string oldSubstr("\\n");
+    const AZStd::string newSubstr(" \n");
     size_t pos = 0;
     for (;; )
     {
         pos = s.find(oldSubstr, pos);
-        if (pos == CryFixedStringT::npos)
+        if (pos == AZStd::fixed_string::npos)
         {
             return;
         }
@@ -565,7 +565,7 @@ void CLocalizedStringsManager::OnSystemEvent(
 
             for (TStringVec::iterator it = m_tagLoadRequests.begin(); it != m_tagLoadRequests.end(); ++it)
             {
-                LoadLocalizationDataByTag(*it);
+                LoadLocalizationDataByTag(it->c_str());
             }
         }
 
@@ -577,7 +577,7 @@ void CLocalizedStringsManager::OnSystemEvent(
         // Load all tags after the Editor has finished initialization.
         for (TTagFileNames::iterator it = m_tagFileNames.begin(); it != m_tagFileNames.end(); ++it)
         {
-            LoadLocalizationDataByTag(it->first);
+            LoadLocalizationDataByTag(it->first.c_str());
         }
 
         break;
@@ -600,7 +600,7 @@ bool CLocalizedStringsManager::InitLocalizationData(
     for (int i = 0; i < root->getChildCount(); i++)
     {
         XmlNodeRef typeNode = root->getChild(i);
-        string sType = typeNode->getTag();
+        AZStd::string sType = typeNode->getTag();
 
         // tags should be unique
         if (m_tagFileNames.find(sType) != m_tagFileNames.end())
@@ -678,9 +678,9 @@ bool CLocalizedStringsManager::LoadLocalizationDataByTag(
     for (TStringVec::iterator it2 = vEntries.begin(); it2 != vEntries.end(); ++it2)
     {
         //Only load files of the correct type for the configured format
-        if ((m_cvarLocalizationFormat == 0 && strstr(*it2, ".xml")) || (m_cvarLocalizationFormat == 1 && strstr(*it2, ".agsxml")))
+        if ((m_cvarLocalizationFormat == 0 && strstr(it2->c_str(), ".xml")) || (m_cvarLocalizationFormat == 1 && strstr(it2->c_str(), ".agsxml")))
         {
-            bResult &= (this->*loadFunction)(*it2, it->second.id, bReload);
+            bResult &= (this->*loadFunction)(it2->c_str(), it->second.id, bReload);
         }
     }
 
@@ -824,7 +824,7 @@ bool CLocalizedStringsManager::LoadAllLocalizationData(bool bReload)
 {
     for (TTagFileNames::iterator it = m_tagFileNames.begin(); it != m_tagFileNames.end(); ++it)
     {
-        if(!LoadLocalizationDataByTag(it->first, bReload))
+        if(!LoadLocalizationDataByTag(it->first.c_str(), bReload))
             return false;
     }
     return true;
@@ -837,6 +837,37 @@ bool CLocalizedStringsManager::LoadExcelXmlSpreadsheet(const char* sFileName, bo
     return (this->*loadFunction)(sFileName, 0, bReload);
 }
 
+enum class YesNoType
+{
+    Yes,
+    No,
+    Invalid
+};
+
+// parse the yes/no string
+/*!
+\param szString any of the following strings: yes, enable, true, 1, no, disable, false, 0
+\return YesNoType::Yes if szString is yes/enable/true/1, YesNoType::No if szString is no, disable, false, 0 and YesNoType::Invalid if the string is not one of the expected values.
+*/
+inline YesNoType ToYesNoType(const char* szString)
+{
+    if (!_stricmp(szString, "yes")
+        || !_stricmp(szString, "enable")
+        || !_stricmp(szString, "true")
+        || !_stricmp(szString, "1"))
+    {
+        return YesNoType::Yes;
+    }
+    if (!_stricmp(szString, "no")
+        || !_stricmp(szString, "disable")
+        || !_stricmp(szString, "false")
+        || !_stricmp(szString, "0"))
+    {
+        return YesNoType::No;
+    }
+    return YesNoType::Invalid;
+}
+
 //////////////////////////////////////////////////////////////////////
 // Loads a string-table from a Excel XML Spreadsheet file.
 bool CLocalizedStringsManager::DoLoadExcelXmlSpreadsheet(const char* sFileName, uint8 nTagID, bool bReload)
@@ -850,7 +881,7 @@ bool CLocalizedStringsManager::DoLoadExcelXmlSpreadsheet(const char* sFileName,
     //check if this table has already been loaded
     if (!bReload)
     {
-        if (m_loadedTables.find(CONST_TEMP_STRING(sFileName)) != m_loadedTables.end())
+        if (m_loadedTables.find(AZStd::string(sFileName)) != m_loadedTables.end())
         {
             return (true);
         }
@@ -866,12 +897,12 @@ bool CLocalizedStringsManager::DoLoadExcelXmlSpreadsheet(const char* sFileName,
     }
 
     XmlNodeRef root;
-    string sPath;
+    AZStd::string sPath;
     {
-        const string sLocalizationFolder(PathUtil::GetLocalizationRoot());
-        const string& languageFolder = m_pLanguage->sLanguage;
+        const AZStd::string sLocalizationFolder(PathUtil::GetLocalizationRoot());
+        const AZStd::string& languageFolder = m_pLanguage->sLanguage;
         sPath = sLocalizationFolder.c_str() + languageFolder + PathUtil::GetSlash() + sFileName;
-        root = m_pSystem->LoadXmlFromFile(sPath);
+        root = m_pSystem->LoadXmlFromFile(sPath.c_str());
         if (!root)
         {
             CryLog("Loading Localization File %s failed!", sPath.c_str());
@@ -948,14 +979,14 @@ bool CLocalizedStringsManager::DoLoadExcelXmlSpreadsheet(const char* sFileName,
     memset(nCellIndexToType, 0, sizeof(nCellIndexToType));
 
     // SoundMood Index
-    std::map SoundMoodIndex;
+    std::map SoundMoodIndex;
 
     // EventParameter Index
-    std::map EventParameterIndex;
+    std::map EventParameterIndex;
 
     bool bFirstRow = true;
 
-    CryFixedStringT sTmp;
+    AZStd::fixed_string sTmp;
 
     // lower case event name
     char szLowerCaseEvent[128];
@@ -1083,7 +1114,7 @@ bool CLocalizedStringsManager::DoLoadExcelXmlSpreadsheet(const char* sFileName,
                 break;
             case ELOCALIZED_COLUMN_USE_SUBTITLE:
                 sTmp.assign(cell.ptr, cell.count);
-                bUseSubtitle = CryStringUtils::ToYesNoType(sTmp.c_str()) == CryStringUtils::YesNoType::No ? false : true; // favor yes (yes and invalid -> yes)
+                bUseSubtitle = ToYesNoType(sTmp.c_str()) == YesNoType::No ? false : true; // favor yes (yes and invalid -> yes)
                 break;
             case ELOCALIZED_COLUMN_VOLUME:
                 sTmp.assign(cell.ptr, cell.count);
@@ -1121,7 +1152,7 @@ bool CLocalizedStringsManager::DoLoadExcelXmlSpreadsheet(const char* sFileName,
                 {
                     bIsIntercepted = true;
                 }
-                bIsDirectRadio = bIsIntercepted || (CryStringUtils::ToYesNoType(sTmp.c_str()) == CryStringUtils::YesNoType::Yes ? true : false); // favor no (no and invalid -> no)
+                bIsDirectRadio = bIsIntercepted || (ToYesNoType(sTmp.c_str()) == YesNoType::Yes ? true : false); // favor no (no and invalid -> no)
                 ++nItems;
                 break;
             // legacy names
@@ -1358,7 +1389,7 @@ bool CLocalizedStringsManager::DoLoadExcelXmlSpreadsheet(const char* sFileName,
             }
             else
             {
-                pEntry->TranslatedText.psUtf8Uncompressed = new string(sTmp.c_str(), sTmp.c_str() + sTmp.length());
+                pEntry->TranslatedText.psUtf8Uncompressed = new AZStd::string(sTmp.c_str(), sTmp.c_str() + sTmp.length());
             }
         }
 
@@ -1367,7 +1398,7 @@ bool CLocalizedStringsManager::DoLoadExcelXmlSpreadsheet(const char* sFileName,
         // the CryString makes sure, that only the ref-count is increment on assignment
         if (*szLowerCaseEvent)
         {
-            PrototypeSoundEvents::iterator it = m_prototypeEvents.find(CONST_TEMP_STRING(szLowerCaseEvent));
+            PrototypeSoundEvents::iterator it = m_prototypeEvents.find(AZStd::string(szLowerCaseEvent));
             if (it != m_prototypeEvents.end())
             {
                 pEntry->sPrototypeSoundEvent = *it;
@@ -1384,8 +1415,8 @@ bool CLocalizedStringsManager::DoLoadExcelXmlSpreadsheet(const char* sFileName,
         {
             sTmp.assign(sWho.ptr, sWho.count);
             ReplaceEndOfLine(sTmp);
-            sTmp.replace(" ", "_");
-            string tmp;
+            AZStd::replace(sTmp.begin(), sTmp.end(), ' ', '_');
+            AZStd::string tmp;
             {
                 tmp = sTmp.c_str();
             }
@@ -1531,19 +1562,19 @@ bool CLocalizedStringsManager::DoLoadAGSXmlDocument(const char* sFileName, uint8
     }
     if (!bReload)
     {
-        if (m_loadedTables.find(CONST_TEMP_STRING(sFileName)) != m_loadedTables.end())
+        if (m_loadedTables.find(AZStd::string(sFileName)) != m_loadedTables.end())
         {
             return true;
         }
     }
     ListAndClearProblemLabels();
     XmlNodeRef root;
-    string sPath;
+    AZStd::string sPath;
     {
-        const string sLocalizationFolder(PathUtil::GetLocalizationRoot());
-        const string& languageFolder = m_pLanguage->sLanguage;
+        const AZStd::string sLocalizationFolder(PathUtil::GetLocalizationRoot());
+        const AZStd::string& languageFolder = m_pLanguage->sLanguage;
         sPath = sLocalizationFolder.c_str() + languageFolder + PathUtil::GetSlash() + sFileName;
-        root = m_pSystem->LoadXmlFromFile(sPath);
+        root = m_pSystem->LoadXmlFromFile(sPath.c_str());
         if (!root)
         {
             AZ_TracePrintf(LOC_WINDOW, "Loading Localization File %s failed!", sPath.c_str());
@@ -1609,7 +1640,7 @@ bool CLocalizedStringsManager::DoLoadAGSXmlDocument(const char* sFileName, uint8
         {
             continue;
         }
-        AzFramework::StringFunc::Replace(textValue, "\\n", " \n");      // carried over from helper func ReplaceEndOfLine(CryFixedStringT<>& s)
+        AzFramework::StringFunc::Replace(textValue, "\\n", " \n");
         if (keyString[0] == '@')
         {
             AzFramework::StringFunc::LChop(keyString, 1);
@@ -1654,7 +1685,7 @@ bool CLocalizedStringsManager::DoLoadAGSXmlDocument(const char* sFileName, uint8
             }
             else
             {
-                pEntry->TranslatedText.psUtf8Uncompressed = new string(textString, textString + textLength);
+                pEntry->TranslatedText.psUtf8Uncompressed = new AZStd::string(textString, textString + textLength);
             }
         }
         {
@@ -1714,7 +1745,7 @@ void CLocalizedStringsManager::ReloadData()
     FreeLocalizationData();
     for (tmapFilenames::iterator it = temp.begin(); it != temp.end(); it++)
     {
-        (this->*loadFunction)((*it).first, (*it).second.nTagID, true);
+        (this->*loadFunction)((*it).first.c_str(), (*it).second.nTagID, true);
     }
 }
 
@@ -1732,19 +1763,19 @@ void CLocalizedStringsManager::AddLocalizedString(SLanguage* pLanguage, SLocaliz
 }
 
 //////////////////////////////////////////////////////////////////////////
-bool CLocalizedStringsManager::LocalizeString_ch(const char* sString, string& outLocalizedString, bool bEnglish)
+bool CLocalizedStringsManager::LocalizeString_ch(const char* sString, AZStd::string& outLocalizedString, bool bEnglish)
 {
     return LocalizeStringInternal(sString, strlen(sString), outLocalizedString, bEnglish);
 }
 
 //////////////////////////////////////////////////////////////////////////
-bool CLocalizedStringsManager::LocalizeString_s(const string& sString, string& outLocalizedString, bool bEnglish)
+bool CLocalizedStringsManager::LocalizeString_s(const AZStd::string& sString, AZStd::string& outLocalizedString, bool bEnglish)
 {
     return LocalizeStringInternal(sString.c_str(), sString.length(), outLocalizedString, bEnglish);
 }
 
 //////////////////////////////////////////////////////////////////////////
-bool CLocalizedStringsManager::LocalizeStringInternal(const char* pStr, size_t len, string& outLocalizedString, bool bEnglish)
+bool CLocalizedStringsManager::LocalizeStringInternal(const char* pStr, size_t len, AZStd::string& outLocalizedString, bool bEnglish)
 {
     assert (m_pLanguage);
     if (m_pLanguage == 0)
@@ -1755,7 +1786,7 @@ bool CLocalizedStringsManager::LocalizeStringInternal(const char* pStr, size_t l
     }
 
     // note: we don't write directly to outLocalizedString, in case it aliases pStr
-    string out;
+    AZStd::string out;
 
     // scan the string
     const char* pPos = pStr;
@@ -1783,8 +1814,8 @@ bool CLocalizedStringsManager::LocalizeStringInternal(const char* pStr, size_t l
         }
 
         // localize token
-        string token(pLabel, pLabelEnd);
-        string sLocalizedToken;
+        AZStd::string token(pLabel, pLabelEnd);
+        AZStd::string sLocalizedToken;
         if (bEnglish)
         {
             GetEnglishString(token.c_str(), sLocalizedToken);
@@ -1803,7 +1834,7 @@ bool CLocalizedStringsManager::LocalizeStringInternal(const char* pStr, size_t l
 
 void CLocalizedStringsManager::LocalizeAndSubstituteInternal(AZStd::string& locString, const AZStd::vector& keys, const AZStd::vector& values)
 {
-    string outString;
+    AZStd::string outString;
     LocalizeString_ch(locString.c_str(), outString);
     locString = outString .c_str();
     if (values.size() != keys.size())
@@ -1866,7 +1897,7 @@ static void LogDecompTimer(__int64 nTotalTicks, __int64 nDecompTicks, __int64 nA
 }
 #endif
 
-string CLocalizedStringsManager::SLocalizedStringEntry::GetTranslatedText(const SLanguage* pLanguage) const
+AZStd::string CLocalizedStringsManager::SLocalizedStringEntry::GetTranslatedText(const SLanguage* pLanguage) const
 {
     FUNCTION_PROFILER_FAST(GetISystem(), PROFILE_SYSTEM, g_bProfilerEnabled);
     if ((flags & IS_COMPRESSED) != 0)
@@ -1876,7 +1907,7 @@ string CLocalizedStringsManager::SLocalizedStringEntry::GetTranslatedText(const
         nTotalTicks = CryGetTicks();
 #endif  //LOG_DECOMP_TIMES
 
-        string outputString;
+        AZStd::string outputString;
         if (TranslatedText.szCompressed != NULL)
         {
             uint8 decompressionBuffer[COMPRESSION_FIXED_BUFFER_LENGTH];
@@ -1923,7 +1954,7 @@ string CLocalizedStringsManager::SLocalizedStringEntry::GetTranslatedText(const
         }
         else
         {
-            string emptyOutputString;
+            AZStd::string emptyOutputString;
             return emptyOutputString;
         }
     }
@@ -1949,7 +1980,7 @@ void CLocalizedStringsManager::ListAndClearProblemLabels()
         CryLog ("These labels caused localization problems:");
         INDENT_LOG_DURING_SCOPE();
 
-        for (std::map::iterator iter = m_warnedAboutLabels.begin(); iter != m_warnedAboutLabels.end(); iter++)
+        for (std::map::iterator iter = m_warnedAboutLabels.begin(); iter != m_warnedAboutLabels.end(); iter++)
         {
             CryLog ("%s", iter->first.c_str());
         }
@@ -1961,7 +1992,7 @@ void CLocalizedStringsManager::ListAndClearProblemLabels()
 #endif
 
 //////////////////////////////////////////////////////////////////////////
-bool CLocalizedStringsManager::LocalizeLabel(const char* sLabel, string& outLocalString, bool bEnglish)
+bool CLocalizedStringsManager::LocalizeLabel(const char* sLabel, AZStd::string& outLocalString, bool bEnglish)
 {
     assert(sLabel);
     if (!m_pLanguage || !sLabel)
@@ -1979,8 +2010,7 @@ bool CLocalizedStringsManager::LocalizeLabel(const char* sLabel, string& outLoca
 
             if (entry != NULL)
             {
-                
-                string translatedText = entry->GetTranslatedText(m_pLanguage);
+                AZStd::string translatedText = entry->GetTranslatedText(m_pLanguage);
                 if ((bEnglish || translatedText.empty()) && entry->pEditorExtension != NULL)
                 {
                     //assert(!"No Localization Text available!");
@@ -2011,7 +2041,7 @@ bool CLocalizedStringsManager::LocalizeLabel(const char* sLabel, string& outLoca
 
 
 //////////////////////////////////////////////////////////////////////////
-bool CLocalizedStringsManager::GetEnglishString(const char* sKey, string& sLocalizedString)
+bool CLocalizedStringsManager::GetEnglishString(const char* sKey, AZStd::string& sLocalizedString)
 {
     assert(sKey);
     if (!m_pLanguage || !sKey)
@@ -2086,7 +2116,7 @@ bool CLocalizedStringsManager::GetLocalizedInfoByKey(const char* sKey, SLocalize
         const SLocalizedStringEntry* entry = stl::find_in_map(m_pLanguage->m_keysMap, keyCRC32, NULL);
         if (entry != NULL)
         {
-            outGameInfo.szCharacterName = entry->sCharacterName;
+            outGameInfo.szCharacterName = entry->sCharacterName.c_str();
             outGameInfo.sUtf8TranslatedText = entry->GetTranslatedText(m_pLanguage);
 
             outGameInfo.bUseSubtitle = (entry->flags & SLocalizedStringEntry::USE_SUBTITLE);
@@ -2119,7 +2149,7 @@ bool CLocalizedStringsManager::GetLocalizedInfoByKey(const char* sKey, SLocalize
         {
             bResult = true;
 
-            pOutSoundInfo->szCharacterName = pEntry->sCharacterName;
+            pOutSoundInfo->szCharacterName = pEntry->sCharacterName.c_str();
             pOutSoundInfo->sUtf8TranslatedText = pEntry->GetTranslatedText(m_pLanguage);
 
             //pOutSoundInfo->sOriginalActorLine = pEntry->sOriginalActorLine.c_str();
@@ -2213,7 +2243,7 @@ bool CLocalizedStringsManager::GetLocalizedInfoByIndex(int nIndex, SLocalizedInf
     }
     const SLocalizedStringEntry* pEntry = entryVec[nIndex];
 
-    outGameInfo.szCharacterName = pEntry->sCharacterName;
+    outGameInfo.szCharacterName = pEntry->sCharacterName.c_str();
     outGameInfo.sUtf8TranslatedText = pEntry->GetTranslatedText(m_pLanguage);
 
     outGameInfo.bUseSubtitle = (pEntry->flags & SLocalizedStringEntry::USE_SUBTITLE);
@@ -2233,18 +2263,18 @@ bool CLocalizedStringsManager::GetLocalizedInfoByIndex(int nIndex, SLocalizedInf
         return false;
     }
     const SLocalizedStringEntry* pEntry = entryVec[nIndex];
-    outEditorInfo.szCharacterName = pEntry->sCharacterName;
+    outEditorInfo.szCharacterName = pEntry->sCharacterName.c_str();
     outEditorInfo.sUtf8TranslatedText = pEntry->GetTranslatedText(m_pLanguage);
 
     assert(pEntry->pEditorExtension != NULL);
 
-    outEditorInfo.sKey = pEntry->pEditorExtension->sKey;
+    outEditorInfo.sKey = pEntry->pEditorExtension->sKey.c_str();
 
-    outEditorInfo.sOriginalActorLine = pEntry->pEditorExtension->sOriginalActorLine;
-    outEditorInfo.sUtf8TranslatedActorLine = pEntry->pEditorExtension->sUtf8TranslatedActorLine;
+    outEditorInfo.sOriginalActorLine = pEntry->pEditorExtension->sOriginalActorLine.c_str();
+    outEditorInfo.sUtf8TranslatedActorLine = pEntry->pEditorExtension->sUtf8TranslatedActorLine.c_str();
 
     //outEditorInfo.sOriginalText = pEntry->sOriginalText;
-    outEditorInfo.sOriginalCharacterName = pEntry->pEditorExtension->sOriginalCharacterName;
+    outEditorInfo.sOriginalCharacterName = pEntry->pEditorExtension->sOriginalCharacterName.c_str();
 
     outEditorInfo.nRow = pEntry->pEditorExtension->nRow;
     outEditorInfo.bUseSubtitle = (pEntry->flags & SLocalizedStringEntry::USE_SUBTITLE);
@@ -2252,7 +2282,7 @@ bool CLocalizedStringsManager::GetLocalizedInfoByIndex(int nIndex, SLocalizedInf
 }
 
 //////////////////////////////////////////////////////////////////////////
-bool CLocalizedStringsManager::GetSubtitle(const char* sKeyOrLabel, string& outSubtitle, bool bForceSubtitle)
+bool CLocalizedStringsManager::GetSubtitle(const char* sKeyOrLabel, AZStd::string& outSubtitle, bool bForceSubtitle)
 {
     assert(sKeyOrLabel);
     if (!m_pLanguage || !sKeyOrLabel || !*sKeyOrLabel)
@@ -2300,21 +2330,20 @@ bool CLocalizedStringsManager::GetSubtitle(const char* sKeyOrLabel, string& outS
     }
 }
 
-template
-void InternalFormatStringMessage(StringClass& outString, const StringClass& sString, const CharType** sParams, int nParams)
+void InternalFormatStringMessage(AZStd::string& outString, const AZStd::string& sString, const char** sParams, int nParams)
 {
-    static const CharType token = (CharType) '%';
-    static const CharType tokens1[2] = { token, (CharType) '\0' };
-    static const CharType tokens2[3] = { token, token, (CharType) '\0' };
+    static const char token = '%';
+    static const char tokens1[2] = { token, '\0' };
+    static const char tokens2[3] = { token, token, '\0' };
 
     int maxArgUsed = 0;
-    int lastPos = 0;
-    int curPos = 0;
+    size_t lastPos = 0;
+    size_t curPos = 0;
     const int sourceLen = static_cast(sString.length());
     while (true)
     {
-        int foundPos = static_cast(sString.find(token, curPos));
-        if (foundPos != string::npos)
+        auto foundPos = sString.find(token, curPos);
+        if (foundPos != AZStd::string::npos)
         {
             if (foundPos + 1 < sourceLen)
             {
@@ -2331,8 +2360,8 @@ void InternalFormatStringMessage(StringClass& outString, const StringClass& sStr
                     }
                     else
                     {
-                        StringClass tmp (sString);
-                        tmp.replace(tokens1, tokens2);
+                        AZStd::string tmp(sString);
+                        AZ::StringFunc::Replace(tmp, tokens1, tokens2);
                         if constexpr (sizeof(*tmp.c_str()) == sizeof(char))
                         {
                             CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Parameter for argument %d is missing. [%s]", nArg + 1, (const char*)tmp.c_str());
@@ -2362,11 +2391,10 @@ void InternalFormatStringMessage(StringClass& outString, const StringClass& sStr
     }
 }
 
-template
-void InternalFormatStringMessage(StringClass& outString, const StringClass& sString, const CharType* param1, const CharType* param2 = 0, const CharType* param3 = 0, const CharType* param4 = 0)
+void InternalFormatStringMessage(AZStd::string& outString, const AZStd::string& sString, const char* param1, const char* param2 = 0, const char* param3 = 0, const char* param4 = 0)
 {
     static const int MAX_PARAMS = 4;
-    const CharType* params[MAX_PARAMS] = { param1, param2, param3, param4 };
+    const char* params[MAX_PARAMS] = { param1, param2, param3, param4 };
     int nParams = 0;
     while (nParams < MAX_PARAMS && params[nParams])
     {
@@ -2376,13 +2404,13 @@ void InternalFormatStringMessage(StringClass& outString, const StringClass& sStr
 }
 
 //////////////////////////////////////////////////////////////////////////
-void CLocalizedStringsManager::FormatStringMessage_List(string& outString, const string& sString, const char** sParams, int nParams)
+void CLocalizedStringsManager::FormatStringMessage_List(AZStd::string& outString, const AZStd::string& sString, const char** sParams, int nParams)
 {
     InternalFormatStringMessage(outString, sString, sParams, nParams);
 }
 
 //////////////////////////////////////////////////////////////////////////
-void CLocalizedStringsManager::FormatStringMessage(string& outString, const string& sString, const char* param1, const char* param2, const char* param3, const char* param4)
+void CLocalizedStringsManager::FormatStringMessage(AZStd::string& outString, const AZStd::string& sString, const char* param1, const char* param2, const char* param3, const char* param4)
 {
     InternalFormatStringMessage(outString, sString, param1, param2, param3, param4);
 }
@@ -2462,7 +2490,7 @@ void CLocalizedStringsManager::InternalSetCurrentLanguage(CLocalizedStringsManag
 #if defined (WIN32) || defined(WIN64)
     if (m_pLanguage != 0)
     {
-        g_currentLanguageID = GetLanguageID(m_pLanguage->sLanguage);
+        g_currentLanguageID = GetLanguageID(m_pLanguage->sLanguage.c_str());
     }
     else
     {
@@ -2494,7 +2522,7 @@ void CLocalizedStringsManager::InternalSetCurrentLanguage(CLocalizedStringsManag
     }
 }
 
-void CLocalizedStringsManager::LocalizeDuration(int seconds, string& outDurationString)
+void CLocalizedStringsManager::LocalizeDuration(int seconds, AZStd::string& outDurationString)
 {
     int s = seconds;
     int d, h, m;
@@ -2504,27 +2532,27 @@ void CLocalizedStringsManager::LocalizeDuration(int seconds, string& outDuration
     s -= h * 3600;
     m = s / 60;
     s = s - m * 60;
-    string str;
+    AZStd::string str;
     if (d > 1)
     {
-        str.Format("%d @ui_days %02d:%02d:%02d", d, h, m, s);
+        str = AZStd::string::format("%d @ui_days %02d:%02d:%02d", d, h, m, s);
     }
     else if (d > 0)
     {
-        str.Format("%d @ui_day %02d:%02d:%02d", d, h, m, s);
+        str = AZStd::string::format("%d @ui_day %02d:%02d:%02d", d, h, m, s);
     }
     else if (h > 0)
     {
-        str.Format("%02d:%02d:%02d", h, m, s);
+        str = AZStd::string::format("%02d:%02d:%02d", h, m, s);
     }
     else
     {
-        str.Format("%02d:%02d", m, s);
+        str = AZStd::string::format("%02d:%02d", m, s);
     }
     LocalizeString_s(str, outDurationString);
 }
 
-void CLocalizedStringsManager::LocalizeNumber(int number, string& outNumberString)
+void CLocalizedStringsManager::LocalizeNumber(int number, AZStd::string& outNumberString)
 {
     if (number == 0)
     {
@@ -2535,8 +2563,8 @@ void CLocalizedStringsManager::LocalizeNumber(int number, string& outNumberStrin
     outNumberString.assign("");
 
     int n = abs(number);
-    string separator;
-    CryFixedStringT<64> tmp;
+    AZStd::string separator;
+    AZStd::fixed_string<64> tmp;
     LocalizeString_ch("@ui_thousand_separator", separator);
     while (n > 0)
     {
@@ -2544,49 +2572,49 @@ void CLocalizedStringsManager::LocalizeNumber(int number, string& outNumberStrin
         int b = n - (a * 1000);
         if (a > 0)
         {
-            tmp.Format("%s%03d%s", separator.c_str(), b, tmp.c_str());
+            tmp = AZStd::string::format("%s%03d%s", separator.c_str(), b, tmp.c_str());
         }
         else
         {
-            tmp.Format("%d%s", b, tmp.c_str());
+            tmp = AZStd::string::format("%d%s", b, tmp.c_str());
         }
         n = a;
     }
 
     if (number < 0)
     {
-        tmp.Format("-%s", tmp.c_str());
+        tmp = AZStd::string::format("-%s", tmp.c_str());
     }
 
     outNumberString.assign(tmp.c_str());
 }
 
-void CLocalizedStringsManager::LocalizeNumber_Decimal(float number, int decimals, string& outNumberString)
+void CLocalizedStringsManager::LocalizeNumber_Decimal(float number, int decimals, AZStd::string& outNumberString)
 {
     if (number == 0.0f)
     {
-        CryFixedStringT<64> tmp;
-        tmp.Format("%.*f", decimals, number);
+        AZStd::fixed_string<64> tmp;
+        tmp = AZStd::fixed_string<64>::format("%.*f", decimals, number);
         outNumberString.assign(tmp.c_str());
         return;
     }
 
     outNumberString.assign("");
 
-    string commaSeparator;
+    AZStd::string commaSeparator;
     LocalizeString_ch("@ui_decimal_separator", commaSeparator);
     float f = number > 0.0f ? number : -number;
     int d = (int)f;
 
-    string intPart;
+    AZStd::string intPart;
     LocalizeNumber(d, intPart);
 
     float decimalsOnly = f - (float)d;
 
     int decimalsAsInt = aznumeric_cast(int_round(decimalsOnly * pow(10.0f, decimals)));
 
-    CryFixedStringT<64> tmp;
-    tmp.Format("%s%s%0*d", intPart.c_str(), commaSeparator.c_str(), decimals, decimalsAsInt);
+    AZStd::fixed_string<64> tmp;
+    tmp = AZStd::fixed_string<64>::format("%s%s%0*d", intPart.c_str(), commaSeparator.c_str(), decimals, decimalsAsInt);
 
     outNumberString.assign(tmp.c_str());
 }
@@ -2640,7 +2668,7 @@ namespace
     }
 };
 
-void CLocalizedStringsManager::LocalizeTime(time_t t, bool bMakeLocalTime, bool bShowSeconds, string& outTimeString)
+void CLocalizedStringsManager::LocalizeTime(time_t t, bool bMakeLocalTime, bool bShowSeconds, AZStd::string& outTimeString)
 {
     if (bMakeLocalTime)
     {
@@ -2648,7 +2676,7 @@ void CLocalizedStringsManager::LocalizeTime(time_t t, bool bMakeLocalTime, bool
         localtime_s(&thetime, &t);
         t = gEnv->pTimer->DateToSecondsUTC(thetime);
     }
-    outTimeString.resize(0);
+    outTimeString.clear();
     LCID lcID = g_currentLanguageID.lcID ? g_currentLanguageID.lcID : LOCALE_USER_DEFAULT;
     DWORD flags = bShowSeconds == false ? TIME_NOSECONDS : 0;
     SYSTEMTIME systemTime;
@@ -2657,14 +2685,14 @@ void CLocalizedStringsManager::LocalizeTime(time_t t, bool bMakeLocalTime, bool
     if (len > 0)
     {
         // len includes terminating null!
-        CryFixedWStringT<256> tmpString;
+        AZStd::fixed_wstring<256> tmpString;
         tmpString.resize(len);
         ::GetTimeFormatW(lcID, flags, &systemTime, 0, (wchar_t*) tmpString.c_str(), len);
-        Unicode::Convert(outTimeString, tmpString);
+        AZStd::to_string(outTimeString, tmpString.data());
     }
 }
 
-void CLocalizedStringsManager::LocalizeDate(time_t t, bool bMakeLocalTime, bool bShort, bool bIncludeWeekday, string& outDateString)
+void CLocalizedStringsManager::LocalizeDate(time_t t, bool bMakeLocalTime, bool bShort, bool bIncludeWeekday, AZStd::string& outDateString)
 {
     if (bMakeLocalTime)
     {
@@ -2678,7 +2706,7 @@ void CLocalizedStringsManager::LocalizeDate(time_t t, bool bMakeLocalTime, bool
     UnixTimeToSystemTime(t, &systemTime);
 
     // len includes terminating null!
-    CryFixedWStringT<256> tmpString;
+    AZStd::fixed_wstring<256> tmpString;
 
     if (bIncludeWeekday)
     {
@@ -2689,8 +2717,8 @@ void CLocalizedStringsManager::LocalizeDate(time_t t, bool bMakeLocalTime, bool
             // len includes terminating null!
             tmpString.resize(len);
             ::GetDateFormatW(lcID, 0, &systemTime, L"ddd", (wchar_t*) tmpString.c_str(), len);
-            string utf8;
-            Unicode::Convert(utf8, tmpString);
+            AZStd::string utf8;
+            AZStd::to_string(utf8, tmpString.data());
             outDateString.append(utf8);
             outDateString.append(" ");
         }
@@ -2702,15 +2730,15 @@ void CLocalizedStringsManager::LocalizeDate(time_t t, bool bMakeLocalTime, bool
         // len includes terminating null!
         tmpString.resize(len);
         ::GetDateFormatW(lcID, flags, &systemTime, 0, (wchar_t*) tmpString.c_str(), len);
-        string utf8;
-        Unicode::Convert(utf8, tmpString);
+        AZStd::string utf8;
+        AZStd::to_string(utf8, tmpString.data());
         outDateString.append(utf8);
     }
 }
 
 #else // #if defined (WIN32) || defined(WIN64)
 
-void CLocalizedStringsManager::LocalizeTime(time_t t, bool bMakeLocalTime, bool bShowSeconds, string& outTimeString)
+void CLocalizedStringsManager::LocalizeTime(time_t t, bool bMakeLocalTime, bool bShowSeconds, AZStd::string& outTimeString)
 {
     struct tm theTime;
     if (bMakeLocalTime)
@@ -2734,10 +2762,10 @@ void CLocalizedStringsManager::LocalizeTime(time_t t, bool bMakeLocalTime, bool
     const size_t bufSize = sizeof(buf) / sizeof(buf[0]);
     wcsftime(buf, bufSize, bShowSeconds ? L"%#X" : L"%X", &theTime);
     buf[bufSize - 1] = 0;
-    Unicode::Convert(outTimeString, buf);
+    AZStd::to_string(outTimeString, buf);
 }
 
-void CLocalizedStringsManager::LocalizeDate(time_t t, bool bMakeLocalTime, bool bShort, bool bIncludeWeekday, string& outDateString)
+void CLocalizedStringsManager::LocalizeDate(time_t t, bool bMakeLocalTime, bool bShort, bool bIncludeWeekday, AZStd::string& outDateString)
 {
     struct tm theTime;
     if (bMakeLocalTime)
@@ -2762,7 +2790,7 @@ void CLocalizedStringsManager::LocalizeDate(time_t t, bool bMakeLocalTime, bool
     const wchar_t* format = bShort ? (bIncludeWeekday ? L"%a %x" : L"%x") : L"%#x"; // long format always contains Weekday name
     wcsftime(buf, bufSize, format, &theTime);
     buf[bufSize - 1] = 0;
-    Unicode::Convert(outDateString, buf);
+    AZStd::to_string(outDateString, buf);
 }
 
 
diff --git a/Code/Legacy/CrySystem/LocalizedStringManager.h b/Code/Legacy/CrySystem/LocalizedStringManager.h
index 581a657c81..72a7916d1f 100644
--- a/Code/Legacy/CrySystem/LocalizedStringManager.h
+++ b/Code/Legacy/CrySystem/LocalizedStringManager.h
@@ -25,7 +25,7 @@ class CLocalizedStringsManager
     , public ISystemEventListener
 {
 public:
-    typedef std::vector TLocalizationTagVec;
+    typedef std::vector TLocalizationTagVec;
 
     constexpr const static size_t LOADING_FIXED_STRING_LENGTH = 2048;
     constexpr const static size_t COMPRESSION_FIXED_BUFFER_LENGTH = 6144;
@@ -56,11 +56,11 @@ public:
     void ReloadData() override;
     void FreeData();
 
-    bool LocalizeString_s(const string& sString, string& outLocalizedString, bool bEnglish = false) override;
-    bool LocalizeString_ch(const char* sString, string& outLocalizedString, bool bEnglish = false) override;
+    bool LocalizeString_s(const AZStd::string& sString, AZStd::string& outLocalizedString, bool bEnglish = false) override;
+    bool LocalizeString_ch(const char* sString, AZStd::string& outLocalizedString, bool bEnglish = false) override;
 
     void LocalizeAndSubstituteInternal(AZStd::string& locString, const AZStd::vector& keys, const AZStd::vector& values) override;
-    bool LocalizeLabel(const char* sLabel, string& outLocalizedString, bool bEnglish = false) override;
+    bool LocalizeLabel(const char* sLabel, AZStd::string& outLocalizedString, bool bEnglish = false) override;
     bool IsLocalizedInfoFound(const char* sKey);
     bool GetLocalizedInfoByKey(const char* sKey, SLocalizedInfoGame& outGameInfo);
     bool GetLocalizedInfoByKey(const char* sKey, SLocalizedSoundInfoGame* pOutSoundInfoGame);
@@ -68,17 +68,17 @@ public:
     bool GetLocalizedInfoByIndex(int nIndex, SLocalizedInfoGame& outGameInfo);
     bool GetLocalizedInfoByIndex(int nIndex, SLocalizedInfoEditor& outEditorInfo);
 
-    bool GetEnglishString(const char* sKey, string& sLocalizedString) override;
-    bool GetSubtitle(const char* sKeyOrLabel, string& outSubtitle, bool bForceSubtitle = false) override;
+    bool GetEnglishString(const char* sKey, AZStd::string& sLocalizedString) override;
+    bool GetSubtitle(const char* sKeyOrLabel, AZStd::string& outSubtitle, bool bForceSubtitle = false) override;
 
-    void FormatStringMessage_List(string& outString, const string& sString, const char** sParams, int nParams) override;
-    void FormatStringMessage(string& outString, const string& sString, const char* param1, const char* param2 = 0, const char* param3 = 0, const char* param4 = 0) override;
+    void FormatStringMessage_List(AZStd::string& outString, const AZStd::string& sString, const char** sParams, int nParams) override;
+    void FormatStringMessage(AZStd::string& outString, const AZStd::string& sString, const char* param1, const char* param2 = 0, const char* param3 = 0, const char* param4 = 0) override;
 
-    void LocalizeTime(time_t t, bool bMakeLocalTime, bool bShowSeconds, string& outTimeString) override;
-    void LocalizeDate(time_t t, bool bMakeLocalTime, bool bShort, bool bIncludeWeekday, string& outDateString) override;
-    void LocalizeDuration(int seconds, string& outDurationString) override;
-    void LocalizeNumber(int number, string& outNumberString) override;
-    void LocalizeNumber_Decimal(float number, int decimals, string& outNumberString) override;
+    void LocalizeTime(time_t t, bool bMakeLocalTime, bool bShowSeconds, AZStd::string& outTimeString) override;
+    void LocalizeDate(time_t t, bool bMakeLocalTime, bool bShort, bool bIncludeWeekday, AZStd::string& outDateString) override;
+    void LocalizeDuration(int seconds, AZStd::string& outDurationString) override;
+    void LocalizeNumber(int number, AZStd::string& outNumberString) override;
+    void LocalizeNumber_Decimal(float number, int decimals, AZStd::string& outNumberString) override;
 
     bool ProjectUsesLocalization() const override;
     // ~ILocalizationManager
@@ -95,7 +95,7 @@ public:
 private:
     void SetAvailableLocalizationsBitfield(const ILocalizationManager::TLocalizationBitfield availableLocalizations);
 
-    bool LocalizeStringInternal(const char* pStr, size_t len, string& outLocalizedString, bool bEnglish);
+    bool LocalizeStringInternal(const char* pStr, size_t len, AZStd::string& outLocalizedString, bool bEnglish);
 
     bool DoLoadExcelXmlSpreadsheet(const char* sFileName, uint8 tagID, bool bReload);
     typedef bool(CLocalizedStringsManager::*LoadFunc)(const char*, uint8, bool);
@@ -104,11 +104,11 @@ private:
 
     struct SLocalizedStringEntryEditorExtension
     {
-        string  sKey;                                           // Map key text equivalent (without @)
-        string  sOriginalActorLine;             // english text
-        string  sUtf8TranslatedActorLine;       // localized text
-        string  sOriginalText;                      // subtitle. if empty, uses English text
-        string  sOriginalCharacterName;     // english character name speaking via XML asset
+        AZStd::string  sKey;                                           // Map key text equivalent (without @)
+        AZStd::string  sOriginalActorLine;             // english text
+        AZStd::string  sUtf8TranslatedActorLine;       // localized text
+        AZStd::string  sOriginalText;                      // subtitle. if empty, uses English text
+        AZStd::string  sOriginalCharacterName;     // english character name speaking via XML asset
 
         unsigned int nRow;                              // Number of row in XML file
 
@@ -141,15 +141,15 @@ private:
 
         union trans_text
         {
-            string*     psUtf8Uncompressed;
+            AZStd::string*     psUtf8Uncompressed;
             uint8*      szCompressed;       // Note that no size information is stored. This is for struct size optimization and unfortunately renders the size info inaccurate.
         };
 
-        string sCharacterName;  // character name speaking via XML asset
+        AZStd::string sCharacterName;  // character name speaking via XML asset
         trans_text TranslatedText;  // Subtitle of this line
 
         // audio specific part
-        string      sPrototypeSoundEvent;           // associated sound event prototype (radio, ...)
+        AZStd::string      sPrototypeSoundEvent;           // associated sound event prototype (radio, ...)
         CryHalf     fVolume;
         CryHalf     fRadioRatio;
         // SoundMoods
@@ -191,7 +191,7 @@ private:
             }
         };
 
-        string GetTranslatedText(const SLanguage* pLanguage) const;
+        AZStd::string GetTranslatedText(const SLanguage* pLanguage) const;
 
         void GetMemoryUsage(ICrySizer* pSizer) const
         {
@@ -224,7 +224,7 @@ private:
         typedef std::vector TLocalizedStringEntries;
         typedef std::vector THuffmanCoders;
 
-        string sLanguage;
+        AZStd::string sLanguage;
         StringsKeyMap m_keysMap;
         TLocalizedStringEntries m_vLocalizedStrings;
         THuffmanCoders m_vEncoders;
@@ -246,7 +246,7 @@ private:
     };
 
 #ifndef _RELEASE
-    std::map m_warnedAboutLabels;
+    std::map m_warnedAboutLabels;
     bool m_haveWarnedAboutAtLeastOneLabel;
 
     void LocalizedStringsManagerWarning(const char* label, const char* message);
@@ -259,45 +259,45 @@ private:
     void AddLocalizedString(SLanguage* pLanguage, SLocalizedStringEntry* pEntry, const uint32 keyCRC32);
     void AddControl(int nKey);
     //////////////////////////////////////////////////////////////////////////
-    void ParseFirstLine(IXmlTableReader* pXmlTableReader, char* nCellIndexToType, std::map& SoundMoodIndex, std::map& EventParameterIndex);
+    void ParseFirstLine(IXmlTableReader* pXmlTableReader, char* nCellIndexToType, std::map& SoundMoodIndex, std::map& EventParameterIndex);
     void InternalSetCurrentLanguage(SLanguage* pLanguage);
     ISystem* m_pSystem;
     // Pointer to the current language.
     SLanguage* m_pLanguage;
 
     // all loaded Localization Files
-    typedef std::pair pairFileName;
-    typedef std::map tmapFilenames;
+    typedef std::pair pairFileName;
+    typedef std::map tmapFilenames;
     tmapFilenames m_loadedTables;
 
 
     // filenames per tag
-    typedef std::vector TStringVec;
+    typedef std::vector TStringVec;
     struct STag
     {
         TStringVec  filenames;
         uint8               id;
         bool                loaded;
     };
-    typedef std::map TTagFileNames;
+    typedef std::map TTagFileNames;
     TTagFileNames m_tagFileNames;
     TStringVec m_tagLoadRequests;
 
     // Array of loaded languages.
     std::vector m_languages;
 
-    typedef std::set PrototypeSoundEvents;
+    typedef std::set PrototypeSoundEvents;
     PrototypeSoundEvents m_prototypeEvents;  // this set is purely used for clever string/string assigning to save memory
 
     struct less_strcmp
     {
-        bool operator()(const string& left, const string& right) const
+        bool operator()(const AZStd::string& left, const AZStd::string& right) const
         {
             return strcmp(left.c_str(), right.c_str()) < 0;
         }
     };
 
-    typedef std::set CharacterNameSet;
+    typedef std::set CharacterNameSet;
     CharacterNameSet m_characterNameSet; // this set is purely used for clever string/string assigning to save memory
 
     // CVARs
diff --git a/Code/Legacy/CrySystem/Log.cpp b/Code/Legacy/CrySystem/Log.cpp
index 96bc29b58a..90c15588c3 100644
--- a/Code/Legacy/CrySystem/Log.cpp
+++ b/Code/Legacy/CrySystem/Log.cpp
@@ -18,7 +18,6 @@
 #include 
 #include "System.h"
 #include "CryPath.h"                    // PathUtil::ReplaceExtension()
-#include "UnicodeFunctions.h"
 
 #include 
 #include 
@@ -466,7 +465,7 @@ void CLog::LogV(const ELogType type, [[maybe_unused]]int flags, const char* szFo
     {
     case eWarning:
     case eWarningAlways:
-        cry_strcpy(szString, MAX_WARNING_LENGTH, "$6[Warning] ");
+        azstrcpy(szString, MAX_WARNING_LENGTH, "$6[Warning] ");
         szString += 12;     // strlen("$6[Warning] ");
         szAfterColour += 2;
         prefixSize = 12;
@@ -474,7 +473,7 @@ void CLog::LogV(const ELogType type, [[maybe_unused]]int flags, const char* szFo
 
     case eError:
     case eErrorAlways:
-        cry_strcpy(szString, MAX_WARNING_LENGTH, "$4[Error] ");
+        azstrcpy(szString, MAX_WARNING_LENGTH, "$4[Error] ");
         szString += 10;     // strlen("$4[Error] ");
         szAfterColour += 2;
         prefixSize = 10;
@@ -509,7 +508,7 @@ void CLog::LogV(const ELogType type, [[maybe_unused]]int flags, const char* szFo
             stack_string s = szBuffer;
             s += "\t ";
             s += sAssetScope;
-            cry_strcpy(szBuffer, s.c_str());
+            azstrcpy(szBuffer, AZ_ARRAY_SIZE(szBuffer), s.c_str());
         }
     }
 
@@ -532,7 +531,7 @@ void CLog::LogV(const ELogType type, [[maybe_unused]]int flags, const char* szFo
             }
         }
         i = m_iLastHistoryItem = m_iLastHistoryItem + 1 & sz - 1;
-        cry_strcpy(m_history[i].str, m_history[i].ptr = szSpamCheck);
+        azstrcpy(m_history[i].str, AZ_ARRAY_SIZE(m_history[i].str), m_history[i].ptr = szSpamCheck);
         m_history[i].type = type;
         m_history[i].time = time;
     }
@@ -863,7 +862,7 @@ bool CLog::LogToMainThread(const char* szString, ELogType logType, bool bAdd, SL
     {
         // When logging from other thread then main, push all log strings to queue.
         SLogMsg msg;
-        cry_strcpy(msg.msg, szString);
+        azstrcpy(msg.msg, AZ_ARRAY_SIZE(msg.msg), szString);
         msg.bAdd = bAdd;
         msg.destination = destination;
         msg.logType = logType;
@@ -956,7 +955,7 @@ void CLog::LogStringToFile(const char* szString, ELogType logType, bool bAdd, [[
             {
                 timeStr.clear();
                 uint32 dwMs = (uint32)((currenttime - lasttime).GetMilliSeconds());
-                timeStr.Format("<%3d.%.3d>: ", dwMs / 1000, dwMs % 1000);
+                timeStr = AZStd::string::format("<%3d.%.3d>: ", dwMs / 1000, dwMs % 1000);
                 tempString = timeStr + tempString;
             }
             lasttime = currenttime;
@@ -983,7 +982,7 @@ void CLog::LogStringToFile(const char* szString, ELogType logType, bool bAdd, [[
             {
                 timeStr.clear();
                 uint32 dwMs = (uint32)((currenttime - lasttime).GetMilliSeconds());
-                timeStr.Format("<%3d.%.3d>: ", dwMs / 1000, dwMs % 1000);
+                timeStr = AZStd::string::format("<%3d.%.3d>: ", dwMs / 1000, dwMs % 1000);
                 tempString = timeStr + tempString;
             }
             lasttime = currenttime;
@@ -1000,7 +999,7 @@ void CLog::LogStringToFile(const char* szString, ELogType logType, bool bAdd, [[
                 {
                     timeStr.clear();
                     uint32 dwMs = (uint32)((currenttime - lasttime).GetMilliSeconds());
-                    timeStr.Format("<%3d.%.3d>: ", dwMs / 1000, dwMs % 1000);
+                    timeStr = AZStd::string::format("<%3d.%.3d>: ", dwMs / 1000, dwMs % 1000);
                     tempString = timeStr + tempString;
                 }
                 if (bFirst)
@@ -1052,13 +1051,7 @@ void CLog::LogStringToFile(const char* szString, ELogType logType, bool bAdd, [[
 #if !defined(_RELEASE)
     if (queueState == MessageQueueState::NotQueued)
     {
-        // Note: OutputDebugString(A) only accepts current ANSI code-page, and the W variant will call the A variant internally.
-        // Here we replace non-ASCII characters with '?', which is the same as OutputDebugStringW will do for non-ANSI.
-        // Thus, we discard slightly more characters (ie, those inside the current ANSI code-page, but outside ASCII).
-        // In exchange, we save double-converting that would have happened otherwise (UTF-8 -> UTF-16 -> ANSI).
-        LogStringType asciiString;
-        Unicode::ConvertSafe(asciiString, tempString);
-        OutputDebugString(asciiString.c_str());
+        AZ::Debug::Platform::OutputToDebugger(nullptr, tempString.c_str());
     }
 
     if (!bIsMainThread)
@@ -1218,14 +1211,14 @@ void CLog::CreateBackupFile() const
 
     // boswej: only create a backup if logging to the engine root, otherwise the
     // log output has been overridden and the user is responsible
-    string logDir = PathUtil::RemoveSlash(PathUtil::ToUnixPath(PathUtil::GetParentDirectory(m_szFilename)));
+    AZStd::string logDir = PathUtil::RemoveSlash(PathUtil::ToUnixPath(PathUtil::GetParentDirectory(m_szFilename)));
 
-    string sExt = PathUtil::GetExt(m_szFilename);
-    string sFileWithoutExt = PathUtil::GetFileName(m_szFilename);
+    AZStd::string sExt = PathUtil::GetExt(m_szFilename);
+    AZStd::string sFileWithoutExt = PathUtil::GetFileName(m_szFilename);
 
     {
-        assert(::strstr(sFileWithoutExt, ":") == 0);
-        assert(::strstr(sFileWithoutExt, "\\") == 0);
+        assert(::strstr(sFileWithoutExt.c_str(), ":") == 0);
+        assert(::strstr(sFileWithoutExt.c_str(), "\\") == 0);
     }
 
     PathUtil::RemoveExtension(sFileWithoutExt);
@@ -1234,14 +1227,14 @@ void CLog::CreateBackupFile() const
     AZ::IO::HandleType inFileHandle = AZ::IO::InvalidHandle;
     fileSystem->Open(m_szFilename, AZ::IO::OpenMode::ModeRead | AZ::IO::OpenMode::ModeBinary, inFileHandle);
 
-    string sBackupNameAttachment;
+    AZStd::string sBackupNameAttachment;
 
     // parse backup name attachment
     // e.g. BackupNameAttachment="attachment name"
     if (inFileHandle != AZ::IO::InvalidHandle)
     {
         bool bKeyFound = false;
-        string sName;
+        AZStd::string sName;
 
         while (!fileSystem->Eof(inFileHandle))
         {
@@ -1253,13 +1246,11 @@ void CLog::CreateBackupFile() const
                 {
                     bKeyFound = true;
 
-                    if (sName.find("BackupNameAttachment=") == string::npos)
+                    if (sName.find("BackupNameAttachment=") == AZStd::string::npos)
                     {
-#ifdef WIN32
-                        OutputDebugString("Log::CreateBackupFile ERROR '");
-                        OutputDebugString(sName.c_str());
-                        OutputDebugString("' not recognized \n");
-#endif
+                        AZ::Debug::Platform::OutputToDebugger("CrySystem Log", "Log::CreateBackupFile ERROR '");
+                        AZ::Debug::Platform::OutputToDebugger(nullptr, sName.c_str());
+                        AZ::Debug::Platform::OutputToDebugger(nullptr, "' not recognized \n");
                         assert(0);      // broken log file? - first line should include this name - written by LogVersion()
                         return;
                     }
@@ -1284,12 +1275,12 @@ void CLog::CreateBackupFile() const
         fileSystem->Close(inFileHandle);
     }
 
-    string bakdest = PathUtil::Make(LOG_BACKUP_PATH, sFileWithoutExt + sBackupNameAttachment + "." + sExt);
+    AZStd::string bakdest = PathUtil::Make(LOG_BACKUP_PATH, sFileWithoutExt + sBackupNameAttachment + "." + sExt);
     fileSystem->CreatePath(LOG_BACKUP_PATH);
-    cry_strcpy(m_sBackupFilename, bakdest.c_str());
+    azstrcpy(m_sBackupFilename, AZ_ARRAY_SIZE(m_sBackupFilename), bakdest.c_str());
     // Remove any existing backup file with the same name first since the copy will fail otherwise.
     fileSystem->Remove(m_sBackupFilename);
-    fileSystem->Copy(m_szFilename, bakdest);
+    fileSystem->Copy(m_szFilename, bakdest.c_str());
 #endif // AZ_LEGACY_CRYSYSTEM_TRAIT_ALLOW_CREATE_BACKUP_LOG_FILE
 }
 
diff --git a/Code/Legacy/CrySystem/Log.h b/Code/Legacy/CrySystem/Log.h
index 5b1956b12f..3c0fa98037 100644
--- a/Code/Legacy/CrySystem/Log.h
+++ b/Code/Legacy/CrySystem/Log.h
@@ -37,7 +37,7 @@ class CLog
 {
 public:
     typedef std::list Callbacks;
-    typedef CryStackStringT LogStringType;
+    typedef AZStd::fixed_string LogStringType;
 
     // constructor
     CLog(ISystem* pSystem);
diff --git a/Code/Legacy/CrySystem/System.cpp b/Code/Legacy/CrySystem/System.cpp
index 7fa7f7d2b0..8c42c4a027 100644
--- a/Code/Legacy/CrySystem/System.cpp
+++ b/Code/Legacy/CrySystem/System.cpp
@@ -88,14 +88,7 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
     }
 
     // Handle with the default procedure
-#if defined(UNICODE) || defined(_UNICODE)
     assert(IsWindowUnicode(hWnd) && "Window should be Unicode when compiling with UNICODE");
-#else
-    if (!IsWindowUnicode(hWnd))
-    {
-        return DefWindowProcA(hWnd, uMsg, wParam, lParam);
-    }
-#endif
     return DefWindowProcW(hWnd, uMsg, wParam, lParam);
 }
 #endif
@@ -138,7 +131,6 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 #include "RemoteConsole/RemoteConsole.h"
 
 #include 
-#include 
 
 #include 
 #include 
@@ -1156,7 +1148,7 @@ void CSystem::WarningV(EValidatorModule module, EValidatorSeverity severity, int
     if (sModuleFilter && *sModuleFilter != 0)
     {
         const char* sModule = ValidatorModuleToString(module);
-        if (strlen(sModule) > 1 || CryStringUtils::stristr(sModule, sModuleFilter) == 0)
+        if (strlen(sModule) > 1 || AZ::StringFunc::Find(sModule, sModuleFilter) == AZStd::string::npos)
         {
             // Filter out warnings from other modules.
             return;
@@ -1190,7 +1182,7 @@ void CSystem::WarningV(EValidatorModule module, EValidatorSeverity severity, int
 
     if (file && *file)
     {
-        CryFixedStringT fmt = szBuffer;
+        AZStd::fixed_string fmt = szBuffer;
         fmt += " [File=";
         fmt += file;
         fmt += "]";
@@ -1209,10 +1201,11 @@ void CSystem::WarningV(EValidatorModule module, EValidatorSeverity severity, int
 }
 
 //////////////////////////////////////////////////////////////////////////
-void CSystem::GetLocalizedPath(const char* sLanguage, string& sLocalizedPath)
+void CSystem::GetLocalizedPath(const char* sLanguage, AZStd::string& sLocalizedPath)
 {
     // Omit the trailing slash!
-    string sLocalizationFolder(string().assign(PathUtil::GetLocalizationFolder(), 0, PathUtil::GetLocalizationFolder().size() - 1));
+    AZStd::string sLocalizationFolder(PathUtil::GetLocalizationFolder());
+    sLocalizationFolder.pop_back();
 
     int locFormat = 0;
     LocalizationManagerRequestBus::BroadcastResult(locFormat, &LocalizationManagerRequestBus::Events::GetLocalizationFormat);
@@ -1222,37 +1215,38 @@ void CSystem::GetLocalizedPath(const char* sLanguage, string& sLocalizedPath)
     }
     else
     {
-    if (sLocalizationFolder.compareNoCase("Languages") != 0)
-    {
-        sLocalizedPath = sLocalizationFolder + "/" + sLanguage + "_xml.pak";
-    }
-    else
-    {
-        sLocalizedPath = string("Localized/") + sLanguage + "_xml.pak";
+        if (AZ::StringFunc::Equal(sLocalizationFolder, "Languages", false))
+        {
+            sLocalizedPath = sLocalizationFolder + "/" + sLanguage + "_xml.pak";
+        }
+        else
+        {
+            sLocalizedPath = AZStd::string("Localized/") + sLanguage + "_xml.pak";
         }
     }
 }
 
 //////////////////////////////////////////////////////////////////////////
-void CSystem::GetLocalizedAudioPath(const char* sLanguage, string& sLocalizedPath)
+void CSystem::GetLocalizedAudioPath(const char* sLanguage, AZStd::string& sLocalizedPath)
 {
     // Omit the trailing slash!
-    string sLocalizationFolder(string().assign(PathUtil::GetLocalizationFolder(), 0, PathUtil::GetLocalizationFolder().size() - 1));
+    AZStd::string sLocalizationFolder(PathUtil::GetLocalizationFolder());
+    sLocalizationFolder.pop_back();
 
-    if (sLocalizationFolder.compareNoCase("Languages") != 0)
+    if (AZ::StringFunc::Equal(sLocalizationFolder, "Languages", false))
     {
         sLocalizedPath = sLocalizationFolder + "/" + sLanguage + ".pak";
     }
     else
     {
-        sLocalizedPath = string("Localized/") + sLanguage + ".pak";
+        sLocalizedPath = AZStd::string("Localized/") + sLanguage + ".pak";
     }
 }
 
 //////////////////////////////////////////////////////////////////////////
 void CSystem::CloseLanguagePak(const char* sLanguage)
 {
-    string sLocalizedPath;
+    AZStd::string sLocalizedPath;
     GetLocalizedPath(sLanguage, sLocalizedPath);
     m_env.pCryPak->ClosePacks({ sLocalizedPath.c_str(), sLocalizedPath.size() });
 }
@@ -1260,7 +1254,7 @@ void CSystem::CloseLanguagePak(const char* sLanguage)
 //////////////////////////////////////////////////////////////////////////
 void CSystem::CloseLanguageAudioPak(const char* sLanguage)
 {
-    string sLocalizedPath;
+    AZStd::string sLocalizedPath;
     GetLocalizedAudioPath(sLanguage, sLocalizedPath);
     m_env.pCryPak->ClosePacks({ sLocalizedPath.c_str(), sLocalizedPath.size() });
 }
@@ -1334,11 +1328,11 @@ void CSystem::ExecuteCommandLine(bool deferred)
 
         if (pCmd->GetType() == eCLAT_Post)
         {
-            string sLine = pCmd->GetName();
+            AZStd::string sLine = pCmd->GetName();
             {
                 if (pCmd->GetValue())
                 {
-                    sLine += string(" ") + pCmd->GetValue();
+                    sLine += AZStd::string(" ") + pCmd->GetValue();
                 }
 
                 GetILog()->Log("Executing command from command line: \n%s\n", sLine.c_str()); // - the actual command might be executed much later (e.g. level load pause)
diff --git a/Code/Legacy/CrySystem/System.h b/Code/Legacy/CrySystem/System.h
index db20dd8f1b..952de817e7 100644
--- a/Code/Legacy/CrySystem/System.h
+++ b/Code/Legacy/CrySystem/System.h
@@ -450,7 +450,7 @@ private:
     bool ReLaunchMediaCenter();
     void UpdateAudioSystems();
 
-    void AddCVarGroupDirectory(const string& sPath);
+    void AddCVarGroupDirectory(const AZStd::string& sPath);
 
     AZStd::unique_ptr LoadDynamiclibrary(const char* dllName) const;
 
@@ -619,7 +619,7 @@ private: // ------------------------------------------------------
     //  ICVar *m_sys_filecache;
     ICVar* m_gpu_particle_physics;
 
-    string  m_sSavedRDriver;                                //!< to restore the driver when quitting the dedicated server
+    AZStd::string  m_sSavedRDriver;                                //!< to restore the driver when quitting the dedicated server
 
     //////////////////////////////////////////////////////////////////////////
     //! User define callback for system events.
@@ -668,8 +668,8 @@ public:
     void OpenBasicPaks();
     void OpenLanguagePak(const char* sLanguage);
     void OpenLanguageAudioPak(const char* sLanguage);
-    void GetLocalizedPath(const char* sLanguage, string& sLocalizedPath);
-    void GetLocalizedAudioPath(const char* sLanguage, string& sLocalizedPath);
+    void GetLocalizedPath(const char* sLanguage, AZStd::string& sLocalizedPath);
+    void GetLocalizedAudioPath(const char* sLanguage, AZStd::string& sLocalizedPath);
     void CloseLanguagePak(const char* sLanguage);
     void CloseLanguageAudioPak(const char* sLanguage);
     void UpdateMovieSystem(const int updateFlags, const float fFrameTime, const bool bPreUpdate);
@@ -714,14 +714,14 @@ protected: // -------------------------------------------------------------
 
     CCmdLine*                                      m_pCmdLine;
 
-    string  m_currentLanguageAudio;
-    string  m_systemConfigName; // computed from system_(hardwareplatform)_(assetsPlatform) - eg, system_android_android.cfg or system_windows_pc.cfg
+    AZStd::string  m_currentLanguageAudio;
+    AZStd::string  m_systemConfigName; // computed from system_(hardwareplatform)_(assetsPlatform) - eg, system_android_android.cfg or system_windows_pc.cfg
 
     std::vector< std::pair > m_updateTimes;
 
     struct SErrorMessage
     {
-        string m_Message;
+        AZStd::string m_Message;
         float m_fTimeToShow;
         float m_Color[4];
         bool m_HardFailure;
diff --git a/Code/Legacy/CrySystem/SystemCFG.cpp b/Code/Legacy/CrySystem/SystemCFG.cpp
index 4ab203ded1..57de0be909 100644
--- a/Code/Legacy/CrySystem/SystemCFG.cpp
+++ b/Code/Legacy/CrySystem/SystemCFG.cpp
@@ -114,20 +114,22 @@ void CSystem::QueryVersionInfo()
 
     char ver[1024 * 8];
 
-    GetModuleFileName(NULL, moduleName, _MAX_PATH);  //retrieves the PATH for the current module
+    AZ::Utils::GetExecutablePath(moduleName, _MAX_PATH);  //retrieves the PATH for the current module
 
 #ifdef AZ_MONOLITHIC_BUILD
-    GetModuleFileName(NULL, moduleName, _MAX_PATH);  //retrieves the PATH for the current module
+    AZ::Utils::GetExecutablePath(moduleName, _MAX_PATH);  //retrieves the PATH for the current module
 #else // AZ_MONOLITHIC_BUILD
     azstrcpy(moduleName, AZ_ARRAY_SIZE(moduleName), "CrySystem.dll"); // we want to version from the system dll
 #endif // AZ_MONOLITHIC_BUILD
 
-    int verSize = GetFileVersionInfoSize(moduleName, &dwHandle);
+    AZStd::wstring moduleNameW;
+    AZStd::to_wstring(moduleNameW, moduleName);
+    int verSize = GetFileVersionInfoSizeW(moduleNameW.c_str(), &dwHandle);
     if (verSize > 0)
     {
-        GetFileVersionInfo(moduleName, dwHandle, 1024 * 8, ver);
+        GetFileVersionInfoW(moduleNameW.c_str(), dwHandle, 1024 * 8, ver);
         VS_FIXEDFILEINFO* vinfo;
-        VerQueryValue(ver, "\\", (void**)&vinfo, &len);
+        VerQueryValueW(ver, L"\\", (void**)&vinfo, &len);
 
         const uint32 verIndices[4] = {0, 1, 2, 3};
         m_fileVersion.v[verIndices[0]] = m_productVersion.v[verIndices[0]] = vinfo->dwFileVersionLS & 0xFFFF;
@@ -143,14 +145,14 @@ void CSystem::QueryVersionInfo()
         }* lpTranslate;
 
         UINT count = 0;
-        char path[256];
+        wchar_t path[256];
         char* version = NULL;
 
-        VerQueryValue(ver, "\\VarFileInfo\\Translation", (LPVOID*)&lpTranslate, &count);
+        VerQueryValueW(ver, L"\\VarFileInfo\\Translation", (LPVOID*)&lpTranslate, &count);
         if (lpTranslate != NULL)
         {
-            azsnprintf(path, sizeof(path), "\\StringFileInfo\\%04x%04x\\InternalName", lpTranslate[0].wLanguage, lpTranslate[0].wCodePage);
-            VerQueryValue(ver, path, (LPVOID*)&version, &count);
+            azsnwprintf(path, sizeof(path), L"\\StringFileInfo\\%04x%04x\\InternalName", lpTranslate[0].wLanguage, lpTranslate[0].wCodePage);
+            VerQueryValueW(ver, path, (LPVOID*)&version, &count);
             if (version)
             {
                 m_buildVersion.Set(version);
@@ -211,7 +213,7 @@ void CSystem::LogVersion()
     CryLogAlways("Running 64 bit Mac version");
 #endif
 #if AZ_LEGACY_CRYSYSTEM_TRAIT_SYSTEMCFG_MODULENAME
-    GetModuleFileName(NULL, s, sizeof(s));
+    AZ::Utils::GetExecutablePath(s, sizeof(s));
 
     // Log EXE filename only if possible (not full EXE path which could contain sensitive info)
     AZStd::string exeName;
@@ -279,7 +281,7 @@ public:
         int nFlags = pCVar->GetFlags();
         if (((nFlags & VF_DUMPTODISK) && (nFlags & VF_MODIFIED)) || (nFlags & VF_WASINCONFIG))
         {
-            string szValue = pCVar->GetString();
+            AZStd::string szValue = pCVar->GetString();
             int pos;
 
             pos = 1;
@@ -287,7 +289,7 @@ public:
             {
                 pos = static_cast(szValue.find_first_of("\\", pos));
 
-                if (pos == string::npos)
+                if (pos == AZStd::string::npos)
                 {
                     break;
                 }
@@ -302,7 +304,7 @@ public:
             {
                 pos = static_cast(szValue.find_first_of("\"", pos));
 
-                if (pos == string::npos)
+                if (pos == AZStd::string::npos)
                 {
                     break;
                 }
@@ -311,7 +313,7 @@ public:
                 pos += 2;
             }
 
-            string szLine = pCVar->GetName();
+            AZStd::string szLine = pCVar->GetName();
 
             if (pCVar->GetType() == CVAR_STRING)
             {
@@ -344,7 +346,7 @@ void CSystem::SaveConfiguration()
 //////////////////////////////////////////////////////////////////////////
 // system cfg
 //////////////////////////////////////////////////////////////////////////
-CSystemConfiguration::CSystemConfiguration(const string& strSysConfigFilePath, CSystem* pSystem, ILoadConfigurationEntrySink* pSink, bool warnIfMissing)
+CSystemConfiguration::CSystemConfiguration(const AZStd::string& strSysConfigFilePath, CSystem* pSystem, ILoadConfigurationEntrySink* pSink, bool warnIfMissing)
     : m_strSysConfigFilePath(strSysConfigFilePath)
     , m_bError(false)
     , m_pSink(pSink)
@@ -364,14 +366,14 @@ CSystemConfiguration::~CSystemConfiguration()
 //////////////////////////////////////////////////////////////////////////
 bool CSystemConfiguration::ParseSystemConfig()
 {
-    string filename = m_strSysConfigFilePath;
-    if (strlen(PathUtil::GetExt(filename)) == 0)
+    AZStd::string filename = m_strSysConfigFilePath;
+    if (strlen(PathUtil::GetExt(filename.c_str())) == 0)
     {
         filename = PathUtil::ReplaceExtension(filename, "cfg");
     }
 
     CCryFile file;
-    string filenameLog;
+    AZStd::string filenameLog;
     {
         int flags = AZ::IO::IArchive::FOPEN_HINT_QUIET | AZ::IO::IArchive::FOPEN_ONDISK;
 
@@ -380,7 +382,7 @@ bool CSystemConfiguration::ParseSystemConfig()
             // this is used when theres a very specific file to read, like @user@/game.cfg which is read
             // IN ADDITION to the one in the game folder, and afterwards to override values in it.
             // if the file is missing and its already prefixed with an alias, there is no need to look any further.
-            if (!(file.Open(filename, "rb", flags)))
+            if (!(file.Open(filename.c_str(), "rb", flags)))
             {
                 if (m_warnIfMissing)
                 {
@@ -394,11 +396,11 @@ bool CSystemConfiguration::ParseSystemConfig()
             // otherwise, if the file isn't prefixed with an alias, then its likely one of the convenience mappings
             // to either root or assets/config.  this is done so that code can just request a simple file name and get its data
             if (
-                !(file.Open(filename, "rb", flags)) &&
-                !(file.Open(string("@root@/") + filename, "rb", flags)) &&
-                !(file.Open(string("@assets@/") + filename, "rb", flags)) &&
-                !(file.Open(string("@assets@/config/") + filename, "rb", flags)) &&
-                !(file.Open(string("@assets@/config/spec/") + filename, "rb", flags))
+                !(file.Open(filename.c_str(), "rb", flags)) &&
+                !(file.Open((AZStd::string("@root@/") + filename).c_str(), "rb", flags)) &&
+                !(file.Open((AZStd::string("@assets@/") + filename).c_str(), "rb", flags)) &&
+                !(file.Open((AZStd::string("@assets@/config/") + filename).c_str(), "rb", flags)) &&
+                !(file.Open((AZStd::string("@assets@/config/spec/") + filename).c_str(), "rb", flags))
                 )
             {
                 if (m_warnIfMissing)
@@ -429,7 +431,7 @@ bool CSystemConfiguration::ParseSystemConfig()
     sAllText[nLen] = '\0';
     sAllText[nLen + 1] = '\0';
 
-    string strGroup;            // current group e.g. "[General]"
+    AZStd::string strGroup;            // current group e.g. "[General]"
 
     char* strLast = sAllText + nLen;
     char* str = sAllText;
@@ -447,26 +449,25 @@ bool CSystemConfiguration::ParseSystemConfig()
             str++;
         }
 
-        string strLine = s;
+        AZStd::string strLine = s;
+        AZ::StringFunc::TrimWhiteSpace(strLine, true, true);
 
         // detect groups e.g. "[General]"   should set strGroup="General"
         {
-            string strTrimmedLine(RemoveWhiteSpaces(strLine));
-            size_t size = strTrimmedLine.size();
+            size_t size = strLine.size();
 
             if (size >= 3)
             {
-                if (strTrimmedLine[0] == '[' && strTrimmedLine[size - 1] == ']')       // currently no comments are allowed to be behind groups
+                if (strLine[0] == '[' && strLine[size - 1] == ']')  // currently no comments are allowed to be behind groups
                 {
-                    strGroup = &strTrimmedLine[1];
-                    strGroup.resize(size - 2);                                  // remove [ and ]
+                    strGroup = &strLine[1];
+                    strGroup.resize(size - 2);                      // remove [ and ]
                     continue;                                       // next line
                 }
             }
         }
 
         //trim all whitespace characters at the beginning and the end of the current line and store its size
-        strLine.Trim();
         size_t strLineSize = strLine.size();
 
         //skip comments, comments start with ";" or "--" but may have preceding whitespace characters
@@ -488,35 +489,36 @@ bool CSystemConfiguration::ParseSystemConfig()
         }
 
         //if line contains a '=' try to read and assign console variable
-        string::size_type posEq(strLine.find("=", 0));
-        if (string::npos != posEq)
+        AZStd::string::size_type posEq(strLine.find("=", 0));
+        if (AZStd::string::npos != posEq)
         {
-            string stemp(strLine, 0, posEq);
-            string strKey(RemoveWhiteSpaces(stemp));
+            AZStd::string stemp;
+            AZStd::string strKey(strLine, 0, posEq);
+            AZ::StringFunc::TrimWhiteSpace(strKey, true, true);
 
             {
                 // extract value
-                string::size_type posValueStart(strLine.find("\"", posEq + 1) + 1);
-                string::size_type posValueEnd(strLine.rfind('\"'));
+                AZStd::string::size_type posValueStart(strLine.find("\"", posEq + 1) + 1);
+                AZStd::string::size_type posValueEnd(strLine.rfind('\"'));
 
-                string strValue;
+                AZStd::string strValue;
 
-                if (string::npos != posValueStart && string::npos != posValueEnd)
+                if (AZStd::string::npos != posValueStart && AZStd::string::npos != posValueEnd)
                 {
-                    strValue = string(strLine, posValueStart, posValueEnd - posValueStart);
+                    strValue = AZStd::string(strLine, posValueStart, posValueEnd - posValueStart);
                 }
                 else
                 {
-                    string strTmp(strLine, posEq + 1, strLine.size() - (posEq + 1));
-                    strValue = RemoveWhiteSpaces(strTmp);
+                    strValue = AZStd::string(strLine, posEq + 1, strLine.size() - (posEq + 1));
+                    AZ::StringFunc::TrimWhiteSpace(strValue, true, true);
                 }
 
                 {
                     // replace '\\\\' with '\\' and '\\\"' with '\"'
-                    strValue.replace("\\\\", "\\");
-                    strValue.replace("\\\"", "\"");
+                    AZ::StringFunc::Replace(strValue, "\\\\", "\\");
+                    AZ::StringFunc::Replace(strValue, "\\\"", "\"");
                     
-                    m_pSink->OnLoadConfigurationEntry(strKey, strValue, strGroup);
+                    m_pSink->OnLoadConfigurationEntry(strKey.c_str(), strValue.c_str(), strGroup.c_str());
                 }
             }
         }
diff --git a/Code/Legacy/CrySystem/SystemCFG.h b/Code/Legacy/CrySystem/SystemCFG.h
index ac4f04d146..7ec6f1231b 100644
--- a/Code/Legacy/CrySystem/SystemCFG.h
+++ b/Code/Legacy/CrySystem/SystemCFG.h
@@ -15,22 +15,16 @@
 #include 
 #include 
 
-typedef string SysConfigKey;
-typedef string SysConfigValue;
+typedef AZStd::string SysConfigKey;
+typedef AZStd::string SysConfigValue;
 
 //////////////////////////////////////////////////////////////////////////
 class CSystemConfiguration
 {
 public:
-    CSystemConfiguration(const string& strSysConfigFilePath, CSystem* pSystem, ILoadConfigurationEntrySink* pSink, bool warnIfMissing = true);
+    CSystemConfiguration(const AZStd::string& strSysConfigFilePath, CSystem* pSystem, ILoadConfigurationEntrySink* pSink, bool warnIfMissing = true);
     ~CSystemConfiguration();
 
-    string RemoveWhiteSpaces(string& s)
-    {
-        s.Trim();
-        return s;
-    }
-
     bool IsError() const { return m_bError; }
 
 private: // ----------------------------------------
@@ -39,10 +33,10 @@ private: // ----------------------------------------
     //   success
     bool ParseSystemConfig();
 
-    CSystem*                                               m_pSystem;
-    string                                                  m_strSysConfigFilePath;
-    bool                                                        m_bError;
-    ILoadConfigurationEntrySink*       m_pSink;                                         // never 0
+    CSystem*                           m_pSystem;
+    AZStd::string                      m_strSysConfigFilePath;
+    bool                               m_bError;
+    ILoadConfigurationEntrySink*       m_pSink;  // never 0
     bool m_warnIfMissing;
 };
 
diff --git a/Code/Legacy/CrySystem/SystemInit.cpp b/Code/Legacy/CrySystem/SystemInit.cpp
index f24bcd2d41..d1ccb56c05 100644
--- a/Code/Legacy/CrySystem/SystemInit.cpp
+++ b/Code/Legacy/CrySystem/SystemInit.cpp
@@ -33,7 +33,6 @@
 
 #include "CryLibrary.h"
 #include "CryPath.h"
-#include 
 
 #include 
 #include 
@@ -452,7 +451,7 @@ AZStd::unique_ptr CSystem::LoadDLL(const char* dllName)
     //////////////////////////////////////////////////////////////////////////
     // After loading DLL initialize it by calling ModuleInitISystem
     //////////////////////////////////////////////////////////////////////////
-    string moduleName = PathUtil::GetFileName(dllName);
+    AZStd::string moduleName = PathUtil::GetFileName(dllName);
 
     typedef void*(*PtrFunc_ModuleInitISystem)(ISystem* pSystem, const char* moduleName);
     PtrFunc_ModuleInitISystem pfnModuleInitISystem = handle->GetFunction(DLL_MODULE_INIT_ISYSTEM);
@@ -524,7 +523,7 @@ void CSystem::ShutdownModuleLibraries()
 /////////////////////////////////////////////////////////////////////////////////
 
 #if defined(WIN32) || defined(WIN64)
-wstring GetErrorStringUnsupportedGPU(const char* gpuName, unsigned int gpuVendorId, unsigned int gpuDeviceId)
+AZStd::wstring GetErrorStringUnsupportedGPU(const char* gpuName, unsigned int gpuVendorId, unsigned int gpuDeviceId)
 {
     const size_t fullLangID = (size_t) GetKeyboardLayout(0);
     const size_t primLangID = fullLangID & 0x3FF;
@@ -878,19 +877,19 @@ void CSystem::InitLocalization()
         languageID = ILocalizationManager::EPlatformIndependentLanguageID::ePILID_English_US;
     }
 
-    string language = m_pLocalizationManager->LangNameFromPILID(languageID);
+    AZStd::string language = m_pLocalizationManager->LangNameFromPILID(languageID);
     m_pLocalizationManager->SetLanguage(language.c_str());
     if (m_pLocalizationManager->GetLocalizationFormat() == 1)
     {
-        string translationsListXML = LOCALIZATION_TRANSLATIONS_LIST_FILE_NAME;
-        m_pLocalizationManager->InitLocalizationData(translationsListXML);
+        AZStd::string translationsListXML = LOCALIZATION_TRANSLATIONS_LIST_FILE_NAME;
+        m_pLocalizationManager->InitLocalizationData(translationsListXML.c_str());
 
         m_pLocalizationManager->LoadAllLocalizationData();
     }
     else
     {
         // if the language value cannot be found, let's default to the english pak
-        OpenLanguagePak(language);
+        OpenLanguagePak(language.c_str());
     }
 
     if (auto console = AZ::Interface::Get(); console != nullptr)
@@ -906,7 +905,7 @@ void CSystem::InitLocalization()
             language.assign(languageAudio.data(), languageAudio.size());
         }
     }
-    OpenLanguageAudioPak(language);
+    OpenLanguageAudioPak(language.c_str());
 }
 
 void CSystem::OpenBasicPaks()
@@ -970,10 +969,10 @@ void CSystem::OpenLanguagePak(const char* sLanguage)
     // Initialize languages.
 
     // Omit the trailing slash!
-    string sLocalizationFolder = PathUtil::GetLocalizationFolder();
+    AZStd::string sLocalizationFolder = PathUtil::GetLocalizationFolder();
 
     // load xml pak with full filenames to perform wildcard searches.
-    string sLocalizedPath;
+    AZStd::string sLocalizedPath;
     GetLocalizedPath(sLanguage, sLocalizedPath);
     if (!m_env.pCryPak->OpenPacks({ sLocalizationFolder.c_str(), sLocalizationFolder.size() }, { sLocalizedPath.c_str(), sLocalizedPath.size() }, 0))
     {
@@ -1000,15 +999,15 @@ void CSystem::OpenLanguageAudioPak([[maybe_unused]] const char* sLanguage)
     int nPakFlags = 0;
 
     // Omit the trailing slash!
-    string sLocalizationFolder(string().assign(PathUtil::GetLocalizationFolder(), 0, PathUtil::GetLocalizationFolder().size() - 1));
+    AZStd::string sLocalizationFolder(AZStd::string().assign(PathUtil::GetLocalizationFolder(), 0, PathUtil::GetLocalizationFolder().size() - 1));
 
-    if (sLocalizationFolder.compareNoCase("Languages") == 0)
+    if (!AZ::StringFunc::Equal(sLocalizationFolder, "Languages", false))
     {
         sLocalizationFolder = "@assets@";
     }
 
     // load localized pak with crc32 filenames on consoles to save memory.
-    string sLocalizedPath = "loc.pak";
+    AZStd::string sLocalizedPath = "loc.pak";
 
     if (!m_env.pCryPak->OpenPacks(sLocalizationFolder.c_str(), sLocalizedPath.c_str(), nPakFlags))
     {
@@ -1018,10 +1017,10 @@ void CSystem::OpenLanguageAudioPak([[maybe_unused]] const char* sLanguage)
 }
 
 
-string GetUniqueLogFileName(string logFileName)
+AZStd::string GetUniqueLogFileName(AZStd::string logFileName)
 {
-    string logFileNamePrefix = logFileName;
-    if ((logFileNamePrefix[0] != '@') && (AzFramework::StringFunc::Path::IsRelative(logFileNamePrefix)))
+    AZStd::string logFileNamePrefix = logFileName;
+    if ((logFileNamePrefix[0] != '@') && (AzFramework::StringFunc::Path::IsRelative(logFileNamePrefix.c_str())))
     {
         logFileNamePrefix = "@log@/";
         logFileNamePrefix += logFileName;
@@ -1037,9 +1036,9 @@ string GetUniqueLogFileName(string logFileName)
         return logFileNamePrefix;
     }
 
-    string logFileExtension;
+    AZStd::string logFileExtension;
     size_t extensionIndex = logFileName.find_last_of('.');
-    if (extensionIndex != string::npos)
+    if (extensionIndex != AZStd::string::npos)
     {
         logFileExtension = logFileName.substr(extensionIndex, logFileName.length() - extensionIndex);
         logFileNamePrefix = logFileName.substr(0, extensionIndex);
@@ -1213,7 +1212,7 @@ bool CSystem::Init(const SSystemInitParams& startupParams)
 
         osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
 AZ_PUSH_DISABLE_WARNING(4996, "-Wunknown-warning-option")
-        GetVersionExA(&osvi);
+        GetVersionExW(&osvi);
 AZ_POP_DISABLE_WARNING
 
         bool bIsWindowsXPorLater = osvi.dwMajorVersion > 5 || (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion >= 1);
@@ -1308,7 +1307,7 @@ AZ_POP_DISABLE_WARNING
             }
             else if (startupParams.sLogFileName)    //otherwise see if the startup params has a log file name, if so use it
             {
-                const string sUniqueLogFileName = GetUniqueLogFileName(startupParams.sLogFileName);
+                const AZStd::string sUniqueLogFileName = GetUniqueLogFileName(startupParams.sLogFileName);
                 m_env.pLog->SetFileName(sUniqueLogFileName.c_str(), startupParams.autoBackupLogs);
             }
             else//use the default log name
@@ -1656,20 +1655,20 @@ static void LoadConfigurationCmd(IConsoleCmdArgs* pParams)
         return;
     }
 
-    GetISystem()->LoadConfiguration(string("Config/") + pParams->GetArg(1));
+    GetISystem()->LoadConfiguration((AZStd::string("Config/") + pParams->GetArg(1)).c_str());
 }
 
 
 // --------------------------------------------------------------------------------------------------------------------------
 
-static string ConcatPath(const char* szPart1, const char* szPart2)
+static AZStd::string ConcatPath(const char* szPart1, const char* szPart2)
 {
     if (szPart1[0] == 0)
     {
         return szPart2;
     }
 
-    string ret;
+    AZStd::string ret;
 
     ret.reserve(strlen(szPart1) + 1 + strlen(szPart2));
 
@@ -2133,12 +2132,12 @@ void CSystem::CreateAudioVars()
 }
 
 /////////////////////////////////////////////////////////////////////
-void CSystem::AddCVarGroupDirectory(const string& sPath)
+void CSystem::AddCVarGroupDirectory(const AZStd::string& sPath)
 {
     CryLog("creating CVarGroups from directory '%s' ...", sPath.c_str());
     INDENT_LOG_DURING_SCOPE();
 
-    AZ::IO::ArchiveFileIterator handle = gEnv->pCryPak->FindFirst(ConcatPath(sPath, "*.cfg").c_str());
+    AZ::IO::ArchiveFileIterator handle = gEnv->pCryPak->FindFirst(ConcatPath(sPath.c_str(), "*.cfg").c_str());
 
     if (!handle)
     {
@@ -2151,16 +2150,9 @@ void CSystem::AddCVarGroupDirectory(const string& sPath)
         {
             if (handle.m_filename != "." && handle.m_filename != "..")
             {
-                AddCVarGroupDirectory(ConcatPath(sPath, handle.m_filename.data()));
+                AddCVarGroupDirectory(ConcatPath(sPath.c_str(), handle.m_filename.data()));
             }
         }
-        else
-        {
-            string sFilePath = ConcatPath(sPath, handle.m_filename.data());
-
-            string sCVarName = sFilePath;
-            PathUtil::RemoveExtension(sCVarName);
-        }
     } while (handle = gEnv->pCryPak->FindNext(handle));
 
     gEnv->pCryPak->FindClose(handle);
diff --git a/Code/Legacy/CrySystem/SystemWin32.cpp b/Code/Legacy/CrySystem/SystemWin32.cpp
index 2cc41adc08..6c9b210c80 100644
--- a/Code/Legacy/CrySystem/SystemWin32.cpp
+++ b/Code/Legacy/CrySystem/SystemWin32.cpp
@@ -15,7 +15,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include  // for AZ_MAX_PATH_LEN
 #include 
@@ -127,7 +126,7 @@ const char* CSystem::GetUserName()
     DWORD dwSize = iNameBufferSize;
     wchar_t nameW[iNameBufferSize];
     ::GetUserNameW(nameW, &dwSize);
-    cry_strcpy(szNameBuffer, CryStringUtils::WStrToUTF8(nameW));
+    AZStd::to_string(szNameBuffer, iNameBufferSize, { nameW, dwSize });
     return szNameBuffer;
 #else
 #if defined(LINUX)
@@ -171,12 +170,12 @@ int CSystem::GetApplicationInstance()
     // this code below essentially "locks" an instance of the USER folder to a specific running application
     if (m_iApplicationInstance == -1)
     {
-        string suffix;
+        AZStd::wstring suffix;
         for (int instance = 0;; ++instance)
         {
-            suffix.Format("(%d)", instance);
+            suffix = AZStd::wstring::format(L"O3DEApplication(%d)", instance);
 
-            CreateMutex(NULL, TRUE, "LumberyardApplication" + suffix);
+            CreateMutexW(NULL, TRUE, suffix.c_str());
             // search for duplicates
             if (GetLastError() != ERROR_ALREADY_EXISTS)
             {
@@ -195,13 +194,13 @@ int CSystem::GetApplicationInstance()
 int CSystem::GetApplicationLogInstance([[maybe_unused]] const char* logFilePath)
 {
 #if AZ_TRAIT_OS_USE_WINDOWS_MUTEX
-    string suffix;
+    AZStd::wstring suffix;
     int instance = 0;
     for (;; ++instance)
     {
-        suffix.Format("(%d)", instance);
+        suffix = AZStd::wstring::format(L"%s(%d)", logFilePath, instance);
 
-        CreateMutex(NULL, TRUE, logFilePath + suffix);
+        CreateMutexW(NULL, TRUE, suffix.c_str());
         if (GetLastError() != ERROR_ALREADY_EXISTS)
         {
             break;
@@ -218,30 +217,11 @@ struct CryDbgModule
 {
     HANDLE heap;
     WIN_HMODULE handle;
-    string name;
+    AZStd::string name;
     DWORD dwSize;
 };
 
 #ifdef WIN32
-//////////////////////////////////////////////////////////////////////////
-class CStringOrder
-{
-public:
-    bool operator () (const char* szLeft, const char* szRight) const {return azstricmp(szLeft, szRight) < 0; }
-};
-typedef std::map StringToSizeMap;
-void AddSize (StringToSizeMap& mapSS, const char* szString, unsigned nSize)
-{
-    StringToSizeMap::iterator it = mapSS.find (szString);
-    if (it == mapSS.end())
-    {
-        mapSS.insert (StringToSizeMap::value_type(szString, nSize));
-    }
-    else
-    {
-        it->second += nSize;
-    }
-}
 
 //////////////////////////////////////////////////////////////////////////
 const char* GetModuleGroup (const char* szString)
@@ -283,7 +263,7 @@ static const char* GetLastSystemErrorMessage()
                 0,
                 NULL))
         {
-            cry_strcpy(szBuffer, (char*)lpMsgBuf);
+            azstrcpy(szBuffer, AZ_ARRAY_SIZE(szBuffer), (char*)lpMsgBuf);
             LocalFree(lpMsgBuf);
         }
         else
@@ -343,12 +323,15 @@ void CSystem::FatalError(const char* format, ...)
     assert(szBuffer[0] >= ' ');
     //  strcpy(szBuffer,szBuffer+1);    // remove verbosity tag since it is not supported by ::MessageBox
 
-    OutputDebugString(szBuffer);
+    AZ::Debug::Platform::OutputToDebugger("CrySystem", szBuffer);
+
 #ifdef WIN32
     OnFatalError(szBuffer);
     if (!g_cvars.sys_no_crash_dialog)
     {
-        ::MessageBox(NULL, szBuffer, "Open 3D Engine Error", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
+        AZStd::wstring szBufferW;
+        AZStd::to_wstring(szBufferW, szBuffer);
+        ::MessageBoxW(NULL, szBufferW.c_str(), L"Open 3D Engine Error", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
     }
 
     // Dump callstack.
@@ -410,7 +393,7 @@ void CSystem::debug_GetCallStack(const char** pFunctions, int& nCount)
     unsigned int numFrames = StackRecorder::Record(frames, nMaxCount, 1);
     SymbolStorage::StackLine* textLines = (SymbolStorage::StackLine*)AZ_ALLOCA(sizeof(SymbolStorage::StackLine)*nMaxCount);
     SymbolStorage::DecodeFrames(frames, numFrames, textLines);
-    for (int i = 0; i < numFrames; i++)
+    for (unsigned int i = 0; i < numFrames; i++)
     {
         pFunctions[i] = textLines[i];
     }
@@ -461,20 +444,20 @@ bool CSystem::ReLaunchMediaCenter()
     }
 
     // Get the path to Media Center
-    char szExpandedPath[AZ_MAX_PATH_LEN];
-    if (!ExpandEnvironmentStrings("%SystemRoot%\\ehome\\ehshell.exe", szExpandedPath, AZ_MAX_PATH_LEN))
+    wchar_t szExpandedPath[AZ_MAX_PATH_LEN];
+    if (!ExpandEnvironmentStringsW(L"%SystemRoot%\\ehome\\ehshell.exe", szExpandedPath, AZ_MAX_PATH_LEN))
     {
         return false;
     }
 
     // Skip if ehshell.exe doesn't exist
-    if (GetFileAttributes(szExpandedPath) == 0xFFFFFFFF)
+    if (GetFileAttributesW(szExpandedPath) == 0xFFFFFFFF)
     {
         return false;
     }
 
     // Launch ehshell.exe
-    INT_PTR result = (INT_PTR)ShellExecute(NULL, TEXT("open"), szExpandedPath, NULL, NULL, SW_SHOWNORMAL);
+    INT_PTR result = (INT_PTR)ShellExecuteW(NULL, TEXT("open"), szExpandedPath, NULL, NULL, SW_SHOWNORMAL);
     return (result > 32);
 }
 #else
@@ -491,7 +474,7 @@ bool CSystem::GetWinGameFolder(char* szMyDocumentsPath, int maxPathSize)
     bool bSucceeded  = false;
     // check Vista and later OS first
 
-    HMODULE shell32 = LoadLibraryA("Shell32.dll");
+    HMODULE shell32 = LoadLibraryW(L"Shell32.dll");
     if (shell32)
     {
         typedef long (__stdcall * T_SHGetKnownFolderPath)(REFKNOWNFOLDERID rfid, unsigned long dwFlags, void* hToken, wchar_t** ppszPath);
@@ -505,7 +488,7 @@ bool CSystem::GetWinGameFolder(char* szMyDocumentsPath, int maxPathSize)
             if (bSucceeded)
             {
                 // Convert from UNICODE to UTF-8
-                cry_strcpy(szMyDocumentsPath, maxPathSize, CryStringUtils::WStrToUTF8(wMyDocumentsPath));
+                AZStd::to_string(szMyDocumentsPath, maxPathSize, wMyDocumentsPath);
                 CoTaskMemFree(wMyDocumentsPath);
             }
         }
@@ -519,7 +502,7 @@ bool CSystem::GetWinGameFolder(char* szMyDocumentsPath, int maxPathSize)
         bSucceeded = SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, NULL, 0, wMyDocumentsPath));
         if (bSucceeded)
         {
-            cry_strcpy(szMyDocumentsPath, maxPathSize, CryStringUtils::WStrToUTF8(wMyDocumentsPath));
+            AZStd::to_string(szMyDocumentsPath, maxPathSize, wMyDocumentsPath);
         }
     }
 
@@ -547,7 +530,7 @@ void CSystem::DetectGameFolderAccessRights()
     BOOL bAccessStatus = FALSE;
 
     // Get a pointer to the existing DACL.
-    dwRes = GetNamedSecurityInfo(".", SE_FILE_OBJECT,
+    dwRes = GetNamedSecurityInfoW(L".", SE_FILE_OBJECT,
             DACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION,
             NULL, NULL, &pDACL, NULL, &pSD);
 
diff --git a/Code/Legacy/CrySystem/WindowsErrorReporting.cpp b/Code/Legacy/CrySystem/WindowsErrorReporting.cpp
index a02f55b69e..d467923c74 100644
--- a/Code/Legacy/CrySystem/WindowsErrorReporting.cpp
+++ b/Code/Legacy/CrySystem/WindowsErrorReporting.cpp
@@ -66,7 +66,9 @@ LONG WINAPI CryEngineExceptionFilterMiniDump(struct _EXCEPTION_POINTERS* pExcept
         return EXCEPTION_CONTINUE_SEARCH;
     }
 
-    HANDLE hFile = ::CreateFile(szDumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+    AZStd::wstring szDumpPathW;
+    AZStd::to_wstring(szDumpPathW, szDumpPath);
+    HANDLE hFile = ::CreateFileW(szDumpPathW.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
     if (hFile == INVALID_HANDLE_VALUE)
     {
         CryLogAlways("Failed to record DMP file: could not open file '%s' for writing - error code: %d", szDumpPath, GetLastError());
diff --git a/Code/Legacy/CrySystem/XConsole.cpp b/Code/Legacy/CrySystem/XConsole.cpp
index a2f3426d5c..ae07f86312 100644
--- a/Code/Legacy/CrySystem/XConsole.cpp
+++ b/Code/Legacy/CrySystem/XConsole.cpp
@@ -15,9 +15,6 @@
 #include "XConsoleVariable.h"
 #include "System.h"
 #include "ConsoleBatchFile.h"
-#include "StringUtils.h"
-#include "UnicodeFunctions.h"
-#include "UnicodeIterator.h"
 
 #include 
 #include 
@@ -87,33 +84,6 @@ inline int GetCharPrio(char x)
         return x;
     }
 }
-// case sensitive
-inline bool less_CVar(const char* left, const char* right)
-{
-    for (;; )
-    {
-        uint32 l = GetCharPrio(*left), r = GetCharPrio(*right);
-
-        if (l < r)
-        {
-            return true;
-        }
-        if (l > r)
-        {
-            return false;
-        }
-
-        if (*left == 0 || *right == 0)
-        {
-            break;
-        }
-
-        ++left;
-        ++right;
-    }
-
-    return false;
-}
 
 void Command_SetWaitSeconds(IConsoleCmdArgs* pCmd)
 {
@@ -149,7 +119,7 @@ void Bind(IConsoleCmdArgs* cmdArgs)
 {
     if (cmdArgs->GetArgCount() >= 3)
     {
-        string arg;
+        AZStd::string arg;
         for (int i = 2; i < cmdArgs->GetArgCount(); ++i)
         {
             arg += cmdArgs->GetArg(i);
@@ -348,28 +318,6 @@ void CXConsole::Init(ISystem* pSystem)
         con_restricted = 0;
     }
 
-    // test cases -----------------------------------------------
-    assert(GetCVar("con_debug") != 0);        // should be registered a few lines above
-    assert(GetCVar("Con_Debug") == GetCVar("con_debug"));     // different case
-
-    // editor
-    assert(strcmp(AutoComplete("con_"), "con_debug") == 0);
-    assert(strcmp(AutoComplete("CON_"), "con_debug") == 0);
-    assert(strcmp(AutoComplete("con_debug"), "con_display_last_messages") == 0);       // actually we should reconsider this behavior
-    assert(strcmp(AutoComplete("Con_Debug"), "con_display_last_messages") == 0);       // actually we should reconsider this behavior
-
-    // game
-    assert(strcmp(ProcessCompletion("con_"), "con_debug ") == 0);
-    ResetAutoCompletion();
-    assert(strcmp(ProcessCompletion("CON_"), "con_debug ") == 0);
-    ResetAutoCompletion();
-    assert(strcmp(ProcessCompletion("con_debug"), "con_debug ") == 0);
-    ResetAutoCompletion();
-    assert(strcmp(ProcessCompletion("Con_Debug"), "con_debug ") == 0);
-    ResetAutoCompletion();
-
-    // ----------------------------------------------------------
-
     m_nLoadingBackTexID = -1;
 
     if (gEnv->IsDedicated())
@@ -414,9 +362,7 @@ void CXConsole::Init(ISystem* pSystem)
 void CXConsole::LogChangeMessage(const char* name, const bool isConst, const bool isCheat, const bool isReadOnly, const bool isDeprecated,
     const char* oldValue, const char* newValue, [[maybe_unused]] const bool isProcessingGroup, const bool allowChange)
 {
-    string logMessage;
-
-    logMessage.Format
+    AZStd::string logMessage = AZStd::string::format
         ("[CVARS]: [%s] variable [%s] from [%s] to [%s]%s; Marked as%s%s%s%s",
         (allowChange) ? "CHANGED" : "IGNORED CHANGE",
         name,
@@ -452,7 +398,7 @@ void CXConsole::RegisterVar(ICVar* pCVar, ConsoleVarFunc pChangeFunc)
     bool isReadOnly = ((pCVar->GetFlags() & VF_READONLY) != 0);
     bool isDeprecated = ((pCVar->GetFlags() & VF_DEPRECATED) != 0);
 
-    ConfigVars::iterator it = m_configVars.find(CONST_TEMP_STRING(pCVar->GetName()));
+    ConfigVars::iterator it = m_configVars.find(pCVar->GetName());
     if (it != m_configVars.end())
     {
         SConfigVar& var = it->second;
@@ -906,7 +852,7 @@ void CXConsole::DumpKeyBinds(IKeyBindDumpSink* pCallback)
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 const char* CXConsole::FindKeyBind(const char* sCmd) const
 {
-    ConsoleBindsMap::const_iterator it = m_mapBinds.find(CONST_TEMP_STRING(sCmd));
+    ConsoleBindsMap::const_iterator it = m_mapBinds.find(sCmd);
 
     if (it != m_mapBinds.end())
     {
@@ -1263,9 +1209,7 @@ bool CXConsole::ProcessInput(const AzFramework::InputChannel& inputChannel)
         if (m_nCursorPos)
         {
             const char* pCursor = m_sInputBuffer.c_str() + m_nCursorPos;
-            Unicode::CIterator pUnicode(pCursor);
-            --pUnicode; // Note: This moves back one UCS code-point, but doesn't necessarily match one displayed character (ie, combining diacritics)
-            pCursor = pUnicode.GetPosition();
+            pCursor -= Utf8::Internal::sequence_length(pCursor); // Note: This moves back one UCS code-point, but doesn't necessarily match one displayed character (ie, combining diacritics)
             m_nCursorPos = pCursor - m_sInputBuffer.c_str();
         }
         return true;
@@ -1275,9 +1219,7 @@ bool CXConsole::ProcessInput(const AzFramework::InputChannel& inputChannel)
         if (m_nCursorPos < (int)(m_sInputBuffer.length()))
         {
             const char* pCursor = m_sInputBuffer.c_str() + m_nCursorPos;
-            Unicode::CIterator pUnicode(pCursor);
-            ++pUnicode; // Note: This moves forward one UCS code-point, but doesn't necessarily match one displayed character (ie, combining diacritics)
-            pCursor = pUnicode.GetPosition();
+            pCursor += Utf8::Internal::sequence_length(pCursor); // Note: This moves forward one UCS code-point, but doesn't necessarily match one displayed character (ie, combining diacritics)
             m_nCursorPos = pCursor - m_sInputBuffer.c_str();
         }
         return true;
@@ -1446,7 +1388,7 @@ bool CXConsole::GetLineNo(const int indwLineNo, char* outszBuffer, const int ind
     {
         buf++;                          // to jump over verbosity level character
     }
-    cry_strcpy(outszBuffer, indwBufferSize, buf);
+    azstrcpy(outszBuffer, indwBufferSize, buf);
 
     return true;
 }
@@ -1552,33 +1494,33 @@ const char* CXConsole::GetFlagsString(const uint32 dwFlags)
     static char sFlags[256];
 
     // hiding this makes it a bit more difficult for cheaters
-    //  if(dwFlags&VF_CHEAT)                  cry_strcat( sFlags,"CHEAT, ");
+    //  if(dwFlags&VF_CHEAT)                  azstrcat( sFlags,"CHEAT, ");
 
-    cry_strcpy(sFlags, "");
+    azstrcpy(sFlags, AZ_ARRAY_SIZE(sFlags), "");
 
     if (dwFlags & VF_READONLY)
     {
-        cry_strcat(sFlags, "READONLY, ");
+        azstrcat(sFlags, AZ_ARRAY_SIZE(sFlags), "READONLY, ");
     }
     if (dwFlags & VF_DEPRECATED)
     {
-        cry_strcat(sFlags, "DEPRECATED, ");
+        azstrcat(sFlags, AZ_ARRAY_SIZE(sFlags), "DEPRECATED, ");
     }
     if (dwFlags & VF_DUMPTODISK)
     {
-        cry_strcat(sFlags, "DUMPTODISK, ");
+        azstrcat(sFlags, AZ_ARRAY_SIZE(sFlags), "DUMPTODISK, ");
     }
     if (dwFlags & VF_REQUIRE_LEVEL_RELOAD)
     {
-        cry_strcat(sFlags, "REQUIRE_LEVEL_RELOAD, ");
+        azstrcat(sFlags, AZ_ARRAY_SIZE(sFlags), "REQUIRE_LEVEL_RELOAD, ");
     }
     if (dwFlags & VF_REQUIRE_APP_RESTART)
     {
-        cry_strcat(sFlags, "REQUIRE_APP_RESTART, ");
+        azstrcat(sFlags, AZ_ARRAY_SIZE(sFlags), "REQUIRE_APP_RESTART, ");
     }
     if (dwFlags & VF_RESTRICTEDMODE)
     {
-        cry_strcat(sFlags, "RESTRICTEDMODE, ");
+        azstrcat(sFlags, AZ_ARRAY_SIZE(sFlags), "RESTRICTEDMODE, ");
     }
 
     if (sFlags[0] != 0)
@@ -1794,7 +1736,7 @@ void CXConsole::DisplayHelp(const char* help, const char* name)
         char* start, * pos;
         for (pos = strstr((char*)help, "\n"), start = (char*)help; pos; start = ++pos)
         {
-            string s = start;
+            AZStd::string s = start;
             s.resize(pos - start);
             ConsoleLogInputResponse("    $3%s", s.c_str());
             pos = strstr(pos, "\n");
@@ -1816,11 +1758,12 @@ void CXConsole::ExecuteString(const char* command, const bool bSilentMode, const
 
     // Store the string commands into a list and defer the execution for later.
     // The commands will be processed in CXConsole::Update()
-    string str(command);
-    str.TrimLeft();
+    AZStd::string str(command);
+    AZ::StringFunc::TrimWhiteSpace(str, true, false);
 
     // Unroll the exec command
-    bool unroll = (0 == str.Left(strlen("exec")).compareNoCase("exec"));
+    
+    bool unroll = (0 == AZ::StringFunc::Find(str, "exec", 0, false, false));
 
     if (unroll)
     {
@@ -1858,10 +1801,10 @@ void CXConsole::ResetCVarsToDefaults()
 
 }
 
-void CXConsole::SplitCommands(const char* line, std::list& split)
+void CXConsole::SplitCommands(const char* line, std::list& split)
 {
     const char* start = line;
-    string working;
+    AZStd::string working;
 
     while (true)
     {
@@ -1881,7 +1824,7 @@ void CXConsole::SplitCommands(const char* line, std::list& split)
         case '\0':
         {
             working.assign(start, line - 1);
-            working.Trim();
+            AZ::StringFunc::TrimWhiteSpace(working, true, true);
 
             if (!working.empty())
             {
@@ -1931,15 +1874,15 @@ void CXConsole::ExecuteStringInternal(const char* command, const bool bFromConso
     ConsoleCommandsMapItor itrCmd;
     ConsoleVariablesMapItor itrVar;
 
-    std::list lineCommands;
+    std::list lineCommands;
     SplitCommands(command, lineCommands);
 
-    string sTemp;
-    string sCommand, sLineCommand;
+    AZStd::string sTemp;
+    AZStd::string sCommand, sLineCommand;
 
     while (!lineCommands.empty())
     {
-        string::size_type nPos;
+        AZStd::string::size_type nPos;
 
         {
             sTemp = lineCommands.front();
@@ -1951,17 +1894,17 @@ void CXConsole::ExecuteStringInternal(const char* command, const bool bFromConso
             {
                 if (GetStatus())
                 {
-                    AddLine(sTemp);
+                    AddLine(sTemp.c_str());
                 }
             }
 
             nPos = sTemp.find_first_of('=');
 
-            if (nPos != string::npos)
+            if (nPos != AZStd::string::npos)
             {
                 sCommand = sTemp.substr(0, nPos);
             }
-            else if ((nPos = sTemp.find_first_of(' ')) != string::npos)
+            else if ((nPos = sTemp.find_first_of(' ')) != AZStd::string::npos)
             {
                 sCommand = sTemp.substr(0, nPos);
             }
@@ -1970,7 +1913,7 @@ void CXConsole::ExecuteStringInternal(const char* command, const bool bFromConso
                 sCommand = sTemp;
             }
 
-            sCommand.Trim();
+            AZ::StringFunc::TrimWhiteSpace(sCommand, true, true);
 
             //////////////////////////////////////////
             // Search for CVars
@@ -2005,7 +1948,7 @@ void CXConsole::ExecuteStringInternal(const char* command, const bool bFromConso
 
         //////////////////////////////////////////
         //Check  if is a variable
-        itrVar = m_mapVariables.find(sCommand);
+        itrVar = m_mapVariables.find(sCommand.c_str());
         if (itrVar != m_mapVariables.end())
         {
             ICVar* pCVar = itrVar->second;
@@ -2017,10 +1960,10 @@ void CXConsole::ExecuteStringInternal(const char* command, const bool bFromConso
                     m_blockCounter++;
                 }
 
-                if (nPos != string::npos)
+                if (nPos != AZStd::string::npos)
                 {
                     sTemp = sTemp.substr(nPos + 1);     // remove the command from sTemp
-                    sTemp.Trim(" \t\r\n\"\'");
+                    AZ::StringFunc::StripEnds(sTemp, " \t\r\n\"\'");
 
                     if (sTemp == "?")
                     {
@@ -2094,12 +2037,12 @@ void CXConsole::ExecuteDeferredCommands()
 }
 
 //////////////////////////////////////////////////////////////////////////
-void CXConsole::ExecuteCommand(CConsoleCommand& cmd, string& str, bool bIgnoreDevMode)
+void CXConsole::ExecuteCommand(CConsoleCommand& cmd, AZStd::string& str, bool bIgnoreDevMode)
 {
     CryLog ("[CONSOLE] Executing console command '%s'", str.c_str());
     INDENT_LOG_DURING_SCOPE();
 
-    std::vector args;
+    std::vector args;
     size_t t;
 
     {
@@ -2118,7 +2061,7 @@ void CXConsole::ExecuteCommand(CConsoleCommand& cmd, string& str, bool bIgnoreDe
                 {
                     ;
                 }
-                args.push_back(string(start + 1, commandLine - 1));
+                args.push_back(AZStd::string(start + 1, commandLine - 1));
                 start = commandLine;
                 break;
             }
@@ -2129,7 +2072,7 @@ void CXConsole::ExecuteCommand(CConsoleCommand& cmd, string& str, bool bIgnoreDe
             {
                 if ((*commandLine == ' ') || !*commandLine)
                 {
-                    args.push_back(string(start, commandLine));
+                    args.push_back(AZStd::string(start, commandLine));
                     start = commandLine + 1;
                 }
             }
@@ -2139,7 +2082,7 @@ void CXConsole::ExecuteCommand(CConsoleCommand& cmd, string& str, bool bIgnoreDe
 
         if (args.size() >= 2 && args[1] == "?")
         {
-            DisplayHelp(cmd.m_sHelp, cmd.m_sName.c_str());
+            DisplayHelp(cmd.m_sHelp.c_str(), cmd.m_sName.c_str());
             return;
         }
 
@@ -2166,13 +2109,13 @@ void CXConsole::ExecuteCommand(CConsoleCommand& cmd, string& str, bool bIgnoreDe
         return;
     }
 
-    string buf;
+    AZStd::string buf;
     {
         // only do this for commands with script implementation
         for (;; )
         {
             t = str.find_first_of("\\", t);
-            if (t == string::npos)
+            if (t == AZStd::string::npos)
             {
                 break;
             }
@@ -2183,7 +2126,7 @@ void CXConsole::ExecuteCommand(CConsoleCommand& cmd, string& str, bool bIgnoreDe
         for (t = 1;; )
         {
             t = str.find_first_of("\"", t);
-            if (t == string::npos)
+            if (t == AZStd::string::npos)
             {
                 break;
             }
@@ -2194,9 +2137,9 @@ void CXConsole::ExecuteCommand(CConsoleCommand& cmd, string& str, bool bIgnoreDe
         buf = cmd.m_sCommand;
 
         size_t pp = buf.find("%%");
-        if (pp != string::npos)
+        if (pp != AZStd::string::npos)
         {
-            string list = "";
+            AZStd::string list = "";
             for (unsigned int i = 1; i < args.size(); i++)
             {
                 list += "\"" + args[i] + "\"";
@@ -2207,9 +2150,9 @@ void CXConsole::ExecuteCommand(CConsoleCommand& cmd, string& str, bool bIgnoreDe
             }
             buf.replace(pp, 2, list);
         }
-        else if ((pp = buf.find("%line")) != string::npos)
+        else if ((pp = buf.find("%line")) != AZStd::string::npos)
         {
-            string tmp = "\"" + str.substr(str.find(" ") + 1) + "\"";
+            AZStd::string tmp = "\"" + str.substr(str.find(" ") + 1) + "\"";
             if (args.size() > 1)
             {
                 buf.replace(pp, 5, tmp);
@@ -2226,7 +2169,7 @@ void CXConsole::ExecuteCommand(CConsoleCommand& cmd, string& str, bool bIgnoreDe
                 char pat[10];
                 azsprintf(pat, "%%%d", i);
                 size_t pos = buf.find(pat);
-                if (pos == string::npos)
+                if (pos == AZStd::string::npos)
                 {
                     if (i != args.size())
                     {
@@ -2241,7 +2184,7 @@ void CXConsole::ExecuteCommand(CConsoleCommand& cmd, string& str, bool bIgnoreDe
                         ConsoleWarning("Not enough arguments for: %s", cmd.m_sName.c_str());
                         return;
                     }
-                    string arg = "\"" + args[i] + "\"";
+                    AZStd::string arg = "\"" + args[i] + "\"";
                     buf.replace(pos, strlen(pat), arg);
                 }
             }
@@ -2340,15 +2283,15 @@ const char* CXConsole::ProcessCompletion(const char* szInputBuffer)
     }
     //try to search in command list
     bool bArgumentAutoComplete = false;
-    std::vector matches;
+    std::vector matches;
 
-    if (m_sPrevTab.find(' ') != string::npos)
+    if (m_sPrevTab.find(' ') != AZStd::string::npos)
     {
         bool bProcessAutoCompl = true;
 
         // Find command.
-        string sVar = m_sPrevTab.substr(0, m_sPrevTab.find(' '));
-        ICVar* pCVar = GetCVar(sVar);
+        AZStd::string sVar = m_sPrevTab.substr(0, m_sPrevTab.find(' '));
+        ICVar* pCVar = GetCVar(sVar.c_str());
         if (pCVar)
         {
             if (!(pCVar->GetFlags() & VF_RESTRICTEDMODE) && con_restricted)            // in restricted mode we allow only VF_RESTRICTEDMODE CVars&CCmd
@@ -2376,7 +2319,7 @@ const char* CXConsole::ProcessCompletion(const char* szInputBuffer)
                 int nMatches = pArgumentAutoComplete->GetCount();
                 for (int i = 0; i < nMatches; i++)
                 {
-                    string cmd = string(sVar) + " " + pArgumentAutoComplete->GetValue(i);
+                    AZStd::string cmd = AZStd::string(sVar) + " " + pArgumentAutoComplete->GetValue(i);
                     if (_strnicmp(m_sPrevTab.c_str(), cmd.c_str(), m_sPrevTab.length()) == 0)
                     {
                         {
@@ -2430,16 +2373,16 @@ const char* CXConsole::ProcessCompletion(const char* szInputBuffer)
 
     if (!matches.empty())
     {
-        std::sort(matches.begin(), matches.end(), less_CVar);       // to sort commands with variables
+        std::sort(matches.begin(), matches.end());       // to sort commands with variables
     }
     if (showlist && !matches.empty())
     {
         ConsoleLogInput(" ");       // empty line before auto completion
 
-        for (std::vector::iterator i = matches.begin(); i != matches.end(); ++i)
+        for (std::vector::iterator i = matches.begin(); i != matches.end(); ++i)
         {
             // List matching variables
-            const char* sVar = *i;
+            const char* sVar = i->c_str();
             ICVar* pVar = GetCVar(sVar);
 
             if (pVar)
@@ -2453,7 +2396,7 @@ const char* CXConsole::ProcessCompletion(const char* szInputBuffer)
         }
     }
 
-    for (std::vector::iterator i = matches.begin(); i != matches.end(); ++i)
+    for (std::vector::iterator i = matches.begin(); i != matches.end(); ++i)
     {
         if (m_nTabCount <= nMatch)
         {
@@ -2485,8 +2428,8 @@ void CXConsole::DisplayVarValue(ICVar* pVar)
 
     const char* sFlagsString = GetFlagsString(pVar->GetFlags());
 
-    string sValue = (pVar->GetFlags() & VF_INVISIBLE) ? "" : pVar->GetString();
-    string sVar = pVar->GetName();
+    AZStd::string sValue = (pVar->GetFlags() & VF_INVISIBLE) ? "" : pVar->GetString();
+    AZStd::string sVar = pVar->GetName();
 
     char szRealState[40] = "";
 
@@ -2623,12 +2566,8 @@ void CXConsole::AddLine(const char* inputStr)
 
 void CXConsole::PostLine(const char* lineOfText, size_t len)
 {
-    string line;
-
-    {
-        line = string(lineOfText, len);
-        m_dqConsoleBuffer.push_back(line);
-    }
+    AZStd::string line = AZStd::string(lineOfText, len);
+    m_dqConsoleBuffer.push_back(line);
 
     int nBufferSize = con_line_buffer_size;
 
@@ -2701,7 +2640,7 @@ void CXConsole::RemoveOutputPrintSink(IOutputPrintSink* inpSink)
 //////////////////////////////////////////////////////////////////////////
 void CXConsole::AddLinePlus(const char* inputStr)
 {
-    string str, tmpStr;
+    AZStd::string str, tmpStr;
 
     {
         if (!m_dqConsoleBuffer.size())
@@ -2717,13 +2656,13 @@ void CXConsole::AddLinePlus(const char* inputStr)
             str.resize(str.size() - 1);
         }
 
-        string::size_type nPos;
-        while ((nPos = str.find('\n')) != string::npos)
+        AZStd::string::size_type nPos;
+        while ((nPos = str.find('\n')) != AZStd::string::npos)
         {
             str.replace(nPos, 1, 1, ' ');
         }
 
-        while ((nPos = str.find('\r')) != string::npos)
+        while ((nPos = str.find('\r')) != AZStd::string::npos)
         {
             str.replace(nPos, 1, 1, ' ');
         }
@@ -2783,7 +2722,7 @@ void CXConsole::AddInputUTF8(const AZStd::string& textUTF8)
 //////////////////////////////////////////////////////////////////////////
 void CXConsole::ExecuteInputBuffer()
 {
-    string sTemp = m_sInputBuffer;
+    AZStd::string sTemp = m_sInputBuffer;
     if (m_sInputBuffer.empty())
     {
         return;
@@ -2814,9 +2753,7 @@ void CXConsole::RemoveInputChar(bool bBackSpace)
             const char* const pBase = m_sInputBuffer.c_str();
             const char* pCursor = pBase + m_nCursorPos;
             const char* const pEnd = pCursor;
-            Unicode::CIterator pUnicode(pCursor);
-            pUnicode--; // Remove one UCS code-point, doesn't account for combining diacritics
-            pCursor = pUnicode.GetPosition();
+            pCursor -= Utf8::Internal::sequence_length(pCursor); // Remove one UCS code-point, doesn't account for combining diacritics
             size_t length = pEnd - pCursor;
             m_sInputBuffer.erase(pCursor - pBase, length);
             m_nCursorPos -= length;
@@ -2829,9 +2766,7 @@ void CXConsole::RemoveInputChar(bool bBackSpace)
             const char* const pBase = m_sInputBuffer.c_str();
             const char* pCursor = pBase + m_nCursorPos;
             const char* const pBegin = pCursor;
-            Unicode::CIterator pUnicode(pCursor);
-            pUnicode--; // Remove one UCS code-point, doesn't account for combining diacritics
-            pCursor = pUnicode.GetPosition();
+            pCursor -= Utf8::Internal::sequence_length(pCursor); // Remove one UCS code-point, doesn't account for combining diacritics
             size_t length = pCursor - pBegin;
             m_sInputBuffer.erase(pBegin - pBase, length);
         }
@@ -2905,29 +2840,29 @@ void CXConsole::Paste()
 #if defined(AZ_PLATFORM_WINDOWS)
     if (OpenClipboard(NULL) != 0)
     {
-        wstring data;
+        AZStd::string data;
         const HANDLE wideData = GetClipboardData(CF_UNICODETEXT);
         if (wideData)
         {
             const LPCWSTR pWideData = (LPCWSTR)GlobalLock(wideData);
             if (pWideData)
             {
-                // Note: This conversion is just to make sure we discard malicious or malformed data
-                Unicode::ConvertSafe(data, pWideData);
+                AZStd::to_string(data, pWideData);
                 GlobalUnlock(wideData);
             }
         }
         CloseClipboard();
 
-        for (Unicode::CIterator it(data.begin(), data.end()); it != data.end(); ++it)
+        Utf8::Unchecked::octet_iterator end(data.end());
+        for (Utf8::Unchecked::octet_iterator it(data.begin()); it != end; ++it)
         {
-            const uint32 cp = *it;
+            const wchar_t cp = *it;
             if (cp != '\r')
             {
                 // Convert UCS code-point into UTF-8 string
-                char utf8_buf[5];
-                Unicode::Convert(utf8_buf, cp);
-                AddInputUTF8(utf8_buf);
+                AZStd::fixed_string<5> utf8_buf = {0};
+                AZStd::to_string(utf8_buf.data(), 5, { &cp, 1 });
+                AddInputUTF8(utf8_buf.c_str());
             }
         }
     }
@@ -3030,7 +2965,7 @@ void CXConsole::AddCVarsToHash(ConsoleVariablesVector::const_iterator begin, Con
     {
         // add name & variable to string. We add both since adding only the value could cause
         // many collisions with variables all having value 0 or all 1.
-        string hashStr = it->first;
+        AZStd::string hashStr = it->first;
 
         runningNameCrc32.Add(hashStr.c_str(), hashStr.length());
         hashStr += it->second->GetDataProbeString();
@@ -3195,7 +3130,7 @@ char* CXConsole::GetCheatVarAt(uint32 nOffset)
 
 
 //////////////////////////////////////////////////////////////////////////
-size_t CXConsole::GetSortedVars(const char** pszArray, size_t numItems, const char* szPrefix)
+size_t CXConsole::GetSortedVars(AZStd::vector& pszArray, const char* szPrefix)
 {
     size_t i = 0;
     size_t iPrefixLen = szPrefix ? strlen(szPrefix) : 0;
@@ -3205,7 +3140,7 @@ size_t CXConsole::GetSortedVars(const char** pszArray, size_t numItems, const ch
         ConsoleVariablesMap::const_iterator it, end = m_mapVariables.end();
         for (it = m_mapVariables.begin(); it != end; ++it)
         {
-            if (pszArray && i >= numItems)
+            if (i >= pszArray.size())
             {
                 break;
             }
@@ -3223,10 +3158,7 @@ size_t CXConsole::GetSortedVars(const char** pszArray, size_t numItems, const ch
                 continue;
             }
 
-            if (pszArray)
-            {
-                pszArray[i] = it->first;
-            }
+            pszArray[i] = it->first;
 
             i++;
         }
@@ -3237,7 +3169,7 @@ size_t CXConsole::GetSortedVars(const char** pszArray, size_t numItems, const ch
         ConsoleCommandsMap::iterator it, end = m_mapCommands.end();
         for (it = m_mapCommands.begin(); it != end; ++it)
         {
-            if (pszArray && i >= numItems)
+            if (i >= pszArray.size())
             {
                 break;
             }
@@ -3255,18 +3187,15 @@ size_t CXConsole::GetSortedVars(const char** pszArray, size_t numItems, const ch
                 continue;
             }
 
-            if (pszArray)
-            {
-                pszArray[i] = it->first.c_str();
-            }
+            pszArray[i] = it->first.c_str();
 
             i++;
         }
     }
 
-    if (i != 0 && pszArray)
+    if (i != 0)
     {
-        std::sort(pszArray, pszArray + i, less_CVar);
+        std::sort(pszArray.begin(), pszArray.end());
     }
 
     return i;
@@ -3275,22 +3204,22 @@ size_t CXConsole::GetSortedVars(const char** pszArray, size_t numItems, const ch
 //////////////////////////////////////////////////////////////////////////
 void CXConsole::FindVar(const char* substr)
 {
-    std::vector cmds;
+    AZStd::vector cmds;
     cmds.resize(GetNumVars() + m_mapCommands.size());
-    size_t cmdCount = GetSortedVars(&cmds[0], cmds.size());
+    size_t cmdCount = GetSortedVars(cmds);
 
     for (size_t i = 0; i < cmdCount; i++)
     {
-        if (CryStringUtils::stristr(cmds[i], substr))
+        if (AZ::StringFunc::Find(cmds[i], substr) != AZStd::string::npos)
         {
-            ICVar* pCvar = gEnv->pConsole->GetCVar(cmds[i]);
+            ICVar* pCvar = gEnv->pConsole->GetCVar(cmds[i].data());
             if (pCvar)
             {
                 DisplayVarValue(pCvar);
             }
             else
             {
-                ConsoleLogInputResponse("    $3%s $6(Command)", cmds[i]);
+                ConsoleLogInputResponse("    $3%.*s $6(Command)", aznumeric_cast(cmds[i].size()), cmds[i].data());
             }
         }
     }
@@ -3301,22 +3230,22 @@ const char* CXConsole::AutoComplete(const char* substr)
 {
     // following code can be optimized
 
-    std::vector cmds;
+    AZStd::vector cmds;
     cmds.resize(GetNumVars() + m_mapCommands.size());
-    size_t cmdCount = GetSortedVars(&cmds[0], cmds.size());
+    size_t cmdCount = GetSortedVars(cmds);
 
     size_t substrLen = strlen(substr);
 
     // If substring is empty return first command.
     if (substrLen == 0 && cmdCount > 0)
     {
-        return cmds[0];
+        return cmds[0].data();
     }
 
     // find next
     for (size_t i = 0; i < cmdCount; i++)
     {
-        const char* szCmd = cmds[i];
+        const char* szCmd = cmds[i].data();
         size_t cmdlen = strlen(szCmd);
         if (cmdlen >= substrLen && memcmp(szCmd, substr, substrLen) == 0)
         {
@@ -3325,32 +3254,32 @@ const char* CXConsole::AutoComplete(const char* substr)
                 i++;
                 if (i < cmdCount)
                 {
-                    return cmds[i];
+                    return cmds[i].data();
                 }
-                return cmds[i - 1];
+                return cmds[i - 1].data();
             }
-            return cmds[i];
+            return cmds[i].data();
         }
     }
 
     // then first matching case insensitive
     for (size_t i = 0; i < cmdCount; i++)
     {
-        const char* szCmd = cmds[i];
+        const char* szCmd = cmds[i].data();
 
         size_t cmdlen = strlen(szCmd);
-        if (cmdlen >= substrLen && azmemicmp(szCmd, substr, substrLen) == 0)
+        if (cmdlen >= substrLen && azstrnicmp(szCmd, substr, substrLen) == 0)
         {
             if (substrLen == cmdlen)
             {
                 i++;
                 if (i < cmdCount)
                 {
-                    return cmds[i];
+                    return cmds[i].data();
                 }
-                return cmds[i - 1];
+                return cmds[i - 1].data();
             }
-            return cmds[i];
+            return cmds[i].data();
         }
     }
 
@@ -3371,27 +3300,27 @@ void CXConsole::SetInputLine(const char* szLine)
 //////////////////////////////////////////////////////////////////////////
 const char* CXConsole::AutoCompletePrev(const char* substr)
 {
-    std::vector cmds;
+    AZStd::vector cmds;
     cmds.resize(GetNumVars() + m_mapCommands.size());
-    size_t cmdCount = GetSortedVars(&cmds[0], cmds.size());
+    size_t cmdCount = GetSortedVars(cmds);
 
     // If substring is empty return last command.
     if (strlen(substr) == 0 && cmds.size() > 0)
     {
-        return cmds[cmdCount - 1];
+        return cmds[cmdCount - 1].data();
     }
 
     for (unsigned int i = 0; i < cmdCount; i++)
     {
-        if (azstricmp(substr, cmds[i]) == 0)
+        if (azstricmp(substr, cmds[i].data()) == 0)
         {
             if (i > 0)
             {
-                return cmds[i - 1];
+                return cmds[i - 1].data();
             }
             else
             {
-                return cmds[0];
+                return cmds[0].data();
             }
         }
     }
@@ -3399,7 +3328,7 @@ const char* CXConsole::AutoCompletePrev(const char* substr)
 }
 
 //////////////////////////////////////////////////////////////////////////
-inline size_t sizeOf (const string& str)
+inline size_t sizeOf (const AZStd::string& str)
 {
     return str.capacity() + 1;
 }
diff --git a/Code/Legacy/CrySystem/XConsole.h b/Code/Legacy/CrySystem/XConsole.h
index 1fee015f22..67d9371e8d 100644
--- a/Code/Legacy/CrySystem/XConsole.h
+++ b/Code/Legacy/CrySystem/XConsole.h
@@ -42,11 +42,11 @@ enum ScrollDir
 //////////////////////////////////////////////////////////////////////////
 struct CConsoleCommand
 {
-    string m_sName;            // Console command name
-    string m_sCommand;         // lua code that is executed when this command is invoked
-    string m_sHelp;            // optional help string - can be shown in the console with " ?"
-    int    m_nFlags;           // bitmask consist of flag starting with VF_ e.g. VF_CHEAT
-    ConsoleCommandFunc m_func; // Pointer to console command.
+    AZStd::string m_sName;            // Console command name
+    AZStd::string m_sCommand;         // lua code that is executed when this command is invoked
+    AZStd::string m_sHelp;            // optional help string - can be shown in the console with " ?"
+    int    m_nFlags;                  // bitmask consist of flag starting with VF_ e.g. VF_CHEAT
+    ConsoleCommandFunc m_func;        // Pointer to console command.
 
     //////////////////////////////////////////////////////////////////////////
     CConsoleCommand()
@@ -67,7 +67,7 @@ struct CConsoleCommand
 struct CConsoleCommandArgs
     : public IConsoleCmdArgs
 {
-    CConsoleCommandArgs(string& line, std::vector& args)
+    CConsoleCommandArgs(AZStd::string& line, std::vector& args)
         : m_line(line)
         , m_args(args) {};
     virtual int GetArgCount() const { return static_cast(m_args.size()); };
@@ -87,34 +87,20 @@ struct CConsoleCommandArgs
     }
 
 private:
-    std::vector& m_args;
-    string& m_line;
+    std::vector& m_args;
+    AZStd::string& m_line;
 };
 
 
 
 struct string_nocase_lt
 {
-    bool operator()(const char* s1, const char* s2) const
+    bool operator()(const AZStd::string& s1, const AZStd::string& s2) const
     {
-        return azstricmp(s1, s2) < 0;
+        return azstricmp(s1.c_str(), s2.c_str()) < 0;
     }
 };
 
-/* - very dangerous to use with STL containers
-struct string_nocase_lt
-{
-    bool operator()( const char *s1,const char *s2 ) const
-    {
-        return _stricmp(s1,s2) < 0;
-    }
-    bool operator()( const string &s1,const string &s2 ) const
-    {
-        return _stricmp(s1.c_str(),s2.c_str()) < 0;
-    }
-};
-*/
-
 //forward declarations
 class ITexture;
 struct IRenderer;
@@ -132,7 +118,7 @@ class CXConsole
     , public AzFramework::CommandRegistrationBus::Handler
 {
 public:
-    typedef std::deque ConsoleBuffer;
+    typedef std::deque ConsoleBuffer;
     typedef ConsoleBuffer::iterator ConsoleBufferItor;
     typedef ConsoleBuffer::reverse_iterator ConsoleBufferRItor;
 
@@ -195,7 +181,7 @@ public:
     virtual bool IsOpened();
     virtual int GetNumVars();
     virtual int GetNumVisibleVars();
-    virtual size_t GetSortedVars(const char** pszArray, size_t numItems, const char* szPrefix = 0);
+    virtual size_t GetSortedVars(AZStd::vector& pszArray, const char* szPrefix = 0);
     virtual int GetNumCheatVars();
     virtual void SetCheatVarHashRange(size_t firstVar, size_t lastVar);
     virtual void CalcCheatVarHash();
@@ -262,7 +248,7 @@ protected: // ------------------------------------------------------------------
     void AddInputUTF8(const AZStd::string& textUTF8);
     void RemoveInputChar(bool bBackSpace);
     void ExecuteInputBuffer();
-    void ExecuteCommand(CConsoleCommand& cmd, string& params, bool bIgnoreDevMode = false);
+    void ExecuteCommand(CConsoleCommand& cmd, AZStd::string& params, bool bIgnoreDevMode = false);
 
     void ScrollConsole();
 
@@ -294,7 +280,7 @@ protected: // ------------------------------------------------------------------
 
     // Arguments:
     //   bFromConsole - true=from console, false=from outside
-    void SplitCommands(const char* line, std::list& split);
+    void SplitCommands(const char* line, std::list& split);
     void ExecuteStringInternal(const char* command, const bool bFromConsole, const bool bSilentMode = false);
     void ExecuteDeferredCommands();
 
@@ -320,27 +306,27 @@ private: // ----------------------------------------------------------
 
     void PostLine(const char* lineOfText, size_t len);
 
-    typedef std::map ConsoleCommandsMap;
+    typedef std::map ConsoleCommandsMap;
     typedef ConsoleCommandsMap::iterator ConsoleCommandsMapItor;
 
-    typedef std::map ConsoleBindsMap;
+    typedef std::map ConsoleBindsMap;
     typedef ConsoleBindsMap::iterator ConsoleBindsMapItor;
 
-    typedef std::map > ArgumentAutoCompleteMap;
+    typedef std::map > ArgumentAutoCompleteMap;
 
     struct SConfigVar
     {
-        string m_value;
+        AZStd::string m_value;
         bool m_partOfGroup;
     };
-    typedef std::map ConfigVars;
+    typedef std::map ConfigVars;
 
     struct SDeferredCommand
     {
-        string  command;
+        AZStd::string  command;
         bool        silentMode;
 
-        SDeferredCommand(const string& _command, bool _silentMode)
+        SDeferredCommand(const AZStd::string& _command, bool _silentMode)
             : command(_command)
             , silentMode(_silentMode)
         {}
@@ -359,10 +345,10 @@ private: // ----------------------------------------------------------
     int                                                         m_nProgress;
     int                                                         m_nProgressRange;
 
-    string                                                  m_sInputBuffer;
-    string                          m_sReturnString;
+    AZStd::string                                                  m_sInputBuffer;
+    AZStd::string                          m_sReturnString;
 
-    string                                                  m_sPrevTab;
+    AZStd::string                                                  m_sPrevTab;
     int                                                         m_nTabCount;
 
     ConsoleCommandsMap                          m_mapCommands;                      //
diff --git a/Code/Legacy/CrySystem/XConsoleVariable.cpp b/Code/Legacy/CrySystem/XConsoleVariable.cpp
index 370931088f..ab6ed0b078 100644
--- a/Code/Legacy/CrySystem/XConsoleVariable.cpp
+++ b/Code/Legacy/CrySystem/XConsoleVariable.cpp
@@ -286,7 +286,7 @@ void CXConsoleVariableCVarGroup::OnLoadConfigurationEntry_End()
 {
     if (!m_sDefaultValue.empty())
     {
-        gEnv->pConsole->LoadConfigVar(GetName(), m_sDefaultValue);
+        gEnv->pConsole->LoadConfigVar(GetName(), m_sDefaultValue.c_str());
         m_sDefaultValue.clear();
     }
 }
@@ -299,9 +299,9 @@ CXConsoleVariableCVarGroup::CXConsoleVariableCVarGroup(CXConsole* pConsole, cons
 }
 
 
-string CXConsoleVariableCVarGroup::GetDetailedInfo() const
+AZStd::string CXConsoleVariableCVarGroup::GetDetailedInfo() const
 {
-    string sRet = GetName();
+    AZStd::string sRet = GetName();
 
     sRet += " [";
 
@@ -326,11 +326,11 @@ string CXConsoleVariableCVarGroup::GetDetailedInfo() const
     sRet += "/default] [current]:\n";
 
 
-    std::map::const_iterator it, end = m_CVarGroupDefault.m_KeyValuePair.end();
+    std::map::const_iterator it, end = m_CVarGroupDefault.m_KeyValuePair.end();
 
     for (it = m_CVarGroupDefault.m_KeyValuePair.begin(); it != end; ++it)
     {
-        const string& rKey = it->first;
+        const AZStd::string& rKey = it->first;
 
         sRet += " ... ";
         sRet += rKey;
@@ -344,7 +344,7 @@ string CXConsoleVariableCVarGroup::GetDetailedInfo() const
             sRet += "/";
         }
         sRet += GetValueSpec(rKey);
-        ICVar* pCVar = gEnv->pConsole->GetCVar(rKey);
+        ICVar* pCVar = gEnv->pConsole->GetCVar(rKey.c_str());
         if (pCVar)
         {
             sRet += " [";
@@ -369,7 +369,7 @@ const char* CXConsoleVariableCVarGroup::GetHelp()
     }
 
     // create help on demand
-    string sRet = "Console variable group to apply settings to multiple variables\n\n";
+    AZStd::string sRet = "Console variable group to apply settings to multiple variables\n\n";
 
     sRet += GetDetailedInfo();
 
@@ -545,12 +545,12 @@ bool CXConsoleVariableCVarGroup::TestCVars(const SCVarGroup* pGroup, const ICVar
 bool CXConsoleVariableCVarGroup::TestCVars(const SCVarGroup& rGroup, const ICVar::EConsoleLogMode mode, const SCVarGroup* pExclude) const
 {
     bool bRet = true;
-    std::map::const_iterator it, end = rGroup.m_KeyValuePair.end();
+    std::map::const_iterator it, end = rGroup.m_KeyValuePair.end();
 
     for (it = rGroup.m_KeyValuePair.begin(); it != end; ++it)
     {
-        const string& rKey = it->first;
-        const string& rValue = it->second;
+        const AZStd::string& rKey = it->first;
+        const AZStd::string& rValue = it->second;
 
         if (pExclude)
         {
@@ -674,7 +674,7 @@ bool CXConsoleVariableCVarGroup::TestCVars(const SCVarGroup& rGroup, const ICVar
 
 
 
-string CXConsoleVariableCVarGroup::GetValueSpec(const string& sKey, const int* pSpec) const
+AZStd::string CXConsoleVariableCVarGroup::GetValueSpec(const AZStd::string& sKey, const int* pSpec) const
 {
     if (pSpec)
     {
@@ -685,7 +685,7 @@ string CXConsoleVariableCVarGroup::GetValueSpec(const string& sKey, const int* p
             const SCVarGroup* pGrp = itGrp->second;
 
             // check in spec
-            std::map::const_iterator it = pGrp->m_KeyValuePair.find(sKey);
+            std::map::const_iterator it = pGrp->m_KeyValuePair.find(sKey);
 
             if (it != pGrp->m_KeyValuePair.end())
             {
@@ -695,7 +695,7 @@ string CXConsoleVariableCVarGroup::GetValueSpec(const string& sKey, const int* p
     }
 
     // check in default
-    std::map::const_iterator it = m_CVarGroupDefault.m_KeyValuePair.find(sKey);
+    std::map::const_iterator it = m_CVarGroupDefault.m_KeyValuePair.find(sKey);
 
     if (it != m_CVarGroupDefault.m_KeyValuePair.end())
     {
@@ -708,14 +708,14 @@ string CXConsoleVariableCVarGroup::GetValueSpec(const string& sKey, const int* p
 
 void CXConsoleVariableCVarGroup::ApplyCVars(const SCVarGroup& rGroup, const SCVarGroup* pExclude)
 {
-    std::map::const_iterator it, end = rGroup.m_KeyValuePair.end();
+    std::map::const_iterator it, end = rGroup.m_KeyValuePair.end();
 
     bool wasProcessingGroup = m_pConsole->GetIsProcessingGroup();
     m_pConsole->SetProcessingGroup(true);
 
     for (it = rGroup.m_KeyValuePair.begin(); it != end; ++it)
     {
-        const string& rKey = it->first;
+        const AZStd::string& rKey = it->first;
 
         if (pExclude)
         {
@@ -728,7 +728,7 @@ void CXConsoleVariableCVarGroup::ApplyCVars(const SCVarGroup& rGroup, const SCVa
         // Useful for debugging cvar groups
         //CryLogAlways("[CVARS]: [APPLY] ([%s]) [%s] = [%s]", GetName(), rKey.c_str(), it->second.c_str());
 
-        m_pConsole->LoadConfigVar(rKey, it->second);
+        m_pConsole->LoadConfigVar(rKey.c_str(), it->second.c_str());
     }
 
     m_pConsole->SetProcessingGroup(wasProcessingGroup);
diff --git a/Code/Legacy/CrySystem/XConsoleVariable.h b/Code/Legacy/CrySystem/XConsoleVariable.h
index 0dd05cdb07..122389407f 100644
--- a/Code/Legacy/CrySystem/XConsoleVariable.h
+++ b/Code/Legacy/CrySystem/XConsoleVariable.h
@@ -16,6 +16,7 @@
 #include "SFunctor.h"
 
 class CXConsole;
+typedef AZStd::fixed_string<512> stack_string;
 
 inline int64 TextToInt64(const char* s, int64 nCurrent, bool bBitfield)
 {
@@ -178,19 +179,22 @@ public:
     CXConsoleVariableString(CXConsole* pConsole, const char* sName, const char* szDefault, int nFlags, const char* help)
         : CXConsoleVariableBase(pConsole, sName, nFlags, help)
     {
-        m_sValue = szDefault;
-        m_sDefault = szDefault;
+        if (szDefault)
+        {
+            m_sValue = szDefault;
+            m_sDefault = szDefault;
+        }
     }
 
     // interface ICVar --------------------------------------------------------------------------------------
 
-    virtual int GetIVal() const { return atoi(m_sValue); }
-    virtual int64 GetI64Val() const { return _atoi64(m_sValue); }
-    virtual float GetFVal() const { return (float)atof(m_sValue); }
-    virtual const char* GetString() const { return m_sValue; }
+    virtual int GetIVal() const { return atoi(m_sValue.c_str()); }
+    virtual int64 GetI64Val() const { return _atoi64(m_sValue.c_str()); }
+    virtual float GetFVal() const { return (float)atof(m_sValue.c_str()); }
+    virtual const char* GetString() const { return m_sValue.c_str(); }
     virtual void ResetImpl()
     {
-        Set(m_sDefault);
+        Set(m_sDefault.c_str());
     }
     virtual void Set(const char* s)
     {
@@ -219,8 +223,7 @@ public:
 
     virtual void Set(float f)
     {
-        stack_string s;
-        s.Format("%g", f);
+        stack_string s = stack_string::format("%g", f);
 
         if ((m_sValue == s.c_str()) && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
         {
@@ -233,8 +236,7 @@ public:
 
     virtual void Set(int i)
     {
-        stack_string s;
-        s.Format("%d", i);
+        stack_string s = stack_string::format("%d", i);
 
         if ((m_sValue == s.c_str()) && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
         {
@@ -248,8 +250,8 @@ public:
 
     virtual void GetMemoryUsage(class ICrySizer* pSizer) const { pSizer->AddObject(this, sizeof(*this)); }
 private: // --------------------------------------------------------------------------------------------
-    string m_sValue;                                            
-    string m_sDefault;                                                                              //!<
+    AZStd::string m_sValue;                                            
+    AZStd::string m_sDefault;                                                                              //!<
 };
 
 
@@ -296,8 +298,7 @@ public:
             return;
         }
 
-        stack_string s;
-        s.Format("%d", i);
+        stack_string s = stack_string::format("%d", i);
 
         if (m_pConsole->OnBeforeVarChange(this, s.c_str()))
         {
@@ -364,8 +365,7 @@ public:
             return;
         }
 
-        stack_string s;
-        s.Format("%lld", i);
+        stack_string s = stack_string::format("%lld", i);
 
         if (m_pConsole->OnBeforeVarChange(this, s.c_str()))
         {
@@ -442,8 +442,7 @@ public:
             return;
         }
 
-        stack_string s;
-        s.Format("%g", f);
+        stack_string s = stack_string::format("%g", f);
 
         if (m_pConsole->OnBeforeVarChange(this, s.c_str()))
         {
@@ -718,7 +717,7 @@ public:
     {
         return m_sValue.c_str();
     }
-    virtual void ResetImpl() { Set(m_sDefault); }
+    virtual void ResetImpl() { Set(m_sDefault.c_str()); }
     virtual void Set(const char* s)
     {
         if ((m_sValue == s) && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
@@ -740,14 +739,12 @@ public:
     }
     virtual void Set(float f)
     {
-        stack_string s;
-        s.Format("%g", f);
+        stack_string s = stack_string::format("%g", f);
         Set(s.c_str());
     }
     virtual void Set(int i)
     {
-        stack_string s;
-        s.Format("%d", i);
+        stack_string s = stack_string::format("%d", i);
         Set(s.c_str());
     }
     virtual int GetType() { return CVAR_STRING; }
@@ -755,8 +752,8 @@ public:
     virtual void GetMemoryUsage(class ICrySizer* pSizer) const { pSizer->AddObject(this, sizeof(*this)); }
 private: // --------------------------------------------------------------------------------------------
 
-    string m_sValue;
-    string m_sDefault;
+    AZStd::string m_sValue;
+    AZStd::string m_sDefault;
     const char*& m_userPtr;                                         //!<
 };
 
@@ -778,7 +775,7 @@ public:
 
     // Returns:
     //   part of the help string - useful to log out detailed description without additional help text
-    string GetDetailedInfo() const;
+    AZStd::string GetDetailedInfo() const;
 
     // interface ICVar -----------------------------------------------------------------------------------
 
@@ -809,7 +806,7 @@ private: // --------------------------------------------------------------------
 
     struct SCVarGroup
     {
-        std::map                         m_KeyValuePair;                 // e.g. m_KeyValuePair["r_fullscreen"]="0"
+        std::map                      m_KeyValuePair;                 // e.g. m_KeyValuePair["r_fullscreen"]="0"
         void GetMemoryUsage(class ICrySizer* pSizer) const
         {
             pSizer->AddObject(m_KeyValuePair);
@@ -818,15 +815,15 @@ private: // --------------------------------------------------------------------
 
     SCVarGroup                                                      m_CVarGroupDefault;
     typedef std::map      TCVarGroupStateMap;
-    TCVarGroupStateMap                                      m_CVarGroupStates;
-    string                                                              m_sDefaultValue;                // used by OnLoadConfigurationEntry_End()
+    TCVarGroupStateMap                                              m_CVarGroupStates;
+    AZStd::string                                                   m_sDefaultValue;                // used by OnLoadConfigurationEntry_End()
 
     void ApplyCVars(const SCVarGroup& rGroup, const SCVarGroup* pExclude = 0);
 
     // Arguments:
     //   sKey - must exist, at least in default
     //   pSpec - can be 0
-    string GetValueSpec(const string& sKey, const int* pSpec = 0) const;
+    AZStd::string GetValueSpec(const AZStd::string& sKey, const int* pSpec = 0) const;
 
     // should only be used by TestCVars()
     // Returns:
diff --git a/Code/Legacy/CrySystem/XML/ReadWriteXMLSink.h b/Code/Legacy/CrySystem/XML/ReadWriteXMLSink.h
index 2634195f64..b4dd28e813 100644
--- a/Code/Legacy/CrySystem/XML/ReadWriteXMLSink.h
+++ b/Code/Legacy/CrySystem/XML/ReadWriteXMLSink.h
@@ -36,7 +36,7 @@ public:
     ELSE_LOAD_PROPERTY(Vec3);                       \
     ELSE_LOAD_PROPERTY(int);                        \
     ELSE_LOAD_PROPERTY(float);                      \
-    ELSE_LOAD_PROPERTY(string);                     \
+    ELSE_LOAD_PROPERTY(AZStd::string);              \
     ELSE_LOAD_PROPERTY(bool);
 
 
diff --git a/Code/Legacy/CrySystem/XML/ReadXMLSink.cpp b/Code/Legacy/CrySystem/XML/ReadXMLSink.cpp
index bddc538bba..e75fed22ed 100644
--- a/Code/Legacy/CrySystem/XML/ReadXMLSink.cpp
+++ b/Code/Legacy/CrySystem/XML/ReadXMLSink.cpp
@@ -13,7 +13,7 @@
 #include 
 #include 
 
-typedef std::map IdTable;
+typedef std::map IdTable;
 struct SParseParams
 {
     IdTable idTable;
@@ -98,7 +98,7 @@ struct ReadPropertyTyped
 };
 
 template <>
-struct ReadPropertyTyped
+struct ReadPropertyTyped
 {
     static bool Load(const SParseParams& parseParams, const char* name, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink)
     {
@@ -235,8 +235,9 @@ bool LoadProperty(const SParseParams& parseParams, XmlNodeRef& definition, XmlNo
 
             dataToRead = GetISystem()->CreateXmlNode(data->getTag());
 
-            string content = childRef->getContent();
-            dataToRead->setAttr(name, content.Trim().c_str());
+            AZStd::string content = childRef->getContent();
+            AZ::StringFunc::TrimWhiteSpace(content, true, true);
+            dataToRead->setAttr(name, content.c_str());
         }
 
         if (!dataToRead->haveAttr(name))
diff --git a/Code/Legacy/CrySystem/XML/SerializeXMLReader.cpp b/Code/Legacy/CrySystem/XML/SerializeXMLReader.cpp
index da4bf66eee..e74b457191 100644
--- a/Code/Legacy/CrySystem/XML/SerializeXMLReader.cpp
+++ b/Code/Legacy/CrySystem/XML/SerializeXMLReader.cpp
@@ -15,7 +15,7 @@
 #define TAG_SCRIPT_TYPE "t"
 #define TAG_SCRIPT_NAME "n"
 
-//#define LOG_SERIALIZE_STACK(tag,szName) CryLogAlways( "<%s> %s/%s",tag,GetStackInfo(),szName );
+//#define LOG_SERIALIZE_STACK(tag,szName) CryLogAlways( "<%s> %s/%s",tag,GetStackInfo().c_str(), szName);
 #define LOG_SERIALIZE_STACK(tag, szName)
 
 CSerializeXMLReaderImpl::CSerializeXMLReaderImpl(const XmlNodeRef& nodeRef)
@@ -49,7 +49,7 @@ bool CSerializeXMLReaderImpl::Value(const char* name, int8& value)
     return bResult;
 }
 
-bool CSerializeXMLReaderImpl::Value(const char* name, string& value)
+bool CSerializeXMLReaderImpl::Value(const char* name, AZStd::string& value)
 {
     DefaultValue(value); // Set input value to default.
     if (m_nErrors)
@@ -175,10 +175,9 @@ void CSerializeXMLReaderImpl::EndGroup()
 }
 
 //////////////////////////////////////////////////////////////////////////
-const char* CSerializeXMLReaderImpl::GetStackInfo() const
+AZStd::string CSerializeXMLReaderImpl::GetStackInfo() const
 {
-    static string str;
-    str.assign("");
+    AZStd::string str;
     for (int i = 0; i < (int)m_nodeStack.size(); i++)
     {
         const char* name = m_nodeStack[i].m_node->getAttr(TAG_SCRIPT_NAME);
@@ -195,7 +194,7 @@ const char* CSerializeXMLReaderImpl::GetStackInfo() const
             str += "/";
         }
     }
-    return str.c_str();
+    return str;
 }
 
 void CSerializeXMLReaderImpl::GetMemoryUsage(ICrySizer* pSizer) const
diff --git a/Code/Legacy/CrySystem/XML/SerializeXMLReader.h b/Code/Legacy/CrySystem/XML/SerializeXMLReader.h
index c0e2059886..f87350d3fe 100644
--- a/Code/Legacy/CrySystem/XML/SerializeXMLReader.h
+++ b/Code/Legacy/CrySystem/XML/SerializeXMLReader.h
@@ -47,7 +47,7 @@ public:
         g_pXmlStrCmp = pPrevCmpFunc;
         return bReturn;
     }
-    ILINE bool GetAttr([[maybe_unused]] XmlNodeRef& node, [[maybe_unused]] const char* name, [[maybe_unused]] const string& value)
+    ILINE bool GetAttr([[maybe_unused]] XmlNodeRef& node, [[maybe_unused]] const char* name, [[maybe_unused]] const AZStd::string& value)
     {
         return false;
     }
@@ -75,7 +75,7 @@ public:
     }
 
     bool Value(const char* name, int8& value);
-    bool Value(const char* name, string& value);
+    bool Value(const char* name, AZStd::string& value);
     bool Value(const char* name, CTimeValue& value);
     bool Value(const char* name, XmlNodeRef& value);
 
@@ -88,7 +88,7 @@ public:
     void BeginGroup(const char* szName);
     bool BeginOptionalGroup(const char* szName, bool condition);
     void EndGroup();
-    const char* GetStackInfo() const;
+    AZStd::string GetStackInfo() const;
 
     void GetMemoryUsage(ICrySizer* pSizer) const;
 
@@ -172,8 +172,8 @@ private:
     void DefaultValue(Quat& v) const { v.w = 1.0f; v.v.x = 0; v.v.y = 0; v.v.z = 0; }
     void DefaultValue(CTimeValue& v) const { v.SetValue(0); }
     //void DefaultValue( char *str ) const { if (str) str[0] = 0; }
-    void DefaultValue(string& str) const { str = ""; }
-    void DefaultValue([[maybe_unused]] const string& str) const {}
+    void DefaultValue(AZStd::string& str) const { str = ""; }
+    void DefaultValue([[maybe_unused]] const AZStd::string& str) const {}
     void DefaultValue([[maybe_unused]] SNetObjectID& id) const {}
     void DefaultValue([[maybe_unused]] SSerializeString& str) const {}
     void DefaultValue(XmlNodeRef& ref) const { ref = NULL; }
diff --git a/Code/Legacy/CrySystem/XML/SerializeXMLWriter.cpp b/Code/Legacy/CrySystem/XML/SerializeXMLWriter.cpp
index e98071ace0..ce3fbcc2b1 100644
--- a/Code/Legacy/CrySystem/XML/SerializeXMLWriter.cpp
+++ b/Code/Legacy/CrySystem/XML/SerializeXMLWriter.cpp
@@ -64,14 +64,14 @@ void CSerializeXMLWriterImpl::BeginGroup(const char* szName)
     if (strchr(szName, ' ') != 0)
     {
         assert(0 && "Spaces in group name not supported");
-        CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "!Spaces in group name not supported: %s/%s", GetStackInfo(), szName);
+        CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "!Spaces in group name not supported: %s/%s", GetStackInfo().c_str(), szName);
     }
     XmlNodeRef node = CreateNodeNamed(szName);
     CurNode()->addChild(node);
     m_nodeStack.push_back(node);
     if (m_nodeStack.size() > MAX_NODE_STACK_DEPTH)
     {
-        CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "!Too Deep Node Stack:\r\n%s", GetStackInfo());
+        CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "!Too Deep Node Stack:\r\n%s", GetStackInfo().c_str());
     }
 }
 
@@ -112,10 +112,9 @@ void CSerializeXMLWriterImpl::GetMemoryUsage(ICrySizer* pSizer) const
 }
 
 //////////////////////////////////////////////////////////////////////////
-const char* CSerializeXMLWriterImpl::GetStackInfo() const
+AZStd::string CSerializeXMLWriterImpl::GetStackInfo() const
 {
-    static string str;
-    str.assign("");
+    AZStd::string str;
     for (int i = 0; i < (int)m_nodeStack.size(); i++)
     {
         const char* name = m_nodeStack[i]->getAttr(TAG_SCRIPT_NAME);
@@ -132,14 +131,13 @@ const char* CSerializeXMLWriterImpl::GetStackInfo() const
             str += "/";
         }
     }
-    return str.c_str();
+    return str;
 }
 
 //////////////////////////////////////////////////////////////////////////
-const char* CSerializeXMLWriterImpl::GetLuaStackInfo() const
+AZStd::string CSerializeXMLWriterImpl::GetLuaStackInfo() const
 {
-    static string str;
-    str.assign("");
+    AZStd::string str;
     for (int i = 0; i < (int)m_luaSaveStack.size(); i++)
     {
         const char* name = m_luaSaveStack[i];
@@ -149,5 +147,5 @@ const char* CSerializeXMLWriterImpl::GetLuaStackInfo() const
             str += ".";
         }
     }
-    return str.c_str();
+    return str;
 }
diff --git a/Code/Legacy/CrySystem/XML/SerializeXMLWriter.h b/Code/Legacy/CrySystem/XML/SerializeXMLWriter.h
index 12a2f6f151..5f3e9f2c53 100644
--- a/Code/Legacy/CrySystem/XML/SerializeXMLWriter.h
+++ b/Code/Legacy/CrySystem/XML/SerializeXMLWriter.h
@@ -77,7 +77,7 @@ private:
         if (strchr(name, ' ') != 0)
         {
             assert(0 && "Spaces in Value name not supported");
-            CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "!Spaces in Value name not supported: %s in Group %s", name, GetStackInfo());
+            CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "!Spaces in Value name not supported: %s in Group %s", name, GetStackInfo().c_str());
             return;
         }
         if (GetISystem()->IsDevMode() && CurNode())
@@ -86,7 +86,7 @@ private:
             if (CurNode()->haveAttr(name))
             {
                 assert(0);
-                CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "!Duplicate tag Value( \"%s\" ) in Group %s", name, GetStackInfo());
+                CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "!Duplicate tag Value( \"%s\" ) in Group %s", name, GetStackInfo().c_str());
             }
         }
 
@@ -115,8 +115,8 @@ private:
     }
 
     // Used for printing currebnt stack info for warnings.
-    const char* GetStackInfo() const;
-    const char* GetLuaStackInfo() const;
+    AZStd::string GetStackInfo() const;
+    AZStd::string GetLuaStackInfo() const;
 
     //////////////////////////////////////////////////////////////////////////
     // Check For Defaults.
@@ -138,7 +138,7 @@ private:
     bool IsDefaultValue(const Quat& v) const { return v.w == 1.0f && v.v.x == 0 && v.v.y == 0 && v.v.z == 0; };
     bool IsDefaultValue(const CTimeValue& v) const { return v.GetValue() == 0; };
     bool IsDefaultValue(const char* str) const { return !str || !*str; };
-    bool IsDefaultValue(const string& str) const { return str.empty(); };
+    bool IsDefaultValue(const AZStd::string& str) const { return str.empty(); };
     bool IsDefaultValue(const SSerializeString& str) const { return str.empty(); };
     //////////////////////////////////////////////////////////////////////////
 
diff --git a/Code/Legacy/CrySystem/XML/WriteXMLSource.cpp b/Code/Legacy/CrySystem/XML/WriteXMLSource.cpp
index def45f27de..c5fa3839e0 100644
--- a/Code/Legacy/CrySystem/XML/WriteXMLSource.cpp
+++ b/Code/Legacy/CrySystem/XML/WriteXMLSource.cpp
@@ -12,7 +12,7 @@
 
 #include 
 
-typedef std::map IdTable;
+typedef std::map IdTable;
 
 static bool IsOptionalWriteXML(XmlNodeRef& definition);
 
@@ -66,7 +66,7 @@ struct WritePropertyTyped
 };
 
 template <>
-struct WritePropertyTyped
+struct WritePropertyTyped
     : public WritePropertyTyped
 {
 };
diff --git a/Code/Legacy/CrySystem/XML/XMLBinaryNode.h b/Code/Legacy/CrySystem/XML/XMLBinaryNode.h
index cd9ce04e6c..34e0ca22ce 100644
--- a/Code/Legacy/CrySystem/XML/XMLBinaryNode.h
+++ b/Code/Legacy/CrySystem/XML/XMLBinaryNode.h
@@ -189,8 +189,6 @@ public:
     bool getAttr(const char* key, Vec3d& value) const;
     bool getAttr(const char* key, Quat& value) const;
     bool getAttr(const char* key, ColorB& value) const;
-    //  bool getAttr( const char *key,CString &value ) const { XmlString v; if (getAttr(key,v)) { value = (const char*)v; return true; } else return false; }
-
 
 private:
     //////////////////////////////////////////////////////////////////////////
diff --git a/Code/Legacy/CrySystem/XML/XMLBinaryReader.cpp b/Code/Legacy/CrySystem/XML/XMLBinaryReader.cpp
index bd31fb3ba4..c86c0691a9 100644
--- a/Code/Legacy/CrySystem/XML/XMLBinaryReader.cpp
+++ b/Code/Legacy/CrySystem/XML/XMLBinaryReader.cpp
@@ -32,7 +32,7 @@ const char* XMLBinary::XMLBinaryReader::GetErrorDescription() const
 
 void XMLBinary::XMLBinaryReader::SetErrorDescription(const char* text)
 {
-    cry_strcpy(m_errorDescription, text);
+    azstrcpy(m_errorDescription, AZ_ARRAY_SIZE(m_errorDescription), text);
 }
 
 
diff --git a/Code/Legacy/CrySystem/XML/XMLBinaryWriter.cpp b/Code/Legacy/CrySystem/XML/XMLBinaryWriter.cpp
index 1500717ddc..f55f792516 100644
--- a/Code/Legacy/CrySystem/XML/XMLBinaryWriter.cpp
+++ b/Code/Legacy/CrySystem/XML/XMLBinaryWriter.cpp
@@ -84,7 +84,7 @@ static void write(XMLBinary::IDataWriter* const pFile, size_t& nPosition, const
 }
 
 //////////////////////////////////////////////////////////////////////////
-bool XMLBinary::CXMLBinaryWriter::WriteNode(IDataWriter* pFile, XmlNodeRef node, bool bNeedSwapEndian, XMLBinary::IFilter* pFilter, string& error)
+bool XMLBinary::CXMLBinaryWriter::WriteNode(IDataWriter* pFile, XmlNodeRef node, bool bNeedSwapEndian, XMLBinary::IFilter* pFilter, AZStd::string& error)
 {
     error = "";
 
@@ -99,7 +99,7 @@ bool XMLBinary::CXMLBinaryWriter::WriteNode(IDataWriter* pFile, XmlNodeRef node,
     static const uint nMaxNodeCount = (NodeIndex) ~0;
     if (m_nodes.size() > nMaxNodeCount)
     {
-        error.Format("XMLBinary: Too many nodes: %d (max is %i)", m_nodes.size(), nMaxNodeCount);
+        error = AZStd::string::format("XMLBinary: Too many nodes: %zu (max is %i)", m_nodes.size(), nMaxNodeCount);
         return false;
     }
 
@@ -192,7 +192,7 @@ bool XMLBinary::CXMLBinaryWriter::WriteNode(IDataWriter* pFile, XmlNodeRef node,
     return true;
 }
 
-bool XMLBinary::CXMLBinaryWriter::CompileTables(XmlNodeRef node, XMLBinary::IFilter* pFilter, string& error)
+bool XMLBinary::CXMLBinaryWriter::CompileTables(XmlNodeRef node, XMLBinary::IFilter* pFilter, AZStd::string& error)
 {
     bool ok = CompileTablesForNode(node, -1, pFilter, error);
     ok = ok && CompileChildTable(node, pFilter, error);
@@ -200,7 +200,7 @@ bool XMLBinary::CXMLBinaryWriter::CompileTables(XmlNodeRef node, XMLBinary::IFil
 }
 
 //////////////////////////////////////////////////////////////////////////
-bool XMLBinary::CXMLBinaryWriter::CompileTablesForNode(XmlNodeRef node, int nParentIndex, XMLBinary::IFilter* pFilter, string& error)
+bool XMLBinary::CXMLBinaryWriter::CompileTablesForNode(XmlNodeRef node, int nParentIndex, XMLBinary::IFilter* pFilter, AZStd::string& error)
 {
     // Add the tag to the string table.
     int nTagStringOffset = AddString(node->getTag());
@@ -231,7 +231,7 @@ bool XMLBinary::CXMLBinaryWriter::CompileTablesForNode(XmlNodeRef node, int nPar
     static const int nMaxAttributeCount = (uint16) ~0;
     if (nAttributeCount > nMaxAttributeCount)
     {
-        error.Format("XMLBinary: Too many attributes in a node: %d (max is %i)", nAttributeCount, nMaxAttributeCount);
+        error = AZStd::string::format("XMLBinary: Too many attributes in a node: %d (max is %i)", nAttributeCount, nMaxAttributeCount);
         return false;
     }
 
@@ -261,7 +261,7 @@ bool XMLBinary::CXMLBinaryWriter::CompileTablesForNode(XmlNodeRef node, int nPar
         {
             if (++nChildCount > nMaxChildCount)
             {
-                error.Format("XMLBinary: Too many children in node '%s': %d (max is %i)", childNode->getTag(), nChildCount, nMaxChildCount);
+                error = AZStd::string::format("XMLBinary: Too many children in node '%s': %d (max is %i)", childNode->getTag(), nChildCount, nMaxChildCount);
                 return false;
             }
             if (!CompileTablesForNode(childNode, nIndex, pFilter, error))
@@ -277,7 +277,7 @@ bool XMLBinary::CXMLBinaryWriter::CompileTablesForNode(XmlNodeRef node, int nPar
 }
 
 //////////////////////////////////////////////////////////////////////////
-bool XMLBinary::CXMLBinaryWriter::CompileChildTable(XmlNodeRef node, XMLBinary::IFilter* pFilter, string& error)
+bool XMLBinary::CXMLBinaryWriter::CompileChildTable(XmlNodeRef node, XMLBinary::IFilter* pFilter, AZStd::string& error)
 {
     const int nIndex = m_nodesMap.find(node)->second; // Assume node always exist in map.
     const int nFirstChildIndex = (int)m_childs.size();
@@ -298,7 +298,7 @@ bool XMLBinary::CXMLBinaryWriter::CompileChildTable(XmlNodeRef node, XMLBinary::
     }
     if (nChildCount != nd.nChildCount)
     {
-        error.Format("XMLBinary: Internal error in CompileChildTable()");
+        error = AZStd::string::format("XMLBinary: Internal error in CompileChildTable()");
         return false;
     }
 
diff --git a/Code/Legacy/CrySystem/XML/XMLBinaryWriter.h b/Code/Legacy/CrySystem/XML/XMLBinaryWriter.h
index 7dcbe075cd..810a2268c9 100644
--- a/Code/Legacy/CrySystem/XML/XMLBinaryWriter.h
+++ b/Code/Legacy/CrySystem/XML/XMLBinaryWriter.h
@@ -25,25 +25,25 @@ namespace XMLBinary
     {
     public:
         CXMLBinaryWriter();
-        bool WriteNode(IDataWriter* pFile, XmlNodeRef node, bool bNeedSwapEndian, XMLBinary::IFilter* pFilter, string& error);
+        bool WriteNode(IDataWriter* pFile, XmlNodeRef node, bool bNeedSwapEndian, XMLBinary::IFilter* pFilter, AZStd::string & error);
 
     private:
-        bool CompileTables(XmlNodeRef node, XMLBinary::IFilter* pFilter, string& error);
+        bool CompileTables(XmlNodeRef node, XMLBinary::IFilter* pFilter, AZStd::string& error);
 
-        bool CompileTablesForNode(XmlNodeRef node, int nParentIndex, XMLBinary::IFilter* pFilter, string& error);
-        bool CompileChildTable(XmlNodeRef node, XMLBinary::IFilter* pFilter, string& error);
+        bool CompileTablesForNode(XmlNodeRef node, int nParentIndex, XMLBinary::IFilter* pFilter, AZStd::string& error);
+        bool CompileChildTable(XmlNodeRef node, XMLBinary::IFilter* pFilter, AZStd::string& error);
         int AddString(const XmlString& sString);
 
     private:
         // tables.
         typedef std::map NodesMap;
-        typedef std::map StringMap;
+        typedef std::map StringMap;
 
         std::vector m_nodes;
         NodesMap m_nodesMap;
         std::vector m_attributes;
         std::vector m_childs;
-        std::vector m_strings;
+        std::vector m_strings;
         StringMap m_stringMap;
 
         uint m_nStringDataSize;
diff --git a/Code/Legacy/CrySystem/XML/XMLPatcher.cpp b/Code/Legacy/CrySystem/XML/XMLPatcher.cpp
index f78fa93a60..03c5af92d3 100644
--- a/Code/Legacy/CrySystem/XML/XMLPatcher.cpp
+++ b/Code/Legacy/CrySystem/XML/XMLPatcher.cpp
@@ -9,7 +9,6 @@
 
 #include "CrySystem_precompiled.h"
 #include "XMLPatcher.h"
-#include "StringUtils.h"
 
 CXMLPatcher::CXMLPatcher(XmlNodeRef& patchXML)
 {
@@ -84,7 +83,7 @@ XmlNodeRef CXMLPatcher::FindPatchForFile(
             {
                 const char* pForFile = child->getAttr("forfile");
 
-                if (pForFile && CryStringUtils::stristr(pForFile, pInFileToPatch) != 0)
+                if (pForFile && AZ::StringFunc::Find(pForFile, pInFileToPatch) != AZStd::string::npos)
                 {
                     result = child;
                     break;
@@ -345,7 +344,7 @@ void CXMLPatcher::DumpXMLNodes(
     AZ::IO::HandleType inFileHandle,
     int inIndent,
     const XmlNodeRef& inNode,
-    CryFixedStringT<512>* ioTempString)
+    AZStd::fixed_string<512>* ioTempString)
 {
     auto pPak = gEnv->pCryPak;
 
@@ -353,7 +352,7 @@ void CXMLPatcher::DumpXMLNodes(
 
     INDENT();
 
-    ioTempString->Format("<%s ", inNode->getTag());
+    *ioTempString = AZStd::fixed_string<512>::format("<%s ", inNode->getTag());
 
     pPak->FWrite(ioTempString->c_str(), ioTempString->length(), inFileHandle);
 
@@ -361,7 +360,7 @@ void CXMLPatcher::DumpXMLNodes(
     {
         const char* pKey, * pVal;
         inNode->getAttributeByIndex(i, &pKey, &pVal);
-        ioTempString->Format("%s=\"%s\" ", pKey, pVal);
+        *ioTempString = AZStd::fixed_string<512>::format("%s=\"%s\" ", pKey, pVal);
         pPak->FWrite(ioTempString->c_str(), ioTempString->length(), inFileHandle);
     }
     pPak->FWrite(">\n", 2, inFileHandle);
@@ -372,7 +371,7 @@ void CXMLPatcher::DumpXMLNodes(
     }
 
     INDENT();
-    ioTempString->Format("\n", inNode->getTag());
+    *ioTempString = AZStd::fixed_string<512>::format("\n", inNode->getTag());
     pPak->FWrite(ioTempString->c_str(), ioTempString->length(), inFileHandle);
 }
 
@@ -391,12 +390,12 @@ void CXMLPatcher::DumpFiles(
         {
             pOrigFileName++;
 
-            DumpXMLFile(string().Format("PATCH_%s", pOrigFileName), inBefore);
+            DumpXMLFile(AZStd::string::format("PATCH_%s", pOrigFileName).c_str(), inBefore);
 
-            CryFixedStringT<128>        newFileName(pOrigFileName);
-            newFileName.replace(".xml", "_patched.xml");
+            AZStd::string newFileName(pOrigFileName);
+            AZ::StringFunc::Replace(newFileName, ".xml", "_patched.xml");
 
-            DumpXMLFile(string().Format("PATCH_%s", newFileName.c_str()), inAfter);
+            DumpXMLFile(AZStd::string::format("PATCH_%s", newFileName.c_str()).c_str(), inAfter);
         }
         else
         {
@@ -414,7 +413,7 @@ void CXMLPatcher::DumpXMLFile(
 
     if (fileHandle != AZ::IO::InvalidHandle)
     {
-        CryFixedStringT<512>        tempStr;
+        AZStd::fixed_string<512>        tempStr;
 
         DumpXMLNodes(fileHandle, 0, inNode, &tempStr);
 
diff --git a/Code/Legacy/CrySystem/XML/XMLPatcher.h b/Code/Legacy/CrySystem/XML/XMLPatcher.h
index 039b369723..ccc5f481eb 100644
--- a/Code/Legacy/CrySystem/XML/XMLPatcher.h
+++ b/Code/Legacy/CrySystem/XML/XMLPatcher.h
@@ -59,7 +59,7 @@ protected:
         AZ::IO::HandleType                                  inFileHandle,
         int                                                 inIndent,
         const XmlNodeRef& inNode,
-        CryFixedStringT<512>* ioTempString);
+        AZStd::fixed_string<512>* ioTempString);
     void                                                DumpFiles(
         const char* pInXMLFileName,
         const XmlNodeRef& inBefore,
diff --git a/Code/Legacy/CrySystem/XML/XmlUtils.cpp b/Code/Legacy/CrySystem/XML/XmlUtils.cpp
index 16ddc6c992..ecc10508f1 100644
--- a/Code/Legacy/CrySystem/XML/XmlUtils.cpp
+++ b/Code/Legacy/CrySystem/XML/XmlUtils.cpp
@@ -313,7 +313,7 @@ bool CXmlUtils::SaveBinaryXmlFile(const char* filename, XmlNodeRef root)
         return false;
     }
     XMLBinary::CXMLBinaryWriter writer;
-    string error;
+    AZStd::string error;
     return writer.WriteNode(&fileSink, root, false, 0, error);
 }
 
diff --git a/Code/Legacy/CrySystem/XML/xml.cpp b/Code/Legacy/CrySystem/XML/xml.cpp
index 0493a64ca8..8eb13c5247 100644
--- a/Code/Legacy/CrySystem/XML/xml.cpp
+++ b/Code/Legacy/CrySystem/XML/xml.cpp
@@ -984,13 +984,13 @@ XmlString CXmlNode::MakeValidXmlString(const XmlString& instr) const
     XmlString str = instr;
 
     // check if str contains any invalid characters
-    str.replace("&", "&");
-    str.replace("\"", """);
-    str.replace("\'", "'");
-    str.replace("<", "<");
-    str.replace(">", ">");
-    str.replace("...", ">");
-    str.replace("\n", "
");
+    AZ::StringFunc::Replace(str, "&", "&");
+    AZ::StringFunc::Replace(str, "\"", """);
+    AZ::StringFunc::Replace(str, "\'", "'");
+    AZ::StringFunc::Replace(str, "<", "<");
+    AZ::StringFunc::Replace(str, ">", ">");
+    AZ::StringFunc::Replace(str, "...", ">");
+    AZ::StringFunc::Replace(str, "\n", "
");
 
     return str;
 }
@@ -1691,8 +1691,8 @@ XmlNodeRef XmlParserImp::ParseFile(const char* filename, XmlString& errorString,
 
     char str[1024];
 
-    CryStackStringT adjustedFilename;
-    CryStackStringT pakPath;
+    AZStd::fixed_string<256> adjustedFilename;
+    AZStd::fixed_string<256> pakPath;
     if (fileSize <= 0)
     {
         CCryFile xmlFile;
@@ -1732,9 +1732,9 @@ XmlNodeRef XmlParserImp::ParseFile(const char* filename, XmlString& errorString,
             return 0;
         }
         adjustedFilename = xmlFile.GetAdjustedFilename();
-        adjustedFilename.replace('\\', '/');
+        AZStd::replace(adjustedFilename.begin(), adjustedFilename.end(), '\\', '/');
         pakPath = xmlFile.GetPakPath();
-        pakPath.replace('\\', '/');
+        AZStd::replace(pakPath.begin(), pakPath.end(), '\\', '/');
     }
 
     if (g_bEnableBinaryXmlLoading)
@@ -1761,7 +1761,7 @@ XmlNodeRef XmlParserImp::ParseFile(const char* filename, XmlString& errorString,
             // not binary XML - refuse to load if in scripts dir and not in bin xml to help reduce hacking
             // wish we could compile the text xml parser out, but too much work to get everything moved over
             static const char SCRIPTS_DIR[] = "Scripts/";
-            CryFixedStringT<32> strScripts("S");
+            AZStd::fixed_string<32> strScripts("S");
             strScripts += "c";
             strScripts += "r";
             strScripts += "i";
@@ -1770,7 +1770,7 @@ XmlNodeRef XmlParserImp::ParseFile(const char* filename, XmlString& errorString,
             strScripts += "s";
             strScripts += "/";
             // exclude files and PAKs from Mods folder
-            CryFixedStringT<8> modsStr("M");
+            AZStd::fixed_string<8> modsStr("M");
             modsStr += "o";
             modsStr += "d";
             modsStr += "s";
diff --git a/Code/Tools/AssetProcessor/native/ui/AssetTreeFilterModel.h b/Code/Tools/AssetProcessor/native/ui/AssetTreeFilterModel.h
index 05fd3d73d7..70b10e915f 100644
--- a/Code/Tools/AssetProcessor/native/ui/AssetTreeFilterModel.h
+++ b/Code/Tools/AssetProcessor/native/ui/AssetTreeFilterModel.h
@@ -10,6 +10,7 @@
 
 #if !defined(Q_MOC_RUN)
 #include 
+#include 
 #include 
 #endif
 
diff --git a/Code/Tools/AssetProcessor/native/ui/ProductAssetTreeModel.cpp b/Code/Tools/AssetProcessor/native/ui/ProductAssetTreeModel.cpp
index 6b5fa191e8..0574f00961 100644
--- a/Code/Tools/AssetProcessor/native/ui/ProductAssetTreeModel.cpp
+++ b/Code/Tools/AssetProcessor/native/ui/ProductAssetTreeModel.cpp
@@ -195,7 +195,7 @@ namespace AssetProcessor
         AZ::IO::Path currentFullFolderPath;
         const AZ::IO::PathView filename = productNamePath.Filename();
         const AZ::IO::PathView fullPathWithoutFilename = productNamePath.RemoveFilename();
-        AZStd::fixed_string currentPath;
+        AZ::IO::FixedMaxPathString currentPath;
         for (auto pathIt = fullPathWithoutFilename.begin(); pathIt != fullPathWithoutFilename.end(); ++pathIt)
         {
             currentPath = pathIt->FixedMaxPathString();
@@ -236,7 +236,7 @@ namespace AssetProcessor
         }
 
         AZStd::shared_ptr productItemData =
-            ProductAssetTreeItemData::MakeShared(&product, product.m_productName, AZStd::fixed_string(filename.Native()).c_str(), false, sourceId);
+            ProductAssetTreeItemData::MakeShared(&product, product.m_productName, AZ::IO::FixedMaxPathString(filename.Native()).c_str(), false, sourceId);
         m_productToTreeItem[product.m_productName] =
             parentItem->CreateChild(productItemData);
         m_productIdToTreeItem[product.m_productID] = m_productToTreeItem[product.m_productName];
diff --git a/Code/Tools/AssetProcessor/native/ui/SourceAssetDetailsPanel.h b/Code/Tools/AssetProcessor/native/ui/SourceAssetDetailsPanel.h
index 99610467a6..dec4749e03 100644
--- a/Code/Tools/AssetProcessor/native/ui/SourceAssetDetailsPanel.h
+++ b/Code/Tools/AssetProcessor/native/ui/SourceAssetDetailsPanel.h
@@ -10,6 +10,7 @@
 
 #if !defined(Q_MOC_RUN)
 #include "AssetDetailsPanel.h"
+#include 
 #include 
 #endif
 
diff --git a/Code/Tools/AssetProcessor/native/ui/SourceAssetTreeModel.cpp b/Code/Tools/AssetProcessor/native/ui/SourceAssetTreeModel.cpp
index 6a5e53eb75..1fcdd62cf7 100644
--- a/Code/Tools/AssetProcessor/native/ui/SourceAssetTreeModel.cpp
+++ b/Code/Tools/AssetProcessor/native/ui/SourceAssetTreeModel.cpp
@@ -94,7 +94,7 @@ namespace AssetProcessor
         AZ::IO::Path currentFullFolderPath(AZ::IO::PosixPathSeparator);
         const AZ::IO::FixedMaxPath filename = fullPath.Filename();
         fullPath.RemoveFilename();
-        AZStd::fixed_string currentPath;
+        AZ::IO::FixedMaxPathString currentPath;
         for (auto pathIt = fullPath.begin(); pathIt != fullPath.end(); ++pathIt)
         {
             currentPath = pathIt->FixedMaxPathString();
@@ -125,7 +125,7 @@ namespace AssetProcessor
         }
 
         m_sourceToTreeItem[source.m_sourceName] =
-            parentItem->CreateChild(SourceAssetTreeItemData::MakeShared(&source, &scanFolder, source.m_sourceName, AZStd::fixed_string(filename.Native()).c_str(), false));
+            parentItem->CreateChild(SourceAssetTreeItemData::MakeShared(&source, &scanFolder, source.m_sourceName, AZ::IO::FixedMaxPathString(filename.Native()).c_str(), false));
         m_sourceIdToTreeItem[source.m_sourceID] = m_sourceToTreeItem[source.m_sourceName];
         if (!modelIsResetting)
         {
diff --git a/Code/Tools/CrashHandler/Support/include/CrashSupport.h b/Code/Tools/CrashHandler/Support/include/CrashSupport.h
index 9932d950d4..e0bec5818b 100644
--- a/Code/Tools/CrashHandler/Support/include/CrashSupport.h
+++ b/Code/Tools/CrashHandler/Support/include/CrashSupport.h
@@ -11,6 +11,8 @@
 #pragma once
 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -23,30 +25,24 @@
 namespace CrashHandler
 {
     std::string GetTimeString();
-    void GetExecutablePathA(char* pathBuffer, int& bufferSize);
-    void GetExecutablePathW(wchar_t* pathBuffer, int& bufferSize);
     void GetTimeInfo(tm& curTime);
 
-    template 
-    inline void GetExecutablePath(T& returnPath)
+    inline void GetExecutablePath(std::string& returnPath)
     {
         char currentFileName[CRASH_HANDLER_MAX_PATH_LEN] = { 0 };
-        int bufferLen{ CRASH_HANDLER_MAX_PATH_LEN };
-        GetExecutablePathA(currentFileName, bufferLen);
+        AZ::Utils::GetExecutablePath(currentFileName, CRASH_HANDLER_MAX_PATH_LEN);
 
         returnPath = currentFileName;
         std::replace(returnPath.begin(), returnPath.end(), '\\', '/');
     }
 
-    template <>
-    inline void GetExecutablePath(std::wstring& returnPath)
+    inline void GetExecutablePath(std::wstring& returnPathW)
     {
-        wchar_t currentFileName[CRASH_HANDLER_MAX_PATH_LEN] = { 0 };
-        int bufferLen{ CRASH_HANDLER_MAX_PATH_LEN };
-        GetExecutablePathW(currentFileName, bufferLen);
-
-        returnPath = currentFileName;
-        std::replace(returnPath.begin(), returnPath.end(), '\\', '/');
+        std::string returnPath;
+        GetExecutablePath(returnPath);
+        wchar_t currentFileNameW[CRASH_HANDLER_MAX_PATH_LEN] = { 0 };
+        AZStd::to_wstring(currentFileNameW, CRASH_HANDLER_MAX_PATH_LEN, { returnPath.c_str(), returnPath.size() });
+        returnPathW = currentFileNameW;
     }
 
     template
diff --git a/Code/Tools/CrashHandler/Support/platform/win/CrashSupport_win.cpp b/Code/Tools/CrashHandler/Support/platform/win/CrashSupport_win.cpp
index 3933b5ea91..6010ac8e17 100644
--- a/Code/Tools/CrashHandler/Support/platform/win/CrashSupport_win.cpp
+++ b/Code/Tools/CrashHandler/Support/platform/win/CrashSupport_win.cpp
@@ -10,13 +10,14 @@
 #include 
 
 #include 
+#include 
 #include 
 
 namespace CrashHandler
 {
-    void GetExecutablePathA(char* pathBuffer, int& bufferSize)
+    void GetExecutablePath(char* pathBuffer, int& bufferSize)
     {
-        GetModuleFileNameA(nullptr, pathBuffer, bufferSize);
+        AZ::Utils::GetExecutablePath(pathBuffer, bufferSize);
     }
 
     void GetExecutablePathW(wchar_t* pathBuffer, int& bufferSize)
diff --git a/Code/Tools/GridHub/GridHub/gridhub.cpp b/Code/Tools/GridHub/GridHub/gridhub.cpp
index f6f0988022..24dd440411 100644
--- a/Code/Tools/GridHub/GridHub/gridhub.cpp
+++ b/Code/Tools/GridHub/GridHub/gridhub.cpp
@@ -358,17 +358,11 @@ GridHubComponent::GridHubComponent()
     m_isLogToFile = false;
     
 #ifdef AZ_PLATFORM_WINDOWS
-    TCHAR name[MAX_COMPUTERNAME_LENGTH + 1];
+    wchar_t name[MAX_COMPUTERNAME_LENGTH + 1];
     DWORD dwCompNameLen = AZ_ARRAY_SIZE(name);
-    if ( GetComputerName(name, &dwCompNameLen) != 0 ) 
+    if (GetComputerName(name, &dwCompNameLen) != 0) 
     {
-#ifdef _UNICODE
-        char c[MAX_COMPUTERNAME_LENGTH + 1];
-        wcstombs(c, name, AZ_ARRAY_SIZE(c));
-        m_hubName = c;
-#else
-        m_hubName = name;
-#endif
+        AZStd::to_string(m_hubName, name);
     }
     else
 #endif
@@ -549,7 +543,7 @@ GridHubComponent::OnMemberJoined([[maybe_unused]] GridMate::GridSession* session
     case AZ::PlatformID::PLATFORM_WINDOWS_64:
     case AZ::PlatformID::PLATFORM_APPLE_MAC:
         {
-            GridMate::string localMachineName = GridMate::Utils::GetMachineAddress();
+            AZStd::string localMachineName = GridMate::Utils::GetMachineAddress();
             if( member->GetMachineName() == localMachineName )
             {
                 ExternalProcessMonitor mi;
@@ -635,7 +629,7 @@ bool GridHubComponent::StartSession(bool isRestarting)
     AZ_Assert(GridMate::HasGridMateService(m_gridMate), "Failed to start multiplayer service for LAN!");
 
     // if we get an address 169.X.X.X (AZCP is NOT ready) or 127.0.0.1 when network is not ready
-    GridMate::string machineIP = GridMate::Utils::GetMachineAddress();
+    AZStd::string machineIP = GridMate::Utils::GetMachineAddress();
     if( machineIP == "127.0.0.1" || machineIP.compare(0,4,"169.") == 0 )
     {
         AZ_Warning("GridHub", false, "\nCurrent IP %s might be invalid.\n",machineIP.c_str());
diff --git a/Code/Tools/GridHub/GridHub/gridhub.hxx b/Code/Tools/GridHub/GridHub/gridhub.hxx
index 468cf525a0..849dbb92e1 100644
--- a/Code/Tools/GridHub/GridHub/gridhub.hxx
+++ b/Code/Tools/GridHub/GridHub/gridhub.hxx
@@ -141,7 +141,7 @@ public:
     /// Callback that notifies the title when a session will be left. session pointer is NOT valid after the callback returns.
     void OnSessionDelete(GridMate::GridSession* session) override;
     /// Called when a session error occurs.
-    void OnSessionError(GridMate::GridSession* session, const GridMate::string& errorMsg ) { (void)session; (void)errorMsg; }
+    void OnSessionError(GridMate::GridSession* session, const AZStd::string& errorMsg ) { (void)session; (void)errorMsg; }
     /// Called when the actual game(match) starts
     void OnSessionStart(GridMate::GridSession* session) { (void)session; }
     /// Called when the actual game(match) ends
diff --git a/Code/Tools/GridHub/GridHub/main.cpp b/Code/Tools/GridHub/GridHub/main.cpp
index f02906e0d4..bfb82efd0d 100644
--- a/Code/Tools/GridHub/GridHub/main.cpp
+++ b/Code/Tools/GridHub/GridHub/main.cpp
@@ -16,7 +16,6 @@
 #include 
 #include 
 #include 
-#include 
 #endif
 
 #include "gridhub.hxx"
@@ -39,6 +38,7 @@ AZ_POP_DISABLE_WARNING
 #include 
 #include 
 #include 
+#include 
 
 #ifdef AZ_PLATFORM_WINDOWS
 #include 
@@ -53,9 +53,9 @@ AZ_POP_DISABLE_WARNING
 #endif
 
 #ifdef AZ_PLATFORM_WINDOWS
-#define GRIDHUB_TSR_SUFFIX _T("_copyapp_")
-#define GRIDHUB_TSR_NAME _T("GridHub_copyapp_.exe")
-#define GRIDHUB_IMAGE_NAME _T("GridHub.exe")
+#define GRIDHUB_TSR_SUFFIX L"_copyapp_"
+#define GRIDHUB_TSR_NAME L"GridHub_copyapp_.exe"
+#define GRIDHUB_IMAGE_NAME L"GridHub.exe"
 #else
 #define GRIDHUB_TSR_SUFFIX "_copyapp_"
 #define GRIDHUB_TSR_NAME "GridHub_copyapp_"
@@ -191,7 +191,7 @@ protected:
          specializations.Append("gridhub");
      }
 
-    QString         m_originalExeFileName;
+     QString        m_originalExeFileName;
      QDateTime      m_originalExeLastModified;
      bool           m_monitorForExeChanges;
      bool           m_needToRelaunch;
@@ -305,22 +305,22 @@ public:
     {
 #ifdef AZ_PLATFORM_WINDOWS
         HRESULT hres;
-        TCHAR startupFolder[MAX_PATH] = {0};
-        TCHAR fullLinkName[MAX_PATH] = {0};
+        wchar_t startupFolder[MAX_PATH] = {0};
+        wchar_t fullLinkName[MAX_PATH] = {0};
 
         LPITEMIDLIST pidlFolder = NULL;
         hres = SHGetFolderLocation(0,/*CSIDL_COMMON_STARTUP all users required admin access*/CSIDL_STARTUP,NULL,0,&pidlFolder);
         if (SUCCEEDED(hres))
         {
-            if( SHGetPathFromIDList(pidlFolder,startupFolder) )
+            if (SHGetPathFromIDList(pidlFolder, startupFolder))
             {
-                _tcscat_s(fullLinkName,startupFolder);
-                _tcscat_s(fullLinkName,"\\Amazon Grid Hub.lnk");
+                wcscat_s(fullLinkName, startupFolder);
+                wcscat_s(fullLinkName, L"\\Amazon Grid Hub.lnk");
             }
             CoTaskMemFree(pidlFolder);
         }
 
-        if( moduleFilename.isEmpty() || _tcslen(fullLinkName) == 0 )
+        if( moduleFilename.isEmpty() || wcslen(fullLinkName) == 0 )
             return;
 
         // for development, never autoadd to startup
@@ -342,8 +342,8 @@ public:
                 IPersistFile* ppf;
 
                 // Set the path to the shortcut target and add the description.
-                psl->SetPath(moduleFilename.toUtf8().data());
-                psl->SetDescription("Amazon Grid Hub");
+                psl->SetPath(moduleFilename.toStdWString().c_str());
+                psl->SetDescription(L"Amazon Grid Hub");
 
                 // Query IShellLink for the IPersistFile interface, used for saving the
                 // shortcut in persistent storage.
@@ -351,16 +351,8 @@ public:
 
                 if (SUCCEEDED(hres))
                 {
-                    WCHAR wsz[MAX_PATH];
-
-                    // Ensure that the string is Unicode.
-                    MultiByteToWideChar(CP_ACP, 0, fullLinkName, -1, wsz, MAX_PATH);
-
-                    // Add code here to check return value from MultiByteWideChar
-                    // for success.
-
                     // Save the link by calling IPersistFile::Save.
-                    hres = ppf->Save(wsz, TRUE);
+                    hres = ppf->Save(fullLinkName, TRUE);
                     ppf->Release();
                 }
                 psl->Release();
@@ -412,13 +404,17 @@ GridHubApplication::Create(const Descriptor& descriptor, const StartupParameters
     {
         bool isError = false;
 #ifdef AZ_PLATFORM_WINDOWS
-        TCHAR originalExeFileName[MAX_PATH];
-        if (GetModuleFileName(NULL, originalExeFileName, AZ_ARRAY_SIZE(originalExeFileName)))
+        char originalExeFileName[MAX_PATH];
+        if (AZ::Utils::GetExecutablePath(originalExeFileName, AZ_ARRAY_SIZE(originalExeFileName)).m_pathStored == AZ::Utils::ExecutablePathResult::Success)
         {
-            PathRemoveFileSpec(originalExeFileName);
-            PathAppend(originalExeFileName, GRIDHUB_IMAGE_NAME);
+            wchar_t originalExeFileNameW[MAX_PATH];
+            AZStd::to_wstring(originalExeFileNameW, MAX_PATH, originalExeFileName);
+            PathRemoveFileSpec(originalExeFileNameW);
+            PathAppend(originalExeFileNameW, GRIDHUB_IMAGE_NAME);
 
-            m_originalExeFileName = originalExeFileName;
+            AZStd::string finalExeFileName;
+            AZStd::to_string(finalExeFileName, originalExeFileNameW);
+            m_originalExeFileName = finalExeFileName.c_str();
 
             m_originalExeLastModified = QFileInfo(m_originalExeFileName).lastModified();
         }
@@ -489,18 +485,20 @@ void GridHubApplication::RegisterCoreComponents()
 void CopyAndRun(bool failSilently)
 {
 #ifdef AZ_PLATFORM_WINDOWS
-    TCHAR myFileName[MAX_PATH] = { _T(0) };
-    if (GetModuleFileName(NULL, myFileName, MAX_PATH ))
+    char myFileName[MAX_PATH] = { 0 };
+    if (AZ::Utils::GetExecutablePath(myFileName, MAX_PATH).m_pathStored == AZ::Utils::ExecutablePathResult::Success)
     {
-        TCHAR sourceProcPath[MAX_PATH] = { _T(0) };
-        TCHAR targetProcPath[MAX_PATH] = { _T(0) };
-        TCHAR procDrive[MAX_PATH] = { _T(0) };
-        TCHAR procDir[MAX_PATH] = { _T(0) };
-        TCHAR procFname[MAX_PATH] = { _T(0) };
-        TCHAR procExt[MAX_PATH] = { _T(0) };
-        _tsplitpath_s(myFileName, procDrive, procDir, procFname, procExt);
-        _tmakepath_s(sourceProcPath, procDrive, procDir, GRIDHUB_IMAGE_NAME, NULL);
-        _tmakepath_s(targetProcPath, procDrive, procDir, GRIDHUB_TSR_NAME, NULL);
+        wchar_t myFileNameW[MAX_PATH] = { 0 };
+        AZStd::to_wstring(myFileNameW, MAX_PATH, myFileName);
+        wchar_t sourceProcPath[MAX_PATH] = { 0 };
+        wchar_t targetProcPath[MAX_PATH] = { 0 };
+        wchar_t procDrive[MAX_PATH] = { 0 };
+        wchar_t procDir[MAX_PATH] = { 0 };
+        wchar_t procFname[MAX_PATH] = { 0 };
+        wchar_t procExt[MAX_PATH] = { 0 };
+        _wsplitpath_s(myFileNameW, procDrive, procDir, procFname, procExt);
+        _wmakepath_s(sourceProcPath, procDrive, procDir, GRIDHUB_IMAGE_NAME, NULL);
+        _wmakepath_s(targetProcPath, procDrive, procDir, GRIDHUB_TSR_NAME, NULL);
         if (CopyFileEx(sourceProcPath, targetProcPath, NULL, NULL, NULL, 0))
         {
             STARTUPINFO si;
@@ -527,9 +525,9 @@ void CopyAndRun(bool failSilently)
         {
             if (!failSilently)
             {
-                TCHAR errorMsg[1024] = { _T(0) };
-                _stprintf_s(errorMsg, _T("Failed to copy GridHub. Make sure that %s%s is writable!"), procFname, procExt);
-                MessageBox(NULL, errorMsg, NULL, MB_ICONSTOP|MB_OK);
+                wchar_t errorMsg[1024] = { 0 };
+                swprintf_s(errorMsg, L"Failed to copy GridHub. Make sure that %s%s is writable!", procFname, procExt);
+                MessageBoxW(NULL, errorMsg, NULL, MB_ICONSTOP|MB_OK);
             }
         }
     }
@@ -565,16 +563,18 @@ void CopyAndRun(bool failSilently)
 void RelaunchImage()
 {
 #ifdef AZ_PLATFORM_WINDOWS
-    TCHAR myFileName[MAX_PATH] = { _T(0) };
-    if (GetModuleFileName(NULL, myFileName, MAX_PATH))
+    char myFileName[MAX_PATH] = { 0 };
+    if (AZ::Utils::GetExecutablePath(myFileName, MAX_PATH).m_pathStored == AZ::Utils::ExecutablePathResult::Success)
     {
-        TCHAR targetProcPath[MAX_PATH] = { _T(0) };
-        TCHAR procDrive[MAX_PATH] = { _T(0) };
-        TCHAR procDir[MAX_PATH] = { _T(0) };
-        TCHAR procFname[MAX_PATH] = { _T(0) };
-        TCHAR procExt[MAX_PATH] = { _T(0) };
-        _tsplitpath_s(myFileName, procDrive, procDir, procFname, procExt);
-        _tmakepath_s(targetProcPath, procDrive, procDir, GRIDHUB_IMAGE_NAME, NULL);
+        wchar_t myFileNameW[MAX_PATH] = { 0 };
+        AZStd::to_wstring(myFileNameW, MAX_PATH, myFileName);
+        wchar_t targetProcPath[MAX_PATH] = { 0 };
+        wchar_t procDrive[MAX_PATH] = { 0 };
+        wchar_t procDir[MAX_PATH] = { 0 };
+        wchar_t procFname[MAX_PATH] = { 0 };
+        wchar_t procExt[MAX_PATH] = { 0 };
+        _wsplitpath_s(myFileNameW, procDrive, procDir, procFname, procExt);
+        _wmakepath_s(targetProcPath, procDrive, procDir, GRIDHUB_IMAGE_NAME, NULL);
 
         STARTUPINFO si;
         PROCESS_INFORMATION pi;
@@ -635,8 +635,8 @@ int main(int argc, char *argv[])
     {
 
 #ifdef AZ_PLATFORM_WINDOWS
-        TCHAR exeFileName[MAX_PATH];
-        if( GetModuleFileName(NULL,exeFileName,AZ_ARRAY_SIZE(exeFileName)) )
+        char exeFileName[MAX_PATH];
+        if (AZ::Utils::GetExecutablePath(exeFileName, AZ_ARRAY_SIZE(exeFileName)).m_pathStored == AZ::Utils::ExecutablePathResult::Success)
 #elif defined AZ_PLATFORM_LINUX
         //KDAB_TODO
         char exeFileName[MAXPATHLEN];
@@ -661,7 +661,7 @@ int main(int argc, char *argv[])
         {
 #ifdef AZ_PLATFORM_WINDOWS
             // Create a OS named mutex while the OS is running
-            HANDLE hInstanceMutex = CreateMutex(NULL,TRUE,"Global\\GridHub-Instance");
+            HANDLE hInstanceMutex = CreateMutex(NULL, TRUE, L"Global\\GridHub-Instance");
             AZ_Assert(hInstanceMutex!=NULL,"Failed to create OS mutex [GridHub-Instance]\n");
             if( hInstanceMutex != NULL && GetLastError() == ERROR_ALREADY_EXISTS)
             {
diff --git a/Code/Tools/ProjectManager/Source/Application.cpp b/Code/Tools/ProjectManager/Source/Application.cpp
index bdcb59897b..c977698152 100644
--- a/Code/Tools/ProjectManager/Source/Application.cpp
+++ b/Code/Tools/ProjectManager/Source/Application.cpp
@@ -56,8 +56,6 @@ namespace O3DE::ProjectManager
         QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
         QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
 
-        QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedStates));
-
         QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
         AzQtComponents::Utilities::HandleDpiAwareness(AzQtComponents::Utilities::SystemDpiAware);
 
diff --git a/Code/Tools/RemoteConsole/Core/RemoteConsoleCore.cpp b/Code/Tools/RemoteConsole/Core/RemoteConsoleCore.cpp
index d4ef5b3ba8..b6a7898ca2 100644
--- a/Code/Tools/RemoteConsole/Core/RemoteConsoleCore.cpp
+++ b/Code/Tools/RemoteConsole/Core/RemoteConsoleCore.cpp
@@ -446,10 +446,10 @@ bool SRemoteClient::SendPackage(const char* buffer, int size)
 /////////////////////////////////////////////////////////////////////////////////////////////
 void SRemoteClient::FillAutoCompleteList(AZStd::vector& list)
 {
-    AZStd::vector cmds;
-    size_t count = gEnv->pConsole->GetSortedVars(nullptr, 0);
+    AZStd::vector cmds;
+    size_t count = gEnv->pConsole->GetSortedVars(cmds);
     cmds.resize(count);
-    count = gEnv->pConsole->GetSortedVars(&cmds[0], count);
+    count = gEnv->pConsole->GetSortedVars(cmds);
     for (size_t i = 0; i < count; ++i)
     {
         list.push_back(cmds[i]);
diff --git a/Code/Tools/SceneAPI/SDKWrapper/AssImpMaterialWrapper.cpp b/Code/Tools/SceneAPI/SDKWrapper/AssImpMaterialWrapper.cpp
index c24577a6de..8ea25a2ff0 100644
--- a/Code/Tools/SceneAPI/SDKWrapper/AssImpMaterialWrapper.cpp
+++ b/Code/Tools/SceneAPI/SDKWrapper/AssImpMaterialWrapper.cpp
@@ -194,7 +194,7 @@ namespace AZ
         AZStd::string AssImpMaterialWrapper::GetTextureFileName(MaterialMapType textureType) const
         {
             /// Engine currently doesn't support multiple textures. Right now we only use first texture.
-            int textureIndex = 0;
+            unsigned int textureIndex = 0;
             aiString absTexturePath;
             switch (textureType)
             {
diff --git a/Code/Tools/SceneAPI/SDKWrapper/NodeWrapper.h b/Code/Tools/SceneAPI/SDKWrapper/NodeWrapper.h
index e011bf213f..bef3cf0db4 100644
--- a/Code/Tools/SceneAPI/SDKWrapper/NodeWrapper.h
+++ b/Code/Tools/SceneAPI/SDKWrapper/NodeWrapper.h
@@ -7,6 +7,7 @@
  */
 #pragma once
 #include 
+#include 
 
 struct aiNode;
 
diff --git a/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpAnimationImporter.cpp b/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpAnimationImporter.cpp
index aadb834aa9..150a50138e 100644
--- a/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpAnimationImporter.cpp
+++ b/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpAnimationImporter.cpp
@@ -445,11 +445,11 @@ namespace AZ
 
                 AZStd::unordered_set boneList;
 
-                for (int meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex)
+                for (unsigned int meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex)
                 {
                     aiMesh* mesh = scene->mMeshes[meshIndex];
 
-                    for (int boneIndex = 0; boneIndex < mesh->mNumBones; ++boneIndex)
+                    for (unsigned int boneIndex = 0; boneIndex < mesh->mNumBones; ++boneIndex)
                     {
                         aiBone* bone = mesh->mBones[boneIndex];
 
@@ -612,10 +612,10 @@ namespace AZ
                 ValueToKeyDataMap valueToKeyDataMap;
                 // Key time can be less than zero, normalize to have zero be the lowest time.
                 double keyOffset = 0;
-                for (int keyIdx = 0; keyIdx < meshMorphAnim->mNumKeys; keyIdx++)
+                for (unsigned int keyIdx = 0; keyIdx < meshMorphAnim->mNumKeys; keyIdx++)
                 {
                     aiMeshMorphKey& key = meshMorphAnim->mKeys[keyIdx];
-                    for (int valIdx = 0; valIdx < key.mNumValuesAndWeights; ++valIdx)
+                    for (unsigned int valIdx = 0; valIdx < key.mNumValuesAndWeights; ++valIdx)
                     {
                         int currentValue = key.mValues[valIdx];
                         KeyData thisKey(key.mWeights[valIdx], key.mTime);
diff --git a/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpBitangentStreamImporter.cpp b/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpBitangentStreamImporter.cpp
index 51e0147599..b9b9af1e65 100644
--- a/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpBitangentStreamImporter.cpp
+++ b/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpBitangentStreamImporter.cpp
@@ -89,11 +89,11 @@ namespace AZ
 
                 bitangentStream->SetGenerationMethod(AZ::SceneAPI::DataTypes::TangentGenerationMethod::FromSourceScene);
                 bitangentStream->ReserveContainerSpace(vertexCount);
-                for (int sdkMeshIndex = 0; sdkMeshIndex < currentNode->mNumMeshes; ++sdkMeshIndex)
+                for (unsigned int sdkMeshIndex = 0; sdkMeshIndex < currentNode->mNumMeshes; ++sdkMeshIndex)
                 {
                     const aiMesh* mesh = scene->mMeshes[currentNode->mMeshes[sdkMeshIndex]];
 
-                    for (int v = 0; v < mesh->mNumVertices; ++v)
+                    for (unsigned int v = 0; v < mesh->mNumVertices; ++v)
                     {
                         if (!mesh->HasTangentsAndBitangents())
                         {
diff --git a/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpBlendShapeImporter.cpp b/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpBlendShapeImporter.cpp
index d139a1c86c..e8eb5ecf68 100644
--- a/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpBlendShapeImporter.cpp
+++ b/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpBlendShapeImporter.cpp
@@ -85,7 +85,7 @@ namespace AZ
                 {
                     int sceneMeshIdx = context.m_sourceNode.GetAssImpNode()->mMeshes[nodeMeshIdx];
                     const aiMesh* aiMesh = context.m_sourceScene.GetAssImpScene()->mMeshes[sceneMeshIdx];
-                    for (int animIdx = 0; animIdx < aiMesh->mNumAnimMeshes; animIdx++)
+                    for (unsigned int animIdx = 0; animIdx < aiMesh->mNumAnimMeshes; animIdx++)
                     {
                         aiAnimMesh* aiAnimMesh = aiMesh->mAnimMeshes[animIdx];
                         animToMeshToAnimMeshIndices[aiAnimMesh->mName.C_Str()].emplace_back(nodeMeshIdx, animIdx);
@@ -130,7 +130,7 @@ namespace AZ
                         blendShapeData->ReserveData(
                             aiAnimMesh->mNumVertices, aiAnimMesh->HasTangentsAndBitangents(), uvSetUsedFlags, colorSetUsedFlags);
 
-                        for (int vertIdx = 0; vertIdx < aiAnimMesh->mNumVertices; ++vertIdx)
+                        for (unsigned int vertIdx = 0; vertIdx < aiAnimMesh->mNumVertices; ++vertIdx)
                         {
                             AZ::Vector3 vertex(AssImpSDKWrapper::AssImpTypeConverter::ToVector3(aiAnimMesh->mVertices[vertIdx]));
                    
@@ -184,7 +184,7 @@ namespace AZ
                         }
 
                         // aiAnimMesh just has a list of positions for vertices. The face indices are on the original mesh.
-                        for (int faceIdx = 0; faceIdx < aiMesh->mNumFaces; ++faceIdx)
+                        for (unsigned int faceIdx = 0; faceIdx < aiMesh->mNumFaces; ++faceIdx)
                         {
                             aiFace face = aiMesh->mFaces[faceIdx];
                             DataTypes::IBlendShapeData::Face blendFace;
@@ -199,7 +199,7 @@ namespace AZ
                                     face.mNumIndices);
                                 continue;
                             }
-                            for (int idx = 0; idx < face.mNumIndices; ++idx)
+                            for (unsigned int idx = 0; idx < face.mNumIndices; ++idx)
                             {
                                 blendFace.vertexIndex[idx] = face.mIndices[idx] + vertexOffset;
                             }
diff --git a/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpColorStreamImporter.cpp b/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpColorStreamImporter.cpp
index 438e56e8ad..4043f529df 100644
--- a/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpColorStreamImporter.cpp
+++ b/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpColorStreamImporter.cpp
@@ -56,7 +56,7 @@ namespace AZ
                 const aiScene* scene = context.m_sourceScene.GetAssImpScene();
 
                 // This node has at least one mesh, verify that the color channel counts are the same for all meshes.
-                const int expectedColorChannels = scene->mMeshes[currentNode->mMeshes[0]]->GetNumColorChannels();
+                const unsigned int expectedColorChannels = scene->mMeshes[currentNode->mMeshes[0]]->GetNumColorChannels();
                 const bool allMeshesHaveSameNumberOfColorChannels =
                     AZStd::all_of(currentNode->mMeshes + 1, currentNode->mMeshes + currentNode->mNumMeshes, [scene, expectedColorChannels](const unsigned int meshIndex)
                         {
@@ -80,17 +80,16 @@ namespace AZ
                 const uint64_t vertexCount = GetVertexCountForAllMeshesOnNode(*currentNode, *scene);
 
                 Events::ProcessingResultCombiner combinedVertexColorResults;
-                for (int colorSetIndex = 0; colorSetIndex < expectedColorChannels; ++colorSetIndex)
+                for (unsigned int colorSetIndex = 0; colorSetIndex < expectedColorChannels; ++colorSetIndex)
                 {
-
                     AZStd::shared_ptr vertexColors =
                         AZStd::make_shared();
                     vertexColors->ReserveContainerSpace(vertexCount);
 
-                    for (int sdkMeshIndex = 0; sdkMeshIndex < currentNode->mNumMeshes; ++sdkMeshIndex)
+                    for (unsigned int sdkMeshIndex = 0; sdkMeshIndex < currentNode->mNumMeshes; ++sdkMeshIndex)
                     {
                         const aiMesh* mesh = scene->mMeshes[currentNode->mMeshes[sdkMeshIndex]];
-                        for (int v = 0; v < mesh->mNumVertices; ++v)
+                        for (unsigned int v = 0; v < mesh->mNumVertices; ++v)
                         {
                             if (colorSetIndex < mesh->GetNumColorChannels())
                             {
diff --git a/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpImporterUtilities.cpp b/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpImporterUtilities.cpp
index d416324240..c61ab147a8 100644
--- a/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpImporterUtilities.cpp
+++ b/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpImporterUtilities.cpp
@@ -105,7 +105,7 @@ namespace AZ
                         nodesWithNoMesh.emplace(currentNode->mName.C_Str());
                     }
 
-                    for (int childIndex = 0; childIndex < currentNode->mNumChildren; ++childIndex)
+                    for (unsigned int childIndex = 0; childIndex < currentNode->mNumChildren; ++childIndex)
                     {
                         queue.push(currentNode->mChildren[childIndex]);
                     }
@@ -171,7 +171,7 @@ namespace AZ
                     return true;
                 }
 
-                for (int childIndex = 0; childIndex < node->mNumChildren; ++childIndex)
+                for (unsigned int childIndex = 0; childIndex < node->mNumChildren; ++childIndex)
                 {
                     const aiNode* childNode = node->mChildren[childIndex];
                     if (RecursiveHasChildBone(childNode, boneByNameMap))
diff --git a/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpMaterialImporter.cpp b/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpMaterialImporter.cpp
index 4880c8d736..8983c76bac 100644
--- a/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpMaterialImporter.cpp
+++ b/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpMaterialImporter.cpp
@@ -56,7 +56,7 @@ namespace AZ
                 Events::ProcessingResultCombiner combinedMaterialImportResults;
 
                 AZStd::unordered_map> materialMap;
-                for (int idx = 0; idx < context.m_sourceNode.m_assImpNode->mNumMeshes; ++idx)
+                for (unsigned int idx = 0; idx < context.m_sourceNode.m_assImpNode->mNumMeshes; ++idx)
                 {
                     int meshIndex = context.m_sourceNode.m_assImpNode->mMeshes[idx];
                     const aiMesh* assImpMesh = context.m_sourceScene.GetAssImpScene()->mMeshes[meshIndex];
diff --git a/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpTangentStreamImporter.cpp b/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpTangentStreamImporter.cpp
index 6f1c364399..fbafd3d24f 100644
--- a/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpTangentStreamImporter.cpp
+++ b/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpTangentStreamImporter.cpp
@@ -91,11 +91,11 @@ namespace AZ
 
                 tangentStream->SetGenerationMethod(AZ::SceneAPI::DataTypes::TangentGenerationMethod::FromSourceScene);
                 tangentStream->ReserveContainerSpace(vertexCount);
-                for (int sdkMeshIndex = 0; sdkMeshIndex < currentNode->mNumMeshes; ++sdkMeshIndex)
+                for (unsigned int sdkMeshIndex = 0; sdkMeshIndex < currentNode->mNumMeshes; ++sdkMeshIndex)
                 {
                     const aiMesh* mesh = scene->mMeshes[currentNode->mMeshes[sdkMeshIndex]];
 
-                    for (int v = 0; v < mesh->mNumVertices; ++v)
+                    for (unsigned int v = 0; v < mesh->mNumVertices; ++v)
                     {
                         if (!mesh->HasTangentsAndBitangents())
                         {
diff --git a/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpUvMapImporter.cpp b/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpUvMapImporter.cpp
index 12e13422cf..fc0ac15244 100644
--- a/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpUvMapImporter.cpp
+++ b/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpUvMapImporter.cpp
@@ -62,7 +62,7 @@ namespace AZ
                 // so they can be separated by engine code instead.
                 bool foundTextureCoordinates = false;
                 AZStd::array meshesPerTextureCoordinateIndex = {};
-                for (int localMeshIndex = 0; localMeshIndex < currentNode->mNumMeshes; ++localMeshIndex)
+                for (unsigned int localMeshIndex = 0; localMeshIndex < currentNode->mNumMeshes; ++localMeshIndex)
                 {
                     aiMesh* mesh = scene->mMeshes[currentNode->mMeshes[localMeshIndex]];
                     for (int texCoordIndex = 0; texCoordIndex < meshesPerTextureCoordinateIndex.size(); ++texCoordIndex)
@@ -110,7 +110,7 @@ namespace AZ
                     uvMap->ReserveContainerSpace(vertexCount);
                     bool customNameFound = false;
                     AZStd::string name(AZStd::string::format("%s%d", m_defaultNodeName, texCoordIndex));
-                    for (int sdkMeshIndex = 0; sdkMeshIndex < currentNode->mNumMeshes; ++sdkMeshIndex)
+                    for (unsigned int sdkMeshIndex = 0; sdkMeshIndex < currentNode->mNumMeshes; ++sdkMeshIndex)
                     {
                         const aiMesh* mesh = scene->mMeshes[currentNode->mMeshes[sdkMeshIndex]];
                         if(mesh->mTextureCoords[texCoordIndex])
@@ -136,7 +136,7 @@ namespace AZ
                             }
                         }
 
-                        for (int v = 0; v < mesh->mNumVertices; ++v)
+                        for (unsigned int v = 0; v < mesh->mNumVertices; ++v)
                         {
                             if (mesh->mTextureCoords[texCoordIndex])
                             {
diff --git a/Code/Tools/SceneAPI/SceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.cpp b/Code/Tools/SceneAPI/SceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.cpp
index a9ab292d25..de94018c9b 100644
--- a/Code/Tools/SceneAPI/SceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.cpp
+++ b/Code/Tools/SceneAPI/SceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.cpp
@@ -40,7 +40,7 @@ namespace AZ::SceneAPI::SceneBuilder
         // This code re-combines them to match previous FBX SDK behavior,
         // so they can be separated by engine code instead.
         int vertOffset = 0;
-        for (int m = 0; m < currentNode->mNumMeshes; ++m)
+        for (unsigned int m = 0; m < currentNode->mNumMeshes; ++m)
         {
             const aiMesh* mesh = scene->mMeshes[currentNode->mMeshes[m]];
 
@@ -50,7 +50,7 @@ namespace AZ::SceneAPI::SceneBuilder
                 assImpMatIndexToLYIndex.insert(AZStd::pair(mesh->mMaterialIndex, lyMeshIndex++));
             }
 
-            for (int vertIdx = 0; vertIdx < mesh->mNumVertices; ++vertIdx)
+            for (unsigned int vertIdx = 0; vertIdx < mesh->mNumVertices; ++vertIdx)
             {
                 AZ::Vector3 vertex(mesh->mVertices[vertIdx].x, mesh->mVertices[vertIdx].y, mesh->mVertices[vertIdx].z);
 
@@ -68,7 +68,7 @@ namespace AZ::SceneAPI::SceneBuilder
                 }
             }
 
-            for (int faceIdx = 0; faceIdx < mesh->mNumFaces; ++faceIdx)
+            for (unsigned int faceIdx = 0; faceIdx < mesh->mNumFaces; ++faceIdx)
             {
                 aiFace face = mesh->mFaces[faceIdx];
                 AZ::SceneAPI::DataTypes::IMeshData::Face meshFace;
@@ -82,7 +82,7 @@ namespace AZ::SceneAPI::SceneBuilder
                         face.mNumIndices);
                     continue;
                 }
-                for (int idx = 0; idx < face.mNumIndices; ++idx)
+                for (unsigned int idx = 0; idx < face.mNumIndices; ++idx)
                 {
                     meshFace.vertexIndex[idx] = face.mIndices[idx] + vertOffset;
                 }
diff --git a/Code/Tools/SceneAPI/SceneCore/DataTypes/Rules/IMeshAdvancedRule.h b/Code/Tools/SceneAPI/SceneCore/DataTypes/Rules/IMeshAdvancedRule.h
index d3b31913dd..04ed3f0949 100644
--- a/Code/Tools/SceneAPI/SceneCore/DataTypes/Rules/IMeshAdvancedRule.h
+++ b/Code/Tools/SceneAPI/SceneCore/DataTypes/Rules/IMeshAdvancedRule.h
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 
 namespace AZ
 {
@@ -18,7 +19,8 @@ namespace AZ
     {
         namespace DataTypes
         {
-            const static AZStd::string s_advancedDisabledString = "Disabled";
+            static const char* s_advancedDisabledString = "Disabled";
+
             class IMeshAdvancedRule
                 : public IRule
             {
diff --git a/Code/Tools/SceneAPI/SceneCore/Utilities/DebugOutput.h b/Code/Tools/SceneAPI/SceneCore/Utilities/DebugOutput.h
index 5bb57a6167..5fe5b98243 100644
--- a/Code/Tools/SceneAPI/SceneCore/Utilities/DebugOutput.h
+++ b/Code/Tools/SceneAPI/SceneCore/Utilities/DebugOutput.h
@@ -13,6 +13,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 namespace AZ::SceneAPI::Utilities
diff --git a/Code/Tools/SceneAPI/SceneData/GraphData/MaterialData.cpp b/Code/Tools/SceneAPI/SceneData/GraphData/MaterialData.cpp
index cf0f0a6f56..d58a89a110 100644
--- a/Code/Tools/SceneAPI/SceneData/GraphData/MaterialData.cpp
+++ b/Code/Tools/SceneAPI/SceneData/GraphData/MaterialData.cpp
@@ -18,11 +18,6 @@ namespace AZ
         {
             namespace DataTypes = AZ::SceneAPI::DataTypes;
 
-            const AZStd::string MaterialData::s_DiffuseMapName = "Diffuse";
-            const AZStd::string MaterialData::s_SpecularMapName = "Specular";
-            const AZStd::string MaterialData::s_BumpMapName = "Bump";
-            const AZStd::string MaterialData::s_emptyString = "";
-
             MaterialData::MaterialData()
                 : m_isNoDraw(false)
                 , m_diffuseColor(AZ::Vector3::CreateOne())
@@ -72,7 +67,7 @@ namespace AZ
                     return result->second;
                 }
 
-                return s_emptyString;
+                return m_emptyString;
             }
 
             void MaterialData::SetNoDraw(bool isNoDraw)
diff --git a/Code/Tools/SceneAPI/SceneData/GraphData/MaterialData.h b/Code/Tools/SceneAPI/SceneData/GraphData/MaterialData.h
index 8cc9de8352..2a83a53c53 100644
--- a/Code/Tools/SceneAPI/SceneData/GraphData/MaterialData.h
+++ b/Code/Tools/SceneAPI/SceneData/GraphData/MaterialData.h
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 
 namespace AZ
 {
@@ -96,10 +97,7 @@ namespace AZ
 
                 bool m_isNoDraw;
 
-                const static AZStd::string s_DiffuseMapName;
-                const static AZStd::string s_SpecularMapName;
-                const static AZStd::string s_BumpMapName;
-                const static AZStd::string s_emptyString;
+                const AZStd::string m_emptyString;
 
                 // A unique id which is used to identify a material in a fbx. 
                 // This is the same as the ID in the fbx file's FbxNode
diff --git a/Code/Tools/Standalone/CMakeLists.txt b/Code/Tools/Standalone/CMakeLists.txt
index 479b8be11f..a8242022a8 100644
--- a/Code/Tools/Standalone/CMakeLists.txt
+++ b/Code/Tools/Standalone/CMakeLists.txt
@@ -36,7 +36,6 @@ ly_add_target(
             ${additional_dependencies}
     COMPILE_DEFINITIONS 
         PRIVATE
-            UNICODE
             STANDALONETOOLS_ENABLE_LUA_IDE
 )
 
@@ -68,6 +67,5 @@ ly_add_target(
             ${additional_dependencies}
     COMPILE_DEFINITIONS 
         PRIVATE
-            UNICODE
             STANDALONETOOLS_ENABLE_PROFILER
 )
diff --git a/Code/Tools/TestImpactFramework/CMakeLists.txt b/Code/Tools/TestImpactFramework/CMakeLists.txt
index 04cbee98dc..1cdf02d101 100644
--- a/Code/Tools/TestImpactFramework/CMakeLists.txt
+++ b/Code/Tools/TestImpactFramework/CMakeLists.txt
@@ -11,8 +11,6 @@ ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Platf
 include(${pal_source_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
 
 if(PAL_TRAIT_TEST_IMPACT_FRAMEWORK_SUPPORTED)
-    if(LY_TEST_IMPACT_INSTRUMENTATION_BIN)
-        add_subdirectory(Runtime)
-        add_subdirectory(Frontend)
-    endif()
+    add_subdirectory(Runtime)
+    add_subdirectory(Frontend)
 endif()
diff --git a/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactCommandLineOptions.cpp b/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactCommandLineOptions.cpp
index cbe587cf1a..0d1f352f21 100644
--- a/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactCommandLineOptions.cpp
+++ b/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactCommandLineOptions.cpp
@@ -6,6 +6,8 @@
  *
  */
 
+#include 
+
 #include 
 #include 
 
@@ -19,8 +21,9 @@ namespace TestImpact
         {
             // Options
             ConfigKey,
+            DataFileKey,
             ChangeListKey,
-            OutputChangeListKey,
+            SequenceReportKey,
             SequenceKey,
             TestPrioritizationPolicyKey,
             ExecutionFailurePolicyKey,
@@ -55,8 +58,9 @@ namespace TestImpact
         {
             // Options
             "config",
+            "datafile",
             "changelist",
-            "ochangelist",
+            "report",
             "sequence",
             "ppolicy",
             "epolicy",
@@ -92,14 +96,19 @@ namespace TestImpact
             return ParsePathOption(OptionKeys[ConfigKey], cmd).value_or(LY_TEST_IMPACT_DEFAULT_CONFIG_FILE);
         }
 
+        AZStd::optional ParseDataFile(const AZ::CommandLine& cmd)
+        {
+            return ParsePathOption(OptionKeys[DataFileKey], cmd);
+        }
+
         AZStd::optional ParseChangeListFile(const AZ::CommandLine& cmd)
         {
             return ParsePathOption(OptionKeys[ChangeListKey], cmd);
         }
 
-        bool ParseOutputChangeList(const AZ::CommandLine& cmd)
+        AZStd::optional ParseSequenceReportFile(const AZ::CommandLine& cmd)
         {
-            return ParseOnOffOption(OptionKeys[OutputChangeListKey], BinaryStateValue{ false, true }, cmd).value_or(false);
+            return ParsePathOption(OptionKeys[SequenceReportKey], cmd);
         }
 
         TestSequenceType ParseTestSequenceType(const AZ::CommandLine& cmd)
@@ -255,9 +264,9 @@ namespace TestImpact
         {
             const AZStd::vector> states =
             {
-                {GetSuiteTypeName(SuiteType::Main), SuiteType::Main},
-                {GetSuiteTypeName(SuiteType::Periodic), SuiteType::Periodic},
-                {GetSuiteTypeName(SuiteType::Sandbox), SuiteType::Sandbox}
+                { SuiteTypeAsString(SuiteType::Main), SuiteType::Main },
+                { SuiteTypeAsString(SuiteType::Periodic), SuiteType::Periodic },
+                { SuiteTypeAsString(SuiteType::Sandbox), SuiteType::Sandbox }
             };
 
             return ParseMultiStateOption(OptionKeys[SuiteFilterKey], states, cmd).value_or(SuiteType::Main);
@@ -270,8 +279,9 @@ namespace TestImpact
         cmd.Parse(argc, argv);
 
         m_configurationFile = ParseConfigurationFile(cmd);
+        m_dataFile = ParseDataFile(cmd);
         m_changeListFile = ParseChangeListFile(cmd);
-        m_outputChangeList = ParseOutputChangeList(cmd);
+        m_sequenceReportFile = ParseSequenceReportFile(cmd);
         m_testSequenceType = ParseTestSequenceType(cmd);
         m_testPrioritizationPolicy = ParseTestPrioritizationPolicy(cmd);
         m_executionFailurePolicy = ParseExecutionFailurePolicy(cmd);
@@ -286,28 +296,43 @@ namespace TestImpact
         m_safeMode = ParseSafeMode(cmd);
         m_suiteFilter = ParseSuiteFilter(cmd);
     }
+
+    bool CommandLineOptions::HasDataFilePath() const
+    {
+        return m_dataFile.has_value();
+    }
  
-    bool CommandLineOptions::HasChangeListFile() const
+    bool CommandLineOptions::HasChangeListFilePath() const
     {
         return m_changeListFile.has_value();
     }
 
+    bool CommandLineOptions::HasSequenceReportFilePath() const
+    {
+        return m_sequenceReportFile.has_value();
+    }
+
     bool CommandLineOptions::HasSafeMode() const
     {
         return m_safeMode;
     }
 
-    const AZStd::optional& CommandLineOptions::GetChangeListFile() const
+    const AZStd::optional& CommandLineOptions::GetDataFilePath() const
+    {
+        return m_dataFile;
+    }
+
+    const AZStd::optional& CommandLineOptions::GetChangeListFilePath() const
     {
         return m_changeListFile;
     }
 
-    bool CommandLineOptions::HasOutputChangeList() const
+    const AZStd::optional& CommandLineOptions::GetSequenceReportFilePath() const
     {
-        return m_outputChangeList;
+        return m_sequenceReportFile;
     }
 
-    const RepoPath& CommandLineOptions::GetConfigurationFile() const
+    const RepoPath& CommandLineOptions::GetConfigurationFilePath() const
     {
         return m_configurationFile;
     }
@@ -379,8 +404,12 @@ namespace TestImpact
             "  options:\n"
             "    -config=                                          Path to the configuration file for the TIAF runtime (default: \n"
             "                                                                ..json).\n"
+            "    -datafile=                                        Optional path to a test impact data file that will used instead of that\n"
+            "                                                                specified in the config file.\n"
             "    -changelist=                                      Path to the JSON of source file changes to perform test impact \n"
             "                                                                analysis on.\n"
+            "    -report=                                          Path to where the sequence report file will be written (if this option \n"
+            "                                                                is not specified, no report will be written).\n"
             "    -gtimeout=                                         Global timeout value to terminate the entire test sequence should it \n"
             "                                                                be exceeded.\n"
             "    -ttimeout=                                         Timeout value to terminate individual test targets should it be \n"
@@ -443,7 +472,6 @@ namespace TestImpact
             "                                                                available, no prioritization will occur).\n"
             "    -maxconcurrency=                                    The maximum number of concurrent test targets/shards to be in flight at \n"
             "                                                                any given moment.\n"
-            "    -ochangelist=                                       Outputs the change list used for test selection.\n"
             "    -suite=                            The test suite to select from for this test sequence.";
 
         return help;
diff --git a/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactCommandLineOptions.h b/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactCommandLineOptions.h
index ea58305afb..36ca4231b9 100644
--- a/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactCommandLineOptions.h
+++ b/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactCommandLineOptions.h
@@ -36,20 +36,29 @@ namespace TestImpact
         CommandLineOptions(int argc, char** argv);
         static AZStd::string GetCommandLineUsageString();
 
+        //! Returns true if a test impact data file path has been supplied, otherwise false.
+        bool HasDataFilePath() const;
+
         //! Returns true if a change list file path has been supplied, otherwise false.
-        bool HasChangeListFile() const;
+        bool HasChangeListFilePath() const;
+
+        //! Returns true if a sequence report file path has been supplied, otherwise false.
+        bool HasSequenceReportFilePath() const;
 
         //! Returns true if the safe mode option has been enabled, otherwise false.
         bool HasSafeMode() const;
 
-        //! Returns true if the output change list option has been enabled, otherwise false.
-        bool HasOutputChangeList() const;
-
         //! Returns the path to the runtime configuration file.
-        const RepoPath& GetConfigurationFile() const;
+        const RepoPath& GetConfigurationFilePath() const;
+
+        //! Returns the path to the data file (if any).
+        const AZStd::optional& GetDataFilePath() const;
 
         //! Returns the path to the change list file (if any).
-        const AZStd::optional& GetChangeListFile() const;
+        const AZStd::optional& GetChangeListFilePath() const;
+
+        //! Returns the path to the sequence report file (if any).
+        const AZStd::optional& GetSequenceReportFilePath() const;
 
         //! Returns the test sequence type to run.
         TestSequenceType GetTestSequenceType() const;
@@ -89,8 +98,9 @@ namespace TestImpact
 
     private:
         RepoPath m_configurationFile;
+        AZStd::optional m_dataFile;
         AZStd::optional m_changeListFile;
-        bool m_outputChangeList = false;
+        AZStd::optional m_sequenceReportFile;
         TestSequenceType m_testSequenceType;
         Policy::TestPrioritization m_testPrioritizationPolicy = Policy::TestPrioritization::None;
         Policy::ExecutionFailure m_executionFailurePolicy = Policy::ExecutionFailure::Continue;
diff --git a/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactConsoleMain.cpp b/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactConsoleMain.cpp
index 8027649a44..bbb4765ad4 100644
--- a/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactConsoleMain.cpp
+++ b/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactConsoleMain.cpp
@@ -9,14 +9,16 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -33,31 +35,6 @@ namespace TestImpact
 {
     namespace Console
     {
-        //! Generates a string to be used for printing to the console for the specified change list.
-        AZStd::string GenerateChangeListString(const ChangeList& changeList)
-        {
-            AZStd::string output;
-
-            const auto& outputFiles = [&output](const AZStd::vector& files)
-            {
-                for (const auto& file : files)
-                {
-                    output += AZStd::string::format("\t%s\n", file.c_str());
-                }
-            };
-
-            output += AZStd::string::format("Created files (%u):\n", changeList.m_createdFiles.size());
-            outputFiles(changeList.m_createdFiles);
-
-            output += AZStd::string::format("Updated files (%u):\n", changeList.m_updatedFiles.size());
-            outputFiles(changeList.m_updatedFiles);
-
-            output += AZStd::string::format("Deleted files (%u):\n", changeList.m_deletedFiles.size());
-            outputFiles(changeList.m_deletedFiles);
-
-            return output;
-        }
-
         //! Gets the appropriate console return code for the specified test sequence result.
         ReturnCode GetReturnCodeForTestSequenceResult(TestSequenceResult result)
         {
@@ -75,6 +52,20 @@ namespace TestImpact
             }
         }
 
+        //! Wrapper around sequence reports to optionally serialize them and transform the result into a return code.
+        template
+        ReturnCode ConsumeSequenceReportAndGetReturnCode(const SequenceReportType& sequenceReport, const CommandLineOptions& options)
+        {
+            if (options.HasSequenceReportFilePath())
+            {
+                std::cout << "Exporting sequence report '" << options.GetSequenceReportFilePath().value().c_str() << "'" << std::endl;
+                const auto sequenceReportJson = SerializeSequenceReport(sequenceReport);
+                WriteFileContents(sequenceReportJson, options.GetSequenceReportFilePath().value());
+            }
+
+            return GetReturnCodeForTestSequenceResult(sequenceReport.GetResult());
+        }
+
         //! Wrapper around impact analysis sequences to handle the case where the safe mode option is active.
         ReturnCode WrappedImpactAnalysisTestSequence(
             const CommandLineOptions& options,
@@ -88,35 +79,34 @@ namespace TestImpact
                 CommandLineOptionsException,
                 "Expected a change list for impact analysis but none was provided");
 
-            TestSequenceResult result = TestSequenceResult::Failure;
             if (options.HasSafeMode())
             {
                 if (options.GetTestSequenceType() == TestSequenceType::ImpactAnalysis)
                 {
-                    auto safeImpactAnalysisSequenceReport = runtime.SafeImpactAnalysisTestSequence(
-                        changeList.value(),
-                        options.GetTestPrioritizationPolicy(),
-                        options.GetTestTargetTimeout(),
-                        options.GetGlobalTimeout(),
-                        SafeImpactAnalysisTestSequenceStartCallback,
-                        SafeImpactAnalysisTestSequenceCompleteCallback,
-                        TestRunCompleteCallback);
-        
-                    result = safeImpactAnalysisSequenceReport.GetResult();
+                    return ConsumeSequenceReportAndGetReturnCode(
+                        runtime.SafeImpactAnalysisTestSequence(
+                            changeList.value(),
+                            options.GetTestPrioritizationPolicy(),
+                            options.GetTestTargetTimeout(),
+                            options.GetGlobalTimeout(),
+                            SafeImpactAnalysisTestSequenceStartCallback,
+                            SafeImpactAnalysisTestSequenceCompleteCallback,
+                            TestRunCompleteCallback),
+                        options);
                 }
                 else if (options.GetTestSequenceType() == TestSequenceType::ImpactAnalysisNoWrite)
                 {
                     // A no-write impact analysis sequence with safe mode enabled is functionally identical to a regular sequence type
                     // due to a) the selected tests being run without instrumentation and b) the discarded tests also being run without
                     // instrumentation
-                    auto sequenceReport = runtime.RegularTestSequence(
-                        options.GetTestTargetTimeout(),
-                        options.GetGlobalTimeout(),
-                        TestSequenceStartCallback,
-                        TestSequenceCompleteCallback,
-                        TestRunCompleteCallback);
-
-                    result = sequenceReport.GetResult();
+                    return ConsumeSequenceReportAndGetReturnCode(
+                        runtime.RegularTestSequence(
+                            options.GetTestTargetTimeout(),
+                            options.GetGlobalTimeout(),
+                            TestSequenceStartCallback,
+                            RegularTestSequenceCompleteCallback,
+                            TestRunCompleteCallback),
+                        options);
                 }
                 else
                 {
@@ -139,20 +129,18 @@ namespace TestImpact
                     throw(Exception("Unexpected sequence type"));
                 }
         
-                auto impactAnalysisSequenceReport = runtime.ImpactAnalysisTestSequence(
-                    changeList.value(),
-                    options.GetTestPrioritizationPolicy(),
-                    dynamicDependencyMapPolicy,
-                    options.GetTestTargetTimeout(),
-                    options.GetGlobalTimeout(),
-                    ImpactAnalysisTestSequenceStartCallback,
-                    ImpactAnalysisTestSequenceCompleteCallback,
-                    TestRunCompleteCallback);
-
-                result = impactAnalysisSequenceReport.GetResult();
+                return ConsumeSequenceReportAndGetReturnCode(
+                    runtime.ImpactAnalysisTestSequence(
+                        changeList.value(),
+                        options.GetTestPrioritizationPolicy(),
+                        dynamicDependencyMapPolicy,
+                        options.GetTestTargetTimeout(),
+                        options.GetGlobalTimeout(),
+                        ImpactAnalysisTestSequenceStartCallback,
+                        ImpactAnalysisTestSequenceCompleteCallback,
+                        TestRunCompleteCallback),
+                    options);
             }
-        
-            return GetReturnCodeForTestSequenceResult(result);
         };
 
         //! Entry point for the test impact analysis framework console front end application.
@@ -164,28 +152,22 @@ namespace TestImpact
                 AZStd::optional changeList;
 
                 // If we have a change list, check to see whether or not the client has requested the printing of said change list
-                if (options.HasChangeListFile())
+                if (options.HasChangeListFilePath())
                 {
-                    changeList = DeserializeChangeList(ReadFileContents(*options.GetChangeListFile()));
-                    if (options.HasOutputChangeList())
-                    {
-                        std::cout << "Change List:\n";
-                        std::cout << GenerateChangeListString(*changeList).c_str();
-
-                        if (options.GetTestSequenceType() == TestSequenceType::None)
-                        {
-                            return ReturnCode::Success;
-                        }
-                    }
+                    changeList = DeserializeChangeList(ReadFileContents(*options.GetChangeListFilePath()));
                 }
 
-                // As of now, there are no other non-test operations other than printing a change list so getting this far is considered an error
-                AZ_TestImpact_Eval(options.GetTestSequenceType() != TestSequenceType::None, CommandLineOptionsException, "No action specified");
+                // As of now, there are no non-test operations but leave this door open for the future
+                if (options.GetTestSequenceType() == TestSequenceType::None)
+                {
+                    return ReturnCode::Success;
+                }
 
                 std::cout << "Constructing in-memory model of source tree and test coverage for test suite ";
-                std::cout << GetSuiteTypeName(options.GetSuiteFilter()).c_str() << ", this may take a moment...\n";
+                std::cout << SuiteTypeAsString(options.GetSuiteFilter()).c_str() << ", this may take a moment...\n";
                 Runtime runtime(
-                    RuntimeConfigurationFactory(ReadFileContents(options.GetConfigurationFile())),
+                    RuntimeConfigurationFactory(ReadFileContents(options.GetConfigurationFilePath())),
+                    options.GetDataFilePath(),
                     options.GetSuiteFilter(),
                     options.GetExecutionFailurePolicy(),
                     options.GetFailedTestCoveragePolicy(),
@@ -208,25 +190,25 @@ namespace TestImpact
                 {
                 case TestSequenceType::Regular:
                 {
-                    const auto sequenceReport = runtime.RegularTestSequence(
-                        options.GetTestTargetTimeout(),
-                        options.GetGlobalTimeout(),
-                        TestSequenceStartCallback,
-                        TestSequenceCompleteCallback,
-                        TestRunCompleteCallback);
-
-                    return GetReturnCodeForTestSequenceResult(sequenceReport.GetResult());
+                    return ConsumeSequenceReportAndGetReturnCode(
+                        runtime.RegularTestSequence(
+                            options.GetTestTargetTimeout(),
+                            options.GetGlobalTimeout(),
+                            TestSequenceStartCallback,
+                            RegularTestSequenceCompleteCallback,
+                            TestRunCompleteCallback),
+                        options);
                 }
                 case TestSequenceType::Seed:
                 {
-                    const auto sequenceReport = runtime.SeededTestSequence(
-                        options.GetTestTargetTimeout(),
-                        options.GetGlobalTimeout(),
-                        TestSequenceStartCallback,
-                        TestSequenceCompleteCallback,
-                        TestRunCompleteCallback);
-
-                    return GetReturnCodeForTestSequenceResult(sequenceReport.GetResult());
+                    return ConsumeSequenceReportAndGetReturnCode(
+                        runtime.SeededTestSequence(
+                            options.GetTestTargetTimeout(),
+                            options.GetGlobalTimeout(),
+                            TestSequenceStartCallback,
+                            SeedTestSequenceCompleteCallback,
+                            TestRunCompleteCallback),
+                        options);
                 }
                 case TestSequenceType::ImpactAnalysisNoWrite:
                 case TestSequenceType::ImpactAnalysis:
@@ -241,14 +223,14 @@ namespace TestImpact
                     }
                     else
                     {
-                        const auto sequenceReport = runtime.SeededTestSequence(
-                            options.GetTestTargetTimeout(),
-                            options.GetGlobalTimeout(),
-                            TestSequenceStartCallback,
-                            TestSequenceCompleteCallback,
-                            TestRunCompleteCallback);
-
-                        return GetReturnCodeForTestSequenceResult(sequenceReport.GetResult());
+                        return ConsumeSequenceReportAndGetReturnCode(
+                            runtime.SeededTestSequence(
+                                options.GetTestTargetTimeout(),
+                                options.GetGlobalTimeout(),
+                                TestSequenceStartCallback,
+                                SeedTestSequenceCompleteCallback,
+                                TestRunCompleteCallback),
+                            options);
                     }
                 }
                 default:
diff --git a/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactConsoleTestSequenceEventHandler.cpp b/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactConsoleTestSequenceEventHandler.cpp
index da7052933c..e7430fe90b 100644
--- a/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactConsoleTestSequenceEventHandler.cpp
+++ b/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactConsoleTestSequenceEventHandler.cpp
@@ -6,8 +6,9 @@
  *
  */
 
-#include 
+#include 
 
+#include 
 #include 
 
 #include 
@@ -20,7 +21,7 @@ namespace TestImpact
         {
             void TestSuiteFilter(SuiteType filter)
             {
-                std::cout << "Test suite filter: " << GetSuiteTypeName(filter).c_str() << "\n";
+                std::cout << "Test suite filter: " << SuiteTypeAsString(filter).c_str() << "\n";
             }
 
             void ImpactAnalysisTestSelection(size_t numSelectedTests, size_t numDiscardedTests, size_t numExcludedTests, size_t numDraftedTests)
@@ -36,69 +37,66 @@ namespace TestImpact
             {
                 std::cout << "Sequence completed in " << (testRunReport.GetDuration().count() / 1000.f) << "s with";
 
-                if (!testRunReport.GetExecutionFailureTests().empty() ||
-                    !testRunReport.GetFailingTests().empty() ||
-                    !testRunReport.GetTimedOutTests().empty() ||
-                    !testRunReport.GetUnexecutedTests().empty())
+                if (!testRunReport.GetExecutionFailureTestRuns().empty() ||
+                    !testRunReport.GetFailingTestRuns().empty() ||
+                    !testRunReport.GetTimedOutTestRuns().empty() ||
+                    !testRunReport.GetUnexecutedTestRuns().empty())
                 {
                     std::cout << ":\n";
                     std::cout << SetColor(Foreground::White, Background::Red).c_str()
-                        << testRunReport.GetFailingTests().size()
+                        << testRunReport.GetFailingTestRuns().size()
                         << ResetColor().c_str() << " test failures\n";
 
                     std::cout << SetColor(Foreground::White, Background::Red).c_str()
-                        << testRunReport.GetExecutionFailureTests().size()
+                        << testRunReport.GetExecutionFailureTestRuns().size()
                         << ResetColor().c_str() << " execution failures\n";
 
                     std::cout << SetColor(Foreground::White, Background::Red).c_str()
-                        << testRunReport.GetTimedOutTests().size()
+                        << testRunReport.GetTimedOutTestRuns().size()
                         << ResetColor().c_str() << " test timeouts\n";
 
                     std::cout << SetColor(Foreground::White, Background::Red).c_str()
-                        << testRunReport.GetUnexecutedTests().size()
+                        << testRunReport.GetUnexecutedTestRuns().size()
                         << ResetColor().c_str() << " unexecuted tests\n";
 
-                    if (!testRunReport.GetFailingTests().empty())
+                    if (!testRunReport.GetFailingTestRuns().empty())
                     {
                         std::cout << "\nTest failures:\n";
-                        for (const auto& testRunFailure : testRunReport.GetFailingTests())
+                        for (const auto& testRunFailure : testRunReport.GetFailingTestRuns())
                         {
-                            for (const auto& testCaseFailure : testRunFailure.GetTestCaseFailures())
+                            for (const auto& test : testRunFailure.GetTests())
                             {
-                                for (const auto& testFailure : testCaseFailure.GetTestFailures())
+                                if (test.GetResult() == Client::TestResult::Failed)
                                 {
-                                    std::cout << "  "
-                                        << testRunFailure.GetTargetName().c_str()
-                                        << "." << testCaseFailure.GetName().c_str()
-                                        << "." << testFailure.GetName().c_str() << "\n";
+                                    std::cout << "  " << test.GetName().c_str() << "\n";
                                 }
                             }
                         }
                     }
 
-                    if (!testRunReport.GetExecutionFailureTests().empty())
+                    if (!testRunReport.GetExecutionFailureTestRuns().empty())
                     {
                         std::cout << "\nExecution failures:\n";
-                        for (const auto& executionFailure : testRunReport.GetExecutionFailureTests())
+                        for (const auto& executionFailure : testRunReport.GetExecutionFailureTestRuns())
                         {
                             std::cout << "  " << executionFailure.GetTargetName().c_str() << "\n";
                             std::cout << executionFailure.GetCommandString().c_str() << "\n";
                         }
                     }
 
-                    if (!testRunReport.GetTimedOutTests().empty())
+                    if (!testRunReport.GetTimedOutTestRuns().empty())
                     {
                         std::cout << "\nTimed out tests:\n";
-                        for (const auto& testTimeout : testRunReport.GetTimedOutTests())
+                        for (const auto& testTimeout : testRunReport.GetTimedOutTestRuns())
                         {
                             std::cout << "  " << testTimeout.GetTargetName().c_str() << "\n";
                         }
                     }
 
-                    if (!testRunReport.GetUnexecutedTests().empty())
+                    if (!testRunReport.GetUnexecutedTestRuns().empty())
                     {
                         std::cout << "\nUnexecuted tests:\n";
-                        for (const auto& unexecutedTest : testRunReport.GetUnexecutedTests())
+                        for (const auto& unexecutedTest : testRunReport.GetUnexecutedTestRuns())
                         {
                             std::cout << "  " << unexecutedTest.GetTargetName().c_str() << "\n";
                         }
@@ -106,7 +104,7 @@ namespace TestImpact
                 }
                 else
                 {
-                    std::cout << SetColor(Foreground::White, Background::Green).c_str() << " \100% passes!\n" << ResetColor().c_str() << "\n";
+                    std::cout << " " << SetColor(Foreground::White, Background::Green).c_str() << "100% passes!\n" << ResetColor().c_str() << "\n";
                 }
             }
         }
@@ -149,13 +147,17 @@ namespace TestImpact
                 draftedTests.size());
         }
 
-        void TestSequenceCompleteCallback(const Client::SequenceReport& sequenceReport)
+        void RegularTestSequenceCompleteCallback(const Client::RegularSequenceReport& sequenceReport)
         {
-            
             Output::FailureReport(sequenceReport.GetSelectedTestRunReport());
             std::cout << "Updating and serializing the test impact analysis data, this may take a moment...\n";
         }
 
+        void SeedTestSequenceCompleteCallback(const Client::SeedSequenceReport& sequenceReport)
+        {
+            Output::FailureReport(sequenceReport.GetSelectedTestRunReport());
+        }
+
         void ImpactAnalysisTestSequenceCompleteCallback(const Client::ImpactAnalysisSequenceReport& sequenceReport)
         {
             std::cout << "Selected test run:\n";
@@ -181,7 +183,7 @@ namespace TestImpact
             std::cout << "Updating and serializing the test impact analysis data, this may take a moment...\n";
         }
 
-        void TestRunCompleteCallback(const Client::TestRun& testRun, size_t numTestRunsCompleted, size_t totalNumTestRuns)
+        void TestRunCompleteCallback(const Client::TestRunBase& testRun, size_t numTestRunsCompleted, size_t totalNumTestRuns)
         {
             const auto progress =
                 AZStd::string::format("(%03u/%03u)", numTestRunsCompleted, totalNumTestRuns, testRun.GetTargetName().c_str());
diff --git a/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactConsoleTestSequenceEventHandler.h b/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactConsoleTestSequenceEventHandler.h
index ff757b2d5a..8f28d60617 100644
--- a/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactConsoleTestSequenceEventHandler.h
+++ b/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactConsoleTestSequenceEventHandler.h
@@ -38,8 +38,11 @@ namespace TestImpact
             const Client::TestRunSelection& discardedTests,
             const AZStd::vector& draftedTests);
 
-        //! Handler for TestSequenceCompleteCallback event.
-        void TestSequenceCompleteCallback(const Client::SequenceReport& sequenceReport);
+        //! Handler for RegularTestSequenceCompleteCallback event.
+        void RegularTestSequenceCompleteCallback(const Client::RegularSequenceReport& sequenceReport);
+
+        //! Handler for SeedTestSequenceCompleteCallback event.
+        void SeedTestSequenceCompleteCallback(const Client::SeedSequenceReport& sequenceReport);
 
         //! Handler for ImpactAnalysisTestSequenceCompleteCallback event.
         void ImpactAnalysisTestSequenceCompleteCallback(const Client::ImpactAnalysisSequenceReport& sequenceReport);
@@ -48,6 +51,6 @@ namespace TestImpact
         void SafeImpactAnalysisTestSequenceCompleteCallback(const Client::SafeImpactAnalysisSequenceReport& sequenceReport);
 
         //! Handler for TestRunCompleteCallback event.
-        void TestRunCompleteCallback(const Client::TestRun& testRun, size_t numTestRunsCompleted, size_t totalNumTestRuns);
+        void TestRunCompleteCallback(const Client::TestRunBase& testRun, size_t numTestRunsCompleted, size_t totalNumTestRuns);
     } // namespace Console
 } // namespace TestImpact
diff --git a/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactRuntimeConfigurationFactory.cpp b/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactRuntimeConfigurationFactory.cpp
index 0d54cf417d..8ea32d6447 100644
--- a/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactRuntimeConfigurationFactory.cpp
+++ b/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactRuntimeConfigurationFactory.cpp
@@ -7,6 +7,7 @@
  */
 
 #include 
+#include 
 
 #include 
 
@@ -140,17 +141,17 @@ namespace TestImpact
         return tempWorkspaceConfig;
     }
 
-    AZStd::array ParseTestImpactAnalysisDataFiles(const RepoPath& root, const rapidjson::Value& sparTIAFile)
+    AZStd::array ParseTestImpactAnalysisDataFiles(const RepoPath& root, const rapidjson::Value& sparTiaFile)
     {
-        AZStd::array sparTIAFiles;
-        sparTIAFiles[static_cast(SuiteType::Main)] =
-            GetAbsPathFromRelPath(root, sparTIAFile[GetSuiteTypeName(SuiteType::Main).c_str()].GetString());
-        sparTIAFiles[static_cast(SuiteType::Periodic)] =
-            GetAbsPathFromRelPath(root, sparTIAFile[GetSuiteTypeName(SuiteType::Periodic).c_str()].GetString());
-        sparTIAFiles[static_cast(SuiteType::Sandbox)] =
-            GetAbsPathFromRelPath(root, sparTIAFile[GetSuiteTypeName(SuiteType::Sandbox).c_str()].GetString());
+        AZStd::array sparTiaFiles;
+        sparTiaFiles[static_cast(SuiteType::Main)] =
+            GetAbsPathFromRelPath(root, sparTiaFile[SuiteTypeAsString(SuiteType::Main).c_str()].GetString());
+        sparTiaFiles[static_cast(SuiteType::Periodic)] =
+            GetAbsPathFromRelPath(root, sparTiaFile[SuiteTypeAsString(SuiteType::Periodic).c_str()].GetString());
+        sparTiaFiles[static_cast(SuiteType::Sandbox)] =
+            GetAbsPathFromRelPath(root, sparTiaFile[SuiteTypeAsString(SuiteType::Sandbox).c_str()].GetString());
 
-        return sparTIAFiles;
+        return sparTiaFiles;
     }
 
     WorkspaceConfig::Active ParseActiveWorkspaceConfig(const rapidjson::Value& activeWorkspace)
@@ -160,7 +161,7 @@ namespace TestImpact
         activeWorkspaceConfig.m_root = activeWorkspace[Config::Keys[Config::Root]].GetString();
         activeWorkspaceConfig.m_enumerationCacheDirectory
             = GetAbsPathFromRelPath(activeWorkspaceConfig.m_root, relativePaths[Config::Keys[Config::EnumerationCacheDir]].GetString());
-        activeWorkspaceConfig.m_sparTIAFiles =
+        activeWorkspaceConfig.m_sparTiaFiles =
             ParseTestImpactAnalysisDataFiles(activeWorkspaceConfig.m_root, relativePaths[Config::Keys[Config::TestImpactDataFiles]]);
         return activeWorkspaceConfig;
     }
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactClientSequenceReport.h b/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactClientSequenceReport.h
index 73f3827fae..e86123ddc7 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactClientSequenceReport.h
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactClientSequenceReport.h
@@ -1,6 +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.
- * 
+ * 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
  *
  */
@@ -11,10 +12,25 @@
 #include 
 #include 
 
+#include 
+#include 
+
 namespace TestImpact
 {
     namespace Client
     {
+        //! The report types generated by each sequence.
+        enum class SequenceReportType : AZ::u8
+        {
+            RegularSequence,
+            SeedSequence,
+            ImpactAnalysisSequence,
+            SafeImpactAnalysisSequence
+        };
+
+        //! Calculates the final sequence result for a composite of multiple sequences.
+        TestSequenceResult CalculateMultiTestSequenceResult(const AZStd::vector& results);
+
         //! Report detailing the result and duration of a given set of test runs along with the details of each individual test run.
         class TestRunReport
         {
@@ -23,20 +39,20 @@ namespace TestImpact
             //! @param result The result of this set of test runs.
             //! @param startTime The time point his set of test runs started.
             //! @param duration The duration this set of test runs took to complete.
-            //! @param passingTests The set of test runs that executed successfully with no failing tests.
-            //! @param failing tests The set of test runs that executed successfully but had one or more failing tests.
-            //! @param executionFailureTests The set of test runs that failed to execute.
-            //! @param timedOutTests The set of test runs that executed successfully but were terminated prematurely due to timing out.
-            //! @param unexecutedTests The set of test runs that were queued up for execution but did not get the opportunity to execute.
+            //! @param passingTestRuns The set of test runs that executed successfully with no failing test runs.
+            //! @param failingTestRuns The set of test runs that executed successfully but had one or more failing tests.
+            //! @param executionFailureTestRuns The set of test runs that failed to execute.
+            //! @param timedOutTestRuns The set of test runs that executed successfully but were terminated prematurely due to timing out.
+            //! @param unexecutedTestRuns The set of test runs that were queued up for execution but did not get the opportunity to execute.
             TestRunReport(
                 TestSequenceResult result,
                 AZStd::chrono::high_resolution_clock::time_point startTime,
                 AZStd::chrono::milliseconds duration,
-                AZStd::vector&& passingTests,
-                AZStd::vector&& failingTests,
-                AZStd::vector&& executionFailureTests,
-                AZStd::vector&& timedOutTests,
-                AZStd::vector&& unexecutedTests);
+                AZStd::vector&& passingTestRuns,
+                AZStd::vector&& failingTestRuns,
+                AZStd::vector&& executionFailureTestRuns,
+                AZStd::vector&& timedOutTestRuns,
+                AZStd::vector&& unexecutedTestRuns);
 
             //! Returns the result of this sequence of test runs.
             TestSequenceResult GetResult() const;
@@ -50,190 +66,478 @@ namespace TestImpact
             //! Returns the duration this sequence of test runs took to complete.
             AZStd::chrono::milliseconds GetDuration() const;
 
+            //! Returns the total number of test runs.
+            size_t GetTotalNumTestRuns() const;
+
             //! Returns the number of passing test runs.
-            size_t GetNumPassingTests() const;
+            size_t GetNumPassingTestRuns() const;
 
             //! Returns the number of failing test runs.
-            size_t GetNumFailingTests() const;
+            size_t GetNumFailingTestRuns() const;
+
+            //! Returns the number of test runs that failed to execute.
+            size_t GetNumExecutionFailureTestRuns() const;
 
             //! Returns the number of timed out test runs.
-            size_t GetNumTimedOutTests() const;
+            size_t GetNumTimedOutTestRuns() const;
 
             //! Returns the number of unexecuted test runs.
-            size_t GetNumUnexecutedTests() const;
+            size_t GetNumUnexecutedTestRuns() const;
+
+            //! Returns the total number of passing tests across all test runs in the report.
+            size_t GetTotalNumPassingTests() const;
+
+            //! Returns the total number of failing tests across all test runs in the report.
+            size_t GetTotalNumFailingTests() const;
+
+            //! Returns the total number of disabled tests across all test runs in the report.
+            size_t GetTotalNumDisabledTests() const;
 
             //! Returns the set of test runs that executed successfully with no failing tests.
-            const AZStd::vector& GetPassingTests() const;
+            const AZStd::vector& GetPassingTestRuns() const;
 
             //! Returns the set of test runs that executed successfully but had one or more failing tests.
-            const AZStd::vector& GetFailingTests() const;
+            const AZStd::vector& GetFailingTestRuns() const;
 
             //! Returns the set of test runs that failed to execute.
-            const AZStd::vector& GetExecutionFailureTests() const;
+            const AZStd::vector& GetExecutionFailureTestRuns() const;
 
             //! Returns the set of test runs that executed successfully but were terminated prematurely due to timing out.
-            const AZStd::vector& GetTimedOutTests() const;
+            const AZStd::vector& GetTimedOutTestRuns() const;
 
             //! Returns the set of test runs that were queued up for execution but did not get the opportunity to execute.
-            const AZStd::vector& GetUnexecutedTests() const;
+            const AZStd::vector& GetUnexecutedTestRuns() const;
         private:
-            TestSequenceResult m_result;
+            TestSequenceResult m_result = TestSequenceResult::Success;
             AZStd::chrono::high_resolution_clock::time_point m_startTime;
-            AZStd::chrono::milliseconds m_duration;
-            AZStd::vector m_passingTests;
-            AZStd::vector m_failingTests;
-            AZStd::vector m_executionFailureTests;
-            AZStd::vector m_timedOutTests;
-            AZStd::vector m_unexecutedTests;
+            AZStd::chrono::milliseconds m_duration = AZStd::chrono::milliseconds{ 0 };
+            AZStd::vector m_passingTestRuns;
+            AZStd::vector m_failingTestRuns;
+            AZStd::vector m_executionFailureTestRuns;
+            AZStd::vector m_timedOutTestRuns;
+            AZStd::vector m_unexecutedTestRuns;
+            size_t m_totalNumPassingTests = 0;
+            size_t m_totalNumFailingTests = 0;
+            size_t m_totalNumDisabledTests = 0;
         };
 
-        //! Report detailing a test run sequence of selected tests.
-        class SequenceReport
+        //! Base class for all sequence report types.
+        template
+        class SequenceReportBase
         {
         public:
             //! Constructs the report for a sequence of selected tests.
+            //! @param type The type of sequence this report is generated for.
+            //! @param maxConcurrency The maximum number of concurrent test targets in flight at any given time.
+            //! @param testTargetTimeout The maximum duration individual test targets may be in flight for (infinite if empty).
+            //! @param globalTimeout The maximum duration the entire test sequence may run for (infinite if empty).
+            //! @param policyState The policy state this sequence was executed under.
             //! @param suiteType The suite from which the tests have been selected from.
-            //! @param selectedTests The target names of the selected tests.
+            //! @param selectedTestRuns The target names of the selected test runs.
             //! @param selectedTestRunReport The report for the set of selected test runs.
-            SequenceReport(SuiteType suiteType, const TestRunSelection& selectedTests, TestRunReport&& selectedTestRunReport);
+            SequenceReportBase(
+                SequenceReportType type,
+                size_t maxConcurrency,
+                const AZStd::optional& testTargetTimeout,
+                const AZStd::optional& globalTimeout,
+                const PolicyStateType& policyState,
+                SuiteType suiteType,
+                const TestRunSelection& selectedTestRuns,
+                TestRunReport&& selectedTestRunReport)
+                : m_type(type)
+                , m_maxConcurrency(maxConcurrency)
+                , m_testTargetTimeout(testTargetTimeout)
+                , m_globalTimeout(globalTimeout)
+                , m_policyState(policyState)
+                , m_suite(suiteType)
+                , m_selectedTestRuns(selectedTestRuns)
+                , m_selectedTestRunReport(AZStd::move(selectedTestRunReport))
+            {
+            }
+
+            virtual ~SequenceReportBase() = default;
+
+            //! Returns the identifying type for this sequence report.
+            SequenceReportType GetType() const
+            {
+                return m_type;
+            }
+
+            //! Returns the maximum concurrency for this sequence.
+            size_t GetMaxConcurrency() const
+            {
+                return m_maxConcurrency;
+            }
+
+            //! Returns the global timeout for this sequence.
+            const AZStd::optional& GetGlobalTimeout() const
+            {
+                return m_globalTimeout;
+            }
+
+            //! Returns the test target timeout for this sequence.
+            const AZStd::optional& GetTestTargetTimeout() const
+            {
+                return m_testTargetTimeout;
+            }
+
+            //! Returns the policy state for this sequence.
+            const PolicyStateType& GetPolicyState() const
+            {
+                return m_policyState;
+            }
+
+            //! Returns the suite for this sequence.
+            SuiteType GetSuite() const
+            {
+                return m_suite;
+            }
+
+             //! Returns the result of the sequence.
+            virtual TestSequenceResult GetResult() const
+            {
+                return m_selectedTestRunReport.GetResult();
+            }
 
             //! Returns the tests selected for running in the sequence.
-            TestRunSelection GetSelectedTests() const;
+            TestRunSelection GetSelectedTestRuns() const
+            {
+                return m_selectedTestRuns;
+            }
 
             //! Returns the report for the selected test runs.
-            TestRunReport GetSelectedTestRunReport() const;
+            TestRunReport GetSelectedTestRunReport() const
+            {
+                return m_selectedTestRunReport;
+            }
 
             //! Returns the start time of the sequence.
-            AZStd::chrono::high_resolution_clock::time_point GetStartTime() const;
+            AZStd::chrono::high_resolution_clock::time_point GetStartTime() const
+            {
+                return m_selectedTestRunReport.GetStartTime();
+            }
 
             //! Returns the end time of the sequence.
-            AZStd::chrono::high_resolution_clock::time_point GetEndTime() const;
-
-            //! Returns the result of the sequence.
-            virtual TestSequenceResult GetResult() const;
+            AZStd::chrono::high_resolution_clock::time_point GetEndTime() const
+            {
+                return GetStartTime() + GetDuration();
+            }
 
             //! Returns the entire duration the sequence took from start to finish.
-            virtual AZStd::chrono::milliseconds GetDuration() const;
+            virtual AZStd::chrono::milliseconds GetDuration() const
+            {
+                return m_selectedTestRunReport.GetDuration();
+            }
 
-            //! Get the total number of tests in the sequence that passed.
-            virtual size_t GetTotalNumPassingTests() const;
+            //! Returns the total number of test runs across all test run reports.
+            virtual size_t GetTotalNumTestRuns() const
+            {
+                return m_selectedTestRunReport.GetTotalNumTestRuns();
+            }
 
-            //! Get the total number of tests in the sequence that contain one or more test failures.
-            virtual size_t GetTotalNumFailingTests() const;
+            //! Returns the total number of passing tests across all test targets in all test run reports.
+            virtual size_t GetTotalNumPassingTests() const
+            {
+                return m_selectedTestRunReport.GetTotalNumPassingTests();
+            }
 
-            //! Get the total number of tests in the sequence that timed out whilst in flight.
-            virtual size_t GetTotalNumTimedOutTests() const;
+            //! Returns the total number of failing tests across all test targets in all test run reports.
+            virtual size_t GetTotalNumFailingTests() const
+            {
+                return m_selectedTestRunReport.GetTotalNumFailingTests();
+            }
 
-            //! Get the total number of tests in the sequence that were queued for execution but did not get the oppurtunity to execute.
-            virtual size_t GetTotalNumUnexecutedTests() const;
+            //! Returns the total number of unexecuted tests across all test targets in all test run reports.
+            virtual size_t GetTotalNumDisabledTests() const
+            {
+                return m_selectedTestRunReport.GetTotalNumDisabledTests();
+            }
+
+            //! Get the total number of test runs in the sequence that passed.
+            virtual size_t GetTotalNumPassingTestRuns() const
+            {
+                return m_selectedTestRunReport.GetNumPassingTestRuns();
+            }
+
+            //! Get the total number of test runs in the sequence that contain one or more test failures.
+            virtual size_t GetTotalNumFailingTestRuns() const
+            {
+                return m_selectedTestRunReport.GetNumFailingTestRuns();
+            }
+
+            //! Returns the total number of test runs that failed to execute.
+            virtual size_t GetTotalNumExecutionFailureTestRuns() const
+            {
+                return m_selectedTestRunReport.GetNumExecutionFailureTestRuns();
+            }
+
+            //! Get the total number of test runs in the sequence that timed out whilst in flight.
+            virtual size_t GetTotalNumTimedOutTestRuns() const
+            {
+                return m_selectedTestRunReport.GetNumTimedOutTestRuns();
+            }
+
+            //! Get the total number of test runs in the sequence that were queued for execution but did not get the opportunity to execute.
+            virtual size_t GetTotalNumUnexecutedTestRuns() const
+            {
+                return m_selectedTestRunReport.GetNumUnexecutedTestRuns();
+            }
 
         private:
-            SuiteType m_suite;
-            TestRunSelection m_selectedTests;
+            SequenceReportType m_type;
+            size_t m_maxConcurrency = 0;
+            AZStd::optional m_testTargetTimeout;
+            AZStd::optional m_globalTimeout;
+            PolicyStateType m_policyState;
+            SuiteType m_suite = SuiteType::Main;
+            TestRunSelection m_selectedTestRuns;
             TestRunReport m_selectedTestRunReport;
         };
 
-        //! Report detailing a test run sequence of selected and drafted tests.
-        class DraftingSequenceReport
-            : public SequenceReport
+        //! Report type for regular test sequences.
+        class RegularSequenceReport
+             : public SequenceReportBase
         {
         public:
-            //! Constructs the report for a sequence of selected and drafted tests.
+            //! Constructs the report for a regular sequence.
+            //! @param maxConcurrency The maximum number of concurrent test targets in flight at any given time.
+            //! @param testTargetTimeout The maximum duration individual test targets may be in flight for (infinite if empty).
+            //! @param globalTimeout The maximum duration the entire test sequence may run for (infinite if empty).
+            //! @param policyState The policy state this sequence was executed under.
             //! @param suiteType The suite from which the tests have been selected from.
-            //! @param selectedTests The target names of the selected tests.
-            //! @param draftedTests The target names of the drafted tests.
+            //! @param selectedTestRuns The target names of the selected test runs.
+            //! @param selectedTestRunReport The report for the set of selected test runs.
+            RegularSequenceReport(
+                size_t maxConcurrency,
+                const AZStd::optional& testTargetTimeout,
+                const AZStd::optional& globalTimeout,
+                const SequencePolicyState& policyState,
+                SuiteType suiteType,
+                const TestRunSelection& selectedTestRuns,
+                TestRunReport&& selectedTestRunReport);
+        };
+
+        //! Report type for seed test sequences.
+        class SeedSequenceReport
+             : public SequenceReportBase
+        {
+        public:
+            //! Constructs the report for a seed sequence.
+            //! @param maxConcurrency The maximum number of concurrent test targets in flight at any given time.
+            //! @param testTargetTimeout The maximum duration individual test targets may be in flight for (infinite if empty).
+            //! @param globalTimeout The maximum duration the entire test sequence may run for (infinite if empty).
+            //! @param policyState The policy state this sequence was executed under.
+            //! @param suiteType The suite from which the tests have been selected from.
+            //! @param selectedTestRuns The target names of the selected test runs.
+            //! @param selectedTestRunReport The report for the set of selected test runs.
+            SeedSequenceReport(
+                size_t maxConcurrency,
+                const AZStd::optional& testTargetTimeout,
+                const AZStd::optional& globalTimeout,
+                const SequencePolicyState& policyState,
+                SuiteType suiteType,
+                const TestRunSelection& selectedTestRuns,
+                TestRunReport&& selectedTestRunReport);
+        };
+
+        //! Report detailing a test run sequence of selected and drafted tests.
+        template
+        class DraftingSequenceReportBase
+            : public SequenceReportBase
+        {
+        public:
+            //! Constructs the report for sequences that draft in previously failed/newly added test targets.
+            //! @param type The type of sequence this report is generated for.
+            //! @param maxConcurrency The maximum number of concurrent test targets in flight at any given time.
+            //! @param testTargetTimeout The maximum duration individual test targets may be in flight for (infinite if empty).
+            //! @param globalTimeout The maximum duration the entire test sequence may run for (infinite if empty).
+            //! @param policyState The policy state this sequence was executed under.
+            //! @param suiteType The suite from which the tests have been selected from.
+            //! @param selectedTestRuns The target names of the selected test runs.
+            //! @param draftedTestRuns The target names of the drafted test runs.
             //! @param selectedTestRunReport The report for the set of selected test runs.
             //! @param draftedTestRunReport The report for the set of drafted test runs.
-            DraftingSequenceReport(
+            DraftingSequenceReportBase(
+                SequenceReportType type,
+                size_t maxConcurrency,
+                const AZStd::optional& testTargetTimeout,
+                const AZStd::optional& globalTimeout,
+                const PolicyStateType& policyState,
                 SuiteType suiteType,
-                const TestRunSelection& selectedTests,
-                const AZStd::vector& draftedTests,
+                const TestRunSelection& selectedTestRuns,
+                const AZStd::vector& draftedTestRuns,
                 TestRunReport&& selectedTestRunReport,
-                TestRunReport&& draftedTestRunReport);
+                TestRunReport&& draftedTestRunReport)
+                : SequenceReportBase(
+                    type,
+                    maxConcurrency,
+                    testTargetTimeout,
+                    globalTimeout,
+                    policyState,
+                    suiteType,
+                    selectedTestRuns,
+                    AZStd::move(selectedTestRunReport))
+                , m_draftedTestRuns(draftedTestRuns)
+                , m_draftedTestRunReport(AZStd::move(draftedTestRunReport))
+            {
+            }
 
-            // SequenceReport overrides ...
-            TestSequenceResult GetResult() const override;
-            AZStd::chrono::milliseconds GetDuration() const override;
-            size_t GetTotalNumPassingTests() const override;
-            size_t GetTotalNumFailingTests() const override;
-            size_t GetTotalNumTimedOutTests() const override;
-            size_t GetTotalNumUnexecutedTests() const override;
-
-             //! Returns the tests drafted for running in the sequence.
-            const AZStd::vector& GetDraftedTests() const;
+            //! Returns the tests drafted for running in the sequence.
+            const AZStd::vector& GetDraftedTestRuns() const
+            {
+                return m_draftedTestRuns;
+            }
 
             //! Returns the report for the drafted test runs.
-            TestRunReport GetDraftedTestRunReport() const;
+            TestRunReport GetDraftedTestRunReport() const
+            {
+                return m_draftedTestRunReport;
+            }
 
+            // SequenceReport overrides ...
+            AZStd::chrono::milliseconds GetDuration() const override
+            {
+                return SequenceReportBase::GetDuration() + m_draftedTestRunReport.GetDuration();
+            }
+
+            TestSequenceResult GetResult() const override
+            {
+                return CalculateMultiTestSequenceResult({ SequenceReportBase::GetResult(), m_draftedTestRunReport.GetResult() });
+            }
+
+            size_t GetTotalNumTestRuns() const override
+            {
+                return SequenceReportBase::GetTotalNumTestRuns() + m_draftedTestRunReport.GetTotalNumTestRuns();
+            }
+
+            size_t GetTotalNumPassingTests() const override
+            {
+                return SequenceReportBase::GetTotalNumPassingTests() + m_draftedTestRunReport.GetTotalNumPassingTests();
+            }
+
+            size_t GetTotalNumFailingTests() const override
+            {
+                return SequenceReportBase::GetTotalNumFailingTests() + m_draftedTestRunReport.GetTotalNumFailingTests();
+            }
+
+            size_t GetTotalNumDisabledTests() const override
+            {
+                return SequenceReportBase::GetTotalNumDisabledTests() + m_draftedTestRunReport.GetTotalNumDisabledTests();
+            }
+
+            size_t GetTotalNumPassingTestRuns() const override
+            {
+                return SequenceReportBase::GetTotalNumPassingTestRuns() + m_draftedTestRunReport.GetNumPassingTestRuns();
+            }
+
+            size_t GetTotalNumFailingTestRuns() const override
+            {
+                return SequenceReportBase::GetTotalNumFailingTestRuns() + m_draftedTestRunReport.GetNumFailingTestRuns();
+            }
+
+            size_t GetTotalNumExecutionFailureTestRuns() const override
+            {
+                return SequenceReportBase::GetTotalNumExecutionFailureTestRuns() + m_draftedTestRunReport.GetNumExecutionFailureTestRuns();
+            }
+
+            size_t GetTotalNumTimedOutTestRuns() const override
+            {
+                return SequenceReportBase::GetTotalNumTimedOutTestRuns() + m_draftedTestRunReport.GetNumTimedOutTestRuns();
+            }
+
+            size_t GetTotalNumUnexecutedTestRuns() const override
+            {
+                return SequenceReportBase::GetTotalNumUnexecutedTestRuns() + m_draftedTestRunReport.GetNumUnexecutedTestRuns();
+            }
         private:
-            AZStd::vector m_draftedTests;
+            AZStd::vector m_draftedTestRuns;
             TestRunReport m_draftedTestRunReport;
         };
 
         //! Report detailing an impact analysis sequence of selected, discarded and drafted tests.
         class ImpactAnalysisSequenceReport
-            : public DraftingSequenceReport
+            : public DraftingSequenceReportBase
         {
         public:
-            //! Constructs the report for a sequence of selected and drafted tests.
+            //! Constructs the report for an impact analysis sequence.
+            //! @param maxConcurrency The maximum number of concurrent test targets in flight at any given time.
+            //! @param testTargetTimeout The maximum duration individual test targets may be in flight for (infinite if empty).
+            //! @param globalTimeout The maximum duration the entire test sequence may run for (infinite if empty).
+            //! @param policyState The policy state this sequence was executed under.
             //! @param suiteType The suite from which the tests have been selected from.
-            //! @param selectedTests The target names of the selected tests.
-            //! @param discardedTests The target names of the discarded tests.
-            //! @param draftedTests The target names of the drafted tests.
+            //! @param selectedTestRuns The target names of the selected test runs.
+            //! @param draftedTestRuns The target names of the drafted test runs.
             //! @param selectedTestRunReport The report for the set of selected test runs.
             //! @param draftedTestRunReport The report for the set of drafted test runs.
             ImpactAnalysisSequenceReport(
+                size_t maxConcurrency,
+                const AZStd::optional& testTargetTimeout,
+                const AZStd::optional& globalTimeout,
+                const ImpactAnalysisSequencePolicyState& policyState,
                 SuiteType suiteType,
-                const TestRunSelection& selectedTests,
-                const AZStd::vector& discardedTests,
-                const AZStd::vector& draftedTests,
+                const TestRunSelection& selectedTestRuns,
+                const AZStd::vector& discardedTestRuns,
+                const AZStd::vector& draftedTestRuns,
                 TestRunReport&& selectedTestRunReport,
                 TestRunReport&& draftedTestRunReport);
 
-            //! Returns the tests discarded from running in the sequence.
-            const AZStd::vector& GetDiscardedTests() const;
+            //! Returns the test runs discarded from running in the sequence.
+            const AZStd::vector& GetDiscardedTestRuns() const;
         private:
-            AZStd::vector m_discardedTests;
+            AZStd::vector m_discardedTestRuns;
         };
 
-        //! Report detailing an impact analysis sequence of selected, discarded and drafted tests.
+        //! Report detailing an impact analysis sequence of selected, discarded and drafted test runs.
         class SafeImpactAnalysisSequenceReport
-            : public DraftingSequenceReport
+            : public DraftingSequenceReportBase
         {
         public:
-            //! Constructs the report for a sequence of selected and drafted tests.
+            //! Constructs the report for a sequence of selected, discarded and drafted test runs.
+            //! @param maxConcurrency The maximum number of concurrent test targets in flight at any given time.
+            //! @param testTargetTimeout The maximum duration individual test targets may be in flight for (infinite if empty).
+            //! @param globalTimeout The maximum duration the entire test sequence may run for (infinite if empty).
+            //! @param policyState The policy state this sequence was executed under.
             //! @param suiteType The suite from which the tests have been selected from.
-            //! @param selectedTests The target names of the selected tests.
-            //! @param discardedTests The target names of the discarded tests.
-            //! @param draftedTests The target names of the drafted tests.
+            //! @param selectedTestRuns The target names of the selected test runs.
+            //! @param discardedTestRuns The target names of the discarded test runs.
+            //! @param draftedTestRuns The target names of the drafted test runs.
             //! @param selectedTestRunReport The report for the set of selected test runs.
             //! @param discardedTestRunReport The report for the set of discarded test runs.
             //! @param draftedTestRunReport The report for the set of drafted test runs.
             SafeImpactAnalysisSequenceReport(
+                size_t maxConcurrency,
+                const AZStd::optional& testTargetTimeout,
+                const AZStd::optional& globalTimeout,
+                const SafeImpactAnalysisSequencePolicyState& policyState,
                 SuiteType suiteType,
-                const TestRunSelection& selectedTests,
-                const TestRunSelection& discardedTests,
-                const AZStd::vector& draftedTests,
+                const TestRunSelection& selectedTestRuns,
+                const TestRunSelection& discardedTestRuns,
+                const AZStd::vector& draftedTestRuns,
                 TestRunReport&& selectedTestRunReport,
                 TestRunReport&& discardedTestRunReport,
                 TestRunReport&& draftedTestRunReport);
 
-            // DraftingSequenceReport overrides ...
-            TestSequenceResult GetResult() const override;
+            // SequenceReport overrides ...
             AZStd::chrono::milliseconds GetDuration() const override;
+            TestSequenceResult GetResult() const override;
+            size_t GetTotalNumTestRuns() const override;
             size_t GetTotalNumPassingTests() const override;
             size_t GetTotalNumFailingTests() const override;
-            size_t GetTotalNumTimedOutTests() const override;
-            size_t GetTotalNumUnexecutedTests() const override;
+            size_t GetTotalNumDisabledTests() const override;
+            size_t GetTotalNumPassingTestRuns() const override;
+            size_t GetTotalNumFailingTestRuns() const override;
+            size_t GetTotalNumExecutionFailureTestRuns() const override;
+            size_t GetTotalNumTimedOutTestRuns() const override;
+            size_t GetTotalNumUnexecutedTestRuns() const override;
 
             //! Returns the report for the discarded test runs.
-            const TestRunSelection GetDiscardedTests() const;
+            const TestRunSelection GetDiscardedTestRuns() const;
 
             //! Returns the report for the discarded test runs.
             TestRunReport GetDiscardedTestRunReport() const;
 
         private:
-            TestRunSelection m_discardedTests;
+            TestRunSelection m_discardedTestRuns;
             TestRunReport m_discardedTestRunReport;
         };
     } // namespace Client
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactClientSequenceReportSerializer.h b/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactClientSequenceReportSerializer.h
new file mode 100644
index 0000000000..fc226588e7
--- /dev/null
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactClientSequenceReportSerializer.h
@@ -0,0 +1,28 @@
+/*
+ * 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
+ *
+ */
+
+#pragma once
+
+#include 
+
+#include 
+
+namespace TestImpact
+{
+    //! Serializes a regular sequence report to JSON format.
+    AZStd::string SerializeSequenceReport(const Client::RegularSequenceReport& sequenceReport);
+
+    //! Serializes a seed sequence report to JSON format.
+    AZStd::string SerializeSequenceReport(const Client::SeedSequenceReport& sequenceReport);
+
+    //! Serializes an impact analysis sequence report to JSON format.
+    AZStd::string SerializeSequenceReport(const Client::ImpactAnalysisSequenceReport& sequenceReport);
+
+    //! Serializes a safe impact analysis sequence report to JSON format.
+    AZStd::string SerializeSequenceReport(const Client::SafeImpactAnalysisSequenceReport& sequenceReport);
+} // namespace TestImpact
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactClientTestRun.h b/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactClientTestRun.h
index 4b7715bf1d..f22963b5e6 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactClientTestRun.h
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactClientTestRun.h
@@ -26,8 +26,8 @@ namespace TestImpact
             AllTestsPass //!< The test run completed its run and all tests passed.
         };
 
-        //! Representation of a completed test run.
-        class TestRun
+        //! Representation of a test run.
+        class TestRunBase
         {
         public:
             //! Constructs the client facing representation of a given test target's run.
@@ -36,13 +36,15 @@ namespace TestImpact
             //! @param startTime The start time, relative to the sequence start, that this run started.
             //! @param duration The duration that this test run took to complete.
             //! @param result The result of the run.
-            TestRun(
+            TestRunBase(
                 const AZStd::string& name,
                 const AZStd::string& commandString,
                 AZStd::chrono::high_resolution_clock::time_point startTime,
                 AZStd::chrono::milliseconds duration,
                 TestRunResult result);
 
+            virtual ~TestRunBase() = default;
+
             //! Returns the test target name.
             const AZStd::string& GetTargetName() const;
 
@@ -69,75 +71,120 @@ namespace TestImpact
             AZStd::chrono::milliseconds m_duration;
         };
 
-        //! Represents an individual test of a test target that failed.
-        class TestFailure
+        //! Representation of a test run that failed to execute.
+        class TestRunWithExecutionFailure
+            : public TestRunBase
         {
         public:
-            TestFailure(const AZStd::string& testName, const AZStd::string& errorMessage);
+            using TestRunBase::TestRunBase;
+            TestRunWithExecutionFailure(TestRunBase&& testRun);
+        };
 
-            //! Returns the name of the test that failed.
+        //! Representation of a test run that was terminated in-flight due to timing out.
+        class TimedOutTestRun 
+            : public TestRunBase
+        {
+        public:
+            using TestRunBase::TestRunBase;
+            TimedOutTestRun(TestRunBase&& testRun);
+        };
+
+        //! Representation of a test run that was not executed.
+        class UnexecutedTestRun 
+            : public TestRunBase
+        {
+        public:
+            using TestRunBase::TestRunBase;
+            UnexecutedTestRun(TestRunBase&& testRun);
+        };
+
+        // Result of a test executed during a test run.
+        enum class TestResult : AZ::u8
+        {
+            Passed,
+            Failed,
+            NotRun
+        };
+
+        //! Representation of a single test in a test target.
+        class Test
+        {
+        public:
+            //! Constructs the test with the specified name and result.
+            Test(const AZStd::string& testName, TestResult result);
+
+            //! Returns the name of this test.
             const AZStd::string& GetName() const;
 
-            //! Returns the error message of the test that failed.
-            const AZStd::string& GetErrorMessage() const;
+            //! Returns the result of executing this test.
+            TestResult GetResult() const;
 
         private:
             AZStd::string m_name;
-            AZStd::string m_errorMessage;
+            TestResult m_result;
         };
 
-        //! Represents a collection of tests that failed.
-        //! @note Only the failing tests are included in the collection.
-        class TestCaseFailure
+        //! Representation of a test run that completed with or without test failures.
+        class CompletedTestRun
+            : public TestRunBase
         {
         public:
-            TestCaseFailure(const AZStd::string& testCaseName, AZStd::vector&& testFailures);
-
-            //! Returns the name of the test case containing the failing tests.
-            const AZStd::string& GetName() const;
-
-            //! Returns the collection of tests in this test case that failed.
-            const AZStd::vector& GetTestFailures() const;
-
-        private:
-            AZStd::string m_name;
-            AZStd::vector m_testFailures;
-        };
-
-        //! Representation of a test run's failing tests.
-        class TestRunWithTestFailures
-            : public TestRun
-        {
-        public:
-            //! Constructs the client facing representation of a given test target's run.
-            //! @param name The name of the test target.
-            //! @param commandString The command string used to execute this test target.
-            //! @param startTime The start time, relative to the sequence start, that this run started.
+            //! Constructs the test run from the specified test target executaion data.
+            //! @param name The name of the test target for this run.
+            //! @param commandString The command string used to execute the test target for this run.
+            //! @param startTime The start time, offset from the sequence start time, that this test run started.
             //! @param duration The duration that this test run took to complete.
-            //! @param result The result of the run.
-            //! @param testFailures The failing tests for this test run.
-            TestRunWithTestFailures(
+            //! @param result The result of this test run.
+            //! @param tests The tests contained in the test target for this test run.
+            CompletedTestRun(
                 const AZStd::string& name,
                 const AZStd::string& commandString,
                 AZStd::chrono::high_resolution_clock::time_point startTime,
                 AZStd::chrono::milliseconds duration,
                 TestRunResult result,
-                AZStd::vector&& testFailures);
+                AZStd::vector&& tests);
 
-            //! Constructs the client facing representation of a given test target's run.
-            //! @param testRun The test run this run is to be derived from.
-            //! @param testFailures The failing tests for this run.
-            TestRunWithTestFailures(TestRun&& testRun, AZStd::vector&& testFailures);
+            //! Constructs the test run from the specified test target executaion data.
+            CompletedTestRun(TestRunBase&& testRun, AZStd::vector&& tests);
 
-            //! Returns the total number of failing tests in this run.
-            size_t GetNumTestFailures() const;
+            //! Returns the total number of tests in the run.
+            size_t GetTotalNumTests() const;
 
-            //! Returns the test cases in this run containing failing tests.
-            const AZStd::vector& GetTestCaseFailures() const;
+            //! Returns the total number of passing tests in the run.
+            size_t GetTotalNumPassingTests() const;
+
+            //! Returns the total number of failing tests in the run.
+            size_t GetTotalNumFailingTests() const;
+
+            //! Returns the total number of disabled tests in the run.
+            size_t GetTotalNumDisabledTests() const;
+
+            //! Returns the tests in the run.
+            const AZStd::vector& GetTests() const;
 
         private:
-            AZStd::vector m_testCaseFailures;
-            size_t m_numTestFailures = 0;
+            AZStd::vector m_tests;
+            size_t m_totalNumPassingTests = 0;
+            size_t m_totalNumFailingTests = 0;
+            size_t m_totalNumDisabledTests = 0;
+        };
+
+        //! Representation of a test run that completed with no test failures.
+        class PassingTestRun 
+            : public CompletedTestRun
+        {
+        public:
+            using CompletedTestRun::CompletedTestRun;
+            PassingTestRun(TestRunBase&& testRun, AZStd::vector&& tests);
+        };
+
+        //! Representation of a test run that completed with one or more test failures.
+        class FailingTestRun 
+            : public CompletedTestRun
+        {
+        public:
+            using CompletedTestRun::CompletedTestRun;
+            FailingTestRun(TestRunBase&& testRun, AZStd::vector&& tests);
         };
     } // namespace Client
 } // namespace TestImpact
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactConfiguration.h b/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactConfiguration.h
index c10c27c643..fcacd90e71 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactConfiguration.h
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactConfiguration.h
@@ -44,7 +44,7 @@ namespace TestImpact
         {
             RepoPath m_root; //!< Path to the persistent workspace tracked by the repository.
             RepoPath m_enumerationCacheDirectory; //!< Path to the test enumerations cache.
-            AZStd::array m_sparTIAFiles; //!< Paths to the test impact analysis data files for each test suite.
+            AZStd::array m_sparTiaFiles; //!< Paths to the test impact analysis data files for each test suite.
         };
 
         Temp m_temp;
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactPolicy.h b/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactPolicy.h
new file mode 100644
index 0000000000..b400af018a
--- /dev/null
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactPolicy.h
@@ -0,0 +1,81 @@
+/*
+ * 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
+ *
+ */
+
+#pragma once
+
+#include 
+
+namespace TestImpact
+{
+    namespace Policy
+    {
+        //! Policy for handling of test targets that fail to execute (e.g. due to the binary not being found).
+        //! @note Test targets that fail to execute will be tagged such that their execution can be attempted at a later date. This is
+        //! important as otherwise it would be erroneously assumed that they cover no sources due to having no entries in the dynamic
+        //! dependency map.
+        enum class ExecutionFailure : AZ::u8
+        {
+            Abort, //!< Abort the test sequence and report a failure.
+            Continue, //!< Continue the test sequence but treat the execution failures as test failures after the run.
+            Ignore //!< Continue the test sequence and ignore the execution failures.
+        };
+
+        //! Policy for handling the coverage data of failed tests targets (both tests that failed to execute and tests that ran but failed).
+        enum class FailedTestCoverage : AZ::u8
+        {
+            Discard, //!< Discard the coverage data produced by the failing tests, causing them to be drafted into future test runs.
+            Keep //!< Keep any existing coverage data and update the coverage data for failed test targets that produce coverage.
+        };
+
+        //! Policy for prioritizing selected tests.
+        enum class TestPrioritization : AZ::u8
+        {
+            None, //!< Do not attempt any test prioritization.
+            DependencyLocality //!< Prioritize test targets according to the locality of the production targets they cover in the build
+                               //!< dependency graph.
+        };
+
+        //! Policy for handling test targets that report failing tests.
+        enum class TestFailure : AZ::u8
+        {
+            Abort, //!< Abort the test sequence and report the test failure.
+            Continue //!< Continue the test sequence and report the test failures after the run.
+        };
+
+        //! Policy for handling integrity failures of the dynamic dependency map and the source to target mappings.
+        enum class IntegrityFailure : AZ::u8
+        {
+            Abort, //!< Abort the test sequence and report the test failure.
+            Continue //!< Continue the test sequence and report the test failures after the run.
+        };
+
+        //! Policy for updating the dynamic dependency map with the coverage data of produced by test sequences.
+        enum class DynamicDependencyMap : AZ::u8
+        {
+            Discard, //!< Discard the coverage data produced by test sequences.
+            Update //!< Update the dynamic dependency map with the coverage data produced by test sequences.
+        };
+
+        //! Policy for sharding test targets that have been marked for test sharding.
+        enum class TestSharding : AZ::u8
+        {
+            Never, //!< Do not shard any test targets.
+            Always //!< Shard all test targets that have been marked for test sharding.
+        };
+
+        //! Standard output capture of test target runs.
+        enum class TargetOutputCapture : AZ::u8
+        {
+            None, //!< Do not capture any output.
+            StdOut, //!< Send captured output to standard output
+            File, //!< Write captured output to file.
+            StdOutAndFile //!< Send captured output to standard output and write to file.
+        };
+
+    } // namespace Policy
+} // namespace TestImpact
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactRuntime.h b/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactRuntime.h
index 69feb48749..ec8d88eaad 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactRuntime.h
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactRuntime.h
@@ -78,7 +78,7 @@ namespace TestImpact
     //! @param testRunMeta The test that has completed.
     //! @param numTestRunsCompleted The number of test runs that have completed.
     //! @param totalNumTestRuns The total number of test runs in the sequence.
-    using TestRunCompleteCallback = AZStd::function;
+    using TestRunCompleteCallback = AZStd::function;
 
     //! The API exposed to the client responsible for all test runs and persistent data management.
     class Runtime
@@ -86,6 +86,7 @@ namespace TestImpact
     public:
         //! Constructs a runtime with the specified configuration and policies.
         //! @param config The configuration used for this runtime instance.
+        //! @param dataFile The optional data file to be used instead of that specified in the config file.
         //! @param suiteFilter The test suite for which the coverage data and test selection will draw from.
         //! @param executionFailurePolicy Determines how to handle test targets that fail to execute.
         //! @param executionFailureDraftingPolicy Determines how test targets that previously failed to execute are drafted into subsequent test sequences.
@@ -94,6 +95,7 @@ namespace TestImpact
         //! @param testShardingPolicy  Determines how to handle test targets that have opted in to test sharding.
         Runtime(
             RuntimeConfig&& config,
+            AZStd::optional dataFile,
             SuiteType suiteFilter,
             Policy::ExecutionFailure executionFailurePolicy,
             Policy::FailedTestCoverage failedTestCoveragePolicy,
@@ -112,11 +114,11 @@ namespace TestImpact
         //! @param testSequenceCompleteCallback The client function to be called after the test sequence has completed.
         //! @param testRunCompleteCallback The client function to be called after an individual test run has completed.
         //! @returns The test run and sequence report for the selected test sequence.
-        Client::SequenceReport RegularTestSequence(
+        Client::RegularSequenceReport RegularTestSequence(
             AZStd::optional testTargetTimeout,
             AZStd::optional globalTimeout,
             AZStd::optional testSequenceStartCallback,
-            AZStd::optional> testSequenceCompleteCallback,
+            AZStd::optional> testSequenceCompleteCallback,
             AZStd::optional testRunCompleteCallback);
 
         //! Runs a test sequence where tests are selected according to test impact analysis so long as they are not on the excluded list.
@@ -164,11 +166,11 @@ namespace TestImpact
         //! @param testSequenceCompleteCallback The client function to be called after the test sequence has completed.
         //! @param testRunCompleteCallback The client function to be called after an individual test run has completed.
         //! @returns The test run and sequence report for the selected test sequence.
-        Client::SequenceReport SeededTestSequence(
+        Client::SeedSequenceReport SeededTestSequence(
             AZStd::optional testTargetTimeout,
             AZStd::optional globalTimeout,
             AZStd::optional testSequenceStartCallback,
-            AZStd::optional> testSequenceCompleteCallback,
+            AZStd::optional> testSequenceCompleteCallback,
             AZStd::optional testRunCompleteCallback);
 
         //! Returns true if the runtime has test impact analysis data (either preexisting or generated).
@@ -184,7 +186,7 @@ namespace TestImpact
         //! @param changeList The change list for which the covering tests and enumeration cache updates will be generated for.
         //! @param testPrioritizationPolicy The test prioritization strategy to use for the selected test targets.
         //! @returns The pair of selected test targets and discarded test targets.
-        AZStd::pair, AZStd::vector> SelectCoveringTestTargetsAndUpdateEnumerationCache(
+        AZStd::pair, AZStd::vector> SelectCoveringTestTargets(
             const ChangeList& changeList,
             Policy::TestPrioritization testPrioritizationPolicy);
 
@@ -204,8 +206,22 @@ namespace TestImpact
         //! Updates the dynamic dependency map and serializes the entire map to disk.
         void UpdateAndSerializeDynamicDependencyMap(const AZStd::vector& jobs);
 
+        //! Generates a base policy state for the current runtime policy runtime configuration.
+        PolicyStateBase GeneratePolicyStateBase() const;
+
+        //! Generates a regular/seed sequence policy state for the current runtime policy runtime configuration.
+        SequencePolicyState GenerateSequencePolicyState() const;
+
+        //! Generates a safe impact analysis sequence policy state for the current runtime policy runtime configuration.
+        SafeImpactAnalysisSequencePolicyState GenerateSafeImpactAnalysisSequencePolicyState(
+            Policy::TestPrioritization testPrioritizationPolicy) const;
+
+        //! Generates an impact analysis sequence policy state for the current runtime policy runtime configuration.
+        ImpactAnalysisSequencePolicyState GenerateImpactAnalysisSequencePolicyState(
+            Policy::TestPrioritization testPrioritizationPolicy, Policy::DynamicDependencyMap dynamicDependencyMapPolicy) const;
+
         RuntimeConfig m_config;
-        RepoPath m_sparTIAFile;
+        RepoPath m_sparTiaFile;
         SuiteType m_suiteFilter;
         Policy::ExecutionFailure m_executionFailurePolicy;
         Policy::FailedTestCoverage m_failedTestCoveragePolicy;
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactSequenceReportException.h b/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactSequenceReportException.h
new file mode 100644
index 0000000000..72c2d0c530
--- /dev/null
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactSequenceReportException.h
@@ -0,0 +1,22 @@
+/*
+ * 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
+ *
+ */
+
+#pragma once
+
+#include 
+
+namespace TestImpact
+{
+    //! Exception for sequence report operations.
+    class SequenceReportException
+        : public Exception
+    {
+    public:
+        using Exception::Exception;
+    };
+} // namespace TestImpact
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactTestSequence.h b/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactTestSequence.h
index 8841c29644..38b716398c 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactTestSequence.h
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactTestSequence.h
@@ -9,76 +9,12 @@
 #pragma once
 
 #include 
+#include 
 
 #include 
 
 namespace TestImpact
 {
-    namespace Policy
-    {
-        //! Policy for handling of test targets that fail to execute (e.g. due to the binary not being found).
-        //! @note Test targets that fail to execute will be tagged such that their execution can be attempted at a later date. This is
-        //! important as otherwise it would be erroneously assumed that they cover no sources due to having no entries in the dynamic
-        //! dependency map.
-        enum class ExecutionFailure
-        {
-            Abort, //!< Abort the test sequence and report a failure.
-            Continue, //!< Continue the test sequence but treat the execution failures as test failures after the run.
-            Ignore //!< Continue the test sequence and ignore the execution failures.
-        };
-
-        //! Policy for handling the coverage data of failed tests targets (both test that failed to execute and tests that ran but failed).
-        enum class FailedTestCoverage
-        {
-            Discard, //!< Discard the coverage data produced by the failing tests, causing them to be drafted into future test runs.
-            Keep //!< Keep any existing coverage data and update the coverage data for failed test targetss that produce coverage.
-        };
-
-        //! Policy for prioritizing selected tests.
-        enum class TestPrioritization
-        {
-            None, //!< Do not attempt any test prioritization.
-            DependencyLocality //!< Prioritize test targets according to the locality of the production targets they cover in the build dependency graph.
-        };
-
-        //! Policy for handling test targets that report failing tests.
-        enum class TestFailure
-        {
-            Abort, //!< Abort the test sequence and report the test failure.
-            Continue //!< Continue the test sequence and report the test failures after the run.
-        };
-
-        //! Policy for handling integrity failures of the dynamic dependency map and the source to target mappings.
-        enum class IntegrityFailure
-        {
-            Abort, //!< Abort the test sequence and report the test failure.
-            Continue //!< Continue the test sequence and report the test failures after the run.
-        };
-
-        //! Policy for updating the dynamic dependency map with the coverage data of produced by test sequences.
-        enum class DynamicDependencyMap
-        {
-            Discard, //!< Discard the coverage data produced by test sequences.
-            Update //!< Update the dynamic dependency map with the coverage data produced by test sequences.
-        };
-
-        //! Policy for sharding test targets that have been marked for test sharding.
-        enum class TestSharding
-        {
-            Never, //!< Do not shard any test targets.
-            Always //!< Shard all test targets that have been marked for test sharding.
-        };
-
-        //! Standard output capture of test target runs. 
-        enum class TargetOutputCapture
-        {
-            None, //!< Do not capture any output.
-            StdOut, //!< Send captured output to standard output
-            File, //!< Write captured output to file.
-            StdOutAndFile //!< Send captured output to standard output and write to file.
-        };
-    }   
-
     //! Configuration for test targets that opt in to test sharding.
     enum class ShardConfiguration
     {
@@ -97,22 +33,6 @@ namespace TestImpact
         Sandbox
     };
 
-    //! User-friendly names for the test suite types.
-    inline AZStd::string GetSuiteTypeName(SuiteType suiteType)
-    {
-        switch (suiteType)
-        {
-        case SuiteType::Main:
-            return "main";
-        case SuiteType::Periodic:
-            return "periodic";
-        case SuiteType::Sandbox:
-            return "sandbox";
-        default:
-            throw(RuntimeException("Unexpected suite type"));
-        }
-    }
-
     //! Result of a test sequence that was run.
     enum class TestSequenceResult
     {
@@ -120,4 +40,36 @@ namespace TestImpact
         Failure, //!< One or more tests failed and/or timed out and/or failed to launch and/or an integrity failure was encountered.
         Timeout //!< The global timeout for the sequence was exceeded.
     };
+
+    //! Base representation of runtime policies.
+    struct PolicyStateBase
+    {
+        Policy::ExecutionFailure m_executionFailurePolicy = Policy::ExecutionFailure::Continue;
+        Policy::FailedTestCoverage m_failedTestCoveragePolicy = Policy::FailedTestCoverage::Keep;
+        Policy::TestFailure m_testFailurePolicy = Policy::TestFailure::Abort;
+        Policy::IntegrityFailure m_integrityFailurePolicy = Policy::IntegrityFailure::Abort;
+        Policy::TestSharding m_testShardingPolicy = Policy::TestSharding::Never;
+        Policy::TargetOutputCapture m_targetOutputCapture = Policy::TargetOutputCapture::None;
+    };
+
+    //! Representation of regular and seed sequence policies.
+    struct SequencePolicyState
+    {
+        PolicyStateBase m_basePolicies;
+    };
+
+    //! Representation of impact analysis sequence policies.
+    struct ImpactAnalysisSequencePolicyState
+    {
+        PolicyStateBase m_basePolicies;
+        Policy::TestPrioritization m_testPrioritizationPolicy = Policy::TestPrioritization::None;
+        Policy::DynamicDependencyMap m_dynamicDependencyMap = Policy::DynamicDependencyMap::Update;
+    };
+
+    //! Representation of safe impact analysis sequence policies.
+    struct SafeImpactAnalysisSequencePolicyState
+    {
+        PolicyStateBase m_basePolicies;
+        Policy::TestPrioritization m_testPrioritizationPolicy = Policy::TestPrioritization::None;
+    };
 } // namespace TestImpact
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactFileUtils.h b/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactUtils.h
similarity index 51%
rename from Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactFileUtils.h
rename to Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactUtils.h
index f77008ffa7..c4625e9d2c 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactFileUtils.h
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactUtils.h
@@ -6,12 +6,12 @@
  *
  */
 
-#include 
-#include 
+#include 
+#include 
+#include 
 
 #include 
 #include 
-#include 
 
 #pragma once
 
@@ -59,23 +59,48 @@ namespace TestImpact
     //! Delete the files that match the pattern from the specified directory.
     //! @param path The path to the directory to pattern match the files for deletion.
     //! @param pattern The pattern to match files for deletion.
-    inline void DeleteFiles(const RepoPath& path, const AZStd::string& pattern)
-    {
-        AZ::IO::SystemFile::FindFiles(AZStd::string::format("%s/%s", path.c_str(), pattern.c_str()).c_str(),
-            [&path](const char* file, bool isFile)
-        {
-            if (isFile)
-            {
-                AZ::IO::SystemFile::Delete(AZStd::string::format("%s/%s", path.c_str(), file).c_str());
-            }
-
-            return true;
-        });
-    }
+    //! @return The number of files that were deleted.
+    size_t DeleteFiles(const RepoPath& path, const AZStd::string& pattern);
 
     //! Deletes the specified file.
-    inline void DeleteFile(const RepoPath& file)
-    {
-        DeleteFiles(file.ParentPath(), file.Filename().Native());
-    }
+    void DeleteFile(const RepoPath& file);
+
+    //! User-friendly names for the test suite types.
+    AZStd::string SuiteTypeAsString(SuiteType suiteType);
+
+    //! User-friendly names for the sequence report types.
+    AZStd::string SequenceReportTypeAsString(Client::SequenceReportType type);
+
+    //! User-friendly names for the sequence result types.
+    AZStd::string TestSequenceResultAsString(TestSequenceResult result);
+
+    //! User-friendly names for the test run result types.
+    AZStd::string TestRunResultAsString(Client::TestRunResult result);
+
+    //! User-friendly names for the execution failure policy types.
+    AZStd::string ExecutionFailurePolicyAsString(Policy::ExecutionFailure executionFailurePolicy);
+
+    //! User-friendly names for the failed test coverage policy types.
+    AZStd::string FailedTestCoveragePolicyAsString(Policy::FailedTestCoverage failedTestCoveragePolicy);
+
+    //! User-friendly names for the test prioritization policy types.
+    AZStd::string TestPrioritizationPolicyAsString(Policy::TestPrioritization testPrioritizationPolicy);
+
+    //! User-friendly names for the test failure policy types.
+    AZStd::string TestFailurePolicyAsString(Policy::TestFailure testFailurePolicy);
+
+    //! User-friendly names for the integrity failure policy types.
+    AZStd::string IntegrityFailurePolicyAsString(Policy::IntegrityFailure integrityFailurePolicy);
+
+    //! User-friendly names for the dynamic dependency map policy types.
+    AZStd::string DynamicDependencyMapPolicyAsString(Policy::DynamicDependencyMap dynamicDependencyMapPolicy);
+
+    //! User-friendly names for the test sharding policy types.
+    AZStd::string TestShardingPolicyAsString(Policy::TestSharding testShardingPolicy);
+
+    //! User-friendly names for the target output capture policy types.
+    AZStd::string TargetOutputCapturePolicyAsString(Policy::TargetOutputCapture targetOutputCapturePolicy);
+
+    //! User-friendly names for the client test result types.
+    AZStd::string ClientTestResultAsString(Client::TestResult result);
 } // namespace TestImpact
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Artifact/Factory/TestImpactTestTargetMetaMapFactory.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Artifact/Factory/TestImpactTestTargetMetaMapFactory.cpp
index d69177814f..4c8d71bba1 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Artifact/Factory/TestImpactTestTargetMetaMapFactory.cpp
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Artifact/Factory/TestImpactTestTargetMetaMapFactory.cpp
@@ -6,6 +6,8 @@
  *
  */
 
+#include 
+
 #include 
 #include 
 
@@ -67,7 +69,7 @@ namespace TestImpact
             {
                 // Check to see if this test target has the suite we're looking for
                 if (const auto suiteName = suite[Keys[SuiteKey]].GetString();
-                    strcmp(GetSuiteTypeName(suiteType).c_str(), suiteName) == 0)
+                    strcmp(SuiteTypeAsString(suiteType).c_str(), suiteName) == 0)
                 {
                     testMeta.m_suite = suiteName;
                     testMeta.m_customArgs = suite[Keys[CommandKey]].GetString();
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactDynamicDependencyMap.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactDynamicDependencyMap.cpp
index 1c79494c30..af32171b2b 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactDynamicDependencyMap.cpp
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactDynamicDependencyMap.cpp
@@ -156,8 +156,6 @@ namespace TestImpact
                 {
                     coveringTestTargetIt->second.erase(source);
                 }
-
-                
             }
 
             // 2.
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactDynamicDependencyMap.h b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactDynamicDependencyMap.h
index 5309a00894..d63938930f 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactDynamicDependencyMap.h
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactDynamicDependencyMap.h
@@ -9,7 +9,7 @@
 #pragma once
 
 #include 
-#include 
+#include 
 
 #include 
 #include 
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactTestSelectorAndPrioritizer.h b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactTestSelectorAndPrioritizer.h
index 4f266af8d2..bcfd8d24d5 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactTestSelectorAndPrioritizer.h
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactTestSelectorAndPrioritizer.h
@@ -8,7 +8,7 @@
 
 #pragma once
 
-#include 
+#include 
 
 #include 
 #include 
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Platform/Windows/Process/TestImpactWin32_Process.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Platform/Windows/Process/TestImpactWin32_Process.cpp
index 2630a63bee..7ba061f932 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Platform/Windows/Process/TestImpactWin32_Process.cpp
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Platform/Windows/Process/TestImpactWin32_Process.cpp
@@ -11,6 +11,7 @@
 #include 
 
 #include 
+#include 
 
 namespace TestImpact
 {
@@ -55,9 +56,11 @@ namespace TestImpact
 
         CreatePipes(sa, si);
 
-        if (!CreateProcess(
+        AZStd::wstring argsW;
+        AZStd::to_wstring(argsW, args.c_str());
+        if (!CreateProcessW(
             NULL,
-            &args[0],
+            argsW.data(),
             NULL,
             NULL,
             IsPiping(),
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/Enumeration/TestImpactTestEnumerator.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/Enumeration/TestImpactTestEnumerator.cpp
index c2ba00835a..e564b93f6c 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/Enumeration/TestImpactTestEnumerator.cpp
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/Enumeration/TestImpactTestEnumerator.cpp
@@ -6,7 +6,7 @@
  *
  */
 
-#include 
+#include 
 
 #include 
 #include 
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/Run/TestImpactInstrumentedTestRunner.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/Run/TestImpactInstrumentedTestRunner.cpp
index cad8df1449..bf7e4d2c34 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/Run/TestImpactInstrumentedTestRunner.cpp
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/Run/TestImpactInstrumentedTestRunner.cpp
@@ -6,7 +6,7 @@
  *
  */
 
-#include 
+#include 
 
 #include 
 #include 
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/Run/TestImpactTestRunner.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/Run/TestImpactTestRunner.cpp
index a138e329b6..a480f4aa4a 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/Run/TestImpactTestRunner.cpp
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/Run/TestImpactTestRunner.cpp
@@ -6,7 +6,7 @@
  *
  */
 
-#include 
+#include 
 
 #include 
 #include 
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngine.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngine.cpp
index 226301d444..c84700065f 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngine.cpp
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngine.cpp
@@ -6,7 +6,7 @@
  *
  */
 
-#include 
+#include 
 
 #include 
 #include 
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactClientSequenceReport.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactClientSequenceReport.cpp
index ba3a479fdf..3f4656758a 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactClientSequenceReport.cpp
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactClientSequenceReport.cpp
@@ -1,6 +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.
- * 
+ * 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
  *
  */
@@ -11,7 +12,6 @@ namespace TestImpact
 {
     namespace Client
     {
-        //! Calculates the final sequence result for a composite of multiple sequences.
         TestSequenceResult CalculateMultiTestSequenceResult(const AZStd::vector& results)
         {
             // Order of precedence:
@@ -19,14 +19,12 @@ namespace TestImpact
             // 2. TestSequenceResult::Timeout
             // 3. TestSequenceResult::Success
 
-            if (const auto it = AZStd::find(results.begin(), results.end(), TestSequenceResult::Failure);
-                it != results.end())
+            if (const auto it = AZStd::find(results.begin(), results.end(), TestSequenceResult::Failure); it != results.end())
             {
                 return TestSequenceResult::Failure;
             }
-            
-            if (const auto it = AZStd::find(results.begin(), results.end(), TestSequenceResult::Timeout);
-                it != results.end())
+
+            if (const auto it = AZStd::find(results.begin(), results.end(), TestSequenceResult::Timeout); it != results.end())
             {
                 return TestSequenceResult::Timeout;
             }
@@ -38,20 +36,32 @@ namespace TestImpact
             TestSequenceResult result,
             AZStd::chrono::high_resolution_clock::time_point startTime,
             AZStd::chrono::milliseconds duration,
-            AZStd::vector&& passingTests,
-            AZStd::vector&& failingTests,
-            AZStd::vector&& executionFailureTests,
-            AZStd::vector&& timedOutTests,
-            AZStd::vector&& unexecutedTests)
+            AZStd::vector&& passingTestRuns,
+            AZStd::vector&& failingTestRuns,
+            AZStd::vector&& executionFailureTestRuns,
+            AZStd::vector&& timedOutTestRuns,
+            AZStd::vector&& unexecutedTestRuns)
             : m_startTime(startTime)
             , m_result(result)
             , m_duration(duration)
-            , m_passingTests(AZStd::move(passingTests))
-            , m_failingTests(AZStd::move(failingTests))
-            , m_executionFailureTests(AZStd::move(executionFailureTests))
-            , m_timedOutTests(AZStd::move(timedOutTests))
-            , m_unexecutedTests(AZStd::move(unexecutedTests))
+            , m_passingTestRuns(AZStd::move(passingTestRuns))
+            , m_failingTestRuns(AZStd::move(failingTestRuns))
+            , m_executionFailureTestRuns(AZStd::move(executionFailureTestRuns))
+            , m_timedOutTestRuns(AZStd::move(timedOutTestRuns))
+            , m_unexecutedTestRuns(AZStd::move(unexecutedTestRuns))
         {
+            for (const auto& failingTestRun : m_failingTestRuns)
+            {
+                m_totalNumPassingTests += failingTestRun.GetTotalNumPassingTests();
+                m_totalNumFailingTests += failingTestRun.GetTotalNumFailingTests();
+                m_totalNumDisabledTests += failingTestRun.GetTotalNumDisabledTests();
+            }
+
+            for (const auto& passingTestRun : m_passingTestRuns)
+            {
+                m_totalNumPassingTests += passingTestRun.GetTotalNumPassingTests();
+                m_totalNumDisabledTests += passingTestRun.GetTotalNumDisabledTests();
+            }
         }
 
         TestSequenceResult TestRunReport::GetResult() const
@@ -74,234 +84,238 @@ namespace TestImpact
             return m_duration;
         }
 
-        size_t TestRunReport::GetNumPassingTests() const
+        size_t TestRunReport::GetTotalNumTestRuns() const
         {
-            return m_passingTests.size();
+            return
+                GetNumPassingTestRuns() +
+                GetNumFailingTestRuns() +
+                GetNumExecutionFailureTestRuns() +
+                GetNumTimedOutTestRuns() +
+                GetNumUnexecutedTestRuns();
         }
 
-        size_t TestRunReport::GetNumFailingTests() const
+        size_t TestRunReport::GetNumPassingTestRuns() const
         {
-            return m_failingTests.size();
+            return m_passingTestRuns.size();
         }
 
-        size_t TestRunReport::GetNumTimedOutTests() const
+        size_t TestRunReport::GetNumFailingTestRuns() const
         {
-            return m_timedOutTests.size();
+            return m_failingTestRuns.size();
         }
 
-        size_t TestRunReport::GetNumUnexecutedTests() const
+        size_t TestRunReport::GetNumExecutionFailureTestRuns() const
         {
-            return m_unexecutedTests.size();
+            return m_executionFailureTestRuns.size();
         }
 
-        const AZStd::vector& TestRunReport::GetPassingTests() const
+        size_t TestRunReport::TestRunReport::GetNumTimedOutTestRuns() const
         {
-            return m_passingTests;
+            return m_timedOutTestRuns.size();
         }
 
-        const AZStd::vector& TestRunReport::GetFailingTests() const
+        size_t TestRunReport::GetNumUnexecutedTestRuns() const
         {
-            return m_failingTests;
+            return m_unexecutedTestRuns.size();
         }
 
-        const AZStd::vector& TestRunReport::GetExecutionFailureTests() const
+        const AZStd::vector& TestRunReport::GetPassingTestRuns() const
         {
-            return m_executionFailureTests;
+            return m_passingTestRuns;
         }
 
-        const AZStd::vector& TestRunReport::GetTimedOutTests() const
+        const AZStd::vector& TestRunReport::GetFailingTestRuns() const
         {
-            return m_timedOutTests;
+            return m_failingTestRuns;
         }
 
-        const AZStd::vector& TestRunReport::GetUnexecutedTests() const
+        const AZStd::vector& TestRunReport::GetExecutionFailureTestRuns() const
         {
-            return m_unexecutedTests;
+            return m_executionFailureTestRuns;
         }
 
-        SequenceReport::SequenceReport(SuiteType suiteType, const TestRunSelection& selectedTests, TestRunReport&& selectedTestRunReport)
-            : m_suite(suiteType)
-            , m_selectedTests(selectedTests)
-            , m_selectedTestRunReport(AZStd::move(selectedTestRunReport))
+        const AZStd::vector& TestRunReport::GetTimedOutTestRuns() const
         {
+            return m_timedOutTestRuns;
         }
 
-        TestSequenceResult SequenceReport::GetResult() const
+        const AZStd::vector& TestRunReport::GetUnexecutedTestRuns() const
         {
-            return m_selectedTestRunReport.GetResult();
+            return m_unexecutedTestRuns;
         }
 
-        AZStd::chrono::high_resolution_clock::time_point SequenceReport::GetStartTime() const
+        size_t TestRunReport::GetTotalNumPassingTests() const
         {
-            return m_selectedTestRunReport.GetStartTime();
+            return m_totalNumPassingTests;
         }
 
-        AZStd::chrono::high_resolution_clock::time_point SequenceReport::GetEndTime() const
+        size_t TestRunReport::GetTotalNumFailingTests() const
         {
-            return GetStartTime() + GetDuration();
+            return m_totalNumFailingTests;
         }
 
-        AZStd::chrono::milliseconds SequenceReport::GetDuration() const
+        size_t TestRunReport::GetTotalNumDisabledTests() const
         {
-            return m_selectedTestRunReport.GetDuration();
+            return m_totalNumDisabledTests;
         }
 
-        TestRunSelection SequenceReport::GetSelectedTests() const
-        {
-            return m_selectedTests;
-        }
-
-        TestRunReport SequenceReport::GetSelectedTestRunReport() const
-        {
-            return m_selectedTestRunReport;
-        }
-
-        size_t SequenceReport::GetTotalNumPassingTests() const
-        {
-            return m_selectedTestRunReport.GetNumPassingTests();
-        }
-
-        size_t SequenceReport::GetTotalNumFailingTests() const
-        {
-            return m_selectedTestRunReport.GetNumFailingTests();
-        }
-
-        size_t SequenceReport::GetTotalNumTimedOutTests() const
-        {
-            return m_selectedTestRunReport.GetNumTimedOutTests();
-        }
-
-        size_t SequenceReport::GetTotalNumUnexecutedTests() const
-        {
-            return m_selectedTestRunReport.GetNumUnexecutedTests();
-        }
-
-        DraftingSequenceReport::DraftingSequenceReport(
+        RegularSequenceReport::RegularSequenceReport(
+            size_t maxConcurrency,
+            const AZStd::optional& testTargetTimeout,
+            const AZStd::optional& globalTimeout,
+            const SequencePolicyState& policyState,
             SuiteType suiteType,
-            const TestRunSelection& selectedTests,
-            const AZStd::vector& draftedTests,
-            TestRunReport&& selectedTestRunReport,
-            TestRunReport&& draftedTestRunReport)
-            : SequenceReport(suiteType, selectedTests, AZStd::move(selectedTestRunReport))
-            , m_draftedTests(draftedTests)
-            , m_draftedTestRunReport(AZStd::move(draftedTestRunReport))
+            const TestRunSelection& selectedTestRuns,
+            TestRunReport&& selectedTestRunReport)
+            : SequenceReportBase(
+                  SequenceReportType::RegularSequence,
+                  maxConcurrency,
+                  testTargetTimeout,
+                  globalTimeout,
+                  policyState,
+                  suiteType,
+                  selectedTestRuns,
+                  AZStd::move(selectedTestRunReport))
         {
         }
 
-        TestSequenceResult DraftingSequenceReport::GetResult() const
+        SeedSequenceReport::SeedSequenceReport(
+            size_t maxConcurrency,
+            const AZStd::optional& testTargetTimeout,
+            const AZStd::optional& globalTimeout,
+            const SequencePolicyState& policyState,
+            SuiteType suiteType,
+            const TestRunSelection& selectedTestRuns,
+            TestRunReport&& selectedTestRunReport)
+            : SequenceReportBase(
+                  SequenceReportType::SeedSequence,
+                  maxConcurrency,
+                  testTargetTimeout,
+                  globalTimeout,
+                  policyState,
+                  suiteType,
+                  selectedTestRuns,
+                  AZStd::move(selectedTestRunReport))
         {
-            return CalculateMultiTestSequenceResult({SequenceReport::GetResult(), m_draftedTestRunReport.GetResult()});
-        }
-
-        AZStd::chrono::milliseconds DraftingSequenceReport::GetDuration() const
-        {
-            return SequenceReport::GetDuration() + m_draftedTestRunReport.GetDuration();
-        }
-
-        size_t DraftingSequenceReport::GetTotalNumPassingTests() const
-        {
-            return SequenceReport::GetTotalNumPassingTests() + m_draftedTestRunReport.GetNumPassingTests();
-        }
-
-        size_t DraftingSequenceReport::GetTotalNumFailingTests() const
-        {
-            return SequenceReport::GetTotalNumFailingTests() + m_draftedTestRunReport.GetNumFailingTests();
-        }
-
-        size_t DraftingSequenceReport::GetTotalNumTimedOutTests() const
-        {
-            return SequenceReport::GetTotalNumTimedOutTests() + m_draftedTestRunReport.GetNumTimedOutTests();
-        }
-
-        size_t DraftingSequenceReport::GetTotalNumUnexecutedTests() const
-        {
-            return SequenceReport::GetTotalNumUnexecutedTests() + m_draftedTestRunReport.GetNumUnexecutedTests();
-        }
-
-        const AZStd::vector& DraftingSequenceReport::GetDraftedTests() const
-        {
-            return m_draftedTests;
-        }
-
-        TestRunReport DraftingSequenceReport::GetDraftedTestRunReport() const
-        {
-            return m_draftedTestRunReport;
         }
 
         ImpactAnalysisSequenceReport::ImpactAnalysisSequenceReport(
+            size_t maxConcurrency,
+            const AZStd::optional& testTargetTimeout,
+            const AZStd::optional& globalTimeout,
+            const ImpactAnalysisSequencePolicyState& policyState,
             SuiteType suiteType,
-            const TestRunSelection& selectedTests,
-            const AZStd::vector& discardedTests,
-            const AZStd::vector& draftedTests,
+            const TestRunSelection& selectedTestRuns,
+            const AZStd::vector& discardedTestRuns,
+            const AZStd::vector& draftedTestRuns,
             TestRunReport&& selectedTestRunReport,
             TestRunReport&& draftedTestRunReport)
-            : DraftingSequenceReport(
-                  suiteType,
-                  selectedTests,
-                  draftedTests,
-                  AZStd::move(selectedTestRunReport),
-                  AZStd::move(draftedTestRunReport))
-            , m_discardedTests(discardedTests)
+            : DraftingSequenceReportBase(
+                SequenceReportType::ImpactAnalysisSequence,
+                maxConcurrency,
+                testTargetTimeout,
+                globalTimeout,
+                policyState,
+                suiteType,
+                selectedTestRuns,
+                draftedTestRuns,
+                AZStd::move(selectedTestRunReport),
+                AZStd::move(draftedTestRunReport))
+            , m_discardedTestRuns(discardedTestRuns)
         {
         }
 
-        const AZStd::vector& ImpactAnalysisSequenceReport::GetDiscardedTests() const
+        const AZStd::vector& ImpactAnalysisSequenceReport::GetDiscardedTestRuns() const
         {
-            return m_discardedTests;
+            return m_discardedTestRuns;
         }
 
         SafeImpactAnalysisSequenceReport::SafeImpactAnalysisSequenceReport(
+            size_t maxConcurrency,
+            const AZStd::optional& testTargetTimeout,
+            const AZStd::optional& globalTimeout,
+            const SafeImpactAnalysisSequencePolicyState& policyState,
             SuiteType suiteType,
-            const TestRunSelection& selectedTests,
-            const TestRunSelection& discardedTests,
-            const AZStd::vector& draftedTests,
+            const TestRunSelection& selectedTestRuns,
+            const TestRunSelection& discardedTestRuns,
+            const AZStd::vector& draftedTestRuns,
             TestRunReport&& selectedTestRunReport,
             TestRunReport&& discardedTestRunReport,
             TestRunReport&& draftedTestRunReport)
-            : DraftingSequenceReport(
-                  suiteType,
-                  selectedTests,
-                  draftedTests,
-                  AZStd::move(selectedTestRunReport),
-                  AZStd::move(draftedTestRunReport))
-            , m_discardedTests(discardedTests)
+            : DraftingSequenceReportBase(
+                SequenceReportType::SafeImpactAnalysisSequence,
+                maxConcurrency,
+                testTargetTimeout,
+                globalTimeout,
+                policyState,
+                suiteType,
+                selectedTestRuns,
+                draftedTestRuns,
+                AZStd::move(selectedTestRunReport),
+                AZStd::move(draftedTestRunReport))
+            , m_discardedTestRuns(discardedTestRuns)
             , m_discardedTestRunReport(AZStd::move(discardedTestRunReport))
         {
         }
 
         TestSequenceResult SafeImpactAnalysisSequenceReport::GetResult() const
         {
-            return CalculateMultiTestSequenceResult({ DraftingSequenceReport::GetResult(), m_discardedTestRunReport.GetResult() });
+            return CalculateMultiTestSequenceResult({ DraftingSequenceReportBase::GetResult(), m_discardedTestRunReport.GetResult() });
         }
 
         AZStd::chrono::milliseconds SafeImpactAnalysisSequenceReport::GetDuration() const
         {
-            return DraftingSequenceReport::GetDuration() + m_discardedTestRunReport.GetDuration();
+            return DraftingSequenceReportBase::GetDuration() + m_discardedTestRunReport.GetDuration();
+        }
+
+        size_t SafeImpactAnalysisSequenceReport::GetTotalNumTestRuns() const
+        {
+            return DraftingSequenceReportBase::GetTotalNumTestRuns() + m_discardedTestRunReport.GetTotalNumTestRuns();
         }
 
         size_t SafeImpactAnalysisSequenceReport::GetTotalNumPassingTests() const
         {
-            return DraftingSequenceReport::GetTotalNumPassingTests() + m_discardedTestRunReport.GetNumPassingTests();
+            return DraftingSequenceReportBase::GetTotalNumPassingTests() + m_discardedTestRunReport.GetTotalNumPassingTests();
         }
 
         size_t SafeImpactAnalysisSequenceReport::GetTotalNumFailingTests() const
         {
-            return DraftingSequenceReport::GetTotalNumFailingTests() + m_discardedTestRunReport.GetNumFailingTests();
+            return DraftingSequenceReportBase::GetTotalNumFailingTests() + m_discardedTestRunReport.GetTotalNumFailingTests();
         }
 
-        size_t SafeImpactAnalysisSequenceReport::GetTotalNumTimedOutTests() const
+        size_t SafeImpactAnalysisSequenceReport::GetTotalNumDisabledTests() const
         {
-            return DraftingSequenceReport::GetTotalNumTimedOutTests() + m_discardedTestRunReport.GetNumTimedOutTests();
+            return DraftingSequenceReportBase::GetTotalNumDisabledTests() + m_discardedTestRunReport.GetTotalNumDisabledTests();
         }
 
-        size_t SafeImpactAnalysisSequenceReport::GetTotalNumUnexecutedTests() const
+        size_t SafeImpactAnalysisSequenceReport::GetTotalNumPassingTestRuns() const
         {
-            return DraftingSequenceReport::GetTotalNumUnexecutedTests() + m_discardedTestRunReport.GetNumUnexecutedTests();
+            return DraftingSequenceReportBase::GetTotalNumPassingTestRuns() + m_discardedTestRunReport.GetNumPassingTestRuns();
+        }
+
+        size_t SafeImpactAnalysisSequenceReport::GetTotalNumFailingTestRuns() const
+        {
+            return DraftingSequenceReportBase::GetTotalNumFailingTestRuns() + m_discardedTestRunReport.GetNumFailingTestRuns();
+        }
+
+        size_t SafeImpactAnalysisSequenceReport::GetTotalNumExecutionFailureTestRuns() const
+        {
+            return DraftingSequenceReportBase::GetTotalNumExecutionFailureTestRuns() + m_discardedTestRunReport.GetNumExecutionFailureTestRuns();
+        }
+
+        size_t SafeImpactAnalysisSequenceReport::GetTotalNumTimedOutTestRuns() const
+        {
+            return DraftingSequenceReportBase::GetTotalNumTimedOutTestRuns() + m_discardedTestRunReport.GetNumTimedOutTestRuns();
+        }
+
+        size_t SafeImpactAnalysisSequenceReport::GetTotalNumUnexecutedTestRuns() const
+        {
+            return DraftingSequenceReportBase::GetTotalNumUnexecutedTestRuns() + m_discardedTestRunReport.GetNumUnexecutedTestRuns();
         }
         
-        const TestRunSelection SafeImpactAnalysisSequenceReport::GetDiscardedTests() const
+        const TestRunSelection SafeImpactAnalysisSequenceReport::GetDiscardedTestRuns() const
         {
-            return m_discardedTests;
+            return m_discardedTestRuns;
         }
 
         TestRunReport SafeImpactAnalysisSequenceReport::GetDiscardedTestRunReport() const
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactClientSequenceReportSerializer.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactClientSequenceReportSerializer.cpp
new file mode 100644
index 0000000000..99a187fe16
--- /dev/null
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactClientSequenceReportSerializer.cpp
@@ -0,0 +1,606 @@
+/*
+ * 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 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+namespace TestImpact
+{
+    namespace
+    {
+        namespace SequenceReportFields
+        {
+            // Keys for pertinent JSON node and attribute names
+            constexpr const char* Keys[] =
+            {
+                "name",
+                "command_args",
+                "start_time",
+                "end_time",
+                "duration",
+                "result",
+                "num_passing_tests",
+                "num_failing_tests",
+                "num_disabled_tests",
+                "tests",
+                "num_passing_test_runs",
+                "num_failing_test_runs",
+                "num_execution_failure_test_runs",
+                "num_timed_out_test_runs",
+                "num_unexecuted_test_runs",
+                "passing_test_runs",
+                "failing_test_runs",
+                "execution_failure_test_runs",
+                "timed_out_test_runs",
+                "unexecuted_test_runs",
+                "total_num_passing_tests",
+                "total_num_failing_tests",
+                "total_num_disabled_tests",
+                "total_num_test_runs",
+                "num_included_test_runs",
+                "num_excluded_test_runs",
+                "included_test_runs",
+                "excluded_test_runs",
+                "execution_failure",
+                "coverage_failure",
+                "test_failure",
+                "integrity_failure",
+                "test_sharding",
+                "target_output_capture",
+                "test_prioritization",
+                "dynamic_dependency_map",
+                "type",
+                "test_target_timeout",
+                "global_timeout",
+                "max_concurrency",
+                "policy",
+                "suite",
+                "selected_test_runs",
+                "selected_test_run_report",
+                "total_num_passing_test_runs",
+                "total_num_failing_test_runs",
+                "total_num_execution_failure_test_runs",
+                "total_num_timed_out_test_runs",
+                "total_num_unexecuted_test_runs",
+                "drafted_test_runs",
+                "drafted_test_run_report",
+                "discarded_test_runs",
+                "discarded_test_run_report"
+            };
+
+            enum
+            {
+                Name,
+                CommandArgs,
+                StartTime,
+                EndTime,
+                Duration,
+                Result,
+                NumPassingTests,
+                NumFailingTests,
+                NumDisabledTests,
+                Tests,
+                NumPassingTestRuns,
+                NumFailingTestRuns,
+                NumExecutionFailureTestRuns,
+                NumTimedOutTestRuns,
+                NumUnexecutedTestRuns,
+                PassingTestRuns,
+                FailingTestRuns,
+                ExecutionFailureTestRuns,
+                TimedOutTestRuns,
+                UnexecutedTestRuns,
+                TotalNumPassingTests,
+                TotalNumFailingTests,
+                TotalNumDisabledTests,
+                TotalNumTestRuns,
+                NumIncludedTestRuns,
+                NumExcludedTestRuns,
+                IncludedTestRuns,
+                ExcludedTestRuns,
+                ExecutionFailure,
+                CoverageFailure,
+                TestFailure,
+                IntegrityFailure,
+                TestSharding,
+                TargetOutputCapture,
+                TestPrioritization,
+                DynamicDependencyMap,
+                Type,
+                TestTargetTimeout,
+                GlobalTimeout,
+                MaxConcurrency,
+                Policy,
+                Suite,
+                SelectedTestRuns,
+                SelectedTestRunReport,
+                TotalNumPassingTestRuns,
+                TotalNumFailingTestRuns,
+                TotalNumExecutionFailureTestRuns,
+                TotalNumTimedOutTestRuns,
+                TotalNumUnexecutedTestRuns,
+                DraftedTestRuns,
+                DraftedTestRunReport,
+                DiscardedTestRuns,
+                DiscardedTestRunReport
+            };
+        } // namespace SequenceReportFields
+
+        AZ::u64 TimePointInMsAsInt64(AZStd::chrono::high_resolution_clock::time_point timePoint)
+        {
+            return AZStd::chrono::duration_cast(timePoint.time_since_epoch()).count();
+        }
+
+        void SerializeTestRunMembers(const Client::TestRunBase& testRun, rapidjson::PrettyWriter& writer)
+        {
+            // Name
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::Name]);
+            writer.String(testRun.GetTargetName().c_str());
+
+            // Command string
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::CommandArgs]);
+            writer.String(testRun.GetCommandString().c_str());
+
+            // Start time
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::StartTime]);
+            writer.Int64(TimePointInMsAsInt64(testRun.GetStartTime()));
+
+            // End time
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::EndTime]);
+            writer.Int64(TimePointInMsAsInt64(testRun.GetEndTime()));
+
+            // Duration
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::Duration]);
+            writer.Uint64(testRun.GetDuration().count());
+
+            // Result
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::Result]);
+            writer.String(TestRunResultAsString(testRun.GetResult()).c_str());
+        }
+
+        void SerializeTestRun(const Client::TestRunBase& testRun, rapidjson::PrettyWriter& writer)
+        {
+            writer.StartObject();
+            {
+                SerializeTestRunMembers(testRun, writer);
+            }
+            writer.EndObject();
+        }
+
+        void SerializeCompletedTestRun(const Client::CompletedTestRun& testRun, rapidjson::PrettyWriter& writer)
+        {
+            writer.StartObject();
+            {
+                SerializeTestRunMembers(testRun, writer);
+
+                // Number of passing test cases
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::NumPassingTests]);
+                writer.Uint64(testRun.GetTotalNumPassingTests());
+
+                // Number of failing test cases
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::NumFailingTests]);
+                writer.Uint64(testRun.GetTotalNumFailingTests());
+
+                // Number of disabled test cases
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::NumDisabledTests]);
+                writer.Uint64(testRun.GetTotalNumDisabledTests());
+
+                // Tests
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::Tests]);
+                writer.StartArray();
+
+                for (const auto& test : testRun.GetTests())
+                {
+                    // Test
+                    writer.StartObject();
+
+                    // Name
+                    writer.Key(SequenceReportFields::Keys[SequenceReportFields::Name]);
+                    writer.String(test.GetName().c_str());
+
+                    // Result
+                    writer.Key(SequenceReportFields::Keys[SequenceReportFields::Result]);
+                    writer.String(ClientTestResultAsString(test.GetResult()).c_str());
+
+                    writer.EndObject(); // Test
+                }
+
+                writer.EndArray(); // Tests
+            }
+            writer.EndObject();
+        }
+
+        void SerializeTestRunReport(
+            const Client::TestRunReport& testRunReport, rapidjson::PrettyWriter& writer)
+        {
+            writer.StartObject();
+            {
+                // Result
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::Result]);
+                writer.String(TestSequenceResultAsString(testRunReport.GetResult()).c_str());
+
+                // Start time
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::StartTime]);
+                writer.Int64(TimePointInMsAsInt64(testRunReport.GetStartTime()));
+
+                // End time
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::EndTime]);
+                writer.Int64(TimePointInMsAsInt64(testRunReport.GetEndTime()));
+
+                // Duration
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::Duration]);
+                writer.Uint64(testRunReport.GetDuration().count());
+
+                // Number of passing test runs
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::NumPassingTestRuns]);
+                writer.Uint64(testRunReport.GetNumPassingTestRuns());
+
+                // Number of failing test runs
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::NumFailingTestRuns]);
+                writer.Uint64(testRunReport.GetNumFailingTestRuns());
+
+                // Number of test runs that failed to execute
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::NumExecutionFailureTestRuns]);
+                writer.Uint64(testRunReport.GetNumExecutionFailureTestRuns());
+
+                // Number of timed out test runs
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::NumTimedOutTestRuns]);
+                writer.Uint64(testRunReport.GetNumTimedOutTestRuns());
+
+                // Number of unexecuted test runs
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::NumUnexecutedTestRuns]);
+                writer.Uint64(testRunReport.GetNumUnexecutedTestRuns());
+
+                // Passing test runs
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::PassingTestRuns]);
+                writer.StartArray();
+                for (const auto& testRun : testRunReport.GetPassingTestRuns())
+                {
+                    SerializeCompletedTestRun(testRun, writer);
+                }
+                writer.EndArray(); // Passing test runs
+
+                // Failing test runs
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::FailingTestRuns]);
+                writer.StartArray();
+                for (const auto& testRun : testRunReport.GetFailingTestRuns())
+                {
+                    SerializeCompletedTestRun(testRun, writer);
+                }
+                writer.EndArray(); // Failing test runs
+
+                // Execution failures
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::ExecutionFailureTestRuns]);
+                writer.StartArray();
+                for (const auto& testRun : testRunReport.GetExecutionFailureTestRuns())
+                {
+                    SerializeTestRun(testRun, writer);
+                }
+                writer.EndArray(); // Execution failures
+
+                // Timed out test runs
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::TimedOutTestRuns]);
+                writer.StartArray();
+                for (const auto& testRun : testRunReport.GetTimedOutTestRuns())
+                {
+                    SerializeTestRun(testRun, writer);
+                }
+                writer.EndArray(); // Timed out test runs
+
+                // Unexecuted test runs
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::UnexecutedTestRuns]);
+                writer.StartArray();
+                for (const auto& testRun : testRunReport.GetUnexecutedTestRuns())
+                {
+                    SerializeTestRun(testRun, writer);
+                }
+                writer.EndArray(); // Unexecuted test runs
+
+                // Number of passing tests
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumPassingTests]);
+                writer.Uint64(testRunReport.GetTotalNumPassingTests());
+
+                // Number of failing tests
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumFailingTests]);
+                writer.Uint64(testRunReport.GetTotalNumFailingTests());
+
+                // Number of disabled tests
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumDisabledTests]);
+                writer.Uint64(testRunReport.GetTotalNumDisabledTests());
+            }
+            writer.EndObject();
+        }
+
+        void SerializeTestSelection(
+            const Client::TestRunSelection& testSelection, rapidjson::PrettyWriter& writer)
+        {
+            writer.StartObject();
+            {
+                // Total number of test runs
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumTestRuns]);
+                writer.Uint64(testSelection.GetTotalNumTests());
+
+                // Number of included test runs
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::NumIncludedTestRuns]);
+                writer.Uint64(testSelection.GetNumIncludedTestRuns());
+
+                // Number of excluded test runs
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::NumExcludedTestRuns]);
+                writer.Uint64(testSelection.GetNumExcludedTestRuns());
+
+                // Included test runs
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::IncludedTestRuns]);
+                writer.StartArray();
+                for (const auto& testRun : testSelection.GetIncludededTestRuns())
+                {
+                    writer.String(testRun.c_str());
+                }
+                writer.EndArray(); // Included test runs
+
+                // Excluded test runs
+                writer.Key(SequenceReportFields::Keys[SequenceReportFields::ExcludedTestRuns]);
+                writer.StartArray();
+                for (const auto& testRun : testSelection.GetExcludedTestRuns())
+                {
+                    writer.String(testRun.c_str());
+                }
+                writer.EndArray(); // Excluded test runs
+            }
+            writer.EndObject();
+        }
+
+        void SerializePolicyStateBaseMembers(const PolicyStateBase& policyState, rapidjson::PrettyWriter& writer)
+        {
+            // Execution failure
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::ExecutionFailure]);
+            writer.String(ExecutionFailurePolicyAsString(policyState.m_executionFailurePolicy).c_str());
+            
+            // Failed test coverage
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::CoverageFailure]);
+            writer.String(FailedTestCoveragePolicyAsString(policyState.m_failedTestCoveragePolicy).c_str());
+            
+            // Test failure
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::TestFailure]);
+            writer.String(TestFailurePolicyAsString(policyState.m_testFailurePolicy).c_str());
+            
+            // Integrity failure
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::IntegrityFailure]);
+            writer.String(IntegrityFailurePolicyAsString(policyState.m_integrityFailurePolicy).c_str());
+            
+            // Test sharding
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::TestSharding]);
+            writer.String(TestShardingPolicyAsString(policyState.m_testShardingPolicy).c_str());
+            
+            // Target output capture
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::TargetOutputCapture]);
+            writer.String(TargetOutputCapturePolicyAsString(policyState.m_targetOutputCapture).c_str());
+        }
+
+        void SerializePolicyStateMembers(
+            const SequencePolicyState& policyState, rapidjson::PrettyWriter& writer)
+        {
+            SerializePolicyStateBaseMembers(policyState.m_basePolicies, writer);
+        }
+
+        void SerializePolicyStateMembers(
+            const SafeImpactAnalysisSequencePolicyState& policyState, rapidjson::PrettyWriter& writer)
+        {
+            SerializePolicyStateBaseMembers(policyState.m_basePolicies, writer);
+
+            // Test prioritization
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::TestPrioritization]);
+            writer.String(TestPrioritizationPolicyAsString(policyState.m_testPrioritizationPolicy).c_str());
+        }
+
+        void SerializePolicyStateMembers(
+            const ImpactAnalysisSequencePolicyState& policyState, rapidjson::PrettyWriter& writer)
+        {
+            SerializePolicyStateBaseMembers(policyState.m_basePolicies, writer);
+
+            // Test prioritization
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::TestPrioritization]);
+            writer.String(TestPrioritizationPolicyAsString(policyState.m_testPrioritizationPolicy).c_str());
+
+            // Dynamic dependency map
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::DynamicDependencyMap]);
+            writer.String(DynamicDependencyMapPolicyAsString(policyState.m_dynamicDependencyMap).c_str());
+        }
+
+        template
+        void SerializeSequenceReportBaseMembers(
+            const Client::SequenceReportBase& sequenceReport, rapidjson::PrettyWriter& writer)
+        {
+            // Type
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::Type]);
+            writer.String(SequenceReportTypeAsString(sequenceReport.GetType()).c_str());
+
+            // Test target timeout
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::TestTargetTimeout]);
+            writer.Uint64(sequenceReport.GetTestTargetTimeout().value_or(AZStd::chrono::milliseconds{0}).count());
+
+            // Global timeout
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::GlobalTimeout]);
+            writer.Uint64(sequenceReport.GetGlobalTimeout().value_or(AZStd::chrono::milliseconds{ 0 }).count());
+
+            // Maximum concurrency
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::MaxConcurrency]);
+            writer.Uint64(sequenceReport.GetMaxConcurrency());
+
+            // Policies
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::Policy]);
+            writer.StartObject();
+            {
+                SerializePolicyStateMembers(sequenceReport.GetPolicyState(), writer);
+            }
+            writer.EndObject(); // Policies
+
+            // Suite
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::Suite]);
+            writer.String(SuiteTypeAsString(sequenceReport.GetSuite()).c_str());
+
+            // Selected test runs
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::SelectedTestRuns]);
+            SerializeTestSelection(sequenceReport.GetSelectedTestRuns(), writer);
+
+            // Selected test run report
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::SelectedTestRunReport]);
+            SerializeTestRunReport(sequenceReport.GetSelectedTestRunReport(), writer);
+
+            // Start time
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::StartTime]);
+            writer.Int64(TimePointInMsAsInt64(sequenceReport.GetStartTime()));
+
+            // End time
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::EndTime]);
+            writer.Int64(TimePointInMsAsInt64(sequenceReport.GetEndTime()));
+
+            // Duration
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::Duration]);
+            writer.Uint64(sequenceReport.GetDuration().count());
+
+            // Result
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::Result]);
+            writer.String(TestSequenceResultAsString(sequenceReport.GetResult()).c_str());
+
+            // Total number of test runs
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumTestRuns]);
+            writer.Uint64(sequenceReport.GetTotalNumTestRuns());
+
+            // Total number of passing test runs
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumPassingTestRuns]);
+            writer.Uint64(sequenceReport.GetTotalNumPassingTestRuns());
+
+            // Total number of failing test runs
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumFailingTestRuns]);
+            writer.Uint64(sequenceReport.GetTotalNumFailingTestRuns());
+
+            // Total number of test runs that failed to execute
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumExecutionFailureTestRuns]);
+            writer.Uint64(sequenceReport.GetTotalNumExecutionFailureTestRuns());
+
+            // Total number of timed out test runs
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumTimedOutTestRuns]);
+            writer.Uint64(sequenceReport.GetTotalNumTimedOutTestRuns());
+
+            // Total number of unexecuted test runs
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumUnexecutedTestRuns]);
+            writer.Uint64(sequenceReport.GetTotalNumUnexecutedTestRuns());
+
+            // Total number of passing tests
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumPassingTests]);
+            writer.Uint64(sequenceReport.GetTotalNumPassingTests());
+
+            // Total number of failing tests
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumFailingTests]);
+            writer.Uint64(sequenceReport.GetTotalNumFailingTests());
+
+             // Total number of disabled tests
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumDisabledTests]);
+            writer.Uint64(sequenceReport.GetTotalNumDisabledTests());
+        }
+
+        template
+        void SerializeDraftingSequenceReportMembers(
+            const Client::DraftingSequenceReportBase& sequenceReport, rapidjson::PrettyWriter& writer)
+        {
+            SerializeSequenceReportBaseMembers(sequenceReport, writer);
+
+            // Drafted test runs
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::DraftedTestRuns]);
+            writer.StartArray();
+            for (const auto& testRun : sequenceReport.GetDraftedTestRuns())
+            {
+                writer.String(testRun.c_str());
+            }
+            writer.EndArray(); // Drafted test runs
+
+            // Drafted test run report
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::DraftedTestRunReport]);
+            SerializeTestRunReport(sequenceReport.GetDraftedTestRunReport(), writer);
+        }
+    } // namespace
+
+    AZStd::string SerializeSequenceReport(const Client::RegularSequenceReport& sequenceReport)
+    {
+        rapidjson::StringBuffer stringBuffer;
+        rapidjson::PrettyWriter writer(stringBuffer);
+
+        writer.StartObject();
+        {
+            SerializeSequenceReportBaseMembers(sequenceReport, writer);
+        }
+        writer.EndObject();
+
+        return stringBuffer.GetString();
+    }
+
+    AZStd::string SerializeSequenceReport(const Client::SeedSequenceReport& sequenceReport)
+    {
+        rapidjson::StringBuffer stringBuffer;
+        rapidjson::PrettyWriter writer(stringBuffer);
+
+        writer.StartObject();
+        {
+            SerializeSequenceReportBaseMembers(sequenceReport, writer);
+        }
+        writer.EndObject();
+
+        return stringBuffer.GetString();
+    }
+
+    AZStd::string SerializeSequenceReport(const Client::ImpactAnalysisSequenceReport& sequenceReport)
+    {
+        rapidjson::StringBuffer stringBuffer;
+        rapidjson::PrettyWriter writer(stringBuffer);
+
+        writer.StartObject();
+        {
+            SerializeDraftingSequenceReportMembers(sequenceReport, writer);
+
+            // Discarded test runs
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::DiscardedTestRuns]);
+            writer.StartArray();
+            for (const auto& testRun : sequenceReport.GetDiscardedTestRuns())
+            {
+                writer.String(testRun.c_str());
+            }
+            writer.EndArray(); // Discarded test runs
+        }
+        writer.EndObject();
+
+        return stringBuffer.GetString();
+    }
+
+    AZStd::string SerializeSequenceReport(const Client::SafeImpactAnalysisSequenceReport& sequenceReport)
+    {
+        rapidjson::StringBuffer stringBuffer;
+        rapidjson::PrettyWriter writer(stringBuffer);
+
+        writer.StartObject();
+        {
+            SerializeDraftingSequenceReportMembers(sequenceReport, writer);
+
+            // Discarded test runs
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::DiscardedTestRuns]);
+            SerializeTestSelection(sequenceReport.GetDiscardedTestRuns(), writer);
+
+            // Discarded test run report
+            writer.Key(SequenceReportFields::Keys[SequenceReportFields::DiscardedTestRunReport]);
+            SerializeTestRunReport(sequenceReport.GetDiscardedTestRunReport(), writer);
+        }
+        writer.EndObject();
+
+        return stringBuffer.GetString();
+    }
+} // namespace TestImpact
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactClientTestRun.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactClientTestRun.cpp
index 0a258c5dac..6f50145716 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactClientTestRun.cpp
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactClientTestRun.cpp
@@ -8,11 +8,13 @@
 
 #include 
 
+#include 
+
 namespace TestImpact
 {
     namespace Client
     {
-        TestRun::TestRun(
+        TestRunBase::TestRunBase(
             const AZStd::string& name,
             const AZStd::string& commandString,
             AZStd::chrono::high_resolution_clock::time_point startTime,
@@ -26,107 +28,145 @@ namespace TestImpact
         {
         }
 
-        const AZStd::string& TestRun::GetTargetName() const
+        const AZStd::string& TestRunBase::GetTargetName() const
         {
             return m_targetName;
         }
 
-        const AZStd::string& TestRun::GetCommandString() const
+        const AZStd::string& TestRunBase::GetCommandString() const
         {
             return m_commandString;
         }
 
-        AZStd::chrono::high_resolution_clock::time_point TestRun::GetStartTime() const
+        AZStd::chrono::high_resolution_clock::time_point TestRunBase::GetStartTime() const
         {
             return m_startTime;
         }
 
-        AZStd::chrono::high_resolution_clock::time_point TestRun::GetEndTime() const
+        AZStd::chrono::high_resolution_clock::time_point TestRunBase::GetEndTime() const
         {
             return m_startTime + m_duration;
         }
 
-        AZStd::chrono::milliseconds TestRun::GetDuration() const
+        AZStd::chrono::milliseconds TestRunBase::GetDuration() const
         {
             return m_duration;
         }
 
-        TestRunResult TestRun::GetResult() const
+        TestRunResult TestRunBase::GetResult() const
         {
             return m_result;
         }
 
-        TestFailure::TestFailure(const AZStd::string& testName, const AZStd::string& errorMessage)
+        TestRunWithExecutionFailure::TestRunWithExecutionFailure(TestRunBase&& testRun)
+            : TestRunBase(AZStd::move(testRun))
+        {
+        }
+
+        TimedOutTestRun::TimedOutTestRun(TestRunBase&& testRun)
+            : TestRunBase(AZStd::move(testRun))
+        {
+        }
+
+        UnexecutedTestRun::UnexecutedTestRun(TestRunBase&& testRun)
+            : TestRunBase(AZStd::move(testRun))
+        {
+        }
+
+        Test::Test(const AZStd::string& testName, TestResult result)
             : m_name(testName)
-            , m_errorMessage(errorMessage)
+            , m_result(result)
         {
         }
 
-        const AZStd::string& TestFailure::GetName() const
+        const AZStd::string& Test::GetName() const
         {
             return m_name;
         }
 
-        const AZStd::string& TestFailure::GetErrorMessage() const
+        TestResult Test::GetResult() const
         {
-            return m_errorMessage;
+            return m_result;
         }
 
-        TestCaseFailure::TestCaseFailure(const AZStd::string& testCaseName, AZStd::vector&& testFailures)
-            : m_name(testCaseName)
-            , m_testFailures(AZStd::move(testFailures))
+        AZStd::tuple CalculateTestCaseMetrics(const AZStd::vector& tests)
         {
-        }
+            size_t totalNumPassingTests = 0;
+            size_t totalNumFailingTests = 0;
+            size_t totalNumDisabledTests = 0;
 
-        const AZStd::string& TestCaseFailure::GetName() const
-        {
-            return m_name;
-        }
-
-        const AZStd::vector& TestCaseFailure::GetTestFailures() const
-        {
-            return m_testFailures;
-        }
-
-        static size_t CalculateNumTestRunFailures(const AZStd::vector& testFailures)
-        {
-            size_t numTestFailures = 0;
-            for (const auto& testCase : testFailures)
+            for (const auto& test : tests)
             {
-                numTestFailures += testCase.GetTestFailures().size();
+                if (test.GetResult() == Client::TestResult::Passed)
+                {
+                    totalNumPassingTests++;
+                }
+                else if (test.GetResult() == Client::TestResult::Failed)
+                {
+                    totalNumFailingTests++;
+                }
+                else
+                {
+                    totalNumDisabledTests++;
+                }
             }
 
-            return numTestFailures;
+            return { totalNumPassingTests, totalNumFailingTests, totalNumDisabledTests };
         }
 
-        TestRunWithTestFailures::TestRunWithTestFailures(
+        CompletedTestRun::CompletedTestRun(
             const AZStd::string& name,
             const AZStd::string& commandString,
             AZStd::chrono::high_resolution_clock::time_point startTime,
             AZStd::chrono::milliseconds duration,
             TestRunResult result,
-            AZStd::vector&& testFailures)
-            : TestRun(name, commandString, startTime, duration, result)
-            , m_testCaseFailures(AZStd::move(testFailures))
+            AZStd::vector&& tests)
+            : TestRunBase(name, commandString, startTime, duration, result)
+            , m_tests(AZStd::move(tests))
         {
-            m_numTestFailures = CalculateNumTestRunFailures(m_testCaseFailures);
+            AZStd::tie(m_totalNumPassingTests, m_totalNumFailingTests, m_totalNumDisabledTests) = CalculateTestCaseMetrics(m_tests);
         }
 
-        TestRunWithTestFailures::TestRunWithTestFailures(TestRun&& testRun, AZStd::vector&& testFailures)
-            : TestRun(AZStd::move(testRun))
-            , m_testCaseFailures(AZStd::move(testFailures))
+        CompletedTestRun::CompletedTestRun(TestRunBase&& testRun, AZStd::vector&& tests)
+            : TestRunBase(AZStd::move(testRun))
+            , m_tests(AZStd::move(tests))
         {
-            m_numTestFailures = CalculateNumTestRunFailures(m_testCaseFailures);
+            AZStd::tie(m_totalNumPassingTests, m_totalNumFailingTests, m_totalNumDisabledTests) = CalculateTestCaseMetrics(m_tests);
         }
 
-        size_t TestRunWithTestFailures::GetNumTestFailures() const
+        size_t CompletedTestRun::GetTotalNumTests() const
         {
-            return m_numTestFailures;
+            return m_tests.size();
         }
 
-        const AZStd::vector& TestRunWithTestFailures::GetTestCaseFailures() const
+        size_t CompletedTestRun::GetTotalNumPassingTests() const
+        {
+            return m_totalNumPassingTests;
+        }
+
+        size_t CompletedTestRun::GetTotalNumFailingTests() const
+        {
+            return m_totalNumFailingTests;
+        }
+
+        size_t CompletedTestRun::GetTotalNumDisabledTests() const
+        {
+            return m_totalNumDisabledTests;
+        }
+
+        const AZStd::vector& CompletedTestRun::GetTests() const
+        {
+            return m_tests;
+        }
+
+        PassingTestRun::PassingTestRun(TestRunBase&& testRun, AZStd::vector&& tests)
+            : CompletedTestRun(AZStd::move(testRun), AZStd::move(tests))
+        {
+        }
+
+        FailingTestRun::FailingTestRun(TestRunBase&& testRun, AZStd::vector&& tests)
+            : CompletedTestRun(AZStd::move(testRun), AZStd::move(tests))
         {
-            return m_testCaseFailures;
         }
     } // namespace Client
 } // namespace TestImpact
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntime.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntime.cpp
index 478b63e8b2..8a9d96bca8 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntime.cpp
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntime.cpp
@@ -6,7 +6,7 @@
  *
  */
 
-#include 
+#include 
 #include 
 #include 
 
@@ -81,7 +81,7 @@ namespace TestImpact
             {
                 if (m_testCompleteCallback.has_value())
                 {
-                    Client::TestRun testRun(
+                    Client::TestRunBase testRun(
                         testJob.GetTestTarget()->GetName(),
                         testJob.GetCommandString(),
                         testJob.GetStartTime(),
@@ -110,8 +110,140 @@ namespace TestImpact
         return result;
     }
 
+    //! Utility structure for holding the pertinent data for test run reports.
+    template
+    struct TestRunData
+    {
+        TestSequenceResult m_result = TestSequenceResult::Success;
+        AZStd::vector m_jobs;
+        AZStd::chrono::high_resolution_clock::time_point m_relativeStartTime;
+        AZStd::chrono::milliseconds m_duration = AZStd::chrono::milliseconds{ 0 };
+    };
+
+    //! Wrapper for the impact analysis test sequence to handle both the updating and non-updating policies through a common pathway.
+    //! @tparam TestRunnerFunctor The functor for running the specified tests.
+    //! @tparam TestJob The test engine job type returned by the functor.
+    //! @param maxConcurrency The maximum concurrency being used for this sequence.
+    //! @param policyState The policy state being used for the sequence.
+    //! @param suiteType The suite type used for this sequence.
+    //! @param timer The timer to use for the test run timings.
+    //! @param testRunner The test runner functor to use for each of the test runs.
+    //! @param includedSelectedTestTargets The subset of test targets that were selected to run and not also fully excluded from running.
+    //! @param excludedSelectedTestTargets The subset of test targets that were selected to run but were fully excluded running.
+    //! @param discardedTestTargets The subset of test targets that were discarded from the test selection and will not be run.
+    //! @param globalTimeout The maximum duration the entire test sequence may run for (infinite if empty).
+    //! @param testSequenceStartCallback The client function to be called after the test targets have been selected but prior to running the
+    //! tests.
+    //! @param testSequenceCompleteCallback The client function to be called after the test sequence has completed.
+    //! @param testRunCompleteCallback The client function to be called after an individual test run has completed.
+    //! @param updateCoverage The function to call to update the dynamic dependency map with test coverage (if any).
+    template
+    Client::ImpactAnalysisSequenceReport ImpactAnalysisTestSequenceWrapper(
+        size_t maxConcurrency,
+        const ImpactAnalysisSequencePolicyState& policyState,
+        SuiteType suiteType,
+        const Timer& sequenceTimer,
+        const TestRunnerFunctor& testRunner,
+        const AZStd::vector& includedSelectedTestTargets,
+        const AZStd::vector& excludedSelectedTestTargets,
+        const AZStd::vector& discardedTestTargets,
+        const AZStd::vector& draftedTestTargets,
+        const AZStd::optional& testTargetTimeout,
+        const AZStd::optional& globalTimeout,
+        AZStd::optional testSequenceStartCallback,
+        AZStd::optional> testSequenceEndCallback,
+        AZStd::optional testCompleteCallback,
+        AZStd::optional& jobs)>> updateCoverage)
+    {
+        TestRunData selectedTestRunData, draftedTestRunData;
+        AZStd::optional sequenceTimeout = globalTimeout;
+
+        // Extract the client facing representation of selected, discarded and drafted test targets
+        const Client::TestRunSelection selectedTests(
+            ExtractTestTargetNames(includedSelectedTestTargets), ExtractTestTargetNames(excludedSelectedTestTargets));
+        const auto discardedTests = ExtractTestTargetNames(discardedTestTargets);
+        const auto draftedTests = ExtractTestTargetNames(draftedTestTargets);
+
+        // Inform the client that the sequence is about to start
+        if (testSequenceStartCallback.has_value())
+        {
+            (*testSequenceStartCallback)(suiteType, selectedTests, discardedTests, draftedTests);
+        }
+
+        // We share the test run complete handler between the selected and drafted test runs as to present them together as one
+        // continuous test sequence to the client rather than two discrete test runs
+        const size_t totalNumTestRuns = includedSelectedTestTargets.size() + draftedTestTargets.size();
+        TestRunCompleteCallbackHandler testRunCompleteHandler(totalNumTestRuns, testCompleteCallback);
+
+        const auto gatherTestRunData = [&sequenceTimer, &testRunner, &testRunCompleteHandler, &globalTimeout]
+        (const AZStd::vector& testsTargets, TestRunData& testRunData)
+        {
+            const Timer testRunTimer;
+            testRunData.m_relativeStartTime = testRunTimer.GetStartTimePointRelative(sequenceTimer);
+            auto [result, jobs] = testRunner(testsTargets, testRunCompleteHandler, globalTimeout);
+            testRunData.m_result = result;
+            testRunData.m_jobs = AZStd::move(jobs);
+            testRunData.m_duration = testRunTimer.GetElapsedMs();
+        };
+
+        if (!includedSelectedTestTargets.empty())
+        {
+            // Run the selected test targets and collect the test run results
+            gatherTestRunData(includedSelectedTestTargets, selectedTestRunData);
+
+            // Carry the remaining global sequence time over to the drafted test run
+            if (globalTimeout.has_value())
+            {
+                const auto elapsed = selectedTestRunData.m_duration;
+                sequenceTimeout = elapsed < globalTimeout.value() ? globalTimeout.value() - elapsed : AZStd::chrono::milliseconds(0);
+            }
+        }
+
+        if (!draftedTestTargets.empty())
+        {
+            // Run the drafted test targets and collect the test run results
+            gatherTestRunData(draftedTestTargets, draftedTestRunData);
+        }
+
+        // Generate the sequence report for the client
+        const auto sequenceReport = Client::ImpactAnalysisSequenceReport(
+            maxConcurrency,
+            testTargetTimeout,
+            globalTimeout,
+            policyState,
+            suiteType,
+            selectedTests,
+            discardedTests,
+            draftedTests,
+            GenerateTestRunReport(
+                selectedTestRunData.m_result, 
+                selectedTestRunData.m_relativeStartTime, 
+                selectedTestRunData.m_duration,
+                selectedTestRunData.m_jobs),
+            GenerateTestRunReport(
+                draftedTestRunData.m_result, 
+                draftedTestRunData.m_relativeStartTime, 
+                draftedTestRunData.m_duration,
+                draftedTestRunData.m_jobs));
+
+        // Inform the client that the sequence has ended
+        if (testSequenceEndCallback.has_value())
+        {
+            (*testSequenceEndCallback)(sequenceReport);
+        }
+
+        // Update the dynamic dependency map with the latest coverage data (if any)
+        if (updateCoverage.has_value())
+        {
+            (*updateCoverage)(ConcatenateVectors(selectedTestRunData.m_jobs, draftedTestRunData.m_jobs));
+        }
+
+        return sequenceReport;
+    }
+
     Runtime::Runtime(
         RuntimeConfig&& config,
+        AZStd::optional dataFile,
         SuiteType suiteFilter,
         Policy::ExecutionFailure executionFailurePolicy,
         Policy::FailedTestCoverage failedTestCoveragePolicy,
@@ -151,27 +283,22 @@ namespace TestImpact
 
         try
         {
+            if (dataFile.has_value())
+            {
+                m_sparTiaFile = dataFile.value().String();
+            }
+            else
+            {
+                m_sparTiaFile = m_config.m_workspace.m_active.m_sparTiaFiles[static_cast(m_suiteFilter)].String();
+            }
+           
             // Populate the dynamic dependency map with the existing source coverage data (if any)
-            m_sparTIAFile = m_config.m_workspace.m_active.m_sparTIAFiles[static_cast(m_suiteFilter)].String();
-            const auto tiaDataRaw = ReadFileContents(m_sparTIAFile);
+            const auto tiaDataRaw = ReadFileContents(m_sparTiaFile);
             const auto tiaData = DeserializeSourceCoveringTestsList(tiaDataRaw);
             if (tiaData.GetNumSources())
             {
                 m_dynamicDependencyMap->ReplaceSourceCoverage(tiaData);
                 m_hasImpactAnalysisData = true;
-
-                // Enumerate new test targets
-                const auto testTargetsWithNoEnumeration = m_dynamicDependencyMap->GetNotCoveringTests();
-                if (!testTargetsWithNoEnumeration.empty())
-                {
-                    m_testEngine->UpdateEnumerationCache(
-                        testTargetsWithNoEnumeration,
-                        Policy::ExecutionFailure::Ignore,
-                        Policy::TestFailure::Continue,
-                        AZStd::nullopt,
-                        AZStd::nullopt,
-                        AZStd::nullopt);
-                }
             }
         }
         catch (const DependencyException& e)
@@ -186,7 +313,7 @@ namespace TestImpact
             AZ_Printf(
                 LogCallSite,
                 AZStd::string::format(
-                    "No test impact analysis data found for suite '%s' at %s\n", GetSuiteTypeName(m_suiteFilter).c_str(), m_sparTIAFile.c_str()).c_str());
+                    "No test impact analysis data found for suite '%s' at %s\n", SuiteTypeAsString(m_suiteFilter).c_str(), m_sparTiaFile.c_str()).c_str());
         }
     }
 
@@ -230,7 +357,7 @@ namespace TestImpact
         }
     }
 
-    AZStd::pair, AZStd::vector> Runtime::SelectCoveringTestTargetsAndUpdateEnumerationCache(
+    AZStd::pair, AZStd::vector> Runtime::SelectCoveringTestTargets(
         const ChangeList& changeList,
         Policy::TestPrioritization testPrioritizationPolicy)
     {
@@ -243,9 +370,6 @@ namespace TestImpact
         // Populate a set with the selected test targets so that we can infer the discarded test target not selected for this change list
         const AZStd::unordered_set selectedTestTargetSet(selectedTestTargets.begin(), selectedTestTargets.end());
 
-        // Update the enumeration caches of mutated targets regardless of the current sharding policy
-        EnumerateMutatedTestTargets(changeDependencyList);
-
         // The test targets in the main list not in the selected test target set are the test targets not selected for this change list
         for (const auto& testTarget : m_dynamicDependencyMap->GetTestTargetList().GetTargets())
         {
@@ -287,7 +411,7 @@ namespace TestImpact
     void Runtime::ClearDynamicDependencyMapAndRemoveExistingFile()
     {
         m_dynamicDependencyMap->ClearAllSourceCoverage();
-        DeleteFile(m_sparTIAFile);
+        DeleteFile(m_sparTiaFile);
     }
 
     SourceCoveringTestsList Runtime::CreateSourceCoveringTestFromTestCoverages(const AZStd::vector& jobs)
@@ -368,9 +492,9 @@ namespace TestImpact
             }
 
             m_dynamicDependencyMap->ReplaceSourceCoverage(sourceCoverageTestsList);
-            const auto sparTIA = m_dynamicDependencyMap->ExportSourceCoverage();
-            const auto sparTIAData = SerializeSourceCoveringTestsList(sparTIA);
-            WriteFileContents(sparTIAData, m_sparTIAFile);
+            const auto sparTia = m_dynamicDependencyMap->ExportSourceCoverage();
+            const auto sparTiaData = SerializeSourceCoveringTestsList(sparTia);
+            WriteFileContents(sparTiaData, m_sparTiaFile);
             m_hasImpactAnalysisData = true;
         }
         catch(const RuntimeException& e)
@@ -386,11 +510,42 @@ namespace TestImpact
         }
     }
 
-    Client::SequenceReport Runtime::RegularTestSequence(
+    PolicyStateBase Runtime::GeneratePolicyStateBase() const
+    {
+        PolicyStateBase policyState;
+
+        policyState.m_executionFailurePolicy = m_executionFailurePolicy;
+        policyState.m_failedTestCoveragePolicy = m_failedTestCoveragePolicy;
+        policyState.m_integrityFailurePolicy = m_integrationFailurePolicy;
+        policyState.m_targetOutputCapture = m_targetOutputCapture;
+        policyState.m_testFailurePolicy = m_testFailurePolicy;
+        policyState.m_testShardingPolicy = m_testShardingPolicy;
+
+        return policyState;
+    }
+
+    SequencePolicyState Runtime::GenerateSequencePolicyState() const
+    {
+        return { GeneratePolicyStateBase() };
+    }
+
+    SafeImpactAnalysisSequencePolicyState Runtime::GenerateSafeImpactAnalysisSequencePolicyState(
+        Policy::TestPrioritization testPrioritizationPolicy) const
+    {
+        return { GeneratePolicyStateBase(), testPrioritizationPolicy };
+    }
+
+    ImpactAnalysisSequencePolicyState Runtime::GenerateImpactAnalysisSequencePolicyState(
+        Policy::TestPrioritization testPrioritizationPolicy, Policy::DynamicDependencyMap dynamicDependencyMapPolicy) const
+    {
+        return { GeneratePolicyStateBase(), testPrioritizationPolicy, dynamicDependencyMapPolicy };
+    }
+
+    Client::RegularSequenceReport Runtime::RegularTestSequence(
         AZStd::optional testTargetTimeout,
         AZStd::optional globalTimeout,
         AZStd::optional testSequenceStartCallback,
-        AZStd::optional> testSequenceEndCallback,
+        AZStd::optional> testSequenceEndCallback,
         AZStd::optional testCompleteCallback)
     {
         const Timer sequenceTimer;
@@ -434,7 +589,11 @@ namespace TestImpact
         const auto testRunDuration = testRunTimer.GetElapsedMs();
 
         // Generate the sequence report for the client
-        const auto sequenceReport = Client::SequenceReport(
+        const auto sequenceReport = Client::RegularSequenceReport(
+            m_maxConcurrency,
+            testTargetTimeout,
+            globalTimeout,
+            GenerateSequencePolicyState(),
             m_suiteFilter,
             selectedTests,
             GenerateTestRunReport(result, testRunTimer.GetStartTimePointRelative(sequenceTimer), testRunDuration, testJobs));
@@ -448,95 +607,6 @@ namespace TestImpact
         return sequenceReport;
     }
 
-    //! Wrapper for the impact analysis test sequence to handle both the updating and non-updating policies through a common pathway.
-    //! @tparam TestRunnerFunctor The functor for running the specified tests.
-    //! @tparam TestJob The test engine job type returned by the functor.
-    //! @param suiteType The suite type used for this sequence.
-    //! @param timer The timer to use for the test run timings.
-    //! @param testRunner The test runner functor to use for each of the test runs.
-    //! @param includedSelectedTestTargets The subset of test targets that were selected to run and not also fully excluded from running.
-    //! @param excludedSelectedTestTargets The subset of test targets that were selected to run but were fully excluded running.
-    //! @param discardedTestTargets The subset of test targets that were discarded from the test selection and will not be run.
-    //! @param globalTimeout The maximum duration the entire test sequence may run for (infinite if empty).
-    //! @param testSequenceStartCallback The client function to be called after the test targets have been selected but prior to running the tests.
-    //! @param testSequenceCompleteCallback The client function to be called after the test sequence has completed.
-    //! @param testRunCompleteCallback The client function to be called after an individual test run has completed.
-    //! @param updateCoverage The function to call to update the dynamic dependency map with test coverage (if any).
-    template
-    Client::ImpactAnalysisSequenceReport ImpactAnalysisTestSequenceWrapper(
-        SuiteType suiteType,
-        const Timer& sequenceTimer,
-        const TestRunnerFunctor& testRunner,
-        const AZStd::vector& includedSelectedTestTargets,
-        const AZStd::vector& excludedSelectedTestTargets,
-        const AZStd::vector& discardedTestTargets,
-        const AZStd::vector& draftedTestTargets,
-        const AZStd::optional globalTimeout,
-        AZStd::optional testSequenceStartCallback,
-        AZStd::optional> testSequenceEndCallback,
-        AZStd::optional testCompleteCallback,
-        AZStd::optional& jobs)>> updateCoverage)
-    {
-        AZStd::optional sequenceTimeout = globalTimeout;
-
-        // Extract the client facing representation of selected, discarded and drafted test targets
-        const Client::TestRunSelection selectedTests(
-            ExtractTestTargetNames(includedSelectedTestTargets), ExtractTestTargetNames(excludedSelectedTestTargets));
-        const auto discardedTests = ExtractTestTargetNames(discardedTestTargets);
-        const auto draftedTests = ExtractTestTargetNames(draftedTestTargets);
-
-        // Inform the client that the sequence is about to start
-        if (testSequenceStartCallback.has_value())
-        {
-            (*testSequenceStartCallback)(suiteType, selectedTests, discardedTests, draftedTests);
-        }
-
-        // We share the test run complete handler between the selected and drafted test runs as to present them together as one
-        // continuous test sequence to the client rather than two discrete test runs
-        const size_t totalNumTestRuns = includedSelectedTestTargets.size() + draftedTestTargets.size();
-        TestRunCompleteCallbackHandler testRunCompleteHandler(totalNumTestRuns, testCompleteCallback);
-
-        // Run the selected test targets and collect the test run results
-        const Timer selectedTestRunTimer;
-        const auto [selectedResult, selectedTestJobs] = testRunner(includedSelectedTestTargets, testRunCompleteHandler, globalTimeout);
-        const auto selectedTestRunDuration = selectedTestRunTimer.GetElapsedMs();
-
-        // Carry the remaining global sequence time over to the drafted test run
-        if (globalTimeout.has_value())
-        {
-            const auto elapsed = selectedTestRunDuration;
-            sequenceTimeout = elapsed < globalTimeout.value() ? globalTimeout.value() - elapsed : AZStd::chrono::milliseconds(0);
-        }
-
-        // Run the drafted test targets and collect the test run results
-        Timer draftedTestRunTimer;
-        const auto [draftedResult, draftedTestJobs] = testRunner(draftedTestTargets, testRunCompleteHandler, globalTimeout);
-        const auto draftedTestRunDuration = draftedTestRunTimer.GetElapsedMs();
-
-        // Generate the sequence report for the client
-        const auto sequenceReport = Client::ImpactAnalysisSequenceReport(
-            suiteType,
-            selectedTests,
-            discardedTests,
-            draftedTests,
-            GenerateTestRunReport(selectedResult, selectedTestRunTimer.GetStartTimePointRelative(sequenceTimer), selectedTestRunDuration, selectedTestJobs),
-            GenerateTestRunReport(draftedResult, draftedTestRunTimer.GetStartTimePointRelative(sequenceTimer), draftedTestRunDuration, draftedTestJobs));
-
-        // Inform the client that the sequence has ended
-        if (testSequenceEndCallback.has_value())
-        {
-            (*testSequenceEndCallback)(sequenceReport);
-        }
-
-        // Update the dynamic dependency map with the latest coverage data (if any)
-        if (updateCoverage.has_value())
-        {
-            (*updateCoverage)(ConcatenateVectors(selectedTestJobs, draftedTestJobs));
-        }
-
-        return sequenceReport;
-    }
-
     Client::ImpactAnalysisSequenceReport Runtime::ImpactAnalysisTestSequence(
         const ChangeList& changeList,
         Policy::TestPrioritization testPrioritizationPolicy,
@@ -550,10 +620,30 @@ namespace TestImpact
         const Timer sequenceTimer;
 
         // Draft in the test targets that have no coverage entries in the dynamic dependency map
-        AZStd::vector draftedTestTargets = m_dynamicDependencyMap->GetNotCoveringTests();
+        const AZStd::vector draftedTestTargets = m_dynamicDependencyMap->GetNotCoveringTests();
 
-        // The test targets that were selected for the change list by the dynamic dependency map and the test targets that were not
-        auto [selectedTestTargets, discardedTestTargets] = SelectCoveringTestTargetsAndUpdateEnumerationCache(changeList, testPrioritizationPolicy);
+        const auto selectCoveringTestTargetsAndPruneDraftedFromDiscarded =
+            [this, &draftedTestTargets, &changeList, testPrioritizationPolicy]()
+        {
+            // The test targets that were selected for the change list by the dynamic dependency map and the test targets that were not
+            const auto [selectedTestTargets, discardedTestTargets] =
+                SelectCoveringTestTargets(changeList, testPrioritizationPolicy);
+
+            const AZStd::unordered_set draftedTestTargetsSet(draftedTestTargets.begin(), draftedTestTargets.end());
+
+            AZStd::vector discardedNotDraftedTestTargets;
+            for (const auto* testTarget : discardedTestTargets)
+            {
+                if (!draftedTestTargetsSet.count(testTarget))
+                {
+                    discardedNotDraftedTestTargets.push_back(testTarget);
+                }
+            }
+
+            return AZStd::pair{ selectedTestTargets, discardedNotDraftedTestTargets };
+        };
+
+        const auto [selectedTestTargets, discardedTestTargets] = selectCoveringTestTargetsAndPruneDraftedFromDiscarded();
 
         // The subset of selected test targets that are not on the configuration's exclude list and those that are
         auto [includedSelectedTestTargets, excludedSelectedTestTargets] = SelectTestTargetsByExcludeList(selectedTestTargets);
@@ -604,6 +694,8 @@ namespace TestImpact
             };
 
             return ImpactAnalysisTestSequenceWrapper(
+                m_maxConcurrency,
+                GenerateImpactAnalysisSequencePolicyState(testPrioritizationPolicy, dynamicDependencyMapPolicy),
                 m_suiteFilter,
                 sequenceTimer,
                 instrumentedTestRun,
@@ -611,6 +703,7 @@ namespace TestImpact
                 excludedSelectedTestTargets,
                 discardedTestTargets,
                 draftedTestTargets,
+                testTargetTimeout,
                 globalTimeout,
                 testSequenceStartCallback,
                 testSequenceEndCallback,
@@ -620,6 +713,8 @@ namespace TestImpact
         else
         {
             return ImpactAnalysisTestSequenceWrapper(
+                m_maxConcurrency,
+                GenerateImpactAnalysisSequencePolicyState(testPrioritizationPolicy, dynamicDependencyMapPolicy),
                 m_suiteFilter,
                 sequenceTimer,
                 regularTestRun,
@@ -627,6 +722,7 @@ namespace TestImpact
                 excludedSelectedTestTargets,
                 discardedTestTargets,
                 draftedTestTargets,
+                testTargetTimeout,
                 globalTimeout,
                 testSequenceStartCallback,
                 testSequenceEndCallback,
@@ -645,13 +741,15 @@ namespace TestImpact
         AZStd::optional testCompleteCallback)
     {
         const Timer sequenceTimer;
-        auto sequenceTimeout = globalTimeout;
+        TestRunData selectedTestRunData, draftedTestRunData;
+        TestRunData discardedTestRunData;
+        AZStd::optional sequenceTimeout = globalTimeout;
 
         // Draft in the test targets that have no coverage entries in the dynamic dependency map
         AZStd::vector draftedTestTargets = m_dynamicDependencyMap->GetNotCoveringTests();
 
         // The test targets that were selected for the change list by the dynamic dependency map and the test targets that were not
-        auto [selectedTestTargets, discardedTestTargets] = SelectCoveringTestTargetsAndUpdateEnumerationCache(changeList, testPrioritizationPolicy);
+        const auto [selectedTestTargets, discardedTestTargets] = SelectCoveringTestTargets(changeList, testPrioritizationPolicy);
 
         // The subset of selected test targets that are not on the configuration's exclude list and those that are
         auto [includedSelectedTestTargets, excludedSelectedTestTargets] = SelectTestTargetsByExcludeList(selectedTestTargets);
@@ -675,71 +773,107 @@ namespace TestImpact
         // continuous test sequence to the client rather than three discrete test runs
         const size_t totalNumTestRuns = includedSelectedTestTargets.size() + draftedTestTargets.size() + includedDiscardedTestTargets.size();
         TestRunCompleteCallbackHandler testRunCompleteHandler(totalNumTestRuns, testCompleteCallback);
-
-        // Run the selected test targets and collect the test run results
-        const Timer selectedTestRunTimer;
-        const auto [selectedResult, selectedTestJobs] = m_testEngine->InstrumentedRun(
-            includedSelectedTestTargets,
-            m_testShardingPolicy,
-            m_executionFailurePolicy,
-            m_integrationFailurePolicy,
-            m_testFailurePolicy,
-            m_targetOutputCapture,
-            testTargetTimeout,
-            sequenceTimeout,
-            AZStd::ref(testRunCompleteHandler));
-        const auto selectedTestRunDuration = selectedTestRunTimer.GetElapsedMs();
-
-        // Carry the remaining global sequence time over to the discarded test run
-        if (globalTimeout.has_value())
+        
+        // Functor for running instrumented test targets
+        const auto instrumentedTestRun =
+            [this, &testTargetTimeout, &sequenceTimeout, &testRunCompleteHandler](const AZStd::vector& testsTargets)
         {
-            const auto elapsed = selectedTestRunDuration;
-            sequenceTimeout = elapsed < globalTimeout.value() ? globalTimeout.value() - elapsed : AZStd::chrono::milliseconds(0);
+            return m_testEngine->InstrumentedRun(
+                testsTargets,
+                m_testShardingPolicy,
+                m_executionFailurePolicy,
+                m_integrationFailurePolicy,
+                m_testFailurePolicy,
+                m_targetOutputCapture,
+                testTargetTimeout,
+                sequenceTimeout,
+                AZStd::ref(testRunCompleteHandler));
+        };
+
+        // Functor for running uninstrumented test targets
+        const auto regularTestRun =
+            [this, &testTargetTimeout, &sequenceTimeout, &testRunCompleteHandler](const AZStd::vector& testsTargets)
+        {
+            return m_testEngine->RegularRun(
+                testsTargets,
+                m_testShardingPolicy,
+                m_executionFailurePolicy,
+                m_testFailurePolicy,
+                m_targetOutputCapture,
+                testTargetTimeout,
+                sequenceTimeout,
+                AZStd::ref(testRunCompleteHandler));
+        };
+
+        // Functor for running instrumented test targets
+        const auto gatherTestRunData = [&sequenceTimer]
+        (const AZStd::vector& testsTargets, const auto& testRunner, auto& testRunData)
+        {
+            const Timer testRunTimer;
+            testRunData.m_relativeStartTime = testRunTimer.GetStartTimePointRelative(sequenceTimer);
+            auto [result, jobs] = testRunner(testsTargets);
+            testRunData.m_result = result;
+            testRunData.m_jobs = AZStd::move(jobs);
+            testRunData.m_duration = testRunTimer.GetElapsedMs();
+        };
+
+        if (!includedSelectedTestTargets.empty())
+        {
+            // Run the selected test targets and collect the test run results
+            gatherTestRunData(includedSelectedTestTargets, instrumentedTestRun, selectedTestRunData);
+
+            // Carry the remaining global sequence time over to the discarded test run
+            if (globalTimeout.has_value())
+            {
+                const auto elapsed = selectedTestRunData.m_duration;
+                sequenceTimeout = elapsed < globalTimeout.value() ? globalTimeout.value() - elapsed : AZStd::chrono::milliseconds(0);
+            }
         }
 
-        // Run the discarded test targets and collect the test run results
-        const Timer discardedTestRunTimer;
-        const auto [discardedResult, discardedTestJobs] = m_testEngine->RegularRun(
-            includedDiscardedTestTargets,
-            m_testShardingPolicy,
-            m_executionFailurePolicy,
-            m_testFailurePolicy,
-            m_targetOutputCapture,
-            testTargetTimeout,
-            sequenceTimeout,
-            AZStd::ref(testRunCompleteHandler));
-        const auto discardedTestRunDuration = discardedTestRunTimer.GetElapsedMs();
-
-        // Carry the remaining global sequence time over to the drafted test run
-        if (globalTimeout.has_value())
+        if (!includedDiscardedTestTargets.empty())
         {
-            const auto elapsed = selectedTestRunDuration + discardedTestRunDuration;
-            sequenceTimeout = elapsed < globalTimeout.value() ? globalTimeout.value() - elapsed : AZStd::chrono::milliseconds(0);
+            // Run the discarded test targets and collect the test run results
+            gatherTestRunData(includedDiscardedTestTargets, regularTestRun, discardedTestRunData);
+
+            // Carry the remaining global sequence time over to the drafted test run
+            if (globalTimeout.has_value())
+            {
+                const auto elapsed = selectedTestRunData.m_duration + discardedTestRunData.m_duration;
+                sequenceTimeout = elapsed < globalTimeout.value() ? globalTimeout.value() - elapsed : AZStd::chrono::milliseconds(0);
+            }
         }
 
-        // Run the drafted test targets and collect the test run results
-        const Timer draftedTestRunTimer;
-        const auto [draftedResult, draftedTestJobs] = m_testEngine->InstrumentedRun(
-            draftedTestTargets,
-            m_testShardingPolicy,
-            m_executionFailurePolicy,
-            m_integrationFailurePolicy,
-            m_testFailurePolicy,
-            m_targetOutputCapture,
-            testTargetTimeout,
-            sequenceTimeout,
-            AZStd::ref(testRunCompleteHandler));
-        const auto draftedTestRunDuration = draftedTestRunTimer.GetElapsedMs();
+        if (!draftedTestTargets.empty())
+        {
+            // Run the drafted test targets and collect the test run results
+            gatherTestRunData(draftedTestTargets, instrumentedTestRun, draftedTestRunData);
+        }
 
         // Generate the sequence report for the client
         const auto sequenceReport = Client::SafeImpactAnalysisSequenceReport(
+            m_maxConcurrency,
+            testTargetTimeout,
+            globalTimeout,
+            GenerateSafeImpactAnalysisSequencePolicyState(testPrioritizationPolicy),
             m_suiteFilter,
             selectedTests,
             discardedTests,
             draftedTests,
-            GenerateTestRunReport(selectedResult, selectedTestRunTimer.GetStartTimePointRelative(sequenceTimer), selectedTestRunDuration, selectedTestJobs),
-            GenerateTestRunReport(discardedResult, discardedTestRunTimer.GetStartTimePointRelative(sequenceTimer), discardedTestRunDuration, discardedTestJobs),
-            GenerateTestRunReport(draftedResult, draftedTestRunTimer.GetStartTimePointRelative(sequenceTimer), draftedTestRunDuration, draftedTestJobs));
+            GenerateTestRunReport(
+                selectedTestRunData.m_result,
+                selectedTestRunData.m_relativeStartTime,
+                selectedTestRunData.m_duration,
+                selectedTestRunData.m_jobs),
+            GenerateTestRunReport(
+                discardedTestRunData.m_result,
+                discardedTestRunData.m_relativeStartTime,
+                discardedTestRunData.m_duration,
+                discardedTestRunData.m_jobs),
+            GenerateTestRunReport(
+                draftedTestRunData.m_result, 
+                draftedTestRunData.m_relativeStartTime, 
+                draftedTestRunData.m_duration,
+                draftedTestRunData.m_jobs));
 
         // Inform the client that the sequence has ended
         if (testSequenceEndCallback.has_value())
@@ -747,15 +881,15 @@ namespace TestImpact
             (*testSequenceEndCallback)(sequenceReport);
         }
 
-        UpdateAndSerializeDynamicDependencyMap(ConcatenateVectors(selectedTestJobs, draftedTestJobs));
+        UpdateAndSerializeDynamicDependencyMap(ConcatenateVectors(selectedTestRunData.m_jobs, draftedTestRunData.m_jobs));
         return sequenceReport;
     }
 
-    Client::SequenceReport Runtime::SeededTestSequence(
+    Client::SeedSequenceReport Runtime::SeededTestSequence(
         AZStd::optional testTargetTimeout,
         AZStd::optional globalTimeout,
         AZStd::optional testSequenceStartCallback,
-        AZStd::optional> testSequenceEndCallback,
+        AZStd::optional> testSequenceEndCallback,
         AZStd::optional testCompleteCallback)
     {
         const Timer sequenceTimer;
@@ -799,7 +933,11 @@ namespace TestImpact
         const auto testRunDuration = testRunTimer.GetElapsedMs();
 
         // Generate the sequence report for the client
-        const auto sequenceReport = Client::SequenceReport(
+        const auto sequenceReport = Client::SeedSequenceReport(
+            m_maxConcurrency,
+            testTargetTimeout,
+            globalTimeout,
+            GenerateSequencePolicyState(),
             m_suiteFilter,
             selectedTests,
             GenerateTestRunReport(result, testRunTimer.GetStartTimePointRelative(sequenceTimer), testRunDuration, testJobs));
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntimeUtils.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntimeUtils.cpp
index 0c61c5f426..fec3d90471 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntimeUtils.cpp
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntimeUtils.cpp
@@ -6,7 +6,7 @@
  *
  */
 
-#include 
+#include 
 #include 
 
 #include 
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntimeUtils.h b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntimeUtils.h
index 33e15bfd20..23d78ee329 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntimeUtils.h
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntimeUtils.h
@@ -38,34 +38,44 @@ namespace TestImpact
     //! Extracts the name information from the specified test targets.
     AZStd::vector ExtractTestTargetNames(const AZStd::vector& testTargets);
 
-    //! Generates a test run failure report from the specified test engine job information.
+    //! Generates the test suites from the specified test engine job information.
     //! @tparam TestJob The test engine job type.
     template
-    AZStd::vector GenerateTestCaseFailures(const TestJob& testJob)
+    AZStd::vector GenerateClientTests(const TestJob& testJob)
     {
-        AZStd::vector testCaseFailures;
+        AZStd::vector tests;
 
         if (testJob.GetTestRun().has_value())
         {
             for (const auto& testSuite : testJob.GetTestRun()->GetTestSuites())
             {
-                AZStd::vector testFailures;
                 for (const auto& testCase : testSuite.m_tests)
                 {
-                    if (testCase.m_result.value_or(TestRunResult::Passed) == TestRunResult::Failed)
+                    auto result = Client::TestResult::NotRun;
+                    if (testCase.m_result.has_value())
                     {
-                        testFailures.push_back(Client::TestFailure(testCase.m_name, "No error message retrieved"));
+                        if (testCase.m_result.value() == TestRunResult::Passed)
+                        {
+                            result = Client::TestResult::Passed;
+                        }
+                        else if (testCase.m_result.value() == TestRunResult::Failed)
+                        {
+                            result = Client::TestResult::Failed;
+                        }
+                        else
+                        {
+                            throw RuntimeException(AZStd::string::format(
+                                "Unexpected test run result: %u", aznumeric_cast(testCase.m_result.value())));
+                        }
                     }
-                }
-    
-                if (!testFailures.empty())
-                {
-                    testCaseFailures.push_back(Client::TestCaseFailure(testSuite.m_name, AZStd::move(testFailures)));
+
+                    const auto name = AZStd::string::format("%s.%s", testSuite.m_name.c_str(), testCase.m_name.c_str());
+                    tests.push_back(Client::Test(name, result));
                 }
             }
         }
 
-        return testCaseFailures;
+        return tests;
     }
 
     template
@@ -75,11 +85,11 @@ namespace TestImpact
         AZStd::chrono::milliseconds duration,
         const AZStd::vector& testJobs)
     {
-        AZStd::vector passingTests;
-        AZStd::vector failingTests;
-        AZStd::vector executionFailureTests;
-        AZStd::vector timedOutTests;
-        AZStd::vector unexecutedTests;
+        AZStd::vector passingTests;
+        AZStd::vector failingTests;
+        AZStd::vector executionFailureTests;
+        AZStd::vector timedOutTests;
+        AZStd::vector unexecutedTests;
         
         for (const auto& testJob : testJobs)
         {
@@ -88,7 +98,7 @@ namespace TestImpact
                 AZStd::chrono::high_resolution_clock::time_point() +
                 AZStd::chrono::duration_cast(testJob.GetStartTime() - startTime);
 
-            Client::TestRun clientTestRun(
+            Client::TestRunBase clientTestRun(
                 testJob.GetTestTarget()->GetName(), testJob.GetCommandString(), relativeStartTime, testJob.GetDuration(),
                 testJob.GetTestResult());
 
@@ -96,27 +106,27 @@ namespace TestImpact
             {
             case Client::TestRunResult::FailedToExecute:
             {
-                executionFailureTests.push_back(clientTestRun);
+                executionFailureTests.emplace_back(AZStd::move(clientTestRun));
                 break;
             }
             case Client::TestRunResult::NotRun:
             {
-                unexecutedTests.push_back(clientTestRun);
+                unexecutedTests.emplace_back(AZStd::move(clientTestRun));
                 break;
             }
             case Client::TestRunResult::Timeout:
             {
-                timedOutTests.push_back(clientTestRun);
+                timedOutTests.emplace_back(AZStd::move(clientTestRun));
                 break;
             }
             case Client::TestRunResult::AllTestsPass:
             {
-                passingTests.push_back(clientTestRun);
+                passingTests.emplace_back(AZStd::move(clientTestRun), GenerateClientTests(testJob));
                 break;
             }
             case Client::TestRunResult::TestFailures:
             {
-                failingTests.emplace_back(AZStd::move(clientTestRun), GenerateTestCaseFailures(testJob));
+                failingTests.emplace_back(AZStd::move(clientTestRun), GenerateClientTests(testJob));
                 break;
             }
             default:
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactUtils.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactUtils.cpp
new file mode 100644
index 0000000000..993aee9af5
--- /dev/null
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactUtils.cpp
@@ -0,0 +1,244 @@
+/*
+ * 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 
+#include 
+
+#include 
+
+namespace TestImpact
+{
+    //! Delete the files that match the pattern from the specified directory.
+    //! @param path The path to the directory to pattern match the files for deletion.
+    //! @param pattern The pattern to match files for deletion.
+    size_t DeleteFiles(const RepoPath& path, const AZStd::string& pattern)
+    {
+        size_t numFilesDeleted = 0;
+
+        AZ::IO::SystemFile::FindFiles(
+            AZStd::string::format("%s/%s", path.c_str(), pattern.c_str()).c_str(),
+            [&path, &numFilesDeleted](const char* file, bool isFile)
+            {
+                if (isFile)
+                {
+                    AZ::IO::SystemFile::Delete(AZStd::string::format("%s/%s", path.c_str(), file).c_str());
+                    numFilesDeleted++;
+                }
+
+                return true;
+            });
+
+        return numFilesDeleted;
+    }
+
+    //! Deletes the specified file.
+    void DeleteFile(const RepoPath& file)
+    {
+        DeleteFiles(file.ParentPath(), file.Filename().Native());
+    }
+
+    //! User-friendly names for the test suite types.
+    AZStd::string SuiteTypeAsString(SuiteType suiteType)
+    {
+        switch (suiteType)
+        {
+        case SuiteType::Main:
+            return "main";
+        case SuiteType::Periodic:
+            return "periodic";
+        case SuiteType::Sandbox:
+            return "sandbox";
+        default:
+            throw(Exception("Unexpected suite type"));
+        }
+    }
+
+    AZStd::string SequenceReportTypeAsString(Client::SequenceReportType type)
+    {
+        switch (type)
+        {
+        case Client::SequenceReportType::RegularSequence:
+            return "regular";
+        case Client::SequenceReportType::SeedSequence:
+            return "seed";
+        case Client::SequenceReportType::ImpactAnalysisSequence:
+            return "impact_analysis";
+        case Client::SequenceReportType::SafeImpactAnalysisSequence:
+            return "safe_impact_analysis";
+        default:
+            throw(Exception(AZStd::string::format("Unexpected sequence report type: %u", aznumeric_cast(type))));
+        }
+    }
+
+    AZStd::string TestSequenceResultAsString(TestSequenceResult result)
+    {
+        switch (result)
+        {
+        case TestSequenceResult::Failure:
+            return "failure";
+        case TestSequenceResult::Success:
+            return "success";
+        case TestSequenceResult::Timeout:
+            return "timeout";
+        default:
+            throw(Exception(AZStd::string::format("Unexpected test sequence result: %u", aznumeric_cast(result))));
+        }
+    }
+
+    AZStd::string TestRunResultAsString(Client::TestRunResult result)
+    {
+        switch (result)
+        {
+        case Client::TestRunResult::AllTestsPass:
+            return "all_tests_pass";
+        case Client::TestRunResult::FailedToExecute:
+            return "failed_to_execute";
+        case Client::TestRunResult::NotRun:
+            return "not_run";
+        case Client::TestRunResult::TestFailures:
+            return "test_failures";
+        case Client::TestRunResult::Timeout:
+            return "timeout";
+        default:
+            throw(Exception(AZStd::string::format("Unexpected test run result: %u", aznumeric_cast(result))));
+        }
+    }
+
+    AZStd::string ExecutionFailurePolicyAsString(Policy::ExecutionFailure executionFailurePolicy)
+    {
+        switch (executionFailurePolicy)
+        {
+        case Policy::ExecutionFailure::Abort:
+            return "abort";
+        case Policy::ExecutionFailure::Continue:
+            return "continue";
+        case Policy::ExecutionFailure::Ignore:
+            return "ignore";
+        default:
+            throw(Exception(
+                AZStd::string::format("Unexpected execution failure policy: %u", aznumeric_cast(executionFailurePolicy))));
+        }
+    }
+
+    AZStd::string FailedTestCoveragePolicyAsString(Policy::FailedTestCoverage failedTestCoveragePolicy)
+    {
+        switch (failedTestCoveragePolicy)
+        {
+        case Policy::FailedTestCoverage::Discard:
+            return "discard";
+        case Policy::FailedTestCoverage::Keep:
+            return "keep";
+        default:
+            throw(Exception(
+                AZStd::string::format("Unexpected failed test coverage policy: %u", aznumeric_cast(failedTestCoveragePolicy))));
+        }
+    }
+
+    AZStd::string TestPrioritizationPolicyAsString(Policy::TestPrioritization testPrioritizationPolicy)
+    {
+        switch (testPrioritizationPolicy)
+        {
+        case Policy::TestPrioritization::DependencyLocality:
+            return "dependency_locality";
+        case Policy::TestPrioritization::None:
+            return "none";
+        default:
+            throw(Exception(
+                AZStd::string::format("Unexpected test prioritization policy: %u", aznumeric_cast(testPrioritizationPolicy))));
+        }
+    }
+
+    AZStd::string TestFailurePolicyAsString(Policy::TestFailure testFailurePolicy)
+    {
+        switch (testFailurePolicy)
+        {
+        case Policy::TestFailure::Abort:
+            return "abort";
+        case Policy::TestFailure::Continue:
+            return "continue";
+        default:
+            throw(
+                Exception(AZStd::string::format("Unexpected test failure policy: %u", aznumeric_cast(testFailurePolicy))));
+        }
+    }
+
+    AZStd::string IntegrityFailurePolicyAsString(Policy::IntegrityFailure integrityFailurePolicy)
+    {
+        switch (integrityFailurePolicy)
+        {
+        case Policy::IntegrityFailure::Abort:
+            return "abort";
+        case Policy::IntegrityFailure::Continue:
+            return "continue";
+        default:
+            throw(Exception(
+                AZStd::string::format("Unexpected integration failure policy: %u", aznumeric_cast(integrityFailurePolicy))));
+        }
+    }
+
+    AZStd::string DynamicDependencyMapPolicyAsString(Policy::DynamicDependencyMap dynamicDependencyMapPolicy)
+    {
+        switch (dynamicDependencyMapPolicy)
+        {
+        case Policy::DynamicDependencyMap::Discard:
+            return "discard";
+        case Policy::DynamicDependencyMap::Update:
+            return "update";
+        default:
+            throw(Exception(AZStd::string::format(
+                "Unexpected dynamic dependency map policy: %u", aznumeric_cast(dynamicDependencyMapPolicy))));
+        }
+    }
+
+    AZStd::string TestShardingPolicyAsString(Policy::TestSharding testShardingPolicy)
+    {
+        switch (testShardingPolicy)
+        {
+        case Policy::TestSharding::Always:
+            return "always";
+        case Policy::TestSharding::Never:
+            return "never";
+        default:
+            throw(Exception(
+                AZStd::string::format("Unexpected test sharding policy: %u", aznumeric_cast(testShardingPolicy))));
+        }
+    }
+
+    AZStd::string TargetOutputCapturePolicyAsString(Policy::TargetOutputCapture targetOutputCapturePolicy)
+    {
+        switch (targetOutputCapturePolicy)
+        {
+        case Policy::TargetOutputCapture::File:
+            return "file";
+        case Policy::TargetOutputCapture::None:
+            return "none";
+        case Policy::TargetOutputCapture::StdOut:
+            return "stdout";
+        case Policy::TargetOutputCapture::StdOutAndFile:
+            return "stdout_file";
+        default:
+            throw(Exception(
+                AZStd::string::format("Unexpected target output capture policy: %u", aznumeric_cast(targetOutputCapturePolicy))));
+        }
+    }
+
+    AZStd::string ClientTestResultAsString(Client::TestResult result)
+    {
+        switch (result)
+        {
+        case Client::TestResult::Failed:
+            return "failed";
+        case Client::TestResult::NotRun:
+            return "not_run";
+        case Client::TestResult::Passed:
+            return "passed";
+        default:
+            throw(Exception(AZStd::string::format("Unexpected client test case result: %u", aznumeric_cast(result))));
+        }
+    }
+} // namespace TestImpact
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/testimpactframework_runtime_files.cmake b/Code/Tools/TestImpactFramework/Runtime/Code/testimpactframework_runtime_files.cmake
index 76673d9f40..75f253ad27 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/testimpactframework_runtime_files.cmake
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/testimpactframework_runtime_files.cmake
@@ -16,11 +16,14 @@ set(FILES
     Include/TestImpactFramework/TestImpactChangelist.h
     Include/TestImpactFramework/TestImpactChangelistSerializer.h
     Include/TestImpactFramework/TestImpactChangelistException.h
+    Include/TestImpactFramework/TestImpactPolicy.h
     Include/TestImpactFramework/TestImpactTestSequence.h
     Include/TestImpactFramework/TestImpactClientTestSelection.h
     Include/TestImpactFramework/TestImpactClientTestRun.h
     Include/TestImpactFramework/TestImpactClientSequenceReport.h
-    Include/TestImpactFramework/TestImpactFileUtils.h
+    Include/TestImpactFramework/TestImpactUtils.h
+    Include/TestImpactFramework/TestImpactClientSequenceReportSerializer.h
+    Include/TestImpactFramework/TestImpactSequenceReportException.h
     Source/Artifact/TestImpactArtifactException.h
     Source/Artifact/Factory/TestImpactBuildTargetDescriptorFactory.cpp
     Source/Artifact/Factory/TestImpactBuildTargetDescriptorFactory.h
@@ -125,5 +128,7 @@ set(FILES
     Source/TestImpactClientTestRun.cpp
     Source/TestImpactClientSequenceReport.cpp
     Source/TestImpactChangeListSerializer.cpp
+    Source/TestImpactClientSequenceReportSerializer.cpp
     Source/TestImpactRepoPath.cpp
+    Source/TestImpactUtils.cpp
 )
diff --git a/Gems/AWSCore/Code/Source/AWSCoreSystemComponent.cpp b/Gems/AWSCore/Code/Source/AWSCoreSystemComponent.cpp
index c24518a4d7..92a5aa493f 100644
--- a/Gems/AWSCore/Code/Source/AWSCoreSystemComponent.cpp
+++ b/Gems/AWSCore/Code/Source/AWSCoreSystemComponent.cpp
@@ -160,7 +160,7 @@ namespace AWSCore
                 // assigned to a specific CPU starting with the specified CPU.
                 AZ::JobManagerDesc jobManagerDesc{};
                 AZ::JobManagerThreadDesc threadDesc(m_firstThreadCPU, m_threadPriority, m_threadStackSize);
-                for (unsigned int i = 0; i < m_threadCount; ++i)
+                for (int i = 0; i < m_threadCount; ++i)
                 {
                     jobManagerDesc.m_workerThreads.push_back(threadDesc);
                     if (threadDesc.m_cpuId > -1)
diff --git a/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionManager.cpp b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionManager.cpp
index e0b4db9165..85dd1469cb 100644
--- a/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionManager.cpp
+++ b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionManager.cpp
@@ -139,7 +139,7 @@ namespace AWSCore
         AZStd::chrono::seconds lastSendTimeStamp = AZStd::chrono::seconds(lastSendTimeStampSeconds);
         AZStd::chrono::seconds secondsSinceLastSend =
             AZStd::chrono::duration_cast(AZStd::chrono::system_clock::now().time_since_epoch()) - lastSendTimeStamp;
-        if (secondsSinceLastSend.count() >= delayInSeconds)
+        if (static_cast(secondsSinceLastSend.count()) >= delayInSeconds)
         {
             return true;
         }
diff --git a/Gems/AWSMetrics/Code/Include/Private/ClientConfiguration.h b/Gems/AWSMetrics/Code/Include/Private/ClientConfiguration.h
index 7bcb60d325..ddda2299d4 100644
--- a/Gems/AWSMetrics/Code/Include/Private/ClientConfiguration.h
+++ b/Gems/AWSMetrics/Code/Include/Private/ClientConfiguration.h
@@ -8,6 +8,7 @@
 #pragma once
 
 #include 
+#include 
 
 namespace AWSMetrics
 {
diff --git a/Gems/AWSMetrics/Code/Source/MetricsManager.cpp b/Gems/AWSMetrics/Code/Source/MetricsManager.cpp
index 5c4d910658..03e31770ee 100644
--- a/Gems/AWSMetrics/Code/Source/MetricsManager.cpp
+++ b/Gems/AWSMetrics/Code/Source/MetricsManager.cpp
@@ -106,7 +106,7 @@ namespace AWSMetrics
         AZStd::lock_guard lock(m_metricsMutex);
         m_metricsQueue.AddMetrics(metricsEvent);
 
-        if (m_metricsQueue.GetSizeInBytes() >= m_clientConfiguration->GetMaxQueueSizeInBytes())
+        if (m_metricsQueue.GetSizeInBytes() >= static_cast(m_clientConfiguration->GetMaxQueueSizeInBytes()))
         {
             // Flush the metrics queue when the accumulated metrics size hits the limit
             m_waitEvent.release();
@@ -431,7 +431,7 @@ namespace AWSMetrics
                 AZStd::lock_guard lock(m_metricsMutex);
                 m_metricsQueue.AddMetrics(offlineRecords[index]);
 
-                if (m_metricsQueue.GetSizeInBytes() >= m_clientConfiguration->GetMaxQueueSizeInBytes())
+                if (m_metricsQueue.GetSizeInBytes() >= static_cast(m_clientConfiguration->GetMaxQueueSizeInBytes()))
                 {
                     // Flush the metrics queue when the accumulated metrics size hits the limit
                     m_waitEvent.release();
diff --git a/Gems/AWSMetrics/Code/Source/MetricsQueue.cpp b/Gems/AWSMetrics/Code/Source/MetricsQueue.cpp
index ab54fb9e3e..4cc037189a 100644
--- a/Gems/AWSMetrics/Code/Source/MetricsQueue.cpp
+++ b/Gems/AWSMetrics/Code/Source/MetricsQueue.cpp
@@ -216,7 +216,7 @@ namespace AWSMetrics
             return false;
         }
 
-        for (int metricsIndex = 0; metricsIndex < doc.Size(); metricsIndex++)
+        for (rapidjson::SizeType metricsIndex = 0; metricsIndex < doc.Size(); metricsIndex++)
         {
             MetricsEvent metrics;
             if (!metrics.ReadFromJson(doc[metricsIndex]))
diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Editor/EditorCommon.cpp b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Editor/EditorCommon.cpp
index 9938d55502..8ce8b2d487 100644
--- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Editor/EditorCommon.cpp
+++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Editor/EditorCommon.cpp
@@ -57,10 +57,10 @@ namespace ImageProcessingAtomEditor
         static double mb = kb * 1024.0;
         static double gb = mb * 1024.0;
 
-        static AZStd::string byteStr = "B";
-        static AZStd::string kbStr = "KB";
-        static AZStd::string mbStr = "MB";
-        static AZStd::string gbStr = "GB";
+        static AZStd::fixed_string<2> byteStr = "B";
+        static AZStd::fixed_string<3> kbStr = "KB";
+        static AZStd::fixed_string<3> mbStr = "MB";
+        static AZStd::fixed_string<3> gbStr = "GB";
 
 #if AZ_TRAIT_IMAGEPROCESSING_USE_BASE10_BYTE_PREFIX
         kb = 1000.0;
diff --git a/Gems/Atom/Feature/Common/Code/Source/LuxCore/LuxCoreRenderer.cpp b/Gems/Atom/Feature/Common/Code/Source/LuxCore/LuxCoreRenderer.cpp
index 40fcbc7f31..c753079d5b 100644
--- a/Gems/Atom/Feature/Common/Code/Source/LuxCore/LuxCoreRenderer.cpp
+++ b/Gems/Atom/Feature/Common/Code/Source/LuxCore/LuxCoreRenderer.cpp
@@ -19,7 +19,7 @@
 
 namespace LuxCoreUI
 {
-    void LaunchLuxCoreUI(const AZStd::string& luxCoreExeFullPath, AZStd::string& commandLine);
+    void LaunchLuxCoreUI(const AZStd::string& luxCoreExeFullPath, const AZStd::string& commandLine);
 }
 
 namespace AZ
diff --git a/Gems/Atom/Feature/Common/Code/Source/Platform/Windows/LaunchLuxCoreUI_Windows.cpp b/Gems/Atom/Feature/Common/Code/Source/Platform/Windows/LaunchLuxCoreUI_Windows.cpp
index 3c8f304cb6..7f15949201 100644
--- a/Gems/Atom/Feature/Common/Code/Source/Platform/Windows/LaunchLuxCoreUI_Windows.cpp
+++ b/Gems/Atom/Feature/Common/Code/Source/Platform/Windows/LaunchLuxCoreUI_Windows.cpp
@@ -7,11 +7,12 @@
  */
 
 #include 
+#include 
 #include 
 
 namespace LuxCoreUI
 {
-    void LaunchLuxCoreUI(const AZStd::string& luxCoreExeFullPath, AZStd::string& commandLine)
+    void LaunchLuxCoreUI(const AZStd::string& luxCoreExeFullPath, const AZStd::string& commandLine)
     {
         STARTUPINFO si;
         PROCESS_INFORMATION pi;
@@ -20,9 +21,14 @@ namespace LuxCoreUI
         si.cb = sizeof(si);
         ZeroMemory(&pi, sizeof(pi));
 
+        AZStd::wstring luxCoreExeFullPathW;
+        AZStd::to_wstring(luxCoreExeFullPathW, luxCoreExeFullPath.c_str());
+        AZStd::wstring commandLineW;
+        AZStd::to_wstring(commandLineW, commandLine.c_str());
+
         // start the program up
-        CreateProcess(luxCoreExeFullPath.data(),   // the path
-            commandLine.data(),        // Command line
+        CreateProcessW(luxCoreExeFullPathW.c_str(),   // the path
+            commandLineW.data(),        // Command line
             NULL,           // Process handle not inheritable
             NULL,           // Thread handle not inheritable
             FALSE,          // Set handle inheritance to FALSE
diff --git a/Gems/Atom/RHI/Code/CMakeLists.txt b/Gems/Atom/RHI/Code/CMakeLists.txt
index eeb8f73bac..343736ff7c 100644
--- a/Gems/Atom/RHI/Code/CMakeLists.txt
+++ b/Gems/Atom/RHI/Code/CMakeLists.txt
@@ -11,20 +11,19 @@ ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Sourc
 
 include(${pal_dir}/AtomRHITests_traits_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
 
+set(LY_RENDERDOC_ENABLED OFF CACHE BOOL "Enable RenderDoc integration.")
 set(RENDERDOC_CMAKE ${CMAKE_CURRENT_SOURCE_DIR}/${pal_dir}/renderdoc_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
 if(EXISTS ${RENDERDOC_CMAKE})
     include(${RENDERDOC_CMAKE})
 endif()
 
-if(TARGET "3rdParty::renderdoc")
+if(LY_RENDERDOC_ENABLED AND TARGET "3rdParty::renderdoc")
     message(STATUS "Renderdoc found, adding as runtime dependency")
     set(USE_RENDERDOC_DEFINE "USE_RENDERDOC")
     set(RENDERDOC_BUILD_DEPENDENCY "3rdParty::renderdoc")
-    set(RENDERDOC_API_DEPENDENCY "3rdParty::renderdoc_api")
 else()
     set(USE_RENDERDOC_DEFINE "")
     set(RENDERDOC_BUILD_DEPENDENCY "")
-    set(RENDERDOC_API_DEPENDENCY "")
 endif()
 
 ly_add_target(
@@ -62,9 +61,8 @@ ly_add_target(
             AZ::AzCore
             AZ::AzFramework
             Gem::Atom_RHI.Reflect
-            ${RENDERDOC_BUILD_DEPENDENCY}
         PUBLIC
-            ${RENDERDOC_API_DEPENDENCY}
+            ${RENDERDOC_BUILD_DEPENDENCY}
     COMPILE_DEFINITIONS
         PUBLIC
             ${USE_RENDERDOC_DEFINE}
diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/ConstantsLayout.h b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/ConstantsLayout.h
index ea9ef23af0..653e8e4474 100644
--- a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/ConstantsLayout.h
+++ b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/ConstantsLayout.h
@@ -82,6 +82,10 @@ namespace AZ
             //! If validation is disabled, true is always returned.
             bool ValidateAccess(ShaderInputConstantIndex inputIndex) const;
 
+            //! Prints to the console the shader input names specified by input list of indices
+            //! Will ignore any indices outside of the inputs array bounds
+            void DebugPrintNames(AZStd::array_view constantList) const;
+
         protected:
             ConstantsLayout() = default;
 
@@ -95,7 +99,6 @@ namespace AZ
 
             AZStd::vector m_inputs;
             IdReflectionMapForConstants m_idReflection;
-            AZStd::vector m_intervals;
             uint32_t m_sizeInBytes = 0;
             HashValue64 m_hash = InvalidHash;
         };
diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/NameIdReflectionMap.h b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/NameIdReflectionMap.h
index 7467c4d6b4..0dc0b30181 100644
--- a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/NameIdReflectionMap.h
+++ b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/NameIdReflectionMap.h
@@ -69,6 +69,9 @@ namespace AZ
             /// Return the number of entries
             size_t Size() const;
 
+            // Returns true if size is zero
+            bool IsEmpty() const;
+
             class NameIdReflectionMapSerializationEvents
                 : public SerializeContext::IEventHandler
             {
@@ -169,6 +172,12 @@ namespace AZ
             return m_reflectionMap.size();
         }
 
+        template 
+        bool NameIdReflectionMap::IsEmpty() const
+        {
+            return Size() == 0;
+        }
+
         template 
         void NameIdReflectionMap::Sort()
         {
diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/ConstantsData.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/ConstantsData.h
index dc5fb80435..ff1158e455 100644
--- a/Gems/Atom/RHI/Code/Include/Atom/RHI/ConstantsData.h
+++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/ConstantsData.h
@@ -85,6 +85,14 @@ namespace AZ
             //! Returns the constants layout.
             const ConstantsLayout* GetLayout() const;
 
+            //! Returns whether other constant data and this have the same value at the specified shader input index
+            bool ConstantIsEqual(const ConstantsData& other, ShaderInputConstantIndex inputIndex) const;
+
+            //! Performs a diff between this and input constant data and returns a list of all the shader input indices
+            //! for which the constants are not the same between the two. If one of the two has more constants than the
+            //! other, these additional constants will be added to the end of the returned list.
+            AZStd::vector GetIndicesOfDifferingConstants(const ConstantsData& other) const;
+
         private:
             enum class ValidateConstantAccessExpect : uint32_t
             {
diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/Device.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/Device.h
index 3f79392403..4232658980 100644
--- a/Gems/Atom/RHI/Code/Include/Atom/RHI/Device.h
+++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/Device.h
@@ -8,6 +8,7 @@
 
 #pragma once
 
+#include 
 #include 
 #include 
 #include 
@@ -140,6 +141,9 @@ namespace AZ
             //! Get the memory requirements for allocating a buffer resource.
             virtual ResourceMemoryRequirements GetResourceMemoryRequirements(const BufferDescriptor& descriptor) = 0;
 
+            //! Notifies after all objects currently in the platform release queue are released
+            virtual void ObjectCollectionNotify(RHI::ObjectCollectorNotifyFunction notifyFunction) = 0;
+
         protected:
             DeviceFeatures m_features;
             DeviceLimits m_limits;
diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/ObjectCollector.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/ObjectCollector.h
index cb66225286..cd8a85a385 100644
--- a/Gems/Atom/RHI/Code/Include/Atom/RHI/ObjectCollector.h
+++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/ObjectCollector.h
@@ -34,6 +34,8 @@ namespace AZ
             using MutexType = NullMutex;
         };
 
+        using ObjectCollectorNotifyFunction = AZStd::function;
+
         /**
          * Deferred-releases reference-counted objects at a specific latency. Example: Use to batch-release
          * objects that exist on the GPU timeline at the end of the frame after syncing the oldest GPU frame.
@@ -85,6 +87,9 @@ namespace AZ
             /// Must not be called at collection time.
             size_t GetObjectCount() const;
 
+            /// Notifies after the current set of pending objects is released.
+            void Notify(ObjectCollectorNotifyFunction notifyFunction);
+
         private:
             void QueueForCollectInternal(ObjectPtrType object);
 
@@ -92,6 +97,7 @@ namespace AZ
             {
                 AZStd::vector m_objects;
                 uint64_t m_collectIteration;
+                AZStd::vector m_notifies;
             };
 
             inline bool IsGarbageReady(size_t collectIteration)
@@ -106,6 +112,7 @@ namespace AZ
             mutable typename Traits::MutexType m_mutex;
             AZStd::vector m_pendingObjects;
             AZStd::vector m_pendingGarbage;
+            AZStd::vector m_pendingNotifies;
         };
 
         template 
@@ -172,6 +179,39 @@ namespace AZ
             {
                 m_pendingGarbage.push_back({ AZStd::move(m_pendingObjects), m_currentIteration });
             }
+
+            if (!m_pendingNotifies.empty())
+            {
+                if (!m_pendingGarbage.empty())
+                {
+                    // find the newest garbage entry and add any pending notifies
+                    Garbage& latestGarbage = m_pendingGarbage.front();
+                    size_t latestGarbageAge = m_currentIteration - latestGarbage.m_collectIteration;
+
+                    // check the rest of the entries to see if they are newer
+                    for (size_t i = 1; i < m_pendingGarbage.size(); ++i)
+                    {
+                        size_t age = m_currentIteration - m_pendingGarbage[i].m_collectIteration;
+                        if (age < latestGarbageAge)
+                        {
+                            latestGarbage = m_pendingGarbage[i];
+                            latestGarbageAge = age;
+                        }
+                    }
+
+                    latestGarbage.m_notifies.insert(latestGarbage.m_notifies.end(), m_pendingNotifies.begin(), m_pendingNotifies.end());
+                }
+                else
+                {
+                    // garbage queue is empty, notify now
+                    for (auto& notifyFunction : m_pendingNotifies)
+                    {
+                        notifyFunction();
+                    }
+                }
+
+                m_pendingNotifies.clear();
+            }
             m_mutex.unlock();
 
             size_t objectCount = 0;
@@ -189,6 +229,12 @@ namespace AZ
                         }
                     }
                     objectCount += garbage.m_objects.size();
+
+                    for (auto& notifyFunction : garbage.m_notifies)
+                    {
+                        notifyFunction();
+                    }
+
                     garbage = AZStd::move(m_pendingGarbage.back());
                     m_pendingGarbage.pop_back();
                 }
@@ -215,5 +261,13 @@ namespace AZ
 
             return objectCount;
         }
+
+        template 
+        void ObjectCollector::Notify(ObjectCollectorNotifyFunction notifyFunction)
+        {
+            m_mutex.lock();
+            m_pendingNotifies.push_back(notifyFunction);
+            m_mutex.unlock();
+        }
     }
 }
diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/ShaderResourceGroupData.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/ShaderResourceGroupData.h
index 5fe645be82..0ce43159f6 100644
--- a/Gems/Atom/RHI/Code/Include/Atom/RHI/ShaderResourceGroupData.h
+++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/ShaderResourceGroupData.h
@@ -173,6 +173,9 @@ namespace AZ
             //! Different platforms might follow different packing rules for the internally-managed SRG constant buffer.
             AZStd::array_view GetConstantData() const;
 
+            //! Returns the underlying ConstantsData struct
+            const ConstantsData& GetConstantsData() const;
+
             //! Returns the shader resource layout for this group.
             const ShaderResourceGroupLayout* GetLayout() const;
 
diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/ShaderResourceGroupDebug.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/ShaderResourceGroupDebug.h
new file mode 100644
index 0000000000..d9ea77d823
--- /dev/null
+++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/ShaderResourceGroupDebug.h
@@ -0,0 +1,31 @@
+/*
+ * 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
+ *
+ */
+#pragma once
+
+namespace AZ
+{
+    namespace RHI
+    {
+        class ConstantsData;
+        struct DrawItem;
+        class ShaderResourceGroup;
+
+        /// Given a ShaderResourceGroup and a reference ConstantsData input, this function will fetch the ConstantsData on the SRG and compare it
+        /// to the reference ConstantsData. It will print the names of any constants that are different between the two.
+        /// The parameter updateReferenceData can be used to set the reference data to the SRG's constant data after the comparison. This is
+        /// useful for keeping track of differences in between calls to the function, such as between frames.
+        void PrintConstantDataDiff(const ShaderResourceGroup& shaderResourceGroup, ConstantsData& referenceData, bool updateReferenceData = false);
+
+        /// Given a DrawItem, an SRG binding slot on that draw item and a reference ConstantsData input, this function will fetch the ConstantsData
+        /// from the draw item's SRG at the binding slot and compare it to the reference ConstantsData. It will print the names of any constants
+        /// that are different between the two.
+        /// The parameter updateReferenceData can be used to set the reference data to the draw item's constant data after the comparison. This is
+        /// useful for keeping track of differences in between calls to the function, such as between frames.
+        void PrintConstantDataDiff(const DrawItem& drawItem, ConstantsData& referenceData, uint32_t srgBindingSlot, bool updateReferenceData = false);
+
+    }
+}
diff --git a/Gems/Atom/RHI/Code/Platform/Linux/renderdoc_linux.cmake b/Gems/Atom/RHI/Code/Platform/Linux/renderdoc_linux.cmake
index 0faccf80ec..222a3d5768 100644
--- a/Gems/Atom/RHI/Code/Platform/Linux/renderdoc_linux.cmake
+++ b/Gems/Atom/RHI/Code/Platform/Linux/renderdoc_linux.cmake
@@ -24,13 +24,6 @@ if(NOT LY_MONOLITHIC_GAME)
                 INCLUDE_DIRECTORIES "."
                 RUNTIME_DEPENDENCIES "${RENDERDOC_PATH}/librenderdoc.so"
             )
-
-            ly_add_external_target(
-                NAME renderdoc_api
-                VERSION
-                3RDPARTY_ROOT_DIRECTORY ${RENDERDOC_PATH}
-                INCLUDE_DIRECTORIES "."
-            )
         endif()
     endif()
 endif()
\ No newline at end of file
diff --git a/Gems/Atom/RHI/Code/Platform/Windows/renderdoc_windows.cmake b/Gems/Atom/RHI/Code/Platform/Windows/renderdoc_windows.cmake
index 499321b2ab..90c44bcb7c 100644
--- a/Gems/Atom/RHI/Code/Platform/Windows/renderdoc_windows.cmake
+++ b/Gems/Atom/RHI/Code/Platform/Windows/renderdoc_windows.cmake
@@ -9,7 +9,7 @@
 # Prevent bundling the renderdoc dll with a packaged title
 if(NOT LY_MONOLITHIC_GAME)
     # Common installation path for renderdoc path
-    set(RENDERDOC_PATH "C:/Program Files/RenderDoc")
+    set(RENDERDOC_PATH "$ENV{PROGRAMFILES}/RenderDoc")
     if(DEFINED ENV{"ATOM_RENDERDOC_PATH"})
         set(RENDERDOC_PATH ENV{"ATOM_RENDERDOC_PATH"})
     endif()
@@ -26,13 +26,6 @@ if(NOT LY_MONOLITHIC_GAME)
                 INCLUDE_DIRECTORIES "."
                 RUNTIME_DEPENDENCIES "${RENDERDOC_PATH}/renderdoc.dll"
             )
-
-            ly_add_external_target(
-                NAME renderdoc_api
-                VERSION
-                3RDPARTY_ROOT_DIRECTORY ${RENDERDOC_PATH}
-                INCLUDE_DIRECTORIES "."
-            )
         endif()
     endif()
 endif()
\ No newline at end of file
diff --git a/Gems/Atom/RHI/Code/Source/RHI.Reflect/ConstantsLayout.cpp b/Gems/Atom/RHI/Code/Source/RHI.Reflect/ConstantsLayout.cpp
index 956cc5be10..8be053e4ef 100644
--- a/Gems/Atom/RHI/Code/Source/RHI.Reflect/ConstantsLayout.cpp
+++ b/Gems/Atom/RHI/Code/Source/RHI.Reflect/ConstantsLayout.cpp
@@ -18,10 +18,9 @@ namespace AZ
             if (SerializeContext* serializeContext = azrtti_cast(context))
             {
                 serializeContext->Class()
-                    ->Version(0)
+                    ->Version(1)    // Version 1: Adding debug helper functions to Shader Resource Groups
                     ->Field("m_inputs", &ConstantsLayout::m_inputs)
                     ->Field("m_idReflection", &ConstantsLayout::m_idReflection)
-                    ->Field("m_intervals", &ConstantsLayout::m_intervals)
                     ->Field("m_sizeInBytes", &ConstantsLayout::m_sizeInBytes)
                     ->Field("m_hash", &ConstantsLayout::m_hash);
             }
@@ -43,7 +42,6 @@ namespace AZ
         {
             m_inputs.clear();
             m_idReflection.Clear();
-            m_intervals.clear();
             m_sizeInBytes = 0;
             m_hash = InvalidHash;
         }
@@ -67,11 +65,8 @@ namespace AZ
                     return false;
                 }
 
-                // The constant data size is the maximum offset + size from the start of the struct.
-                constantDataSize = AZStd::max(constantDataSize, constantDescriptor.m_constantByteOffset + constantDescriptor.m_constantByteCount);
-
-                // Add the [min, max) interval for the inline constant.
-                m_intervals.emplace_back(constantDescriptor.m_constantByteOffset, constantDescriptor.m_constantByteOffset + constantDescriptor.m_constantByteCount);
+                uint32_t end = constantDescriptor.m_constantByteOffset + constantDescriptor.m_constantByteCount;
+                constantDataSize = AZStd::max(constantDataSize, end);
 
                 ++constantInputIndex;
                 m_hash = TypeHash64(constantDescriptor.GetHash(), m_hash);
@@ -100,7 +95,10 @@ namespace AZ
 
         Interval ConstantsLayout::GetInterval(ShaderInputConstantIndex inputIndex) const
         {
-            return m_intervals[inputIndex.GetIndex()];
+            const ShaderInputConstantDescriptor& desc = GetShaderInput(inputIndex);
+            uint32_t start = desc.m_constantByteOffset;
+            uint32_t end = start + desc.m_constantByteCount;
+            return Interval(start, end);
         }
 
         const ShaderInputConstantDescriptor& ConstantsLayout::GetShaderInput(ShaderInputConstantIndex inputIndex) const
@@ -139,8 +137,8 @@ namespace AZ
             {
                 if (!m_sizeInBytes)
                 {
-                    AZ_Assert(m_intervals.empty(), "Constants size is not valid.");
-                    return m_intervals.empty();
+                    AZ_Assert(m_idReflection.IsEmpty(), "Constants size is not valid.");
+                    return m_idReflection.IsEmpty();
                 }
             }
 
@@ -149,5 +147,20 @@ namespace AZ
 
             return true;
         }
+
+        void ConstantsLayout::DebugPrintNames(AZStd::array_view constantList) const
+        {
+            AZStd::string output;
+            for (const ShaderInputConstantIndex& constantIdx : constantList)
+            {
+                if (constantIdx.GetIndex() < m_inputs.size())
+                {
+                    output += m_inputs[constantIdx.GetIndex()].m_name.GetCStr();
+                    output += " - ";
+                }
+            }
+            AZ_Printf("RHI", output.c_str());
+        }
+
     }
 }
diff --git a/Gems/Atom/RHI/Code/Source/RHI/ConstantsData.cpp b/Gems/Atom/RHI/Code/Source/RHI/ConstantsData.cpp
index 9144265a6d..1524883e54 100644
--- a/Gems/Atom/RHI/Code/Source/RHI/ConstantsData.cpp
+++ b/Gems/Atom/RHI/Code/Source/RHI/ConstantsData.cpp
@@ -405,5 +405,71 @@ namespace AZ
             AZ_Assert(m_layout, "Constants layout is null");
             return m_layout.get();
         }
+
+        bool ConstantsData::ConstantIsEqual(const ConstantsData& other, ShaderInputConstantIndex inputIndex) const
+        {
+            AZStd::array_view myConstant = GetConstantRaw(inputIndex);
+            AZStd::array_view otherConstant = other.GetConstantRaw(inputIndex);
+
+            // If they point to the same data, they are equal
+            if (myConstant == otherConstant)
+            {
+                return true;
+            }
+
+            // If they point to data of different size, they are not equal
+            if (myConstant.size() != otherConstant.size())
+            {
+                return false;
+            }
+
+            // If they point to differing data of same size, compare the data
+            // Note: due to small size of data this loop will be faster than a mem compare
+            for(uint32_t i = 0; i < myConstant.size(); ++i)
+            {
+                if (myConstant[i] != otherConstant[i])
+                {
+                    return false;
+                }
+            }
+
+            // Arrays point to different locations in memory but all bytes match, return true
+            return true;
+        }
+
+        AZStd::vector ConstantsData::GetIndicesOfDifferingConstants(const ConstantsData& other) const
+        {
+            AZStd::vector differingIndices;
+
+            if (m_layout == nullptr || other.m_layout == nullptr)
+            {
+                return differingIndices;
+            }
+
+            AZStd::array_view myShaderInputs = m_layout->GetShaderInputList();
+            AZStd::array_view otherShaderInputs = other.m_layout->GetShaderInputList();
+
+            size_t minSize = AZStd::min(myShaderInputs.size(), otherShaderInputs.size());
+            size_t maxSize = AZStd::max(myShaderInputs.size(), otherShaderInputs.size());
+
+            for (size_t idx = 0; idx < minSize; ++idx)
+            {
+                const ShaderInputConstantIndex inputIndex(idx);
+                if (!ConstantIsEqual(other, inputIndex))
+                {
+                    differingIndices.push_back(inputIndex);
+                }
+            }
+
+            // If sizes are different, add difference at the end
+            for (size_t idx = minSize; idx < maxSize; ++idx)
+            {
+                const ShaderInputConstantIndex inputIndex(idx);
+                differingIndices.push_back(inputIndex);
+            }
+
+            return differingIndices;
+        }
+
     }
 }
diff --git a/Gems/Atom/RHI/Code/Source/RHI/ShaderResourceGroupData.cpp b/Gems/Atom/RHI/Code/Source/RHI/ShaderResourceGroupData.cpp
index a9e08249c4..da7697d8f2 100644
--- a/Gems/Atom/RHI/Code/Source/RHI/ShaderResourceGroupData.cpp
+++ b/Gems/Atom/RHI/Code/Source/RHI/ShaderResourceGroupData.cpp
@@ -335,5 +335,10 @@ namespace AZ
             return m_constantsData.GetConstantData();
         }
 
+        const ConstantsData& ShaderResourceGroupData::GetConstantsData() const
+        {
+            return m_constantsData;
+        }
+
     } // namespace RHI
 } // namespace AZ
diff --git a/Gems/Atom/RHI/Code/Source/RHI/ShaderResourceGroupDebug.cpp b/Gems/Atom/RHI/Code/Source/RHI/ShaderResourceGroupDebug.cpp
new file mode 100644
index 0000000000..54399eba88
--- /dev/null
+++ b/Gems/Atom/RHI/Code/Source/RHI/ShaderResourceGroupDebug.cpp
@@ -0,0 +1,59 @@
+/*
+ * 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 
+#include 
+#include 
+#include 
+
+namespace AZ
+{
+    namespace RHI
+    {
+
+        void PrintConstantDataDiff(const ShaderResourceGroup& shaderResourceGroup, ConstantsData& referenceData, bool updateReferenceData)
+        {
+            const RHI::ConstantsData& currentData = shaderResourceGroup.GetData().GetConstantsData();
+
+            AZStd::vector differingIndices = currentData.GetIndicesOfDifferingConstants(referenceData);
+
+            if (differingIndices.size() > 0)
+            {
+                AZ_Printf("RHI", "Detected different SRG values for the following fields:\n");
+                if (currentData.GetLayout())
+                {
+                    currentData.GetLayout()->DebugPrintNames(differingIndices);
+                }
+            }
+
+            if (updateReferenceData)
+            {
+                referenceData = currentData;
+            }
+        }
+
+        void PrintConstantDataDiff(const DrawItem& drawItem, ConstantsData& referenceData, uint32_t srgBindingSlot, bool updateReferenceData)
+        {
+            int srgIndex = -1;
+            for (uint32_t i = 0; i < drawItem.m_shaderResourceGroupCount; ++i)
+            {
+                if (drawItem.m_shaderResourceGroups[i]->GetBindingSlot() == srgBindingSlot)
+                {
+                    srgIndex = i;
+                    break;
+                }
+            }
+
+            if (srgIndex != -1)
+            {
+                const ShaderResourceGroup& srg = *drawItem.m_shaderResourceGroups[srgIndex];
+                PrintConstantDataDiff(srg, referenceData, updateReferenceData);
+            }
+        }
+
+    }
+}
diff --git a/Gems/Atom/RHI/Code/Tests/Device.h b/Gems/Atom/RHI/Code/Tests/Device.h
index 3a7c513c8b..e11bd75983 100644
--- a/Gems/Atom/RHI/Code/Tests/Device.h
+++ b/Gems/Atom/RHI/Code/Tests/Device.h
@@ -60,6 +60,8 @@ namespace UnitTest
         AZ::RHI::ResourceMemoryRequirements GetResourceMemoryRequirements([[maybe_unused]] const AZ::RHI::ImageDescriptor& descriptor) { return AZ::RHI::ResourceMemoryRequirements{}; };
 
         AZ::RHI::ResourceMemoryRequirements GetResourceMemoryRequirements([[maybe_unused]] const AZ::RHI::BufferDescriptor& descriptor) { return AZ::RHI::ResourceMemoryRequirements{}; };
+
+        void ObjectCollectionNotify(AZ::RHI::ObjectCollectorNotifyFunction notifyFunction) override {}
     };
 
     AZ::RHI::Ptr MakeTestDevice();
diff --git a/Gems/Atom/RHI/Code/atom_rhi_public_files.cmake b/Gems/Atom/RHI/Code/atom_rhi_public_files.cmake
index a8c98c6674..338bae6386 100644
--- a/Gems/Atom/RHI/Code/atom_rhi_public_files.cmake
+++ b/Gems/Atom/RHI/Code/atom_rhi_public_files.cmake
@@ -157,10 +157,12 @@ set(FILES
     Source/RHI/ScopeAttachment.cpp
     Include/Atom/RHI/ShaderResourceGroup.h
     Include/Atom/RHI/ShaderResourceGroupData.h
+    Include/Atom/RHI/ShaderResourceGroupDebug.h
     Include/Atom/RHI/ShaderResourceGroupInvalidateRegistry.h
     Include/Atom/RHI/ShaderResourceGroupPool.h
     Source/RHI/ShaderResourceGroup.cpp
     Source/RHI/ShaderResourceGroupData.cpp
+    Source/RHI/ShaderResourceGroupDebug.cpp
     Source/RHI/ShaderResourceGroupInvalidateRegistry.cpp
     Source/RHI/ShaderResourceGroupPool.cpp
     Include/Atom/RHI/MemoryStatisticsBuilder.h
diff --git a/Gems/Atom/RHI/DX12/Code/Source/Platform/Windows/RHI/PhysicalDevice_Windows.cpp b/Gems/Atom/RHI/DX12/Code/Source/Platform/Windows/RHI/PhysicalDevice_Windows.cpp
index 6e5206fc00..2c56a860e8 100644
--- a/Gems/Atom/RHI/DX12/Code/Source/Platform/Windows/RHI/PhysicalDevice_Windows.cpp
+++ b/Gems/Atom/RHI/DX12/Code/Source/Platform/Windows/RHI/PhysicalDevice_Windows.cpp
@@ -78,7 +78,7 @@ namespace AZ
             }
 
             constexpr uint32_t SubKeyLength = 256;
-            char subKeyName[SubKeyLength];
+            wchar_t subKeyName[SubKeyLength];
 
             uint32_t driverVersion = 0;
 
diff --git a/Gems/Atom/RHI/DX12/Code/Source/Platform/Windows/RHI/WindowsVersionQuery.cpp b/Gems/Atom/RHI/DX12/Code/Source/Platform/Windows/RHI/WindowsVersionQuery.cpp
index 0301d48454..91f0a712dd 100644
--- a/Gems/Atom/RHI/DX12/Code/Source/Platform/Windows/RHI/WindowsVersionQuery.cpp
+++ b/Gems/Atom/RHI/DX12/Code/Source/Platform/Windows/RHI/WindowsVersionQuery.cpp
@@ -18,7 +18,7 @@ namespace AZ
             bool GetWindowsVersionFromSystemDLL(WindowsVersion* windowsVersion)
             {
                 // We get the file version of one of the system DLLs to get the OS version.
-                constexpr const char* dllName = "Kernel32.dll";
+                constexpr const wchar_t* dllName = L"Kernel32.dll";
                 VS_FIXEDFILEINFO* fileInfo = nullptr;
                 DWORD handle;
                 DWORD infoSize = GetFileVersionInfoSize(dllName, &handle);
@@ -28,7 +28,7 @@ namespace AZ
                     if (GetFileVersionInfo(dllName, handle, infoSize, versionData.data()) != 0)
                     {
                         UINT len;
-                        const char* subBlock = "\\";
+                        const wchar_t* subBlock = L"\\";
                         if (VerQueryValue(versionData.data(), subBlock, reinterpret_cast(&fileInfo), &len) != 0)
                         {
                             windowsVersion->m_majorVersion = HIWORD(fileInfo->dwProductVersionMS);
diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/Device.cpp b/Gems/Atom/RHI/DX12/Code/Source/RHI/Device.cpp
index 88c9098952..9d23dfa43d 100644
--- a/Gems/Atom/RHI/DX12/Code/Source/RHI/Device.cpp
+++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/Device.cpp
@@ -292,6 +292,11 @@ namespace AZ
             return memoryRequirements;
         }
 
+        void Device::ObjectCollectionNotify(RHI::ObjectCollectorNotifyFunction notifyFunction)
+        {
+            m_releaseQueue.Notify(notifyFunction);
+        }
+
         //AZStd::vector Device::GetValidSwapChainImageFormats(const RHI::WindowHandle& windowHandle) const
         //{
         //    AZStd::vector formatsList;
diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/Device.h b/Gems/Atom/RHI/DX12/Code/Source/RHI/Device.h
index 149508307a..9119545342 100644
--- a/Gems/Atom/RHI/DX12/Code/Source/RHI/Device.h
+++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/Device.h
@@ -162,6 +162,7 @@ namespace AZ
             void PreShutdown() override;
             RHI::ResourceMemoryRequirements GetResourceMemoryRequirements(const RHI::ImageDescriptor & descriptor) override;
             RHI::ResourceMemoryRequirements GetResourceMemoryRequirements(const RHI::BufferDescriptor & descriptor) override;
+            void ObjectCollectionNotify(RHI::ObjectCollectorNotifyFunction notifyFunction) override;
             //////////////////////////////////////////////////////////////////////////
 
             RHI::ResultCode InitSubPlatform(RHI::PhysicalDevice& physicalDevice);
diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/Fence.cpp b/Gems/Atom/RHI/DX12/Code/Source/RHI/Fence.cpp
index db15930c01..f61aa3f67f 100644
--- a/Gems/Atom/RHI/DX12/Code/Source/RHI/Fence.cpp
+++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/Fence.cpp
@@ -13,9 +13,13 @@ namespace AZ
     namespace DX12
     {
         FenceEvent::FenceEvent(const char* name)
-            : m_EventHandle(CreateEvent(nullptr, false, false, name))
+            : m_EventHandle(nullptr)
             , m_name(name)
-        {}
+        {
+            AZStd::wstring nameW;
+            AZStd::to_wstring(nameW, name);
+            m_EventHandle = CreateEvent(nullptr, false, false, nameW.c_str());
+        }
 
         FenceEvent::~FenceEvent()
         {
diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/MemoryView.cpp b/Gems/Atom/RHI/DX12/Code/Source/RHI/MemoryView.cpp
index 1246fb5b1a..c9d932afb1 100644
--- a/Gems/Atom/RHI/DX12/Code/Source/RHI/MemoryView.cpp
+++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/MemoryView.cpp
@@ -94,7 +94,7 @@ namespace AZ
             if (m_memoryAllocation.m_memory)
             {
                 AZStd::wstring wname;
-                AZStd::to_wstring(wname, name.data(), name.size());
+                AZStd::to_wstring(wname, name);
                 m_memoryAllocation.m_memory->SetName(wname.data());
             }
         }
diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/RayTracingPipelineState.cpp b/Gems/Atom/RHI/DX12/Code/Source/RHI/RayTracingPipelineState.cpp
index aebf705790..be0c084d95 100644
--- a/Gems/Atom/RHI/DX12/Code/Source/RHI/RayTracingPipelineState.cpp
+++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/RayTracingPipelineState.cpp
@@ -84,15 +84,15 @@ namespace AZ
             for (const RHI::RayTracingHitGroup& hitGroup : descriptor->GetHitGroups())
             {
                 AZStd::wstring hitGroupNameWstring;
-                AZStd::to_wstring(hitGroupNameWstring, hitGroup.m_hitGroupName.GetStringView().data(), hitGroup.m_hitGroupName.GetStringView().size());
+                AZStd::to_wstring(hitGroupNameWstring, hitGroup.m_hitGroupName.GetStringView());
                 hitGroupNameWstrings.push_back(hitGroupNameWstring);
 
                 AZStd::wstring closestHitShaderNameWstring;
-                AZStd::to_wstring(closestHitShaderNameWstring, hitGroup.m_closestHitShaderName.GetStringView().data(), hitGroup.m_closestHitShaderName.GetStringView().size());
+                AZStd::to_wstring(closestHitShaderNameWstring, hitGroup.m_closestHitShaderName.GetStringView());
                 closestHitShaderNameWstrings.push_back(closestHitShaderNameWstring);
 
                 AZStd::wstring anyHitShaderNameWstring;
-                AZStd::to_wstring(anyHitShaderNameWstring, hitGroup.m_anyHitShaderName.GetStringView().data(), hitGroup.m_anyHitShaderName.GetStringView().size());
+                AZStd::to_wstring(anyHitShaderNameWstring, hitGroup.m_anyHitShaderName.GetStringView());
                 anyHitShaderNameWstrings.push_back(anyHitShaderNameWstring);
 
                 D3D12_HIT_GROUP_DESC hitGroupDesc = {};
diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/RayTracingShaderTable.cpp b/Gems/Atom/RHI/DX12/Code/Source/RHI/RayTracingShaderTable.cpp
index eefb1a28aa..21e7dbc82e 100644
--- a/Gems/Atom/RHI/DX12/Code/Source/RHI/RayTracingShaderTable.cpp
+++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/RayTracingShaderTable.cpp
@@ -85,7 +85,7 @@ namespace AZ
                 uint8_t* nextRecord = RHI::AlignUp(mappedData + shaderRecordSize, D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT);
 
                 AZStd::wstring shaderExportNameWstring;
-                AZStd::to_wstring(shaderExportNameWstring, record.m_shaderExportName.GetStringView().data(), record.m_shaderExportName.GetStringView().size());
+                AZStd::to_wstring(shaderExportNameWstring, record.m_shaderExportName.GetStringView());
                 void* shaderIdentifier = stateObjectProperties->GetShaderIdentifier(shaderExportNameWstring.c_str());
                 memcpy(mappedData, shaderIdentifier, D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES);
                 mappedData += D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES;
diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.cpp b/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.cpp
index f0771d7c45..dbd2204e93 100644
--- a/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.cpp
+++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.cpp
@@ -315,7 +315,12 @@ namespace AZ
             memoryRequirements.m_sizeInBytes = bufferSizeAndAlign.size;
             return memoryRequirements;
         }
-      
+
+        void Device::ObjectCollectionNotify(RHI::ObjectCollectorNotifyFunction notifyFunction)
+        {
+            m_releaseQueue.Notify(notifyFunction);
+        }
+
         void Device::InitFeatures()
         {
             
diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.h b/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.h
index d8c3092c59..9cdeee7eae 100644
--- a/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.h
+++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.h
@@ -151,7 +151,8 @@ namespace AZ
             NullDescriptorManager& GetNullDescriptorManager();
             RHI::ResourceMemoryRequirements GetResourceMemoryRequirements(const RHI::ImageDescriptor & descriptor) override;
             RHI::ResourceMemoryRequirements GetResourceMemoryRequirements(const RHI::BufferDescriptor & descriptor) override;
-            
+            void ObjectCollectionNotify(RHI::ObjectCollectorNotifyFunction notifyFunction) override;
+
         private:
             Device() = default;
             
diff --git a/Gems/Atom/RHI/Null/Code/Source/RHI/Device.cpp b/Gems/Atom/RHI/Null/Code/Source/RHI/Device.cpp
index 7b94efb69f..08a2c4f411 100644
--- a/Gems/Atom/RHI/Null/Code/Source/RHI/Device.cpp
+++ b/Gems/Atom/RHI/Null/Code/Source/RHI/Device.cpp
@@ -20,5 +20,10 @@ namespace AZ
         {
             formatsCapabilities.fill(static_cast(~0));
         }
+
+        void Device::ObjectCollectionNotify(RHI::ObjectCollectorNotifyFunction notifyFunction)
+        {
+            notifyFunction();
+        }
     }
 }
diff --git a/Gems/Atom/RHI/Null/Code/Source/RHI/Device.h b/Gems/Atom/RHI/Null/Code/Source/RHI/Device.h
index 3aa045212b..cd44135e62 100644
--- a/Gems/Atom/RHI/Null/Code/Source/RHI/Device.h
+++ b/Gems/Atom/RHI/Null/Code/Source/RHI/Device.h
@@ -42,6 +42,7 @@ namespace AZ
             void PreShutdown() override {}
             RHI::ResourceMemoryRequirements GetResourceMemoryRequirements([[maybe_unused]] const RHI::ImageDescriptor& descriptor) override { return RHI::ResourceMemoryRequirements();}
             RHI::ResourceMemoryRequirements GetResourceMemoryRequirements([[maybe_unused]] const RHI::BufferDescriptor& descriptor) override { return RHI::ResourceMemoryRequirements();}
+            void ObjectCollectionNotify(RHI::ObjectCollectorNotifyFunction notifyFunction) override;
             //////////////////////////////////////////////////////////////////////////
         };
     }
diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.cpp
index 6d3080dce8..05ff8bb2a6 100644
--- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.cpp
+++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.cpp
@@ -652,6 +652,11 @@ namespace AZ
             return RHI::ResourceMemoryRequirements{ vkRequirements.alignment, vkRequirements.size };
         }
 
+        void Device::ObjectCollectionNotify(RHI::ObjectCollectorNotifyFunction notifyFunction)
+        {
+            m_releaseQueue.Notify(notifyFunction);
+        }
+
         void Device::InitFeaturesAndLimits(const PhysicalDevice& physicalDevice)
         {
             m_features.m_tessellationShader = (m_enabledDeviceFeatures.tessellationShader == VK_TRUE);
diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.h b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.h
index d5f055f4cd..28e56d1fa9 100644
--- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.h
+++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.h
@@ -134,6 +134,7 @@ namespace AZ
             void PreShutdown() override;
             RHI::ResourceMemoryRequirements GetResourceMemoryRequirements(const RHI::ImageDescriptor& descriptor) override;
             RHI::ResourceMemoryRequirements GetResourceMemoryRequirements(const RHI::BufferDescriptor& descriptor) override;
+            void ObjectCollectionNotify(RHI::ObjectCollectorNotifyFunction notifyFunction) override;
             //////////////////////////////////////////////////////////////////////////
 
             void InitFeaturesAndLimits(const PhysicalDevice& physicalDevice);
diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialFunctorSourceDataRegistration.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialFunctorSourceDataRegistration.h
index 8d8700f284..6ec4641fd8 100644
--- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialFunctorSourceDataRegistration.h
+++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialFunctorSourceDataRegistration.h
@@ -9,6 +9,7 @@
 #pragma once
 
 #include 
+#include 
 #include 
 #include 
 #include 
diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystem.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystem.h
index 227fcb41d3..30fa27e64b 100644
--- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystem.h
+++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystem.h
@@ -75,6 +75,12 @@ namespace AZ
             const AZ::Name& GetTargetedPassDebuggingName() const override;
             void ConnectEvent(OnReadyLoadTemplatesEvent::Handler& handler) override;
             PassSystemState GetState() const override;
+            SwapChainPass* FindSwapChainPass(AzFramework::NativeWindowHandle windowHandle) const override;
+
+            // PassSystemInterface statistics related functions
+            void IncrementFrameDrawItemCount(u32 numDrawItems) override;
+            void IncrementFrameRenderPassCount() override;
+            PassSystemFrameStatistics GetFrameStatistics() override;
 
             // PassSystemInterface factory related functions...
             void AddPassCreator(Name className, PassCreator createFunction) override;
@@ -93,7 +99,6 @@ namespace AZ
             void RegisterPass(Pass* pass) override;
             void UnregisterPass(Pass* pass) override;
             AZStd::vector FindPasses(const PassFilter& passFilter) const override;
-            SwapChainPass* FindSwapChainPass(AzFramework::NativeWindowHandle windowHandle) const override;
 
         private:
             // Returns the root of the pass tree hierarchy
@@ -116,6 +121,9 @@ namespace AZ
             void QueueForRemoval(Pass* pass) override;
             void QueueForInitialization(Pass* pass) override;
 
+            // Resets the frame statistic counters
+            void ResetFrameStatistics();
+
             // Lists for queuing passes for various function calls
             // Name of the list reflects the pass function it will call
             AZStd::vector< Ptr > m_buildPassList;
@@ -141,13 +149,16 @@ namespace AZ
             AZ::Name m_targetedPassDebugName;
 
             // Counts the number of passes
-            int32_t m_passCounter = 0;
+            u32 m_passCounter = 0;
 
             // Events
             OnReadyLoadTemplatesEvent m_loadTemplatesEvent;
 
             // Used to track what phase of execution the pass system is in
             PassSystemState m_state = PassSystemState::Unitialized;
+
+            // Counters used to gather statistics about the frame
+            PassSystemFrameStatistics m_frameStatistics;
         };
     }   // namespace RPI
 }   // namespace AZ
diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystemInterface.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystemInterface.h
index 2e51bc7bae..0e9386f3bb 100644
--- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystemInterface.h
+++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystemInterface.h
@@ -67,6 +67,14 @@ namespace AZ
             FrameEnd,
         };
 
+        //! Frame counters used for collecting statistics
+        struct PassSystemFrameStatistics
+        {
+            u32 m_numRenderPassesExecuted = 0;
+            u32 m_totalDrawItemsRendered = 0;
+            u32 m_maxDrawItemsRenderedInAPass = 0;
+        };
+
         class PassSystemInterface
         {
             friend class Pass;
@@ -116,6 +124,27 @@ namespace AZ
             virtual void SetTargetedPassDebuggingName(const AZ::Name& targetPassName) = 0;
             virtual const AZ::Name& GetTargetedPassDebuggingName() const = 0;
 
+            //! Find the SwapChainPass associated with window Handle
+            virtual SwapChainPass* FindSwapChainPass(AzFramework::NativeWindowHandle windowHandle) const = 0;
+
+            using OnReadyLoadTemplatesEvent = AZ::Event<>;
+            //! Connect a handler to listen to the event that the pass system is ready to load pass templates
+            //! The event is triggered when pass system is initialized and asset system is ready.
+            //! The handler can add new pass templates or load pass template mappings from assets
+            virtual void ConnectEvent(OnReadyLoadTemplatesEvent::Handler& handler) = 0;
+
+            virtual PassSystemState GetState() const = 0;
+
+            // Passes call this function to notify the pass system that they are drawing X draw items this frame
+            // Used for Pass System statistics
+            virtual void IncrementFrameDrawItemCount(u32 numDrawItems) = 0;
+
+            // Increments the counter for the number of render passes executed this frame (does not include passes that are disabled) 
+            virtual void IncrementFrameRenderPassCount() = 0;
+
+            // Get frame statistics from the Pass System
+            virtual PassSystemFrameStatistics GetFrameStatistics() = 0;
+
             // --- Pass Factory related functionality ---
 
             //! Directly creates a pass given a PassDescriptor
@@ -172,17 +201,6 @@ namespace AZ
             //! Find matching passes from registered passes with specified filter
             virtual AZStd::vector FindPasses(const PassFilter& passFilter) const = 0;
 
-            //! Find the SwapChainPass associated with window Handle
-            virtual SwapChainPass* FindSwapChainPass(AzFramework::NativeWindowHandle windowHandle) const = 0;
-
-            using OnReadyLoadTemplatesEvent = AZ::Event<>;
-            //! Connect a handler to listen to the event that the pass system is ready to load pass templates
-            //! The event is triggered when pass system is initialized and asset system is ready.
-            //! The handler can add new pass templates or load pass template mappings from assets
-            virtual void ConnectEvent(OnReadyLoadTemplatesEvent::Handler& handler) = 0;
-
-            virtual PassSystemState GetState() const = 0;
-
         private:
             // These functions are only meant to be used by the Pass class
 
@@ -200,7 +218,6 @@ namespace AZ
 
             //! Unregisters the pass with the pass library. Called in the Pass destructor.
             virtual void UnregisterPass(Pass* pass) = 0;
-
         };
                 
         namespace PassSystemEvents
diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/RasterPass.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/RasterPass.h
index 847fe36bd0..2c884ceedf 100644
--- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/RasterPass.h
+++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/RasterPass.h
@@ -38,11 +38,13 @@ namespace AZ
 
             void SetDrawListTag(Name drawListName);
 
-            void SetPipelineStateDataIndex(u32 index);
+            void SetPipelineStateDataIndex(uint32_t index);
 
             //! Expose shader resource group.
             ShaderResourceGroup* GetShaderResourceGroup();
 
+            uint32_t GetDrawItemCount();
+
         protected:
             explicit RasterPass(const PassDescriptor& descriptor);
 
@@ -76,6 +78,7 @@ namespace AZ
             RHI::Viewport m_viewportState;
             bool m_overrideScissorSate = false;
             bool m_overrideViewportState = false;
+            uint32_t m_drawItemCount = 0;
         };
     }   // namespace RPI
 }   // namespace AZ
diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MorphTargetExporter.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MorphTargetExporter.cpp
index 0a1fb49ab5..fa437c002f 100644
--- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MorphTargetExporter.cpp
+++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MorphTargetExporter.cpp
@@ -159,9 +159,14 @@ namespace AZ::RPI
 
         // Determine the vertex index range for the morph target.
         const uint32_t numVertices = blendShapeData->GetVertexCount();
-        AZ_Assert(blendShapeData->GetVertexCount() == sourceMesh.m_meshData->GetVertexCount(),
-            "Blend shape (%s) contains more/less vertices (%d) than the neutral mesh (%d).",
-            blendShapeName.c_str(), numVertices, sourceMesh.m_meshData->GetVertexCount());
+        if (blendShapeData->GetVertexCount() != sourceMesh.m_meshData->GetVertexCount())
+        {
+            AZ_Error(ModelAssetBuilderComponent::s_builderName, false,
+                "Skipping blend shape (%s) as it contains more/less vertices (%d) than the neutral mesh (%d). "
+                "The blend shape is most likely influencing multiple meshes, which is currently not supported.",
+                blendShapeName.c_str(), numVertices, sourceMesh.m_meshData->GetVertexCount());
+            return;
+        }
 
         // The start index is after any previously added deltas
         metaData.m_startIndex = aznumeric_cast(packedCompressedMorphTargetVertexData.size());
diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp
index 27e3612a4c..d73521763f 100644
--- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp
+++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp
@@ -310,6 +310,7 @@ namespace AZ
             AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzRender);
             AZ_ATOM_PROFILE_FUNCTION("RPI", "PassSystem: FrameUpdate");
 
+            ResetFrameStatistics();
             ProcessQueuedChanges();
 
             m_state = PassSystemState::Rendering;
@@ -398,6 +399,29 @@ namespace AZ
             handler.Connect(m_loadTemplatesEvent);
         }
 
+        void PassSystem::ResetFrameStatistics()
+        {
+            m_frameStatistics.m_numRenderPassesExecuted = 0;
+            m_frameStatistics.m_totalDrawItemsRendered = 0;
+            m_frameStatistics.m_maxDrawItemsRenderedInAPass = 0;
+        }
+
+        PassSystemFrameStatistics PassSystem::GetFrameStatistics()
+        {
+            return m_frameStatistics;
+        }
+
+        void PassSystem::IncrementFrameDrawItemCount(u32 numDrawItems)
+        {
+            m_frameStatistics.m_totalDrawItemsRendered += numDrawItems;
+            m_frameStatistics.m_maxDrawItemsRenderedInAPass = AZStd::max(m_frameStatistics.m_maxDrawItemsRenderedInAPass, numDrawItems);
+        }
+
+        void PassSystem::IncrementFrameRenderPassCount()
+        {
+            ++m_frameStatistics.m_numRenderPassesExecuted;
+        }
+
         // --- Pass Factory Functions --- 
 
         void PassSystem::AddPassCreator(Name className, PassCreator createFunction)
diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RasterPass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RasterPass.cpp
index 8890499cb7..ce02e1c570 100644
--- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RasterPass.cpp
+++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RasterPass.cpp
@@ -104,7 +104,7 @@ namespace AZ
             m_flags.m_hasDrawListTag = true;
         }
 
-        void RasterPass::SetPipelineStateDataIndex(u32 index)
+        void RasterPass::SetPipelineStateDataIndex(uint32_t index)
         {
             m_pipelineStateDataIndex.m_index = index;
         }
@@ -114,6 +114,11 @@ namespace AZ
             return m_shaderResourceGroup.get();
         }
 
+        uint32_t RasterPass::GetDrawItemCount()
+        {
+            return m_drawItemCount;
+        }
+
         // --- Pass behaviour overrides ---
 
         void RasterPass::Validate(PassValidationResults& validationResults)
@@ -154,17 +159,21 @@ namespace AZ
                 // Assert the view has our draw list (the view's DrawlistTags are collected from passes using its viewTag)
                 AZ_Assert(view->HasDrawListTag(m_drawListTag), "View's DrawListTags out of sync with pass'. ");
 
+                // Draw List 
                 viewDrawList = view->GetDrawList(m_drawListTag);
             }
 
             // clean up data
             m_drawListView = {};
             m_combinedDrawList.clear();
+            m_drawItemCount = 0;
 
             // draw list from view was sorted and if it's the only draw list then we can use it directly
             if (viewDrawList.size() > 0 && drawLists.size() == 0)
             {
                 m_drawListView = viewDrawList;
+                m_drawItemCount += static_cast(viewDrawList.size());
+                PassSystemInterface::Get()->IncrementFrameDrawItemCount(m_drawItemCount);
                 return;
             }
 
@@ -172,12 +181,12 @@ namespace AZ
             drawLists.push_back(viewDrawList);
 
             // combine draw items from mutiple draw lists to one draw list and sort it.
-            size_t itemCount = 0;
             for (auto drawList : drawLists)
             {
-                itemCount += drawList.size();
+                m_drawItemCount += static_cast(drawList.size());
             }
-            m_combinedDrawList.resize(itemCount);
+            PassSystemInterface::Get()->IncrementFrameDrawItemCount(m_drawItemCount);
+            m_combinedDrawList.resize(m_drawItemCount);
             RHI::DrawItemProperties* currentBuffer = m_combinedDrawList.data();
             for (auto drawList : drawLists)
             {
@@ -202,7 +211,7 @@ namespace AZ
         void RasterPass::SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph)
         {
             RenderPass::SetupFrameGraphDependencies(frameGraph);
-            frameGraph.SetEstimatedItemCount(static_cast(m_drawListView.size()));
+            frameGraph.SetEstimatedItemCount(static_cast(m_drawListView.size()));
         }
 
         void RasterPass::CompileResources(const RHI::FrameGraphCompileContext& context)
diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp
index 913f83254e..9b182a3c4b 100644
--- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp
+++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp
@@ -201,6 +201,8 @@ namespace AZ
                 m_attachmentCopy.lock()->FrameBegin(params);
             }
             CollectSrgs();
+
+            PassSystemInterface::Get()->IncrementFrameRenderPassCount();
         }
 
 
diff --git a/Gems/Atom/RPI/Code/Tests/Common/RHI/Stubs.h b/Gems/Atom/RPI/Code/Tests/Common/RHI/Stubs.h
index 1de06802b1..be362c60d6 100644
--- a/Gems/Atom/RPI/Code/Tests/Common/RHI/Stubs.h
+++ b/Gems/Atom/RPI/Code/Tests/Common/RHI/Stubs.h
@@ -70,6 +70,7 @@ namespace UnitTest
             void PreShutdown() override {}
             AZ::RHI::ResourceMemoryRequirements GetResourceMemoryRequirements([[maybe_unused]] const AZ::RHI::ImageDescriptor& descriptor) { return AZ::RHI::ResourceMemoryRequirements{}; };
             AZ::RHI::ResourceMemoryRequirements GetResourceMemoryRequirements([[maybe_unused]] const AZ::RHI::BufferDescriptor& descriptor) { return AZ::RHI::ResourceMemoryRequirements{}; };
+            void ObjectCollectionNotify(AZ::RHI::ObjectCollectorNotifyFunction notifyFunction) override {}
         };
 
         class ImageView
diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/AtomFont.h b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/AtomFont.h
index 7dd2629bd0..7636b45060 100644
--- a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/AtomFont.h
+++ b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/AtomFont.h
@@ -82,7 +82,7 @@ namespace AZ
         FontFamilyPtr GetFontFamily(const char* fontFamilyName) override;
         void AddCharsToFontTextures(FontFamilyPtr fontFamily, const char* chars, int glyphSizeX = ICryFont::defaultGlyphSizeX, int glyphSizeY = ICryFont::defaultGlyphSizeY) override;
         void GetMemoryUsage([[maybe_unused]] ICrySizer* sizer) const override {}
-        string GetLoadedFontNames() const;
+        AZStd::string GetLoadedFontNames() const;
         void OnLanguageChanged() override;
         void ReloadAllFonts() override;
         //////////////////////////////////////////////////////////////////////////////////
@@ -124,7 +124,7 @@ namespace AZ
         //! \param fontFamilyName The name of the font family, or path to a font family file.
         //! \param outputDirectory Path to loaded font family (no filename), may need resolving with PathUtil::MakeGamePath.
         //! \param outputFullPath Full path to loaded font family, may need resolving with PathUtil::MakeGamePath.
-        XmlNodeRef LoadFontFamilyXml(const char* fontFamilyName, string& outputDirectory, string& outputFullPath);
+        XmlNodeRef LoadFontFamilyXml(const char* fontFamilyName, AZStd::string& outputDirectory, AZStd::string& outputFullPath);
 
         // Data::AssetBus::Handler overrides...
         void OnAssetReady(Data::Asset asset) override;
diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/AtomNullFont.h b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/AtomNullFont.h
index ebbdaf09d0..4820d1c176 100644
--- a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/AtomNullFont.h
+++ b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/AtomNullFont.h
@@ -42,7 +42,7 @@ namespace AZ
 
         size_t GetTextLength([[maybe_unused]] const char* str, [[maybe_unused]] const bool asciiMultiLine) const override { return 0; }
 
-        void WrapText(string& result, [[maybe_unused]] float maxWidth, const char* str, [[maybe_unused]] const TextDrawContext& ctx) override { result = str; }
+        void WrapText(AZStd::string& result, [[maybe_unused]] float maxWidth, const char* str, [[maybe_unused]] const TextDrawContext& ctx) override { result = str; }
 
         void GetMemoryUsage([[maybe_unused]] ICrySizer* sizer) const override {}
 
@@ -76,7 +76,7 @@ namespace AZ
         virtual FontFamilyPtr GetFontFamily([[maybe_unused]] const char* fontFamilyName) override { CRY_ASSERT(false); return nullptr; }
         virtual void AddCharsToFontTextures([[maybe_unused]] FontFamilyPtr fontFamily, [[maybe_unused]] const char* chars, [[maybe_unused]] int glyphSizeX, [[maybe_unused]] int glyphSizeY) override {};
         virtual void GetMemoryUsage([[maybe_unused]] ICrySizer* sizer) const override {}
-        virtual string GetLoadedFontNames() const override { return ""; }
+        virtual AZStd::string GetLoadedFontNames() const override { return ""; }
         virtual void OnLanguageChanged() override { }
         virtual void ReloadAllFonts() override { } 
 
diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FBitmap.h b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FBitmap.h
index 0e97440538..6443633245 100644
--- a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FBitmap.h
+++ b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FBitmap.h
@@ -26,7 +26,7 @@ namespace AZ
         int Create(int width, int height);
         int Release();
 
-        int SaveBitmap(const string& fileName);
+        int SaveBitmap(const AZStd::string& fileName);
         int Get32Bpp(unsigned int** buffer)
         {
             (*buffer) = new unsigned int[m_width * m_height];
diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FFont.h b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FFont.h
index 795c823fd6..6f56d912a0 100644
--- a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FFont.h
+++ b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FFont.h
@@ -18,7 +18,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include "AtomFont.h"
@@ -123,7 +122,7 @@ namespace AZ
 
         struct FontEffect
         {
-            string m_name;
+            AZStd::string m_name;
             std::vector m_passes;
 
             FontEffect(const char* name)
@@ -179,7 +178,7 @@ namespace AZ
         void DrawString(float x, float y, float z, const char* str, const bool asciiMultiLine, const TextDrawContext& ctx) override;
         Vec2 GetTextSize(const char* str, const bool asciiMultiLine, const TextDrawContext& ctx) override;
         size_t GetTextLength(const char* str, const bool asciiMultiLine) const override;
-        void WrapText(string& result, float maxWidth, const char* str, const TextDrawContext& ctx) override;
+        void WrapText(AZStd::string& result, float maxWidth, const char* str, const TextDrawContext& ctx) override;
         void GetMemoryUsage([[maybe_unused]] ICrySizer* sizer) const override {};
         void GetGradientTextureCoord(float& minU, float& minV, float& maxU, float& maxV) const override;
         unsigned int GetEffectId(const char* effectName) const override;
@@ -216,7 +215,7 @@ namespace AZ
         FFont(AtomFont* atomFont, const char* fontName);
 
         FontTexture* GetFontTexture() const { return m_fontTexture; }
-        const string& GetName() const { return m_name; }
+        const AZStd::string& GetName() const { return m_name; }
 
         FontEffect* AddEffect(const char* effectName);
         FontEffect* GetDefaultEffect();
@@ -292,8 +291,8 @@ namespace AZ
         static constexpr uint32_t NumBuffers = 2;
         static constexpr float WindowScaleWidth = 800.0f;
         static constexpr float WindowScaleHeight = 600.0f;
-        string m_name;
-        string m_curPath;
+        AZStd::string m_name;
+        AZStd::string m_curPath;
 
         AZ::Name m_dynamicDrawContextName = AZ::Name(AZ::AtomFontDynamicDrawContextName);
 
@@ -342,7 +341,7 @@ namespace AZ
         FFont* font = const_cast(static_cast(ptr));
         if (font && font->m_atomFont)
         {
-            font->m_atomFont->UnregisterFont(font->m_name);
+            font->m_atomFont->UnregisterFont(font->m_name.c_str());
             font->m_atomFont = nullptr;
         }
 
diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FontRenderer.h b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FontRenderer.h
index 9f95c12180..3cfb900055 100644
--- a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FontRenderer.h
+++ b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FontRenderer.h
@@ -60,7 +60,7 @@ namespace AZ
         FontRenderer();
         ~FontRenderer();
 
-        int         LoadFromFile(const string& fileName);
+        int         LoadFromFile(const AZStd::string& fileName);
         int         LoadFromMemory(unsigned char* buffer, int bufferSize);
         int         Release();
 
diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FontTexture.h b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FontTexture.h
index 91fecfa3ef..b9bdce6810 100644
--- a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FontTexture.h
+++ b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FontTexture.h
@@ -74,7 +74,7 @@ namespace AZ
         FontTexture();
         ~FontTexture();
 
-        int CreateFromFile(const string& fileName, int width, int height, AZ::FontSmoothMethod smoothMethod, AZ::FontSmoothAmount smoothAmount, int widthCharCount = 16, int heightCharCount = 16);
+        int CreateFromFile(const AZStd::string& fileName, int width, int height, AZ::FontSmoothMethod smoothMethod, AZ::FontSmoothAmount smoothAmount, int widthCharCount = 16, int heightCharCount = 16);
 
         //! Default texture slot width/height is 16x8 slots, allowing for 128 glyphs to be stored in the font texture. This was
         //! previously 16x16, allowing 256 glyphs to be stored. For reference, there are 95 printable ASCII characters, so by
@@ -129,7 +129,7 @@ namespace AZ
         // useful for special feature rendering interleaved with fonts (e.g. box behind the text)
         void CreateGradientSlot();
 
-        int WriteToFile(const string& fileName);
+        int WriteToFile(const AZStd::string& fileName);
 
         void GetMemoryUsage([[maybe_unused]] ICrySizer* sizer) const {}
 
diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/GlyphCache.h b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/GlyphCache.h
index cd37cb6b79..8c6cf721b3 100644
--- a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/GlyphCache.h
+++ b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/GlyphCache.h
@@ -79,7 +79,7 @@ namespace AZ
         int Create(int iCacheSize, int glyphBitmapWidth, int glyphBitmapHeight, FontSmoothMethod smoothMethod, FontSmoothAmount smoothAmount, float sizeRatio);
         int Release();
 
-        int LoadFontFromFile(const string& fileName);
+        int LoadFontFromFile(const AZStd::string& fileName);
         int LoadFontFromMemory(unsigned char* fileBuffer, int dataSize);
         int ReleaseFont();
 
diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Platform/Common/FontTexture_Common.cpp b/Gems/AtomLyIntegration/AtomFont/Code/Platform/Common/FontTexture_Common.cpp
index 02cbb5a7a4..e3be52965c 100644
--- a/Gems/AtomLyIntegration/AtomFont/Code/Platform/Common/FontTexture_Common.cpp
+++ b/Gems/AtomLyIntegration/AtomFont/Code/Platform/Common/FontTexture_Common.cpp
@@ -11,7 +11,7 @@
 #include 
 
 //-------------------------------------------------------------------------------------------------
-int AZ::FontTexture::WriteToFile([[maybe_unused]] const string& fileName)
+int AZ::FontTexture::WriteToFile([[maybe_unused]] const AZStd::string& fileName)
 {
     return 1;
 }
diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Platform/Windows/FFontXML_Windows.cpp b/Gems/AtomLyIntegration/AtomFont/Code/Platform/Windows/FFontXML_Windows.cpp
index 9aaaf2ffeb..dc7c6ccbb2 100644
--- a/Gems/AtomLyIntegration/AtomFont/Code/Platform/Windows/FFontXML_Windows.cpp
+++ b/Gems/AtomLyIntegration/AtomFont/Code/Platform/Windows/FFontXML_Windows.cpp
@@ -8,22 +8,25 @@
 
 #include 
 
+#include 
+#include 
+
 #include 
 
 namespace AtomFontInternal
 {
     void XmlFontShader::FoundElementImpl()
     {
-        TCHAR sysFontPath[MAX_PATH];
-        if (SUCCEEDED(SHGetFolderPath(0, CSIDL_FONTS, 0, SHGFP_TYPE_DEFAULT, sysFontPath)))
+        wchar_t sysFontPathW[MAX_PATH];
+        if (SUCCEEDED(SHGetFolderPath(0, CSIDL_FONTS, 0, SHGFP_TYPE_DEFAULT, sysFontPathW)))
         {
-            const char* fontPath = m_strFontPath.c_str();
-            const char* fontName = CryStringUtils::FindFileNameInPath(fontPath);
+            const AZ::IO::PathView fontName = AZ::IO::PathView(m_strFontPath.c_str()).Filename();
 
-            string newFontPath(sysFontPath);
-            newFontPath += "/";
-            newFontPath += fontName;
-            m_font->Load(newFontPath, m_FontTexSize.x, m_FontTexSize.y, m_slotSizes.x, m_slotSizes.y, CreateTTFFontFlag(m_FontSmoothMethod, m_FontSmoothAmount), m_SizeRatio);
+            AZStd::string sysFontPath;
+            AZStd::to_string(sysFontPath, sysFontPathW);
+            AZ::IO::Path newFontPath(sysFontPath);
+            newFontPath /= fontName;
+            m_font->Load(newFontPath.c_str(), m_FontTexSize.x, m_FontTexSize.y, m_slotSizes.x, m_slotSizes.y, CreateTTFFontFlag(m_FontSmoothMethod, m_FontSmoothAmount), m_SizeRatio);
         }
     }
 }
diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Platform/Windows/FontTexture_Windows.cpp b/Gems/AtomLyIntegration/AtomFont/Code/Platform/Windows/FontTexture_Windows.cpp
index 5aae754a7d..33950689f5 100644
--- a/Gems/AtomLyIntegration/AtomFont/Code/Platform/Windows/FontTexture_Windows.cpp
+++ b/Gems/AtomLyIntegration/AtomFont/Code/Platform/Windows/FontTexture_Windows.cpp
@@ -11,7 +11,7 @@
 #include 
 
 //-------------------------------------------------------------------------------------------------
-int AZ::FontTexture::WriteToFile(const string& fileName)
+int AZ::FontTexture::WriteToFile(const AZStd::string& fileName)
 {
     AZ::IO::FileIOStream outputFile(fileName.c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary);
 
diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Source/AtomFont.cpp b/Gems/AtomLyIntegration/AtomFont/Code/Source/AtomFont.cpp
index 35c2b26b48..ecf0789220 100644
--- a/Gems/AtomLyIntegration/AtomFont/Code/Source/AtomFont.cpp
+++ b/Gems/AtomLyIntegration/AtomFont/Code/Source/AtomFont.cpp
@@ -46,7 +46,7 @@ static void DumfontTexture(IConsoleCmdArgs* cmdArgs)
 
     if (fontName && *fontName && *fontName != '0')
     {
-        string fontFilePath("@devroot@/");
+        AZStd::string fontFilePath("@devroot@/");
         fontFilePath += fontName;
         fontFilePath += ".bmp";
 
@@ -61,7 +61,7 @@ static void DumfontTexture(IConsoleCmdArgs* cmdArgs)
 
 static void DumfontNames([[maybe_unused]] IConsoleCmdArgs* cmdArgs)
 {
-    string names = gEnv->pCryFont->GetLoadedFontNames();
+    AZStd::string names = gEnv->pCryFont->GetLoadedFontNames();
     gEnv->pLog->LogWithType(IMiniLog::eInputResponse, "Currently loaded fonts: %s", names.c_str());
 }
 
@@ -97,15 +97,15 @@ namespace
                 && !m_boldItalicFontFilename.empty();
         }
 
-        string m_lang;                      //!< Stores a comma-separated list of languages this collection of fonts applies to.
+        AZStd::string m_lang;               //!< Stores a comma-separated list of languages this collection of fonts applies to.
                                             //!< If this is an empty string, it implies that these set of fonts will be applied
                                             //!< by default (when a language is being used but no fonts in the font family are
                                             //!< mapped to that language).
 
-        string m_fontFilename;              //!< Font used when no styling is applied.
-        string m_boldFontFilename;          //!< Bold-styled font
-        string m_italicFontFilename;        //!< Italic-styled font
-        string m_boldItalicFontFilename;    //!< Bold-italic-styled font
+        AZStd::string m_fontFilename;              //!< Font used when no styling is applied.
+        AZStd::string m_boldFontFilename;          //!< Bold-styled font
+        AZStd::string m_italicFontFilename;        //!< Italic-styled font
+        AZStd::string m_boldItalicFontFilename;    //!< Bold-italic-styled font
     };
 
     //! Stores parsed font family XML data.
@@ -152,7 +152,7 @@ namespace
             return !m_fontFamilyName.empty();
         }
 
-        string m_fontFamilyName;                  //!< Value of the "name" font-family tag attribute
+        AZStd::string m_fontFamilyName;                  //!< Value of the "name" font-family tag attribute
         AZStd::list m_fontTagsXml;    //!< List of child  tag data.
     };
 
@@ -179,7 +179,7 @@ namespace
                 return false;
             }
 
-            string name;
+            AZStd::string name;
 
             for (int i = 0, count = node->getNumAttributes(); i < count; ++i)
             {
@@ -187,7 +187,7 @@ namespace
                 const char* value = "";
                 if (node->getAttributeByIndex(i, &key, &value))
                 {
-                    if (string(key) == "name")
+                    if (AZStd::string(key) == "name")
                     {
                         name = value;
                     }
@@ -199,7 +199,7 @@ namespace
                 }
             }
 
-            name.Trim();
+            AZ::StringFunc::TrimWhiteSpace(name, true, true);
             if (!name.empty())
             {
                 xmlData.m_fontFamilyName = name;
@@ -216,14 +216,14 @@ namespace
         {
             xmlData.m_fontTagsXml.push_back(FontTagXml());
 
-            string lang;
+            AZStd::string lang;
             for (int i = 0, count = node->getNumAttributes(); i < count; ++i)
             {
                 const char* key = "";
                 const char* value = "";
                 if (node->getAttributeByIndex(i, &key, &value))
                 {
-                    if (string(key) == "lang")
+                    if (AZStd::string(key) == "lang")
                     {
                         lang = value;
                     }
@@ -235,7 +235,7 @@ namespace
                 }
             }
 
-            lang.Trim();
+            AZ::StringFunc::TrimWhiteSpace(lang, true, true);
             if (!lang.empty())
             {
                 xmlData.m_fontTagsXml.back().m_lang = lang;
@@ -253,8 +253,8 @@ namespace
                 return false;
             }
 
-            string path;
-            string tags;
+            AZStd::string path;
+            AZStd::string tags;
 
             for (int i = 0, count = node->getNumAttributes(); i < count; ++i)
             {
@@ -262,11 +262,11 @@ namespace
                 const char* value = "";
                 if (node->getAttributeByIndex(i, &key, &value))
                 {
-                    if (string(key) == "path")
+                    if (AZStd::string(key) == "path")
                     {
                         path = value;
                     }
-                    else if (string(key) == "tags")
+                    else if (AZStd::string(key) == "tags")
                     {
                         tags = value;
                     }
@@ -278,7 +278,7 @@ namespace
                 }
             }
 
-            tags.Trim();
+            AZ::StringFunc::TrimWhiteSpace(tags, true, true);
             if (tags.empty())
             {
                 xmlData.m_fontTagsXml.back().m_fontFilename = path;
@@ -315,7 +315,7 @@ namespace
     //! when referencing font family names from font family XML files), and
     //! attempting to load the XML files directly via ISystem() methods can
     //! produce a lot of warning noise.
-    XmlNodeRef SafeLoadXmlFromFile(const string& xmlPath)
+    XmlNodeRef SafeLoadXmlFromFile(const AZStd::string& xmlPath)
     {
         if (gEnv->pCryPak->IsFileExist(xmlPath.c_str()))
         {
@@ -383,8 +383,8 @@ void AZ::AtomFont::Release()
 
 IFFont* AZ::AtomFont::NewFont(const char* fontName)
 {
-    string name = fontName;
-    name.MakeLower();
+    AZStd::string name = fontName;
+    AZStd::to_lower(name.begin(), name.end());
     AzFramework::FontId fontId = GetFontId(name.c_str());
 
     FontMapItor it = m_fonts.find(fontId);
@@ -404,7 +404,9 @@ IFFont* AZ::AtomFont::NewFont(const char* fontName)
 
 IFFont* AZ::AtomFont::GetFont(const char* fontName) const
 {
-    AzFramework::FontId fontId = GetFontId(string(fontName).MakeLower().c_str());
+    AZStd::string name = fontName;
+    AZStd::to_lower(name.begin(), name.end());
+    AzFramework::FontId fontId = GetFontId(name.c_str());
     FontMapConstItor it = m_fonts.find(fontId);
     return it != m_fonts.end() ? it->second : 0;
 }
@@ -423,8 +425,8 @@ AzFramework::FontDrawInterface* AZ::AtomFont::GetDefaultFontDrawInterface() cons
 FontFamilyPtr AZ::AtomFont::LoadFontFamily(const char* fontFamilyName)
 {
     FontFamilyPtr fontFamily(nullptr);
-    string fontFamilyPath;
-    string fontFamilyFullPath;
+    AZStd::string fontFamilyPath;
+    AZStd::string fontFamilyFullPath;
     
     XmlNodeRef root = LoadFontFamilyXml(fontFamilyName, fontFamilyPath, fontFamilyFullPath);
 
@@ -450,13 +452,13 @@ FontFamilyPtr AZ::AtomFont::LoadFontFamily(const char* fontFamilyName)
                 }
                 else
                 {
-                    int searchPos = 0;
-                    string langToken;
-
                     // "lang" font-tag attribute could be comma-separated
-                    while (!(langToken = fontTagXml.m_lang.Tokenize(",", searchPos)).empty())
+                    AZStd::vector tokens;
+                    AZ::StringFunc::Tokenize(fontTagXml.m_lang, tokens, ',');
+                    for(AZStd::string& langToken : tokens)
                     {
-                        if (langToken.Trim() == currentLanguage)
+                        AZ::StringFunc::TrimWhiteSpace(langToken, true, true);
+                        if (langToken == currentLanguage)
                         {
                             langSpecificFont = &fontTagXml;
                             break;
@@ -494,7 +496,7 @@ FontFamilyPtr AZ::AtomFont::LoadFontFamily(const char* fontFamilyName)
                     // Map the font family name both by path and by name defined
                     // within the Font Family XML itself. This allows font 
                     // families to also be referenced simply by name.
-                    if (!AddFontFamilyToMaps(fontFamilyFullPath, xmlData.m_fontFamilyName, fontFamily))
+                    if (!AddFontFamilyToMaps(fontFamilyFullPath.c_str(), xmlData.m_fontFamilyName.c_str(), fontFamily))
                     {
                         SAFE_RELEASE(normal);
                         SAFE_RELEASE(bold);
@@ -540,7 +542,7 @@ FontFamilyPtr AZ::AtomFont::LoadFontFamily(const char* fontFamilyName)
             // Use filepath as familyName so font loading/unloading doesn't break with duplicate file names
             fontFamily->familyName = fontFamilyName;
 
-            if (!AddFontFamilyToMaps(fontFamilyName, fontFamily->familyName, fontFamily))
+            if (!AddFontFamilyToMaps(fontFamilyName, fontFamily->familyName.c_str(), fontFamily))
             {
                 SAFE_RELEASE(font);
 
@@ -581,7 +583,9 @@ FontFamilyPtr AZ::AtomFont::GetFontFamily(const char* fontFamilyName)
     // or just the filename of a font itself. Fonts are mapped by font family
     // name or by filepath, so attempt lookup using the map first since it's
     // the fastest.
-    string loweredName = string(fontFamilyName).Trim().MakeLower();
+    AZStd::string loweredName = AZStd::string(fontFamilyName);
+    AZ::StringFunc::TrimWhiteSpace(loweredName, true, true);
+    AZStd::to_lower(loweredName.begin(), loweredName.end());
     auto it = m_fontFamilies.find(PathUtil::MakeGamePath(loweredName).c_str());
     if (it != m_fontFamilies.end())
     {
@@ -596,9 +600,9 @@ FontFamilyPtr AZ::AtomFont::GetFontFamily(const char* fontFamilyName)
         for (const auto& fontFamilyIter : m_fontFamilies)
         {
             const AZStd::string& mappedFontFamilyName = fontFamilyIter.first;
-            string mappedFilenameNoExtension = PathUtil::GetFileName(mappedFontFamilyName.c_str());
+            AZStd::string mappedFilenameNoExtension = PathUtil::GetFileName(mappedFontFamilyName.c_str());
 
-            string searchStringFilenameNoExtension = PathUtil::GetFileName(loweredName);
+            AZStd::string searchStringFilenameNoExtension = PathUtil::GetFileName(loweredName);
 
             if (mappedFilenameNoExtension == searchStringFilenameNoExtension)
             {
@@ -619,9 +623,9 @@ void AZ::AtomFont::AddCharsToFontTextures(FontFamilyPtr fontFamily, const char*
     fontFamily->boldItalic->AddCharsToFontTexture(chars, glyphSizeX, glyphSizeY);
 }
 
-string AZ::AtomFont::GetLoadedFontNames() const
+AZStd::string AZ::AtomFont::GetLoadedFontNames() const
 {
-    string ret;
+    AZStd::string ret;
     for (FontMapConstItor it = m_fonts.begin(), itEnd = m_fonts.end(); it != itEnd; ++it)
     {
         FFont* font = it->second;
@@ -678,7 +682,9 @@ void AZ::AtomFont::ReloadAllFonts()
 
 void AZ::AtomFont::UnregisterFont(const char* fontName)
 {
-    AzFramework::FontId fontId = GetFontId(string(fontName).MakeLower().c_str());
+    AZStd::string name(fontName);
+    AZStd::to_lower(name.begin(), name.end());
+    AzFramework::FontId fontId = GetFontId(name.c_str());
     FontMapItor it = m_fonts.find(fontId);
 
 #if defined(AZ_ENABLE_TRACING)
@@ -715,10 +721,10 @@ void AZ::AtomFont::UnregisterFont(const char* fontName)
 
 IFFont* AZ::AtomFont::LoadFont(const char* fontName)
 {
-    string fontNameLower = fontName;
-    fontNameLower.MakeLower();
+    AZStd::string fontNameLower = fontName;
+    AZStd::to_lower(fontNameLower.begin(), fontNameLower.end());
 
-    IFFont* font = GetFont(fontNameLower);
+    IFFont* font = GetFont(fontNameLower.c_str());
     if (font)
     {
         font->AddRef(); // use existing loaded font
@@ -726,10 +732,10 @@ IFFont* AZ::AtomFont::LoadFont(const char* fontName)
     else
     {
         // attempt to create and load a new font, use the font pathname as the font name
-        font = NewFont(fontNameLower);
+        font = NewFont(fontNameLower.c_str());
         if (!font)
         {
-            string errorMsg = "Error creating a new font named ";
+            AZStd::string errorMsg = "Error creating a new font named ";
             errorMsg += fontNameLower;
             errorMsg += ".";
             CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, errorMsg.c_str());
@@ -737,12 +743,12 @@ IFFont* AZ::AtomFont::LoadFont(const char* fontName)
         else
         {
             // creating font adds one to its refcount so no need for AddRef here
-            if (!font->Load(fontNameLower))
+            if (!font->Load(fontNameLower.c_str()))
             {
-                string errorMsg = "Error loading a font from ";
+                AZStd::string errorMsg = "Error loading a font from ";
                 errorMsg += fontNameLower;
                 errorMsg += ".";
-                CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, errorMsg);
+                CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, errorMsg.c_str());
                 font->Release();
                 font = nullptr;
             }
@@ -764,8 +770,9 @@ void AZ::AtomFont::ReleaseFontFamily(FontFamily* fontFamily)
     // Note that the FontFamily is mapped both by filename and by "family name"
     auto it = m_fontFamilyReverseLookup[fontFamily];
     m_fontFamilies.erase(it);
-    string familyName(fontFamily->familyName);
-    m_fontFamilies.erase(familyName.MakeLower().c_str());
+    AZStd::string familyName(fontFamily->familyName);
+    AZStd::to_lower(familyName.begin(), familyName.end());
+    m_fontFamilies.erase(familyName.c_str());
 
     // Reverse lookup is used to avoid needing to store filename path with
     // the font family, so we need to remove that entry also.
@@ -785,12 +792,11 @@ bool AZ::AtomFont::AddFontFamilyToMaps(const char* fontFamilyFilename, const cha
     }
 
     // We don't support "updating" mapped values. 
-    AZStd::string loweredFilename(PathUtil::MakeGamePath(string(fontFamilyFilename)).c_str());
+    AZStd::string loweredFilename(PathUtil::MakeGamePath(AZStd::string(fontFamilyFilename)).c_str());
     AZStd::to_lower(loweredFilename.begin(), loweredFilename.end());
     if (m_fontFamilies.find(loweredFilename) != m_fontFamilies.end())
     {
-        string warnMsg;
-        warnMsg.Format("Couldn't load Font Family '%s': already loaded", fontFamilyFilename);
+        AZStd::string warnMsg = AZStd::string::format("Couldn't load Font Family '%s': already loaded", fontFamilyFilename);
         CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, warnMsg.c_str());
         return false;
     }
@@ -801,8 +807,7 @@ bool AZ::AtomFont::AddFontFamilyToMaps(const char* fontFamilyFilename, const cha
     AZStd::to_lower(loweredFontFamilyName.begin(), loweredFontFamilyName.end());
     if (m_fontFamilies.find(loweredFontFamilyName) != m_fontFamilies.end())
     {
-        string warnMsg;
-        warnMsg.Format("Couldn't load Font Family '%s': already loaded", fontFamilyName);
+        AZStd::string warnMsg = AZStd::string::format("Couldn't load Font Family '%s': already loaded", fontFamilyName);
         CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, warnMsg.c_str());
         return false;
     }
@@ -819,7 +824,7 @@ bool AZ::AtomFont::AddFontFamilyToMaps(const char* fontFamilyFilename, const cha
     return true;
 }
 
-XmlNodeRef AZ::AtomFont::LoadFontFamilyXml(const char* fontFamilyName, string& outputDirectory, string& outputFullPath)
+XmlNodeRef AZ::AtomFont::LoadFontFamilyXml(const char* fontFamilyName, AZStd::string& outputDirectory, AZStd::string& outputFullPath)
 {
     outputFullPath = fontFamilyName;
     outputDirectory = PathUtil::GetPath(fontFamilyName);
@@ -829,8 +834,8 @@ XmlNodeRef AZ::AtomFont::LoadFontFamilyXml(const char* fontFamilyName, string& o
     // not a path, so we try to build a "best guess" path from the name.
     if (!root)
     {
-        string fileNoExtension(PathUtil::GetFileName(fontFamilyName));
-        string fileExtension(PathUtil::GetExt(fontFamilyName));
+        AZStd::string fileNoExtension(PathUtil::GetFileName(fontFamilyName));
+        AZStd::string fileExtension(PathUtil::GetExt(fontFamilyName));
 
         if (fileExtension.empty())
         {
@@ -838,14 +843,14 @@ XmlNodeRef AZ::AtomFont::LoadFontFamilyXml(const char* fontFamilyName, string& o
         }
 
         // Try: "fonts/fontName.fontfamily"
-        outputDirectory = string("fonts/");
+        outputDirectory = AZStd::string("fonts/");
         outputFullPath = outputDirectory + fileNoExtension + fileExtension;
         root = SafeLoadXmlFromFile(outputFullPath);
 
         // Finally, try: "fonts/fontName/fontName.fontfamily"
         if (!root)
         {
-            outputDirectory = string("fonts/") + fileNoExtension + "/";
+            outputDirectory = AZStd::string("fonts/") + fileNoExtension + "/";
             outputFullPath = outputDirectory + fileNoExtension + fileExtension;
             root = SafeLoadXmlFromFile(outputFullPath);
         }
diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp b/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp
index 421a757b04..9317cae846 100644
--- a/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp
+++ b/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp
@@ -13,6 +13,8 @@
 
 #if !defined(USE_NULLFONT_ALWAYS)
 
+#include 
+
 #include 
 #include 
 #include 
@@ -26,7 +28,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 
 #include 
@@ -126,7 +127,7 @@ bool AZ::FFont::Load(const char* fontFilePath, unsigned int width, unsigned int
 
     auto pPak = gEnv->pCryPak;
 
-    string fullFile;
+    AZStd::string fullFile;
     if (pPak->IsAbsPath(fontFilePath))
     {
         fullFile = fontFilePath;
@@ -409,6 +410,9 @@ Vec2 AZ::FFont::GetTextSizeUInternal(
     const size_t fxIdx = ctx.m_fxIdx < fxSize ? ctx.m_fxIdx : 0;
     const FontEffect& fx = m_effects[fxIdx];
 
+    AZStd::wstring strW;
+    AZStd::to_wstring(strW, str);
+
     for (size_t i = 0, numPasses = fx.m_passes.size(); i < numPasses; ++i)
     {
         const FontRenderingPass* pass = &fx.m_passes[numPasses - i - 1];
@@ -426,7 +430,7 @@ Vec2 AZ::FFont::GetTextSizeUInternal(
 
         // parse the string, ignoring control characters
         uint32_t nextCh = 0;
-        Unicode::CIterator pChar(str);
+        const wchar_t* pChar = strW.c_str();
         while (uint32_t ch = *pChar)
         {
             ++pChar;
@@ -556,6 +560,9 @@ uint32_t AZ::FFont::GetNumQuadsForText(const char* str, const bool asciiMultiLin
     const size_t fxIdx = ctx.m_fxIdx < fxSize ? ctx.m_fxIdx : 0;
     const FontEffect& fx = m_effects[fxIdx];
 
+    AZStd::wstring strW;
+    AZStd::to_wstring(strW, str);
+
     for (size_t j = 0, numPasses = fx.m_passes.size(); j < numPasses; ++j)
     {
         size_t i = numPasses - j - 1;
@@ -567,7 +574,7 @@ uint32_t AZ::FFont::GetNumQuadsForText(const char* str, const bool asciiMultiLin
         }
 
         uint32_t nextCh = 0;
-        Unicode::CIterator pChar(str);
+        const wchar_t* pChar = strW.c_str();
         while (uint32_t ch = *pChar)
         {
             ++pChar;
@@ -862,9 +869,12 @@ int AZ::FFont::CreateQuadsForText(const RHI::Viewport& viewport, float x, float
             }
         }
 
+        AZStd::wstring strW;
+        AZStd::to_wstring(strW, str);
+
         // parse the string, ignoring control characters
         uint32_t nextCh = 0;
-        Unicode::CIterator pChar(str);
+        const wchar_t* pChar = strW.c_str();
         while (uint32_t ch = *pChar)
         {
             ++pChar;
@@ -1166,7 +1176,7 @@ size_t AZ::FFont::GetTextLength(const char* str, const bool asciiMultiLine) cons
     return len;
 }
 
-void AZ::FFont::WrapText(string& result, float maxWidth, const char* str, const TextDrawContext& ctx)
+void AZ::FFont::WrapText(AZStd::string& result, float maxWidth, const char* str, const TextDrawContext& ctx)
 {
     result = str;
 
@@ -1188,7 +1198,7 @@ void AZ::FFont::WrapText(string& result, float maxWidth, const char* str, const
     const bool multiLine = strSize.y > GetRestoredFontSize(ctx).y;
 
     int lastSpace = -1;
-    const char* pLastSpace = NULL;
+    const wchar_t* pLastSpace = NULL;
     float lastSpaceWidth = 0.0f;
 
     float curCharWidth = 0.0f;
@@ -1197,7 +1207,9 @@ void AZ::FFont::WrapText(string& result, float maxWidth, const char* str, const
     float widthSum = 0.0f;
 
     int curChar = 0;
-    Unicode::CIterator pChar(result.c_str());
+    AZStd::wstring resultW;
+    AZStd::to_wstring(resultW, result.c_str());
+    const wchar_t* pChar = resultW.c_str();
     while (uint32_t ch = *pChar)
     {
         // Dollar sign escape codes.  The following scenarios can happen with dollar signs embedded in a string.
@@ -1224,7 +1236,7 @@ void AZ::FFont::WrapText(string& result, float maxWidth, const char* str, const
         // get char width and sum it to the line width
         // Note: This is not unicode compatible, since char-width depends on surrounding context (ie, combining diacritics etc)
         char codepoint[5];
-        Unicode::Convert(codepoint, ch);
+        AZStd::to_string(codepoint, 5, { (wchar_t*)&ch, 1 });
         curCharWidth = GetTextSize(codepoint, true, ctx).x;
 
         // keep track of spaces
@@ -1233,15 +1245,15 @@ void AZ::FFont::WrapText(string& result, float maxWidth, const char* str, const
         {
             lastSpace = curChar;
             lastSpaceWidth = curLineWidth + curCharWidth;
-            pLastSpace = pChar.GetPosition();
+            pLastSpace = pChar;
             assert(*pLastSpace == ' ');
         }
 
         bool prevCharWasNewline = false;
-        const bool notFirstChar = pChar.GetPosition() != result.c_str();
+        const bool notFirstChar = pChar != resultW.c_str();
         if (*pChar && notFirstChar)
         {
-            const char* pPrevCharStr = pChar.GetPosition() - 1;
+            const wchar_t* pPrevCharStr = pChar - 1;
             prevCharWasNewline = pPrevCharStr[0] == '\n';
         }
 
@@ -1268,12 +1280,12 @@ void AZ::FFont::WrapText(string& result, float maxWidth, const char* str, const
             }
             else
             {
-                const char* buf = pChar.GetPosition();
-                size_t bytesProcessed = buf - result.c_str();
-                result.insert(bytesProcessed, '\n'); // Insert the newline, this invalidates the iterator
-                buf = result.c_str() + bytesProcessed; // In case reallocation occurs, we ensure we are inside the new buffer
+                const wchar_t* buf = pChar;
+                size_t bytesProcessed = buf - resultW.c_str();
+                resultW.insert(resultW.begin() + bytesProcessed, L'\n'); // Insert the newline, this invalidates the iterator
+                buf = resultW.c_str() + bytesProcessed; // In case reallocation occurs, we ensure we are inside the new buffer
                 assert(*buf == '\n');
-                pChar.SetPosition(buf); // pChar once again points inside the target string, at the current character
+                pChar = buf; // pChar once again points inside the target string, at the current character
                 assert(*pChar == ch);
                 ++pChar;
                 ++curChar;
diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Source/FFontXML_Internal.h b/Gems/AtomLyIntegration/AtomFont/Code/Source/FFontXML_Internal.h
index 2cae7b45ee..ac6d140dfc 100644
--- a/Gems/AtomLyIntegration/AtomFont/Code/Source/FFontXML_Internal.h
+++ b/Gems/AtomLyIntegration/AtomFont/Code/Source/FFontXML_Internal.h
@@ -36,7 +36,7 @@ namespace AtomFontInternal
         ELEMENT_PASS_BLEND      = 14
     };
 
-    inline int GetBlendModeFromString(const string& str, bool dst)
+    inline int GetBlendModeFromString(const AZStd::string& str, bool dst)
     {
         int blend = GS_BLSRC_ONE;
 
@@ -100,7 +100,7 @@ namespace AtomFontInternal
             );
     }
 
-    inline AZ::FontSmoothMethod TranslateSmoothMethod(const string& value)
+    inline AZ::FontSmoothMethod TranslateSmoothMethod(const AZStd::string& value)
     {
         AZ::FontSmoothMethod smoothMethod = AZ::FontSmoothMethod::None;
         if (value == "blur")
@@ -179,9 +179,8 @@ namespace AtomFontInternal
         void FoundElementImpl();
 
         // notify methods
-        void FoundElement(const string& name)
+        void FoundElement(const AZStd::string& name)
         {
-            //MessageBox(NULL, string("[" + name + "]").c_str(), "FoundElement", MB_OK);
             // process the previous element
             switch (m_nElement)
             {
@@ -246,9 +245,8 @@ namespace AtomFontInternal
             }
         }
 
-        void FoundAttribute(const string& name, const string& value)
+        void FoundAttribute(const AZStd::string& name, const AZStd::string& value)
         {
-            //MessageBox(NULL, string(name + "\n" + value).c_str(), "FoundAttribute", MB_OK);
             switch (m_nElement)
             {
             case ELEMENT_FONT:
@@ -388,8 +386,8 @@ namespace AtomFontInternal
         AZ::FFont::FontEffect*  m_effect;
         AZ::FFont::FontRenderingPass* m_pass;
 
-        string                  m_strFontPath;
-        string                  m_strFontEffectPath;
+        AZStd::string           m_strFontPath;
+        AZStd::string           m_strFontEffectPath;
         vector2l                m_FontTexSize;
         AZ::AtomFont::GlyphSize m_slotSizes;
         float                   m_SizeRatio = IFFontConstants::defaultSizeRatio;
diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Source/FontRenderer.cpp b/Gems/AtomLyIntegration/AtomFont/Code/Source/FontRenderer.cpp
index 101a506ddc..8c023f9353 100644
--- a/Gems/AtomLyIntegration/AtomFont/Code/Source/FontRenderer.cpp
+++ b/Gems/AtomLyIntegration/AtomFont/Code/Source/FontRenderer.cpp
@@ -22,6 +22,8 @@
 
 #include 
 
+#include 
+
 // Sizes are defined in in 26.6 fixed float format (TT_F26Dot6), where
 // 1 unit is 1/64 of a pixel.
 constexpr int FractionalPixelUnits = 64;
@@ -94,7 +96,7 @@ AZ::FontRenderer::~FontRenderer()
 }
 
 //-------------------------------------------------------------------------------------------------
-int AZ::FontRenderer::LoadFromFile(const string& fileName)
+int AZ::FontRenderer::LoadFromFile(const AZStd::string& fileName)
 {
     int iError = FT_Init_FreeType(&m_library);
 
@@ -252,8 +254,8 @@ int AZ::FontRenderer::GetGlyph(GlyphBitmap* glyphBitmap, int* horizontalAdvance,
     const int textureSlotBufferHeight = glyphBitmap->GetHeight();
 
     // might happen if font characters are too big or cache dimenstions in font.xml is too small ""
-    const bool charWidthFits = iX + m_glyph->bitmap.width <= textureSlotBufferWidth;
-    const bool charHeightFits = iY + m_glyph->bitmap.rows <= textureSlotBufferHeight;
+    const bool charWidthFits = static_cast(iX + m_glyph->bitmap.width) <= textureSlotBufferWidth;
+    const bool charHeightFits = static_cast(iY + m_glyph->bitmap.rows) <= textureSlotBufferHeight;
     const bool charFitsInSlot = charWidthFits && charHeightFits;
     AZ_Error("Font", charFitsInSlot, "Character code %d doesn't fit in font texture; check 'sizeRatio' attribute in font XML or adjust this character's sizing in the font.", characterCode);
 
@@ -309,8 +311,7 @@ Vec2 AZ::FontRenderer::GetKerning(uint32_t leftGlyph, uint32_t rightGlyph)
 #if !defined(_RELEASE)
         if (0 != ftError)
         {
-            string warnMsg;
-            warnMsg.Format("FT_Get_Kerning returned %d", ftError);
+            AZStd::string warnMsg = AZStd::string::format("FT_Get_Kerning returned %d", ftError);
             CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, warnMsg.c_str());
         }
 #endif
diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Source/FontTexture.cpp b/Gems/AtomLyIntegration/AtomFont/Code/Source/FontTexture.cpp
index 6008881ec3..1ee7f80eda 100644
--- a/Gems/AtomLyIntegration/AtomFont/Code/Source/FontTexture.cpp
+++ b/Gems/AtomLyIntegration/AtomFont/Code/Source/FontTexture.cpp
@@ -14,8 +14,8 @@
 #if !defined(USE_NULLFONT_ALWAYS)
 
 #include 
-#include 
 #include 
+#include 
 
 //-------------------------------------------------------------------------------------------------
 AZ::FontTexture::FontTexture()
@@ -44,7 +44,7 @@ AZ::FontTexture::~FontTexture()
 }
 
 //-------------------------------------------------------------------------------------------------
-int AZ::FontTexture::CreateFromFile(const string& fileName, int width, int height, AZ::FontSmoothMethod smoothMethod, AZ::FontSmoothAmount smoothAmount, int widthCellCount, int heightCellCount)
+int AZ::FontTexture::CreateFromFile(const AZStd::string& fileName, int width, int height, AZ::FontSmoothMethod smoothMethod, AZ::FontSmoothAmount smoothAmount, int widthCellCount, int heightCellCount)
 {
     if (!m_glyphCache.LoadFontFromFile(fileName))
     {
@@ -255,10 +255,10 @@ int AZ::FontTexture::PreCacheString(const char* string, int* updated, float size
     uint16_t slotUsage = m_slotUsage++;
     int updateCount = 0;
 
-    uint32_t character;
-    for (Unicode::CIterator it(string); *it; ++it)
+    AZStd::wstring stringW;
+    AZStd::to_wstring(stringW, string);
+    for (wchar_t character : stringW)
     {
-        character = *it;
         TextureSlot* slot = GetCharSlot(character, clampedGlyphSize);
 
         if (!slot)
diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Source/GlyphCache.cpp b/Gems/AtomLyIntegration/AtomFont/Code/Source/GlyphCache.cpp
index 12ebd99183..ee52d36af5 100644
--- a/Gems/AtomLyIntegration/AtomFont/Code/Source/GlyphCache.cpp
+++ b/Gems/AtomLyIntegration/AtomFont/Code/Source/GlyphCache.cpp
@@ -124,7 +124,7 @@ int AZ::GlyphCache::Release()
 }
 
 //-------------------------------------------------------------------------------------------------
-int AZ::GlyphCache::LoadFontFromFile(const string& fileName)
+int AZ::GlyphCache::LoadFontFromFile(const AZStd::string & fileName)
 {
     return m_fontRenderer.LoadFromFile(fileName);
 }
diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp
index 3e622e8994..40c4f8e48f 100644
--- a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp
+++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp
@@ -230,25 +230,20 @@ namespace AZ::Render
         AZ::RPI::ViewportContextPtr viewportContext = GetViewportContext();
         auto rootPass = viewportContext->GetCurrentPipeline()->GetRootPass();
         const RPI::PipelineStatisticsResult stats = rootPass->GetLatestPipelineStatisticsResult();
-        AZStd::function)> containingPassCount = [&containingPassCount](const AZ::RPI::Ptr pass)
-        {
-            int count = 1;
-            if (auto passAsParent = pass->AsParent())
-            {
-                for (const auto& child : passAsParent->GetChildren())
-                {
-                    count += containingPassCount(child);
-                }
-            }
-            return count;
-        };
-        const int numPasses = containingPassCount(rootPass);
+
+        RPI::PassSystemFrameStatistics passSystemFrameStatistics = AZ::RPI::PassSystemInterface::Get()->GetFrameStatistics();
+
         DrawLine(AZStd::string::format(
-            "Total Passes: %d Vertex Count: %lld Primitive Count: %lld",
-            numPasses,
+            "RenderPasses: %d Vertex Count: %lld Primitive Count: %lld",
+            passSystemFrameStatistics.m_numRenderPassesExecuted,
             aznumeric_cast(stats.m_vertexCount),
             aznumeric_cast(stats.m_primitiveCount)
         ));
+        DrawLine(AZStd::string::format(
+            "Total Draw Item Count: %d  Max Draw Items in a Pass: %d",
+            passSystemFrameStatistics.m_totalDrawItemsRendered,
+            passSystemFrameStatistics.m_maxDrawItemsRenderedInAPass
+        ));
     }
 
     void AtomViewportDisplayInfoSystemComponent::UpdateFramerate()
diff --git a/Gems/Blast/Code/Source/Components/BlastSystemComponent.cpp b/Gems/Blast/Code/Source/Components/BlastSystemComponent.cpp
index b7a7443daa..bee94ed116 100644
--- a/Gems/Blast/Code/Source/Components/BlastSystemComponent.cpp
+++ b/Gems/Blast/Code/Source/Components/BlastSystemComponent.cpp
@@ -32,6 +32,7 @@
 #include 
 #include 
 #endif
+#include 
 
 namespace Blast
 {
@@ -437,8 +438,6 @@ namespace Blast
 
     static void CmdToggleBlastDebugVisualization(IConsoleCmdArgs* args)
     {
-        using namespace CryStringUtils;
-
         const int argumentCount = args->GetArgCount();
 
         if (argumentCount == 2)
diff --git a/Gems/Blast/Code/Source/Family/BlastFamilyImpl.cpp b/Gems/Blast/Code/Source/Family/BlastFamilyImpl.cpp
index ec4925fe51..2690a12f24 100644
--- a/Gems/Blast/Code/Source/Family/BlastFamilyImpl.cpp
+++ b/Gems/Blast/Code/Source/Family/BlastFamilyImpl.cpp
@@ -450,7 +450,7 @@ namespace Blast
             const auto buffer = m_asset.GetAccelerator()->fillDebugRender(-1, mode == DebugRenderAabbTreeSegments);
             if (buffer.lineCount)
             {
-                for (int i = 0; i < buffer.lineCount; ++i)
+                for (uint32_t i = 0; i < buffer.lineCount; ++i)
                 {
                     auto& line = buffer.lines[i];
                     AZ::Color color;
diff --git a/Gems/Blast/Code/Tests/Mocks/BlastMocks.h b/Gems/Blast/Code/Tests/Mocks/BlastMocks.h
index 0733862e25..dddd1e275a 100644
--- a/Gems/Blast/Code/Tests/Mocks/BlastMocks.h
+++ b/Gems/Blast/Code/Tests/Mocks/BlastMocks.h
@@ -562,7 +562,7 @@ namespace Blast
     public:
         FakeEntityProvider(uint32_t entityCount)
         {
-            for (int i = 0; i < entityCount; ++i)
+            for (uint32 i = 0; i < entityCount; ++i)
             {
                 m_entities.push_back(AZStd::make_shared());
             }
diff --git a/Gems/CrashReporting/Code/CMakeLists.txt b/Gems/CrashReporting/Code/CMakeLists.txt
index 37224ea1aa..b12b5d8944 100644
--- a/Gems/CrashReporting/Code/CMakeLists.txt
+++ b/Gems/CrashReporting/Code/CMakeLists.txt
@@ -28,6 +28,7 @@ ly_add_target(
     BUILD_DEPENDENCIES
         PRIVATE
             AZ::CrashHandler
+            AZ::AzCore
 )
 
 # Load the "Gem::CrashReporting" module in Clients and Servers
diff --git a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/MetaData.cpp b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/MetaData.cpp
index 9a0913a5db..f98e88a760 100644
--- a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/MetaData.cpp
+++ b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/MetaData.cpp
@@ -41,15 +41,15 @@ namespace CommandSystem
     void MetaData::GenerateNodeGroupMetaData(EMotionFX::Actor* actor, AZStd::string& outMetaDataString)
     {
         AZStd::string nodeNameList;
-        const AZ::u32 numNodeGroups = actor->GetNumNodeGroups();
-        for (uint32 i = 0; i < numNodeGroups; ++i)
+        const size_t numNodeGroups = actor->GetNumNodeGroups();
+        for (size_t i = 0; i < numNodeGroups; ++i)
         {
             EMotionFX::NodeGroup* nodeGroup = actor->GetNodeGroup(i);
             outMetaDataString += AZStd::string::format("AddNodeGroup -actorID $(ACTORID) -name \"%s\"\n", nodeGroup->GetName());
 
             nodeNameList.clear();
-            const AZ::u16 numNodes = nodeGroup->GetNumNodes();
-            for (AZ::u16 n = 0; n < numNodes; ++n)
+            const size_t numNodes = nodeGroup->GetNumNodes();
+            for (size_t n = 0; n < numNodes; ++n)
             {
                 const AZ::u16    nodeIndex = nodeGroup->GetNode(n);
                 EMotionFX::Node* node = actor->GetSkeleton()->GetNode(nodeIndex);
diff --git a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/NodeGroupCommands.cpp b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/NodeGroupCommands.cpp
index c65429ab83..adaa9802d9 100644
--- a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/NodeGroupCommands.cpp
+++ b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/NodeGroupCommands.cpp
@@ -80,7 +80,7 @@ namespace CommandSystem
         {
             if (*m_nodeAction == NodeAction::Replace)
             {
-                nodeGroup->GetNodeArray().Clear();
+                nodeGroup->GetNodeArray().clear();
             }
             for (const AZStd::string& nodeName : *m_nodeNames)
             {
@@ -146,12 +146,12 @@ namespace CommandSystem
         if (m_nodeNames.has_value())
         {
             // clear previous nodes
-            nodeGroup->GetNodeArray().Clear();
-            const uint16 numNodes = m_oldNodeGroup->GetNumNodes();
+            nodeGroup->GetNodeArray().clear();
+            const size_t numNodes = m_oldNodeGroup->GetNumNodes();
             nodeGroup->SetNumNodes(numNodes);
 
             // add all nodes to the group
-            for (uint16 i = 0; i < numNodes; ++i)
+            for (size_t i = 0; i < numNodes; ++i)
             {
                 nodeGroup->SetNode(i, m_oldNodeGroup->GetNode(i));
             }
diff --git a/Gems/EMotionFX/Code/EMotionFX/Exporters/ExporterLib/Exporter/NodeExport.cpp b/Gems/EMotionFX/Code/EMotionFX/Exporters/ExporterLib/Exporter/NodeExport.cpp
index 91727b2113..d8404cc991 100644
--- a/Gems/EMotionFX/Code/EMotionFX/Exporters/ExporterLib/Exporter/NodeExport.cpp
+++ b/Gems/EMotionFX/Code/EMotionFX/Exporters/ExporterLib/Exporter/NodeExport.cpp
@@ -249,7 +249,7 @@ namespace ExporterLib
         {
             chunkHeader.m_sizeInBytes += sizeof(EMotionFX::FileFormat::Actor_NodeGroup);
             chunkHeader.m_sizeInBytes += GetStringChunkSize(nodeGroup->GetNameString());
-            chunkHeader.m_sizeInBytes += sizeof(uint16) * nodeGroup->GetNumNodes();
+            chunkHeader.m_sizeInBytes += sizeof(uint16) * aznumeric_cast(nodeGroup->GetNumNodes());
         }
 
         // endian conversion
@@ -277,14 +277,14 @@ namespace ExporterLib
         MCORE_ASSERT(actor);
 
         // get the number of node groups
-        const uint32 numGroups = actor->GetNumNodeGroups();
+        const size_t numGroups = actor->GetNumNodeGroups();
 
         // create the node group array and reserve some elements
         AZStd::vector nodeGroups;
         nodeGroups.reserve(numGroups);
 
         // iterate through the node groups and add them to the array
-        for (uint32 i = 0; i < numGroups; ++i)
+        for (size_t i = 0; i < numGroups; ++i)
         {
             nodeGroups.emplace_back(actor->GetNodeGroup(i));
         }
diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Actor.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/Actor.cpp
index df039b7186..94a56cc0d5 100644
--- a/Gems/EMotionFX/Code/EMotionFX/Source/Actor.cpp
+++ b/Gems/EMotionFX/Code/EMotionFX/Source/Actor.cpp
@@ -142,9 +142,9 @@ namespace EMotionFX
         result->RecursiveAddDependencies(this);
 
         // clone all nodes groups
-        for (uint32 i = 0; i < m_nodeGroups.GetLength(); ++i)
+        for (const NodeGroup* nodeGroup : m_nodeGroups)
         {
-            result->AddNodeGroup(aznew NodeGroup(*m_nodeGroups[i]));
+            result->AddNodeGroup(aznew NodeGroup(*nodeGroup));
         }
 
         // clone the materials
@@ -948,12 +948,11 @@ namespace EMotionFX
     // remove all node groups
     void Actor::RemoveAllNodeGroups()
     {
-        const uint32 numGroups = m_nodeGroups.GetLength();
-        for (uint32 i = 0; i < numGroups; ++i)
+        for (NodeGroup*& nodeGroup : m_nodeGroups)
         {
-            delete m_nodeGroups[i];
+            delete nodeGroup;
         }
-        m_nodeGroups.Clear();
+        m_nodeGroups.clear();
     }
 
 
@@ -1965,13 +1964,13 @@ namespace EMotionFX
     }
 
 
-    uint32 Actor::GetNumNodeGroups() const
+    size_t Actor::GetNumNodeGroups() const
     {
-        return m_nodeGroups.GetLength();
+        return m_nodeGroups.size();
     }
 
 
-    NodeGroup* Actor::GetNodeGroup(uint32 index) const
+    NodeGroup* Actor::GetNodeGroup(size_t index) const
     {
         return m_nodeGroups[index];
     }
@@ -1979,90 +1978,76 @@ namespace EMotionFX
 
     void Actor::AddNodeGroup(NodeGroup* newGroup)
     {
-        m_nodeGroups.Add(newGroup);
+        m_nodeGroups.emplace_back(newGroup);
     }
 
 
-    void Actor::RemoveNodeGroup(uint32 index, bool delFromMem)
+    void Actor::RemoveNodeGroup(size_t index, bool delFromMem)
     {
         if (delFromMem)
         {
             delete m_nodeGroups[index];
         }
 
-        m_nodeGroups.Remove(index);
+        m_nodeGroups.erase(AZStd::next(begin(m_nodeGroups), index));
     }
 
 
     void Actor::RemoveNodeGroup(NodeGroup* group, bool delFromMem)
     {
-        m_nodeGroups.RemoveByValue(group);
-        if (delFromMem)
+        const auto found = AZStd::find(begin(m_nodeGroups), end(m_nodeGroups), group);
+        if (found != end(m_nodeGroups))
         {
-            delete group;
+            m_nodeGroups.erase(found);
+            if (delFromMem)
+            {
+                delete group;
+            }
         }
     }
 
 
     // find a group index by its name
-    uint32 Actor::FindNodeGroupIndexByName(const char* groupName) const
+    size_t Actor::FindNodeGroupIndexByName(const char* groupName) const
     {
-        const uint32 numGroups = m_nodeGroups.GetLength();
-        for (uint32 i = 0; i < numGroups; ++i)
+        const auto found = AZStd::find_if(begin(m_nodeGroups), end(m_nodeGroups), [groupName](const NodeGroup* nodeGroup)
         {
-            if (m_nodeGroups[i]->GetNameString() == groupName)
-            {
-                return i;
-            }
-        }
-
-        return MCORE_INVALIDINDEX32;
+            return nodeGroup->GetNameString() == groupName;
+        });
+        return found != end(m_nodeGroups) ? AZStd::distance(begin(m_nodeGroups), found) : InvalidIndex;
     }
 
 
     // find a group index by its name, but not case sensitive
-    uint32 Actor::FindNodeGroupIndexByNameNoCase(const char* groupName) const
+    size_t Actor::FindNodeGroupIndexByNameNoCase(const char* groupName) const
     {
-        const uint32 numGroups = m_nodeGroups.GetLength();
-        for (uint32 i = 0; i < numGroups; ++i)
+        const auto found = AZStd::find_if(begin(m_nodeGroups), end(m_nodeGroups), [groupName](const NodeGroup* nodeGroup)
         {
-            if (AzFramework::StringFunc::Equal(m_nodeGroups[i]->GetNameString().c_str(), groupName, false /* no case */))
-            {
-                return i;
-            }
-        }
-
-        return MCORE_INVALIDINDEX32;
+            return AzFramework::StringFunc::Equal(nodeGroup->GetNameString(), groupName, false /* no case */);
+        });
+        return found != end(m_nodeGroups) ? AZStd::distance(begin(m_nodeGroups), found) : InvalidIndex;
     }
 
 
     // find a group by its name
     NodeGroup* Actor::FindNodeGroupByName(const char* groupName) const
     {
-        const uint32 numGroups = m_nodeGroups.GetLength();
-        for (uint32 i = 0; i < numGroups; ++i)
+        const auto found = AZStd::find_if(begin(m_nodeGroups), end(m_nodeGroups), [groupName](const NodeGroup* nodeGroup)
         {
-            if (m_nodeGroups[i]->GetNameString() == groupName)
-            {
-                return m_nodeGroups[i];
-            }
-        }
-        return nullptr;
+            return nodeGroup->GetNameString() == groupName;
+        });
+        return found != end(m_nodeGroups) ? *found : nullptr;
     }
 
 
     // find a group by its name, but without case sensitivity
     NodeGroup* Actor::FindNodeGroupByNameNoCase(const char* groupName) const
     {
-        const uint32 numGroups = m_nodeGroups.GetLength();
-        for (uint32 i = 0; i < numGroups; ++i)
+        const auto found = AZStd::find_if(begin(m_nodeGroups), end(m_nodeGroups), [groupName](const NodeGroup* nodeGroup)
         {
-            if (AzFramework::StringFunc::Equal(m_nodeGroups[i]->GetNameString().c_str(), groupName, false /* no case */))
-            {
-                return m_nodeGroups[i];
-            }
-        }
-        return nullptr;
+            return AzFramework::StringFunc::Equal(nodeGroup->GetNameString(), groupName, false /* no case */);
+        });
+        return found != end(m_nodeGroups) ? *found : nullptr;
     }
 
 
diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Actor.h b/Gems/EMotionFX/Code/EMotionFX/Source/Actor.h
index 5c4a15e2d8..aa5c5df45c 100644
--- a/Gems/EMotionFX/Code/EMotionFX/Source/Actor.h
+++ b/Gems/EMotionFX/Code/EMotionFX/Source/Actor.h
@@ -23,7 +23,6 @@
 // include MCore related files
 #include 
 #include 
-#include 
 #include 
 
 // include required headers
@@ -567,13 +566,13 @@ namespace EMotionFX
          * Get the number of node groups inside this actor object.
          * @result The number of node groups.
          */
-        uint32 GetNumNodeGroups() const;
+        size_t GetNumNodeGroups() const;
 
         /**
          * Get a pointer to a given node group.
          * @param index The node group index, which must be in range of [0..GetNumNodeGroups()-1].
          */
-        NodeGroup* GetNodeGroup(uint32 index) const;
+        NodeGroup* GetNodeGroup(size_t index) const;
 
         /**
          * Add a node group.
@@ -586,7 +585,7 @@ namespace EMotionFX
          * @param index The node group number to remove. This value must be in range of [0..GetNumNodeGroups()-1].
          * @param delFromMem Set to true (default) when you wish to also delete the specified group from memory.
          */
-        void RemoveNodeGroup(uint32 index, bool delFromMem = true);
+        void RemoveNodeGroup(size_t index, bool delFromMem = true);
 
         /**
          * Remove a given node group by its pointer.
@@ -601,14 +600,14 @@ namespace EMotionFX
          * @param groupName The name of the group to search for. This is case sensitive.
          * @result The group number, or MCORE_INVALIDINDEX32 when it cannot be found.
          */
-        uint32 FindNodeGroupIndexByName(const char* groupName) const;
+        size_t FindNodeGroupIndexByName(const char* groupName) const;
 
         /**
          * Find a group index by its name, on a non-case sensitive way.
          * @param groupName The name of the group to search for. This is NOT case sensitive.
          * @result The group number, or MCORE_INVALIDINDEX32 when it cannot be found.
          */
-        uint32 FindNodeGroupIndexByNameNoCase(const char* groupName) const;
+        size_t FindNodeGroupIndexByNameNoCase(const char* groupName) const;
 
         /**
          * Find a node group by its name.
@@ -925,7 +924,7 @@ namespace EMotionFX
         AZStd::vector                    m_nodeMirrorInfos;           /**< The array of node mirror info. */
         AZStd::vector< AZStd::vector< Material* > >       m_materials;                 /**< A collection of materials (for each lod). */
         AZStd::vector< MorphSetup* >                     m_morphSetups;               /**< A morph setup for each geometry LOD. */
-        MCore::SmallArray                   m_nodeGroups;                /**< The set of node groups. */
+        AZStd::vector                       m_nodeGroups;                /**< The set of node groups. */
         AZStd::shared_ptr                 m_physicsSetup;             /**< Hit detection, ragdoll and cloth colliders, joint limits and rigid bodies. */
         AZStd::shared_ptr         m_simulatedObjectSetup;     /**< Setup for simulated objects */
         MCore::Distance::EUnitType                      m_unitType;                  /**< The unit type used on export. */
diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/ActorInstance.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/ActorInstance.cpp
index 6097784e2f..13927f3fd3 100644
--- a/Gems/EMotionFX/Code/EMotionFX/Source/ActorInstance.cpp
+++ b/Gems/EMotionFX/Code/EMotionFX/Source/ActorInstance.cpp
@@ -84,8 +84,8 @@ namespace EMotionFX
         EnableAllNodes();
 
         // apply actor node group default states (disable groups of nodes that are disabled on default)
-        const uint32 numGroups = m_actor->GetNumNodeGroups();
-        for (uint32 i = 0; i < numGroups; ++i)
+        const size_t numGroups = m_actor->GetNumNodeGroups();
+        for (size_t i = 0; i < numGroups; ++i)
         {
             if (m_actor->GetNodeGroup(i)->GetIsEnabledOnDefault() == false) // if this group is disabled on default
             {
diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/NodeGroup.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/NodeGroup.cpp
index 293d64775d..74e59150e0 100644
--- a/Gems/EMotionFX/Code/EMotionFX/Source/NodeGroup.cpp
+++ b/Gems/EMotionFX/Code/EMotionFX/Source/NodeGroup.cpp
@@ -17,7 +17,7 @@ namespace EMotionFX
     AZ_CLASS_ALLOCATOR_IMPL(NodeGroup, NodeAllocator, 0)
 
 
-    NodeGroup::NodeGroup(const AZStd::string& groupName, uint16 numNodes, bool enabledOnDefault)
+    NodeGroup::NodeGroup(const AZStd::string& groupName, size_t numNodes, bool enabledOnDefault)
         : m_name(groupName)
         , m_nodes(numNodes)
         , m_enabledOnDefault(enabledOnDefault)
@@ -47,28 +47,28 @@ namespace EMotionFX
 
 
     // set the number of nodes
-    void NodeGroup::SetNumNodes(const uint16 numNodes)
+    void NodeGroup::SetNumNodes(const size_t numNodes)
     {
-        m_nodes.Resize(numNodes);
+        m_nodes.resize(numNodes);
     }
 
 
     // get the number of nodes
-    uint16 NodeGroup::GetNumNodes() const
+    size_t NodeGroup::GetNumNodes() const
     {
-        return static_cast(m_nodes.GetLength());
+        return m_nodes.size();
     }
 
 
     // set a given node to a given node number
-    void NodeGroup::SetNode(uint16 index, uint16 nodeIndex)
+    void NodeGroup::SetNode(size_t index, uint16 nodeIndex)
     {
         m_nodes[index] = nodeIndex;
     }
 
 
     // get the node number of a given index
-    uint16 NodeGroup::GetNode(uint16 index) const
+    uint16 NodeGroup::GetNode(size_t index) const
     {
         return m_nodes[index];
     }
@@ -77,10 +77,9 @@ namespace EMotionFX
     // enable all nodes in the group inside a given actor instance
     void NodeGroup::EnableNodes(ActorInstance* targetActorInstance)
     {
-        const uint16 numNodes = static_cast(m_nodes.GetLength());
-        for (uint16 i = 0; i < numNodes; ++i)
+        for (uint16 node : m_nodes)
         {
-            targetActorInstance->EnableNode(m_nodes[i]);
+            targetActorInstance->EnableNode(node);
         }
     }
 
@@ -88,10 +87,9 @@ namespace EMotionFX
     // disable all nodes in the group inside a given actor instance
     void NodeGroup::DisableNodes(ActorInstance* targetActorInstance)
     {
-        const uint16 numNodes = static_cast(m_nodes.GetLength());
-        for (uint16 i = 0; i < numNodes; ++i)
+        for (uint16 node : m_nodes)
         {
-            targetActorInstance->DisableNode(m_nodes[i]);
+            targetActorInstance->DisableNode(node);
         }
     }
 
@@ -99,26 +97,29 @@ namespace EMotionFX
     // add a given node to the group (performs a realloc internally)
     void NodeGroup::AddNode(uint16 nodeIndex)
     {
-        m_nodes.Add(nodeIndex);
+        m_nodes.emplace_back(nodeIndex);
     }
 
 
     // remove a given node by its node number
     void NodeGroup::RemoveNodeByNodeIndex(uint16 nodeIndex)
     {
-        m_nodes.RemoveByValue(nodeIndex);
+        if (const auto found = AZStd::find(begin(m_nodes), end(m_nodes), nodeIndex); found)
+        {
+            m_nodes.erase(found);
+        }
     }
 
 
     // remove a given array element from the list of nodes
-    void NodeGroup::RemoveNodeByGroupIndex(uint16 index)
+    void NodeGroup::RemoveNodeByGroupIndex(size_t index)
     {
-        m_nodes.Remove(index);
+        m_nodes.erase(AZStd::next(begin(m_nodes), index));
     }
 
 
     // get the node array directly
-    MCore::SmallArray& NodeGroup::GetNodeArray()
+    AZStd::vector& NodeGroup::GetNodeArray()
     {
         return m_nodes;
     }
diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/NodeGroup.h b/Gems/EMotionFX/Code/EMotionFX/Source/NodeGroup.h
index 7ee74415c0..02dc7d70a9 100644
--- a/Gems/EMotionFX/Code/EMotionFX/Source/NodeGroup.h
+++ b/Gems/EMotionFX/Code/EMotionFX/Source/NodeGroup.h
@@ -11,8 +11,8 @@
 // include required files
 #include "EMotionFXConfig.h"
 #include "BaseObject.h"
-#include 
 #include 
+#include 
 
 
 namespace EMotionFX
@@ -34,7 +34,7 @@ namespace EMotionFX
     public:
         AZ_CLASS_ALLOCATOR_DECL
 
-        NodeGroup(const AZStd::string& groupName = {}, uint16 numNodes = 0, bool enabledOnDefault = true);
+        NodeGroup(const AZStd::string& groupName = {}, size_t numNodes = 0, bool enabledOnDefault = true);
         NodeGroup(const NodeGroup& aOther);
         NodeGroup& operator=(const NodeGroup& aOther);
 
@@ -61,13 +61,13 @@ namespace EMotionFX
          * This will resize the array of node indices. Don't forget to initialize the node values after increasing the number of nodes though.
          * @param numNodes The number of nodes that are inside this group.
          */
-        void SetNumNodes(const uint16 numNodes);
+        void SetNumNodes(size_t numNodes);
 
         /**
          * Get the number of nodes that remain inside this group.
          * @result The number of nodes inside this group.
          */
-        uint16 GetNumNodes() const;
+        size_t GetNumNodes() const;
 
         /**
          * Set the value of a given node.
@@ -75,14 +75,14 @@ namespace EMotionFX
          * @param nodeIndex The value for the given node. This is the node index which points inside the Actor object where this group will belong to.
          *                  To get access to the actual node object use Actor::GetNode( nodeIndex ).
          */
-        void SetNode(uint16 index, uint16 nodeIndex);
+        void SetNode(size_t index, uint16 nodeIndex);
 
         /**
          * Get the node index for a given node inside the group.
          * @param index The node number inside this group, which must be in range of [0..GetNumNodes()-1].
          * @result The node number, which points inside the Actor object. Use Actor::GetNode( returnValue ) to get access to the node information.
          */
-        uint16 GetNode(uint16 index) const;
+        uint16 GetNode(size_t index) const;
 
         /**
          * Enable all nodes that remain inside this group, for a given actor instance.
@@ -127,13 +127,13 @@ namespace EMotionFX
          * @param index The node index in the group. So for example an index value of 5 will remove the sixth node from the group.
          *              The index value must be in range of [0..GetNumNodes() - 1].
          */
-        void RemoveNodeByGroupIndex(uint16 index);
+        void RemoveNodeByGroupIndex(size_t index);
 
         /**
          * Get direct access to the array of node indices that are part of this group.
          * @result A reference to the array of nodes inside this group. Please use this with care.
          */
-        MCore::SmallArray& GetNodeArray();
+        AZStd::vector& GetNodeArray();
 
         /**
          * Check whether this group is enabled after actor instance creation time.
@@ -155,7 +155,7 @@ namespace EMotionFX
 
     private:
         AZStd::string               m_name;              /**< The name of the group. */
-        MCore::SmallArray   m_nodes;             /**< The node index numbers that are inside this group. */
+        AZStd::vector       m_nodes;             /**< The node index numbers that are inside this group. */
         bool                        m_enabledOnDefault;  /**< Specifies whether this group is enabled on default (true) or disabled (false). With on default we mean after directly after the actor instance using this group has been created. */
     };
 }   // namespace EMotionFX
diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Pose.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/Pose.cpp
index 23390bf69b..99f1474c89 100644
--- a/Gems/EMotionFX/Code/EMotionFX/Source/Pose.cpp
+++ b/Gems/EMotionFX/Code/EMotionFX/Source/Pose.cpp
@@ -24,10 +24,6 @@ namespace EMotionFX
         m_actorInstance  = nullptr;
         m_actor          = nullptr;
         m_skeleton       = nullptr;
-        m_localSpaceTransforms.SetMemoryCategory(EMFX_MEMCATEGORY_ANIMGRAPH_POSE);
-        m_modelSpaceTransforms.SetMemoryCategory(EMFX_MEMCATEGORY_ANIMGRAPH_POSE);
-        m_flags.SetMemoryCategory(EMFX_MEMCATEGORY_ANIMGRAPH_POSE);
-        m_morphWeights.SetMemoryCategory(EMFX_MEMCATEGORY_ANIMGRAPH_POSE);
     }
 
 
@@ -55,10 +51,10 @@ namespace EMotionFX
 
         // resize the buffers
         const size_t numTransforms = m_actor->GetSkeleton()->GetNumNodes();
-        m_localSpaceTransforms.ResizeFast(numTransforms);
-        m_modelSpaceTransforms.ResizeFast(numTransforms);
-        m_flags.ResizeFast(numTransforms);
-        m_morphWeights.ResizeFast(actorInstance->GetMorphSetupInstance()->GetNumMorphTargets());
+        m_localSpaceTransforms.resize_no_construct(numTransforms);
+        m_modelSpaceTransforms.resize_no_construct(numTransforms);
+        m_flags.resize_no_construct(numTransforms);
+        m_morphWeights.resize_no_construct(actorInstance->GetMorphSetupInstance()->GetNumMorphTargets());
 
         for (const auto& poseDataItem : m_poseDatas)
         {
@@ -79,11 +75,11 @@ namespace EMotionFX
 
         // resize the buffers
         const size_t numTransforms = m_actor->GetSkeleton()->GetNumNodes();
-        m_localSpaceTransforms.ResizeFast(numTransforms);
-        m_modelSpaceTransforms.ResizeFast(numTransforms);
+        m_localSpaceTransforms.resize_no_construct(numTransforms);
+        m_modelSpaceTransforms.resize_no_construct(numTransforms);
 
-        const size_t oldSize = m_flags.GetLength();
-        m_flags.ResizeFast(numTransforms);
+        const size_t oldSize = m_flags.size();
+        m_flags.resize_no_construct(numTransforms);
         if (oldSize < numTransforms && clearAllFlags == false)
         {
             for (size_t i = oldSize; i < numTransforms; ++i)
@@ -93,7 +89,7 @@ namespace EMotionFX
         }
 
         MorphSetup* morphSetup = m_actor->GetMorphSetup(0);
-        m_morphWeights.ResizeFast((morphSetup) ? morphSetup->GetNumMorphTargets() : 0);
+        m_morphWeights.resize_no_construct((morphSetup) ? morphSetup->GetNumMorphTargets() : 0);
 
         for (const auto& poseDataItem : m_poseDatas)
         {
@@ -111,11 +107,11 @@ namespace EMotionFX
     void Pose::SetNumTransforms(size_t numTransforms)
     {
         // resize the buffers
-        m_localSpaceTransforms.ResizeFast(numTransforms);
-        m_modelSpaceTransforms.ResizeFast(numTransforms);
+        m_localSpaceTransforms.resize_no_construct(numTransforms);
+        m_modelSpaceTransforms.resize_no_construct(numTransforms);
 
-        const size_t oldSize = m_flags.GetLength();
-        m_flags.ResizeFast(numTransforms);
+        const size_t oldSize = m_flags.size();
+        m_flags.resize_no_construct(numTransforms);
 
         for (size_t i = oldSize; i < numTransforms; ++i)
         {
@@ -127,10 +123,18 @@ namespace EMotionFX
 
     void Pose::Clear(bool clearMem)
     {
-        m_localSpaceTransforms.Clear(clearMem);
-        m_modelSpaceTransforms.Clear(clearMem);
-        m_flags.Clear(clearMem);
-        m_morphWeights.Clear(clearMem);
+        const auto clear = [clearMem](auto& vector)
+        {
+            vector.clear();
+            if (clearMem)
+            {
+                vector.shrink_to_fit();
+            }
+        };
+        clear(m_localSpaceTransforms);
+        clear(m_modelSpaceTransforms);
+        clear(m_flags);
+        clear(m_morphWeights);
 
         ClearPoseDatas();
     }
@@ -139,7 +143,7 @@ namespace EMotionFX
     // clear the pose flags
     void Pose::ClearFlags(uint8 newFlags)
     {
-        MCore::MemSet((uint8*)m_flags.GetPtr(), newFlags, sizeof(uint8) * m_flags.GetLength());
+        MCore::MemSet((uint8*)m_flags.data(), newFlags, sizeof(uint8) * m_flags.size());
     }
 
 
@@ -398,30 +402,27 @@ namespace EMotionFX
     // invalidate all local transforms
     void Pose::InvalidateAllLocalSpaceTransforms()
     {
-        const size_t numFlags = m_flags.GetLength();
-        for (size_t i = 0; i < numFlags; ++i)
+        for (uint8& flag : m_flags)
         {
-            m_flags[i] &= ~FLAG_LOCALTRANSFORMREADY;
+            flag &= ~FLAG_LOCALTRANSFORMREADY;
         }
     }
 
 
     void Pose::InvalidateAllModelSpaceTransforms()
     {
-        const size_t numFlags = m_flags.GetLength();
-        for (size_t i = 0; i < numFlags; ++i)
+        for (uint8& flag : m_flags)
         {
-            m_flags[i] &= ~FLAG_MODELTRANSFORMREADY;
+            flag &= ~FLAG_MODELTRANSFORMREADY;
         }
     }
 
 
     void Pose::InvalidateAllLocalAndModelSpaceTransforms()
     {
-        const size_t numFlags = m_flags.GetLength();
-        for (size_t i = 0; i < numFlags; ++i)
+        for (uint8& flag : m_flags)
         {
-            m_flags[i] &= ~(FLAG_LOCALTRANSFORMREADY | FLAG_MODELTRANSFORMREADY);
+            flag &= ~(FLAG_LOCALTRANSFORMREADY | FLAG_MODELTRANSFORMREADY);
         }
     }
 
@@ -469,8 +470,8 @@ namespace EMotionFX
         // make sure the number of transforms are equal
         MCORE_ASSERT(destPose);
         MCORE_ASSERT(outPose);
-        MCORE_ASSERT(m_localSpaceTransforms.GetLength() == destPose->m_localSpaceTransforms.GetLength());
-        MCORE_ASSERT(m_localSpaceTransforms.GetLength() == outPose->m_localSpaceTransforms.GetLength());
+        MCORE_ASSERT(m_localSpaceTransforms.size() == destPose->m_localSpaceTransforms.size());
+        MCORE_ASSERT(m_localSpaceTransforms.size() == outPose->m_localSpaceTransforms.size());
         MCORE_ASSERT(instance->GetIsMixing() == false);
 
         // get some motion instance properties which we use to decide the optimized blending routine
@@ -509,7 +510,7 @@ namespace EMotionFX
             }
 
             // blend the morph weights
-            const size_t numMorphs = m_morphWeights.GetLength();
+            const size_t numMorphs = m_morphWeights.size();
             MCORE_ASSERT(actorInstance->GetMorphSetupInstance()->GetNumMorphTargets() == numMorphs);
             MCORE_ASSERT(numMorphs == destPose->GetNumMorphWeights());
             for (size_t i = 0; i < numMorphs; ++i)
@@ -533,7 +534,7 @@ namespace EMotionFX
             outPose->InvalidateAllModelSpaceTransforms();
 
             // blend the morph weights
-            const size_t numMorphs = m_morphWeights.GetLength();
+            const size_t numMorphs = m_morphWeights.size();
             MCORE_ASSERT(actorInstance->GetMorphSetupInstance()->GetNumMorphTargets() == numMorphs);
             MCORE_ASSERT(numMorphs == destPose->GetNumMorphWeights());
             for (size_t i = 0; i < numMorphs; ++i)
@@ -550,8 +551,8 @@ namespace EMotionFX
         // make sure the number of transforms are equal
         MCORE_ASSERT(destPose);
         MCORE_ASSERT(outPose);
-        MCORE_ASSERT(m_localSpaceTransforms.GetLength() == destPose->m_localSpaceTransforms.GetLength());
-        MCORE_ASSERT(m_localSpaceTransforms.GetLength() == outPose->m_localSpaceTransforms.GetLength());
+        MCORE_ASSERT(m_localSpaceTransforms.size() == destPose->m_localSpaceTransforms.size());
+        MCORE_ASSERT(m_localSpaceTransforms.size() == outPose->m_localSpaceTransforms.size());
         MCORE_ASSERT(instance->GetIsMixing());
 
         const bool additive = (instance->GetBlendMode() == BLENDMODE_ADDITIVE);
@@ -564,7 +565,7 @@ namespace EMotionFX
         Transform result;
 
         const MotionLinkData* motionLinkData = instance->GetMotion()->GetMotionData()->FindMotionLinkData(actorInstance->GetActor());
-        AZ_Assert(motionLinkData->GetJointDataLinks().size() == m_localSpaceTransforms.GetLength(), "Expecting there to be the same amount of motion links as pose transforms.");
+        AZ_Assert(motionLinkData->GetJointDataLinks().size() == m_localSpaceTransforms.size(), "Expecting there to be the same amount of motion links as pose transforms.");
 
         // blend all transforms
         if (!additive)
@@ -589,7 +590,7 @@ namespace EMotionFX
             outPose->InvalidateAllModelSpaceTransforms();
 
             // blend the morph weights
-            const size_t numMorphs = m_morphWeights.GetLength();
+            const size_t numMorphs = m_morphWeights.size();
             MCORE_ASSERT(actorInstance->GetMorphSetupInstance()->GetNumMorphTargets() == numMorphs);
             MCORE_ASSERT(numMorphs == destPose->GetNumMorphWeights());
             for (size_t i = 0; i < numMorphs; ++i)
@@ -619,7 +620,7 @@ namespace EMotionFX
             outPose->InvalidateAllModelSpaceTransforms();
 
             // blend the morph weights
-            const size_t numMorphs = m_morphWeights.GetLength();
+            const size_t numMorphs = m_morphWeights.size();
             MCORE_ASSERT(actorInstance->GetMorphSetupInstance()->GetNumMorphTargets() == numMorphs);
             MCORE_ASSERT(numMorphs == destPose->GetNumMorphWeights());
             for (size_t i = 0; i < numMorphs; ++i)
@@ -647,10 +648,10 @@ namespace EMotionFX
             return;
         }
 
-        m_modelSpaceTransforms.MemCopyContentsFrom(sourcePose->m_modelSpaceTransforms);
-        m_localSpaceTransforms.MemCopyContentsFrom(sourcePose->m_localSpaceTransforms);
-        m_flags.MemCopyContentsFrom(sourcePose->m_flags);
-        m_morphWeights.MemCopyContentsFrom(sourcePose->m_morphWeights);
+        m_modelSpaceTransforms = sourcePose->m_modelSpaceTransforms;
+        m_localSpaceTransforms = sourcePose->m_localSpaceTransforms;
+        m_flags = sourcePose->m_flags;
+        m_morphWeights = sourcePose->m_morphWeights;
 
         // Deactivate pose datas from the current pose that are not in the source that we copy from.
         // This is needed in order to prevent leftover pose datas and to avoid de-/allocations.
@@ -727,11 +728,11 @@ namespace EMotionFX
                 m_localSpaceTransforms[nodeNr].Zero();
             }
 
-            const size_t numMorphs = m_morphWeights.GetLength();
+            const size_t numMorphs = m_morphWeights.size();
             MCORE_ASSERT(m_actorInstance->GetMorphSetupInstance()->GetNumMorphTargets() == numMorphs);
-            for (size_t i = 0; i < numMorphs; ++i)
+            for (float& morphWeight : m_morphWeights)
             {
-                m_morphWeights[i] = 0.0f;
+                morphWeight = 0.0f;
             }
         }
         else
@@ -742,11 +743,11 @@ namespace EMotionFX
                 m_localSpaceTransforms[i].Zero();
             }
 
-            const size_t numMorphs = m_morphWeights.GetLength();
+            const size_t numMorphs = m_morphWeights.size();
             MCORE_ASSERT(m_actor->GetMorphSetup(0)->GetNumMorphTargets() == numMorphs);
-            for (size_t i = 0; i < numMorphs; ++i)
+            for (float& morphWeight : m_morphWeights)
             {
-                m_morphWeights[i] = 0.0f;
+                morphWeight = 0.0f;
             }
         }
 
@@ -795,7 +796,7 @@ namespace EMotionFX
             }
 
             // blend the morph weights
-            const size_t numMorphs = m_morphWeights.GetLength();
+            const size_t numMorphs = m_morphWeights.size();
             MCORE_ASSERT(m_actorInstance->GetMorphSetupInstance()->GetNumMorphTargets() == numMorphs);
             MCORE_ASSERT(numMorphs == other->GetNumMorphWeights());
             for (size_t i = 0; i < numMorphs; ++i)
@@ -814,7 +815,7 @@ namespace EMotionFX
             }
 
             // blend the morph weights
-            const size_t numMorphs = m_morphWeights.GetLength();
+            const size_t numMorphs = m_morphWeights.size();
             MCORE_ASSERT(m_actor->GetMorphSetup(0)->GetNumMorphTargets() == numMorphs);
             MCORE_ASSERT(numMorphs == other->GetNumMorphWeights());
             for (size_t i = 0; i < numMorphs; ++i)
@@ -841,7 +842,7 @@ namespace EMotionFX
             }
 
             // blend the morph weights
-            const size_t numMorphs = m_morphWeights.GetLength();
+            const size_t numMorphs = m_morphWeights.size();
             MCORE_ASSERT(m_actorInstance->GetMorphSetupInstance()->GetNumMorphTargets() == numMorphs);
             MCORE_ASSERT(numMorphs == destPose->GetNumMorphWeights());
             for (size_t i = 0; i < numMorphs; ++i)
@@ -865,7 +866,7 @@ namespace EMotionFX
             }
 
             // blend the morph weights
-            const size_t numMorphs = m_morphWeights.GetLength();
+            const size_t numMorphs = m_morphWeights.size();
             MCORE_ASSERT(m_actor->GetMorphSetup(0)->GetNumMorphTargets() == numMorphs);
             MCORE_ASSERT(numMorphs == destPose->GetNumMorphWeights());
             for (size_t i = 0; i < numMorphs; ++i)
@@ -886,7 +887,7 @@ namespace EMotionFX
 
     Pose& Pose::MakeRelativeTo(const Pose& other)
     {
-        AZ_Assert(m_localSpaceTransforms.GetLength() == other.m_localSpaceTransforms.GetLength(), "Poses must be of the same size");
+        AZ_Assert(m_localSpaceTransforms.size() == other.m_localSpaceTransforms.size(), "Poses must be of the same size");
         if (m_actorInstance)
         {
             const size_t numNodes = m_actorInstance->GetNumEnabledNodes();
@@ -899,7 +900,7 @@ namespace EMotionFX
         }
         else
         {
-            const size_t numNodes = m_localSpaceTransforms.GetLength();
+            const size_t numNodes = m_localSpaceTransforms.size();
             for (size_t i = 0; i < numNodes; ++i)
             {
                 Transform& transform = const_cast(GetLocalSpaceTransform(i));
@@ -907,7 +908,7 @@ namespace EMotionFX
             }
         }
 
-        const size_t numMorphs = m_morphWeights.GetLength();
+        const size_t numMorphs = m_morphWeights.size();
         AZ_Assert(numMorphs == other.GetNumMorphWeights(), "Number of morphs in the pose doesn't match the number of morphs inside the provided input pose.");
         for (size_t i = 0; i < numMorphs; ++i)
         {
@@ -921,7 +922,7 @@ namespace EMotionFX
 
     Pose& Pose::ApplyAdditive(const Pose& additivePose, float weight)
     {
-        AZ_Assert(m_localSpaceTransforms.GetLength() == additivePose.m_localSpaceTransforms.GetLength(), "Poses must be of the same size");
+        AZ_Assert(m_localSpaceTransforms.size() == additivePose.m_localSpaceTransforms.size(), "Poses must be of the same size");
         if (m_actorInstance)
         {
             AZ_Assert(weight > -MCore::Math::epsilon && weight < (1 + MCore::Math::epsilon), "Expected weight to be between 0..1");
@@ -939,7 +940,7 @@ namespace EMotionFX
         }
         else
         {
-            AZ_Assert(m_localSpaceTransforms.GetLength() == additivePose.m_localSpaceTransforms.GetLength(), "Poses must be of the same size");
+            AZ_Assert(m_localSpaceTransforms.size() == additivePose.m_localSpaceTransforms.size(), "Poses must be of the same size");
             if (m_actorInstance)
             {
                 const size_t numNodes = m_actorInstance->GetNumEnabledNodes();
@@ -959,7 +960,7 @@ namespace EMotionFX
             }
             else
             {
-                const size_t numNodes = m_localSpaceTransforms.GetLength();
+                const size_t numNodes = m_localSpaceTransforms.size();
                 for (size_t i = 0; i < numNodes; ++i)
                 {
                     Transform& transform = const_cast(GetLocalSpaceTransform(i));
@@ -974,7 +975,7 @@ namespace EMotionFX
                 }
             }
 
-            const size_t numMorphs = m_morphWeights.GetLength();
+            const size_t numMorphs = m_morphWeights.size();
             AZ_Assert(numMorphs == additivePose.GetNumMorphWeights(), "Number of morphs in the pose doesn't match the number of morphs inside the provided input pose.");
             for (size_t i = 0; i < numMorphs; ++i)
             {
@@ -989,7 +990,7 @@ namespace EMotionFX
 
     Pose& Pose::ApplyAdditive(const Pose& additivePose)
     {
-        AZ_Assert(m_localSpaceTransforms.GetLength() == additivePose.m_localSpaceTransforms.GetLength(), "Poses must be of the same size");
+        AZ_Assert(m_localSpaceTransforms.size() == additivePose.m_localSpaceTransforms.size(), "Poses must be of the same size");
         if (m_actorInstance)
         {
             const size_t numNodes = m_actorInstance->GetNumEnabledNodes();
@@ -1009,7 +1010,7 @@ namespace EMotionFX
         }
         else
         {
-            const size_t numNodes = m_localSpaceTransforms.GetLength();
+            const size_t numNodes = m_localSpaceTransforms.size();
             for (size_t i = 0; i < numNodes; ++i)
             {
                 Transform& transform = const_cast(GetLocalSpaceTransform(i));
@@ -1024,7 +1025,7 @@ namespace EMotionFX
             }
         }
 
-        const size_t numMorphs = m_morphWeights.GetLength();
+        const size_t numMorphs = m_morphWeights.size();
         AZ_Assert(numMorphs == additivePose.GetNumMorphWeights(), "Number of morphs in the pose doesn't match the number of morphs inside the provided input pose.");
         for (size_t i = 0; i < numMorphs; ++i)
         {
@@ -1038,7 +1039,7 @@ namespace EMotionFX
 
     Pose& Pose::MakeAdditive(const Pose& refPose)
     {
-        AZ_Assert(m_localSpaceTransforms.GetLength() == refPose.m_localSpaceTransforms.GetLength(), "Poses must be of the same size");
+        AZ_Assert(m_localSpaceTransforms.size() == refPose.m_localSpaceTransforms.size(), "Poses must be of the same size");
         if (m_actorInstance)
         {
             const size_t numNodes = m_actorInstance->GetNumEnabledNodes();
@@ -1057,7 +1058,7 @@ namespace EMotionFX
         }
         else
         {
-            const size_t numNodes = m_localSpaceTransforms.GetLength();
+            const size_t numNodes = m_localSpaceTransforms.size();
             for (size_t i = 0; i < numNodes; ++i)
             {
                 Transform& transform = const_cast(GetLocalSpaceTransform(i));
@@ -1071,7 +1072,7 @@ namespace EMotionFX
             }
         }
 
-        const size_t numMorphs = m_morphWeights.GetLength();
+        const size_t numMorphs = m_morphWeights.size();
         AZ_Assert(numMorphs == refPose.GetNumMorphWeights(), "Number of morphs in the pose doesn't match the number of morphs inside the provided input pose.");
         for (size_t i = 0; i < numMorphs; ++i)
         {
@@ -1101,7 +1102,7 @@ namespace EMotionFX
             }
 
             // blend the morph weights
-            const size_t numMorphs = m_morphWeights.GetLength();
+            const size_t numMorphs = m_morphWeights.size();
             MCORE_ASSERT(m_actorInstance->GetMorphSetupInstance()->GetNumMorphTargets() == numMorphs);
             MCORE_ASSERT(numMorphs == destPose->GetNumMorphWeights());
             for (size_t i = 0; i < numMorphs; ++i)
@@ -1123,7 +1124,7 @@ namespace EMotionFX
             }
 
             // blend the morph weights
-            const size_t numMorphs = m_morphWeights.GetLength();
+            const size_t numMorphs = m_morphWeights.size();
             MCORE_ASSERT(m_actor->GetMorphSetup(0)->GetNumMorphTargets() == numMorphs);
             MCORE_ASSERT(numMorphs == destPose->GetNumMorphWeights());
             for (size_t i = 0; i < numMorphs; ++i)
@@ -1274,23 +1275,19 @@ namespace EMotionFX
     // zero all morph weights
     void Pose::ZeroMorphWeights()
     {
-        const size_t numMorphs = m_morphWeights.GetLength();
-        for (size_t m = 0; m < numMorphs; ++m)
-        {
-            m_morphWeights[m] = 0.0f;
-        }
+        AZStd::fill(begin(m_morphWeights), end(m_morphWeights), 0.0f);
     }
 
 
     void Pose::ResizeNumMorphs(size_t numMorphTargets)
     {
-        m_morphWeights.Resize(numMorphTargets);
+        m_morphWeights.resize(numMorphTargets);
     }
 
 
     Pose& Pose::PreMultiply(const Pose& other)
     {
-        AZ_Assert(m_localSpaceTransforms.GetLength() == other.m_localSpaceTransforms.GetLength(), "Poses must be of the same size");
+        AZ_Assert(m_localSpaceTransforms.size() == other.m_localSpaceTransforms.size(), "Poses must be of the same size");
         if (m_actorInstance)
         {
             const size_t numNodes = m_actorInstance->GetNumEnabledNodes();
@@ -1304,7 +1301,7 @@ namespace EMotionFX
         }
         else
         {
-            const size_t numNodes = m_localSpaceTransforms.GetLength();
+            const size_t numNodes = m_localSpaceTransforms.size();
             for (size_t i = 0; i < numNodes; ++i)
             {
                 Transform& transform = const_cast(GetLocalSpaceTransform(i));
@@ -1320,7 +1317,7 @@ namespace EMotionFX
 
     Pose& Pose::Multiply(const Pose& other)
     {
-        AZ_Assert(m_localSpaceTransforms.GetLength() == other.m_localSpaceTransforms.GetLength(), "Poses must be of the same size");
+        AZ_Assert(m_localSpaceTransforms.size() == other.m_localSpaceTransforms.size(), "Poses must be of the same size");
         if (m_actorInstance)
         {
             const size_t numNodes = m_actorInstance->GetNumEnabledNodes();
@@ -1333,7 +1330,7 @@ namespace EMotionFX
         }
         else
         {
-            const size_t numNodes = m_localSpaceTransforms.GetLength();
+            const size_t numNodes = m_localSpaceTransforms.size();
             for (size_t i = 0; i < numNodes; ++i)
             {
                 Transform& transform = const_cast(GetLocalSpaceTransform(i));
@@ -1348,7 +1345,7 @@ namespace EMotionFX
 
     Pose& Pose::MultiplyInverse(const Pose& other)
     {
-        AZ_Assert(m_localSpaceTransforms.GetLength() == other.m_localSpaceTransforms.GetLength(), "Poses must be of the same size");
+        AZ_Assert(m_localSpaceTransforms.size() == other.m_localSpaceTransforms.size(), "Poses must be of the same size");
         if (m_actorInstance)
         {
             const size_t numNodes = m_actorInstance->GetNumEnabledNodes();
@@ -1363,7 +1360,7 @@ namespace EMotionFX
         }
         else
         {
-            const size_t numNodes = m_localSpaceTransforms.GetLength();
+            const size_t numNodes = m_localSpaceTransforms.size();
             for (size_t i = 0; i < numNodes; ++i)
             {
                 Transform& transform = const_cast(GetLocalSpaceTransform(i));
diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Pose.h b/Gems/EMotionFX/Code/EMotionFX/Source/Pose.h
index 32c7a33bd2..b7844276be 100644
--- a/Gems/EMotionFX/Code/EMotionFX/Source/Pose.h
+++ b/Gems/EMotionFX/Code/EMotionFX/Source/Pose.h
@@ -9,7 +9,7 @@
 #pragma once
 
 #include 
-#include 
+#include 
 #include 
 #include 
 
@@ -98,9 +98,9 @@ namespace EMotionFX
 
         Transform CalcTrajectoryTransform() const;
 
-        MCORE_INLINE const Transform* GetLocalSpaceTransforms() const                               { return m_localSpaceTransforms.GetReadPtr(); }
-        MCORE_INLINE const Transform* GetModelSpaceTransforms() const                               { return m_modelSpaceTransforms.GetReadPtr(); }
-        MCORE_INLINE size_t GetNumTransforms() const                                                { return m_localSpaceTransforms.GetLength(); }
+        MCORE_INLINE const Transform* GetLocalSpaceTransforms() const                               { return m_localSpaceTransforms.data(); }
+        MCORE_INLINE const Transform* GetModelSpaceTransforms() const                               { return m_modelSpaceTransforms.data(); }
+        MCORE_INLINE size_t GetNumTransforms() const                                                { return m_localSpaceTransforms.size(); }
         MCORE_INLINE const ActorInstance* GetActorInstance() const                                  { return m_actorInstance; }
         MCORE_INLINE const Actor* GetActor() const                                                  { return m_actor; }
         MCORE_INLINE const Skeleton* GetSkeleton() const                                            { return m_skeleton; }
@@ -116,7 +116,7 @@ namespace EMotionFX
 
         MCORE_INLINE void SetMorphWeight(size_t index, float weight)                                { m_morphWeights[index] = weight; }
         MCORE_INLINE float GetMorphWeight(size_t index) const                                       { return m_morphWeights[index]; }
-        MCORE_INLINE size_t GetNumMorphWeights() const                                              { return m_morphWeights.GetLength(); }
+        MCORE_INLINE size_t GetNumMorphWeights() const                                              { return m_morphWeights.size(); }
         void ResizeNumMorphs(size_t numMorphTargets);
 
         /**
@@ -193,11 +193,11 @@ namespace EMotionFX
         T* GetAndPreparePoseData(ActorInstance* linkToActorInstance) { return azdynamic_cast(GetAndPreparePoseData(azrtti_typeid(), linkToActorInstance)); }
 
     private:
-        mutable MCore::AlignedArray  m_localSpaceTransforms;
-        mutable MCore::AlignedArray  m_modelSpaceTransforms;
-        mutable MCore::AlignedArray      m_flags;
+        mutable AZStd::vector  m_localSpaceTransforms;
+        mutable AZStd::vector  m_modelSpaceTransforms;
+        mutable AZStd::vector      m_flags;
         AZStd::unordered_map > m_poseDatas;
-        MCore::AlignedArray              m_morphWeights;      /**< The morph target weights. */
+        AZStd::vector              m_morphWeights;      /**< The morph target weights. */
         const ActorInstance*                        m_actorInstance;
         const Actor*                                m_actor;
         const Skeleton*                             m_skeleton;
diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/RenderPlugins/Source/OpenGLRender/GLWidget.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/RenderPlugins/Source/OpenGLRender/GLWidget.cpp
index 622dd6b566..be9d704727 100644
--- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/RenderPlugins/Source/OpenGLRender/GLWidget.cpp
+++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/RenderPlugins/Source/OpenGLRender/GLWidget.cpp
@@ -272,8 +272,7 @@ namespace EMStudio
                 fpsNumFrames    = 0;
             }
 
-            static AZStd::string perfTempString;
-            perfTempString = AZStd::string::format("%d FPS (%.1f ms)", lastFPS, renderTime);
+            const AZStd::string perfTempString = AZStd::string::format("%d FPS (%.1f ms)", lastFPS, renderTime);
 
             // initialize the painter and get the font metrics
             EMStudioManager::RenderText(painter, perfTempString.c_str(), QColor(150, 150, 150), m_font, *m_fontMetrics, Qt::AlignRight, QRect(width() - 55, height() - 20, 50, 20));
diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/GameController.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/GameController.cpp
index 4c32cdb0cc..ee3ca0ca7c 100644
--- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/GameController.cpp
+++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/GameController.cpp
@@ -12,6 +12,7 @@
 #if AZ_TRAIT_EMOTIONFX_HAS_GAME_CONTROLLER
 
 #include 
+#include 
 
 
 // joystick enum callback
@@ -20,7 +21,7 @@ BOOL CALLBACK GameController::EnumJoysticksCallback(const DIDEVICEINSTANCE* pdid
     GameController* manager = static_cast(pContext);
 
     // store the name
-    manager->m_deviceInfo.m_name = pdidInstance->tszProductName;
+    AZStd::to_string(manager->m_deviceInfo.m_name, pdidInstance->tszProductName);
 
     // Skip anything other than the perferred Joystick device as defined by the control panel.
     // Instead you could store all the enumerated Joysticks and let the user pick.
@@ -71,7 +72,7 @@ BOOL CALLBACK GameController::EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE*
 
     if (pdidoi->guidType == GUID_XAxis)
     {
-        manager->m_deviceElements[ ELEM_POS_X ].m_name                = pdidoi->tszName;
+        AZStd::to_string(manager->m_deviceElements[ ELEM_POS_X ].m_name, pdidoi->tszName);
         manager->m_deviceElements[ ELEM_POS_X ].m_present             = true;
         manager->m_deviceElements[ ELEM_POS_X ].m_value               = 0.0f;
         manager->m_deviceElements[ ELEM_POS_X ].m_type                = ELEMTYPE_AXIS;
@@ -80,7 +81,7 @@ BOOL CALLBACK GameController::EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE*
 
     if (pdidoi->guidType == GUID_YAxis)
     {
-        manager->m_deviceElements[ ELEM_POS_Y ].m_name                = pdidoi->tszName;
+        AZStd::to_string(manager->m_deviceElements[ ELEM_POS_Y ].m_name, pdidoi->tszName);
         manager->m_deviceElements[ ELEM_POS_Y ].m_present             = true;
         manager->m_deviceElements[ ELEM_POS_Y ].m_value               = 0.0f;
         manager->m_deviceElements[ ELEM_POS_Y ].m_type                = ELEMTYPE_AXIS;
@@ -89,7 +90,7 @@ BOOL CALLBACK GameController::EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE*
 
     if (pdidoi->guidType == GUID_ZAxis)
     {
-        manager->m_deviceElements[ ELEM_POS_Z ].m_name                = pdidoi->tszName;
+        AZStd::to_string(manager->m_deviceElements[ ELEM_POS_Z ].m_name, pdidoi->tszName);
         manager->m_deviceElements[ ELEM_POS_Z ].m_present             = true;
         manager->m_deviceElements[ ELEM_POS_Z ].m_value               = 0.0f;
         manager->m_deviceElements[ ELEM_POS_Z ].m_type                = ELEMTYPE_AXIS;
@@ -98,7 +99,7 @@ BOOL CALLBACK GameController::EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE*
 
     if (pdidoi->guidType == GUID_RxAxis)
     {
-        manager->m_deviceElements[ ELEM_ROT_X ].m_name                = pdidoi->tszName;
+        AZStd::to_string(manager->m_deviceElements[ ELEM_ROT_X ].m_name, pdidoi->tszName);
         manager->m_deviceElements[ ELEM_ROT_X ].m_present             = true;
         manager->m_deviceElements[ ELEM_ROT_X ].m_value               = 0.0f;
         manager->m_deviceElements[ ELEM_ROT_X ].m_type                = ELEMTYPE_AXIS;
@@ -107,7 +108,7 @@ BOOL CALLBACK GameController::EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE*
 
     if (pdidoi->guidType == GUID_RyAxis)
     {
-        manager->m_deviceElements[ ELEM_ROT_Y ].m_name                = pdidoi->tszName;
+        AZStd::to_string(manager->m_deviceElements[ ELEM_ROT_Y ].m_name, pdidoi->tszName);
         manager->m_deviceElements[ ELEM_ROT_Y ].m_present             = true;
         manager->m_deviceElements[ ELEM_ROT_Y ].m_value               = 0.0f;
         manager->m_deviceElements[ ELEM_ROT_Y ].m_type                = ELEMTYPE_AXIS;
@@ -116,7 +117,7 @@ BOOL CALLBACK GameController::EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE*
 
     if (pdidoi->guidType == GUID_RzAxis)
     {
-        manager->m_deviceElements[ ELEM_ROT_Z ].m_name                = pdidoi->tszName;
+        AZStd::to_string(manager->m_deviceElements[ ELEM_ROT_Z ].m_name, pdidoi->tszName);
         manager->m_deviceElements[ ELEM_ROT_Z ].m_present             = true;
         manager->m_deviceElements[ ELEM_ROT_Z ].m_value               = 0.0f;
         manager->m_deviceElements[ ELEM_ROT_Z ].m_type                = ELEMTYPE_AXIS;
@@ -128,14 +129,14 @@ BOOL CALLBACK GameController::EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE*
     {
         if (manager->m_deviceInfo.m_numSliders == 0)
         {
-            manager->m_deviceElements[ ELEM_SLIDER_1 ].m_name                 = pdidoi->tszName;
+            AZStd::to_string(manager->m_deviceElements[ ELEM_SLIDER_1 ].m_name, pdidoi->tszName);
             manager->m_deviceElements[ ELEM_SLIDER_1 ].m_present              = true;
             manager->m_deviceElements[ ELEM_SLIDER_1 ].m_value                = 0.0f;
             manager->m_deviceElements[ ELEM_SLIDER_1 ].m_type                 = ELEMTYPE_SLIDER;
         }
         else
         {
-            manager->m_deviceElements[ ELEM_SLIDER_2 ].m_name                 = pdidoi->tszName;
+            AZStd::to_string(manager->m_deviceElements[ ELEM_SLIDER_2 ].m_name, pdidoi->tszName);
             manager->m_deviceElements[ ELEM_SLIDER_2 ].m_present              = true;
             manager->m_deviceElements[ ELEM_SLIDER_2 ].m_value                = 0.0f;
             manager->m_deviceElements[ ELEM_SLIDER_2 ].m_type                 = ELEMTYPE_SLIDER;
@@ -148,7 +149,7 @@ BOOL CALLBACK GameController::EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE*
     if (pdidoi->guidType == GUID_POV)
     {
         const uint32 povIndex = manager->m_deviceInfo.m_numPoVs;
-        manager->m_deviceElements[ ELEM_POV_1 + povIndex ].m_name                 = pdidoi->tszName;
+        AZStd::to_string(manager->m_deviceElements[ ELEM_POV_1 + povIndex ].m_name, pdidoi->tszName);
         manager->m_deviceElements[ ELEM_POV_1 + povIndex ].m_present              = true;
         manager->m_deviceElements[ ELEM_POV_1 + povIndex ].m_value                = 0.0f;
         manager->m_deviceElements[ ELEM_POV_1 + povIndex ].m_type                 = ELEMTYPE_POV;
diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/MorphTargetsWindow/PhonemeSelectionWindow.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/MorphTargetsWindow/PhonemeSelectionWindow.cpp
index 4f1aa5b42b..a0d0e62abd 100644
--- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/MorphTargetsWindow/PhonemeSelectionWindow.cpp
+++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/MorphTargetsWindow/PhonemeSelectionWindow.cpp
@@ -330,7 +330,7 @@ namespace EMStudio
         const size_t numMorphTargets = m_morphSetup->GetNumMorphTargets();
         const uint32 numPhonemeSets  = m_morphTarget->GetNumAvailablePhonemeSets();
         int insertPosition = 0;
-        for (int i = 1; i < numPhonemeSets; ++i)
+        for (uint32 i = 1; i < numPhonemeSets; ++i)
         {
             // check if another morph target already has this phoneme set.
             bool phonemeSetFound = false;
diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeGroups/NodeGroupManagementWidget.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeGroups/NodeGroupManagementWidget.cpp
index 67aee6a5af..bd5a93a0ae 100644
--- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeGroups/NodeGroupManagementWidget.cpp
+++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeGroups/NodeGroupManagementWidget.cpp
@@ -262,11 +262,11 @@ namespace EMStudio
         m_clearButton->setDisabled(disableButtons);
 
         // set the row count
-        m_nodeGroupsTable->setRowCount(m_actor->GetNumNodeGroups());
+        m_nodeGroupsTable->setRowCount(aznumeric_caster(m_actor->GetNumNodeGroups()));
 
         // fill the table with the existing node groups
-        const uint32 numNodeGroups = m_actor->GetNumNodeGroups();
-        for (uint32 i = 0; i < numNodeGroups; ++i)
+        const size_t numNodeGroups = m_actor->GetNumNodeGroups();
+        for (size_t i = 0; i < numNodeGroups; ++i)
         {
             // get the nodegroup
             EMotionFX::NodeGroup* nodeGroup = m_actor->GetNodeGroup(i);
@@ -287,16 +287,16 @@ namespace EMStudio
 
             // create table items
             QTableWidgetItem* tableItemGroupName = new QTableWidgetItem(nodeGroup->GetName());
-            AZStd::string numGroupString = AZStd::string::format("%i", nodeGroup->GetNumNodes());
+            AZStd::string numGroupString = AZStd::string::format("%zu", nodeGroup->GetNumNodes());
             QTableWidgetItem* tableItemNumNodes = new QTableWidgetItem(numGroupString.c_str());
 
             // add items to the table
-            m_nodeGroupsTable->setCellWidget(i, 0, checkbox);
-            m_nodeGroupsTable->setItem(i, 1, tableItemGroupName);
-            m_nodeGroupsTable->setItem(i, 2, tableItemNumNodes);
+            m_nodeGroupsTable->setCellWidget(aznumeric_caster(i), 0, checkbox);
+            m_nodeGroupsTable->setItem(aznumeric_caster(i), 1, tableItemGroupName);
+            m_nodeGroupsTable->setItem(aznumeric_caster(i), 2, tableItemNumNodes);
 
             // set the row height
-            m_nodeGroupsTable->setRowHeight(i, 21);
+            m_nodeGroupsTable->setRowHeight(aznumeric_caster(i), 21);
         }
 
         // set the old selected row if any one
diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeGroups/NodeGroupWidget.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeGroups/NodeGroupWidget.cpp
index 7ce09a55d7..8a20070505 100644
--- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeGroups/NodeGroupWidget.cpp
+++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeGroups/NodeGroupWidget.cpp
@@ -150,17 +150,17 @@ namespace EMStudio
         m_removeNodesButton->setEnabled((m_nodeTable->rowCount() != 0) && (m_nodeTable->selectedItems().size() != 0));
 
         // clear the table widget
-        m_nodeTable->setRowCount(m_nodeGroup->GetNumNodes());
+        m_nodeTable->setRowCount(aznumeric_caster(m_nodeGroup->GetNumNodes()));
 
         // set header items for the table
-        AZStd::string headerText = AZStd::string::format("%s Nodes (%i / %zu)", ((m_nodeGroup->GetIsEnabledOnDefault()) ? "Enabled" : "Disabled"), m_nodeGroup->GetNumNodes(), m_actor->GetNumNodes());
+        AZStd::string headerText = AZStd::string::format("%s Nodes (%zu / %zu)", ((m_nodeGroup->GetIsEnabledOnDefault()) ? "Enabled" : "Disabled"), m_nodeGroup->GetNumNodes(), m_actor->GetNumNodes());
         QTableWidgetItem* nameHeaderItem = new QTableWidgetItem(headerText.c_str());
         nameHeaderItem->setTextAlignment(Qt::AlignVCenter | Qt::AlignCenter);
         m_nodeTable->setHorizontalHeaderItem(0, nameHeaderItem);
 
         // fill the table with content
-        const uint16 numNodes = m_nodeGroup->GetNumNodes();
-        for (uint16 i = 0; i < numNodes; ++i)
+        const size_t numNodes = m_nodeGroup->GetNumNodes();
+        for (size_t i = 0; i < numNodes; ++i)
         {
             // get the nodegroup
             EMotionFX::Node* node = m_actor->GetSkeleton()->GetNode(m_nodeGroup->GetNode(i));
@@ -173,10 +173,10 @@ namespace EMStudio
 
             // create table items
             QTableWidgetItem* tableItemNodeName = new QTableWidgetItem(node->GetName());
-            m_nodeTable->setItem(i, 0, tableItemNodeName);
+            m_nodeTable->setItem(aznumeric_caster(i), 0, tableItemNodeName);
 
             // set the row height
-            m_nodeTable->setRowHeight(i, 21);
+            m_nodeTable->setRowHeight(aznumeric_caster(i), 21);
         }
 
         // resize to contents and adjust header
@@ -257,11 +257,9 @@ namespace EMStudio
         m_nodeSelectionList.Clear();
         if (senderWidget == m_selectNodesButton)
         {
-            MCore::SmallArray&  nodes       = m_nodeGroup->GetNodeArray();
-            const uint16                numNodes    = nodes.GetLength();
-            for (uint16 i = 0; i < numNodes; ++i)
+            for (const uint16 i : m_nodeGroup->GetNodeArray())
             {
-                EMotionFX::Node* node = m_actor->GetSkeleton()->GetNode(nodes[i]);
+                EMotionFX::Node* node = m_actor->GetSkeleton()->GetNode(i);
                 m_nodeSelectionList.AddNode(node);
             }
         }
diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeWindow/ActorInfo.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeWindow/ActorInfo.cpp
index 6bd00a2b94..9936410231 100644
--- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeWindow/ActorInfo.cpp
+++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeWindow/ActorInfo.cpp
@@ -32,9 +32,9 @@ namespace EMStudio
         m_nodeCount = actor->GetNumNodes();
 
         // node groups
-        const uint32 numNodeGroups = actor->GetNumNodeGroups();
+        const size_t numNodeGroups = actor->GetNumNodeGroups();
         m_nodeGroups.reserve(numNodeGroups);
-        for (uint32 i = 0; i < numNodeGroups; ++i)
+        for (size_t i = 0; i < numNodeGroups; ++i)
         {
             m_nodeGroups.emplace_back(actor, actor->GetNodeGroup(i));
         }
diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeWindow/NodeGroupInfo.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeWindow/NodeGroupInfo.cpp
index 07a31f4402..f25158ae0d 100644
--- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeWindow/NodeGroupInfo.cpp
+++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeWindow/NodeGroupInfo.cpp
@@ -23,8 +23,8 @@ namespace EMStudio
         m_name = nodeGroup->GetNameString();
 
         // iterate over the nodes inside the node group
-        const uint32 numGroupNodes = nodeGroup->GetNumNodes();
-        for (uint32 j = 0; j < numGroupNodes; ++j)
+        const size_t numGroupNodes = nodeGroup->GetNumNodes();
+        for (size_t j = 0; j < numGroupNodes; ++j)
         {
             const uint16 nodeIndex = nodeGroup->GetNode(j);
             const EMotionFX::Node* node = actor->GetSkeleton()->GetNode(nodeIndex);
diff --git a/Gems/EMotionFX/Code/MCore/Source/AlignedArray.h b/Gems/EMotionFX/Code/MCore/Source/AlignedArray.h
deleted file mode 100644
index 5ffaac2e40..0000000000
--- a/Gems/EMotionFX/Code/MCore/Source/AlignedArray.h
+++ /dev/null
@@ -1,783 +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
- *
- */
-
-#pragma once
-
-#include "StandardHeaders.h"
-#include "MCoreSystem.h"
-#include "Algorithms.h"
-#include "MemoryManager.h"
-
-
-namespace MCore
-{
-    /**
-     * Dynamic array template, using aligned memory allocations.
-     * This array template allows dynamic sizing. It also stores the memory category of the data.
-     * It can theoretically store 18446744073709551614 items (maximum size_t value - 1 for the invalid index).
-     */
-    template 
-    class AlignedArray
-    {
-    public:
-        /**
-         * The memory block ID, used inside the memory manager.
-         * This will make all arrays remain in the same memory blocks, which is more efficient in a lot of cases.
-         * However, array data can still remain in other blocks.
-         */
-        enum
-        {
-            MEMORYBLOCK_ID = 3
-        };
-
-        /**
-         * Default constructor.
-         * Initializes the array so it's empty and has no memory allocated.
-         */
-        MCORE_INLINE AlignedArray()
-            : m_data(nullptr)
-            , m_length(0)
-            , m_maxLength(0)
-            , m_memCategory(MCORE_MEMCATEGORY_ARRAY)              {}
-
-        /**
-         * Constructor which creates a given number of elements.
-         * @param elems The element data.
-         * @param num The number of elements in 'elems'.
-         * @param memCategory The memory category the array is in.
-         */
-        MCORE_INLINE explicit AlignedArray(T* elems, size_t num, uint16 memCategory = MCORE_MEMCATEGORY_ARRAY)
-            : m_length(num)
-            , m_maxLength(AllocSize(num))
-            , m_memCategory(memCategory)
-        {
-            m_data = (T*)AlignedAllocate(m_maxLength * sizeof(T), alignment, m_memCategory, MEMORYBLOCK_ID, MCORE_FILE, MCORE_LINE);
-            for (size_t i = 0; i < m_length; ++i)
-            {
-                Construct(i, elems[i]);
-            }
-        }
-
-        /**
-         * Constructor which initializes the length of the array on a given number.
-         * @param initSize The number of ellements to allocate space for.
-         * @param memCategory The memory category the array is in.
-         */
-        MCORE_INLINE explicit AlignedArray(size_t initSize, uint16 memCategory = MCORE_MEMCATEGORY_ARRAY)
-            : m_data(nullptr)
-            , m_length(initSize)
-            , m_maxLength(initSize)
-            , m_memCategory(memCategory)
-        {
-            if (m_maxLength > 0)
-            {
-                m_data = (T*)AlignedAllocate(m_maxLength * sizeof(T), alignment, m_memCategory, MEMORYBLOCK_ID, MCORE_FILE, MCORE_LINE);
-                for (size_t i = 0; i < m_length; ++i)
-                {
-                    Construct(i);
-                }
-            }
-        }
-
-        /**
-         * Copy constructor.
-         * @param other The other array to copy the data from.
-         */
-        AlignedArray(const AlignedArray& other)
-            : m_data(nullptr)
-            , m_length(0)
-            , m_maxLength(0)
-            , m_memCategory(MCORE_MEMCATEGORY_ARRAY)              { *this = other; }
-
-        /**
-         * Move constructor.
-         * @param other The array to move the data from.
-         */
-        AlignedArray(AlignedArray&& other)                                                                { m_data = other.m_data; m_length = other.m_length; m_maxLength = other.m_maxLength; m_memCategory = other.m_memCategory; other.m_data = nullptr; other.m_length = 0; other.m_maxLength = 0; }
-
-        /**
-         * Destructor. Deletes all entry data.
-         * However, if you store pointers to objects, these objects won't be deleted.
- * Example:
- *
-         * AlignedArray< Object*, 16 > data;
-         * for (size_t i=0; i<10; i++)
-         *    data.Add( new Object() );
-         * 
- * Now when the array 'data' will be destructed, it will NOT free up the memory of the integers which you allocated by hand, using new. - * In order to free up this memory, you can do this: - *
-         * for (size_t i=0; i
-         */
-        ~AlignedArray()
-        {
-            for (size_t i = 0; i < m_length; ++i)
-            {
-                Destruct(i);
-            }
-            if (m_data)
-            {
-                AlignedFree(m_data);
-            }
-        }
-
-        /**
-         * Get the memory category ID where allocations made by this array belong to.
-         * On default the memory category is 0, which means unknown.
-         * @result The memory category ID.
-         */
-        MCORE_INLINE uint16 GetMemoryCategory() const                           { return m_memCategory; }
-
-        /**
-         * Set the memory category ID, where allocations made by this array will belong to.
-         * On default, after construction of the array, the category ID is 0, which means it is unknown.
-         * @param categoryID The memory category ID where this arrays allocations belong to.
-         */
-        MCORE_INLINE void SetMemoryCategory(uint16 categoryID)                  { m_memCategory = categoryID; }
-
-        /**
-         * Get a pointer to the first element.
-         * @result A pointer to the first element.
-         */
-        MCORE_INLINE T* GetPtr()                                                { return m_data; }
-
-        /**
-         * Get a pointer to the first element.
-         * @result A pointer to the first element.
-         */
-        MCORE_INLINE T* GetPtr() const                                          { return m_data; }
-
-        /**
-         * Get a given item/element.
-         * @param pos The item/element number.
-         * @result A reference to the element.
-         */
-        MCORE_INLINE T& GetItem(size_t pos)                                     { return m_data[pos]; }
-
-        /**
-         * Get the first element.
-         * @result A reference to the first element.
-         */
-        MCORE_INLINE T& GetFirst()                                              { return m_data[0]; }
-
-        /**
-         * Get the last element.
-         * @result A reference to the last element.
-         */
-        MCORE_INLINE T& GetLast()                                               { return m_data[m_length - 1]; }
-
-        /**
-         * Get a read-only pointer to the first element.
-         * @result A read-only pointer to the first element.
-         */
-        MCORE_INLINE const T* GetReadPtr() const                                { return m_data; }
-
-        /**
-         * Get a read-only reference to a given element number.
-         * @param pos The element number.
-         * @result A read-only reference to the given element.
-         */
-        MCORE_INLINE const T& GetItem(size_t pos) const                         { return m_data[pos]; }
-
-        /**
-         * Get a read-only reference to the first element.
-         * @result A read-only reference to the first element.
-         */
-        MCORE_INLINE const T& GetFirst() const                                  { return m_data[0]; }
-
-        /**
-         * Get a read-only reference to the last element.
-         * @result A read-only reference to the last element.
-         */
-        MCORE_INLINE const T& GetLast() const                                   { return m_data[m_length - 1]; }
-
-        /**
-         * Check if the array is empty or not.
-         * @result Returns true when there are no elements in the array, otherwise false is returned.
-         */
-        MCORE_INLINE bool GetIsEmpty() const                                    { return (m_length == 0); }
-
-        /**
-         * Checks if the passed index is in the array's range.
-         * @param index The index to check.
-         * @return True if the passed index is valid, false if not.
-         */
-        MCORE_INLINE bool GetIsValidIndex(size_t index) const                   { return (index < m_length); }
-
-        /**
-         * Get the number of elements in the array.
-         * @result The number of elements in the array.
-         */
-        MCORE_INLINE size_t GetLength() const                                   { return m_length; }
-
-        /**
-         * Get the maximum number of elements. This is the number of elements there currently is space for to store.
-         * However, never use this to make for-loops to iterate through all elements. Use GetLength() instead for that.
-         * This purely has to do with pre-allocating, to reduce the number of reallocs.
-         * @result The maximum array length.
-         */
-        MCORE_INLINE size_t GetMaxLength() const                                { return m_maxLength; }
-
-        /**
-         * Calculates the memory usage used by this array.
-         * @param includeMembers Include the class members in the calculation? (default=true).
-         * @result The number of bytes allocated by this array.
-         */
-        MCORE_INLINE size_t CalcMemoryUsage(bool includeMembers = true) const
-        {
-            size_t result = m_maxLength * sizeof(T);
-            if (includeMembers)
-            {
-                result += sizeof(AlignedArray);
-            }
-            return result;
-        }
-
-        /**
-         * Set a given element to a given value.
-         * @param pos The element number.
-         * @param value The value to store at that element number.
-         */
-        MCORE_INLINE void SetElem(size_t pos, const T& value)                   { m_data[pos] = value; }
-
-        /**
-         * Add a given element to the back of the array.
-         * @param x The element to add.
-         */
-        MCORE_INLINE void Add(const T& x)                                       { Grow(++m_length); Construct(m_length - 1, x); }
-
-        /**
-         * Add a given element to the back of the array, but without pre-allocation caching.
-         * @param x The element to add.
-         */
-        MCORE_INLINE void AddExact(const T& x)                                  { GrowExact(++m_length); Construct(m_length - 1, x); }
-
-        /**
-         * Add a given array to the back of this array.
-         * @param a The array to add.
-         */
-        MCORE_INLINE void Add(const AlignedArray& a)
-        {
-            size_t l = m_length;
-            Grow(m_length + a.m_length);
-            for (size_t i = 0; i < a.GetLength(); ++i)
-            {
-                Construct(l + i, a[i]);
-            }
-        }                                                                                                                                                                                   // TODO: a.GetLength() can be precaled before loop?
-
-        /**
-         * Add an empty (default constructed) element to the back of the array.
-         */
-        MCORE_INLINE void AddEmpty()                                            { Grow(++m_length); Construct(m_length - 1); }
-
-        /**
-         * Add an empty (default constructed) element to the back of the array, but without pre-allocation caching.
-         */
-        MCORE_INLINE void AddEmptyExact()                                       { GrowExact(++m_length); Construct(m_length - 1); }
-
-        /**
-         * Remove the first array element.
-         */
-        MCORE_INLINE void RemoveFirst()
-        {
-            if (m_length > 0)
-            {
-                Remove(0);
-            }
-        }
-
-        /**
-         * Remove the last array element.
-         */
-        MCORE_INLINE void RemoveLast()
-        {
-            if (m_length > 0)
-            {
-                Destruct(--m_length);
-            }
-        }
-
-        /**
-         * Insert an empty element (default constructed) at a given position in the array.
-         * @param pos The position to create the empty element.
-         */
-        MCORE_INLINE void Insert(size_t pos)                                    { Grow(m_length + 1); MoveElements(pos + 1, pos, m_length - pos - 1); Construct(pos); }
-
-        /**
-         * Insert a given element at a given position in the array.
-         * @param pos The position to insert the empty element.
-         * @param x The element to store at this position.
-         */
-        MCORE_INLINE void Insert(size_t pos, const T& x)                        { Grow(m_length + 1); MoveElements(pos + 1, pos, m_length - pos - 1); Construct(pos, x); }
-
-        /**
-         * Remove an element at a given position.
-         * @param pos The element number to remove.
-         */
-        MCORE_INLINE void Remove(size_t pos)
-        {
-            Destruct(pos);
-            if (m_length > 1)
-            {
-                MoveElements(pos, pos + 1, m_length - pos - 1);
-            }
-            m_length--;
-        }
-
-        /**
-         * Remove a given number of elements starting at a given position in the array.
-         * @param pos The start element, so to start removing from.
-         * @param num The number of elements to remove from this position.
-         */
-        MCORE_INLINE void Remove(size_t pos, size_t num)
-        {
-            for (size_t i = pos; i < pos + num; ++i)
-            {
-                Destruct(i);
-            }
-            MoveElements(pos, pos + num, m_length - pos - num);
-            m_length -= num;
-        }
-
-        /**
-         * Remove a given element with a given value.
-         * Only the first element with the given value will be removed.
-         * @param item The item/element to remove.
-         */
-        MCORE_INLINE bool RemoveByValue(const T& item)
-        {
-            size_t index = Find(item);
-            if (index == InvalidIndex)
-            {
-                return false;
-            }
-            Remove(index);
-            return true;
-        }
-
-        /**
-         * Remove a given element in the array and place the last element in the array at the created empty position.
-         * So if we have an array with the following characters : ABCDEFG
- * And we perform a SwapRemove(2), we will remove element C and place the last element (G) at the empty created position where C was located. - * So we will get this:
- * AB.DEFG [where . is empty, after we did the SwapRemove(2)]
- * ABGDEF [this is the result. G has been moved to the empty position]. - */ - MCORE_INLINE void SwapRemove(size_t pos) - { - Destruct(pos); - if (pos != m_length - 1) - { - Construct(pos, m_data[m_length - 1]); - Destruct(m_length - 1); - } - m_length--; - } // remove element at and place the last element of the array in that position - - /** - * Swap two elements. - * @param pos1 The first element number. - * @param pos2 The second element number. - */ - MCORE_INLINE void Swap(size_t pos1, size_t pos2) - { - if (pos1 != pos2) - { - Swap(GetItem(pos1), GetItem(pos2)); - } - } - - /** - * Clear the array contents. So GetLength() will return 0 after performing this method. - * @param clearMem If set to true (default) the allocated memory will also be released. If set to false, GetMaxLength() will still return the number of elements - * which the array contained before calling the Clear() method. - */ - MCORE_INLINE void Clear(bool clearMem = true) - { - for (size_t i = 0; i < m_length; ++i) - { - Destruct(i); - } - m_length = 0; - if (clearMem) - { - this->Free(); - } - } - - /** - * Make sure the array has enough space to store a given number of elements. - * @param newLength The number of elements we want to make sure that will fit in the array. - */ - MCORE_INLINE void AssureSize(size_t newLength) - { - if (m_length >= newLength) - { - return; - } - size_t oldLen = m_length; - Grow(newLength); - for (size_t i = oldLen; i < newLength; ++i) - { - Construct(i); - } - } - - /** - * Make sure this array has enough allocated storage to grow to a given number of elements elements without having to realloc. - * @param minLength The minimum length the array should have (actually the minimum maxLength, because this has no influence on what GetLength() will return). - */ - MCORE_INLINE void Reserve(size_t minLength) - { - if (m_maxLength < minLength) - { - Realloc(minLength); - } - } - - /** - * Make the array as small as possible. So remove all extra pre-allocated data, so that the array consumes the least possible amount of memory. - */ - MCORE_INLINE void Shrink() - { - if (m_length == m_maxLength) - { - return; - } - MCORE_ASSERT(m_maxLength >= m_length); - Realloc(m_length); - } - - /** - * Check if the array contains a given element. - * @param x The element to check. - * @result Returns true when the array contains the element, otherwise false is returned. - */ - MCORE_INLINE bool Contains(const T& x) const { return (Find(x) != InvalidIndex); } - - /** - * Find the position of a given element. - * @param x The element to find. - * @result Returns the index in the array, ranging from [0 to GetLength()-1] when found, otherwise InvalidIndex is returned. - */ - MCORE_INLINE size_t Find(const T& x) const - { - for (size_t i = 0; i < m_length; ++i) - { - if (m_data[i] == x) - { - return i; - } - } - return InvalidIndex; - } - - /** - * Copy the contents of another array into this one using a direct memory copy. - * This does not call copy constructors of the objects, but just copies the raw memory data. - * This resizes this array to be the exact length of the array we will copy the data from. - * @param other The array to copy the data from. - */ - MCORE_INLINE void MemCopyContentsFrom(const AlignedArray& other) { Resize(other.GetLength()); MemCopy((uint8*)m_data, (uint8*)other.m_data, sizeof(T) * other.m_length); } - - // sort function and standard sort function - typedef int32 (MCORE_CDECL * CmpFunc)(const T& itemA, const T& itemB); - static int32 MCORE_CDECL StdCmp(const T& itemA, const T& itemB) - { - if (itemA < itemB) - { - return -1; - } - else if (itemA == itemB) - { - return 0; - } - else - { - return 1; - } - } - static int32 MCORE_CDECL StdPtrObjCmp(const T& itemA, const T& itemB) - { - if (*itemA < *itemB) - { - return -1; - } - else if (*itemA == *itemB) - { - return 0; - } - else - { - return 1; - } - } - - /** - * Sort the complete array using a given sort function. - * @param cmp The sort function to use. - */ - MCORE_INLINE void Sort(CmpFunc cmp) { InnerSort(0, m_length - 1, cmp); } - - /** - * Sort a given part of the array using a given sort function. - * The default parameters are set so that it will sort the compelete array with a default compare function (which uses the < and > operators). - * The method will sort all elements between the given 'first' and 'last' element (first and last are also included in the sort). - * @param first The first element to start sorting. - * @param last The last element to sort (when set to InvalidIndex, GetLength()-1 will be used). - * @param cmp The compare function. - */ - MCORE_INLINE void Sort(size_t first = 0, size_t last = InvalidIndex, CmpFunc cmp = StdCmp) - { - if (last == InvalidIndex) - { - last = m_length - 1; - } - InnerSort(first, last, cmp); - } - - /** - * Performs a sort on a given part of the array. - * @param first The first element to start the sorting at. - * @param last The last element to end the sorting. - * @param cmp The compare function. - */ - MCORE_INLINE void InnerSort(int32 first, int32 last, CmpFunc cmp) - { - if (first >= last) - { - return; - } - int32 split = Partition(first, last, cmp); - InnerSort(first, split - 1, cmp); - InnerSort(split + 1, last, cmp); - } - - // resize in a fast way that doesn't call constructors or destructors - void ResizeFast(size_t newLength) - { - if (m_length == newLength) - { - return; - } - - if (newLength > m_length) - { - GrowExact(newLength); - } - - m_length = newLength; - } - - /** - * Resize the array to a given size. - * This does not mean an actual realloc will be made. This will only happen when the new length is bigger than the maxLength of the array. - * @param newLength The new length the array should be. - */ - void Resize(size_t newLength) - { - if (m_length == newLength) - { - return; - } - - // check for growing or shrinking array - if (newLength > m_length) - { - // growing array, construct empty elements at end of array - const size_t oldLen = m_length; - GrowExact(newLength); - for (size_t i = oldLen; i < newLength; ++i) - { - Construct(i); - } - } - else - { - // shrinking array, destruct elements at end of array - for (size_t i = newLength; i < m_length; ++i) - { - Destruct(i); - } - - m_length = newLength; - } - } - - /** - * Move "numElements" elements starting from the source index, to the dest index. - * Please note thate the array has to be large enough. You can't move data past the end of the array. - * @param destIndex The destination index. - * @param sourceIndex The source index, where the source elements start. - * @param numElements The number of elements to move. - */ - MCORE_INLINE void MoveElements(size_t destIndex, size_t sourceIndex, size_t numElements) - { - if (numElements > 0) - { - MemMove(m_data + destIndex, m_data + sourceIndex, numElements * sizeof(T)); - } - } - - // operators - bool operator==(const AlignedArray& other) const - { - if (m_length != other.m_length) - { - return false; - } - for (size_t i = 0; i < m_length; ++i) - { - if (m_data[i] != other.m_data[i]) - { - return false; - } - } - return true; - } - AlignedArray& operator= (const AlignedArray& other) - { - if (&other != this) - { - Clear(false); - m_memCategory = other.m_memCategory; - Grow(other.m_length); - for (size_t i = 0; i < m_length; ++i) - { - Construct(i, other.m_data[i]); - } - } - return *this; - } - AlignedArray& operator= (AlignedArray&& other) - { - MCORE_ASSERT(&other != this); - if (m_data) - { - AlignedFree(m_data); - } - m_data = other.m_data; - m_memCategory = other.m_memCategory; - m_length = other.m_length; - m_maxLength = other.m_maxLength; - other.m_data = nullptr; - other.m_length = 0; - other.m_maxLength = 0; - return *this; - } - AlignedArray& operator+=(const T& other) { Add(other); return *this; } - AlignedArray& operator+=(const AlignedArray& other) { Add(other); return *this; } - MCORE_INLINE T& operator[](size_t index) { MCORE_ASSERT(index < m_length); return m_data[index]; } - MCORE_INLINE const T& operator[](size_t index) const { MCORE_ASSERT(index < m_length); return m_data[index]; } - - private: - T* m_data; /**< The element data. */ - size_t m_length; /**< The number of used elements in the array. */ - size_t m_maxLength; /**< The number of elements that we have allocated memory for. */ - uint16 m_memCategory; /**< The memory category ID. */ - - // private functions - MCORE_INLINE void Grow(size_t newLength) - { - m_length = newLength; - if (m_maxLength >= newLength) - { - return; - } - Realloc(AllocSize(newLength)); - } - MCORE_INLINE void GrowExact(size_t newLength) - { - m_length = newLength; - if (m_maxLength < newLength) - { - Realloc(newLength); - } - } - MCORE_INLINE size_t AllocSize(size_t num) { return 1 + num /*+num/8*/; } - MCORE_INLINE void Alloc(size_t num) { m_data = (T*)AlignedAllocate(num * sizeof(T), alignment, m_memCategory, MEMORYBLOCK_ID, MCORE_FILE, MCORE_LINE); } - MCORE_INLINE void Realloc(size_t newSize) - { - if (newSize == 0) - { - this->Free(); - return; - } - if (m_data) - { - m_data = (T*)AlignedRealloc(m_data, newSize * sizeof(T), m_maxLength * sizeof(T), alignment, m_memCategory, MEMORYBLOCK_ID, MCORE_FILE, MCORE_LINE); - } - else - { - m_data = (T*)AlignedAllocate(newSize * sizeof(T), alignment, m_memCategory, MEMORYBLOCK_ID, MCORE_FILE, MCORE_LINE); - } - - m_maxLength = newSize; - } - void Free() - { - m_length = 0; - m_maxLength = 0; - if (m_data) - { - AlignedFree(m_data); - m_data = nullptr; - } - } - MCORE_INLINE void Construct(size_t index, const T& original) { ::new(m_data + index)T(original); } // copy-construct an element at which is a copy of - MCORE_INLINE void Construct(size_t index) { ::new(m_data + index)T; } // construct an element at place - MCORE_INLINE void Destruct(size_t index) - { - #if (MCORE_COMPILER == MCORE_COMPILER_MSVC) - MCORE_UNUSED(index); // work around an MSVC compiler bug, where it triggers a warning that parameter 'index' is unused - #endif - (m_data + index)->~T(); - } - - // partition part of array (for sorting) - int32 Partition(int32 left, int32 right, CmpFunc cmp) - { - ::MCore::Swap(m_data[left], m_data[ (left + right) >> 1 ]); - - T& target = m_data[right]; - int32 i = left - 1; - int32 j = right; - - bool neverQuit = true; // workaround to disable a "warning C4127: conditional expression is constant" - while (neverQuit) - { - while (i < j) - { - if (cmp(m_data[++i], target) >= 0) - { - break; - } - } - while (j > i) - { - if (cmp(m_data[--j], target) <= 0) - { - break; - } - } - if (i >= j) - { - break; - } - ::MCore::Swap(m_data[i], m_data[j]); - } - - ::MCore::Swap(m_data[i], m_data[right]); - return i; - } - }; -} // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/SmallArray.h b/Gems/EMotionFX/Code/MCore/Source/SmallArray.h deleted file mode 100644 index ab94cabbfe..0000000000 --- a/Gems/EMotionFX/Code/MCore/Source/SmallArray.h +++ /dev/null @@ -1,414 +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 - * - */ - -#pragma once - -#include "StandardHeaders.h" -#include "MCoreSystem.h" -#include "Algorithms.h" -#include "MemoryManager.h" - - -namespace MCore -{ - -/** - * Dynamic array template with a maximum of 65536 items. - * It also doesn't store a memory category and maximum number of elements like the MCore::Array template. - */ -template -class SmallArray -{ - public: - /** - * The memory block ID, used inside the memory manager. - * This will make all arrays remain in the same memory blocks, which is more efficient in a lot of cases. - * However, array data can still remain in other blocks. - */ - enum { MEMORYBLOCK_ID = 2 }; - - /** - * Default constructor. - * Initializes the array so it's empty and has no memory allocated. - */ - MCORE_INLINE SmallArray() : m_data(nullptr), m_length(0) {} - - /** - * Constructor which creates a given number of elements. - * @param elems The element data. - * @param num The number of elements in 'elems'. - */ - MCORE_INLINE explicit SmallArray(T* elems, uint32 num) : m_length(num) { m_data = (T*)MCore::Allocate(m_length * sizeof(T), MCORE_MEMCATEGORY_SMALLARRAY, MEMORYBLOCK_ID, MCORE_FILE, MCORE_LINE); for (uint32 i=0; i 0) { m_data = (T*)MCore::Allocate(m_length * sizeof(T), MCORE_MEMCATEGORY_SMALLARRAY, MEMORYBLOCK_ID, MCORE_FILE, MCORE_LINE); for (uint32 i=0; i& other) : m_data(nullptr), m_length(0) { *this = other; } - - /** - * Move constructor. - * @param other The array to move the data from. - */ - SmallArray(SmallArray&& other) { m_data=other.m_data; m_length=other.m_length; other.m_data=nullptr; other.m_length=0; } - - /** - * Destructor. Deletes all entry data. - * However, if you store pointers to objects, these objects won't be deleted.
- * Example:
- *
-         * SmallArray< Object* > data;
-         * for (uint32 i=0; i<10; i++)
-         *    data.Add( new Object() );
-         * 
- * Now when the array 'data' will be destructed, it will NOT free up the memory of the integers which you allocated by hand, using new. - * In order to free up this memory, you can do this: - *
-         * for (uint32 i=0; i
-         */
-        ~SmallArray()                                                            { for (uint32 i=0; i); return result; }
-
-        /**
-         * Set a given element to a given value.
-         * @param pos The element number.
-         * @param value The value to store at that element number.
-         */
-        MCORE_INLINE void SetElem(uint32 pos, const T& value)                    { m_data[pos] = value; }
-
-        /**
-         * Add a given element to the back of the array.
-         * @param x The element to add.
-         */
-        MCORE_INLINE void Add(const T& x)                                        { Grow(++m_length); Construct(m_length-1, x); }
-
-        /**
-         * Add a given array to the back of this array.
-         * @param a The array to add.
-         */
-        MCORE_INLINE void Add(const SmallArray& a)                            { uint32 l=m_length; Grow(m_length+a.m_length); for (uint32 i=0; i 0) Remove((uint32)0); }
-
-        /**
-         * Remove the last array element.
-         */
-        MCORE_INLINE void RemoveLast()                                            { if (m_length > 0) Destruct(--m_length); }
-
-        /**
-         * Insert an empty element (default constructed) at a given position in the array.
-         * @param pos The position to create the empty element.
-         */
-        MCORE_INLINE void Insert(uint32 pos)                                    { Grow(m_length+1); MoveElements(pos+1, pos, m_length-pos-1); Construct(pos); }
-
-        /**
-         * Insert a given element at a given position in the array.
-         * @param pos The position to insert the empty element.
-         * @param x The element to store at this position.
-         */
-        MCORE_INLINE void Insert(uint32 pos, const T& x)                        { Grow(m_length+1); MoveElements(pos+1, pos, m_length-pos-1); Construct(pos, x); }
-
-        /**
-         * Remove an element at a given position.
-         * @param pos The element number to remove.
-         */
-        MCORE_INLINE void Remove(uint32 pos)                                    { Destruct(pos); MoveElements(pos, pos+1, m_length-pos-1); m_length--; }
-
-        /**
-         * Remove a given number of elements starting at a given position in the array.
-         * @param pos The start element, so to start removing from.
-         * @param num The number of elements to remove from this position.
-         */
-        MCORE_INLINE void Remove(uint32 pos, uint32 num)                        { for (uint32 i=pos; i
-         * And we perform a SwapRemove(2), we will remove element C and place the last element (G) at the empty created position where C was located.
-         * So we will get this:
- * AB.DEFG [where . is empty, after we did the SwapRemove(2)]
- * ABGDEF [this is the result. G has been moved to the empty position]. - */ - MCORE_INLINE void SwapRemove(uint32 pos) { Destruct(pos); if (pos != m_length-1) { Construct(pos, m_data[m_length-1]); Destruct(m_length-1); } m_length--; } // remove element at and place the last element of the array in that position - - /** - * Swap two elements. - * @param pos1 The first element number. - * @param pos2 The second element number. - */ - MCORE_INLINE void Swap(uint32 pos1, uint32 pos2) { if (pos1 != pos2) MCore::Swap(GetItem(pos1), GetItem(pos2)); } - - /** - * Clear the array contents. So GetLength() will return 0 after performing this method. - * @param clearMem If set to true (default) the allocated memory will also be released. If set to false, GetMaxLength() will still return the number of elements - * which the array contained before calling the Clear() method. - */ - MCORE_INLINE void Clear(bool clearMem=true) { for (uint32 i=0; i= newLength) return; uint32 oldLen=m_length; Grow(newLength); for (uint32 i=oldLen; i operators). - * The method will sort all elements between the given 'first' and 'last' element (first and last are also included in the sort). - * @param first The first element to start sorting. - * @param last The last element to sort (when set to MCORE_INVALIDINDEX32, GetLength()-1 will be used). - * @param cmp The compare function. - */ - MCORE_INLINE void Sort(uint32 first=0, uint32 last=MCORE_INVALIDINDEX32, CmpFunc cmp=StdCmp) { if (last==MCORE_INVALIDINDEX32) last=m_length-1; InnerSort(first, last, cmp); } - - /** - * Performs a sort on a given part of the array. - * @param first The first element to start the sorting at. - * @param last The last element to end the sorting. - * @param cmp The compare function. - */ - MCORE_INLINE void InnerSort(int32 first, int32 last, CmpFunc cmp) { if (first >= last) return; int32 split=Partition(first, last, cmp); InnerSort(first, split-1, cmp); InnerSort(split+1, last, cmp); } - - /** - * Resize the array to a given size. - * This does not mean an actual realloc will be made. This will only happen when the new length is bigger than the maxLength of the array. - * @param newLength The new length the array should be. - * @result returns false if the allocation/reallocation of the array failed - */ - bool Resize(uint32 newLength) - { - // check for growing or shrinking array - if (newLength > m_length) - { - // growing array, construct empty elements at end of array - uint32 oldLen = m_length; - GrowExact(newLength); - if (m_data == nullptr) - { - return false; - } - for (uint32 i=oldLen; i 0) - MCore::MemMove(m_data+destIndex, m_data+sourceIndex, numElements * sizeof(T)); - } - - // operators - bool operator==(const SmallArray& other) const { if (m_length != other.m_length) return false; for (uint32 i=0; i& operator= (const SmallArray& other) { if (&other != this) { Clear(); Grow(other.m_length); for (uint32 i=0; i& operator= (SmallArray&& other) { MCORE_ASSERT(&other != this); if (m_data!=nullptr) MCore::Free(m_data); m_data=other.m_data; m_length=other.m_length; other.m_data=nullptr; other.m_length=0; return *this; } - SmallArray& operator+=(const T& other) { Add(other); return *this; } - SmallArray& operator+=(const SmallArray& other) { Add(other); return *this; } - MCORE_INLINE T& operator[](const uint32 index) { MCORE_ASSERT(indexFree(); return; } - if (m_data) - m_data = (T*)MCore::Realloc(m_data, newSize * sizeof(T), MCORE_MEMCATEGORY_SMALLARRAY, MEMORYBLOCK_ID, MCORE_FILE, MCORE_LINE); - else - m_data = (T*)MCore::Allocate(newSize * sizeof(T), MCORE_MEMCATEGORY_SMALLARRAY, MEMORYBLOCK_ID, MCORE_FILE, MCORE_LINE); - } - MCORE_INLINE void Free() { m_length=0; if (m_data) MCore::Free(m_data); m_data=nullptr; } - MCORE_INLINE void Construct(uint32 index, const T& original) { ::new(m_data+index) T(original); } // copy-construct an element at which is a copy of - MCORE_INLINE void Construct(uint32 index) { ::new(m_data+index) T; } // construct an element at place - MCORE_INLINE void Destruct(uint32 index) - { - #if (MCORE_COMPILER == MCORE_COMPILER_MSVC) // work around a compiler bug, marking this index parameter as unused - MCORE_UNUSED(index); - #endif - (m_data+index)->~T(); - } // destruct an element at - - // partition part of array (for sorting) - int32 Partition(int32 left, int32 right, CmpFunc cmp) - { - ::MCore::Swap(m_data[left], m_data[ (left+right)>>1 ]); - - T& target = m_data[right]; - int32 i = left-1; - int32 j = right; - - bool neverQuit = true; // workaround to disable a "warning C4127: conditional expression is constant" - while (neverQuit) - { - while (i < j) { if (cmp(m_data[++i], target) >= 0) break; } - while (j > i) { if (cmp(m_data[--j], target) <= 0) break; } - if (i >= j) break; - ::MCore::Swap(m_data[i], m_data[j]); - } - - ::MCore::Swap(m_data[i], m_data[right]); - return i; - } -}; - -} // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/mcore_files.cmake b/Gems/EMotionFX/Code/MCore/mcore_files.cmake index 47b35e004b..fd4eeb23c4 100644 --- a/Gems/EMotionFX/Code/MCore/mcore_files.cmake +++ b/Gems/EMotionFX/Code/MCore/mcore_files.cmake @@ -11,7 +11,6 @@ set(FILES Source/Algorithms.cpp Source/Algorithms.h Source/Algorithms.inl - Source/AlignedArray.h Source/Array2D.h Source/Array2D.inl Source/Attribute.cpp @@ -106,7 +105,6 @@ set(FILES Source/StaticAllocator.cpp Source/StaticAllocator.h Source/StaticString.h - Source/SmallArray.h Source/StandardHeaders.h Source/Stream.h Source/StringConversions.cpp diff --git a/Gems/EMotionFX/Code/MysticQt/Source/DialogStack.cpp b/Gems/EMotionFX/Code/MysticQt/Source/DialogStack.cpp index 27f83b07a3..5e9cf66fa7 100644 --- a/Gems/EMotionFX/Code/MysticQt/Source/DialogStack.cpp +++ b/Gems/EMotionFX/Code/MysticQt/Source/DialogStack.cpp @@ -498,7 +498,7 @@ namespace MysticQt } if (findPreviousMaximizedDialogNeeded) { - for (auto curDialog = AZStd::make_reverse_iterator(dialog) + 1; curDialog != m_dialogs.rend(); ++curDialog) + for (auto curDialog = AZStd::make_reverse_iterator(dialog); curDialog != m_dialogs.rend(); ++curDialog) { if (curDialog->m_maximizeSize && curDialog->m_frame->isHidden() == false) { diff --git a/Gems/EMotionFX/Code/Source/Integration/Editor/Components/EditorAnimGraphComponent.cpp b/Gems/EMotionFX/Code/Source/Integration/Editor/Components/EditorAnimGraphComponent.cpp index eef41bc919..8721acbf3d 100644 --- a/Gems/EMotionFX/Code/Source/Integration/Editor/Components/EditorAnimGraphComponent.cpp +++ b/Gems/EMotionFX/Code/Source/Integration/Editor/Components/EditorAnimGraphComponent.cpp @@ -117,16 +117,16 @@ namespace EMotionFX void EditorAnimGraphComponent::LaunchAnimationEditor(const AZ::Data::AssetId& assetId, [[maybe_unused]] const AZ::Data::AssetType& assetType) { + // call to open must be done before LoadCharacter + const char* panelName = EMStudio::MainWindow::GetEMotionFXPaneName(); + EBUS_EVENT(AzToolsFramework::EditorRequests::Bus, OpenViewPane, panelName); + if (assetId.IsValid()) { AZ::Data::AssetId actorAssetId; actorAssetId.SetInvalid(); EditorActorComponentRequestBus::EventResult(actorAssetId, GetEntityId(), &EditorActorComponentRequestBus::Events::GetActorAssetId); - // call to open must be done before LoadCharacter - const char* panelName = EMStudio::MainWindow::GetEMotionFXPaneName(); - EBUS_EVENT(AzToolsFramework::EditorRequests::Bus, OpenViewPane, panelName); - EMStudio::MainWindow* mainWindow = EMStudio::GetMainWindow(); if (mainWindow) { diff --git a/Gems/EMotionFX/Code/Tests/AnimGraphCopyPasteTests.cpp b/Gems/EMotionFX/Code/Tests/AnimGraphCopyPasteTests.cpp index eb16a1a57c..4feb8cd86a 100644 --- a/Gems/EMotionFX/Code/Tests/AnimGraphCopyPasteTests.cpp +++ b/Gems/EMotionFX/Code/Tests/AnimGraphCopyPasteTests.cpp @@ -159,7 +159,7 @@ namespace EMotionFX (azrtti_typeid<>(conditionPrototype) != azrtti_typeid())) { AZ::TypeId type = azrtti_typeid<>(conditionPrototype); - OutputDebugString(AZStd::string::format("Condition: Name=%s, Type=%s\n", conditionPrototype->GetPaletteName(), type.ToString().c_str()).c_str()); + AZ::Debug::Platform::OutputToDebugger(nullptr, AZStd::string::format("Condition: Name=%s, Type=%s\n", conditionPrototype->GetPaletteName(), type.ToString().c_str()).c_str()); result.emplace_back(azrtti_typeid<>(conditionPrototype)); } } diff --git a/Gems/GameStateSamples/Code/Include/GameStateSamples/GameStatePrimaryControllerDisconnected.inl b/Gems/GameStateSamples/Code/Include/GameStateSamples/GameStatePrimaryControllerDisconnected.inl index 4e9fb33c7e..ded069a638 100644 --- a/Gems/GameStateSamples/Code/Include/GameStateSamples/GameStatePrimaryControllerDisconnected.inl +++ b/Gems/GameStateSamples/Code/Include/GameStateSamples/GameStatePrimaryControllerDisconnected.inl @@ -83,7 +83,7 @@ namespace GameStateSamples return; } - string localizedMessage; + AZStd::string localizedMessage; const char* localizationKey = AZ_TRAIT_GAMESTATESAMPLES_PRIMARY_CONTROLLER_DISCONNECTED_LOC_KEY; bool wasLocalized = false; LocalizationManagerRequestBus::BroadcastResult(wasLocalized, diff --git a/Gems/GameStateSamples/Code/Include/GameStateSamples/GameStatePrimaryUserSignedOut.inl b/Gems/GameStateSamples/Code/Include/GameStateSamples/GameStatePrimaryUserSignedOut.inl index d7e45fcbdd..62fa9710dc 100644 --- a/Gems/GameStateSamples/Code/Include/GameStateSamples/GameStatePrimaryUserSignedOut.inl +++ b/Gems/GameStateSamples/Code/Include/GameStateSamples/GameStatePrimaryUserSignedOut.inl @@ -99,7 +99,7 @@ namespace GameStateSamples return; } - string localizedMessage; + AZStd::string localizedMessage; const char* localizationKey = "@PRIMARY_CONTROLLER_DISCONNECTED_LOC_KEY"; bool wasLocalized = false; LocalizationManagerRequestBus::BroadcastResult(wasLocalized, diff --git a/Gems/Gestures/Code/Include/Gestures/GestureRecognizerClickOrTap.inl b/Gems/Gestures/Code/Include/Gestures/GestureRecognizerClickOrTap.inl index 84837972e8..57716c7d9f 100644 --- a/Gems/Gestures/Code/Include/Gestures/GestureRecognizerClickOrTap.inl +++ b/Gems/Gestures/Code/Include/Gestures/GestureRecognizerClickOrTap.inl @@ -8,6 +8,7 @@ #include #include +#include //////////////////////////////////////////////////////////////////////////////////////////////////// inline void Gestures::RecognizerClickOrTap::Config::Reflect(AZ::ReflectContext* context) diff --git a/Gems/Gestures/Code/Include/Gestures/GestureRecognizerDrag.inl b/Gems/Gestures/Code/Include/Gestures/GestureRecognizerDrag.inl index 368f236338..2c1af6fbc9 100644 --- a/Gems/Gestures/Code/Include/Gestures/GestureRecognizerDrag.inl +++ b/Gems/Gestures/Code/Include/Gestures/GestureRecognizerDrag.inl @@ -8,6 +8,7 @@ #include #include +#include //////////////////////////////////////////////////////////////////////////////////////////////////// inline void Gestures::RecognizerDrag::Config::Reflect(AZ::ReflectContext* context) diff --git a/Gems/Gestures/Code/Include/Gestures/GestureRecognizerHold.h b/Gems/Gestures/Code/Include/Gestures/GestureRecognizerHold.h index b8d538b426..87c53d815a 100644 --- a/Gems/Gestures/Code/Include/Gestures/GestureRecognizerHold.h +++ b/Gems/Gestures/Code/Include/Gestures/GestureRecognizerHold.h @@ -9,6 +9,7 @@ #include "IGestureRecognizer.h" +#include #include //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Gems/Gestures/Code/Include/Gestures/GestureRecognizerHold.inl b/Gems/Gestures/Code/Include/Gestures/GestureRecognizerHold.inl index 48f23cce1f..b399639f6d 100644 --- a/Gems/Gestures/Code/Include/Gestures/GestureRecognizerHold.inl +++ b/Gems/Gestures/Code/Include/Gestures/GestureRecognizerHold.inl @@ -8,6 +8,7 @@ #include #include +#include //////////////////////////////////////////////////////////////////////////////////////////////////// inline void Gestures::RecognizerHold::Config::Reflect(AZ::ReflectContext* context) diff --git a/Gems/Gestures/Code/Include/Gestures/GestureRecognizerPinch.inl b/Gems/Gestures/Code/Include/Gestures/GestureRecognizerPinch.inl index e577be0e48..f6c0427b2c 100644 --- a/Gems/Gestures/Code/Include/Gestures/GestureRecognizerPinch.inl +++ b/Gems/Gestures/Code/Include/Gestures/GestureRecognizerPinch.inl @@ -8,6 +8,7 @@ #include #include +#include //////////////////////////////////////////////////////////////////////////////////////////////////// inline void Gestures::RecognizerPinch::Config::Reflect(AZ::ReflectContext* context) diff --git a/Gems/Gestures/Code/Include/Gestures/GestureRecognizerRotate.inl b/Gems/Gestures/Code/Include/Gestures/GestureRecognizerRotate.inl index eb3b20287e..9dff9a115a 100644 --- a/Gems/Gestures/Code/Include/Gestures/GestureRecognizerRotate.inl +++ b/Gems/Gestures/Code/Include/Gestures/GestureRecognizerRotate.inl @@ -8,6 +8,7 @@ #include #include +#include //////////////////////////////////////////////////////////////////////////////////////////////////// inline void Gestures::RecognizerRotate::Config::Reflect(AZ::ReflectContext* context) diff --git a/Gems/Gestures/Code/Include/Gestures/GestureRecognizerSwipe.inl b/Gems/Gestures/Code/Include/Gestures/GestureRecognizerSwipe.inl index 9fdab7b1a2..8d59525e93 100644 --- a/Gems/Gestures/Code/Include/Gestures/GestureRecognizerSwipe.inl +++ b/Gems/Gestures/Code/Include/Gestures/GestureRecognizerSwipe.inl @@ -8,6 +8,7 @@ #include #include +#include //////////////////////////////////////////////////////////////////////////////////////////////////// inline void Gestures::RecognizerSwipe::Config::Reflect(AZ::ReflectContext* context) diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalImageTests.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalImageTests.cpp index b1aa74c397..ea9a1d380f 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalImageTests.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalImageTests.cpp @@ -116,9 +116,9 @@ namespace UnitTest size_t value = 0; AZStd::hash_combine(value, seed); - for (int x = 0; x < width; ++x) + for (AZ::u32 x = 0; x < width; ++x) { - for (int y = 0; y < height; ++y) + for (AZ::u32 y = 0; y < height; ++y) { AZStd::hash_combine(value, x); AZStd::hash_combine(value, y); @@ -141,9 +141,9 @@ namespace UnitTest const AZ::u8 pixelValue = 255; // Image data should be stored inverted on the y axis relative to our engine, so loop backwards through y. - for (int y = height - 1; y >= 0; --y) + for (int y = static_cast(height) - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) + for (AZ::u32 x = 0; x < width; ++x) { if ((x == pixelX) && (y == pixelY)) { diff --git a/Gems/ImGui/Code/Source/ImGuiManager.cpp b/Gems/ImGui/Code/Source/ImGuiManager.cpp index ac3247b6a4..427af6d7dc 100644 --- a/Gems/ImGui/Code/Source/ImGuiManager.cpp +++ b/Gems/ImGui/Code/Source/ImGuiManager.cpp @@ -409,7 +409,7 @@ void ImGuiManager::Render() break; case ImGuiResolutionMode::MatchToMaxRenderResolution: - if (backBufferWidth <= static_cast(m_renderResolution.x)) + if (backBufferWidth <= static_cast(m_renderResolution.x)) { renderRes[0] = backBufferWidth; renderRes[1] = backBufferHeight; diff --git a/Gems/LmbrCentral/Code/Source/LmbrCentral.cpp b/Gems/LmbrCentral/Code/Source/LmbrCentral.cpp index 640fc2100e..78742028f9 100644 --- a/Gems/LmbrCentral/Code/Source/LmbrCentral.cpp +++ b/Gems/LmbrCentral/Code/Source/LmbrCentral.cpp @@ -85,7 +85,7 @@ namespace LmbrCentral { static const char* s_assetCatalogFilename = "assetcatalog.xml"; - using LmbrCentralAllocatorScope = AZ::AllocatorScope; + using LmbrCentralAllocatorScope = AZ::AllocatorScope; // This component boots the required allocators for LmbrCentral everywhere but AssetBuilders class LmbrCentralAllocatorComponent @@ -347,12 +347,6 @@ namespace LmbrCentral m_allocatorShutdowns.push_back([]() { AZ::AllocatorInstance::Destroy(); }); } - if (!AZ::AllocatorInstance::IsReady()) - { - AZ::AllocatorInstance::Create(); - m_allocatorShutdowns.push_back([]() { AZ::AllocatorInstance::Destroy(); }); - } - // Register asset handlers. Requires "AssetDatabaseService" AZ_Assert(AZ::Data::AssetManager::IsReady(), "Asset manager isn't ready!"); diff --git a/Gems/LmbrCentral/Code/Source/Shape/ShapeGeometryUtil.cpp b/Gems/LmbrCentral/Code/Source/Shape/ShapeGeometryUtil.cpp index cdb97d2702..3b54447fdd 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/ShapeGeometryUtil.cpp +++ b/Gems/LmbrCentral/Code/Source/Shape/ShapeGeometryUtil.cpp @@ -353,10 +353,10 @@ namespace LmbrCentral const AZ::u32 sides, const AZ::u32 segments, const AZ::u32 capSegments, AZ::u32* indices) { - const auto capSegmentTipVerts = capSegments > 0 ? 1 : 0; - const auto totalSegments = segments + capSegments * 2; - const auto numVerts = sides * (totalSegments + 1) + 2 * capSegmentTipVerts; - const auto hasEnds = capSegments > 0; + const AZ::u32 capSegmentTipVerts = capSegments > 0 ? 1 : 0; + const AZ::u32 totalSegments = segments + capSegments * 2; + const AZ::u32 numVerts = sides * (totalSegments + 1) + 2 * capSegmentTipVerts; + const AZ::u32 hasEnds = capSegments > 0; // Start Faces (start point of tube) // Each starting face shares the same vertex at the beginning of the vertex buffer @@ -365,8 +365,7 @@ namespace LmbrCentral // 1 face per side if (hasEnds) { - - for (auto i = 0; i < sides; ++i) + for (AZ::u32 i = 0; i < sides; ++i) { AZ::u32 a = i + 1; AZ::u32 b = a + 1; @@ -383,9 +382,9 @@ namespace LmbrCentral // Middle Faces // 2 triangles per face. // 1 face per side. - for (auto i = 0; i < totalSegments; ++i) + for (AZ::u32 i = 0; i < totalSegments; ++i) { - for (auto j = 0; j < sides; ++j) + for (AZ::u32 j = 0; j < sides; ++j) { // 4 corners for each face // a ------ d @@ -416,7 +415,7 @@ namespace LmbrCentral // 1 face per side if (hasEnds) { - for (auto i = 0; i < sides; ++i) + for (AZ::u32 i = 0; i < sides; ++i) { AZ::u32 a = totalSegments * sides + i + 1; AZ::u32 b = a + 1; diff --git a/Gems/LyShine/Code/Editor/Animation/Controls/UiSplineCtrlEx.cpp b/Gems/LyShine/Code/Editor/Animation/Controls/UiSplineCtrlEx.cpp index 315a8ebfef..cf5c1b2d8f 100644 --- a/Gems/LyShine/Code/Editor/Animation/Controls/UiSplineCtrlEx.cpp +++ b/Gems/LyShine/Code/Editor/Animation/Controls/UiSplineCtrlEx.cpp @@ -135,7 +135,7 @@ private: std::vector keySelectionFlags; _smart_ptr undo; _smart_ptr redo; - string id; + AZStd::string id; ISplineInterpolator* pSpline; }; diff --git a/Gems/LyShine/Code/Editor/Animation/Controls/UiSplineCtrlEx.h b/Gems/LyShine/Code/Editor/Animation/Controls/UiSplineCtrlEx.h index edb0cfa4e2..1bbcf8eea7 100644 --- a/Gems/LyShine/Code/Editor/Animation/Controls/UiSplineCtrlEx.h +++ b/Gems/LyShine/Code/Editor/Animation/Controls/UiSplineCtrlEx.h @@ -45,8 +45,8 @@ class QRubberBand; class ISplineSet { public: - virtual ISplineInterpolator* GetSplineFromID(const string& id) = 0; - virtual string GetIDFromSpline(ISplineInterpolator* pSpline) = 0; + virtual ISplineInterpolator* GetSplineFromID(const AZStd::string& id) = 0; + virtual AZStd::string GetIDFromSpline(ISplineInterpolator* pSpline) = 0; virtual int GetSplineCount() const = 0; virtual int GetKeyCountAtTime(float time, float threshold) const = 0; }; diff --git a/Gems/LyShine/Code/Editor/Animation/UiAVEventsDialog.cpp b/Gems/LyShine/Code/Editor/Animation/UiAVEventsDialog.cpp index e9f5d04314..b45cee6948 100644 --- a/Gems/LyShine/Code/Editor/Animation/UiAVEventsDialog.cpp +++ b/Gems/LyShine/Code/Editor/Animation/UiAVEventsDialog.cpp @@ -352,7 +352,7 @@ int UiAVEventsModel::GetNumberOfUsageAndFirstTimeUsed(const char* eventName, flo { CUiAnimViewTrack* pTrack = tracks.GetTrack(currentTrack); - for (int currentKey = 0; currentKey < pTrack->GetKeyCount(); ++currentKey) + for (unsigned int currentKey = 0; currentKey < pTrack->GetKeyCount(); ++currentKey) { CUiAnimViewKeyHandle keyHandle = pTrack->GetKey(currentKey); diff --git a/Gems/LyShine/Code/Editor/Animation/UiAnimViewAnimNode.cpp b/Gems/LyShine/Code/Editor/Animation/UiAnimViewAnimNode.cpp index 2b13132606..697820d75c 100644 --- a/Gems/LyShine/Code/Editor/Animation/UiAnimViewAnimNode.cpp +++ b/Gems/LyShine/Code/Editor/Animation/UiAnimViewAnimNode.cpp @@ -1099,7 +1099,7 @@ bool CUiAnimViewAnimNode::SetName(const char* pName) } } - string oldName = GetName(); + AZStd::string oldName = GetName(); m_pAnimNode->SetName(pName); if (UiAnimUndo::IsRecording()) @@ -1107,7 +1107,7 @@ bool CUiAnimViewAnimNode::SetName(const char* pName) UiAnimUndo::Record(new CUndoAnimNodeRename(this, oldName)); } - GetSequence()->OnNodeRenamed(this, oldName); + GetSequence()->OnNodeRenamed(this, oldName.c_str()); return true; } diff --git a/Gems/LyShine/Code/Editor/Animation/UiAnimViewDialog.cpp b/Gems/LyShine/Code/Editor/Animation/UiAnimViewDialog.cpp index 61d6b66b29..ac210ba2f2 100644 --- a/Gems/LyShine/Code/Editor/Animation/UiAnimViewDialog.cpp +++ b/Gems/LyShine/Code/Editor/Animation/UiAnimViewDialog.cpp @@ -992,7 +992,7 @@ void CUiAnimViewDialog::ReloadSequencesComboBox() for (int k = 0; k < numSequences; ++k) { CUiAnimViewSequence* pSequence = pSequenceManager->GetSequenceByIndex(k); - QString fullname = QtUtil::ToQString(pSequence->GetName()); + QString fullname = pSequence->GetName(); m_sequencesComboBox->addItem(fullname); } } @@ -1132,7 +1132,7 @@ void CUiAnimViewDialog::OnSequenceChanged(CUiAnimViewSequence* pSequence) if (pSequence) { - m_currentSequenceName = QtUtil::ToQString(pSequence->GetName()); + m_currentSequenceName = pSequence->GetName(); pSequence->Reset(true); SaveZoomScrollSettings(); @@ -1733,7 +1733,7 @@ void CUiAnimViewDialog::OnNodeRenamed(CUiAnimViewNode* pNode, const char* pOldNa { if (m_currentSequenceName == QString(pOldName)) { - m_currentSequenceName = QtUtil::ToQString(pNode->GetName()); + m_currentSequenceName = pNode->GetName(); } ReloadSequencesComboBox(); diff --git a/Gems/LyShine/Code/Editor/Animation/UiAnimViewDopeSheetBase.cpp b/Gems/LyShine/Code/Editor/Animation/UiAnimViewDopeSheetBase.cpp index f9ce0e522f..a38736ff67 100644 --- a/Gems/LyShine/Code/Editor/Animation/UiAnimViewDopeSheetBase.cpp +++ b/Gems/LyShine/Code/Editor/Animation/UiAnimViewDopeSheetBase.cpp @@ -2362,10 +2362,10 @@ void CUiAnimViewDopeSheetBase::DrawKeys(CUiAnimViewTrack* pTrack, QPainter* pain } else { - cry_strcpy(keydesc, "{"); + azstrcpy(keydesc, AZ_ARRAY_SIZE(keydesc), "{"); } - cry_strcat(keydesc, pDescription); - cry_strcat(keydesc, "}"); + azstrcat(keydesc, AZ_ARRAY_SIZE(keydesc), pDescription); + azstrcat(keydesc, AZ_ARRAY_SIZE(keydesc), "}"); // Draw key description text. // Find next key. const QRect textRect(QPoint(x + 10, rect.top()), QPoint(x1, rect.bottom())); diff --git a/Gems/LyShine/Code/Editor/Animation/UiAnimViewFindDlg.cpp b/Gems/LyShine/Code/Editor/Animation/UiAnimViewFindDlg.cpp index 86f1f786d0..511866db43 100644 --- a/Gems/LyShine/Code/Editor/Animation/UiAnimViewFindDlg.cpp +++ b/Gems/LyShine/Code/Editor/Animation/UiAnimViewFindDlg.cpp @@ -13,7 +13,6 @@ #include "UiAnimViewSequenceManager.h" #include -#include #include #include @@ -64,7 +63,7 @@ void CUiAnimViewFindDlg::FillData() ObjName obj; obj.m_objName = pNode->GetName(); obj.m_directorName = pNode->HasDirectorAsParent() ? pNode->HasDirectorAsParent()->GetName() : ""; - string fullname = seq->GetName(); + AZStd::string fullname = seq->GetName(); obj.m_seqName = fullname.c_str(); m_objs.push_back(obj); } diff --git a/Gems/LyShine/Code/Editor/Animation/UiAnimViewNewSequenceDialog.cpp b/Gems/LyShine/Code/Editor/Animation/UiAnimViewNewSequenceDialog.cpp index 7c4882e7f0..ac824bfc4d 100644 --- a/Gems/LyShine/Code/Editor/Animation/UiAnimViewNewSequenceDialog.cpp +++ b/Gems/LyShine/Code/Editor/Animation/UiAnimViewNewSequenceDialog.cpp @@ -46,7 +46,7 @@ void CUiAVNewSequenceDialog::OnOK() for (int k = 0; k < CUiAnimViewSequenceManager::GetSequenceManager()->GetCount(); ++k) { CUiAnimViewSequence* pSequence = CUiAnimViewSequenceManager::GetSequenceManager()->GetSequenceByIndex(k); - QString fullname = QtUtil::ToQString(pSequence->GetName()); + QString fullname = pSequence->GetName(); if (fullname.compare(m_sequenceName, Qt::CaseInsensitive) == 0) { diff --git a/Gems/LyShine/Code/Editor/Animation/UiAnimViewNodes.cpp b/Gems/LyShine/Code/Editor/Animation/UiAnimViewNodes.cpp index 136d405465..820849bc93 100644 --- a/Gems/LyShine/Code/Editor/Animation/UiAnimViewNodes.cpp +++ b/Gems/LyShine/Code/Editor/Animation/UiAnimViewNodes.cpp @@ -485,7 +485,7 @@ CUiAnimViewNodesCtrl::CRecord* CUiAnimViewNodesCtrl::AddAnimNodeRecord(CRecord* { CRecord* pNewRecord = new CRecord(pAnimNode); - pNewRecord->setText(0, QtUtil::ToQString(pAnimNode->GetName())); + pNewRecord->setText(0, pAnimNode->GetName()); UpdateUiAnimNodeRecord(pNewRecord, pAnimNode); pParentRecord->insertChild(GetInsertPosition(pParentRecord, pAnimNode), pNewRecord); FillNodesRec(pNewRecord, pAnimNode); @@ -498,7 +498,7 @@ CUiAnimViewNodesCtrl::CRecord* CUiAnimViewNodesCtrl::AddTrackRecord(CRecord* pPa { CRecord* pNewTrackRecord = new CRecord(pTrack); pNewTrackRecord->setSizeHint(0, QSize(30, 18)); - pNewTrackRecord->setText(0, QtUtil::ToQString(pTrack->GetName())); + pNewTrackRecord->setText(0, pTrack->GetName()); UpdateTrackRecord(pNewTrackRecord, pTrack); pParentRecord->insertChild(GetInsertPosition(pParentRecord, pTrack), pNewTrackRecord); FillNodesRec(pNewTrackRecord, pTrack); @@ -707,7 +707,7 @@ void CUiAnimViewNodesCtrl::OnFillItems() m_nodeToRecordMap.clear(); CRecord* pRootGroupRec = new CRecord(pSequence); - pRootGroupRec->setText(0, QtUtil::ToQString(pSequence->GetName())); + pRootGroupRec->setText(0, pSequence->GetName()); QFont f = font(); f.setBold(true); pRootGroupRec->setData(0, Qt::FontRole, f); @@ -1322,7 +1322,7 @@ int CUiAnimViewNodesCtrl::ShowPopupMenuSingleSelection(UiAnimContextMenu& contex continue; } - QAction* a = contextMenu.main.addAction(QString(" %1").arg(QtUtil::ToQString(pTrack2->GetName()))); + QAction* a = contextMenu.main.addAction(QString(" %1").arg(pTrack2->GetName())); a->setData(eMI_ShowHideBase + childIndex); a->setCheckable(true); a->setChecked(!pTrack2->IsHidden()); @@ -1458,7 +1458,7 @@ void CUiAnimViewNodesCtrl::FillAutoCompletionListForFilter() for (unsigned int i = 0; i < animNodeCount; ++i) { - strings << QtUtil::ToQString(animNodes.GetNode(i)->GetName()); + strings << QString(animNodes.GetNode(i)->GetName()); } } else @@ -1511,7 +1511,7 @@ int CUiAnimViewNodesCtrl::GetMatNameAndSubMtlIndexFromName(QString& matName, con if (const char* pCh = strstr(nodeName, ".[")) { char matPath[MAX_PATH]; - cry_strcpy(matPath, nodeName, (size_t)(pCh - nodeName)); + azstrncpy(matPath, AZ_ARRAY_SIZE(matPath), nodeName, (size_t)(pCh - nodeName)); matName = matPath; pCh += 2; if ((*pCh) != 0) @@ -1762,7 +1762,7 @@ void CUiAnimViewNodesCtrl::OnNodeRenamed(CUiAnimViewNode* pNode, [[maybe_unused] if (!m_bIgnoreNotifications) { CRecord* pNodeRecord = GetNodeRecord(pNode); - pNodeRecord->setText(0, QtUtil::ToQString(pNode->GetName())); + pNodeRecord->setText(0, pNode->GetName()); update(); } diff --git a/Gems/LyShine/Code/Editor/Animation/UiAnimViewSequence.cpp b/Gems/LyShine/Code/Editor/Animation/UiAnimViewSequence.cpp index 86554c2004..d8888124a4 100644 --- a/Gems/LyShine/Code/Editor/Animation/UiAnimViewSequence.cpp +++ b/Gems/LyShine/Code/Editor/Animation/UiAnimViewSequence.cpp @@ -683,7 +683,7 @@ bool CUiAnimViewSequence::SetName(const char* pName) return false; } - string oldName = GetName(); + AZStd::string oldName = GetName(); m_pAnimSequence->SetName(pName); if (UiAnimUndo::IsRecording()) @@ -691,7 +691,7 @@ bool CUiAnimViewSequence::SetName(const char* pName) UiAnimUndo::Record(new CUndoAnimNodeRename(this, oldName)); } - GetSequence()->OnNodeRenamed(this, oldName); + GetSequence()->OnNodeRenamed(this, oldName.c_str()); return true; } @@ -893,7 +893,7 @@ std::deque CUiAnimViewSequence::GetMatchingTracks(CUiAnimView { std::deque matchingTracks; - const string trackName = trackNode->getAttr("name"); + const AZStd::string trackName = trackNode->getAttr("name"); IUiAnimationSystem* animationSystem = nullptr; EBUS_EVENT_RESULT(animationSystem, UiEditorAnimationBus, GetAnimationSystem); @@ -956,11 +956,11 @@ void CUiAnimViewSequence::GetMatchedPasteLocationsRec(std::vectorgetChild(nodeIndex); - const string tagName = xmlChildNode->getTag(); + const AZStd::string tagName = xmlChildNode->getTag(); if (tagName == "Node") { - const string nodeName = xmlChildNode->getAttr("name"); + const AZStd::string nodeName = xmlChildNode->getAttr("name"); int nodeType = eUiAnimNodeType_Invalid; xmlChildNode->getAttr("type", nodeType); @@ -982,7 +982,7 @@ void CUiAnimViewSequence::GetMatchedPasteLocationsRec(std::vectorgetAttr("name"); + const AZStd::string trackName = xmlChildNode->getAttr("name"); IUiAnimationSystem* animationSystem = nullptr; EBUS_EVENT_RESULT(animationSystem, UiEditorAnimationBus, GetAnimationSystem); @@ -1093,7 +1093,7 @@ void CUiAnimViewSequence::DeselectAllKeys() CUiAnimViewSequenceNotificationContext context(this); CUiAnimViewKeyBundle selectedKeys = GetSelectedKeys(); - for (int i = 0; i < selectedKeys.GetKeyCount(); ++i) + for (unsigned int i = 0; i < selectedKeys.GetKeyCount(); ++i) { CUiAnimViewKeyHandle keyHandle = selectedKeys.GetKey(i); keyHandle.Select(false); @@ -1237,7 +1237,7 @@ float CUiAnimViewSequence::ClipTimeOffsetForSliding(const float timeOffset) for (pTrackIter = tracks.begin(); pTrackIter != tracks.end(); ++pTrackIter) { CUiAnimViewTrack* pTrack = *pTrackIter; - for (int i = 0; i < pTrack->GetKeyCount(); ++i) + for (unsigned int i = 0; i < pTrack->GetKeyCount(); ++i) { CUiAnimViewKeyHandle keyHandle = pTrack->GetKey(i); diff --git a/Gems/LyShine/Code/Editor/Animation/UiAnimViewUndo.cpp b/Gems/LyShine/Code/Editor/Animation/UiAnimViewUndo.cpp index 8ab6f2e58c..cd4bf5b1ac 100644 --- a/Gems/LyShine/Code/Editor/Animation/UiAnimViewUndo.cpp +++ b/Gems/LyShine/Code/Editor/Animation/UiAnimViewUndo.cpp @@ -546,7 +546,7 @@ void CUndoAnimNodeReparent::AddParentsInChildren(CUiAnimViewAnimNode* pCurrentNo } ////////////////////////////////////////////////////////////////////////// -CUndoAnimNodeRename::CUndoAnimNodeRename(CUiAnimViewAnimNode* pNode, const string& oldName) +CUndoAnimNodeRename::CUndoAnimNodeRename(CUiAnimViewAnimNode* pNode, const AZStd::string& oldName) : m_pNode(pNode) , m_newName(pNode->GetName()) , m_oldName(oldName) @@ -556,13 +556,13 @@ CUndoAnimNodeRename::CUndoAnimNodeRename(CUiAnimViewAnimNode* pNode, const strin ////////////////////////////////////////////////////////////////////////// void CUndoAnimNodeRename::Undo([[maybe_unused]] bool bUndo) { - m_pNode->SetName(m_oldName); + m_pNode->SetName(m_oldName.c_str()); } ////////////////////////////////////////////////////////////////////////// void CUndoAnimNodeRename::Redo() { - m_pNode->SetName(m_newName); + m_pNode->SetName(m_newName.c_str()); } ////////////////////////////////////////////////////////////////////////// diff --git a/Gems/LyShine/Code/Editor/Animation/UiAnimViewUndo.h b/Gems/LyShine/Code/Editor/Animation/UiAnimViewUndo.h index d79336cedd..923420c653 100644 --- a/Gems/LyShine/Code/Editor/Animation/UiAnimViewUndo.h +++ b/Gems/LyShine/Code/Editor/Animation/UiAnimViewUndo.h @@ -304,7 +304,7 @@ class CUndoAnimNodeRename : public UiAnimUndoObject { public: - CUndoAnimNodeRename(CUiAnimViewAnimNode* pNode, const string& oldName); + CUndoAnimNodeRename(CUiAnimViewAnimNode* pNode, const AZStd::string& oldName); protected: virtual int GetSize() override { return sizeof(*this); }; @@ -315,8 +315,8 @@ protected: private: CUiAnimViewAnimNode* m_pNode; - string m_newName; - string m_oldName; + AZStd::string m_newName; + AZStd::string m_oldName; }; /** Base class for track event transactions diff --git a/Gems/LyShine/Code/Editor/AssetTreeEntry.cpp b/Gems/LyShine/Code/Editor/AssetTreeEntry.cpp index 5a281ba312..0aef09a59f 100644 --- a/Gems/LyShine/Code/Editor/AssetTreeEntry.cpp +++ b/Gems/LyShine/Code/Editor/AssetTreeEntry.cpp @@ -75,7 +75,7 @@ void AssetTreeEntry::Insert(const AZStd::string& path, const AZStd::string& menu AZStd::string folderName; AZStd::string remainderPath; size_t separator = path.find('/'); - if (separator == string::npos) + if (separator == AZStd::string::npos) { folderName = path; } diff --git a/Gems/LyShine/Code/Editor/EditorMenu.cpp b/Gems/LyShine/Code/Editor/EditorMenu.cpp index 97db065a4d..840bd206ab 100644 --- a/Gems/LyShine/Code/Editor/EditorMenu.cpp +++ b/Gems/LyShine/Code/Editor/EditorMenu.cpp @@ -724,7 +724,7 @@ void EditorWindow::AddMenu_View_LanguageSetting(QMenu* viewMenu) // Iterate through the subdirectories of the localization folder. Each // directory corresponds to a different language containing localization // translations for that language. - string fullLocPath(string(gEnv->pFileIO->GetAlias("@assets@")) + "/" + string(m_startupLocFolderName.toUtf8().constData())); + AZStd::string fullLocPath(AZStd::string(gEnv->pFileIO->GetAlias("@assets@")) + "/" + AZStd::string(m_startupLocFolderName.toUtf8().constData())); QDir locDir(fullLocPath.c_str()); locDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot); locDir.setSorting(QDir::Name); diff --git a/Gems/LyShine/Code/Editor/PropertiesContainer.cpp b/Gems/LyShine/Code/Editor/PropertiesContainer.cpp index 36a78fe684..21b3b99b02 100644 --- a/Gems/LyShine/Code/Editor/PropertiesContainer.cpp +++ b/Gems/LyShine/Code/Editor/PropertiesContainer.cpp @@ -788,7 +788,7 @@ void PropertiesContainer::Update() } else // more than one entity selected { - displayName = ToString(selectedEntitiesAmount) + " elements selected"; + displayName = (ToString(selectedEntitiesAmount) + " elements selected").c_str(); } // Update the selected element display name diff --git a/Gems/LyShine/Code/Editor/PropertyHandlerChar.cpp b/Gems/LyShine/Code/Editor/PropertyHandlerChar.cpp index ac55cd38e9..b3cacec065 100644 --- a/Gems/LyShine/Code/Editor/PropertyHandlerChar.cpp +++ b/Gems/LyShine/Code/Editor/PropertyHandlerChar.cpp @@ -9,6 +9,8 @@ #include "PropertyHandlerChar.h" +#include + QWidget* PropertyHandlerChar::CreateGUI(QWidget* pParent) { AzToolsFramework::PropertyStringLineEditCtrl* ctrl = aznew AzToolsFramework::PropertyStringLineEditCtrl(pParent); @@ -29,12 +31,8 @@ void PropertyHandlerChar::WriteGUIValuesIntoProperty(size_t index, AzToolsFramew { (int)index; AZStd::string str = GUI->value(); - uint32_t character = '\0'; - if (!str.empty()) - { - Unicode::CIterator pChar(str.c_str()); - character = *pChar; - } + wchar_t character = '\0'; + AZStd::to_wstring(&character, 1, str.c_str()); instance = character; } @@ -47,7 +45,8 @@ bool PropertyHandlerChar::ReadValuesIntoGUI(size_t index, AzToolsFramework::Prop // NOTE: this assumes the uint32_t can be interpreted as a wchar_t, it seems to // work for cases tested but may not in general. wchar_t wcharString[2] = { static_cast(instance), 0 }; - AZStd::string val(CryStringUtils::WStrToUTF8(wcharString)); + AZStd::string val; + AZStd::to_string(val, wcharString); GUI->setValue(val); } GUI->blockSignals(false); diff --git a/Gems/LyShine/Code/Editor/PropertyHandlerDirectory.cpp b/Gems/LyShine/Code/Editor/PropertyHandlerDirectory.cpp index ab51c3a29d..1f3e28b077 100644 --- a/Gems/LyShine/Code/Editor/PropertyHandlerDirectory.cpp +++ b/Gems/LyShine/Code/Editor/PropertyHandlerDirectory.cpp @@ -93,7 +93,7 @@ AzToolsFramework::AssetBrowser::AssetSelectionModel PropertyAssetDirectorySelect void PropertyAssetDirectorySelectionCtrl::SetFolderSelection(const AZStd::string& folderPath) { - string strFolderPath = folderPath.c_str(); + AZStd::string strFolderPath = folderPath.c_str(); if (strFolderPath.empty()) { m_folderPath.clear(); @@ -106,12 +106,14 @@ void PropertyAssetDirectorySelectionCtrl::SetFolderSelection(const AZStd::string // the project folder, which we need to omit since file IO routines // seem to assume this anyways. strFolderPath = strFolderPath.substr(strFolderPath.find('/') + 1); - m_folderPath = PathUtil::MakeGamePath(strFolderPath).MakeLower(); + m_folderPath = PathUtil::MakeGamePath(strFolderPath); + AZStd::to_lower(m_folderPath.begin(), m_folderPath.end()); } // For paths in gems, absolute paths are returned else { - m_folderPath = Path::FullPathToGamePath(strFolderPath.c_str()).MakeLower(); + m_folderPath = Path::FullPathToGamePath(strFolderPath.c_str()); + AZStd::to_lower(m_folderPath.begin(), m_folderPath.end()); } } diff --git a/Gems/LyShine/Code/Editor/SpriteBorderEditor.cpp b/Gems/LyShine/Code/Editor/SpriteBorderEditor.cpp index 1d8de3598e..f53da64110 100644 --- a/Gems/LyShine/Code/Editor/SpriteBorderEditor.cpp +++ b/Gems/LyShine/Code/Editor/SpriteBorderEditor.cpp @@ -191,9 +191,9 @@ void SpriteBorderEditor::UpdateSpriteSheetCellInfo(int newNumRows, int newNumCol // Calculate uniformly sized sprite-sheet cell UVs based on the given // row and column cell configuration. - for (int row = 0; row < m_numRows; ++row) + for (unsigned int row = 0; row < m_numRows; ++row) { - for (int col = 0; col < m_numCols; ++col) + for (unsigned int col = 0; col < m_numCols; ++col) { AZ::Vector2 min(col / floatNumCols, row / floatNumRows); AZ::Vector2 max((col + 1) / floatNumCols, (row + 1) / floatNumRows); @@ -921,7 +921,7 @@ void SpriteBorderEditor::AddButtonsSection(QGridLayout* gridLayout, int& rowNum) // The texture is guaranteed to exist so use that to get the full path. QString fullTexturePath = Path::GamePathToFullPath(m_sprite->GetTexturePathname().c_str()); const char* const spriteExtension = "sprite"; - string fullSpritePath = PathUtil::ReplaceExtension(fullTexturePath.toUtf8().data(), spriteExtension); + AZStd::string fullSpritePath = PathUtil::ReplaceExtension(fullTexturePath.toUtf8().data(), spriteExtension); FileHelpers::SourceControlAddOrEdit(fullSpritePath.c_str(), QApplication::activeWindow()); diff --git a/Gems/LyShine/Code/Source/Animation/AnimSequence.cpp b/Gems/LyShine/Code/Source/Animation/AnimSequence.cpp index 51e5e925ca..9b841bfd45 100644 --- a/Gems/LyShine/Code/Source/Animation/AnimSequence.cpp +++ b/Gems/LyShine/Code/Source/Animation/AnimSequence.cpp @@ -80,10 +80,10 @@ void CUiAnimSequence::SetName(const char* name) return; // should never happen, null pointer guard } - string originalName = GetName(); + AZStd::string originalName = GetName(); m_name = name; - m_pUiAnimationSystem->OnSequenceRenamed(originalName, m_name.c_str()); + m_pUiAnimationSystem->OnSequenceRenamed(originalName.c_str(), m_name.c_str()); if (GetOwner()) { @@ -594,6 +594,8 @@ void CUiAnimSequence::Activate() } } +typedef AZStd::fixed_string<512> stack_string; + ////////////////////////////////////////////////////////////////////////// void CUiAnimSequence::Deactivate() { diff --git a/Gems/LyShine/Code/Source/Animation/AnimSequence.h b/Gems/LyShine/Code/Source/Animation/AnimSequence.h index efbe886ce2..e4026ce250 100644 --- a/Gems/LyShine/Code/Source/Animation/AnimSequence.h +++ b/Gems/LyShine/Code/Source/Animation/AnimSequence.h @@ -146,7 +146,7 @@ private: uint32 m_id; AZStd::string m_name; - mutable string m_fullNameHolder; + mutable AZStd::string m_fullNameHolder; Range m_timeRange; UiTrackEvents m_events; diff --git a/Gems/LyShine/Code/Source/Animation/AzEntityNode.cpp b/Gems/LyShine/Code/Source/Animation/AzEntityNode.cpp index 49c38c8eb0..a98b651ea0 100644 --- a/Gems/LyShine/Code/Source/Animation/AzEntityNode.cpp +++ b/Gems/LyShine/Code/Source/Animation/AzEntityNode.cpp @@ -278,8 +278,8 @@ const AZ::SerializeContext::ClassElement* CUiAnimAzEntityNode::ComputeOffsetFrom if (mismatch) { - string warnMsg = "Data mismatch reading animation data for type "; - warnMsg += classData->m_typeId.ToString(); + AZStd::string warnMsg = "Data mismatch reading animation data for type "; + warnMsg += classData->m_typeId.ToString(); warnMsg += ". The field \""; warnMsg += paramData.GetName(); if (!element) diff --git a/Gems/LyShine/Code/Source/Animation/AzEntityNode.h b/Gems/LyShine/Code/Source/Animation/AzEntityNode.h index 6ca26ef84a..56680f1094 100644 --- a/Gems/LyShine/Code/Source/Animation/AzEntityNode.h +++ b/Gems/LyShine/Code/Source/Animation/AzEntityNode.h @@ -170,14 +170,14 @@ private: struct SScriptPropertyParamInfo { - string variableName; - string displayName; + AZStd::string variableName; + AZStd::string displayName; bool isVectorTable; SParamInfo animNodeParamInfo; }; std::vector< SScriptPropertyParamInfo > m_entityScriptPropertiesParamInfos; - typedef AZStd::unordered_map< string, size_t, stl::hash_string_caseless, stl::equality_string_caseless > TScriptPropertyParamInfoMap; + typedef AZStd::unordered_map, stl::equality_string_caseless > TScriptPropertyParamInfoMap; TScriptPropertyParamInfoMap m_nameToScriptPropertyParamInfo; #ifdef CHECK_FOR_TOO_MANY_ONPROPERTY_SCRIPT_CALLS uint32 m_OnPropertyCalls; diff --git a/Gems/LyShine/Code/Source/Animation/CompoundSplineTrack.h b/Gems/LyShine/Code/Source/Animation/CompoundSplineTrack.h index b707d0bc77..3ae230d4e4 100644 --- a/Gems/LyShine/Code/Source/Animation/CompoundSplineTrack.h +++ b/Gems/LyShine/Code/Source/Animation/CompoundSplineTrack.h @@ -112,7 +112,7 @@ public: virtual int NextKeyByTime(int key) const; - void SetSubTrackName(const int i, const string& name) { assert (i < MAX_SUBTRACKS); m_subTrackNames[i] = name; } + void SetSubTrackName(const int i, const AZStd::string& name) { assert (i < MAX_SUBTRACKS); m_subTrackNames[i] = name; } #ifdef UI_ANIMATION_SYSTEM_SUPPORT_EDITING virtual ColorB GetCustomColor() const diff --git a/Gems/LyShine/Code/Source/Animation/UiAnimationSystem.cpp b/Gems/LyShine/Code/Source/Animation/UiAnimationSystem.cpp index d61090f79d..324f32b414 100644 --- a/Gems/LyShine/Code/Source/Animation/UiAnimationSystem.cpp +++ b/Gems/LyShine/Code/Source/Animation/UiAnimationSystem.cpp @@ -27,19 +27,19 @@ // Serialization for anim nodes & param types #define REGISTER_NODE_TYPE(name) assert(g_animNodeEnumToStringMap.find(eUiAnimNodeType_ ## name) == g_animNodeEnumToStringMap.end()); \ g_animNodeEnumToStringMap[eUiAnimNodeType_ ## name] = STRINGIFY(name); \ - g_animNodeStringToEnumMap[string(STRINGIFY(name))] = eUiAnimNodeType_ ## name; + g_animNodeStringToEnumMap[AZStd::string(STRINGIFY(name))] = eUiAnimNodeType_ ## name; #define REGISTER_PARAM_TYPE(name) assert(g_animParamEnumToStringMap.find(eUiAnimParamType_ ## name) == g_animParamEnumToStringMap.end()); \ g_animParamEnumToStringMap[eUiAnimParamType_ ## name] = STRINGIFY(name); \ - g_animParamStringToEnumMap[string(STRINGIFY(name))] = eUiAnimParamType_ ## name; + g_animParamStringToEnumMap[AZStd::string(STRINGIFY(name))] = eUiAnimParamType_ ## name; namespace { - AZStd::unordered_map g_animNodeEnumToStringMap; - StaticInstance >> g_animNodeStringToEnumMap; + AZStd::unordered_map g_animNodeEnumToStringMap; + StaticInstance >> g_animNodeStringToEnumMap; - AZStd::unordered_map g_animParamEnumToStringMap; - StaticInstance >> g_animParamStringToEnumMap; + AZStd::unordered_map g_animParamEnumToStringMap; + StaticInstance >> g_animParamStringToEnumMap; // If you get an assert in this function, it means two node types have the same enum value. void RegisterNodeTypes() @@ -1189,7 +1189,7 @@ void UiAnimationSystem::SerializeNodeType(EUiAnimNodeType& animNodeType, XmlNode { const char* pTypeString = "Invalid"; assert(g_animNodeEnumToStringMap.find(animNodeType) != g_animNodeEnumToStringMap.end()); - pTypeString = g_animNodeEnumToStringMap[animNodeType]; + pTypeString = g_animNodeEnumToStringMap[animNodeType].c_str(); xmlNode->setAttr(kType, pTypeString); } } @@ -1273,7 +1273,7 @@ void UiAnimationSystem::SerializeParamType(CUiAnimParamType& animParamType, XmlN else { assert(g_animParamEnumToStringMap.find(animParamType.m_type) != g_animParamEnumToStringMap.end()); - pTypeString = g_animParamEnumToStringMap[animParamType.m_type]; + pTypeString = g_animParamEnumToStringMap[animParamType.m_type].c_str(); } xmlNode->setAttr(kParamType, pTypeString); @@ -1341,7 +1341,7 @@ const char* UiAnimationSystem::GetParamTypeName(const CUiAnimParamType& animPara { if (g_animParamEnumToStringMap.find(animParamType.m_type) != g_animParamEnumToStringMap.end()) { - return g_animParamEnumToStringMap[animParamType.m_type]; + return g_animParamEnumToStringMap[animParamType.m_type].c_str(); } } diff --git a/Gems/LyShine/Code/Source/EditorPropertyTypes.cpp b/Gems/LyShine/Code/Source/EditorPropertyTypes.cpp index 77a9f59732..695412819d 100644 --- a/Gems/LyShine/Code/Source/EditorPropertyTypes.cpp +++ b/Gems/LyShine/Code/Source/EditorPropertyTypes.cpp @@ -17,8 +17,9 @@ LyShine::AZu32ComboBoxVec LyShine::GetEnumSpriteIndexList(AZ::EntityId entityId, int indexCount = 0; EBUS_EVENT_ID_RESULT(indexCount, entityId, UiIndexableImageBus, GetImageIndexCount); + const AZ::u32 indexCountu32 = static_cast(indexCount); - if (indexCount > 0 && (indexMax <= indexCount - 1) && indexMin <= indexMax) + if (indexCount > 0 && (indexMax <= indexCountu32 - 1) && indexMin <= indexMax) { for (AZ::u32 i = indexMin; i <= indexMax; ++i) { diff --git a/Gems/LyShine/Code/Source/LyShine.cpp b/Gems/LyShine/Code/Source/LyShine.cpp index c776dc11e9..694a9665a8 100644 --- a/Gems/LyShine/Code/Source/LyShine.cpp +++ b/Gems/LyShine/Code/Source/LyShine.cpp @@ -291,7 +291,7 @@ AZ::EntityId CLyShine::CreateCanvas() } //////////////////////////////////////////////////////////////////////////////////////////////////// -AZ::EntityId CLyShine::LoadCanvas(const string& assetIdPathname) +AZ::EntityId CLyShine::LoadCanvas(const AZStd::string& assetIdPathname) { return m_uiCanvasManager->LoadCanvas(assetIdPathname.c_str()); } @@ -303,7 +303,7 @@ AZ::EntityId CLyShine::CreateCanvasInEditor(UiEntityContext* entityContext) } //////////////////////////////////////////////////////////////////////////////////////////////////// -AZ::EntityId CLyShine::LoadCanvasInEditor(const string& assetIdPathname, const string& sourceAssetPathname, UiEntityContext* entityContext) +AZ::EntityId CLyShine::LoadCanvasInEditor(const AZStd::string& assetIdPathname, const AZStd::string& sourceAssetPathname, UiEntityContext* entityContext) { return m_uiCanvasManager->LoadCanvasInEditor(assetIdPathname, sourceAssetPathname, entityContext); } @@ -321,7 +321,7 @@ AZ::EntityId CLyShine::FindCanvasById(LyShine::CanvasId id) } //////////////////////////////////////////////////////////////////////////////////////////////////// -AZ::EntityId CLyShine::FindLoadedCanvasByPathName(const string& assetIdPathname) +AZ::EntityId CLyShine::FindLoadedCanvasByPathName(const AZStd::string& assetIdPathname) { return m_uiCanvasManager->FindLoadedCanvasByPathName(assetIdPathname.c_str()); } @@ -339,13 +339,13 @@ void CLyShine::ReleaseCanvasDeferred(AZ::EntityId canvas) } //////////////////////////////////////////////////////////////////////////////////////////////////// -ISprite* CLyShine::LoadSprite(const string& pathname) +ISprite* CLyShine::LoadSprite(const AZStd::string& pathname) { return CSprite::LoadSprite(pathname); } //////////////////////////////////////////////////////////////////////////////////////////////////// -ISprite* CLyShine::CreateSprite(const string& renderTargetName) +ISprite* CLyShine::CreateSprite(const AZStd::string& renderTargetName) { return CSprite::CreateSprite(renderTargetName); } diff --git a/Gems/LyShine/Code/Source/LyShine.h b/Gems/LyShine/Code/Source/LyShine.h index 488131389a..19a4e664e5 100644 --- a/Gems/LyShine/Code/Source/LyShine.h +++ b/Gems/LyShine/Code/Source/LyShine.h @@ -61,18 +61,18 @@ public: IDraw2d* GetDraw2d() override; AZ::EntityId CreateCanvas() override; - AZ::EntityId LoadCanvas(const string& assetIdPathname) override; + AZ::EntityId LoadCanvas(const AZStd::string& assetIdPathname) override; AZ::EntityId CreateCanvasInEditor(UiEntityContext* entityContext) override; - AZ::EntityId LoadCanvasInEditor(const string& assetIdPathname, const string& sourceAssetPathname, UiEntityContext* entityContext) override; + AZ::EntityId LoadCanvasInEditor(const AZStd::string& assetIdPathname, const AZStd::string& sourceAssetPathname, UiEntityContext* entityContext) override; AZ::EntityId ReloadCanvasFromXml(const AZStd::string& xmlString, UiEntityContext* entityContext) override; AZ::EntityId FindCanvasById(LyShine::CanvasId id) override; - AZ::EntityId FindLoadedCanvasByPathName(const string& assetIdPathname) override; + AZ::EntityId FindLoadedCanvasByPathName(const AZStd::string& assetIdPathname) override; void ReleaseCanvas(AZ::EntityId canvas, bool forEditor) override; void ReleaseCanvasDeferred(AZ::EntityId canvas) override; - ISprite* LoadSprite(const string& pathname) override; - ISprite* CreateSprite(const string& renderTargetName) override; + ISprite* LoadSprite(const AZStd::string& pathname) override; + ISprite* CreateSprite(const AZStd::string& renderTargetName) override; bool DoesSpriteTextureAssetExist(const AZStd::string& pathname) override; void PostInit() override; diff --git a/Gems/LyShine/Code/Source/LyShineDebug.cpp b/Gems/LyShine/Code/Source/LyShineDebug.cpp index c7ffea1aec..c7dccc162f 100644 --- a/Gems/LyShine/Code/Source/LyShineDebug.cpp +++ b/Gems/LyShine/Code/Source/LyShineDebug.cpp @@ -995,7 +995,7 @@ static AZ::Entity* CreateButton(const char* name, bool atRoot, AZ::EntityId pare EBUS_EVENT_ID(buttonId, UiInteractableStatesBus, SetStateColor, UiInteractableStatesInterface::StatePressed, buttonId, pressedColor); EBUS_EVENT_ID(buttonId, UiInteractableStatesBus, SetStateAlpha, UiInteractableStatesInterface::StatePressed, buttonId, pressedColor.GetA()); - string pathname = "Textures/Basic/Button_Sliced_Normal.sprite"; + AZStd::string pathname = "Textures/Basic/Button_Sliced_Normal.sprite"; ISprite* sprite = gEnv->pLyShine->LoadSprite(pathname); EBUS_EVENT_ID(buttonId, UiImageBus, SetSprite, sprite); @@ -1094,7 +1094,7 @@ static AZ::Entity* CreateTextInput(const char* name, bool atRoot, AZ::EntityId p EBUS_EVENT_ID(textInputId, UiInteractableStatesBus, SetStateColor, UiInteractableStatesInterface::StatePressed, textInputId, pressedColor); EBUS_EVENT_ID(textInputId, UiInteractableStatesBus, SetStateAlpha, UiInteractableStatesInterface::StatePressed, textInputId, pressedColor.GetA()); - string pathname = "Textures/Basic/Button_Sliced_Normal.sprite"; + AZStd::string pathname = "Textures/Basic/Button_Sliced_Normal.sprite"; ISprite* sprite = gEnv->pLyShine->LoadSprite(pathname); EBUS_EVENT_ID(textInputId, UiImageBus, SetSprite, sprite); diff --git a/Gems/LyShine/Code/Source/LyShineLoadScreen.cpp b/Gems/LyShine/Code/Source/LyShineLoadScreen.cpp index 9d4f0bcc3c..64a577efa2 100644 --- a/Gems/LyShine/Code/Source/LyShineLoadScreen.cpp +++ b/Gems/LyShine/Code/Source/LyShineLoadScreen.cpp @@ -215,7 +215,7 @@ namespace LyShine AZ::EntityId LyShineLoadScreenComponent::loadFromCfg(const char* pathVarName, const char* autoPlayVarName) { ICVar* pathVar = gEnv->pConsole->GetCVar(pathVarName); - string path = pathVar ? pathVar->GetString() : ""; + AZStd::string path = pathVar ? pathVar->GetString() : ""; if (path.empty()) { // No canvas specified. @@ -238,7 +238,7 @@ namespace LyShine EBUS_EVENT_ID(canvasId, UiCanvasBus, SetDrawOrder, std::numeric_limits::max()); ICVar* autoPlayVar = gEnv->pConsole->GetCVar(autoPlayVarName); - string sequence = autoPlayVar ? autoPlayVar->GetString() : ""; + AZStd::string sequence = autoPlayVar ? autoPlayVar->GetString() : ""; if (sequence.empty()) { // Nothing to auto-play. @@ -253,7 +253,7 @@ namespace LyShine return canvasId; } - animSystem->PlaySequence(sequence, nullptr, false, false); + animSystem->PlaySequence(sequence.c_str(), nullptr, false, false); return canvasId; } diff --git a/Gems/LyShine/Code/Source/LyShineSystemComponent.h b/Gems/LyShine/Code/Source/LyShineSystemComponent.h index 2e0d40e8b0..3d5e81f7c5 100644 --- a/Gems/LyShine/Code/Source/LyShineSystemComponent.h +++ b/Gems/LyShine/Code/Source/LyShineSystemComponent.h @@ -26,9 +26,9 @@ namespace LyShine { - // LyShine depends on the LegacyAllocator and CryStringAllocator. This will be managed + // LyShine depends on the LegacyAllocator. This will be managed // by the LyShineSystemComponent - using LyShineAllocatorScope = AZ::AllocatorScope; + using LyShineAllocatorScope = AZ::AllocatorScope; class LyShineSystemComponent : public AZ::Component diff --git a/Gems/LyShine/Code/Source/Platform/Common/Unimplemented/UiClipboard_Unimplemented.cpp b/Gems/LyShine/Code/Source/Platform/Common/Unimplemented/UiClipboard_Unimplemented.cpp index 744cb65ac8..9175c7b2be 100644 --- a/Gems/LyShine/Code/Source/Platform/Common/Unimplemented/UiClipboard_Unimplemented.cpp +++ b/Gems/LyShine/Code/Source/Platform/Common/Unimplemented/UiClipboard_Unimplemented.cpp @@ -8,16 +8,13 @@ // UiClipboard is responsible setting and getting clipboard data for the UI elements in a platform-independent way. #include "UiClipboard.h" -#include -bool UiClipboard::SetText(const AZStd::string& text) +bool UiClipboard::SetText([[maybe_unused]] const AZStd::string& text) { - AZ_UNUSED(text); return false; } AZStd::string UiClipboard::GetText() { - AZStd::string outText; - return outText; + return {}; } diff --git a/Gems/LyShine/Code/Source/Platform/Windows/UiClipboard_Windows.cpp b/Gems/LyShine/Code/Source/Platform/Windows/UiClipboard_Windows.cpp index 318a165914..ae118aee00 100644 --- a/Gems/LyShine/Code/Source/Platform/Windows/UiClipboard_Windows.cpp +++ b/Gems/LyShine/Code/Source/Platform/Windows/UiClipboard_Windows.cpp @@ -9,7 +9,7 @@ #include "UiClipboard.h" #include -#include +#include bool UiClipboard::SetText(const AZStd::string& text) { @@ -20,7 +20,8 @@ bool UiClipboard::SetText(const AZStd::string& text) { if (text.length() > 0) { - auto wstr = CryStringUtils::UTF8ToWStr(text.c_str()); + AZStd::wstring wstr; + AZStd::to_wstring(wstr, text.c_str()); const SIZE_T buffSize = (wstr.size() + 1) * sizeof(WCHAR); if (HGLOBAL hBuffer = GlobalAlloc(GMEM_MOVEABLE, buffSize)) { @@ -46,7 +47,7 @@ AZStd::string UiClipboard::GetText() if (HANDLE hText = GetClipboardData(CF_UNICODETEXT)) { const WCHAR* text = static_cast(GlobalLock(hText)); - outText = CryStringUtils::WStrToUTF8(text); + AZStd::to_string(outText, text); GlobalUnlock(hText); } CloseClipboard(); diff --git a/Gems/LyShine/Code/Source/Sprite.cpp b/Gems/LyShine/Code/Source/Sprite.cpp index b24c473e0f..a097e23dfe 100644 --- a/Gems/LyShine/Code/Source/Sprite.cpp +++ b/Gems/LyShine/Code/Source/Sprite.cpp @@ -146,9 +146,9 @@ namespace { if (ser.IsReading()) { - string stringVal; + AZStd::string stringVal; ser.Value(attributeName, stringVal); - stringVal.replace(',', ' '); + AZ::StringFunc::Replace(stringVal, ',', ' '); char* pEnd = nullptr; float uVal = strtof(stringVal.c_str(), &pEnd); float vVal = strtof(pEnd, nullptr); @@ -202,13 +202,13 @@ CSprite::~CSprite() } //////////////////////////////////////////////////////////////////////////////////////////////////// -const string& CSprite::GetPathname() const +const AZStd::string& CSprite::GetPathname() const { return m_pathname; } //////////////////////////////////////////////////////////////////////////////////////////////////// -const string& CSprite::GetTexturePathname() const +const AZStd::string& CSprite::GetTexturePathname() const { return m_texturePathname; } @@ -283,7 +283,7 @@ void CSprite::Serialize(TSerialize ser) m_spriteSheetCells.push_back(SpriteSheetCell()); } - string aliasTemp; + AZStd::string aliasTemp; if (ser.IsReading()) { ser.Value("alias", aliasTemp); @@ -318,7 +318,7 @@ void CSprite::Serialize(TSerialize ser) } //////////////////////////////////////////////////////////////////////////////////////////////////// -bool CSprite::SaveToXml(const string& pathname) +bool CSprite::SaveToXml(const AZStd::string& pathname) { // NOTE: The input pathname has to be a path that can used to save - so not an Asset ID // because of this we do not store the pathname @@ -331,7 +331,7 @@ bool CSprite::SaveToXml(const string& pathname) ser.Value(spriteVersionNumberTag, spriteFileVersionNumber); Serialize(ser); - return root->saveToFile(pathname); + return root->saveToFile(pathname.c_str()); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -629,7 +629,7 @@ void CSprite::Shutdown() } //////////////////////////////////////////////////////////////////////////////////////////////////// -CSprite* CSprite::LoadSprite(const string& pathname) +CSprite* CSprite::LoadSprite(const AZStd::string& pathname) { AZStd::string spritePath; AZStd::string texturePath; @@ -691,7 +691,7 @@ CSprite* CSprite::LoadSprite(const string& pathname) } //////////////////////////////////////////////////////////////////////////////////////////////////// -CSprite* CSprite::CreateSprite(const string& renderTargetName) +CSprite* CSprite::CreateSprite(const AZStd::string& renderTargetName) { // test if the sprite is already loaded, if so return loaded sprite auto result = s_loadedSprites->find(renderTargetName); diff --git a/Gems/LyShine/Code/Source/Sprite.h b/Gems/LyShine/Code/Source/Sprite.h index e7e353a77b..8a645b78b1 100644 --- a/Gems/LyShine/Code/Source/Sprite.h +++ b/Gems/LyShine/Code/Source/Sprite.h @@ -32,13 +32,13 @@ public: // member functions ~CSprite() override; - const string& GetPathname() const override; - const string& GetTexturePathname() const override; + const AZStd::string& GetPathname() const override; + const AZStd::string& GetTexturePathname() const override; Borders GetBorders() const override; void SetBorders(Borders borders) override; void SetCellBorders(int cellIndex, Borders borders) override; void Serialize(TSerialize ser) override; - bool SaveToXml(const string& pathname) override; + bool SaveToXml(const AZStd::string& pathname) override; bool AreBordersZeroWidth() const override; bool AreCellBordersZeroWidth(int index) const override; AZ::Vector2 GetSize() override; @@ -72,8 +72,8 @@ public: // static member functions static void Initialize(); static void Shutdown(); - static CSprite* LoadSprite(const string& pathname); - static CSprite* CreateSprite(const string& renderTargetName); + static CSprite* LoadSprite(const AZStd::string& pathname); + static CSprite* CreateSprite(const AZStd::string& renderTargetName); static bool DoesSpriteTextureAssetExist(const AZStd::string& pathname); //! Replaces baseSprite with newSprite with proper ref-count handling and null-checks. @@ -96,7 +96,7 @@ protected: // member functions bool CellIndexWithinRange(int cellIndex) const; private: // types - typedef AZStd::unordered_map, stl::equality_string_caseless > CSpriteHashMap; + typedef AZStd::unordered_map, stl::equality_string_caseless > CSpriteHashMap; private: // member functions bool LoadFromXmlFile(); @@ -109,8 +109,8 @@ private: // data SpriteSheetCellContainer m_spriteSheetCells; //!< Stores information for each cell defined within the sprite-sheet. - string m_pathname; - string m_texturePathname; + AZStd::string m_pathname; + AZStd::string m_texturePathname; Borders m_borders; AZ::Data::Instance m_image; int m_numSpriteSheetCellTags; //!< Number of Cell child-tags in sprite XML; unfortunately needed to help with serialization. diff --git a/Gems/LyShine/Code/Source/StringUtfUtils.h b/Gems/LyShine/Code/Source/StringUtfUtils.h index f57deb1d3d..40dd22dd33 100644 --- a/Gems/LyShine/Code/Source/StringUtfUtils.h +++ b/Gems/LyShine/Code/Source/StringUtfUtils.h @@ -7,6 +7,8 @@ */ #pragma once +#include + namespace LyShine { //! \brief Returns the number of UTF8 characters in a string. @@ -16,15 +18,9 @@ namespace LyShine //! character in the string. inline int GetUtf8StringLength(const AZStd::string& utf8String) { - int utf8StrLen = 0; - Unicode::CIterator pChar(utf8String.c_str()); - while (uint32_t ch = *pChar) - { - ++pChar; - ++utf8StrLen; - } - - return utf8StrLen; + AZStd::wstring utf8StringW; + AZStd::to_wstring(utf8StringW, utf8String.c_str()); + return static_cast(utf8StringW.size()); } //! \brief Returns the number of bytes of the size of the given multi-byte char. @@ -34,17 +30,16 @@ namespace LyShine // NOTE: this assumes the uint32_t can be interpreted as a wchar_t, it seems to // work for cases tested but may not in general. // In the long run it would be better to eliminate - // this function and use Unicode::CIterator<>::Position instead. - wchar_t wcharString[2] = { static_cast(multiByteChar), 0 }; - AZStd::string utf8String(CryStringUtils::WStrToUTF8(wcharString)); - int utf8Length = static_cast(utf8String.length()); - return utf8Length; + // this function and use some sequence_lenght function that is not internal. + return Utf8::Internal::sequence_length(&multiByteChar); } inline int GetByteLengthOfUtf8Chars(const char* utf8String, int numUtf8Chars) { + AZStd::wstring utf8StringW; + AZStd::to_wstring(utf8StringW, utf8String); + AZStd::wstring::const_iterator pChar = utf8StringW.begin(); int byteStrlen = 0; - Unicode::CIterator pChar(utf8String); for (int i = 0; i < numUtf8Chars; i++) { uint32_t ch = *pChar; diff --git a/Gems/LyShine/Code/Source/Tests/internal/test_UiTextComponent.cpp b/Gems/LyShine/Code/Source/Tests/internal/test_UiTextComponent.cpp index bb8bc47556..05e670fdd5 100644 --- a/Gems/LyShine/Code/Source/Tests/internal/test_UiTextComponent.cpp +++ b/Gems/LyShine/Code/Source/Tests/internal/test_UiTextComponent.cpp @@ -3508,7 +3508,7 @@ void UiTextComponent::UnitTestLocalization(CLyShine* lyshine, IConsoleCmdArgs* / { ILocalizationManager* pLocMan = GetISystem()->GetLocalizationManager(); - string localizationXml("libs/localization/localization.xml"); + AZStd::string localizationXml("libs/localization/localization.xml"); bool initLocSuccess = false; diff --git a/Gems/LyShine/Code/Source/TextMarkup.cpp b/Gems/LyShine/Code/Source/TextMarkup.cpp index 864d7a2cfc..8c1a6e0b62 100644 --- a/Gems/LyShine/Code/Source/TextMarkup.cpp +++ b/Gems/LyShine/Code/Source/TextMarkup.cpp @@ -162,7 +162,8 @@ namespace } else if (AZStd::string(key) == "color") { - AZStd::string colorValue(string(value).Trim()); + AZStd::string colorValue(value); + AZ::StringFunc::TrimWhiteSpace(colorValue, true, true); AZStd::string::size_type ExpectedNumChars = 7; if (ExpectedNumChars == colorValue.size() && '#' == colorValue.at(0)) { diff --git a/Gems/LyShine/Code/Source/UiButtonComponent.cpp b/Gems/LyShine/Code/Source/UiButtonComponent.cpp index bf0a67d08a..11bb088400 100644 --- a/Gems/LyShine/Code/Source/UiButtonComponent.cpp +++ b/Gems/LyShine/Code/Source/UiButtonComponent.cpp @@ -220,48 +220,9 @@ bool UiButtonComponent::VersionConverter(AZ::SerializeContext& context, // conversion from version 1 to 2: // - Need to convert CryString elements to AZStd::string // - Need to convert Color to Color and Alpha - if (classElement.GetVersion() < 2) - { - if (!LyShine::ConvertSubElementFromCryStringToAzString(context, classElement, "SelectedSprite")) - { - return false; - } - - if (!LyShine::ConvertSubElementFromCryStringToAzString(context, classElement, "PressedSprite")) - { - return false; - } - - if (!LyShine::ConvertSubElementFromCryStringToAzString(context, classElement, "DisabledSprite")) - { - return false; - } - - if (!LyShine::ConvertSubElementFromColorToColorPlusAlpha(context, classElement, "SelectedColor", "SelectedAlpha")) - { - return false; - } - - if (!LyShine::ConvertSubElementFromColorToColorPlusAlpha(context, classElement, "PressedColor", "PressedAlpha")) - { - return false; - } - - if (!LyShine::ConvertSubElementFromColorToColorPlusAlpha(context, classElement, "DisabledColor", "DisabledAlpha")) - { - return false; - } - } - // conversion from version 2 to 3: // - Need to convert CryString ActionName elements to AZStd::string - if (classElement.GetVersion() < 3) - { - if (!LyShine::ConvertSubElementFromCryStringToAzString(context, classElement, "ActionName")) - { - return false; - } - } + AZ_Assert(classElement.GetVersion() >= 3, "Unsupported UiButtonComponent version: %d", classElement.GetVersion()); // conversion from version 3 to 4: // - Need to convert AZStd::string sprites to AzFramework::SimpleAssetReference diff --git a/Gems/LyShine/Code/Source/UiCanvasComponent.cpp b/Gems/LyShine/Code/Source/UiCanvasComponent.cpp index 0040870386..9d17f90f0b 100644 --- a/Gems/LyShine/Code/Source/UiCanvasComponent.cpp +++ b/Gems/LyShine/Code/Source/UiCanvasComponent.cpp @@ -181,11 +181,11 @@ namespace //////////////////////////////////////////////////////////////////////////////////////////////// // test if the given text file starts with the given text string - bool TestFileStartString(const string& pathname, const char* expectedStart) + bool TestFileStartString(const AZStd::string& pathname, const char* expectedStart) { // Open the file using CCryFile, this supports it being in the pak file or a standalone file CCryFile file; - if (!file.Open(pathname, "r")) + if (!file.Open(pathname.c_str(), "r")) { return false; } @@ -212,7 +212,7 @@ namespace //////////////////////////////////////////////////////////////////////////////////////////////// // Check if the given file was saved using AZ serialization - bool IsValidAzSerializedFile(const string& pathname) + bool IsValidAzSerializedFile(const AZStd::string& pathname) { return TestFileStartString(pathname, " dstData; @@ -3963,7 +3963,7 @@ UiCanvasComponent* UiCanvasComponent::CreateCanvasInternal(UiEntityContext* enti } //////////////////////////////////////////////////////////////////////////////////////////////////// -UiCanvasComponent* UiCanvasComponent::LoadCanvasInternal(const string& pathnameToOpen, bool forEditor, const string& assetIdPathname, UiEntityContext* entityContext, +UiCanvasComponent* UiCanvasComponent::LoadCanvasInternal(const AZStd::string& pathnameToOpen, bool forEditor, const AZStd::string& assetIdPathname, UiEntityContext* entityContext, const AZ::SliceComponent::EntityIdToEntityIdMap* previousRemapTable, AZ::EntityId previousCanvasId) { UiCanvasComponent* canvasComponent = nullptr; diff --git a/Gems/LyShine/Code/Source/UiCanvasComponent.h b/Gems/LyShine/Code/Source/UiCanvasComponent.h index 0848e368fa..79cb044af0 100644 --- a/Gems/LyShine/Code/Source/UiCanvasComponent.h +++ b/Gems/LyShine/Code/Source/UiCanvasComponent.h @@ -102,7 +102,7 @@ public: // member functions LyShine::EntityArray PickElements(const AZ::Vector2& bound0, const AZ::Vector2& bound1) override; AZ::EntityId FindInteractableToHandleEvent(AZ::Vector2 point) override; - bool SaveToXml(const string& assetIdPathname, const string& sourceAssetPathname) override; + bool SaveToXml(const AZStd::string& assetIdPathname, const AZStd::string& sourceAssetPathname) override; void FixupCreatedEntities(LyShine::EntityArray topLevelEntities, bool makeUniqueNamesAndIds, AZ::Entity* optionalInsertionPoint) override; void AddElement(AZ::Entity* element, AZ::Entity* parent, AZ::Entity* insertBefore) override; void ReinitializeElements() override; @@ -320,7 +320,7 @@ public: // static member functions static void Shutdown(); static UiCanvasComponent* CreateCanvasInternal(UiEntityContext* entityContext, bool forEditor); - static UiCanvasComponent* LoadCanvasInternal(const string& pathToOpen, bool forEditor, const string& assetIdPathname, UiEntityContext* entityContext, + static UiCanvasComponent* LoadCanvasInternal(const AZStd::string& pathToOpen, bool forEditor, const AZStd::string& assetIdPathname, UiEntityContext* entityContext, const AZ::SliceComponent::EntityIdToEntityIdMap* previousRemapTable = nullptr, AZ::EntityId previousCanvasId = AZ::EntityId()); static UiCanvasComponent* FixupReloadedCanvasForEditorInternal(AZ::Entity* newCanvasEntity, AZ::Entity* rootSliceEntity, UiEntityContext* entityContext, @@ -416,7 +416,7 @@ private: // member functions void DestroyRenderTarget(); void RenderCanvasToTexture(); - bool SaveCanvasToFile(const string& pathname, AZ::DataStream::StreamType streamType); + bool SaveCanvasToFile(const AZStd::string& pathname, AZ::DataStream::StreamType streamType); bool SaveCanvasToStream(AZ::IO::GenericStream& stream, AZ::DataStream::StreamType streamType); //! Notify elements that their canvas space rect has changed since the last update, and recompute invalid layouts diff --git a/Gems/LyShine/Code/Source/UiCanvasManager.cpp b/Gems/LyShine/Code/Source/UiCanvasManager.cpp index 0672d7b5f6..5f2adcd20c 100644 --- a/Gems/LyShine/Code/Source/UiCanvasManager.cpp +++ b/Gems/LyShine/Code/Source/UiCanvasManager.cpp @@ -353,7 +353,7 @@ void UiCanvasManager::OnCatalogAssetChanged(const AZ::Data::AssetId& assetId) // reload canvas with the same entity IDs (except for new entities, deleted entities etc) UiGameEntityContext* entityContext = new UiGameEntityContext(); - string pathname(assetPath.c_str()); + AZStd::string pathname(assetPath.c_str()); UiCanvasComponent* newCanvasComponent = UiCanvasComponent::LoadCanvasInternal(pathname, false, "", entityContext, &existingRemapTable, existingCanvasEntityId); if (!newCanvasComponent) @@ -404,7 +404,7 @@ AZ::EntityId UiCanvasManager::CreateCanvasInEditor(UiEntityContext* entityContex } //////////////////////////////////////////////////////////////////////////////////////////////////// -AZ::EntityId UiCanvasManager::LoadCanvasInEditor(const string& assetIdPathname, const string& sourceAssetPathname, UiEntityContext* entityContext) +AZ::EntityId UiCanvasManager::LoadCanvasInEditor(const AZStd::string& assetIdPathname, const AZStd::string& sourceAssetPathname, UiEntityContext* entityContext) { return LoadCanvasInternal(assetIdPathname.c_str(), true, sourceAssetPathname.c_str(), entityContext); } @@ -1068,10 +1068,10 @@ void UiCanvasManager::DebugDisplayCanvasData(int setting) const for (auto canvas : m_loadedCanvases) { // Name - const string pathname = canvas->GetPathname().c_str(); + const AZStd::string pathname = canvas->GetPathname().c_str(); size_t lastDot = pathname.find_last_of("."); size_t lastSlash = pathname.find_last_of("/"); - string leafName = pathname; + AZStd::string leafName = pathname; if (lastDot > lastSlash) { leafName = pathname.substr(lastSlash+1, lastDot-lastSlash-1); @@ -1213,10 +1213,10 @@ void UiCanvasManager::DebugDisplayDrawCallData() const for (auto canvas : m_loadedCanvases) { // Name - const string pathname = canvas->GetPathname().c_str(); + const AZStd::string pathname = canvas->GetPathname().c_str(); size_t lastDot = pathname.find_last_of("."); size_t lastSlash = pathname.find_last_of("/"); - string leafName = pathname; + AZStd::string leafName = pathname; if (lastDot > lastSlash) { leafName = pathname.substr(lastSlash+1, lastDot-lastSlash-1); @@ -1377,7 +1377,7 @@ void UiCanvasManager::DebugReportDrawCalls(const AZStd::string& name) const } // Name of canvas - const string pathname = canvas->GetPathname().c_str(); + const AZStd::string pathname = canvas->GetPathname().c_str(); logLine = "\r\n=====================================================================================\r\n"; AZ::IO::LocalFileIO::GetInstance()->Write(logHandle, logLine.c_str(), logLine.size()); logLine = AZStd::string::format("Canvas: %s\r\n", pathname.c_str()); @@ -1465,7 +1465,7 @@ void UiCanvasManager::DebugReportDrawCalls(const AZStd::string& name) const { if (!loggedCanvasHeader) { - const string pathname = canvas->GetPathname().c_str(); + const AZStd::string pathname = canvas->GetPathname().c_str(); logLine = AZStd::string::format("\r\nCanvas: %s\r\n\r\n", pathname.c_str()); AZ::IO::LocalFileIO::GetInstance()->Write(logHandle, logLine.c_str(), logLine.size()); loggedCanvasHeader = true; diff --git a/Gems/LyShine/Code/Source/UiCanvasManager.h b/Gems/LyShine/Code/Source/UiCanvasManager.h index a2bf2dde97..1d8a77a673 100644 --- a/Gems/LyShine/Code/Source/UiCanvasManager.h +++ b/Gems/LyShine/Code/Source/UiCanvasManager.h @@ -69,7 +69,7 @@ public: // member functions // ~AssetCatalogEventBus::Handler AZ::EntityId CreateCanvasInEditor(UiEntityContext* entityContext); - AZ::EntityId LoadCanvasInEditor(const string& assetIdPathname, const string& sourceAssetPathname, UiEntityContext* entityContext); + AZ::EntityId LoadCanvasInEditor(const AZStd::string& assetIdPathname, const AZStd::string& sourceAssetPathname, UiEntityContext* entityContext); AZ::EntityId ReloadCanvasFromXml(const AZStd::string& xmlString, UiEntityContext* entityContext); void ReleaseCanvas(AZ::EntityId canvas, bool forEditor); diff --git a/Gems/LyShine/Code/Source/UiDropdownComponent.cpp b/Gems/LyShine/Code/Source/UiDropdownComponent.cpp index 1940d57cbb..448c208c5e 100644 --- a/Gems/LyShine/Code/Source/UiDropdownComponent.cpp +++ b/Gems/LyShine/Code/Source/UiDropdownComponent.cpp @@ -826,7 +826,8 @@ AZ::Outcome UiDropdownComponent::ValidatePotentialExpandedP } //////////////////////////////////////////////////////////////////////////////////////////////////// -AZ::FailureValue FailureMessage(string message) { +AZ::FailureValue FailureMessage(AZStd::string message) +{ return AZ::Failure(AZStd::string(message)); } diff --git a/Gems/LyShine/Code/Source/UiImageComponent.cpp b/Gems/LyShine/Code/Source/UiImageComponent.cpp index 1e48bdff51..83c184cfc8 100644 --- a/Gems/LyShine/Code/Source/UiImageComponent.cpp +++ b/Gems/LyShine/Code/Source/UiImageComponent.cpp @@ -224,9 +224,9 @@ namespace IDraw2d::Rounding pixelRounding = isPixelAligned ? IDraw2d::Rounding::Nearest : IDraw2d::Rounding::None; float z = 1.0f; int i = 0; - for (int y = 0; y < numY; ++y) + for (uint32 y = 0; y < numY; ++y) { - for (int x = 0; x < numX; x += 1) + for (uint32 x = 0; x < numX; x += 1) { AZ::Vector3 point3(xValues[x], yValues[y], z); point3 = transform * point3; @@ -2030,7 +2030,7 @@ void UiImageComponent::ClipValuesForSlicedLinearFill(uint32 numValues, float* xV float previousPercentage = 0; int previousIndex = startClip; int clampIndex = -1; // to clamp all values greater than m_fillAmount in specified direction. - for (int arrayPos = 1; arrayPos < numValues; ++arrayPos) + for (uint32 arrayPos = 1; arrayPos < numValues; ++arrayPos) { int currentIndex = startClip + arrayPos * clipInc; float thisPercentage = (clipPosition[currentIndex] - clipPosition[startClip]) / totalLength; @@ -2102,7 +2102,7 @@ void UiImageComponent::ClipAndRenderForSlicedRadialFill(uint32 numVertsPerSide, if (m_fillAmount < 0.5f) { // Clips against first half line and then rotating line and adds results to render list. - for (int currentIndex = 0; currentIndex < totalIndices; currentIndex += 3) + for (uint32 currentIndex = 0; currentIndex < totalIndices; currentIndex += 3) { SVF_P2F_C4B_T2F_F4B intermediateVerts[maxTemporaryVerts]; uint16 intermediateIndices[maxTemporaryIndices]; @@ -2118,7 +2118,7 @@ void UiImageComponent::ClipAndRenderForSlicedRadialFill(uint32 numVertsPerSide, else { // Clips against first half line and adds results to render list then clips against the second half line and rotating line and also adds those results to render list. - for (int currentIndex = 0; currentIndex < totalIndices; currentIndex += 3) + for (uint32 currentIndex = 0; currentIndex < totalIndices; currentIndex += 3) { SVF_P2F_C4B_T2F_F4B intermediateVerts[maxTemporaryVerts]; uint16 intermediateIndices[maxTemporaryIndices]; @@ -2201,7 +2201,7 @@ void UiImageComponent::ClipAndRenderForSlicedRadialCornerOrEdgeFill(uint32 numVe int numIndicesToRender = 0; int vertexOffset = 0; - for (int ix = 0; ix < totalIndices; ix += 3) + for (uint32 ix = 0; ix < totalIndices; ix += 3) { int indicesUsed = ClipToLine(verts, &indices[ix], renderVerts, renderIndices, vertexOffset, numIndicesToRender, lineOrigin, lineEnd); numIndicesToRender += indicesUsed; @@ -2663,18 +2663,7 @@ bool UiImageComponent::VersionConverter(AZ::SerializeContext& context, // conversion from version 1: // - Need to convert CryString elements to AZStd::string // - Need to convert Color to Color and Alpha - if (classElement.GetVersion() <= 1) - { - if (!LyShine::ConvertSubElementFromCryStringToAzString(context, classElement, "SpritePath")) - { - return false; - } - - if (!LyShine::ConvertSubElementFromColorToColorPlusAlpha(context, classElement, "Color", "Alpha")) - { - return false; - } - } + AZ_Assert(classElement.GetVersion() > 1, "Unsupported UiImageComponent version: %d", classElement.GetVersion()); // conversion from version 1 or 2 to current: // - Need to convert AZStd::string sprites to AzFramework::SimpleAssetReference diff --git a/Gems/LyShine/Code/Source/UiInteractableState.cpp b/Gems/LyShine/Code/Source/UiInteractableState.cpp index d3440a9354..e81c48a43a 100644 --- a/Gems/LyShine/Code/Source/UiInteractableState.cpp +++ b/Gems/LyShine/Code/Source/UiInteractableState.cpp @@ -575,7 +575,7 @@ void UiInteractableStateFont::SetFontPathname(const AZStd::string& pathname) fontFamily = gEnv->pCryFont->LoadFontFamily(fileName.c_str()); if (!fontFamily) { - string errorMsg = "Error loading a font from "; + AZStd::string errorMsg = "Error loading a font from "; errorMsg += fileName.c_str(); errorMsg += "."; CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, errorMsg.c_str()); @@ -616,7 +616,7 @@ UiInteractableStateFont::FontEffectComboBoxVec UiInteractableStateFont::Populate // NOTE: Curently, in order for this to work, when the font is changed we need to do // "RefreshEntireTree" to get the combo box list refreshed. unsigned int numEffects = m_fontFamily ? m_fontFamily->normal->GetNumEffects() : 0; - for (int i = 0; i < numEffects; ++i) + for (unsigned int i = 0; i < numEffects; ++i) { const char* name = m_fontFamily->normal->GetEffectName(i); result.push_back(AZStd::make_pair(i, name)); diff --git a/Gems/LyShine/Code/Source/UiParticleEmitterComponent.cpp b/Gems/LyShine/Code/Source/UiParticleEmitterComponent.cpp index 9668ebf463..a8b678947b 100644 --- a/Gems/LyShine/Code/Source/UiParticleEmitterComponent.cpp +++ b/Gems/LyShine/Code/Source/UiParticleEmitterComponent.cpp @@ -830,7 +830,7 @@ void UiParticleEmitterComponent::Render(LyShine::IRenderGraph* renderGraph) AZ::u32 totalVerticesInserted = 0; // particlesToRender is the max particles we will render, we could render less if some have zero alpha - for (int i = 0; i < particlesToRender; ++i) + for (AZ::u32 i = 0; i < particlesToRender; ++i) { SVF_P2F_C4B_T2F_F4B* firstVertexOfParticle = &m_cachedPrimitive.m_vertices[totalVerticesInserted]; @@ -1827,7 +1827,7 @@ void UiParticleEmitterComponent::ResetParticleBuffers() const int verticesPerParticle = 4; int baseIndex = 0; - for (int i = 0; i < numIndices; i += indicesPerParticle) + for (AZ::u32 i = 0; i < numIndices; i += indicesPerParticle) { m_cachedPrimitive.m_indices[i + 0] = 0 + baseIndex; m_cachedPrimitive.m_indices[i + 1] = 1 + baseIndex; diff --git a/Gems/LyShine/Code/Source/UiSerialize.cpp b/Gems/LyShine/Code/Source/UiSerialize.cpp index f44d011863..e0892596ff 100644 --- a/Gems/LyShine/Code/Source/UiSerialize.cpp +++ b/Gems/LyShine/Code/Source/UiSerialize.cpp @@ -31,67 +31,6 @@ namespace UiSerialize { - //////////////////////////////////////////////////////////////////////////////////////////////////// - class CryStringTCharSerializer - : public AZ::SerializeContext::IDataSerializer - { - /// Return the size of binary buffer necessary to store the value in binary format - size_t GetRequiredBinaryBufferSize(const void* classPtr) const - { - const CryStringT* string = reinterpret_cast*>(classPtr); - return string->length() + 1; - } - - /// Store the class data into a stream. - size_t Save(const void* classPtr, AZ::IO::GenericStream& stream, [[maybe_unused]] bool isDataBigEndian /*= false*/) override - { - const CryStringT* string = reinterpret_cast*>(classPtr); - const char* data = string->c_str(); - - return static_cast(stream.Write(string->length() + 1, reinterpret_cast(data))); - } - - size_t DataToText(AZ::IO::GenericStream& in, AZ::IO::GenericStream& out, [[maybe_unused]] bool isDataBigEndian /*= false*/) override - { - size_t len = in.GetLength(); - char* buffer = static_cast(azmalloc(len)); - in.Read(in.GetLength(), reinterpret_cast(buffer)); - - AZStd::string outText = buffer; - azfree(buffer); - - return static_cast(out.Write(outText.size(), outText.data())); - } - - size_t TextToData(const char* text, unsigned int textVersion, AZ::IO::GenericStream& stream, [[maybe_unused]] bool isDataBigEndian /*= false*/) override - { - (void)textVersion; - - size_t len = strlen(text) + 1; - stream.Seek(0, AZ::IO::GenericStream::ST_SEEK_BEGIN); - return static_cast(stream.Write(len, reinterpret_cast(text))); - } - - bool Load(void* classPtr, AZ::IO::GenericStream& stream, unsigned int /*version*/, [[maybe_unused]] bool isDataBigEndian /*= false*/) override - { - CryStringT* string = reinterpret_cast*>(classPtr); - - size_t len = stream.GetLength(); - char* buffer = static_cast(azmalloc(len)); - - stream.Read(len, reinterpret_cast(buffer)); - - *string = buffer; - azfree(buffer); - return true; - } - - bool CompareValueData(const void* lhs, const void* rhs) override - { - return AZ::SerializeContext::EqualityCompareHelper >::CompareValues(lhs, rhs); - } - }; - ////////////////////////////////////////////////////////////////////////// void UiOffsetsScriptConstructor(UiTransform2dInterface::Offsets* thisPtr, AZ::ScriptDataContext& dc) { @@ -553,9 +492,6 @@ namespace UiSerialize if (serializeContext) { - serializeContext->Class >()-> - Serializer(&AZ::Serialize::StaticInstance::s_instance); - serializeContext->Class() ->Version(1) ->Field("SerializeString", &AnimationData::m_serializeData); diff --git a/Gems/LyShine/Code/Source/UiTextComponent.cpp b/Gems/LyShine/Code/Source/UiTextComponent.cpp index d95b15622b..35f351a9e6 100644 --- a/Gems/LyShine/Code/Source/UiTextComponent.cpp +++ b/Gems/LyShine/Code/Source/UiTextComponent.cpp @@ -623,12 +623,14 @@ namespace int batchCurChar = 0; - Unicode::CIterator pChar(drawBatch.text.c_str()); + Utf8::Unchecked::octet_iterator pChar(drawBatch.text.data()); uint32_t prevCh = 0; while (uint32_t ch = *pChar) { - char codepoint[5]; - Unicode::Convert(codepoint, ch); + size_t maxSize = 5; + char codepoint[5] = { 0 }; + char* codepointPtr = codepoint; + Utf8::Unchecked::octet_iterator::to_utf8_sequence(ch, codepointPtr, maxSize); float curCharWidth = drawBatch.font->GetTextSize(codepoint, true, ctx).x; @@ -652,15 +654,15 @@ namespace lastSpaceIndexInBatch = batchCurChar; lastSpaceBatch = &drawBatch; lastSpaceWidth = curLineWidth + curCharWidth; - pLastSpace = pChar.GetPosition(); + pLastSpace = pChar.base(); assert(*pLastSpace == ' '); } bool prevCharWasNewline = false; - const bool isFirstChar = pChar.GetPosition() == drawBatch.text.c_str(); + const bool isFirstChar = pChar.base() == drawBatch.text.c_str(); if (ch && !isFirstChar) { - const char* pPrevCharStr = pChar.GetPosition() - 1; + const char* pPrevCharStr = pChar.base() - 1; prevCharWasNewline = pPrevCharStr[0] == '\n'; } else if (isFirstChar) @@ -705,12 +707,12 @@ namespace } else { - const char* pBuf = pChar.GetPosition(); + char* pBuf = pChar.base(); AZStd::string::size_type bytesProcessed = pBuf - drawBatch.text.c_str(); drawBatch.text.insert(bytesProcessed, "\n"); // Insert the newline, this invalidates the iterator - pBuf = drawBatch.text.c_str() + bytesProcessed; // In case reallocation occurs, we ensure we are inside the new buffer + pBuf = drawBatch.text.data() + bytesProcessed; // In case reallocation occurs, we ensure we are inside the new buffer assert(*pBuf == '\n'); - pChar.SetPosition(pBuf); // pChar once again points inside the target string, at the current character + pChar = Utf8::Unchecked::octet_iterator(pBuf); // pChar once again points inside the target string, at the current character assert(*pChar == ch); ++pChar; ++curChar; @@ -1189,7 +1191,7 @@ void UiTextComponent::DrawBatch::CalculateSize(const STextDrawContext& ctx, bool if (displayString.length() > 0) { AZStd::string::size_type endpos = displayString.find_last_not_of(" \t\n\v\f\r"); - if ((endpos != string::npos) && (endpos != displayString.length() - 1)) + if ((endpos != AZStd::string::npos) && (endpos != displayString.length() - 1)) { displayString.erase(endpos + 1); } @@ -1295,12 +1297,14 @@ bool UiTextComponent::DrawBatch::GetOverflowInfo(const STextDrawContext& ctx, float maxEffectOffsetX = font->GetMaxEffectOffset(ctx.m_fxIdx).x; - Unicode::CIterator pChar(text.c_str()); + Utf8::Unchecked::octet_iterator pChar(text.data()); uint32_t prevCh = 0; while (uint32_t ch = *pChar) { - char codepoint[5]; - Unicode::Convert(codepoint, ch); + size_t maxSize = 5; + char codepoint[5] = { 0 }; + char* codepointPtr = codepoint; + Utf8::Unchecked::octet_iterator::to_utf8_sequence(ch, codepointPtr, maxSize); float curCharWidth = font->GetTextSize(codepoint, true, ctx).x; if (prevCh) @@ -2274,7 +2278,7 @@ int UiTextComponent::GetCharIndexFromCanvasSpacePoint(AZ::Vector2 point, bool mu // Iterate across the line for (const DrawBatch& drawBatch : batchLine.drawBatchList) { - Unicode::CIterator pChar(drawBatch.text.c_str()); + Utf8::Unchecked::octet_iterator pChar(drawBatch.text.data()); while (uint32_t ch = *pChar) { ++pChar; @@ -3527,7 +3531,7 @@ UiTextComponent::FontEffectComboBoxVec UiTextComponent::PopulateFontEffectList() if (m_font) { unsigned int numEffects = m_font->GetNumEffects(); - for (int i = 0; i < numEffects; ++i) + for (unsigned int i = 0; i < numEffects; ++i) { const char* name = m_font->GetEffectName(i); result.push_back(AZStd::make_pair(i, name)); @@ -4827,14 +4831,16 @@ int UiTextComponent::GetStartEllipseIndexInDrawBatch(const DrawBatch* drawBatchT { float overflowStringSize = 0.0f; int ellipsisCharPos = 0; - Unicode::CIterator pChar(drawBatchToEllipse->text.c_str()); + Utf8::Unchecked::octet_iterator pChar(drawBatchToEllipse->text.data()); uint32_t stringBufferIndex = 0; uint32_t prevCh = 0; while (uint32_t ch = *pChar) { ++pChar; - char codepoint[5]; - Unicode::Convert(codepoint, ch); + size_t maxSize = 5; + char codepoint[5] = { 0 }; + char* codepointPtr = codepoint; + Utf8::Unchecked::octet_iterator::to_utf8_sequence(ch, codepointPtr, maxSize); overflowStringSize += drawBatchToEllipse->font->GetTextSize(codepoint, true, ctx).x; @@ -4925,7 +4931,7 @@ AZ::Vector2 UiTextComponent::GetTextSizeFromDrawBatchLines(const UiTextComponent //////////////////////////////////////////////////////////////////////////////////////////////////// AZStd::string UiTextComponent::GetLocalizedText([[maybe_unused]] const AZStd::string& text) { - string locText; + AZStd::string locText; LocalizationManagerRequestBus::Broadcast(&LocalizationManagerRequestBus::Events::LocalizeString_ch, m_text.c_str(), locText, false); return locText.c_str(); } @@ -4995,28 +5001,8 @@ bool UiTextComponent::VersionConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement) { // conversion from version 1: Need to convert Color to Color and Alpha - if (classElement.GetVersion() == 1) - { - if (!LyShine::ConvertSubElementFromCryStringToAssetRef(context, classElement, "FontFileName")) - { - return false; - } - - if (!LyShine::ConvertSubElementFromColorToColorPlusAlpha(context, classElement, "Color", "Alpha")) - { - return false; - } - } - // conversion from version 1 or 2: Need to convert Text from CryString to AzString - if (classElement.GetVersion() <= 2) - { - // Call internal function to work-around serialization of empty AZ std string - if (!LyShine::ConvertSubElementFromCryStringToAzString(context, classElement, "Text")) - { - return false; - } - } + AZ_Assert(classElement.GetVersion() > 2, "Unsupported UiTextComponent version: %d", classElement.GetVersion()); // Versions prior to v4: Change default font if (classElement.GetVersion() <= 3) @@ -5130,7 +5116,7 @@ int UiTextComponent::GetLineNumberFromCharIndex(const DrawBatchLines& drawBatchL for (const DrawBatch& drawBatch : batchLine.drawBatchList) { - Unicode::CIterator pChar(drawBatch.text.c_str()); + Utf8::Unchecked::octet_iterator pChar(drawBatch.text.data()); while (uint32_t ch = *pChar) { ++pChar; diff --git a/Gems/LyShine/Code/Source/UiTextComponentOffsetsSelector.cpp b/Gems/LyShine/Code/Source/UiTextComponentOffsetsSelector.cpp index 24f2bff49c..8803a1881c 100644 --- a/Gems/LyShine/Code/Source/UiTextComponentOffsetsSelector.cpp +++ b/Gems/LyShine/Code/Source/UiTextComponentOffsetsSelector.cpp @@ -30,7 +30,7 @@ void UiTextComponentOffsetsSelector::ParseBatchLine(const UiTextComponent::DrawB { // Iterate character by character over DrawBatch string contents, // looking for m_firstIndex and m_lastIndex. - Unicode::CIterator pChar(drawBatch.text.c_str()); + Utf8::Unchecked::octet_iterator pChar(drawBatch.text.data()); while (uint32_t ch = *pChar) { ++pChar; diff --git a/Gems/LyShine/Code/Source/UiTextInputComponent.cpp b/Gems/LyShine/Code/Source/UiTextInputComponent.cpp index 6a02d94b1f..0d9fc09063 100644 --- a/Gems/LyShine/Code/Source/UiTextInputComponent.cpp +++ b/Gems/LyShine/Code/Source/UiTextInputComponent.cpp @@ -70,7 +70,7 @@ namespace if (stringLength > 0 && stringLength >= utf8Index) { // Iterate over the string until the given index is found. - Unicode::CIterator pChar(utf8String.c_str()); + Utf8::Unchecked::octet_iterator pChar(utf8String.data()); while (uint32_t ch = *pChar) { if (utf8Index == utfIndexIter) @@ -1185,7 +1185,8 @@ void UiTextInputComponent::UpdateDisplayedTextFunction() // NOTE: this assumes the uint32_t can be interpreted as a wchar_t, it seems to // work for cases tested but may not in general. wchar_t wcharString[2] = { static_cast(this->GetReplacementCharacter()), 0 }; - AZStd::string replacementCharString(CryStringUtils::WStrToUTF8(wcharString)); + AZStd::string replacementCharString; + AZStd::to_string(replacementCharString, { wcharString, 1 }); int numReplacementChars = LyShine::GetUtf8StringLength(originalText); @@ -1475,54 +1476,10 @@ bool UiTextInputComponent::VersionConverter(AZ::SerializeContext& context, // conversion from version 1: // - Need to convert CryString elements to AZStd::string // - Need to convert Color to Color and Alpha - if (classElement.GetVersion() <= 1) - { - if (!LyShine::ConvertSubElementFromCryStringToAzString(context, classElement, "SelectedSprite")) - { - return false; - } - - if (!LyShine::ConvertSubElementFromCryStringToAzString(context, classElement, "PressedSprite")) - { - return false; - } - - if (!LyShine::ConvertSubElementFromColorToColorPlusAlpha(context, classElement, "SelectedColor", "SelectedAlpha")) - { - return false; - } - - if (!LyShine::ConvertSubElementFromColorToColorPlusAlpha(context, classElement, "PressedColor", "PressedAlpha")) - { - return false; - } - - if (!LyShine::ConvertSubElementFromCryStringToChar(context, classElement, "ReplacementCharacter", defaultReplacementChar)) - { - return false; - } - } - // conversion from version 1 or 2 to current: // - Need to convert CryString ActionName elements to AZStd::string - if (classElement.GetVersion() <= 2) - { - if (!LyShine::ConvertSubElementFromCryStringToAzString(context, classElement, "ChangeAction")) - { - return false; - } - - if (!LyShine::ConvertSubElementFromCryStringToAzString(context, classElement, "EndEditAction")) - { - return false; - } - - if (!LyShine::ConvertSubElementFromCryStringToAzString(context, classElement, "EnterAction")) - { - return false; - } - } - + AZ_Assert(classElement.GetVersion() > 2, "Unsupported UiTextInputComponent version: %d", classElement.GetVersion()); + // conversion from version 1, 2 or 3 to current: // - Need to convert AZStd::string sprites to AzFramework::SimpleAssetReference if (classElement.GetVersion() <= 3) diff --git a/Gems/LyShine/Code/Tests/SerializationTest.cpp b/Gems/LyShine/Code/Tests/SerializationTest.cpp index e5ed3638d4..70ae590358 100644 --- a/Gems/LyShine/Code/Tests/SerializationTest.cpp +++ b/Gems/LyShine/Code/Tests/SerializationTest.cpp @@ -24,7 +24,6 @@ namespace UnitTest appDesc.m_stackRecordLevels = 20; AZ::ComponentApplication::StartupParameters appStartup; - // Module needs to be created this way to create CryString allocator for test appStartup.m_createStaticModulesCallback = [](AZStd::vector& modules) { diff --git a/Gems/LyShine/Code/Tests/SpriteTest.cpp b/Gems/LyShine/Code/Tests/SpriteTest.cpp index 0ac3465cd7..84b47955b4 100644 --- a/Gems/LyShine/Code/Tests/SpriteTest.cpp +++ b/Gems/LyShine/Code/Tests/SpriteTest.cpp @@ -27,7 +27,6 @@ namespace UnitTest appDesc.m_stackRecordLevels = 20; AZ::ComponentApplication::StartupParameters appStartup; - // Module needs to be created this way to create CryString allocator for test appStartup.m_createStaticModulesCallback = [](AZStd::vector& modules) { diff --git a/Gems/Maestro/Code/Source/Cinematics/AnimComponentNode.h b/Gems/Maestro/Code/Source/Cinematics/AnimComponentNode.h index 4df6021aa9..5ad3ab6f94 100644 --- a/Gems/Maestro/Code/Source/Cinematics/AnimComponentNode.h +++ b/Gems/Maestro/Code/Source/Cinematics/AnimComponentNode.h @@ -144,7 +144,7 @@ private: { public: BehaviorPropertyInfo() {} - BehaviorPropertyInfo(const string& name) + BehaviorPropertyInfo(const AZStd::string& name) { *this = name; } @@ -154,7 +154,7 @@ private: m_animNodeParamInfo.paramType = other.m_displayName; m_animNodeParamInfo.name = &m_displayName[0]; } - BehaviorPropertyInfo& operator=(const string& str) + BehaviorPropertyInfo& operator=(const AZStd::string& str) { // TODO: clean this up - this weird memory sharing was copied from legacy Cry - could be better. m_displayName = str; @@ -163,7 +163,7 @@ private: return *this; } - string m_displayName; + AZStd::string m_displayName; SParamInfo m_animNodeParamInfo; }; diff --git a/Gems/Maestro/Code/Source/Cinematics/AnimPostFXNode.cpp b/Gems/Maestro/Code/Source/Cinematics/AnimPostFXNode.cpp index 8160f97de7..9da32d757a 100644 --- a/Gems/Maestro/Code/Source/Cinematics/AnimPostFXNode.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/AnimPostFXNode.cpp @@ -39,7 +39,7 @@ public: virtual void GetDefault(bool& val) const = 0; virtual void GetDefault(Vec4& val) const = 0; - string m_name; + AZStd::string m_name; protected: virtual ~CControlParamBase(){} diff --git a/Gems/Maestro/Code/Source/Cinematics/AnimSequence.cpp b/Gems/Maestro/Code/Source/Cinematics/AnimSequence.cpp index ad78e4e420..6caa918227 100644 --- a/Gems/Maestro/Code/Source/Cinematics/AnimSequence.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/AnimSequence.cpp @@ -98,10 +98,10 @@ void CAnimSequence::SetName(const char* name) return; // should never happen, null pointer guard } - string originalName = GetName(); + AZStd::string originalName = GetName(); m_name = name; - m_pMovieSystem->OnSequenceRenamed(originalName, m_name.c_str()); + m_pMovieSystem->OnSequenceRenamed(originalName.c_str(), m_name.c_str()); // the sequence named LIGHT_ANIMATION_SET_NAME is a singleton sequence to hold all light animations. if (m_name == LIGHT_ANIMATION_SET_NAME) @@ -744,9 +744,6 @@ void CAnimSequence::Deactivate() static_cast(animNode)->OnReset(); } - // Remove a possibly cached game hint associated with this anim sequence. - stack_string sTemp("anim_sequence_"); - sTemp += m_name.c_str(); // Audio: Release precached sound m_bActive = false; @@ -776,16 +773,6 @@ void CAnimSequence::PrecacheStatic(const float startTime) return; } - // Try to cache this sequence's game hint if one exists. - stack_string sTemp("anim_sequence_"); - sTemp += m_name.c_str(); - - //if (gEnv->pAudioSystem) - { - // Make sure to use the non-serializable game hint type as trackview sequences get properly reactivated after load - // Audio: Precache sound - } - gEnv->pLog->Log("=== Precaching render data for cutscene: %s ===", GetName()); m_precached = true; diff --git a/Gems/Maestro/Code/Source/Cinematics/AnimSequence.h b/Gems/Maestro/Code/Source/Cinematics/AnimSequence.h index 2c12f6e5ea..f69017c3a6 100644 --- a/Gems/Maestro/Code/Source/Cinematics/AnimSequence.h +++ b/Gems/Maestro/Code/Source/Cinematics/AnimSequence.h @@ -174,7 +174,7 @@ private: uint32 m_id; AZStd::string m_name; - mutable string m_fullNameHolder; + mutable AZStd::string m_fullNameHolder; Range m_timeRange; TrackEvents m_events; diff --git a/Gems/Maestro/Code/Source/Cinematics/CaptureTrack.cpp b/Gems/Maestro/Code/Source/Cinematics/CaptureTrack.cpp index 114e768975..f4faf4dbeb 100644 --- a/Gems/Maestro/Code/Source/Cinematics/CaptureTrack.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/CaptureTrack.cpp @@ -52,7 +52,7 @@ void CCaptureTrack::GetKeyInfo(int key, const char*& description, float& duratio char prefix[64] = "Frame"; if (!m_keys[key].prefix.empty()) { - cry_strcpy(prefix, m_keys[key].prefix.c_str()); + azstrcpy(prefix, AZ_ARRAY_SIZE(prefix), m_keys[key].prefix.c_str()); } description = buffer; if (!m_keys[key].folder.empty()) diff --git a/Gems/Maestro/Code/Source/Cinematics/CommentTrack.cpp b/Gems/Maestro/Code/Source/Cinematics/CommentTrack.cpp index c9a50a0979..8c1baf4684 100644 --- a/Gems/Maestro/Code/Source/Cinematics/CommentTrack.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/CommentTrack.cpp @@ -25,7 +25,7 @@ void CCommentTrack::GetKeyInfo(int key, const char*& description, float& duratio description = 0; duration = m_keys[key].m_duration; - cry_strcpy(desc, m_keys[key].m_strComment.c_str()); + azstrcpy(desc, AZ_ARRAY_SIZE(desc), m_keys[key].m_strComment.c_str()); description = desc; } diff --git a/Gems/Maestro/Code/Source/Cinematics/CompoundSplineTrack.cpp b/Gems/Maestro/Code/Source/Cinematics/CompoundSplineTrack.cpp index 4dd52a734a..884a90b200 100644 --- a/Gems/Maestro/Code/Source/Cinematics/CompoundSplineTrack.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/CompoundSplineTrack.cpp @@ -457,31 +457,31 @@ void CCompoundSplineTrack::GetKeyInfo(int key, const char*& description, float& { float dummy; m_subTracks[0]->GetKeyInfo(m, subDesc, dummy); - cry_strcat(str, subDesc); + azstrcat(str, AZ_ARRAY_SIZE(str), subDesc); break; } } if (m == m_subTracks[0]->GetNumKeys()) { - cry_strcat(str, m_subTrackNames[0].c_str()); + azstrcat(str, AZ_ARRAY_SIZE(str), m_subTrackNames[0].c_str()); } // Tail cases for (int i = 1; i < GetSubTrackCount(); ++i) { - cry_strcat(str, ","); + azstrcat(str, AZ_ARRAY_SIZE(str), ","); for (m = 0; m < m_subTracks[i]->GetNumKeys(); ++m) { if (m_subTracks[i]->GetKeyTime(m) == time) { float dummy; m_subTracks[i]->GetKeyInfo(m, subDesc, dummy); - cry_strcat(str, subDesc); + azstrcat(str, AZ_ARRAY_SIZE(str), subDesc); break; } } if (m == m_subTracks[i]->GetNumKeys()) { - cry_strcat(str, m_subTrackNames[i].c_str()); + azstrcat(str, AZ_ARRAY_SIZE(str), m_subTrackNames[i].c_str()); } } } diff --git a/Gems/Maestro/Code/Source/Cinematics/CompoundSplineTrack.h b/Gems/Maestro/Code/Source/Cinematics/CompoundSplineTrack.h index f22b0fb144..b0a2733316 100644 --- a/Gems/Maestro/Code/Source/Cinematics/CompoundSplineTrack.h +++ b/Gems/Maestro/Code/Source/Cinematics/CompoundSplineTrack.h @@ -108,7 +108,7 @@ public: virtual int NextKeyByTime(int key) const; - void SetSubTrackName(const int i, const string& name) { assert (i < MAX_SUBTRACKS); m_subTrackNames[i] = name; } + void SetSubTrackName(const int i, const AZStd::string& name) { assert (i < MAX_SUBTRACKS); m_subTrackNames[i] = name; } #ifdef MOVIESYSTEM_SUPPORT_EDITING virtual ColorB GetCustomColor() const diff --git a/Gems/Maestro/Code/Source/Cinematics/EventTrack.cpp b/Gems/Maestro/Code/Source/Cinematics/EventTrack.cpp index 5e1a63b4bc..4d32a4a4a1 100644 --- a/Gems/Maestro/Code/Source/Cinematics/EventTrack.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/EventTrack.cpp @@ -69,11 +69,11 @@ void CEventTrack::GetKeyInfo(int key, const char*& description, float& duration) CheckValid(); description = 0; duration = 0; - cry_strcpy(desc, m_keys[key].event.c_str()); + azstrcpy(desc, AZ_ARRAY_SIZE(desc), m_keys[key].event.c_str()); if (!m_keys[key].eventValue.empty()) { - cry_strcat(desc, ", "); - cry_strcat(desc, m_keys[key].eventValue.c_str()); + azstrcat(desc, AZ_ARRAY_SIZE(desc), ", "); + azstrcat(desc, AZ_ARRAY_SIZE(desc), m_keys[key].eventValue.c_str()); } description = desc; diff --git a/Gems/Maestro/Code/Source/Cinematics/MaterialNode.h b/Gems/Maestro/Code/Source/Cinematics/MaterialNode.h index 51d1b8be15..003312c426 100644 --- a/Gems/Maestro/Code/Source/Cinematics/MaterialNode.h +++ b/Gems/Maestro/Code/Source/Cinematics/MaterialNode.h @@ -58,7 +58,7 @@ private: float m_fMaxKeyValue; std::vector< CAnimNode::SParamInfo > m_dynamicShaderParamInfos; - typedef AZStd::unordered_map< string, size_t, stl::hash_string_caseless, stl::equality_string_caseless > TDynamicShaderParamsMap; + typedef AZStd::unordered_map, stl::equality_string_caseless > TDynamicShaderParamsMap; TDynamicShaderParamsMap m_nameToDynamicShaderParam; }; diff --git a/Gems/Maestro/Code/Source/Cinematics/Movie.cpp b/Gems/Maestro/Code/Source/Cinematics/Movie.cpp index b781dd6c82..bd586a12c1 100644 --- a/Gems/Maestro/Code/Source/Cinematics/Movie.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/Movie.cpp @@ -75,19 +75,19 @@ static SMovieSequenceAutoComplete s_movieSequenceAutoComplete; // Serialization for anim nodes & param types #define REGISTER_NODE_TYPE(name) assert(g_animNodeEnumToStringMap.find(AnimNodeType::name) == g_animNodeEnumToStringMap.end()); \ g_animNodeEnumToStringMap[AnimNodeType::name] = STRINGIFY(name); \ - g_animNodeStringToEnumMap[string(STRINGIFY(name))] = AnimNodeType::name; + g_animNodeStringToEnumMap[AZStd::string(STRINGIFY(name))] = AnimNodeType::name; #define REGISTER_PARAM_TYPE(name) assert(g_animParamEnumToStringMap.find(AnimParamType::name) == g_animParamEnumToStringMap.end()); \ g_animParamEnumToStringMap[AnimParamType::name] = STRINGIFY(name); \ - g_animParamStringToEnumMap[string(STRINGIFY(name))] = AnimParamType::name; + g_animParamStringToEnumMap[AZStd::string(STRINGIFY(name))] = AnimParamType::name; namespace { - AZStd::unordered_map g_animNodeEnumToStringMap; - StaticInstance >> g_animNodeStringToEnumMap; + AZStd::unordered_map g_animNodeEnumToStringMap; + StaticInstance >> g_animNodeStringToEnumMap; - AZStd::unordered_map g_animParamEnumToStringMap; - StaticInstance >> g_animParamStringToEnumMap; + AZStd::unordered_map g_animParamEnumToStringMap; + StaticInstance >> g_animParamStringToEnumMap; // If you get an assert in this function, it means two node types have the same enum value. void RegisterNodeTypes() @@ -1479,8 +1479,7 @@ void CMovieSystem::GoToFrame(const char* seqName, float targetFrame) if (gEnv->IsEditor() && gEnv->IsEditorGameMode() == false) { - string editorCmd; - editorCmd.Format("mov_goToFrameEditor %s %f", seqName, targetFrame); + AZStd::string editorCmd = AZStd::string::format("mov_goToFrameEditor %s %f", seqName, targetFrame); gEnv->pConsole->ExecuteString(editorCmd.c_str()); return; } @@ -1679,7 +1678,7 @@ void CMovieSystem::SerializeNodeType(AnimNodeType& animNodeType, XmlNodeRef& xml { const char* pTypeString = "Invalid"; assert(g_animNodeEnumToStringMap.find(animNodeType) != g_animNodeEnumToStringMap.end()); - pTypeString = g_animNodeEnumToStringMap[animNodeType]; + pTypeString = g_animNodeEnumToStringMap[animNodeType].c_str(); xmlNode->setAttr(kType, pTypeString); } } @@ -1780,7 +1779,7 @@ void CMovieSystem::SaveParamTypeToXml(const CAnimParamType& animParamType, XmlNo } assert(g_animParamEnumToStringMap.find(animParamType.m_type) != g_animParamEnumToStringMap.end()); - pTypeString = g_animParamEnumToStringMap[animParamType.m_type]; + pTypeString = g_animParamEnumToStringMap[animParamType.m_type].c_str(); } xmlNode->setAttr(kParamType, pTypeString); @@ -1815,7 +1814,7 @@ const char* CMovieSystem::GetParamTypeName(const CAnimParamType& animParamType) { if (g_animParamEnumToStringMap.find(animParamType.m_type) != g_animParamEnumToStringMap.end()) { - return g_animParamEnumToStringMap[animParamType.m_type]; + return g_animParamEnumToStringMap[animParamType.m_type].c_str(); } } @@ -1963,20 +1962,20 @@ void CLightAnimWrapper::InvalidateAllNodes() CLightAnimWrapper* CLightAnimWrapper::FindLightAnim(const char* name) { - LightAnimWrapperCache::const_iterator it = ms_lightAnimWrapperCache.find(CONST_TEMP_STRING(name)); + LightAnimWrapperCache::const_iterator it = ms_lightAnimWrapperCache.find(name); return it != ms_lightAnimWrapperCache.end() ? (*it).second : 0; } ////////////////////////////////////////////////////////////////////////// void CLightAnimWrapper::CacheLightAnim(const char* name, CLightAnimWrapper* p) { - ms_lightAnimWrapperCache.insert(LightAnimWrapperCache::value_type(string(name), p)); + ms_lightAnimWrapperCache.insert(LightAnimWrapperCache::value_type(AZStd::string(name), p)); } ////////////////////////////////////////////////////////////////////////// void CLightAnimWrapper::RemoveCachedLightAnim(const char* name) { - ms_lightAnimWrapperCache.erase(CONST_TEMP_STRING(name)); + ms_lightAnimWrapperCache.erase(name); } #ifdef MOVIESYSTEM_SUPPORT_EDITING diff --git a/Gems/Maestro/Code/Source/Cinematics/Movie.h b/Gems/Maestro/Code/Source/Cinematics/Movie.h index cb97cfc40b..6ac857d652 100644 --- a/Gems/Maestro/Code/Source/Cinematics/Movie.h +++ b/Gems/Maestro/Code/Source/Cinematics/Movie.h @@ -48,7 +48,7 @@ public: static void InvalidateAllNodes(); private: - typedef std::map LightAnimWrapperCache; + typedef std::map LightAnimWrapperCache; static StaticInstance ms_lightAnimWrapperCache; static AZStd::intrusive_ptr ms_pLightAnimSet; diff --git a/Gems/Maestro/Code/Source/Cinematics/SceneNode.cpp b/Gems/Maestro/Code/Source/Cinematics/SceneNode.cpp index fb12b3e795..d4b894dc92 100644 --- a/Gems/Maestro/Code/Source/Cinematics/SceneNode.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/SceneNode.cpp @@ -916,8 +916,8 @@ void CAnimSceneNode::ApplyCameraKey(ISelectKey& key, SAnimContext& ec) void CAnimSceneNode::ApplyEventKey(IEventKey& key, [[maybe_unused]] SAnimContext& ec) { char funcName[1024]; - cry_strcpy(funcName, "Event_"); - cry_strcat(funcName, key.event.c_str()); + azstrcpy(funcName, AZ_ARRAY_SIZE(funcName), "Event_"); + azstrcat(funcName, AZ_ARRAY_SIZE(funcName), key.event.c_str()); gEnv->pMovieSystem->SendGlobalEvent(funcName); } @@ -1003,7 +1003,7 @@ void CAnimSceneNode::ApplyGotoKey(CGotoTrack* poGotoTrack, SAnimContext& ec) { if (stDiscreteFloadKey.m_fValue >= 0) { - string fullname = m_pSequence->GetName(); + AZStd::string fullname = m_pSequence->GetName(); GetMovieSystem()->GoToFrame(fullname.c_str(), stDiscreteFloadKey.m_fValue); } } diff --git a/Gems/Maestro/Code/Source/Cinematics/ScreenFaderTrack.cpp b/Gems/Maestro/Code/Source/Cinematics/ScreenFaderTrack.cpp index af5b931dec..9ac19f91ea 100644 --- a/Gems/Maestro/Code/Source/Cinematics/ScreenFaderTrack.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/ScreenFaderTrack.cpp @@ -32,7 +32,7 @@ void CScreenFaderTrack::GetKeyInfo(int key, const char*& description, float& dur CheckValid(); description = 0; duration = m_keys[key].m_fadeTime; - cry_strcpy(desc, m_keys[key].m_fadeType == IScreenFaderKey::eFT_FadeIn ? "In" : "Out"); + azstrcpy(desc, AZ_ARRAY_SIZE(desc), m_keys[key].m_fadeType == IScreenFaderKey::eFT_FadeIn ? "In" : "Out"); description = desc; } diff --git a/Gems/Maestro/Code/Source/Cinematics/TrackEventTrack.cpp b/Gems/Maestro/Code/Source/Cinematics/TrackEventTrack.cpp index f6a0920901..83b141cfb2 100644 --- a/Gems/Maestro/Code/Source/Cinematics/TrackEventTrack.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/TrackEventTrack.cpp @@ -143,11 +143,11 @@ void CTrackEventTrack::GetKeyInfo(int key, const char*& description, float& dura CheckValid(); description = 0; duration = 0; - cry_strcpy(desc, m_keys[key].event.c_str()); + azstrcpy(desc, AZ_ARRAY_SIZE(desc), m_keys[key].event.c_str()); if (!m_keys[key].eventValue.empty()) { - cry_strcat(desc, ", "); - cry_strcat(desc, m_keys[key].eventValue.c_str()); + azstrcat(desc, AZ_ARRAY_SIZE(desc), ", "); + azstrcat(desc, AZ_ARRAY_SIZE(desc), m_keys[key].eventValue.c_str()); } description = desc; diff --git a/Gems/Maestro/Code/Source/MaestroSystemComponent.h b/Gems/Maestro/Code/Source/MaestroSystemComponent.h index e5776c6628..b27075dbc0 100644 --- a/Gems/Maestro/Code/Source/MaestroSystemComponent.h +++ b/Gems/Maestro/Code/Source/MaestroSystemComponent.h @@ -17,10 +17,10 @@ namespace Maestro { - // Ensure that Maestro always has the LegacyAllocator and CryStringAllocators available + // Ensure that Maestro always has the LegacyAllocator available // NOTE: This component is only activated in the AssetBuilder, as the required allocators are // booted by the launcher or editor. - using MaestroAllocatorScope = AZ::AllocatorScope; + using MaestroAllocatorScope = AZ::AllocatorScope; class MaestroAllocatorComponent : public AZ::Component diff --git a/Gems/Metastream/Code/Source/MetastreamGem.cpp b/Gems/Metastream/Code/Source/MetastreamGem.cpp index d1792c439f..2bb213662c 100644 --- a/Gems/Metastream/Code/Source/MetastreamGem.cpp +++ b/Gems/Metastream/Code/Source/MetastreamGem.cpp @@ -323,7 +323,7 @@ namespace Metastream { // Initialise and start the HTTP server m_server = std::unique_ptr(new CivetHttpServer(m_cache.get())); - string serverOptions = m_serverOptionsCVar->GetString(); + AZStd::string serverOptions = m_serverOptionsCVar->GetString(); CryLogAlways("Initializing Metastream: Options=\"%s\"", serverOptions.c_str()); bool result = m_server->Start(serverOptions.c_str()); diff --git a/Gems/Metastream/Code/Tests/MetastreamTest.cpp b/Gems/Metastream/Code/Tests/MetastreamTest.cpp index c304a1c55f..1b25fb5327 100644 --- a/Gems/Metastream/Code/Tests/MetastreamTest.cpp +++ b/Gems/Metastream/Code/Tests/MetastreamTest.cpp @@ -38,12 +38,10 @@ protected: AZ::AllocatorInstance::Create(); AZ::AllocatorInstance::Create(); AZ::AllocatorInstance::Create(); - AZ::AllocatorInstance::Create(); } void TeardownEnvironment() override { - AZ::AllocatorInstance::Destroy(); AZ::AllocatorInstance::Destroy(); AZ::AllocatorInstance::Destroy(); AZ::AllocatorInstance::Destroy(); @@ -62,7 +60,7 @@ public: } - const string m_serverOptionsString = "document_root=Gems/Metastream/Files;listening_ports=8082"; + const char* m_serverOptionsString = "document_root=Gems/Metastream/Files;listening_ports=8082"; protected: void SetUp() override diff --git a/Gems/Multiplayer/Code/CMakeLists.txt b/Gems/Multiplayer/Code/CMakeLists.txt index 96527fbfc4..e8b38c8799 100644 --- a/Gems/Multiplayer/Code/CMakeLists.txt +++ b/Gems/Multiplayer/Code/CMakeLists.txt @@ -79,7 +79,7 @@ ly_add_target( # The "Multiplayer" target is used by clients and servers, Debug is used only on clients. ly_create_alias(NAME Multiplayer.Clients NAMESPACE Gem TARGETS Gem::Multiplayer Gem::Multiplayer.Debug) -ly_create_alias(NAME Multiplayer.Servers NAMESPACE Gem TARGETS Gem::Multiplayer) +ly_create_alias(NAME Multiplayer.Servers NAMESPACE Gem TARGETS Gem::Multiplayer Gem::Multiplayer.Debug) if (PAL_TRAIT_BUILD_HOST_TOOLS) ly_add_target( diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/Components/MultiplayerComponent.h b/Gems/Multiplayer/Code/Include/Multiplayer/Components/MultiplayerComponent.h index 8526b6c70b..64ceb6e16f 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/Components/MultiplayerComponent.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/Components/MultiplayerComponent.h @@ -105,14 +105,14 @@ namespace Multiplayer template inline void SerializeNetworkPropertyHelper ( - AzNetworking::ISerializer& serializer, - bool modifyRecord, - AzNetworking::FixedSizeBitsetView& bitset, - int32_t bitIndex, - TYPE& value, - const char* name, - NetComponentId componentId, - PropertyIndex propertyIndex, + AzNetworking::ISerializer& serializer, + bool modifyRecord, + AzNetworking::FixedSizeBitsetView& bitset, + int32_t bitIndex, + TYPE& value, + const char* name, + NetComponentId componentId, + PropertyIndex propertyIndex, MultiplayerStats& stats ) { diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayerDebug.h b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayerDebug.h new file mode 100644 index 0000000000..e528a44ed9 --- /dev/null +++ b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayerDebug.h @@ -0,0 +1,28 @@ +/* + * 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 + * + */ + +#pragma once + +namespace Multiplayer +{ + //! @class IMultiplayerDebug + //! @brief IMultiplayerDebug provides access to multiplayer debug overlays + class IMultiplayerDebug + { + public: + AZ_RTTI(IMultiplayerDebug, "{C5EB7F3A-E19F-4921-A604-C9BDC910123C}"); + + virtual ~IMultiplayerDebug() = default; + + //! Enables printing of debug text over entities that have significant amount of traffic. + virtual void ShowEntityBandwidthDebugOverlay() = 0; + + //! Disables printing of debug text over entities that have significant amount of traffic. + virtual void HideEntityBandwidthDebugOverlay() = 0; + }; +} diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerStats.h b/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerStats.h index d279355d7c..98a7b165f8 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerStats.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerStats.h @@ -50,10 +50,13 @@ namespace Multiplayer AZStd::vector m_componentStats; void ReserveComponentStats(NetComponentId netComponentId, uint16_t propertyCount, uint16_t rpcCount); + void RecordEntitySerializeStart(AzNetworking::SerializerMode mode, AZ::EntityId entityId, const char* entityName); + void RecordComponentSerializeEnd(AzNetworking::SerializerMode mode, NetComponentId netComponentId); + void RecordEntitySerializeStop(AzNetworking::SerializerMode mode, AZ::EntityId entityId, const char* entityName); void RecordPropertySent(NetComponentId netComponentId, PropertyIndex propertyId, uint32_t totalBytes); void RecordPropertyReceived(NetComponentId netComponentId, PropertyIndex propertyId, uint32_t totalBytes); - void RecordRpcSent(NetComponentId netComponentId, RpcIndex rpcId, uint32_t totalBytes); - void RecordRpcReceived(NetComponentId netComponentId, RpcIndex rpcId, uint32_t totalBytes); + void RecordRpcSent(AZ::EntityId entityId, const char* entityName, NetComponentId netComponentId, RpcIndex rpcId, uint32_t totalBytes); + void RecordRpcReceived(AZ::EntityId entityId, const char* entityName, NetComponentId netComponentId, RpcIndex rpcId, uint32_t totalBytes); void TickStats(AZ::TimeMs metricFrameTimeMs); Metric CalculateComponentPropertyUpdateSentMetrics(NetComponentId netComponentId) const; @@ -64,5 +67,31 @@ namespace Multiplayer Metric CalculateTotalPropertyUpdateRecvMetrics() const; Metric CalculateTotalRpcsSentMetrics() const; Metric CalculateTotalRpcsRecvMetrics() const; + + struct Events + { + AZ::Event m_entitySerializeStart; + AZ::Event m_componentSerializeEnd; + AZ::Event m_entitySerializeStop; + AZ::Event m_propertySent; + AZ::Event m_propertyReceived; + AZ::Event m_rpcSent; + AZ::Event m_rpcReceived; + }; + + Events m_events; + + struct EventHandlers + { + AZ::Event::Handler m_entitySerializeStart; + AZ::Event::Handler m_componentSerializeEnd; + AZ::Event::Handler m_entitySerializeStop; + AZ::Event::Handler m_propertySent; + AZ::Event::Handler m_propertyReceived; + AZ::Event::Handler m_rpcSent; + AZ::Event::Handler m_rpcReceived; + }; + + void ConnectHandlers(EventHandlers& handlers); }; } diff --git a/Gems/Multiplayer/Code/Source/Components/NetBindComponent.cpp b/Gems/Multiplayer/Code/Source/Components/NetBindComponent.cpp index e8da34fc7f..cfaeaedeff 100644 --- a/Gems/Multiplayer/Code/Source/Components/NetBindComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Components/NetBindComponent.cpp @@ -447,12 +447,19 @@ namespace Multiplayer bool NetBindComponent::SerializeStateDeltaMessage(ReplicationRecord& replicationRecord, AzNetworking::ISerializer& serializer) { + auto& stats = GetMultiplayer()->GetStats(); + stats.RecordEntitySerializeStart(serializer.GetSerializerMode(), GetEntityId(), GetEntity()->GetName().c_str()); + bool success = true; for (auto iter = m_multiplayerSerializationComponentVector.begin(); iter != m_multiplayerSerializationComponentVector.end(); ++iter) { success &= (*iter)->SerializeStateDeltaMessage(replicationRecord, serializer); + + stats.RecordComponentSerializeEnd(serializer.GetSerializerMode(), (*iter)->GetNetComponentId()); } + stats.RecordEntitySerializeStop(serializer.GetSerializerMode(), GetEntityId(), GetEntity()->GetName().c_str()); + return success; } diff --git a/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugByteReporter.cpp b/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugByteReporter.cpp new file mode 100644 index 0000000000..45305e3b39 --- /dev/null +++ b/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugByteReporter.cpp @@ -0,0 +1,202 @@ +/* + * 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 "MultiplayerDebugByteReporter.h" + +#include // for std::setfill +#include +#include + +namespace Multiplayer +{ + MultiplayerDebugByteReporter::MultiplayerDebugByteReporter() + { + MultiplayerDebugByteReporter::Reset(); + } + + void MultiplayerDebugByteReporter::ReportBytes(size_t byteSize) + { + m_count++; + m_totalBytes += byteSize; + m_totalBytesThisSecond += byteSize; + m_minBytes = AZStd::min(m_minBytes, byteSize); + m_maxBytes = AZStd::max(m_maxBytes, byteSize); + } + + void MultiplayerDebugByteReporter::AggregateBytes(size_t byteSize) + { + m_aggregateBytes += byteSize; + } + + void MultiplayerDebugByteReporter::ReportAggregateBytes() + { + ReportBytes(m_aggregateBytes); + m_aggregateBytes = 0; + } + + float MultiplayerDebugByteReporter::GetAverageBytes() const + { + if (m_count == 0) + { + return 0.0f; + } + + return aznumeric_cast(m_totalBytes) / aznumeric_cast(m_count); + } + + size_t MultiplayerDebugByteReporter::GetMaxBytes() const + { + return m_maxBytes; + } + + size_t MultiplayerDebugByteReporter::GetMinBytes() const + { + return m_minBytes; + } + + size_t MultiplayerDebugByteReporter::GetTotalBytes() const + { + return m_totalBytes; + } + + float MultiplayerDebugByteReporter::GetKbitsPerSecond() + { + const auto now = AZStd::chrono::monotonic_clock::now(); + + // Check the amount of time elapsed and update totals if necessary. + // Time here is measured in whole seconds from the epoch, providing synchronization in + // reporting intervals across all byte reporters. + const AZStd::chrono::seconds nowSeconds = AZStd::chrono::duration_cast(now.time_since_epoch()); + const AZStd::chrono::seconds secondsSinceLastUpdate = nowSeconds - + AZStd::chrono::duration_cast(m_lastUpdateTime.time_since_epoch()); + if (secondsSinceLastUpdate.count()) + { + // normalize over elapsed milliseconds + constexpr int k_millisecondsPerSecond = 1000; + const auto msSinceLastUpdate = AZStd::chrono::duration_cast(now - m_lastUpdateTime); + m_totalBytesLastSecond = k_millisecondsPerSecond * aznumeric_cast(m_totalBytesThisSecond) / aznumeric_cast(msSinceLastUpdate.count()); + m_totalBytesThisSecond = 0; + m_lastUpdateTime = now; + } + + constexpr float bitsPerByte = 8.0f; + constexpr int bitsPerKilobit = 1024; + return bitsPerByte * m_totalBytesLastSecond / bitsPerKilobit; + } + + void MultiplayerDebugByteReporter::Combine(const MultiplayerDebugByteReporter& other) + { + m_count += other.m_count; + m_totalBytes += other.m_totalBytes; + m_totalBytesThisSecond += other.m_totalBytesThisSecond; + m_minBytes = AZStd::GetMin(m_minBytes, other.m_minBytes); + m_maxBytes = AZStd::GetMax(m_maxBytes, other.m_maxBytes); + } + + void MultiplayerDebugByteReporter::Reset() + { + m_count = 0; + m_totalBytes = 0; + m_totalBytesThisSecond = 0; + m_totalBytesLastSecond = 0; + m_minBytes = std::numeric_limits::max(); + m_maxBytes = 0; + m_aggregateBytes = 0; + } + + void MultiplayerDebugComponentReporter::ReportField(const char* fieldName, size_t byteSize) + { + MultiplayerDebugByteReporter::AggregateBytes(byteSize); + m_fieldReports[fieldName].ReportBytes(byteSize); + } + + void MultiplayerDebugComponentReporter::ReportFragmentEnd() + { + MultiplayerDebugByteReporter::ReportAggregateBytes(); + m_componentDirtyBytes.ReportAggregateBytes(); + } + + AZStd::vector MultiplayerDebugComponentReporter::GetFieldReports() + { + AZStd::vector copy; + for (auto field = m_fieldReports.begin(); field != m_fieldReports.end(); ++field) + { + copy.emplace_back(field->first, &field->second); + } + + auto sortByFrequency = [](const Report& a, const Report& b) + { + return a.second->GetTotalCount() > b.second->GetTotalCount(); + }; + + AZStd::sort(copy.begin(), copy.end(), sortByFrequency); + + return copy; + } + + void MultiplayerDebugComponentReporter::Combine(const MultiplayerDebugComponentReporter& other) + { + MultiplayerDebugByteReporter::Combine(other); + + for (const auto& fieldIterator : other.m_fieldReports) + { + m_fieldReports[fieldIterator.first].Combine(fieldIterator.second); + } + + m_componentDirtyBytes.Combine(other.m_componentDirtyBytes); + } + + void MultiplayerDebugEntityReporter::ReportField(AZ::u32 index, const char* componentName, + const char* fieldName, size_t byteSize) + { + if (m_currentComponentReport == nullptr) + { + std::stringstream component; + component << "[" << std::setw(2) << std::setfill('0') << aznumeric_cast(index) << "]" << " " << componentName; + m_currentComponentReport = &m_componentReports[component.str().c_str()]; + } + + m_currentComponentReport->ReportField(fieldName, byteSize); + MultiplayerDebugByteReporter::AggregateBytes(byteSize); + } + + void MultiplayerDebugEntityReporter::ReportFragmentEnd() + { + if (m_currentComponentReport) + { + m_currentComponentReport->ReportFragmentEnd(); + m_currentComponentReport = nullptr; + } + + MultiplayerDebugByteReporter::ReportAggregateBytes(); + } + + void MultiplayerDebugEntityReporter::Combine(const MultiplayerDebugEntityReporter& other) + { + MultiplayerDebugByteReporter::Combine(other); + + for (const auto& componentIterator : other.m_componentReports) + { + m_componentReports[componentIterator.first].Combine(componentIterator.second); + } + + SetEntityName(other.GetEntityName()); + } + + void MultiplayerDebugEntityReporter::Reset() + { + MultiplayerDebugByteReporter::Reset(); + + m_componentReports.clear(); + } + + AZStd::map& MultiplayerDebugEntityReporter::GetComponentReports() + { + return m_componentReports; + } +} diff --git a/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugByteReporter.h b/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugByteReporter.h new file mode 100644 index 0000000000..8f7513d5d4 --- /dev/null +++ b/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugByteReporter.h @@ -0,0 +1,96 @@ +/* + * 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 + * + */ + +#pragma once + +#include +#include +#include +#include + +namespace Multiplayer +{ + class MultiplayerDebugByteReporter + { + public: + MultiplayerDebugByteReporter(); + virtual ~MultiplayerDebugByteReporter() = default; + + void ReportBytes(size_t byteSize); + void AggregateBytes(size_t byteSize); + void ReportAggregateBytes(); + + float GetAverageBytes() const; + size_t GetMaxBytes() const; + size_t GetMinBytes() const; + size_t GetTotalBytes() const; + float GetKbitsPerSecond(); + + void Combine(const MultiplayerDebugByteReporter& other); + virtual void Reset(); + + size_t GetTotalCount() const { return m_count; } + + private: + size_t m_count; + size_t m_totalBytes; + size_t m_totalBytesThisSecond; + float m_totalBytesLastSecond; + size_t m_minBytes; + size_t m_maxBytes; + size_t m_aggregateBytes; + + AZStd::chrono::monotonic_clock::time_point m_lastUpdateTime; + }; + + class MultiplayerDebugComponentReporter final + : public MultiplayerDebugByteReporter + { + public: + MultiplayerDebugComponentReporter() = default; + + void ReportField(const char* fieldName, size_t byteSize); + void ReportFragmentEnd(); + + using Report = AZStd::pair; + AZStd::vector GetFieldReports(); + + void Combine(const MultiplayerDebugComponentReporter& other); + + private: + AZStd::map m_fieldReports; + MultiplayerDebugByteReporter m_componentDirtyBytes; + }; + + class MultiplayerDebugEntityReporter final + : public MultiplayerDebugByteReporter + { + public: + MultiplayerDebugEntityReporter() = default; + + void ReportField(AZ::u32 index, const char* componentName, const char* fieldName, size_t byteSize); + void ReportFragmentEnd(); + + void Combine(const MultiplayerDebugEntityReporter& other); + void Reset() override; + + const char* GetEntityName() const { return m_entityName.c_str(); } + void SetEntityName(const char* entityName) + { + // copying because the entity might go away + m_entityName = entityName; + } + + AZStd::map& GetComponentReports(); + + private: + MultiplayerDebugComponentReporter* m_currentComponentReport = nullptr; + AZStd::map m_componentReports; + AZStd::string m_entityName; + }; +} diff --git a/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugPerEntityReporter.cpp b/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugPerEntityReporter.cpp new file mode 100644 index 0000000000..adfef397b6 --- /dev/null +++ b/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugPerEntityReporter.cpp @@ -0,0 +1,389 @@ +/* + * 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 "MultiplayerDebugPerEntityReporter.h" + +#include +#include +#include +#include + +#if defined(IMGUI_ENABLED) +#include +#endif + +AZ_CVAR(float, net_DebugEntities_ShowAboveKbps, 1.f, nullptr, AZ::ConsoleFunctorFlags::Null, + "Prints bandwidth on network entities with higher kpbs than this value"); + +AZ_CVAR(float, net_DebugEntities_WarnAboveKbps, 10.f, nullptr, AZ::ConsoleFunctorFlags::Null, + "Prints bandwidth on network entities with higher kpbs than this value"); + +AZ_CVAR(AZ::Color, net_DebugEntities_WarningColor, AZ::Colors::Red, nullptr, AZ::ConsoleFunctorFlags::Null, + "If true, prints debug text over entities that use a considerable amount of network traffic"); + +AZ_CVAR(AZ::Color, net_DebugEntities_BelowWarningColor, AZ::Colors::Grey, nullptr, AZ::ConsoleFunctorFlags::Null, + "If true, prints debug text over entities that use a considerable amount of network traffic"); + +namespace Multiplayer +{ +#if defined(IMGUI_ENABLED) + static const ImVec4 k_ImGuiTomato = ImVec4(1.0f, 0.4f, 0.3f, 1.0f); + static const ImVec4 k_ImGuiKhaki = ImVec4(0.9f, 0.8f, 0.5f, 1.0f); + static const ImVec4 k_ImGuiCyan = ImVec4(0.5f, 1.0f, 1.0f, 1.0f); + static const ImVec4 k_ImGuiDusk = ImVec4(0.7f, 0.7f, 1.0f, 1.0f); + static const ImVec4 k_ImGuiWhite = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); + + // -------------------------------------------------------------------------------------------- + template + bool ReplicatedStateTreeNode(const AZStd::string& name, Reporter& report, const ImVec4& color, int depth = 0) + { + const int defaultPadAmount = 55; + const int depthReduction = 3; + ImGui::PushStyleColor(ImGuiCol_Text, color); + + const bool expanded = ImGui::TreeNode(name.c_str(), + "%-*s %7.2f kbps %7.2f B Avg. %4zu B Max %10zu B Payload", + defaultPadAmount - depthReduction * depth, + name.c_str(), + report.GetKbitsPerSecond(), + report.GetAverageBytes(), + report.GetMaxBytes(), + report.GetTotalBytes()); + ImGui::PopStyleColor(); + return expanded; + } + + // -------------------------------------------------------------------------------------------- + void DisplayReplicatedStateReport(AZStd::map& componentReports, float kbpsWarn, float maxWarn) + { + for (auto& componentPair : componentReports) + { + ImGui::Separator(); + MultiplayerDebugComponentReporter& componentReport = componentPair.second; + + if (ReplicatedStateTreeNode(componentPair.first, componentReport, k_ImGuiCyan, 1)) + { + ImGui::Separator(); + ImGui::Columns(6, "replicated_field_columns"); + ImGui::NextColumn(); + ImGui::Text("kbps"); + ImGui::NextColumn(); + ImGui::Text("Avg. Bytes"); + ImGui::NextColumn(); + ImGui::Text("Min Bytes"); + ImGui::NextColumn(); + ImGui::Text("Max Bytes"); + ImGui::NextColumn(); + ImGui::Text("Total Bytes"); + ImGui::NextColumn(); + + auto fieldReports = componentReport.GetFieldReports(); + for (auto& fieldPair : fieldReports) + { + MultiplayerDebugByteReporter& fieldReport = *fieldPair.second; + const float kbitsLastSecond = fieldReport.GetKbitsPerSecond(); + + const ImVec4* textColor = &k_ImGuiWhite; + if (aznumeric_cast(fieldReport.GetMaxBytes()) > maxWarn) + { + textColor = &k_ImGuiKhaki; + } + + if (kbitsLastSecond > kbpsWarn) + { + textColor = &k_ImGuiTomato; + } + + ImGui::PushStyleColor(ImGuiCol_Text, *textColor); + + ImGui::Text("%s", fieldPair.first.c_str()); + ImGui::NextColumn(); + ImGui::Text("%.2f", kbitsLastSecond); + ImGui::NextColumn(); + ImGui::Text("%.2f", fieldReport.GetAverageBytes()); + ImGui::NextColumn(); + ImGui::Text("%zu", fieldReport.GetMinBytes()); + ImGui::NextColumn(); + ImGui::Text("%zu", fieldReport.GetMaxBytes()); + ImGui::NextColumn(); + ImGui::Text("%zu", fieldReport.GetTotalBytes()); + ImGui::NextColumn(); + + ImGui::PopStyleColor(); + } + + ImGui::Columns(1); + ImGui::TreePop(); + } + } + } +#endif + + MultiplayerDebugPerEntityReporter::MultiplayerDebugPerEntityReporter() + : m_updateDebugOverlay([this]() { UpdateDebugOverlay(); }, AZ::Name("UpdateDebugPerEntityOverlay")) + { + m_updateDebugOverlay.Enqueue(AZ::TimeMs{ 0 }, true); + + m_eventHandlers.m_entitySerializeStart = decltype(m_eventHandlers.m_entitySerializeStart)([this](AzNetworking::SerializerMode mode, AZ::EntityId entityId, const char* entityName) + { + RecordEntitySerializeStart(mode, entityId, entityName); + }); + m_eventHandlers.m_componentSerializeEnd = decltype(m_eventHandlers.m_componentSerializeEnd)([this](AzNetworking::SerializerMode mode, + NetComponentId netComponentId) + { + RecordComponentSerializeEnd(mode, netComponentId); + }); + m_eventHandlers.m_entitySerializeStop = decltype(m_eventHandlers.m_entitySerializeStop)([this](AzNetworking::SerializerMode mode, AZ::EntityId entityId, const char* entityName) + { + RecordEntitySerializeStop(mode, entityId, entityName); + }); + m_eventHandlers.m_propertySent = decltype(m_eventHandlers.m_propertySent)([this](NetComponentId netComponentId, + PropertyIndex propertyId, uint32_t totalBytes) + { + RecordPropertySent(netComponentId, propertyId, totalBytes); + }); + m_eventHandlers.m_propertyReceived = decltype(m_eventHandlers.m_propertyReceived)([this](NetComponentId netComponentId, + PropertyIndex propertyId, uint32_t totalBytes) + { + RecordPropertyReceived(netComponentId, propertyId, totalBytes); + }); + m_eventHandlers.m_rpcSent = decltype(m_eventHandlers.m_rpcSent)([this](AZ::EntityId entityId, const char* entityName, + NetComponentId netComponentId, + RpcIndex rpcId, uint32_t totalBytes) + { + RecordRpcSent(entityId, entityName, netComponentId, rpcId, totalBytes); + }); + m_eventHandlers.m_rpcReceived = decltype(m_eventHandlers.m_rpcReceived)([this](AZ::EntityId entityId, const char* entityName, + NetComponentId netComponentId, + RpcIndex rpcId, uint32_t totalBytes) + { + RecordRpcSent(entityId, entityName, netComponentId, rpcId, totalBytes); + }); + + GetMultiplayer()->GetStats().ConnectHandlers(m_eventHandlers); + } + + // -------------------------------------------------------------------------------------------- + void MultiplayerDebugPerEntityReporter::OnImGuiUpdate() + { +#if defined(IMGUI_ENABLED) + static ImGuiTextFilter filter; + filter.Draw(); + + if (ImGui::CollapsingHeader("Receiving Entities")) + { + for (AZStd::pair& entityPair : m_receivingEntityReports) + { + if (!filter.PassFilter(entityPair.second.GetEntityName())) + { + continue; + } + + ImGui::Separator(); + if (ReplicatedStateTreeNode(entityPair.second.GetEntityName(), entityPair.second, k_ImGuiDusk)) + { + DisplayReplicatedStateReport(entityPair.second.GetComponentReports(), m_replicatedStateKbpsWarn, m_replicatedStateMaxSizeWarn); + ImGui::TreePop(); + } + } + } + + if (ImGui::CollapsingHeader("Sending Entities")) + { + for (AZStd::pair& entityPair : m_sendingEntityReports) + { + const char* name = entityPair.second.GetEntityName(); + if (!filter.PassFilter(name)) + { + continue; + } + + ImGui::Separator(); + if (ReplicatedStateTreeNode(name, entityPair.second, k_ImGuiDusk)) + { + DisplayReplicatedStateReport(entityPair.second.GetComponentReports(), m_replicatedStateKbpsWarn, m_replicatedStateMaxSizeWarn); + ImGui::TreePop(); + } + } + } +#endif + } + + void MultiplayerDebugPerEntityReporter::RecordEntitySerializeStart(AzNetworking::SerializerMode mode, + [[maybe_unused]] AZ::EntityId entityId, [[maybe_unused]] const char* entityName) + { + switch (mode) + { + case AzNetworking::SerializerMode::ReadFromObject: + m_currentSendingEntityReport.Reset(); + m_currentSendingEntityReport.SetEntityName(entityName); + break; + case AzNetworking::SerializerMode::WriteToObject: + m_currentReceivingEntityReport.Reset(); + m_currentReceivingEntityReport.SetEntityName(entityName); + break; + } + } + + void MultiplayerDebugPerEntityReporter::RecordComponentSerializeEnd(AzNetworking::SerializerMode mode, [[maybe_unused]] NetComponentId + netComponentId) + { + switch (mode) + { + case AzNetworking::SerializerMode::ReadFromObject: + m_currentSendingEntityReport.ReportFragmentEnd(); + break; + case AzNetworking::SerializerMode::WriteToObject: + m_currentReceivingEntityReport.ReportFragmentEnd(); + break; + } + } + + void MultiplayerDebugPerEntityReporter::RecordEntitySerializeStop(AzNetworking::SerializerMode mode, + [[maybe_unused]] AZ::EntityId entityId, [[maybe_unused]] const char* entityName) + { + switch (mode) + { + case AzNetworking::SerializerMode::ReadFromObject: + m_sendingEntityReports[entityId].Combine(m_currentSendingEntityReport); + break; + case AzNetworking::SerializerMode::WriteToObject: + m_receivingEntityReports[entityId].Combine(m_currentReceivingEntityReport); + break; + } + } + + void MultiplayerDebugPerEntityReporter::RecordPropertySent( + NetComponentId netComponentId, + PropertyIndex propertyId, + uint32_t totalBytes) + { + if (const MultiplayerComponentRegistry* componentRegistry = GetMultiplayerComponentRegistry()) + { + m_currentSendingEntityReport.ReportField(static_cast(netComponentId), + componentRegistry->GetComponentName(netComponentId), + componentRegistry->GetComponentPropertyName(netComponentId, propertyId), totalBytes); + } + } + + void MultiplayerDebugPerEntityReporter::RecordPropertyReceived( + NetComponentId netComponentId, + PropertyIndex propertyId, + uint32_t totalBytes) + { + if (const MultiplayerComponentRegistry* componentRegistry = GetMultiplayerComponentRegistry()) + { + m_currentReceivingEntityReport.ReportField(static_cast(netComponentId), + componentRegistry->GetComponentName(netComponentId), + componentRegistry->GetComponentPropertyName(netComponentId, propertyId), totalBytes); + } + } + + void MultiplayerDebugPerEntityReporter::RecordRpcSent(AZ::EntityId entityId, const char* entityName, NetComponentId netComponentId, + RpcIndex rpcId, uint32_t totalBytes) + { + if (const MultiplayerComponentRegistry* componentRegistry = GetMultiplayerComponentRegistry()) + { + // MultiplayerDebugByteReporter requires a + RecordEntitySerializeStart(AzNetworking::SerializerMode::ReadFromObject, entityId, entityName); + + m_currentSendingEntityReport.ReportField(static_cast(netComponentId), + componentRegistry->GetComponentName(netComponentId), + componentRegistry->GetComponentRpcName(netComponentId, rpcId), totalBytes); + + RecordComponentSerializeEnd(AzNetworking::SerializerMode::ReadFromObject, netComponentId); + RecordEntitySerializeStop(AzNetworking::SerializerMode::ReadFromObject, entityId, entityName); + } + } + + void MultiplayerDebugPerEntityReporter::RecordRpcReceived( + AZ::EntityId entityId, const char* entityName, + NetComponentId netComponentId, + RpcIndex rpcId, + uint32_t totalBytes) + { + if (const MultiplayerComponentRegistry* componentRegistry = GetMultiplayerComponentRegistry()) + { + RecordEntitySerializeStart(AzNetworking::SerializerMode::WriteToObject, entityId, entityName); + + m_currentReceivingEntityReport.ReportField(static_cast(netComponentId), + componentRegistry->GetComponentName(netComponentId), + componentRegistry->GetComponentRpcName(netComponentId, rpcId), totalBytes); + + RecordComponentSerializeEnd(AzNetworking::SerializerMode::WriteToObject, netComponentId); + RecordEntitySerializeStop(AzNetworking::SerializerMode::WriteToObject, entityId, entityName); + } + } + + void MultiplayerDebugPerEntityReporter::UpdateDebugOverlay() + { + m_networkEntitiesTraffic.clear(); + + // Merging up and down traffic to provide a unified debug text per entity + for (AZStd::pair& entityPair : m_receivingEntityReports) + { + m_networkEntitiesTraffic[entityPair.first].m_name = entityPair.second.GetEntityName(); + m_networkEntitiesTraffic[entityPair.first].m_down = entityPair.second.GetKbitsPerSecond(); + } + for (AZStd::pair& entityPair : m_sendingEntityReports) + { + m_networkEntitiesTraffic[entityPair.first].m_name = entityPair.second.GetEntityName(); + m_networkEntitiesTraffic[entityPair.first].m_up = entityPair.second.GetKbitsPerSecond(); + } + + if (m_debugDisplay == nullptr) + { + AzFramework::DebugDisplayRequestBus::BusPtr debugDisplayBus; + AzFramework::DebugDisplayRequestBus::Bind(debugDisplayBus, AzFramework::g_defaultSceneEntityDebugDisplayId); + m_debugDisplay = AzFramework::DebugDisplayRequestBus::FindFirstHandler(debugDisplayBus); + } + + const AZ::u32 stateBefore = m_debugDisplay->GetState(); + + for (const AZStd::pair& networkEntity : m_networkEntitiesTraffic) + { + if (networkEntity.second.m_down < net_DebugEntities_ShowAboveKbps && networkEntity.second.m_up < net_DebugEntities_ShowAboveKbps) + { + continue; + } + + if (networkEntity.second.m_down > net_DebugEntities_WarnAboveKbps || networkEntity.second.m_up > net_DebugEntities_WarnAboveKbps) + { + m_debugDisplay->SetColor(net_DebugEntities_WarningColor); + } + else + { + m_debugDisplay->SetColor(net_DebugEntities_BelowWarningColor); + } + + if (networkEntity.second.m_down > net_DebugEntities_ShowAboveKbps && networkEntity.second.m_up > net_DebugEntities_ShowAboveKbps) + { + azsprintf(m_statusBuffer, "[%s] %.0f down / %0.f up (kbps)", networkEntity.second.m_name, + networkEntity.second.m_down, networkEntity.second.m_up); + } + else if (networkEntity.second.m_down > net_DebugEntities_ShowAboveKbps) + { + azsprintf(m_statusBuffer, "[%s] %.0f down (kbps)", networkEntity.second.m_name, networkEntity.second.m_down); + } + else + { + azsprintf(m_statusBuffer, "[%s] %.0f up (kbps)", networkEntity.second.m_name, networkEntity.second.m_up); + } + + AZ::Vector3 entityPosition = AZ::Vector3::CreateZero(); + AZ::TransformBus::EventResult(entityPosition, networkEntity.first, &AZ::TransformBus::Events::GetWorldTranslation); + if (entityPosition.IsZero() == false) + { + constexpr bool centerText = true; + m_debugDisplay->DrawTextLabel(entityPosition, 1.0f, m_statusBuffer, centerText, 0, 0); + } + } + + m_debugDisplay->SetState(stateBefore); + } +} diff --git a/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugPerEntityReporter.h b/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugPerEntityReporter.h new file mode 100644 index 0000000000..8a68110b93 --- /dev/null +++ b/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugPerEntityReporter.h @@ -0,0 +1,72 @@ +/* + * 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 + * + */ + +#pragma once +#include "MultiplayerDebugByteReporter.h" + +#include +#include +#include +#include +#include + +namespace Multiplayer +{ + /** + * \brief Multiplayer traffic live analysis tool via ImGui. + */ + class MultiplayerDebugPerEntityReporter + { + public: + MultiplayerDebugPerEntityReporter(); + + //! main update loop + void OnImGuiUpdate(); + + //! Event handlers + // @{ + void RecordEntitySerializeStart(AzNetworking::SerializerMode mode, AZ::EntityId entityId, const char* entityName); + void RecordComponentSerializeEnd(AzNetworking::SerializerMode mode, NetComponentId netComponentId); + void RecordEntitySerializeStop(AzNetworking::SerializerMode mode, AZ::EntityId entityId, const char* entityName); + void RecordPropertySent(NetComponentId netComponentId, PropertyIndex propertyId, uint32_t totalBytes); + void RecordPropertyReceived(NetComponentId netComponentId, PropertyIndex propertyId, uint32_t totalBytes); + void RecordRpcSent(AZ::EntityId entityId, const char* entityName, NetComponentId netComponentId, RpcIndex rpcId, uint32_t totalBytes); + void RecordRpcReceived(AZ::EntityId entityId, const char* entityName, NetComponentId netComponentId, RpcIndex rpcId, uint32_t totalBytes); + // }@ + + //! Draws bandwidth text over entities + void UpdateDebugOverlay(); + + private: + + AZ::ScheduledEvent m_updateDebugOverlay; + MultiplayerStats::EventHandlers m_eventHandlers; + + AZStd::map m_sendingEntityReports{}; + MultiplayerDebugEntityReporter m_currentSendingEntityReport; + + AZStd::map m_receivingEntityReports{}; + MultiplayerDebugEntityReporter m_currentReceivingEntityReport; + + float m_replicatedStateKbpsWarn = 10.f; + float m_replicatedStateMaxSizeWarn = 30.f; + + char m_statusBuffer[100] = {}; + + struct NetworkEntityTraffic + { + const char* m_name = nullptr; + float m_up = 0.f; + float m_down = 0.f; + }; + + AZStd::unordered_map m_networkEntitiesTraffic; + + AzFramework::DebugDisplayRequests* m_debugDisplay = nullptr; + }; +} diff --git a/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugSystemComponent.cpp index 4d2d47444c..27a4dff485 100644 --- a/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugSystemComponent.cpp @@ -13,6 +13,11 @@ #include #include +void OnDebugEntities_ShowBandwidth_Changed(const bool& showBandwidth); + +AZ_CVAR(bool, net_DebugEntities_ShowBandwidth, false, &OnDebugEntities_ShowBandwidth_Changed, AZ::ConsoleFunctorFlags::Null, + "If true, prints bandwidth values over entities that use a considerable amount of network traffic"); + namespace Multiplayer { void MultiplayerDebugSystemComponent::Reflect(AZ::ReflectContext* context) @@ -47,6 +52,17 @@ namespace Multiplayer ImGui::ImGuiUpdateListenerBus::Handler::BusDisconnect(); #endif } + + void MultiplayerDebugSystemComponent::ShowEntityBandwidthDebugOverlay() + { + m_reporter = AZStd::make_unique(); + } + + void MultiplayerDebugSystemComponent::HideEntityBandwidthDebugOverlay() + { + m_reporter.reset(); + } + #ifdef IMGUI_ENABLED void MultiplayerDebugSystemComponent::OnImGuiMainMenuUpdate() { @@ -54,6 +70,7 @@ namespace Multiplayer { ImGui::Checkbox("Networking Stats", &m_displayNetworkingStats); ImGui::Checkbox("Multiplayer Stats", &m_displayMultiplayerStats); + ImGui::Checkbox("Multiplayer Entity Stats", &m_displayPerEntityStats); ImGui::EndMenu(); } } @@ -432,6 +449,36 @@ namespace Multiplayer DrawMultiplayerStats(); } } + + if (m_displayPerEntityStats) + { + if (ImGui::Begin("Multiplayer Per Entity Stats", &m_displayPerEntityStats, ImGuiWindowFlags_AlwaysAutoResize)) + { + // This overrides @net_DebugNetworkEntity_ShowBandwidth value + if (m_reporter == nullptr) + { + ShowEntityBandwidthDebugOverlay(); + } + + if (m_reporter) + { + m_reporter->OnImGuiUpdate(); + } + } + } } #endif } + +void OnDebugEntities_ShowBandwidth_Changed(const bool& showBandwidth) +{ + if (showBandwidth) + { + AZ::Interface::Get()->ShowEntityBandwidthDebugOverlay(); + } + else + { + AZ::Interface::Get()->HideEntityBandwidthDebugOverlay(); + } +} + diff --git a/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugSystemComponent.h b/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugSystemComponent.h index 77daaf9b7d..7b3c852f58 100644 --- a/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugSystemComponent.h +++ b/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugSystemComponent.h @@ -9,6 +9,9 @@ #pragma once #include +#include +#include +#include #ifdef IMGUI_ENABLED # include @@ -19,6 +22,7 @@ namespace Multiplayer { class MultiplayerDebugSystemComponent final : public AZ::Component + , public AZ::Interface::Registrar #ifdef IMGUI_ENABLED , public ImGui::ImGuiUpdateListenerBus::Handler #endif @@ -29,7 +33,7 @@ namespace Multiplayer static void Reflect(AZ::ReflectContext* context); static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatbile); + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); ~MultiplayerDebugSystemComponent() override = default; @@ -39,6 +43,12 @@ namespace Multiplayer void Deactivate() override; //! @} + //! IMultiplayerDebug overrides + //! @{ + void ShowEntityBandwidthDebugOverlay() override; + void HideEntityBandwidthDebugOverlay() override; + //! @} + #ifdef IMGUI_ENABLED //! ImGui::ImGuiUpdateListenerBus overrides //! @{ @@ -49,5 +59,8 @@ namespace Multiplayer private: bool m_displayNetworkingStats = false; bool m_displayMultiplayerStats = false; + + bool m_displayPerEntityStats = false; + AZStd::unique_ptr m_reporter; }; } diff --git a/Gems/Multiplayer/Code/Source/MultiplayerStats.cpp b/Gems/Multiplayer/Code/Source/MultiplayerStats.cpp index 6ee9f09cf7..7e56cd34f3 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerStats.cpp +++ b/Gems/Multiplayer/Code/Source/MultiplayerStats.cpp @@ -29,6 +29,21 @@ namespace Multiplayer m_componentStats[netComponentIndex].m_rpcsRecv.resize(rpcCount); } + void MultiplayerStats::RecordEntitySerializeStart(AzNetworking::SerializerMode mode, AZ::EntityId entityId, const char* entityName) + { + m_events.m_entitySerializeStart.Signal(mode, entityId, entityName); + } + + void MultiplayerStats::RecordComponentSerializeEnd(AzNetworking::SerializerMode mode, NetComponentId netComponentId) + { + m_events.m_componentSerializeEnd.Signal(mode, netComponentId); + } + + void MultiplayerStats::RecordEntitySerializeStop(AzNetworking::SerializerMode mode, AZ::EntityId entityId, const char* entityName) + { + m_events.m_entitySerializeStop.Signal(mode, entityId, entityName); + } + void MultiplayerStats::RecordPropertySent(NetComponentId netComponentId, PropertyIndex propertyId, uint32_t totalBytes) { const uint16_t netComponentIndex = aznumeric_cast(netComponentId); @@ -37,6 +52,8 @@ namespace Multiplayer m_componentStats[netComponentIndex].m_propertyUpdatesSent[propertyIndex].m_totalBytes += totalBytes; m_componentStats[netComponentIndex].m_propertyUpdatesSent[propertyIndex].m_callHistory[m_recordMetricIndex]++; m_componentStats[netComponentIndex].m_propertyUpdatesSent[propertyIndex].m_byteHistory[m_recordMetricIndex] += totalBytes; + + m_events.m_propertySent.Signal(netComponentId, propertyId, totalBytes); } void MultiplayerStats::RecordPropertyReceived(NetComponentId netComponentId, PropertyIndex propertyId, uint32_t totalBytes) @@ -47,9 +64,11 @@ namespace Multiplayer m_componentStats[netComponentIndex].m_propertyUpdatesRecv[propertyIndex].m_totalBytes += totalBytes; m_componentStats[netComponentIndex].m_propertyUpdatesRecv[propertyIndex].m_callHistory[m_recordMetricIndex]++; m_componentStats[netComponentIndex].m_propertyUpdatesRecv[propertyIndex].m_byteHistory[m_recordMetricIndex] += totalBytes; + + m_events.m_propertyReceived.Signal(netComponentId, propertyId, totalBytes); } - void MultiplayerStats::RecordRpcSent(NetComponentId netComponentId, RpcIndex rpcId, uint32_t totalBytes) + void MultiplayerStats::RecordRpcSent(AZ::EntityId entityId, const char* entityName, NetComponentId netComponentId, RpcIndex rpcId, uint32_t totalBytes) { const uint16_t netComponentIndex = aznumeric_cast(netComponentId); const uint16_t rpcIndex = aznumeric_cast(rpcId); @@ -57,9 +76,11 @@ namespace Multiplayer m_componentStats[netComponentIndex].m_rpcsSent[rpcIndex].m_totalBytes += totalBytes; m_componentStats[netComponentIndex].m_rpcsSent[rpcIndex].m_callHistory[m_recordMetricIndex]++; m_componentStats[netComponentIndex].m_rpcsSent[rpcIndex].m_byteHistory[m_recordMetricIndex] += totalBytes; + + m_events.m_rpcSent.Signal(entityId, entityName, netComponentId, rpcId, totalBytes); } - void MultiplayerStats::RecordRpcReceived(NetComponentId netComponentId, RpcIndex rpcId, uint32_t totalBytes) + void MultiplayerStats::RecordRpcReceived(AZ::EntityId entityId, const char* entityName, NetComponentId netComponentId, RpcIndex rpcId, uint32_t totalBytes) { const uint16_t netComponentIndex = aznumeric_cast(netComponentId); const uint16_t rpcIndex = aznumeric_cast(rpcId); @@ -67,6 +88,8 @@ namespace Multiplayer m_componentStats[netComponentIndex].m_rpcsRecv[rpcIndex].m_totalBytes += totalBytes; m_componentStats[netComponentIndex].m_rpcsRecv[rpcIndex].m_callHistory[m_recordMetricIndex]++; m_componentStats[netComponentIndex].m_rpcsRecv[rpcIndex].m_byteHistory[m_recordMetricIndex] += totalBytes; + + m_events.m_rpcReceived.Signal(entityId, entityName, netComponentId, rpcId, totalBytes); } void MultiplayerStats::TickStats(AZ::TimeMs metricFrameTimeMs) @@ -186,4 +209,15 @@ namespace Multiplayer } return result; } + + void MultiplayerStats::ConnectHandlers(EventHandlers& handlers) + { + handlers.m_entitySerializeStart.Connect(m_events.m_entitySerializeStart); + handlers.m_componentSerializeEnd.Connect(m_events.m_componentSerializeEnd); + handlers.m_entitySerializeStop.Connect(m_events.m_entitySerializeStop); + handlers.m_propertySent.Connect(m_events.m_propertySent); + handlers.m_propertyReceived.Connect(m_events.m_propertyReceived); + handlers.m_rpcSent.Connect(m_events.m_rpcSent); + handlers.m_rpcReceived.Connect(m_events.m_rpcReceived); + } } diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.cpp index eb51c3c478..14df1bb028 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.cpp @@ -441,7 +441,8 @@ namespace Multiplayer { // Received rpc metrics, log rpc sent, number of bytes, and the componentId/rpcId for bandwidth metrics MultiplayerStats& stats = GetMultiplayer()->GetStats(); - stats.RecordRpcSent(entityRpcMessage.GetComponentId(), entityRpcMessage.GetRpcIndex(), entityRpcMessage.GetEstimatedSerializeSize()); + stats.RecordRpcSent(GetEntityHandle().GetEntity()->GetId(), GetEntityHandle().GetEntity()->GetName().c_str(), + entityRpcMessage.GetComponentId(), entityRpcMessage.GetRpcIndex(), entityRpcMessage.GetEstimatedSerializeSize()); m_replicationManager.AddDeferredRpcMessage(entityRpcMessage); } @@ -515,7 +516,7 @@ namespace Multiplayer && (GetRemoteNetworkRole() == NetEntityRole::Server)) { // We are on a server, and we received this message from another server, therefore we should forward this to our autonomous player - // This can occur if we've recently migrated + // This can occur if we've recently migrated result = RpcValidationResult::ForwardToAutonomous; } } @@ -624,7 +625,8 @@ namespace Multiplayer { // Received rpc metrics, log rpc received, time spent, number of bytes, and the componentId/rpcId for bandwidth metrics MultiplayerStats& stats = GetMultiplayer()->GetStats(); - stats.RecordRpcReceived(entityRpcMessage.GetComponentId(), entityRpcMessage.GetRpcIndex(), entityRpcMessage.GetEstimatedSerializeSize()); + stats.RecordRpcReceived(GetEntityHandle().GetEntity()->GetId(), GetEntityHandle().GetEntity()->GetName().c_str(), + entityRpcMessage.GetComponentId(), entityRpcMessage.GetRpcIndex(), entityRpcMessage.GetEstimatedSerializeSize()); if (!m_netBindComponent) { diff --git a/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp b/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp index d49f6901f3..acfec5eb38 100644 --- a/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp +++ b/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp @@ -56,7 +56,7 @@ namespace Multiplayer // convert Prefab DOM into Prefab Instance. AZStd::unique_ptr sourceInstance(aznew Instance()); - if (!PrefabDomUtils::LoadInstanceFromPrefabDom(*sourceInstance, prefab, PrefabDomUtils::LoadInstanceFlags::AssignRandomEntityId)) + if (!PrefabDomUtils::LoadInstanceFromPrefabDom(*sourceInstance, prefab, PrefabDomUtils::LoadFlags::AssignRandomEntityId)) { PrefabDomValueConstReference sourceReference = PrefabDomUtils::FindPrefabDomValue(prefab, PrefabDomUtils::SourceName); diff --git a/Gems/Multiplayer/Code/multiplayer_debug_files.cmake b/Gems/Multiplayer/Code/multiplayer_debug_files.cmake index 62bd632e7e..37a1c91640 100644 --- a/Gems/Multiplayer/Code/multiplayer_debug_files.cmake +++ b/Gems/Multiplayer/Code/multiplayer_debug_files.cmake @@ -7,6 +7,10 @@ # set(FILES + Source/Debug/MultiplayerDebugByteReporter.cpp + Source/Debug/MultiplayerDebugByteReporter.h + Source/Debug/MultiplayerDebugPerEntityReporter.cpp + Source/Debug/MultiplayerDebugPerEntityReporter.h Source/Debug/MultiplayerDebugModule.cpp Source/Debug/MultiplayerDebugModule.h Source/Debug/MultiplayerDebugSystemComponent.cpp diff --git a/Gems/Multiplayer/Code/multiplayer_files.cmake b/Gems/Multiplayer/Code/multiplayer_files.cmake index 7392ea6856..0b2adb1530 100644 --- a/Gems/Multiplayer/Code/multiplayer_files.cmake +++ b/Gems/Multiplayer/Code/multiplayer_files.cmake @@ -8,6 +8,7 @@ set(FILES Include/Multiplayer/IMultiplayer.h + Include/Multiplayer/IMultiplayerDebug.h Include/Multiplayer/IMultiplayerTools.h Include/Multiplayer/MultiplayerConstants.h Include/Multiplayer/MultiplayerStats.h diff --git a/Gems/PhysX/Code/CMakeLists.txt b/Gems/PhysX/Code/CMakeLists.txt index a69019249f..80e8bee8e3 100644 --- a/Gems/PhysX/Code/CMakeLists.txt +++ b/Gems/PhysX/Code/CMakeLists.txt @@ -186,7 +186,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) ly_add_googlebenchmark( NAME Gem::PhysX.Benchmarks TARGET Gem::PhysX.Tests - TIMEOUT 1500 #25mins ) list(APPEND testTargets PhysX.Tests) diff --git a/Gems/PhysXDebug/Code/Source/SystemComponent.cpp b/Gems/PhysXDebug/Code/Source/SystemComponent.cpp index 138ca0822c..831a7fdf1d 100644 --- a/Gems/PhysXDebug/Code/Source/SystemComponent.cpp +++ b/Gems/PhysXDebug/Code/Source/SystemComponent.cpp @@ -30,7 +30,7 @@ #include #include -#include +#include #include @@ -586,8 +586,6 @@ namespace PhysXDebug static void physx_Debug([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments) { - using namespace CryStringUtils; - const size_t argumentCount = arguments.size(); if (argumentCount == 1) @@ -705,7 +703,7 @@ namespace PhysXDebug if (GetCurrentPxScene()) { // Reserve vector capacity - const int numTriangles = rb.getNbTriangles(); + const physx::PxU32 numTriangles = static_cast(rb.getNbTriangles()); m_trianglePoints.reserve(numTriangles * 3); m_triangleColors.reserve(numTriangles * 3); @@ -739,7 +737,7 @@ namespace PhysXDebug if (GetCurrentPxScene()) { - const int numLines = rb.getNbLines(); + const physx::PxU32 numLines = static_cast(rb.getNbLines()); // Reserve vector capacity m_linePoints.reserve(numLines * 2); diff --git a/Gems/PhysXDebug/Code/Source/SystemComponent.h b/Gems/PhysXDebug/Code/Source/SystemComponent.h index 40434ad3e1..83756f20f9 100644 --- a/Gems/PhysXDebug/Code/Source/SystemComponent.h +++ b/Gems/PhysXDebug/Code/Source/SystemComponent.h @@ -18,6 +18,7 @@ #include #include +#include #include diff --git a/Gems/SaveData/Code/Source/Platform/Windows/SaveData_SystemComponent_Windows.cpp b/Gems/SaveData/Code/Source/Platform/Windows/SaveData_SystemComponent_Windows.cpp index 236b2f525c..2e473cfea7 100644 --- a/Gems/SaveData/Code/Source/Platform/Windows/SaveData_SystemComponent_Windows.cpp +++ b/Gems/SaveData/Code/Source/Platform/Windows/SaveData_SystemComponent_Windows.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -99,7 +100,7 @@ namespace SaveData AZStd::string GetExecutableName() { char moduleFileName[AZ_MAX_PATH_LEN]; - GetModuleFileNameA(nullptr, moduleFileName, AZ_MAX_PATH_LEN); + AZ::Utils::GetExecutablePath(moduleFileName, AZ_MAX_PATH_LEN); const AZStd::string moduleFileNameString(moduleFileName); const size_t executableNameStart = moduleFileNameString.find_last_of('\\') + 1; diff --git a/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp b/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp index 7541e2fce7..a410c4e6c9 100644 --- a/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp +++ b/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp @@ -379,10 +379,12 @@ namespace AZ::SceneGenerationComponents auto [optimizedMesh, optimizedUVs, optimizedTangents, optimizedBitangents, optimizedVertexColors, optimizedSkinWeights] = OptimizeMesh(mesh, mesh, uvDatas, tangentDatas, bitangentDatas, colorDatas, skinWeightDatas, meshGroup, hasBlendShapes); - AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "Base mesh: %zu vertices, optimized mesh: %zu vertices, %0.02f%% of the original", + AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "Optimized mesh '%s': Original: %zu vertices -> optimized: %zu vertices, %0.02f%% of the original (hasBlendShapes=%s)", + graph.GetNodeName(nodeIndex).GetName(), mesh->GetUsedControlPointCount(), optimizedMesh->GetUsedControlPointCount(), - ((float)optimizedMesh->GetUsedControlPointCount() / (float)mesh->GetUsedControlPointCount()) * 100.0f + ((float)optimizedMesh->GetUsedControlPointCount() / (float)mesh->GetUsedControlPointCount()) * 100.0f, + hasBlendShapes ? "Yes" : "No" ); const NodeIndex optimizedMeshNodeIndex = graph.AddChild(graph.GetNodeParent(nodeIndex), name.c_str(), AZStd::move(optimizedMesh)); diff --git a/Gems/ScriptCanvas/Code/Editor/Utilities/RecentFiles.cpp b/Gems/ScriptCanvas/Code/Editor/Utilities/RecentFiles.cpp index fa665bb48f..84ee2a8ff8 100644 --- a/Gems/ScriptCanvas/Code/Editor/Utilities/RecentFiles.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Utilities/RecentFiles.cpp @@ -8,6 +8,7 @@ #include "RecentFiles.h" #include "CommonSettingsConfigurations.h" +#include #include #include diff --git a/cmake/LYTestWrappers.cmake b/cmake/LYTestWrappers.cmake index efb19a20dd..8e71cb3db1 100644 --- a/cmake/LYTestWrappers.cmake +++ b/cmake/LYTestWrappers.cmake @@ -114,7 +114,7 @@ function(ly_add_test) if(NOT ly_add_test_TIMEOUT) set(ly_add_test_TIMEOUT ${LY_TEST_DEFAULT_TIMEOUT}) elseif(ly_add_test_TIMEOUT GREATER LY_TEST_DEFAULT_TIMEOUT) - message(WARNING "TIMEOUT for test ${ly_add_test_NAME} set at ${ly_add_test_TIMEOUT} seconds which is longer than the default of ${LY_TEST_DEFAULT_TIMEOUT}. Allowing a single module to run exceedingly long creates problems in a CI pipeline.") + message(FATAL_ERROR "TIMEOUT for test ${ly_add_test_NAME} set at ${ly_add_test_TIMEOUT} seconds which is longer than the default of ${LY_TEST_DEFAULT_TIMEOUT}. Allowing a single module to run exceedingly long creates problems in a CI pipeline.") endif() if(NOT ly_add_test_TEST_COMMAND) diff --git a/cmake/Platform/Common/MSVC/Configurations_msvc.cmake b/cmake/Platform/Common/MSVC/Configurations_msvc.cmake index 4024e45bad..118a515e30 100644 --- a/cmake/Platform/Common/MSVC/Configurations_msvc.cmake +++ b/cmake/Platform/Common/MSVC/Configurations_msvc.cmake @@ -38,7 +38,6 @@ ly_append_configurations_options( /wd4201 # nonstandard extension used: nameless struct/union. This actually became part of the C++11 std, MS has an open issue: https://developercommunity.visualstudio.com/t/warning-level-4-generates-a-bogus-warning-c4201-no/103064 # Disabling these warnings while they get fixed - /wd4018 # signed/unsigned mismatch /wd4244 # conversion, possible loss of data /wd4245 # conversion, signed/unsigned mismatch /wd4389 # comparison, signed/unsigned mismatch diff --git a/cmake/Platform/Windows/PackagingPostBuild.cmake b/cmake/Platform/Windows/PackagingPostBuild.cmake index 3f364b89c5..5e09743373 100644 --- a/cmake/Platform/Windows/PackagingPostBuild.cmake +++ b/cmake/Platform/Windows/PackagingPostBuild.cmake @@ -189,7 +189,7 @@ if(CPACK_AUTO_GEN_TAG) upload_to_s3( ${_latest_upload_url} ${_temp_dir} - "(${_non_versioned_exe}|build_tag.txt)$" + ".*(${_non_versioned_exe}|build_tag.txt)$" ) # cleanup the temp files diff --git a/cmake/TestImpactFramework/ConsoleFrontendConfig.in b/cmake/TestImpactFramework/ConsoleFrontendConfig.in index e4111fb9cd..17fbd217d7 100644 --- a/cmake/TestImpactFramework/ConsoleFrontendConfig.in +++ b/cmake/TestImpactFramework/ConsoleFrontendConfig.in @@ -1,7 +1,8 @@ { "meta": { "platform": "${platform}", - "timestamp": "${timestamp}" + "timestamp": "${timestamp}", + "build_config": "${build_config}" }, "jenkins": { "use_test_impact_analysis": ${use_tiaf} @@ -32,8 +33,7 @@ "historic": { "root": "${historic_dir}", "relative_paths": { - "last_run_hash_file": "last_run.hash", - "last_build_target_list_file": "LastRunBuildTargets.json" + "data": "historic_data.json" } } }, diff --git a/cmake/TestImpactFramework/LYTestImpactFramework.cmake b/cmake/TestImpactFramework/LYTestImpactFramework.cmake index 61cc8c200a..7dd2617582 100644 --- a/cmake/TestImpactFramework/LYTestImpactFramework.cmake +++ b/cmake/TestImpactFramework/LYTestImpactFramework.cmake @@ -22,10 +22,10 @@ set(LY_TEST_IMPACT_CONSOLE_TARGET "TestImpact.Frontend.Console") set(LY_TEST_IMPACT_WORKING_DIR "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/TestImpactFramework") # Directory for artifacts generated at runtime -set(LY_TEST_IMPACT_TEMP_DIR "${LY_TEST_IMPACT_WORKING_DIR}/Temp") +set(LY_TEST_IMPACT_TEMP_DIR "${LY_TEST_IMPACT_WORKING_DIR}/$/Temp") # Directory for files that persist between runtime runs -set(LY_TEST_IMPACT_PERSISTENT_DIR "${LY_TEST_IMPACT_WORKING_DIR}/Persistent") +set(LY_TEST_IMPACT_PERSISTENT_DIR "${LY_TEST_IMPACT_WORKING_DIR}/$/Persistent") # Directory for static artifacts produced as part of the build system generation process set(LY_TEST_IMPACT_ARTIFACT_DIR "${LY_TEST_IMPACT_WORKING_DIR}/Artifact") @@ -43,7 +43,7 @@ set(LY_TEST_IMPACT_TEST_TYPE_FILE "${LY_TEST_IMPACT_ARTIFACT_DIR}/TestType/All.t set(LY_TEST_IMPACT_GEM_TARGET_FILE "${LY_TEST_IMPACT_ARTIFACT_DIR}/BuildType/All.gems") # Path to the config file for each build configuration -set(LY_TEST_IMPACT_CONFIG_FILE_PATH "${LY_TEST_IMPACT_PERSISTENT_DIR}/tiaf.$.json") +set(LY_TEST_IMPACT_CONFIG_FILE_PATH "${LY_TEST_IMPACT_PERSISTENT_DIR}/tiaf.json") # Preprocessor directive for the config file path set(LY_TEST_IMPACT_CONFIG_FILE_PATH_DEFINITION "LY_TEST_IMPACT_DEFAULT_CONFIG_FILE=\"${LY_TEST_IMPACT_CONFIG_FILE_PATH}\"") @@ -379,6 +379,9 @@ function(ly_test_impact_write_config_file CONFIG_TEMPLATE_FILE BIN_DIR) # Timestamp this config file was generated at string(TIMESTAMP timestamp "%Y-%m-%d %H:%M:%S") + # Build configuration this config file is being generated for + set(build_config "$") + # Instrumentation binary if(NOT LY_TEST_IMPACT_INSTRUMENTATION_BIN) # No binary specified is not an error, it just means that the test impact analysis part of the framework is disabled diff --git a/scripts/build/Platform/Windows/build_config.json b/scripts/build/Platform/Windows/build_config.json index 235e1406ab..4c275a49cf 100644 --- a/scripts/build/Platform/Windows/build_config.json +++ b/scripts/build/Platform/Windows/build_config.json @@ -89,7 +89,7 @@ "CONFIGURATION": "profile", "SCRIPT_PATH": "scripts/build/TestImpactAnalysis/tiaf_driver.py", "SCRIPT_PARAMETERS": - "--config=\"!OUTPUT_DIRECTORY!/bin/TestImpactFramework/persistent/tiaf.profile.json\" --suite=main --test-failure-policy=continue --src-branch=!BRANCH_NAME! --dst-branch=!CHANGE_TARGET! --pipeline=!PIPELINE_NAME! --dest-commit=!CHANGE_ID! --seeding-branches=!BUILD_SNAPSHOTS! --seeding-pipelines=default" + "--config=\"!OUTPUT_DIRECTORY!/bin/TestImpactFramework/profile/Persistent/tiaf.json\" --src-branch=!BRANCH_NAME! --dst-branch=!CHANGE_TARGET! --commit=!CHANGE_ID! --s3-bucket=!TEST_IMPACT_S3_BUCKET! --mars-index-prefix=jonawals --suite=main --test-failure-policy=continue" } }, "debug_vs2019": { diff --git a/scripts/build/Platform/Windows/deploy_cdk_applications.cmd b/scripts/build/Platform/Windows/deploy_cdk_applications.cmd new file mode 100644 index 0000000000..2845707923 --- /dev/null +++ b/scripts/build/Platform/Windows/deploy_cdk_applications.cmd @@ -0,0 +1,105 @@ +@ECHO OFF +REM +REM Copyright (c) Contributors to the Open 3D Engine Project. +REM For complete copyright and license terms please see the LICENSE at the root of this distribution. +REM +REM SPDX-License-Identifier: Apache-2.0 OR MIT +REM +REM + +REM Deploy the CDK applcations for AWS gems (Windows only) +REM Prerequisites: +REM 1) Node.js is installed +REM 2) Node.js version >= 10.13.0, except for versions 13.0.0 - 13.6.0. A version in active long-term support is recommended. +SETLOCAL EnableDelayedExpansion + +SET SOURCE_DIRECTORY=%CD% +SET PATH=%SOURCE_DIRECTORY%\python;%PATH% +SET GEM_DIRECTORY=%SOURCE_DIRECTORY%\Gems + +REM Create and activate a virtualenv for the CDK deployment +CALL python -m venv .env +IF ERRORLEVEL 1 ( + ECHO [cdk_bootstrap] Failed to create a virtualenv for the CDK deployment + exit /b 1 +) +CALL .env\Scripts\activate.bat +IF ERRORLEVEL 1 ( + ECHO [cdk_bootstrap] Failed to activate the virtualenv for the CDK deployment + exit /b 1 +) + +ECHO [cdk_installation] Install the latest version of CDK +CALL npm uninstall -g aws-cdk +IF ERRORLEVEL 1 ( + ECHO [cdk_bootstrap] Failed to uninstall the current version of CDK + exit /b 1 +) +CALL npm install -g aws-cdk@latest +IF ERRORLEVEL 1 ( + ECHO [cdk_bootstrap] Failed to install the latest version of CDK + exit /b 1 +) + +REM Set temporary AWS credentials from the assume role +FOR /f "tokens=1,2,3" %%a IN ('CALL aws sts assume-role --query Credentials.[SecretAccessKey^,SessionToken^,AccessKeyId] --output text --role-arn %ASSUME_ROLE_ARN% --role-session-name o3de-Automation-session') DO ( + SET AWS_SECRET_ACCESS_KEY=%%a + SET AWS_SESSION_TOKEN=%%b + SET AWS_ACCESS_KEY_ID=%%c +) +FOR /F "tokens=4 delims=:" %%a IN ("%ASSUME_ROLE_ARN%") DO SET O3DE_AWS_DEPLOY_ACCOUNT=%%a + +REM Bootstrap and deploy the CDK applications +ECHO [cdk_bootstrap] Bootstrap CDK +CALL cdk bootstrap aws://%O3DE_AWS_DEPLOY_ACCOUNT%/%O3DE_AWS_DEPLOY_REGION% +IF ERRORLEVEL 1 ( + ECHO [cdk_bootstrap] Failed to bootstrap CDK + exit /b 1 +) + +CALL :DeployCDKApplication AWSCore --all +IF ERRORLEVEL 1 ( + exit /b 1 +) +CALL :DeployCDKApplication AWSClientAuth +IF ERRORLEVEL 1 ( + exit /b 1 +) +CALL :DeployCDKApplication AWSMetrics "-c batch_processing=true" +IF ERRORLEVEL 1 ( + exit /b 1 +) + +EXIT /b 0 + +:DeployCDKApplication +REM Deploy the CDK application for a specific AWS gem +SET GEM_NAME=%~1 +SET ADDITIONAL_ARGUMENTS=%~2 +ECHO [cdk_deployment] Deploy the CDK application for the %GEM_NAME% gem +PUSHD %GEM_DIRECTORY%\%GEM_NAME%\cdk + +REM Revert the CDK application code to a stable state using the provided commit ID +CALL git checkout %COMMIT_ID% -- . +IF ERRORLEVEL 1 ( + ECHO [git_checkout] Failed to checkout the CDK application for the %GEM_NAME% gem using commit ID %COMMIT_ID% + POPD + exit /b 1 +) + +REM Install required packages for the CDK application +CALL python -m pip install -r requirements.txt +IF ERRORLEVEL 1 ( + ECHO [cdk_deployment] Failed to install required packages for the %GEM_NAME% gem + POPD + exit /b 1 +) + +REM Deploy the CDK application +CALL cdk deploy %ADDITIONAL_ARGUMENTS% --require-approval never +IF ERRORLEVEL 1 ( + ECHO [cdk_deployment] Failed to deploy the CDK application for the %GEM_NAME% gem + POPD + exit /b 1 +) +POPD diff --git a/scripts/build/TestImpactAnalysis/git_utils.py b/scripts/build/TestImpactAnalysis/git_utils.py index ec31ab1f53..3561b337f3 100644 --- a/scripts/build/TestImpactAnalysis/git_utils.py +++ b/scripts/build/TestImpactAnalysis/git_utils.py @@ -6,34 +6,69 @@ # # -import os import subprocess import git +import pathlib -# Returns True if the dst commit descends from the src commit, otherwise False -def is_descendent(src_commit_hash, dst_commit_hash): - if src_commit_hash is None or dst_commit_hash is None: - return False - result = subprocess.run(["git", "merge-base", "--is-ancestor", src_commit_hash, dst_commit_hash]) - return result.returncode == 0 - -# Attempts to create a diff from the src and dst commits and write to the specified output file -def create_diff_file(src_commit_hash, dst_commit_hash, output_path): - if os.path.isfile(output_path): - os.remove(output_path) - os.makedirs(os.path.dirname(output_path), exist_ok=True) - # git diff will only write to the output file if both commit hashes are valid - subprocess.run(["git", "diff", "--name-status", f"--output={output_path}", src_commit_hash, dst_commit_hash]) - if not os.path.isfile(output_path): - raise FileNotFoundError(f"Source commit '{src_commit_hash}' and/or destination commit '{dst_commit_hash}' are invalid") - -# Basic representation of a repository +# Basic representation of a git repository class Repo: - def __init__(self, repo_path): - self.__repo = git.Repo(repo_path) + def __init__(self, repo_path: str): + self._repo = git.Repo(repo_path) # Returns the current branch @property def current_branch(self): - branch = self.__repo.active_branch + branch = self._repo.active_branch return branch.name + + def create_diff_file(self, src_commit_hash: str, dst_commit_hash: str, output_path: pathlib.Path): + """ + Attempts to create a diff from the src and dst commits and write to the specified output file. + + @param src_commit_hash: The hash for the source commit. + @param dst_commit_hash: The hash for the destination commit. + @param output_path: The path to the file to write the diff to. + """ + + try: + # Remove the existing file (if any) and create the parent directory + # output_path.unlink(missing_ok=True) # missing_ok is only available in Python 3.8+ + if output_path.is_file(): + output_path.unlink() + output_path.parent.mkdir(exist_ok=True) + except EnvironmentError as e: + raise RuntimeError(f"Could not create path for output file '{output_path}'") + + # git diff will only write to the output file if both commit hashes are valid + subprocess.run(["git", "diff", "--name-status", f"--output={output_path}", src_commit_hash, dst_commit_hash]) + if not output_path.is_file(): + raise RuntimeError(f"Source commit '{src_commit_hash}' and/or destination commit '{dst_commit_hash}' are invalid") + + def is_descendent(self, src_commit_hash: str, dst_commit_hash: str): + """ + Determines whether or not dst_commit is a descendent of src_commit. + + @param src_commit_hash: The hash for the source commit. + @param dst_commit_hash: The hash for the destination commit. + @return: True if the dst commit descends from the src commit, otherwise False. + """ + + if not src_commit_hash and not dst_commit_hash: + return False + result = subprocess.run(["git", "merge-base", "--is-ancestor", src_commit_hash, dst_commit_hash]) + return result.returncode == 0 + + # Returns the distance between two commits + def commit_distance(self, src_commit_hash: str, dst_commit_hash: str): + """ + Determines the number of commits between src_commit and dst_commit. + + @param src_commit_hash: The hash for the source commit. + @param dst_commit_hash: The hash for the destination commit. + @return: The distance between src_commit and dst_commit (if both are valid commits), otherwise None. + """ + + if not src_commit_hash and not dst_commit_hash: + return None + commits = self._repo.iter_commits(src_commit_hash + '..' + dst_commit_hash) + return len(list(commits)) diff --git a/scripts/build/TestImpactAnalysis/mars_utils.py b/scripts/build/TestImpactAnalysis/mars_utils.py new file mode 100644 index 0000000000..69374512a3 --- /dev/null +++ b/scripts/build/TestImpactAnalysis/mars_utils.py @@ -0,0 +1,452 @@ +# +# 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 +# +# + +import datetime +import json +import socket +from tiaf_logger import get_logger + +logger = get_logger(__file__) + +MARS_JOB_KEY = "job" +SRC_COMMIT_KEY = "src_commit" +DST_COMMIT_KEY = "src_commit" +COMMIT_DISTANCE_KEY = "commit_distance" +SRC_BRANCH_KEY = "src_branch" +DST_BRANCH_KEY = "dst_branch" +SUITE_KEY = "suite" +SOURCE_OF_TRUTH_BRANCH_KEY = "source_of_truth_branch" +IS_SOURCE_OF_TRUTH_BRANCH_KEY = "is_source_of_truth_branch" +USE_TEST_IMPACT_ANALYSIS_KEY = "use_test_impact_analysis" +HAS_CHANGE_LIST_KEY = "has_change_list" +HAS_HISTORIC_DATA_KEY = "has_historic_data" +S3_BUCKET_KEY = "s3_bucket" +DRIVER_ARGS_KEY = "driver_args" +RUNTIME_ARGS_KEY = "runtime_args" +RUNTIME_RETURN_CODE_KEY = "return_code" +NAME_KEY = "name" +RESULT_KEY = "result" +NUM_PASSING_TESTS_KEY = "num_passing_tests" +NUM_FAILING_TESTS_KEY = "num_failing_tests" +NUM_DISABLED_TESTS_KEY = "num_disabled_tests" +COMMAND_ARGS_STRING = "command_args" +NUM_PASSING_TEST_RUNS_KEY = "num_passing_test_runs" +NUM_FAILING_TEST_RUNS_KEY = "num_failing_test_runs" +NUM_EXECUTION_FAILURE_TEST_RUNS_KEY = "num_execution_failure_test_runs" +NUM_TIMED_OUT_TEST_RUNS_KEY = "num_timed_out_test_runs" +NUM_UNEXECUTED_TEST_RUNS_KEY = "num_unexecuted_test_runs" +TOTAL_NUM_PASSING_TESTS_KEY = "total_num_passing_tests" +TOTAL_NUM_FAILING_TESTS_KEY = "total_num_failing_tests" +TOTAL_NUM_DISABLED_TESTS_KEY = "total_num_disabled_tests" +START_TIME_KEY = "start_time" +END_TIME_KEY = "end_time" +DURATION_KEY = "duration" +INCLUDED_TEST_RUNS_KEY = "included_test_runs" +EXCLUDED_TEST_RUNS_KEY = "excluded_test_runs" +NUM_INCLUDED_TEST_RUNS_KEY = "num_included_test_runs" +NUM_EXCLUDED_TEST_RUNS_KEY = "num_excluded_test_runs" +TOTAL_NUM_TEST_RUNS_KEY = "total_num_test_runs" +PASSING_TEST_RUNS_KEY = "passing_test_runs" +FAILING_TEST_RUNS_KEY = "failing_test_runs" +EXECUTION_FAILURE_TEST_RUNS_KEY = "execution_failure_test_runs" +TIMED_OUT_TEST_RUNS_KEY = "timed_out_test_runs" +UNEXECUTED_TEST_RUNS_KEY = "unexecuted_test_runs" +TOTAL_NUM_PASSING_TEST_RUNS_KEY = "total_num_passing_test_runs" +TOTAL_NUM_FAILING_TEST_RUNS_KEY = "total_num_failing_test_runs" +TOTAL_NUM_EXECUTION_FAILURE_TEST_RUNS_KEY = "total_num_execution_failure_test_runs" +TOTAL_NUM_TIMED_OUT_TEST_RUNS_KEY = "total_num_timed_out_test_runs" +TOTAL_NUM_UNEXECUTED_TEST_RUNS_KEY = "total_num_unexecuted_test_runs" +SEQUENCE_TYPE_KEY = "type" +IMPACT_ANALYSIS_SEQUENCE_TYPE_KEY = "impact_analysis" +SAFE_IMPACT_ANALYSIS_SEQUENCE_TYPE_KEY = "safe_impact_analysis" +SEED_SEQUENCE_TYPE_KEY = "seed" +TEST_TARGET_TIMEOUT_KEY = "test_target_timeout" +GLOBAL_TIMEOUT_KEY = "global_timeout" +MAX_CONCURRENCY_KEY = "max_concurrency" +SELECTED_KEY = "selected" +DRAFTED_KEY = "drafted" +DISCARDED_KEY = "discarded" +SELECTED_TEST_RUN_REPORT_KEY = "selected_test_run_report" +DISCARDED_TEST_RUN_REPORT_KEY = "discarded_test_run_report" +DRAFTED_TEST_RUN_REPORT_KEY = "drafted_test_run_report" +SELECTED_TEST_RUNS_KEY = "selected_test_runs" +DRAFTED_TEST_RUNS_KEY = "drafted_test_runs" +DISCARDED_TEST_RUNS_KEY = "discarded_test_runs" +INSTRUMENTATION_KEY = "instrumentation" +EFFICIENCY_KEY = "efficiency" +CONFIG_KEY = "config" +POLICY_KEY = "policy" +CHANGE_LIST_KEY = "change_list" +TEST_RUN_SELECTION_KEY = "test_run_selection" +DYNAMIC_DEPENDENCY_MAP_POLICY_KEY = "dynamic_dependency_map" +DYNAMIC_DEPENDENCY_MAP_POLICY_UPDATE_KEY = "update" +REPORT_KEY = "report" + +class FilebeatExn(Exception): + pass + +class FilebeatClient(object): + def __init__(self, host="127.0.0.1", port=9000, timeout=20): + self._filebeat_host = host + self._filebeat_port = port + self._socket_timeout = timeout + self._socket = None + + self._open_socket() + + def send_event(self, payload, index, timestamp=None, pipeline="filebeat"): + if not timestamp: + timestamp = datetime.datetime.utcnow().timestamp() + + event = { + "index": index, + "timestamp": timestamp, + "pipeline": pipeline, + "payload": json.dumps(payload) + } + + # Serialise event, add new line and encode as UTF-8 before sending to Filebeat. + data = json.dumps(event, sort_keys=True) + "\n" + data = data.encode() + + #print(f"-> {data}") + self._send_data(data) + + def _open_socket(self): + logger.info(f"Connecting to Filebeat on {self._filebeat_host}:{self._filebeat_port}") + + self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self._socket.settimeout(self._socket_timeout) + + try: + self._socket.connect((self._filebeat_host, self._filebeat_port)) + except (ConnectionError, socket.timeout): + raise FilebeatExn("Failed to connect to Filebeat") from None + + def _send_data(self, data): + total_sent = 0 + + while total_sent < len(data): + try: + sent = self._socket.send(data[total_sent:]) + except BrokenPipeError: + logging.error("Filebeat socket closed by peer") + self._socket.close() + self._open_socket() + total_sent = 0 + else: + total_sent = total_sent + sent + +def format_timestamp(timestamp: float): + """ + Formats the given floating point timestamp into "yyyy-MM-dd'T'HH:mm:ss.SSSXX" format. + + @param timestamp: The timestamp to format. + @return: The formatted timestamp. + """ + return datetime.datetime.utcfromtimestamp(timestamp).strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z" + +def generate_mars_timestamp(t0_offset_milliseconds: int, t0_timestamp: float): + """ + Generates a MARS timestamp in the format "yyyy-MM-dd'T'HH:mm:ss.SSSXX" by offsetting the T0 timestamp + by the specified amount of milliseconds. + + @param t0_offset_milliseconds: The amount of time to offset from T0. + @param t0_timestamp: The T0 timestamp that TIAF timings will be offst from. + @return: The formatted timestamp offset from T0 by the specified amount of milliseconds. + """ + + t0_offset_seconds = get_duration_in_seconds(t0_offset_milliseconds) + t0_offset_timestamp = t0_timestamp + t0_offset_seconds + return format_timestamp(t0_offset_timestamp) + +def get_duration_in_seconds(duration_in_milliseconds: int): + """ + Gets the specified duration in milliseconds (as used by TIAF) in seconds (as used my MARS documents). + + @param duration_in_milliseconds: The millisecond duration to transform into seconds. + @return: The duration in seconds. + """ + + return duration_in_milliseconds * 0.001 + +def generate_mars_job(tiaf_result, driver_args): + """ + Generates a MARS job document using the job meta-data used to drive the TIAF sequence. + + @param tiaf_result: The result object generated by the TIAF script. + @param driver_args: The arguments specified to the driver script. + @return: The MARS job document with the job meta-data. + """ + + mars_job = {key:tiaf_result[key] for key in + [ + SRC_COMMIT_KEY, + DST_COMMIT_KEY, + COMMIT_DISTANCE_KEY, + SRC_BRANCH_KEY, + DST_BRANCH_KEY, + SUITE_KEY, + SOURCE_OF_TRUTH_BRANCH_KEY, + IS_SOURCE_OF_TRUTH_BRANCH_KEY, + USE_TEST_IMPACT_ANALYSIS_KEY, + HAS_CHANGE_LIST_KEY, + HAS_HISTORIC_DATA_KEY, + S3_BUCKET_KEY, + RUNTIME_ARGS_KEY, + RUNTIME_RETURN_CODE_KEY + ]} + + mars_job[DRIVER_ARGS_KEY] = driver_args + return mars_job + +def generate_test_run_list(test_runs): + """ + Generates a list of test run name strings from the list of TIAF test runs. + + @param test_runs: The list of TIAF test runs to generate the name strings from. + @return: The list of test run name strings. + """ + + test_run_list = [] + for test_run in test_runs: + test_run_list.append(test_run[NAME_KEY]) + return test_run_list + +def generate_mars_test_run_selections(test_run_selection, test_run_report, t0_timestamp: float): + """ + Generates a list of MARS test run selections from a TIAF test run selection and report. + + @param test_run_selection: The TIAF test run selection. + @param test_run_report: The TIAF test run report. + @param t0_timestamp: The T0 timestamp that TIAF timings will be offst from. + @return: The list of TIAF test runs. + """ + + mars_test_run_selection = {key:test_run_report[key] for key in + [ + RESULT_KEY, + NUM_PASSING_TEST_RUNS_KEY, + NUM_FAILING_TEST_RUNS_KEY, + NUM_EXECUTION_FAILURE_TEST_RUNS_KEY, + NUM_TIMED_OUT_TEST_RUNS_KEY, + NUM_UNEXECUTED_TEST_RUNS_KEY, + TOTAL_NUM_PASSING_TESTS_KEY, + TOTAL_NUM_FAILING_TESTS_KEY, + TOTAL_NUM_DISABLED_TESTS_KEY + ]} + + mars_test_run_selection[START_TIME_KEY] = generate_mars_timestamp(test_run_report[START_TIME_KEY], t0_timestamp) + mars_test_run_selection[END_TIME_KEY] = generate_mars_timestamp(test_run_report[END_TIME_KEY], t0_timestamp) + mars_test_run_selection[DURATION_KEY] = get_duration_in_seconds(test_run_report[DURATION_KEY]) + + mars_test_run_selection[INCLUDED_TEST_RUNS_KEY] = test_run_selection[INCLUDED_TEST_RUNS_KEY] + mars_test_run_selection[EXCLUDED_TEST_RUNS_KEY] = test_run_selection[EXCLUDED_TEST_RUNS_KEY] + mars_test_run_selection[NUM_INCLUDED_TEST_RUNS_KEY] = test_run_selection[NUM_INCLUDED_TEST_RUNS_KEY] + mars_test_run_selection[NUM_EXCLUDED_TEST_RUNS_KEY] = test_run_selection[NUM_EXCLUDED_TEST_RUNS_KEY] + mars_test_run_selection[TOTAL_NUM_TEST_RUNS_KEY] = test_run_selection[TOTAL_NUM_TEST_RUNS_KEY] + + mars_test_run_selection[PASSING_TEST_RUNS_KEY] = generate_test_run_list(test_run_report[PASSING_TEST_RUNS_KEY]) + mars_test_run_selection[FAILING_TEST_RUNS_KEY] = generate_test_run_list(test_run_report[FAILING_TEST_RUNS_KEY]) + mars_test_run_selection[EXECUTION_FAILURE_TEST_RUNS_KEY] = generate_test_run_list(test_run_report[EXECUTION_FAILURE_TEST_RUNS_KEY]) + mars_test_run_selection[TIMED_OUT_TEST_RUNS_KEY] = generate_test_run_list(test_run_report[TIMED_OUT_TEST_RUNS_KEY]) + mars_test_run_selection[UNEXECUTED_TEST_RUNS_KEY] = generate_test_run_list(test_run_report[UNEXECUTED_TEST_RUNS_KEY]) + + return mars_test_run_selection + +def generate_test_runs_from_list(test_run_list: list): + """ + Generates a list of TIAF test runs from a list of test target name strings. + + @param test_run_list: The list of test target names. + @return: The list of TIAF test runs. + """ + + test_run_list = { + TOTAL_NUM_TEST_RUNS_KEY: len(test_run_list), + NUM_INCLUDED_TEST_RUNS_KEY: len(test_run_list), + NUM_EXCLUDED_TEST_RUNS_KEY: 0, + INCLUDED_TEST_RUNS_KEY: test_run_list, + EXCLUDED_TEST_RUNS_KEY: [] + } + + return test_run_list + +def generate_mars_sequence(sequence_report: dict, mars_job: dict, change_list:dict, t0_timestamp: float): + """ + Generates the MARS sequence document from the specified TIAF sequence report. + + @param sequence_report: The TIAF runtime sequence report. + @param mars_job: The MARS job for this sequence. + @param change_list: The change list for which the TIAF sequence was run. + @param t0_timestamp: The T0 timestamp that TIAF timings will be offst from. + @return: The MARS sequence document for the specified TIAF sequence report. + """ + + mars_sequence = {key:sequence_report[key] for key in + [ + SEQUENCE_TYPE_KEY, + RESULT_KEY, + POLICY_KEY, + TOTAL_NUM_TEST_RUNS_KEY, + TOTAL_NUM_PASSING_TEST_RUNS_KEY, + TOTAL_NUM_FAILING_TEST_RUNS_KEY, + TOTAL_NUM_EXECUTION_FAILURE_TEST_RUNS_KEY, + TOTAL_NUM_TIMED_OUT_TEST_RUNS_KEY, + TOTAL_NUM_UNEXECUTED_TEST_RUNS_KEY, + TOTAL_NUM_PASSING_TESTS_KEY, + TOTAL_NUM_FAILING_TESTS_KEY, + TOTAL_NUM_DISABLED_TESTS_KEY + ]} + + mars_sequence[START_TIME_KEY] = generate_mars_timestamp(sequence_report[START_TIME_KEY], t0_timestamp) + mars_sequence[END_TIME_KEY] = generate_mars_timestamp(sequence_report[END_TIME_KEY], t0_timestamp) + mars_sequence[DURATION_KEY] = get_duration_in_seconds(sequence_report[DURATION_KEY]) + + config = {key:sequence_report[key] for key in + [ + TEST_TARGET_TIMEOUT_KEY, + GLOBAL_TIMEOUT_KEY, + MAX_CONCURRENCY_KEY + ]} + + test_run_selection = {} + test_run_selection[SELECTED_KEY] = generate_mars_test_run_selections(sequence_report[SELECTED_TEST_RUNS_KEY], sequence_report[SELECTED_TEST_RUN_REPORT_KEY], t0_timestamp) + if sequence_report[SEQUENCE_TYPE_KEY] == IMPACT_ANALYSIS_SEQUENCE_TYPE_KEY or sequence_report[SEQUENCE_TYPE_KEY] == SAFE_IMPACT_ANALYSIS_SEQUENCE_TYPE_KEY: + total_test_runs = sequence_report[TOTAL_NUM_TEST_RUNS_KEY] + if total_test_runs > 0: + test_run_selection[SELECTED_KEY][EFFICIENCY_KEY] = (1.0 - (test_run_selection[SELECTED_KEY][TOTAL_NUM_TEST_RUNS_KEY] / total_test_runs)) * 100 + else: + test_run_selection[SELECTED_KEY][EFFICIENCY_KEY] = 100 + test_run_selection[DRAFTED_KEY] = generate_mars_test_run_selections(generate_test_runs_from_list(sequence_report[DRAFTED_TEST_RUNS_KEY]), sequence_report[DRAFTED_TEST_RUN_REPORT_KEY], t0_timestamp) + if sequence_report[SEQUENCE_TYPE_KEY] == SAFE_IMPACT_ANALYSIS_SEQUENCE_TYPE_KEY: + test_run_selection[DISCARDED_KEY] = generate_mars_test_run_selections(sequence_report[DISCARDED_TEST_RUNS_KEY], sequence_report[DISCARDED_TEST_RUN_REPORT_KEY], t0_timestamp) + else: + test_run_selection[SELECTED_KEY][EFFICIENCY_KEY] = 0 + + mars_sequence[MARS_JOB_KEY] = mars_job + mars_sequence[CONFIG_KEY] = config + mars_sequence[TEST_RUN_SELECTION_KEY] = test_run_selection + mars_sequence[CHANGE_LIST_KEY] = change_list + + return mars_sequence + +def extract_mars_test_target(test_run, instrumentation, mars_job, t0_timestamp: float): + """ + Extracts a MARS test target from the specified TIAF test run. + + @param test_run: The TIAF test run. + @param instrumentation: Flag specifying whether or not instrumentation was used for the test targets in this run. + @param mars_job: The MARS job for this test target. + @param t0_timestamp: The T0 timestamp that TIAF timings will be offst from. + @return: The MARS test target documents for the specified TIAF test target. + """ + + mars_test_run = {key:test_run[key] for key in + [ + NAME_KEY, + RESULT_KEY, + NUM_PASSING_TESTS_KEY, + NUM_FAILING_TESTS_KEY, + NUM_DISABLED_TESTS_KEY, + COMMAND_ARGS_STRING + ]} + + mars_test_run[START_TIME_KEY] = generate_mars_timestamp(test_run[START_TIME_KEY], t0_timestamp) + mars_test_run[END_TIME_KEY] = generate_mars_timestamp(test_run[END_TIME_KEY], t0_timestamp) + mars_test_run[DURATION_KEY] = get_duration_in_seconds(test_run[DURATION_KEY]) + + mars_test_run[MARS_JOB_KEY] = mars_job + mars_test_run[INSTRUMENTATION_KEY] = instrumentation + return mars_test_run + +def extract_mars_test_targets_from_report(test_run_report, instrumentation, mars_job, t0_timestamp: float): + """ + Extracts the MARS test targets from the specified TIAF test run report. + + @param test_run_report: The TIAF runtime test run report. + @param instrumentation: Flag specifying whether or not instrumentation was used for the test targets in this run. + @param mars_job: The MARS job for these test targets. + @param t0_timestamp: The T0 timestamp that TIAF timings will be offst from. + @return: The list of all MARS test target documents for the test targets in the TIAF test run report. + """ + + mars_test_targets = [] + + for test_run in test_run_report[PASSING_TEST_RUNS_KEY]: + mars_test_targets.append(extract_mars_test_target(test_run, instrumentation, mars_job, t0_timestamp)) + for test_run in test_run_report[FAILING_TEST_RUNS_KEY]: + mars_test_targets.append(extract_mars_test_target(test_run, instrumentation, mars_job, t0_timestamp)) + for test_run in test_run_report[EXECUTION_FAILURE_TEST_RUNS_KEY]: + mars_test_targets.append(extract_mars_test_target(test_run, instrumentation, mars_job, t0_timestamp)) + for test_run in test_run_report[TIMED_OUT_TEST_RUNS_KEY]: + mars_test_targets.append(extract_mars_test_target(test_run, instrumentation, mars_job, t0_timestamp)) + for test_run in test_run_report[UNEXECUTED_TEST_RUNS_KEY]: + mars_test_targets.append(extract_mars_test_target(test_run, instrumentation, mars_job, t0_timestamp)) + + return mars_test_targets + +def generate_mars_test_targets(sequence_report: dict, mars_job: dict, t0_timestamp: float): + """ + Generates a MARS test target document for each test target in the TIAF sequence report. + + @param sequence_report: The TIAF runtime sequence report. + @param mars_job: The MARS job for this sequence. + @param t0_timestamp: The T0 timestamp that TIAF timings will be offst from. + @return: The list of all MARS test target documents for the test targets in the TIAF sequence report. + """ + + mars_test_targets = [] + + # Determine whether or not the test targets were executed with instrumentation + if sequence_report[SEQUENCE_TYPE_KEY] == SEED_SEQUENCE_TYPE_KEY or sequence_report[SEQUENCE_TYPE_KEY] == SAFE_IMPACT_ANALYSIS_SEQUENCE_TYPE_KEY or (sequence_report[SEQUENCE_TYPE_KEY] == IMPACT_ANALYSIS_SEQUENCE_TYPE_KEY and sequence_report[POLICY_KEY][DYNAMIC_DEPENDENCY_MAP_POLICY_KEY] == DYNAMIC_DEPENDENCY_MAP_POLICY_UPDATE_KEY): + instrumentation = True + else: + instrumentation = False + + # Extract the MARS test target documents from each of the test run reports + mars_test_targets += extract_mars_test_targets_from_report(sequence_report[SELECTED_TEST_RUN_REPORT_KEY], instrumentation, mars_job, t0_timestamp) + if sequence_report[SEQUENCE_TYPE_KEY] == IMPACT_ANALYSIS_SEQUENCE_TYPE_KEY or sequence_report[SEQUENCE_TYPE_KEY] == SAFE_IMPACT_ANALYSIS_SEQUENCE_TYPE_KEY: + mars_test_targets += extract_mars_test_targets_from_report(sequence_report[DRAFTED_TEST_RUN_REPORT_KEY], instrumentation, mars_job, t0_timestamp) + if sequence_report[SEQUENCE_TYPE_KEY] == SAFE_IMPACT_ANALYSIS_SEQUENCE_TYPE_KEY: + mars_test_targets += extract_mars_test_targets_from_report(sequence_report[DISCARDED_TEST_RUN_REPORT_KEY], instrumentation, mars_job, t0_timestamp) + + return mars_test_targets + +def transmit_report_to_mars(mars_index_prefix: str, tiaf_result: dict, driver_args: list): + """ + Transforms the TIAF result into the appropriate MARS documents and transmits them to MARS. + + @param mars_index_prefix: The index prefix to be used for all MARS documents. + @param tiaf_result: The result object from the TIAF script. + @param driver_args: The arguments passed to the TIAF driver script. + """ + + try: + filebeat = FilebeatClient("localhost", 9000, 60) + + # T0 is the current timestamp that the report timings will be offset from + t0_timestamp = datetime.datetime.now().timestamp() + + # Generate and transmit the MARS job document + mars_job = generate_mars_job(tiaf_result, driver_args) + filebeat.send_event(mars_job, f"{mars_index_prefix}.tiaf.job") + + if tiaf_result[REPORT_KEY]: + # Generate and transmit the MARS sequence document + mars_sequence = generate_mars_sequence(tiaf_result[REPORT_KEY], mars_job, tiaf_result[CHANGE_LIST_KEY], t0_timestamp) + filebeat.send_event(mars_sequence, f"{mars_index_prefix}.tiaf.sequence") + + # Generate and transmit the MARS test target documents + mars_test_targets = generate_mars_test_targets(tiaf_result[REPORT_KEY], mars_job, t0_timestamp) + for mars_test_target in mars_test_targets: + filebeat.send_event(mars_test_target, f"{mars_index_prefix}.tiaf.test_target") + except FilebeatExn as e: + logger.error(e) + except KeyError as e: + logger.error(f"The report does not contain the key {str(e)}.") \ No newline at end of file diff --git a/scripts/build/TestImpactAnalysis/tiaf.py b/scripts/build/TestImpactAnalysis/tiaf.py index ce869b975a..3c94c2b5f4 100644 --- a/scripts/build/TestImpactAnalysis/tiaf.py +++ b/scripts/build/TestImpactAnalysis/tiaf.py @@ -6,237 +6,301 @@ # # -import os import json import subprocess import re -import git_utils +import uuid +import pathlib from git_utils import Repo -from enum import Enum +from tiaf_persistent_storage_local import PersistentStorageLocal +from tiaf_persistent_storage_s3 import PersistentStorageS3 +from tiaf_logger import get_logger -# Returns True if the specified child path is a child of the specified parent path, otherwise False -def is_child_path(parent_path, child_path): - parent_path = os.path.abspath(parent_path) - child_path = os.path.abspath(child_path) - return os.path.commonpath([os.path.abspath(parent_path)]) == os.path.commonpath([os.path.abspath(parent_path), os.path.abspath(child_path)]) +logger = get_logger(__file__) class TestImpact: - def __init__(self, config_file, dst_commit, src_branch, dst_branch, pipeline, seeding_branches, seeding_pipelines): - # Commit - self.__dst_commit = dst_commit - print(f"Commit: '{self.__dst_commit}'.") - self.__src_commit = None - self.__has_src_commit = False - # Branch - self.__src_branch = src_branch - print(f"Source branch: '{self.__src_branch}'.") - self.__dst_branch = dst_branch - print(f"Destination branch: '{self.__dst_branch}'.") - print(f"Seeding branches: '{seeding_branches}'.") - if self.__src_branch in seeding_branches: - self.__is_seeding_branch = True - else: - self.__is_seeding_branch = False - print(f"Is seeding branch: '{self.__is_seeding_branch}'.") - # Pipeline - self.__pipeline = pipeline - print(f"Pipeline: '{self.__pipeline}'.") - print(f"Seeding pipelines: '{seeding_pipelines}'.") - if self.__pipeline in seeding_pipelines: - self.__is_seeding_pipeline = True - else: - self.__is_seeding_pipeline = False - print(f"Is seeding pipeline: '{self.__is_seeding_pipeline}'.") - # Config - self.__parse_config_file(config_file) - # Sequence - if self.__is_seeding_branch and self.__is_seeding_pipeline: - self.__is_seeding = True - else: - self.__is_seeding = False - print(f"Is seeding: '{self.__is_seeding}'.") - if self.__use_test_impact_analysis and not self.__is_seeding: - self.__generate_change_list() + def __init__(self, config_file: str): + """ + Initializes the test impact model with the commit, branches as runtime configuration. - # Parse the configuration file and retrieve the data needed for launching the test impact analysis runtime - def __parse_config_file(self, config_file): - print(f"Attempting to parse configuration file '{config_file}'...") - with open(config_file, "r") as config_data: - config = json.load(config_data) - self.__repo_dir = config["repo"]["root"] - self.__repo = Repo(self.__repo_dir) - # TIAF - self.__use_test_impact_analysis = config["jenkins"]["use_test_impact_analysis"] - print(f"Is using test impact analysis: '{self.__use_test_impact_analysis}'.") - self.__tiaf_bin = config["repo"]["tiaf_bin"] - if self.__use_test_impact_analysis and not os.path.isfile(self.__tiaf_bin): - raise FileNotFoundError("Could not find tiaf binary") - # Workspaces - self.__active_workspace = config["workspace"]["active"]["root"] - self.__historic_workspace = config["workspace"]["historic"]["root"] - self.__temp_workspace = config["workspace"]["temp"]["root"] - # Last commit hash - last_commit_hash_path_file = config["workspace"]["historic"]["relative_paths"]["last_run_hash_file"] - self.__last_commit_hash_path = os.path.join(self.__historic_workspace, last_commit_hash_path_file) - print("The configuration file was parsed successfully.") + @param config_file: The runtime config file to obtain the runtime configuration data from. + """ - # Restricts change lists from checking in test impact analysis files - def __check_for_restricted_files(self, file_path): - if is_child_path(self.__active_workspace, file_path) or is_child_path(self.__historic_workspace, file_path) or is_child_path(self.__temp_workspace, file_path): - raise ValueError(f"Checking in test impact analysis framework files is illegal: '{file_path}''.") + self._has_change_list = False + self._parse_config_file(config_file) - def __read_last_run_hash(self): - self.__has_src_commit = False - if os.path.isfile(self.__last_commit_hash_path): - print(f"Previous commit hash found at '{self.__last_commit_hash_path}'.") - with open(self.__last_commit_hash_path) as file: - self.__src_commit = file.read() - self.__has_src_commit = True + def _parse_config_file(self, config_file: str): + """ + Parse the configuration file and retrieve the data needed for launching the test impact analysis runtime. - def __write_last_run_hash(self, last_run_hash): - os.makedirs(self.__historic_workspace, exist_ok=True) - f = open(self.__last_commit_hash_path, "w") - f.write(last_run_hash) - f.close() + @param config_file: The runtime config file to obtain the runtime configuration data from. + """ + + logger.info(f"Attempting to parse configuration file '{config_file}'...") + try: + with open(config_file, "r") as config_data: + self._config = json.load(config_data) + self._repo_dir = self._config["repo"]["root"] + self._repo = Repo(self._repo_dir) + + # TIAF + self._use_test_impact_analysis = self._config["jenkins"]["use_test_impact_analysis"] + self._tiaf_bin = pathlib.Path(self._config["repo"]["tiaf_bin"]) + if self._use_test_impact_analysis and not self._tiaf_bin.is_file(): + logger.warning(f"Could not find TIAF binary at location {self._tiaf_bin}, TIAF will be turned off.") + self._use_test_impact_analysis = False + else: + logger.info(f"Runtime binary found at location {self._tiaf_bin}") + + # Workspaces + self._active_workspace = self._config["workspace"]["active"]["root"] + self._historic_workspace = self._config["workspace"]["historic"]["root"] + self._temp_workspace = self._config["workspace"]["temp"]["root"] + logger.info("The configuration file was parsed successfully.") + except KeyError as e: + logger.error(f"The config does not contain the key {str(e)}.") + return + + def _attempt_to_generate_change_list(self, last_commit_hash, instance_id: str): + """ + Attempts to determine the change list bewteen now and the last tiaf run (if any). + + @param last_commit_hash: The commit hash of the last TIAF run. + @param instance_id: The unique id to derive the change list file name from. + """ + + self._has_change_list = False + self._change_list_path = None - # Determines the change list bewteen now and the last tiaf run (if any) - def __generate_change_list(self): - self.__has_change_list = False - self.__change_list_path = None # Check whether or not a previous commit hash exists (no hash is not a failure) - self.__read_last_run_hash() - if self.__has_src_commit == True: - if git_utils.is_descendent(self.__src_commit, self.__dst_commit) == False: - print(f"Source commit '{self.__src_commit}' and destination commit '{self.__dst_commit}' are not related.") + self._src_commit = last_commit_hash + if self._src_commit: + if self._repo.is_descendent(self._src_commit, self._dst_commit) == False: + logger.info(f"Source commit '{self._src_commit}' and destination commit '{self._dst_commit}' are not related.") return - diff_path = os.path.join(self.__temp_workspace, "changelist.diff") + self._commit_distance = self._repo.commit_distance(self._src_commit, self._dst_commit) + diff_path = pathlib.Path(pathlib.PurePath(self._temp_workspace).joinpath(f"changelist.{instance_id}.diff")) try: - git_utils.create_diff_file(self.__src_commit, self.__dst_commit, diff_path) - except FileNotFoundError as e: - print(e) + self._repo.create_diff_file(self._src_commit, self._dst_commit, diff_path) + except RuntimeError as e: + logger.error(e) return + # A diff was generated, attempt to parse the diff and construct the change list - print(f"Generated diff between commits '{self.__src_commit}' and '{self.__dst_commit}': '{diff_path}'.") - change_list = {} - change_list["createdFiles"] = [] - change_list["updatedFiles"] = [] - change_list["deletedFiles"] = [] + logger.info(f"Generated diff between commits '{self._src_commit}' and '{self._dst_commit}': '{diff_path}'.") with open(diff_path, "r") as diff_data: lines = diff_data.readlines() for line in lines: match = re.split("^R[0-9]+\\s(\\S+)\\s(\\S+)", line) if len(match) > 1: # File rename - self.__check_for_restricted_files(match[1]) - self.__check_for_restricted_files(match[2]) # Treat renames as a deletion and an addition - change_list["deletedFiles"].append(match[1]) - change_list["createdFiles"].append(match[2]) + self._change_list["deletedFiles"].append(match[1]) + self._change_list["createdFiles"].append(match[2]) else: match = re.split("^[AMD]\\s(\\S+)", line) - self.__check_for_restricted_files(match[1]) if len(match) > 1: if line[0] == 'A': # File addition - change_list["createdFiles"].append(match[1]) + self._change_list["createdFiles"].append(match[1]) elif line[0] == 'M': # File modification - change_list["updatedFiles"].append(match[1]) + self._change_list["updatedFiles"].append(match[1]) elif line[0] == 'D': # File Deletion - change_list["deletedFiles"].append(match[1]) + self._change_list["deletedFiles"].append(match[1]) + # Serialize the change list to the JSON format the test impact analysis runtime expects - change_list_json = json.dumps(change_list, indent = 4) - change_list_path = os.path.join(self.__temp_workspace, "changelist.json") + change_list_json = json.dumps(self._change_list, indent = 4) + change_list_path = pathlib.PurePath(self._temp_workspace).joinpath(f"changelist.{instance_id}.json") f = open(change_list_path, "w") f.write(change_list_json) f.close() - print(f"Change list constructed successfully: '{change_list_path}'.") - print(f"{len(change_list['createdFiles'])} created files, {len(change_list['updatedFiles'])} updated files and {len(change_list['deletedFiles'])} deleted files.") + logger.info(f"Change list constructed successfully: '{change_list_path}'.") + logger.info(f"{len(self._change_list['createdFiles'])} created files, {len(self._change_list['updatedFiles'])} updated files and {len(self._change_list['deletedFiles'])} deleted files.") + # Note: an empty change list generated due to no changes between last and current commit is valid - self.__has_change_list = True - self.__change_list_path = change_list_path + self._has_change_list = True + self._change_list_path = change_list_path else: - print("No previous commit hash found, regular or seeded sequences only will be run.") - self.__has_change_list = False + logger.error("No previous commit hash found, regular or seeded sequences only will be run.") + self._has_change_list = False return - # Runs the specified test sequence - def run(self, suite, test_failure_policy, safe_mode, test_timeout, global_timeout): + def _generate_result(self, s3_bucket: str, suite: str, return_code: int, report: dict, runtime_args: list): + """ + Generates the result object from the pertinent runtime meta-data and sequence report. + + @param The generated result object. + """ + + result = {} + result["src_commit"] = self._src_commit + result["dst_commit"] = self._dst_commit + result["commit_distance"] = self._commit_distance + result["src_branch"] = self._src_branch + result["dst_branch"] = self._dst_branch + result["suite"] = suite + result["use_test_impact_analysis"] = self._use_test_impact_analysis + result["source_of_truth_branch"] = self._source_of_truth_branch + result["is_source_of_truth_branch"] = self._is_source_of_truth_branch + result["has_change_list"] = self._has_change_list + result["has_historic_data"] = self._has_historic_data + result["s3_bucket"] = s3_bucket + result["runtime_args"] = runtime_args + result["return_code"] = return_code + result["report"] = report + result["change_list"] = self._change_list + return result + + def run(self, commit: str, src_branch: str, dst_branch: str, s3_bucket: str, suite: str, test_failure_policy: str, safe_mode: bool, test_timeout: int, global_timeout: int): + """ + Determins the type of sequence to run based on the commit, source branch and test branch before running the + sequence with the specified values. + + @param commit: The commit hash of the changes to run test impact analysis on. + @param src_branch: If not equal to dst_branch, the branch that is being built. + @param dst_branch: If not equal to src_branch, the destination branch for the PR being built. + @param s3_bucket: Location of S3 bucket to use for persistent storage, otherwise local disk storage will be used. + @param suite: Test suite to run. + @param test_failure_policy: Test failure policy for regular and test impact sequences (ignored when seeding). + @param safe_mode: Flag to run impact analysis tests in safe mode (ignored when seeding). + @param test_timeout: Maximum run time (in seconds) of any test target before being terminated (unlimited if None). + @param global_timeout: Maximum run time of the sequence before being terminated (unlimited if None). + """ + args = [] - seed_sequence_test_failure_policy = "continue" - # Suite - args.append(f"--suite={suite}") - print(f"Test suite is set to '{suite}'.") - # Timeouts - if test_timeout != None: - args.append(f"--ttimeout={test_timeout}") - print(f"Test target timeout is set to {test_timeout} seconds.") - if global_timeout != None: - args.append(f"--gtimeout={global_timeout}") - print(f"Global sequence timeout is set to {test_timeout} seconds.") - if self.__use_test_impact_analysis: - print("Test impact analysis is enabled.") - # Seed sequences - if self.__is_seeding: + persistent_storage = None + self._has_historic_data = False + self._change_list = {} + self._change_list["createdFiles"] = [] + self._change_list["updatedFiles"] = [] + self._change_list["deletedFiles"] = [] + + # Branches + self._src_branch = src_branch + self._dst_branch = dst_branch + logger.info(f"Src branch: '{self._src_branch}'.") + logger.info(f"Dst branch: '{self._dst_branch}'.") + + # Source of truth (the branch from which the coverage data will be stored/retrieved from) + if not self._dst_branch or self._src_branch == self._dst_branch: + # Branch builds are their own source of truth and will update the coverage data for the source of truth after any instrumented sequences complete + self._is_source_of_truth_branch = True + self._source_of_truth_branch = self._src_branch + else: + # PR builds use their destination as the source of truth and never update the coverage data for the source of truth + self._is_source_of_truth_branch = False + self._source_of_truth_branch = self._dst_branch + + logger.info(f"Source of truth branch: '{self._source_of_truth_branch}'.") + logger.info(f"Is source of truth branch: '{self._is_source_of_truth_branch}'.") + + # Commit + self._dst_commit = commit + logger.info(f"Commit: '{self._dst_commit}'.") + self._src_commit = None + self._commit_distance = None + + # Generate a unique ID to be used as part of the file name for required runtime dynamic artifacts. + instance_id = uuid.uuid4().hex + + if self._use_test_impact_analysis: + logger.info("Test impact analysis is enabled.") + try: + # Persistent storage location + if s3_bucket: + persistent_storage = PersistentStorageS3(self._config, suite, s3_bucket, self._source_of_truth_branch) + else: + persistent_storage = PersistentStorageLocal(self._config, suite) + except SystemError as e: + logger.warning(f"The persistent storage encountered an irrecoverable error, test impact analysis will be disabled: '{e}'") + persistent_storage = None + + if persistent_storage: + if persistent_storage.has_historic_data: + logger.info("Historic data found.") + self._attempt_to_generate_change_list(persistent_storage.last_commit_hash, instance_id) + else: + logger.info("No historic data found.") + # Sequence type - args.append("--sequence=seed") - print("Sequence type is set to 'seed'.") - # Test failure policy - args.append(f"--fpolicy={seed_sequence_test_failure_policy}") - print(f"Test failure policy is set to '{seed_sequence_test_failure_policy}'.") - # Impact analysis sequences - else: - if self.__has_change_list: - # Change list - args.append(f"--changelist={self.__change_list_path}") - print(f"Change list is set to '{self.__change_list_path}'.") - # Sequence type - args.append("--sequence=tianowrite") - print("Sequence type is set to 'tianowrite'.") - # Integrity failure policy - args.append("--ipolicy=continue") - print("Integration failure policy is set to 'continue'.") + if self._has_change_list: + if self._is_source_of_truth_branch: + # Use TIA sequence (instrumented subset of tests) for coverage updating branches so we can update the coverage data with the generated coverage + sequence_type = "tia" + else: + # Use TIA no-write sequence (regular subset of tests) for non coverage updating branche + sequence_type = "tianowrite" + # Ignore integrity failures for non coverage updating branches as our confidence in the + args.append("--ipolicy=continue") + logger.info("Integration failure policy is set to 'continue'.") # Safe mode if safe_mode: args.append("--safemode=on") - print("Safe mode set to 'on'.") + logger.info("Safe mode set to 'on'.") else: args.append("--safemode=off") - print("Safe mode set to 'off'.") + logger.info("Safe mode set to 'off'.") + # Change list + args.append(f"--changelist={self._change_list_path}") + logger.info(f"Change list is set to '{self._change_list_path}'.") else: - args.append("--sequence=regular") - print("Sequence type is set to 'regular'.") - # Test failure policy - args.append(f"--fpolicy={test_failure_policy}") - print(f"Test failure policy is set to '{test_failure_policy}'.") - else: - print("Test impact analysis is disabled.") - # Sequence type - args.append("--sequence=regular") - print("Sequence type is set to 'regular'.") - # Seeding job - if self.__is_seeding: - # Test failure policy - args.append(f"--fpolicy={seed_sequence_test_failure_policy}") - print(f"Test failure policy is set to '{seed_sequence_test_failure_policy}'.") - # Non seeding job + if self._is_source_of_truth_branch: + # Use seed sequence (instrumented all tests) for coverage updating branches so we can generate the coverage bed for future sequences + sequence_type = "seed" + # We always continue after test failures when seeding to ensure we capture the coverage for all test targets + test_failure_policy = "continue" + else: + # Use regular sequence (regular all tests) for non coverage updating branches as we have no coverage to use nor coverage to update + sequence_type = "regular" + # Ignore integrity failures for non coverage updating branches as our confidence in the + args.append("--ipolicy=continue") + logger.info("Integration failure policy is set to 'continue'.") else: - # Test failure policy - args.append(f"--fpolicy={test_failure_policy}") - print(f"Test failure policy is set to '{test_failure_policy}'.") - - print("Args: ", end='') - print(*args) - result = subprocess.run([self.__tiaf_bin] + args) - # If the sequence completed (with or without failures) we will update the historical meta-data - if result.returncode == 0 or result.returncode == 7: - print("Test impact analysis runtime returned successfully.") - if self.__is_seeding: - print("Writing historical meta-data...") - self.__write_last_run_hash(self.__dst_commit) - print("Complete!") + # Use regular sequence (regular all tests) when the persistent storage fails to avoid wasting time generating seed data that will not be preserved + sequence_type = "regular" else: - print(f"The test impact analysis runtime returned with error: '{result.returncode}'.") - return result.returncode - \ No newline at end of file + # Use regular sequence (regular all tests) when test impact analysis is disabled + sequence_type = "regular" + args.append(f"--sequence={sequence_type}") + logger.info(f"Sequence type is set to '{sequence_type}'.") + + # Test failure policy + args.append(f"--fpolicy={test_failure_policy}") + logger.info(f"Test failure policy is set to '{test_failure_policy}'.") + + # Sequence report + report_file = pathlib.PurePath(self._temp_workspace).joinpath(f"report.{instance_id}.json") + args.append(f"--report={report_file}") + logger.info(f"Sequence report file is set to '{report_file}'.") + + # Suite + args.append(f"--suite={suite}") + logger.info(f"Test suite is set to '{suite}'.") + + # Timeouts + if test_timeout is not None: + args.append(f"--ttimeout={test_timeout}") + logger.info(f"Test target timeout is set to {test_timeout} seconds.") + if global_timeout is not None: + args.append(f"--gtimeout={global_timeout}") + logger.info(f"Global sequence timeout is set to {test_timeout} seconds.") + + # Run sequence + unpacked_args = " ".join(args) + logger.info(f"Args: {unpacked_args}") + runtime_result = subprocess.run([str(self._tiaf_bin)] + args) + report = None + + # If the sequence completed (with or without failures) we will update the historical meta-data + if runtime_result.returncode == 0 or runtime_result.returncode == 7: + logger.info("Test impact analysis runtime returned successfully.") + if self._is_source_of_truth_branch and persistent_storage is not None: + persistent_storage.update_and_store_historic_data(self._dst_commit) + with open(report_file) as json_file: + report = json.load(json_file) + else: + logger.error(f"The test impact analysis runtime returned with error: '{runtime_result.returncode}'.") + + return self._generate_result(s3_bucket, suite, runtime_result.returncode, report, args) \ No newline at end of file diff --git a/scripts/build/TestImpactAnalysis/tiaf_driver.py b/scripts/build/TestImpactAnalysis/tiaf_driver.py index 77fc8c1fc2..5ad16abaa0 100644 --- a/scripts/build/TestImpactAnalysis/tiaf_driver.py +++ b/scripts/build/TestImpactAnalysis/tiaf_driver.py @@ -7,60 +7,138 @@ # import argparse -from tiaf import TestImpact - +import mars_utils import sys -import os -import datetime -import json -import socket +import pathlib +import traceback +from tiaf import TestImpact +from tiaf_logger import get_logger + +logger = get_logger(__file__) def parse_args(): - def file_path(value): - if os.path.isfile(value): + def valid_file_path(value): + if pathlib.Path(value).is_file(): return value else: raise FileNotFoundError(value) - def timout_type(value): + def valid_timout_type(value): value = int(value) if value <= 0: raise ValueError("Timer values must be positive integers") return value - def test_failure_policy(value): + def valid_test_failure_policy(value): if value == "continue" or value == "abort" or value == "ignore": return value else: raise ValueError("Test failure policy must be 'abort', 'continue' or 'ignore'") parser = argparse.ArgumentParser() - parser.add_argument('--config', dest="config", type=file_path, help="Path to the test impact analysis framework configuration file", required=True) - parser.add_argument('--src-branch', dest="src_branch", help="The branch that is being build", required=True) - parser.add_argument('--dst-branch', dest="dst_branch", help="For PR builds, the destination branch to be merged to, otherwise empty") - parser.add_argument('--seeding-branches', dest="seeding_branches", type=lambda arg: arg.split(','), help="Comma separated branches that seeding will occur on", required=True) - parser.add_argument('--pipeline', dest="pipeline", help="Pipeline the test impact analysis framework is running on", required=True) - parser.add_argument('--seeding-pipelines', dest="seeding_pipelines", type=lambda arg: arg.split(','), help="Comma separated pipeline that seeding will occur on", required=True) - parser.add_argument('--dest-commit', dest="dst_commit", help="Commit to run test impact analysis on (ignored when seeding)", required=True) - parser.add_argument('--suite', dest="suite", help="Test suite to run", required=True) - parser.add_argument('--test-failure-policy', dest="test_failure_policy", type=test_failure_policy, help="Test failure policy for regular and test impact sequences (ignored when seeding)", required=True) - parser.add_argument('--safeMode', dest="safe_mode", action='store_true', help="Run impact analysis tests in safe mode (ignored when seeding)") - parser.add_argument('--testTimeout', dest="test_timeout", type=timout_type, help="Maximum run time (in seconds) of any test target before being terminated", required=False) - parser.add_argument('--globalTimeout', dest="global_timeout", type=timout_type, help="Maximum run time of the sequence before being terminated", required=False) - parser.set_defaults(test_timeout=None) - parser.set_defaults(global_timeout=None) + + # Configuration file path + parser.add_argument( + '--config', + type=valid_file_path, + help="Path to the test impact analysis framework configuration file", + required=True + ) + + # Source branch + parser.add_argument( + '--src-branch', + help="Branch that is being built", + required=True + ) + + # Destination branch + parser.add_argument( + '--dst-branch', + help="For PR builds, the destination branch to be merged to, otherwise empty", + required=False + ) + + # Commit hash + parser.add_argument( + '--commit', + help="Commit that is being built", + required=True + ) + + # S3 bucket + parser.add_argument( + '--s3-bucket', + help="Location of S3 bucket to use for persistent storage, otherwise local disk storage will be used", + required=False + ) + + # MARS index prefix + parser.add_argument( + '--mars-index-prefix', + help="Index prefix to use for MARS, otherwise no data will be tramsmitted to MARS", + required=False + ) + + # Test suite + parser.add_argument( + '--suite', + help="Test suite to run", + required=True + ) + + # Test failure policy + parser.add_argument( + '--test-failure-policy', + type=valid_test_failure_policy, + help="Test failure policy for regular and test impact sequences (ignored when seeding)", + required=True + ) + + # Safe mode + parser.add_argument( + '--safe-mode', + action='store_true', + help="Run impact analysis tests in safe mode (ignored when seeding)", + required=False + ) + + # Test timeout + parser.add_argument( + '--test-timeout', + type=valid_timout_type, + help="Maximum run time (in seconds) of any test target before being terminated", + required=False + ) + + # Global timeout + parser.add_argument( + '--global-timeout', + type=valid_timout_type, + help="Maximum run time of the sequence before being terminated", + required=False + ) + args = parser.parse_args() return args if __name__ == "__main__": + try: args = parse_args() - tiaf = TestImpact(args.config, args.dst_commit, args.src_branch, args.dst_branch, args.pipeline, args.seeding_branches, args.seeding_pipelines) - return_code = tiaf.run(args.suite, args.test_failure_policy, args.safe_mode, args.test_timeout, args.global_timeout) + tiaf = TestImpact(args.config) + tiaf_result = tiaf.run(args.commit, args.src_branch, args.dst_branch, args.s3_bucket, args.suite, args.test_failure_policy, args.safe_mode, args.test_timeout, args.global_timeout) + + if args.mars_index_prefix: + logger.info("Transmitting report to MARS...") + mars_utils.transmit_report_to_mars(args.mars_index_prefix, tiaf_result, sys.argv) + + logger.info("Complete!") # Non-gating will be removed from this script and handled at the job level in SPEC-7413 - #sys.exit(return_code) + #sys.exit(result.return_code) sys.exit(0) except Exception as e: # Non-gating will be removed from this script and handled at the job level in SPEC-7413 - print(f"Exception caught by TIAF driver: {e}") + logger.error(f"Exception caught by TIAF driver: '{e}'.") + traceback.print_exc() diff --git a/scripts/build/TestImpactAnalysis/tiaf_logger.py b/scripts/build/TestImpactAnalysis/tiaf_logger.py new file mode 100644 index 0000000000..0acb9349d4 --- /dev/null +++ b/scripts/build/TestImpactAnalysis/tiaf_logger.py @@ -0,0 +1,20 @@ +# +# 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 +# +# + +import logging +import sys + +def get_logger(name: str): + logger = logging.getLogger(name) + logger.setLevel(logging.INFO) + handler = logging.StreamHandler(sys.stdout) + handler.setLevel(logging.DEBUG) + formatter = logging.Formatter('[%(asctime)s][TIAF][%(levelname)s] %(message)s') + handler.setFormatter(formatter) + logger.addHandler(handler) + return logger \ No newline at end of file diff --git a/scripts/build/TestImpactAnalysis/tiaf_persistent_storage.py b/scripts/build/TestImpactAnalysis/tiaf_persistent_storage.py new file mode 100644 index 0000000000..18ea25091f --- /dev/null +++ b/scripts/build/TestImpactAnalysis/tiaf_persistent_storage.py @@ -0,0 +1,118 @@ +# +# 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 +# +# + +import json +import pathlib +from abc import ABC, abstractmethod +from tiaf_logger import get_logger + +logger = get_logger(__file__) + +# Abstraction for the persistent storage required by TIAF to store and retrieve the branch coverage data and other meta-data +class PersistentStorage(ABC): + def __init__(self, config: dict, suite: str): + """ + Initializes the persistent storage into a state for which there is no historic data available. + + @param config: The runtime configuration to obtain the data file paths from. + @param suite: The test suite for which the historic data will be obtained for. + """ + + # Work on the assumption that there is no historic meta-data (a valid state to be in, should none exist) + self._last_commit_hash = None + self._has_historic_data = False + + try: + # The runtime expects the coverage data to be in the location specified in the config file (unless overridden with + # the --datafile command line argument, which the TIAF scripts do not do) + self._active_workspace = pathlib.Path(config["workspace"]["active"]["root"]) + unpacked_coverage_data_file = config["workspace"]["active"]["relative_paths"]["test_impact_data_files"][suite] + except KeyError as e: + raise SystemError(f"The config does not contain the key {str(e)}.") + + self._unpacked_coverage_data_file = self._active_workspace.joinpath(unpacked_coverage_data_file) + + def _unpack_historic_data(self, historic_data_json: str): + """ + Unpacks the historic data into the appropriate memory and disk locations. + + @param historic_data_json: The historic data in JSON format. + """ + + self._has_historic_data = False + + try: + historic_data = json.loads(historic_data_json) + self._last_commit_hash = historic_data["last_commit_hash"] + + # Create the active workspace directory where the coverage data file will be placed and unpack the coverage data so + # it is accessible by the runtime + self._active_workspace.mkdir(exist_ok=True) + with open(self._unpacked_coverage_data_file, "w", newline='\n') as coverage_data: + coverage_data.write(historic_data["coverage_data"]) + + self._has_historic_data = True + except json.JSONDecodeError: + logger.error("The historic data does not contain valid JSON.") + except KeyError as e: + logger.error(f"The historic data does not contain the key {str(e)}.") + except EnvironmentError as e: + logger.error(f"There was a problem the coverage data file '{self._unpacked_coverage_data_file}': '{e}'.") + + def _pack_historic_data(self, last_commit_hash: str): + """ + Packs the current historic data into a JSON file for serializing. + + @param last_commit_hash: The commit hash to associate the coverage data (and any other meta data) with. + @return: The packed historic data in JSON format. + """ + + try: + # Attempt to read the existing coverage data + if self._unpacked_coverage_data_file.is_file(): + with open(self._unpacked_coverage_data_file, "r") as coverage_data: + historic_data = {"last_commit_hash": last_commit_hash, "coverage_data": coverage_data.read()} + return json.dumps(historic_data) + else: + logger.info(f"No coverage data exists at location '{self._unpacked_coverage_data_file}'.") + except EnvironmentError as e: + logger.error(f"There was a problem the coverage data file '{self._unpacked_coverage_data_file}': '{e}'.") + except TypeError: + logger.error("The historic data could not be serialized to valid JSON.") + + return None + + @abstractmethod + def _store_historic_data(self, historic_data_json: str): + """ + Stores the historic data in the designated persistent storage location. + + @param historic_data_json: The historic data (in JSON format) to be stored in persistent storage. + """ + pass + + def update_and_store_historic_data(self, last_commit_hash: str): + """ + Updates the historic data and stores it in the designated persistent storage location. + + @param last_commit_hash: The commit hash to associate the coverage data (and any other meta data) with. + """ + + historic_data_json = self._pack_historic_data(last_commit_hash) + if historic_data_json: + self._store_historic_data(historic_data_json) + else: + logger.info("The historic data could not be successfully stored.") + + @property + def has_historic_data(self): + return self._has_historic_data + + @property + def last_commit_hash(self): + return self._last_commit_hash \ No newline at end of file diff --git a/scripts/build/TestImpactAnalysis/tiaf_persistent_storage_local.py b/scripts/build/TestImpactAnalysis/tiaf_persistent_storage_local.py new file mode 100644 index 0000000000..ba9b58fbf3 --- /dev/null +++ b/scripts/build/TestImpactAnalysis/tiaf_persistent_storage_local.py @@ -0,0 +1,56 @@ +# +# 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 +# +# + +import pathlib +import logging +from tiaf_persistent_storage import PersistentStorage +from tiaf_logger import get_logger + +logger = get_logger(__file__) + +# Implementation of local persistent storage +class PersistentStorageLocal(PersistentStorage): + def __init__(self, config: str, suite: str): + """ + Initializes the persistent storage with any local historic data available. + + @param config: The runtime config file to obtain the data file paths from. + @param suite: The test suite for which the historic data will be obtained for. + """ + + super().__init__(config, suite) + try: + # Attempt to obtain the local persistent data location specified in the runtime config file + self._historic_workspace = pathlib.Path(config["workspace"]["historic"]["root"]) + historic_data_file = pathlib.Path(config["workspace"]["historic"]["relative_paths"]["data"]) + + # Attempt to unpack the local historic data file + self._historic_data_file = self._historic_workspace.joinpath(historic_data_file) + if self._historic_data_file.is_file(): + with open(self._historic_data_file, "r") as historic_data_raw: + historic_data_json = historic_data_raw.read() + self._unpack_historic_data(historic_data_json) + + except KeyError as e: + raise SystemError(f"The config does not contain the key {str(e)}.") + except EnvironmentError as e: + raise SystemError(f"There was a problem the historic data file '{self._historic_data_file}': '{e}'.") + + def _store_historic_data(self, historic_data_json: str): + """ + Stores then historical data in historic workspace location specified in the runtime config file. + + @param historic_data_json: The historic data (in JSON format) to be stored in persistent storage. + """ + + try: + self._historic_workspace.mkdir(exist_ok=True) + with open(self._historic_data_file, "w") as historic_data_file: + historic_data_file.write(historic_data_json) + except EnvironmentError as e: + logger.error(f"There was a problem the historic data file '{self._historic_data_file}': '{e}'.") \ No newline at end of file diff --git a/scripts/build/TestImpactAnalysis/tiaf_persistent_storage_s3.py b/scripts/build/TestImpactAnalysis/tiaf_persistent_storage_s3.py new file mode 100644 index 0000000000..09b4df0564 --- /dev/null +++ b/scripts/build/TestImpactAnalysis/tiaf_persistent_storage_s3.py @@ -0,0 +1,84 @@ +# +# 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 +# +# + +import boto3 +import botocore.exceptions +import zlib +import logging +from io import BytesIO +from tiaf_persistent_storage import PersistentStorage +from tiaf_logger import get_logger + +logger = get_logger(__file__) + +# Implementation of s3 bucket persistent storage +class PersistentStorageS3(PersistentStorage): + def __init__(self, config: dict, suite: str, s3_bucket: str, branch: str): + """ + Initializes the persistent storage with the specified s3 bucket. + + @param config: The runtime config file to obtain the data file paths from. + @param suite: The test suite for which the historic data will be obtained for. + @param s3_bucket: The s3 bucket to use for storing nd retrieving historic data. + """ + + super().__init__(config, suite) + + try: + # We store the historic data as compressed JSON + object_extension = "json.zip" + + # historic_data.json.zip is the file containing the coverage and meta-data of the last TIAF sequence run + historic_data_file = f"historic_data.{object_extension}" + + # The location of the data is in the form / so the build config of each branch gets its own historic data + self._dir = f'{branch}/{config["meta"]["build_config"]}' + self._historic_data_key = f'{self._dir}/{historic_data_file}' + + logger.info(f"Attempting to retrieve historic data for branch '{branch}' at location '{self._historic_data_key}' on bucket '{s3_bucket}'...") + self._s3 = boto3.resource("s3") + self._bucket = self._s3.Bucket(s3_bucket) + + # There is only one historic_data.json.zip in the specified location + for object in self._bucket.objects.filter(Prefix=self._historic_data_key): + logger.info(f"Historic data found for branch '{branch}'.") + + # Decode the historic data object into raw bytes + logger.info(f"Attempting to decode historic data object...") + response = object.get() + file_stream = response['Body'] + logger.info(f"Decoding complete.") + + # Decompress and unpack the zipped historic data JSON + historic_data_json = zlib.decompress(file_stream.read()).decode('UTF-8') + self._unpack_historic_data(historic_data_json) + + return + except KeyError as e: + raise SystemError(f"The config does not contain the key {str(e)}.") + except botocore.exceptions.BotoCoreError as e: + raise SystemError(f"There was a problem with the s3 bucket: {e}") + except botocore.exceptions.ClientError as e: + raise SystemError(f"There was a problem with the s3 client: {e}") + + def _store_historic_data(self, historic_data_json: str): + """ + Stores then historical data in specified s3 bucket at the location //historical_data.json.zip. + + @param historic_data_json: The historic data (in JSON format) to be stored in persistent storage. + """ + + try: + data = BytesIO(zlib.compress(bytes(historic_data_json, "UTF-8"))) + logger.info(f"Uploading historic data to location '{self._historic_data_key}'...") + self._bucket.upload_fileobj(data, self._historic_data_key, ExtraArgs={'ACL': 'bucket-owner-full-control'}) + logger.info("Upload complete.") + except botocore.exceptions.BotoCoreError as e: + logger.error(f"There was a problem with the s3 bucket: {e}") + except botocore.exceptions.ClientError as e: + logger.error(f"There was a problem with the s3 client: {e}") \ No newline at end of file