diff --git a/.gitignore b/.gitignore
index 9012ec7576..2820d1e1c1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,18 +2,14 @@
.vs/
.vscode/
__pycache__
-AssetProcessorTemp/**
[Bb]uild/
[Oo]ut/**
CMakeUserPresets.json
[Cc]ache/
/[Ii]nstall/
-Editor/EditorEventLog.xml
-Editor/EditorLayout.xml
**/*egg-info/**
**/*egg-link
**/[Rr]estricted
-UserSettings.xml
[Uu]ser/
FrameCapture/**
.DS_Store
@@ -22,9 +18,6 @@ client*.cfg
server*.cfg
.mayaSwatches/
_savebackup/
-#Output folder for test results when running Automated Tests
-TestResults/**
*.swatches
/imgui.ini
-/scripts/project_manager/logs/
-/AutomatedTesting/Gem/PythonTests/scripting/TestResults
+
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 5e3828ad02..36fc6003f7 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
@@ -5,15 +5,22 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
+from typing import List
+from math import isclose
+import collections.abc
+
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
-from math import isclose
-import collections.abc
+from editor_python_test_tools.utils import TestHelper as helper
+
+
+def open_base_level():
+ helper.init_idle()
+ helper.open_level("Prefab", "Base")
def find_entity_by_name(entity_name):
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_bundler_batch_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_bundler_batch_tests.py
index f5e5642573..f64427f6df 100755
--- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_bundler_batch_tests.py
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_bundler_batch_tests.py
@@ -108,7 +108,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object):
"""
helper = bundler_batch_helper
seed_list = os.path.join(workspace.paths.engine_root(), "Assets", "Engine", "SeedAssetList.seed") # Engine seed list
- asset = r"levels\testdependencieslevel\level.pak"
+ asset = r"levels\testdependencieslevel\testdependencieslevel.spawnable"
# Create Asset list
helper.call_assetLists(
@@ -191,7 +191,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object):
"""
helper = bundler_batch_helper
seed_list = os.path.join(workspace.paths.engine_root(), "Assets", "Engine", "SeedAssetList.seed") # Engine seed list
- asset = r"levels\testdependencieslevel\level.pak"
+ asset = r"levels\testdependencieslevel\testdependencieslevel.spawnable"
# Useful bundle locations / names (2 for comparing contents)
# fmt:off
@@ -924,7 +924,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object):
# Create a seed file
helper.call_seeds(
seedListFile=helper["seed_list_file"],
- addSeed=r"levels\testdependencieslevel\level.pak",
+ addSeed=r"levels\testdependencieslevel\testdependencieslevel.spawnable",
platform="pc",
)
@@ -947,9 +947,9 @@ class TestsAssetBundlerBatch_WindowsAndMac(object):
# Specifying platform but not "add" or "remove" should fail
result, _ = helper.call_assetLists(
assetListFile=helper["asset_info_file_request"],
+ allowOverwrites="",
seedListFile=helper["seed_list_file"],
platform="pc",
- allowOverwrites="",
)
assert result, "Overwriting with override threw an error"
@@ -982,7 +982,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object):
request.addfinalizer(lambda: fs.delete([bundle_result_path], True, False))
bundles_folder = os.path.join(workspace.paths.project(), "Bundles")
- level_pak = r"levels\testdependencieslevel\level.pak"
+ level_pak = r"levels\testdependencieslevel\testdependencieslevel.spawnable"
bundle_request_path = os.path.join(bundles_folder, "bundle.pak")
bundle_result_path = os.path.join(bundles_folder,
helper.platform_file_name("bundle.pak", workspace.asset_processor_platform))
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_tests.py
index af92bb1773..b2252567b6 100644
--- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_tests.py
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_tests.py
@@ -23,12 +23,11 @@ from ..ap_fixtures.timeout_option_fixture import timeout_option_fixture as timeo
@pytest.mark.SUITE_periodic
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
-@pytest.mark.parametrize('level', ['auto_test'])
+@pytest.mark.parametrize('level', ['TestDependenciesLevel'])
class TestBundleMode(object):
def test_bundle_mode_with_levels_mounts_bundles_correctly(self, request, editor, level, launcher_platform,
asset_processor, workspace, bundler_batch_helper):
- level_pak = os.path.join("levels", level, "level.pak")
-
+ level_pak = os.path.join("levels", level, "TestDependenciesLevel.spawnable")
bundles_folder = os.path.join(workspace.paths.project(), "Bundles")
bundle_request_path = os.path.join(bundles_folder, "bundle.pak")
bundle_result_path = os.path.join(bundles_folder,
diff --git a/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/base.py b/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/base.py
index 0441f8a1dc..4db959b23e 100755
--- a/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/base.py
+++ b/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/base.py
@@ -182,7 +182,7 @@ class TestAutomationBase:
@staticmethod
def _kill_ly_processes(include_asset_processor=True):
LY_PROCESSES = [
- 'Editor', 'Profiler', 'RemoteConsole', 'AutomatedTesting.ServerLauncher'
+ 'Editor', 'Profiler', 'RemoteConsole', 'AutomatedTesting.ServerLauncher', 'o3de'
]
AP_PROCESSES = [
'AssetProcessor', 'AssetProcessorBatch', 'AssetBuilder', 'CrySCompileServer',
diff --git a/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt
index 1fc71da972..b3f0d2da8e 100644
--- a/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt
@@ -9,10 +9,10 @@
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_FOUNDATION_TEST_SUPPORTED)
ly_add_pytest(
- NAME AutomatedTesting::EditorTests_Main_Optimized
+ NAME AutomatedTesting::EditorTests_Main
TEST_SUITE main
TEST_SERIAL
- PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main_Optimized.py
+ PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py
PYTEST_MARKS "not REQUIRES_gpu"
RUNTIME_DEPENDENCIES
Legacy::Editor
@@ -27,7 +27,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
TEST_SUITE main
TEST_SERIAL
TEST_REQUIRES gpu
- PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main_Optimized.py
+ PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py
PYTEST_MARKS "REQUIRES_gpu"
RUNTIME_DEPENDENCIES
Legacy::Editor
@@ -37,17 +37,4 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
Editor
)
- ly_add_pytest(
- NAME AutomatedTesting::EditorTests_Sandbox_Optimized
- TEST_SUITE sandbox
- TEST_SERIAL
- PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Sandbox_Optimized.py
- RUNTIME_DEPENDENCIES
- Legacy::Editor
- AZ::AssetProcessor
- AutomatedTesting.Assets
- COMPONENT
- Editor
- )
-
endif()
diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_SearchFiltering.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_SearchFiltering.py
index b18bf65312..4265dd6fc9 100644
--- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_SearchFiltering.py
+++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_SearchFiltering.py
@@ -59,8 +59,8 @@ def AssetBrowser_SearchFiltering():
import azlmbr.legacy.general as general
+ import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
- from editor_python_test_tools.utils import TestHelper as helper
def verify_files_appeared(model, allowed_asset_extensions, parent_index=QtCore.QModelIndex()):
indexes = [parent_index]
@@ -80,8 +80,7 @@ def AssetBrowser_SearchFiltering():
return True
# 1) Open an existing simple level
- helper.init_idle()
- helper.open_level("Physics", "Base")
+ hydra.open_base_level()
# 2) Open Asset Browser (if not opened already)
editor_window = pyside_utils.get_editor_main_window()
diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_TreeNavigation.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_TreeNavigation.py
index ecc77778cc..52072205b5 100644
--- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_TreeNavigation.py
+++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_TreeNavigation.py
@@ -53,6 +53,7 @@ def AssetBrowser_TreeNavigation():
import azlmbr.legacy.general as general
import editor_python_test_tools.pyside_utils as pyside_utils
+ import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
@@ -69,8 +70,7 @@ def AssetBrowser_TreeNavigation():
file_path = ("AutomatedTesting", "Assets", "ImageGradients", "image_grad_test_gsi.png")
# 1) Open an existing simple level
- helper.init_idle()
- helper.open_level("Physics", "Base")
+ hydra.open_base_level()
# 2) Open Asset Browser (if not opened already)
editor_window = pyside_utils.get_editor_main_window()
diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetPicker_UI_UX.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetPicker_UI_UX.py
index 59a78c9e5d..047d6edf41 100644
--- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetPicker_UI_UX.py
+++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetPicker_UI_UX.py
@@ -215,8 +215,7 @@ def AssetPicker_UI_UX():
QtTest.QTest.keyClick(tree, Qt.Key_Enter, Qt.NoModifier)
# 1) Open an existing simple level
- helper.init_idle()
- helper.open_level("Physics", "Base")
+ hydra.open_base_level()
# 2) Create entity and add Mesh component
entity_position = math.Vector3(125.0, 136.0, 32.0)
diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD.py
index 39cacf9af5..48b7d2b176 100644
--- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD.py
+++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD.py
@@ -56,19 +56,17 @@ def BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD():
06. delete parent entity
"""
+ import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
from editor_python_test_tools.editor_entity_utils import EditorEntity
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.entity as entity
- import azlmbr.legacy.general as general
import azlmbr.object
# 01. load an existing level
- test_level = 'Simple'
- general.open_level_no_prompt(test_level)
- Report.result(Tests.load_level, general.get_current_level_name() == test_level)
+ hydra.open_base_level()
# 02. create parent entity and set name
# Delete any exiting entity and Create a new Entity at the root level
diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_LevelEntityComponentCRUD.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_LevelEntityComponentCRUD.py
index 9c5880ab1e..f13b924e30 100644
--- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_LevelEntityComponentCRUD.py
+++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_LevelEntityComponentCRUD.py
@@ -31,7 +31,7 @@ class Tests:
"Component removed from entity successfully",
"Failed to remove component from entity"
)
- level_saved_and_exported = (
+ saved_and_exported = (
"Level saved and exported successfully",
"Failed to save/export level"
)
@@ -52,8 +52,7 @@ def BasicEditorWorkflows_LevelEntityComponentCRUD():
- A new entity can be created
- Entity hierarchy can be adjusted
- Components can be added/removed/updated
- - Level can be saved
- - Level can be exported
+ - Level can be saved/exported
Note:
- This test file must be called from the O3DE Editor command terminal
@@ -70,7 +69,7 @@ def BasicEditorWorkflows_LevelEntityComponentCRUD():
import azlmbr.editor as editor
import azlmbr.entity as entity
import azlmbr.math as math
- import azlmbr.paths
+ import azlmbr.paths as paths
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
@@ -84,7 +83,7 @@ def BasicEditorWorkflows_LevelEntityComponentCRUD():
return None
# 1) Create a new level
- level = "tmp_level"
+ lvl_name = "tmp_level"
editor_window = pyside_utils.get_editor_main_window()
new_level_action = pyside_utils.get_action_for_menu_path(editor_window, "File", "New Level")
pyside_utils.trigger_action_async(new_level_action)
@@ -95,23 +94,24 @@ def BasicEditorWorkflows_LevelEntityComponentCRUD():
Report.info("New Level dialog opened")
grp_box = new_level_dlg.findChild(QtWidgets.QGroupBox, "STATIC_GROUP1")
level_name = grp_box.findChild(QtWidgets.QLineEdit, "LEVEL")
- level_name.setText(level)
+ level_name.setText(lvl_name)
button_box = new_level_dlg.findChild(QtWidgets.QDialogButtonBox, "buttonBox")
button_box.button(QtWidgets.QDialogButtonBox.Ok).click()
# Verify new level was created successfully
level_create_success = await pyside_utils.wait_for_condition(lambda: editor.EditorToolsApplicationRequestBus(
- bus.Broadcast, "GetCurrentLevelName") == level, 5.0)
+ bus.Broadcast, "GetCurrentLevelName") == lvl_name, 5.0)
Report.critical_result(Tests.level_created, level_create_success)
# 2) Delete existing entities, and create and manipulate new entities via Entity Inspector
search_filter = azlmbr.entity.SearchFilter()
all_entities = entity.SearchBus(azlmbr.bus.Broadcast, "SearchEntities", search_filter)
editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntities", all_entities)
- entity_outliner_widget = editor_window.findChild(QtWidgets.QWidget, "OutlinerWidgetUI")
+ entity_outliner_widget = editor_window.findChild(QtWidgets.QWidget, "EntityOutlinerWidgetUI")
outliner_object_list = entity_outliner_widget.findChild(QtWidgets.QWidget, "m_objectList_Contents")
outliner_tree = outliner_object_list.findChild(QtWidgets.QWidget, "m_objectTree")
- await pyside_utils.trigger_context_menu_entry(outliner_tree, "Create entity")
+ outliner_viewport = outliner_tree.findChild(QtWidgets.QWidget, "qt_scrollarea_viewport")
+ await pyside_utils.trigger_context_menu_entry(outliner_viewport, "Create entity")
# Find the new entity
parent_entity_id = find_entity_by_name("Entity1")
@@ -153,14 +153,10 @@ def BasicEditorWorkflows_LevelEntityComponentCRUD():
save_level_action = pyside_utils.get_action_for_menu_path(editor_window, "File", "Save")
pyside_utils.trigger_action_async(save_level_action)
- # 5) Export the level
- export_action = pyside_utils.get_action_for_menu_path(editor_window, "Game", "Export to Engine")
- pyside_utils.trigger_action_async(export_action)
- level_pak_file = os.path.join(
- "AutomatedTesting", "Levels", level, "level.pak"
- )
- export_success = await pyside_utils.wait_for_condition(lambda: os.path.exists(level_pak_file), 5.0)
- Report.result(Tests.level_saved_and_exported, export_success)
+ # 5) Verify the save/export of the level
+ level_prefab_path = os.path.join(paths.products, "levels", lvl_name, f"{lvl_name}.spawnable")
+ success = await pyside_utils.wait_for_condition(lambda: os.path.exists(level_prefab_path), 5.0)
+ Report.result(Tests.saved_and_exported, success)
run_test()
diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/ComponentCRUD_Add_Delete_Components.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/ComponentCRUD_Add_Delete_Components.py
index 779f1ef953..6772450405 100755
--- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/ComponentCRUD_Add_Delete_Components.py
+++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/ComponentCRUD_Add_Delete_Components.py
@@ -63,7 +63,7 @@ def ComponentCRUD_Add_Delete_Components():
:return: None
"""
- from PySide2 import QtWidgets, QtTest, QtCore
+ from PySide2 import QtWidgets, QtTest
from PySide2.QtCore import Qt
import azlmbr.legacy.general as general
@@ -74,7 +74,6 @@ def ComponentCRUD_Add_Delete_Components():
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
- from editor_python_test_tools.utils import TestHelper as helper
async def add_component(component_name):
pyside_utils.click_button_async(add_comp_btn)
@@ -88,8 +87,7 @@ def ComponentCRUD_Add_Delete_Components():
QtTest.QTest.keyClick(tree, Qt.Key_Enter, Qt.NoModifier)
# 1) Open an existing simple level
- helper.init_idle()
- helper.open_level("Physics", "Base")
+ hydra.open_base_level()
# 2) Create entity
entity_position = math.Vector3(125.0, 136.0, 32.0)
diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py
index 6683fc952a..a5a94f06a5 100644
--- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py
+++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py
@@ -62,12 +62,11 @@ def Docking_BasicDockedTools():
import azlmbr.editor as editor
import azlmbr.entity as entity
+ import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
- from editor_python_test_tools.utils import TestHelper as helper
# Open an existing simple level
- helper.init_idle()
- helper.open_level("Physics", "Base")
+ hydra.open_base_level()
# Make sure the Entity Outliner, Entity Inspector and Console tools are open
general.open_pane("Entity Outliner (PREVIEW)")
@@ -80,7 +79,7 @@ def Docking_BasicDockedTools():
editor.EditorEntityAPIBus(bus.Event, 'SetName', entity_id, entity_original_name)
editor_window = pyside_utils.get_editor_main_window()
- entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner (PREVIEW)")
+ entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner")
# 1) Open the tools and dock them together in a floating tabbed widget.
# We drag/drop it over the viewport since it doesn't allow docking, so this will undock it
@@ -88,15 +87,15 @@ def Docking_BasicDockedTools():
pyside_utils.drag_and_drop(entity_outliner, render_overlay)
# We need to grab a new reference to the Entity Outliner QDockWidget because when it gets moved
- # to the floating window, its parent changes so the wrapped intance we had becomes invalid
- entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner (PREVIEW)")
+ # to the floating window, its parent changes so the wrapped instance we had becomes invalid
+ entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner")
# Dock the Entity Inspector tabbed with the floating Entity Outliner
entity_inspector = editor_window.findChild(QtWidgets.QDockWidget, "Entity Inspector")
pyside_utils.drag_and_drop(entity_inspector, entity_outliner)
# We need to grab a new reference to the Entity Inspector QDockWidget because when it gets moved
- # to the floating window, its parent changes so the wrapped intance we had becomes invalid
+ # to the floating window, its parent changes so the wrapped instance we had becomes invalid
entity_inspector = editor_window.findChild(QtWidgets.QDockWidget, "Entity Inspector")
# Dock the Console tabbed with the floating Entity Inspector
@@ -106,7 +105,7 @@ def Docking_BasicDockedTools():
# Check to ensure all the tools are parented to the same QStackedWidget
def check_all_panes_tabbed():
entity_inspector = editor_window.findChild(QtWidgets.QDockWidget, "Entity Inspector")
- entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner (PREVIEW)")
+ entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner")
console = editor_window.findChild(QtWidgets.QDockWidget, "Console")
entity_inspector_parent = entity_inspector.parentWidget()
entity_outliner_parent = entity_outliner.parentWidget()
@@ -122,7 +121,7 @@ def Docking_BasicDockedTools():
# 2.1,2) Select an Entity in the Entity Outliner.
entity_inspector = editor_window.findChild(QtWidgets.QDockWidget, "Entity Inspector")
- entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner (PREVIEW)")
+ entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner")
console = editor_window.findChild(QtWidgets.QDockWidget, "Console")
object_tree = entity_outliner.findChild(QtWidgets.QTreeView, "m_objectTree")
test_entity_index = pyside_utils.find_child_by_pattern(object_tree, entity_original_name)
diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/EntityOutliner_EntityOrdering.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/EntityOutliner_EntityOrdering.py
index 5fa8130302..fab7984df9 100644
--- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/EntityOutliner_EntityOrdering.py
+++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/EntityOutliner_EntityOrdering.py
@@ -30,11 +30,13 @@ def EntityOutliner_EntityOrdering():
5) Add another new entity, ensure the rest of the order is unchanged
"""
- import editor_python_test_tools.pyside_utils as pyside_utils
+ from PySide2 import QtCore
+
import azlmbr.legacy.general as general
+
+ import editor_python_test_tools.hydra_editor_utils as hydra
+ import editor_python_test_tools.pyside_utils as pyside_utils
from editor_python_test_tools.utils import Report
- from editor_python_test_tools.utils import TestHelper as helper
- from PySide2 import QtCore, QtWidgets, QtGui, QtTest
# Grab the Editor, Entity Outliner, and Outliner Model
editor_window = pyside_utils.get_editor_main_window()
@@ -110,8 +112,7 @@ def EntityOutliner_EntityOrdering():
expected_order = []
# 1) Open the empty Prefab Base level
- helper.init_idle()
- helper.open_level("Prefab", "Base")
+ hydra.open_base_level()
# 2) Add 5 entities to the outliner
ENTITIES_TO_ADD = 5
diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/InputBindings_Add_Remove_Input_Events.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/InputBindings_Add_Remove_Input_Events.py
index f4769dab4d..07c89ff110 100755
--- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/InputBindings_Add_Remove_Input_Events.py
+++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/InputBindings_Add_Remove_Input_Events.py
@@ -69,8 +69,8 @@ def InputBindings_Add_Remove_Input_Events():
import azlmbr.legacy.general as general
+ import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
- from editor_python_test_tools.utils import TestHelper as helper
def open_asset_editor():
general.open_pane("Asset Editor")
@@ -81,8 +81,7 @@ def InputBindings_Add_Remove_Input_Events():
return not general.is_pane_visible("Asset Editor")
# 1) Open an existing simple level
- helper.init_idle()
- helper.open_level("Physics", "Base")
+ hydra.open_base_level()
# 2) Open Asset Editor
Report.result(Tests.asset_editor_opened, open_asset_editor())
diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py
index bd213be293..ce85cf223f 100644
--- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py
+++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py
@@ -26,9 +26,9 @@ def Menus_EditMenuOptions_Work():
:return: None
"""
+ import editor_python_test_tools.hydra_editor_utils as hydra
import editor_python_test_tools.pyside_utils as pyside_utils
from editor_python_test_tools.utils import Report
- from editor_python_test_tools.utils import TestHelper as helper
edit_menu_options = [
("Undo",),
@@ -52,19 +52,20 @@ def Menus_EditMenuOptions_Work():
("Editor Settings", "Global Preferences"),
("Editor Settings", "Editor Settings Manager"),
("Editor Settings", "Keyboard Customization", "Customize Keyboard"),
- ("Editor Settings", "Keyboard Customization", "Export Keyboard Settings"),
- ("Editor Settings", "Keyboard Customization", "Import Keyboard Settings"),
+ # The following menu options are temporarily disabled due to https://github.com/o3de/o3de/issues/6746
+ #("Editor Settings", "Keyboard Customization", "Export Keyboard Settings"),
+ #("Editor Settings", "Keyboard Customization", "Import Keyboard Settings"),
]
# 1) Open an existing simple level
- helper.init_idle()
- helper.open_level("Physics", "Base")
+ hydra.open_base_level()
# 2) Interact with Edit Menu options
editor_window = pyside_utils.get_editor_main_window()
for option in edit_menu_options:
try:
action = pyside_utils.get_action_for_menu_path(editor_window, "Edit", *option)
+ Report.info(f"Triggering {action.iconText()}")
action.trigger()
action_triggered = True
except Exception as e:
diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py
index a3e7611b5e..4fcdc371e7 100644
--- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py
+++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py
@@ -26,35 +26,34 @@ def Menus_FileMenuOptions_Work():
:return: None
"""
+ import editor_python_test_tools.hydra_editor_utils as hydra
import editor_python_test_tools.pyside_utils as pyside_utils
from editor_python_test_tools.utils import Report
- from editor_python_test_tools.utils import TestHelper as helper
file_menu_options = [
("New Level",),
- ("Open Level",),
- ("Import",),
+ #("Open Level",), Temporarily disabled due to https://github.com/o3de/o3de/issues/6605
+ #("Import",), Temporarily disabled due to https://github.com/o3de/o3de/issues/6746
("Save",),
- ("Save As",),
+ #("Save As",), Temporarily disabled due to https://github.com/o3de/o3de/issues/6605
("Save Level Statistics",),
("Edit Project Settings",),
- ("Edit Platform Settings",),
+ #("Edit Platform Settings",), Temporarily disabled due to https://github.com/o3de/o3de/issues/6604
("New Project",),
("Open Project",),
("Show Log File",),
- ("Resave All Slices",),
("Exit",),
]
# 1) Open an existing simple level
- helper.init_idle()
- helper.open_level("Physics", "Base")
+ hydra.open_base_level()
# 2) Interact with File Menu options
editor_window = pyside_utils.get_editor_main_window()
for option in file_menu_options:
try:
action = pyside_utils.get_action_for_menu_path(editor_window, "File", *option)
+ Report.info(f"Triggering {action.iconText()}")
action.trigger()
action_triggered = True
except Exception as e:
diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py
index deff2855a0..bb9ff15082 100644
--- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py
+++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py
@@ -26,13 +26,15 @@ def Menus_ViewMenuOptions_Work():
:return: None
"""
+ import editor_python_test_tools.hydra_editor_utils as hydra
import editor_python_test_tools.pyside_utils as pyside_utils
from editor_python_test_tools.utils import Report
- from editor_python_test_tools.utils import TestHelper as helper
view_menu_options = [
("Center on Selection",),
("Show Quick Access Bar",),
+ ("Layouts", "Component Entity Layout",),
+ ("Layouts", "Save Layout",),
("Viewport", "Configure Layout"),
("Viewport", "Go to Position"),
("Viewport", "Center on Selection"),
@@ -45,14 +47,14 @@ def Menus_ViewMenuOptions_Work():
]
# 1) Open an existing simple level
- helper.init_idle()
- helper.open_level("Physics", "Base")
+ hydra.open_base_level()
# 2) Interact with View Menu options
editor_window = pyside_utils.get_editor_main_window()
for option in view_menu_options:
try:
action = pyside_utils.get_action_for_menu_path(editor_window, "View", *option)
+ Report.info(f"Triggering {action.iconText()}")
action.trigger()
action_triggered = True
except Exception as e:
diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main.py
index c9e91687e0..3805ef15dd 100644
--- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main.py
+++ b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main.py
@@ -7,48 +7,77 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
import os
import pytest
-import sys
import ly_test_tools.environment.file_system as file_system
-
-sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared')
-from base import TestAutomationBase
-
-
-@pytest.fixture
-def remove_test_level(request, workspace, project):
- file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", "tmp_level")], True, True)
-
- def teardown():
- file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", "tmp_level")], True, True)
-
- request.addfinalizer(teardown)
+from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
@pytest.mark.SUITE_main
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
-class TestAutomation(TestAutomationBase):
+class TestAutomationNoAutoTestMode(EditorTestSuite):
- def test_BasicEditorWorkflows_LevelEntityComponentCRUD(self, request, workspace, editor, launcher_platform,
- remove_test_level):
+ # Disable -autotest_mode and -BatchMode. Tests cannot run in -BatchMode due to UI interactions, and these tests
+ # interact with modal dialogs
+ global_extra_cmdline_args = []
+
+ class test_AssetPicker_UI_UX(EditorSharedTest):
+ from .EditorScripts import AssetPicker_UI_UX as test_module
+
+ class test_BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD(EditorSharedTest):
+ from .EditorScripts import BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD as test_module
+
+ class test_BasicEditorWorkflows_LevelEntityComponentCRUD(EditorSingleTest):
+ # Custom teardown to remove level created during test
+ def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
+ file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")],
+ True, True)
from .EditorScripts import BasicEditorWorkflows_LevelEntityComponentCRUD as test_module
- self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False, enable_prefab_system=False)
@pytest.mark.REQUIRES_gpu
- def test_BasicEditorWorkflows_GPU_LevelEntityComponentCRUD(self, request, workspace, editor, launcher_platform,
- remove_test_level):
- from .EditorScripts import BasicEditorWorkflows_LevelEntityComponentCRUD as test_module
- self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False,
- use_null_renderer=False, enable_prefab_system=False)
+ class test_BasicEditorWorkflows_GPU_LevelEntityComponentCRUD(EditorSingleTest):
+ # Disable null renderer
+ use_null_renderer = False
- def test_EntityOutlienr_EntityOrdering(self, request, workspace, editor, launcher_platform):
+ # Custom teardown to remove level created during test
+ def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
+ file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")],
+ True, True)
+ from .EditorScripts import BasicEditorWorkflows_LevelEntityComponentCRUD as test_module
+
+ class test_InputBindings_Add_Remove_Input_Events(EditorSharedTest):
+ from .EditorScripts import InputBindings_Add_Remove_Input_Events as test_module
+
+
+@pytest.mark.SUITE_main
+@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
+@pytest.mark.parametrize("project", ["AutomatedTesting"])
+class TestAutomationAutoTestMode(EditorTestSuite):
+
+ # Enable only -autotest_mode for these tests. Tests cannot run in -BatchMode due to UI interactions
+ global_extra_cmdline_args = ["-autotest_mode"]
+
+ class test_AssetBrowser_SearchFiltering(EditorSharedTest):
+ from .EditorScripts import AssetBrowser_SearchFiltering as test_module
+
+ class test_AssetBrowser_TreeNavigation(EditorSharedTest):
+ from .EditorScripts import AssetBrowser_TreeNavigation as test_module
+
+ class test_ComponentCRUD_Add_Delete_Components(EditorSharedTest):
+ from .EditorScripts import ComponentCRUD_Add_Delete_Components as test_module
+
+ @pytest.mark.skip("Passes locally/fails on Jenkins. https://github.com/o3de/o3de/issues/6747")
+ class test_Docking_BasicDockedTools(EditorSharedTest):
+ from .EditorScripts import Docking_BasicDockedTools as test_module
+
+ class test_EntityOutliner_EntityOrdering(EditorSharedTest):
from .EditorScripts import EntityOutliner_EntityOrdering as test_module
- self._run_test(
- request,
- workspace,
- editor,
- test_module,
- batch_mode=False,
- autotest_mode=True,
- )
+
+ class test_Menus_EditMenuOptions_Work(EditorSharedTest):
+ from .EditorScripts import Menus_EditMenuOptions as test_module
+
+ class test_Menus_FileMenuOptions_Work(EditorSharedTest):
+ from .EditorScripts import Menus_FileMenuOptions as test_module
+
+ class test_Menus_ViewMenuOptions_Work(EditorSharedTest):
+ from .EditorScripts import Menus_ViewMenuOptions as test_module
diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py
deleted file mode 100644
index d87fd8625b..0000000000
--- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py
+++ /dev/null
@@ -1,79 +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
-"""
-
-import os
-import pytest
-
-import ly_test_tools.environment.file_system as file_system
-from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
-
-
-@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.")
-@pytest.mark.SUITE_main
-@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
-@pytest.mark.parametrize("project", ["AutomatedTesting"])
-class TestAutomationNoAutoTestMode(EditorTestSuite):
-
- # Disable -autotest_mode and -BatchMode. Tests cannot run in -BatchMode due to UI interactions, and these tests
- # interact with modal dialogs
- global_extra_cmdline_args = []
-
- enable_prefab_system = False
-
- class test_BasicEditorWorkflows_LevelEntityComponentCRUD(EditorSingleTest):
- # Custom teardown to remove slice asset created during test
- def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
- file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")],
- True, True)
- from .EditorScripts import BasicEditorWorkflows_LevelEntityComponentCRUD as test_module
-
- @pytest.mark.REQUIRES_gpu
- class test_BasicEditorWorkflows_GPU_LevelEntityComponentCRUD(EditorSingleTest):
- # Disable null renderer
- use_null_renderer = False
-
- # Custom teardown to remove slice asset created during test
- def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
- file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")],
- True, True)
- from .EditorScripts import BasicEditorWorkflows_LevelEntityComponentCRUD as test_module
-
- class test_InputBindings_Add_Remove_Input_Events(EditorSharedTest):
- from .EditorScripts import InputBindings_Add_Remove_Input_Events as test_module
-
- class test_AssetPicker_UI_UX(EditorSharedTest):
- from .EditorScripts import AssetPicker_UI_UX as test_module
-
-
-@pytest.mark.SUITE_main
-@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
-@pytest.mark.parametrize("project", ["AutomatedTesting"])
-class TestAutomationAutoTestMode(EditorTestSuite):
-
- # Enable only -autotest_mode for these tests. Tests cannot run in -BatchMode due to UI interactions
- global_extra_cmdline_args = ["-autotest_mode"]
-
- enable_prefab_system = False
-
- class test_AssetBrowser_TreeNavigation(EditorSharedTest):
- from .EditorScripts import AssetBrowser_TreeNavigation as test_module
-
- class test_AssetBrowser_SearchFiltering(EditorSharedTest):
- from .EditorScripts import AssetBrowser_SearchFiltering as test_module
-
- class test_ComponentCRUD_Add_Delete_Components(EditorSharedTest):
- from .EditorScripts import ComponentCRUD_Add_Delete_Components as test_module
-
- class test_Menus_ViewMenuOptions_Work(EditorSharedTest):
- from .EditorScripts import Menus_ViewMenuOptions as test_module
-
- @pytest.mark.skip(reason="Times out due to dialogs failing to dismiss: LYN-4208")
- class test_Menus_FileMenuOptions_Work(EditorSharedTest):
- from .EditorScripts import Menus_FileMenuOptions as test_module
-
- class test_BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD(EditorSharedTest):
- from .EditorScripts import BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD as test_module
diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py
deleted file mode 100644
index 1bd1d7f987..0000000000
--- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py
+++ /dev/null
@@ -1,60 +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
-"""
-
-import os
-import pytest
-import sys
-
-import ly_test_tools.environment.file_system as file_system
-
-sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared')
-from base import TestAutomationBase
-
-
-@pytest.fixture
-def remove_test_level(request, workspace, project):
- file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", "tmp_level")], True, True)
-
- def teardown():
- file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", "tmp_level")], True, True)
-
- request.addfinalizer(teardown)
-
-
-@pytest.mark.SUITE_periodic
-@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
-@pytest.mark.parametrize("project", ["AutomatedTesting"])
-class TestAutomation(TestAutomationBase):
-
- def test_AssetBrowser_TreeNavigation(self, request, workspace, editor, launcher_platform):
- from .EditorScripts import AssetBrowser_TreeNavigation as test_module
- self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False)
-
- def test_AssetBrowser_SearchFiltering(self, request, workspace, editor, launcher_platform):
- from .EditorScripts import AssetBrowser_SearchFiltering as test_module
- self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False)
-
- def test_AssetPicker_UI_UX(self, request, workspace, editor, launcher_platform):
- from .EditorScripts import AssetPicker_UI_UX as test_module
- self._run_test(request, workspace, editor, test_module, autotest_mode=False, batch_mode=False, enable_prefab_system=False)
-
- def test_ComponentCRUD_Add_Delete_Components(self, request, workspace, editor, launcher_platform):
- from .EditorScripts import ComponentCRUD_Add_Delete_Components as test_module
- self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False)
-
- def test_InputBindings_Add_Remove_Input_Events(self, request, workspace, editor, launcher_platform):
- from .EditorScripts import InputBindings_Add_Remove_Input_Events as test_module
- self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False, enable_prefab_system=False)
-
- def test_Menus_ViewMenuOptions_Work(self, request, workspace, editor, launcher_platform):
- from .EditorScripts import Menus_ViewMenuOptions as test_module
- self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False)
-
- @pytest.mark.skip(reason="Times out due to dialogs failing to dismiss: LYN-4208")
- def test_Menus_FileMenuOptions_Work(self, request, workspace, editor, launcher_platform):
- from .EditorScripts import Menus_FileMenuOptions as test_module
- self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False)
diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox.py
deleted file mode 100644
index 8a56a2dbfd..0000000000
--- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox.py
+++ /dev/null
@@ -1,27 +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
-"""
-
-import os
-import pytest
-import sys
-
-sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared')
-from base import TestAutomationBase
-
-
-@pytest.mark.SUITE_sandbox
-@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
-@pytest.mark.parametrize("project", ["AutomatedTesting"])
-class TestAutomation(TestAutomationBase):
-
- def test_Menus_EditMenuOptions_Work(self, request, workspace, editor, launcher_platform):
- from .EditorScripts import Menus_EditMenuOptions as test_module
- self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False)
-
- def test_Docking_BasicDockedTools(self, request, workspace, editor, launcher_platform):
- from .EditorScripts import Docking_BasicDockedTools as test_module
- self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False)
diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox_Optimized.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox_Optimized.py
deleted file mode 100644
index ce0d5e43e9..0000000000
--- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox_Optimized.py
+++ /dev/null
@@ -1,28 +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
-"""
-
-import os
-import pytest
-
-from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
-
-
-@pytest.mark.SUITE_sandbox
-@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
-@pytest.mark.parametrize("project", ["AutomatedTesting"])
-class TestAutomationAutoTestMode(EditorTestSuite):
-
- # Enable only -autotest_mode for these tests. Tests cannot run in -BatchMode due to UI interactions
- global_extra_cmdline_args = ["-autotest_mode"]
-
- enable_prefab_system = False
-
- class test_Docking_BasicDockedTools(EditorSharedTest):
- from .EditorScripts import Docking_BasicDockedTools as test_module
-
- class test_Menus_EditMenuOptions_Work(EditorSharedTest):
- from .EditorScripts import Menus_EditMenuOptions as test_module
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt
index 5d0808adb6..69d411536f 100644
--- a/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt
@@ -31,19 +31,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
Smoke
)
- ly_add_pytest(
- NAME AutomatedTesting::EditorTestWithGPU
- TEST_REQUIRES gpu
- PATH ${CMAKE_CURRENT_LIST_DIR}/test_Editor_NewExistingLevels_Works.py
- TIMEOUT 100
- RUNTIME_DEPENDENCIES
- AZ::AssetProcessor
- AZ::PythonBindingsExample
- Legacy::Editor
- AutomatedTesting.GameLauncher
- AutomatedTesting.Assets
- )
-
ly_add_pytest(
NAME AutomatedTesting::GameLauncherWithGPU
TEST_SUITE sandbox
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/Editor_NewExistingLevels_Works.py b/AutomatedTesting/Gem/PythonTests/smoke/Editor_NewExistingLevels_Works.py
deleted file mode 100644
index 71956488fc..0000000000
--- a/AutomatedTesting/Gem/PythonTests/smoke/Editor_NewExistingLevels_Works.py
+++ /dev/null
@@ -1,143 +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
-
-
-Test Case Title: Create Test for UI apps- Editor
-"""
-
-
-class Tests():
- level_created = ("Level created", "Failed to create level")
- entity_found = ("New Entity created in level", "Failed to create New Entity in level")
- mesh_added = ("Mesh Component added", "Failed to add Mesh Component")
- enter_game_mode = ("Game Mode successfully entered", "Failed to enter in Game Mode")
- exit_game_mode = ("Game Mode successfully exited", "Failed to exit in Game Mode")
- level_opened = ("Level opened successfully", "Failed to open level")
- level_exported = ("Level exported successfully", "Failed to export level")
- mesh_removed = ("Mesh Component removed", "Failed to remove Mesh Component")
- entity_deleted = ("Entity deleted", "Failed to delete Entity")
- level_edits_present = ("Level edits persist after saving", "Failed to save level edits after saving")
-
-
-def Editor_NewExistingLevels_Works():
- """
- Summary: Perform the below operations on Editor
-
- 1) Launch & Close editor
- 2) Create new level
- 3) Saving and loading levels
- 4) Level edits persist after saving
- 5) Export Level
- 6) Can switch to play mode (ctrl+g) and exit that
- 7) Run editor python bindings test
- 8) Create an Entity
- 9) Delete an Entity
- 10) Add a component to an Entity
-
- Expected Behavior:
- All operations succeed and do not cause a crash
-
- Test Steps:
- 1) Launch editor and Create a new level
- 2) Create a new entity
- 3) Add Mesh component
- 4) Verify enter/exit game mode
- 5) Save, Load and Export level
- 6) Remove Mesh component
- 7) Delete entity
- 8) Open an existing level
- 9) Create a new entity in an existing level
- 10) Save, Load and Export an existing level and close editor
-
- Note:
- - This test file must be called from the O3DE Editor command terminal
- - Any passed and failed tests are written to the Editor.log file.
- Parsing the file or running a log_monitor are required to observe the test results.
-
- :return: None
- """
-
- import os
- import editor_python_test_tools.hydra_editor_utils as hydra
- from editor_python_test_tools.utils import TestHelper as helper
- from editor_python_test_tools.utils import Report
- import azlmbr.bus as bus
- import azlmbr.editor as editor
- import azlmbr.legacy.general as general
- import azlmbr.math as math
-
- # 1) Launch editor and Create a new level
- helper.init_idle()
- test_level_name = "temp_level"
- general.create_level_no_prompt(test_level_name, 128, 1, 128, False)
- helper.wait_for_condition(lambda: general.get_current_level_name() == test_level_name, 2.0)
- Report.result(Tests.level_created, general.get_current_level_name() == test_level_name)
-
- # 2) Create a new entity
- entity_position = math.Vector3(200.0, 200.0, 38.0)
- new_entity = hydra.Entity("Entity1")
- new_entity.create_entity(entity_position, [])
- test_entity = hydra.find_entity_by_name("Entity1")
- Report.result(Tests.entity_found, test_entity.IsValid())
-
- # 3) Add Mesh component
- new_entity.add_component("Mesh")
- Report.result(Tests.mesh_added, hydra.has_components(new_entity.id, ["Mesh"]))
-
- # 4) Verify enter/exit game mode
- helper.enter_game_mode(Tests.enter_game_mode)
- helper.exit_game_mode(Tests.exit_game_mode)
-
- # 5) Save, Load and Export level
- # Save Level
- general.save_level()
- # Open Level
- general.open_level(test_level_name)
- Report.result(Tests.level_opened, general.get_current_level_name() == test_level_name)
- # Export Level
- general.export_to_engine()
- level_pak_file = os.path.join("AutomatedTesting", "Levels", test_level_name, "level.pak")
- Report.result(Tests.level_exported, os.path.exists(level_pak_file))
-
- # 6) Remove Mesh component
- new_entity.remove_component("Mesh")
- Report.result(Tests.mesh_removed, not hydra.has_components(new_entity.id, ["Mesh"]))
-
- # 7) Delete entity
- editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntityById", new_entity.id)
- test_entity = hydra.find_entity_by_name("Entity1")
- Report.result(Tests.entity_deleted, len(test_entity) == 0)
-
- # 8) Open an existing level
- general.open_level(test_level_name)
- Report.result(Tests.level_opened, general.get_current_level_name() == test_level_name)
-
- # 9) Create a new entity in an existing level
- entity_position = math.Vector3(200.0, 200.0, 38.0)
- new_entity_2 = hydra.Entity("Entity2")
- new_entity_2.create_entity(entity_position, [])
- test_entity = hydra.find_entity_by_name("Entity2")
- Report.result(Tests.entity_found, test_entity.IsValid())
-
- # 10) Save, Load and Export an existing level
- # Save Level
- general.save_level()
- # Open Level
- general.open_level(test_level_name)
- Report.result(Tests.level_opened, general.get_current_level_name() == test_level_name)
- entity_id = hydra.find_entity_by_name(new_entity_2.name)
- Report.result(Tests.level_edits_present, entity_id == new_entity_2.id)
- # Export Level
- general.export_to_engine()
- level_pak_file = os.path.join("AutomatedTesting", "Levels", test_level_name, "level.pak")
- Report.result(Tests.level_exported, os.path.exists(level_pak_file))
-
-
-if __name__ == "__main__":
-
- from editor_python_test_tools.utils import Report
-
- Report.start_test(Editor_NewExistingLevels_Works)
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_Editor_NewExistingLevels_Works.py b/AutomatedTesting/Gem/PythonTests/smoke/test_Editor_NewExistingLevels_Works.py
deleted file mode 100644
index 5caf7744c4..0000000000
--- a/AutomatedTesting/Gem/PythonTests/smoke/test_Editor_NewExistingLevels_Works.py
+++ /dev/null
@@ -1,34 +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
-
-
-Test should run in both gpu and non gpu
-"""
-
-import pytest
-import os
-from automatedtesting_shared.base import TestAutomationBase
-
-import ly_test_tools
-import ly_test_tools.environment.file_system as file_system
-
-
-@pytest.mark.SUITE_smoke
-@pytest.mark.skipif(not ly_test_tools.WINDOWS, reason="Only succeeds on windows https://github.com/o3de/o3de/issues/5539")
-@pytest.mark.parametrize("launcher_platform", ["windows_editor"])
-@pytest.mark.parametrize("project", ["AutomatedTesting"])
-@pytest.mark.parametrize("level", ["temp_level"])
-class TestAutomation(TestAutomationBase):
- def test_Editor_NewExistingLevels_Works(self, request, workspace, editor, level, project, launcher_platform):
- def teardown():
- file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
-
- request.addfinalizer(teardown)
- file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
-
- from . import Editor_NewExistingLevels_Works as test_module
-
- self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
diff --git a/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/Environment.xml b/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/Environment.xml
deleted file mode 100644
index 4ba36f66ae..0000000000
--- a/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/Environment.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/TerrainTexture.xml b/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/TerrainTexture.xml
deleted file mode 100644
index f43df05b22..0000000000
--- a/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/TerrainTexture.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/TimeOfDay.xml b/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/TimeOfDay.xml
deleted file mode 100644
index c5b404318e..0000000000
--- a/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/TimeOfDay.xml
+++ /dev/null
@@ -1,356 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/VegetationMap.dat b/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/VegetationMap.dat
deleted file mode 100644
index dce5631cd0..0000000000
--- a/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/VegetationMap.dat
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:0e6a5435c928079b27796f6b202bbc2623e7e454244ddc099a3cadf33b7cb9e9
-size 63
diff --git a/AutomatedTesting/Levels/TestDependenciesLevel/TerrainTexture.pak b/AutomatedTesting/Levels/TestDependenciesLevel/TerrainTexture.pak
deleted file mode 100644
index fe3604a050..0000000000
--- a/AutomatedTesting/Levels/TestDependenciesLevel/TerrainTexture.pak
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:8739c76e681f900923b900c9df0ef75cf421d39cabb54650c4b9ad19b6a76d85
-size 22
diff --git a/AutomatedTesting/Levels/TestDependenciesLevel/TestDependenciesLevel.ly b/AutomatedTesting/Levels/TestDependenciesLevel/TestDependenciesLevel.ly
deleted file mode 100644
index 95cc91cd6b..0000000000
--- a/AutomatedTesting/Levels/TestDependenciesLevel/TestDependenciesLevel.ly
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:825828fe7c183e765315f933a8b1eb25283739d34d62cb84c34e2dcb56591d6e
-size 12415
diff --git a/AutomatedTesting/Levels/TestDependenciesLevel/TestDependenciesLevel.prefab b/AutomatedTesting/Levels/TestDependenciesLevel/TestDependenciesLevel.prefab
new file mode 100644
index 0000000000..cf30cb178c
--- /dev/null
+++ b/AutomatedTesting/Levels/TestDependenciesLevel/TestDependenciesLevel.prefab
@@ -0,0 +1,555 @@
+{
+ "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,
+ "Child Entity Order": [
+ "Entity_[1176639161715]"
+ ]
+ },
+ "Component_[15230859088967841193]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 15230859088967841193,
+ "Parent Entity": ""
+ },
+ "Component_[16239496886950819870]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 16239496886950819870
+ },
+ "Component_[5688118765544765547]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 5688118765544765547
+ },
+ "Component_[6545738857812235305]": {
+ "$type": "SelectionComponent",
+ "Id": 6545738857812235305
+ },
+ "Component_[7247035804068349658]": {
+ "$type": "EditorPrefabComponent",
+ "Id": 7247035804068349658
+ },
+ "Component_[9307224322037797205]": {
+ "$type": "EditorLockComponent",
+ "Id": 9307224322037797205
+ },
+ "Component_[9562516168917670048]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 9562516168917670048
+ }
+ }
+ },
+ "Entities": {
+ "Entity_[1155164325235]": {
+ "Id": "Entity_[1155164325235]",
+ "Name": "Sun",
+ "Components": {
+ "Component_[10440557478882592717]": {
+ "$type": "SelectionComponent",
+ "Id": 10440557478882592717
+ },
+ "Component_[13620450453324765907]": {
+ "$type": "EditorLockComponent",
+ "Id": 13620450453324765907
+ },
+ "Component_[2134313378593666258]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 2134313378593666258
+ },
+ "Component_[234010807770404186]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 234010807770404186
+ },
+ "Component_[2970359110423865725]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 2970359110423865725
+ },
+ "Component_[3722854130373041803]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 3722854130373041803
+ },
+ "Component_[5992533738676323195]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 5992533738676323195
+ },
+ "Component_[7378860763541895402]": {
+ "$type": "AZ::Render::EditorDirectionalLightComponent",
+ "Id": 7378860763541895402,
+ "Controller": {
+ "Configuration": {
+ "Intensity": 1.0,
+ "CameraEntityId": "",
+ "ShadowFilterMethod": 1
+ }
+ }
+ },
+ "Component_[7892834440890947578]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7892834440890947578,
+ "Parent Entity": "Entity_[1176639161715]",
+ "Transform Data": {
+ "Translate": [
+ 0.0,
+ 0.0,
+ 13.487043380737305
+ ],
+ "Rotate": [
+ -76.13099670410156,
+ -0.847000002861023,
+ -15.8100004196167
+ ]
+ }
+ },
+ "Component_[8599729549570828259]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 8599729549570828259
+ },
+ "Component_[952797371922080273]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 952797371922080273
+ }
+ }
+ },
+ "Entity_[1159459292531]": {
+ "Id": "Entity_[1159459292531]",
+ "Name": "Ground",
+ "Components": {
+ "Component_[11701138785793981042]": {
+ "$type": "SelectionComponent",
+ "Id": 11701138785793981042
+ },
+ "Component_[12260880513256986252]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 12260880513256986252
+ },
+ "Component_[13711420870643673468]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 13711420870643673468
+ },
+ "Component_[138002849734991713]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 138002849734991713
+ },
+ "Component_[16578565737331764849]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 16578565737331764849,
+ "Parent Entity": "Entity_[1176639161715]"
+ },
+ "Component_[16919232076966545697]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 16919232076966545697
+ },
+ "Component_[5182430712893438093]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 5182430712893438093
+ },
+ "Component_[5675108321710651991]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 5675108321710651991,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{0CD745C0-6AA8-569A-A68A-73A3270986C4}",
+ "subId": 277889906
+ },
+ "assetHint": "objects/groudplane/groundplane_512x512m.azmodel"
+ }
+ }
+ }
+ },
+ "Component_[5681893399601237518]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 5681893399601237518
+ },
+ "Component_[592692962543397545]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 592692962543397545
+ },
+ "Component_[7090012899106946164]": {
+ "$type": "EditorLockComponent",
+ "Id": 7090012899106946164
+ },
+ "Component_[9410832619875640998]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 9410832619875640998
+ }
+ }
+ },
+ "Entity_[1163754259827]": {
+ "Id": "Entity_[1163754259827]",
+ "Name": "Camera",
+ "Components": {
+ "Component_[11895140916889160460]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 11895140916889160460
+ },
+ "Component_[16880285896855930892]": {
+ "$type": "{CA11DA46-29FF-4083-B5F6-E02C3A8C3A3D} EditorCameraComponent",
+ "Id": 16880285896855930892,
+ "Controller": {
+ "Configuration": {
+ "Field of View": 55.0,
+ "EditorEntityId": 3342481886060234850
+ }
+ }
+ },
+ "Component_[17187464423780271193]": {
+ "$type": "EditorLockComponent",
+ "Id": 17187464423780271193
+ },
+ "Component_[17495696818315413311]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 17495696818315413311
+ },
+ "Component_[18086214374043522055]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 18086214374043522055,
+ "Parent Entity": "Entity_[1176639161715]",
+ "Transform Data": {
+ "Translate": [
+ -2.3000001907348633,
+ -3.9368600845336914,
+ 1.0
+ ],
+ "Rotate": [
+ -2.050307512283325,
+ 1.9552897214889526,
+ -43.623355865478516
+ ]
+ }
+ },
+ "Component_[18387556550380114975]": {
+ "$type": "SelectionComponent",
+ "Id": 18387556550380114975
+ },
+ "Component_[2654521436129313160]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 2654521436129313160
+ },
+ "Component_[5265045084611556958]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 5265045084611556958
+ },
+ "Component_[7169798125182238623]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 7169798125182238623
+ },
+ "Component_[7255796294953281766]": {
+ "$type": "GenericComponentWrapper",
+ "Id": 7255796294953281766,
+ "m_template": {
+ "$type": "FlyCameraInputComponent"
+ }
+ },
+ "Component_[8866210352157164042]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 8866210352157164042
+ },
+ "Component_[9129253381063760879]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 9129253381063760879
+ }
+ }
+ },
+ "Entity_[1168049227123]": {
+ "Id": "Entity_[1168049227123]",
+ "Name": "Grid",
+ "Components": {
+ "Component_[11443347433215807130]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 11443347433215807130
+ },
+ "Component_[11779275529534764488]": {
+ "$type": "SelectionComponent",
+ "Id": 11779275529534764488
+ },
+ "Component_[14249419413039427459]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 14249419413039427459
+ },
+ "Component_[15448581635946161318]": {
+ "$type": "AZ::Render::EditorGridComponent",
+ "Id": 15448581635946161318,
+ "Controller": {
+ "Configuration": {
+ "primarySpacing": 4.0,
+ "primaryColor": [
+ 0.501960813999176,
+ 0.501960813999176,
+ 0.501960813999176
+ ],
+ "secondarySpacing": 0.5,
+ "secondaryColor": [
+ 0.250980406999588,
+ 0.250980406999588,
+ 0.250980406999588
+ ]
+ }
+ }
+ },
+ "Component_[1843303322527297409]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 1843303322527297409
+ },
+ "Component_[380249072065273654]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 380249072065273654,
+ "Parent Entity": "Entity_[1176639161715]"
+ },
+ "Component_[7476660583684339787]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 7476660583684339787
+ },
+ "Component_[7557626501215118375]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 7557626501215118375
+ },
+ "Component_[7984048488947365511]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 7984048488947365511
+ },
+ "Component_[8118181039276487398]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 8118181039276487398
+ },
+ "Component_[9189909764215270515]": {
+ "$type": "EditorLockComponent",
+ "Id": 9189909764215270515
+ }
+ }
+ },
+ "Entity_[1172344194419]": {
+ "Id": "Entity_[1172344194419]",
+ "Name": "Shader Ball",
+ "Components": {
+ "Component_[10789351944715265527]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 10789351944715265527
+ },
+ "Component_[12037033284781049225]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 12037033284781049225
+ },
+ "Component_[13759153306105970079]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13759153306105970079
+ },
+ "Component_[14135560884830586279]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 14135560884830586279
+ },
+ "Component_[16247165675903986673]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 16247165675903986673
+ },
+ "Component_[18082433625958885247]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 18082433625958885247
+ },
+ "Component_[6472623349872972660]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 6472623349872972660,
+ "Parent Entity": "Entity_[1176639161715]",
+ "Transform Data": {
+ "Rotate": [
+ 0.0,
+ 0.10000000149011612,
+ 180.0
+ ]
+ }
+ },
+ "Component_[6495255223970673916]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 6495255223970673916,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{FD340C30-755C-5911-92A3-19A3F7A77931}",
+ "subId": 281415304
+ },
+ "assetHint": "objects/shaderball/shaderball_default_1m.azmodel"
+ }
+ }
+ }
+ },
+ "Component_[8056625192494070973]": {
+ "$type": "SelectionComponent",
+ "Id": 8056625192494070973
+ },
+ "Component_[8550141614185782969]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 8550141614185782969
+ },
+ "Component_[9439770997198325425]": {
+ "$type": "EditorLockComponent",
+ "Id": 9439770997198325425
+ }
+ }
+ },
+ "Entity_[1176639161715]": {
+ "Id": "Entity_[1176639161715]",
+ "Name": "Atom Default Environment",
+ "Components": {
+ "Component_[10757302973393310045]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 10757302973393310045,
+ "Parent Entity": "Entity_[1146574390643]"
+ },
+ "Component_[14505817420424255464]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 14505817420424255464,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 10757302973393310045
+ }
+ ]
+ },
+ "Component_[14988041764659020032]": {
+ "$type": "EditorLockComponent",
+ "Id": 14988041764659020032
+ },
+ "Component_[15808690248755038124]": {
+ "$type": "SelectionComponent",
+ "Id": 15808690248755038124
+ },
+ "Component_[15900837685796817138]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 15900837685796817138
+ },
+ "Component_[3298767348226484884]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 3298767348226484884
+ },
+ "Component_[4076975109609220594]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 4076975109609220594
+ },
+ "Component_[5679760548946028854]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 5679760548946028854
+ },
+ "Component_[5855590796136709437]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 5855590796136709437,
+ "Child Entity Order": [
+ "Entity_[1155164325235]",
+ "Entity_[1180934129011]",
+ "Entity_[1172344194419]",
+ "Entity_[1168049227123]",
+ "Entity_[1163754259827]",
+ "Entity_[1159459292531]"
+ ]
+ },
+ "Component_[9277695270015777859]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 9277695270015777859
+ }
+ }
+ },
+ "Entity_[1180934129011]": {
+ "Id": "Entity_[1180934129011]",
+ "Name": "Global Sky",
+ "Components": {
+ "Component_[11231930600558681245]": {
+ "$type": "AZ::Render::EditorHDRiSkyboxComponent",
+ "Id": 11231930600558681245,
+ "Controller": {
+ "Configuration": {
+ "CubemapAsset": {
+ "assetId": {
+ "guid": "{215E47FD-D181-5832-B1AB-91673ABF6399}",
+ "subId": 1000
+ },
+ "assetHint": "lightingpresets/highcontrast/goegap_4k_skyboxcm.exr.streamingimage"
+ }
+ }
+ }
+ },
+ "Component_[11980494120202836095]": {
+ "$type": "SelectionComponent",
+ "Id": 11980494120202836095
+ },
+ "Component_[1428633914413949476]": {
+ "$type": "EditorLockComponent",
+ "Id": 1428633914413949476
+ },
+ "Component_[14936200426671614999]": {
+ "$type": "AZ::Render::EditorImageBasedLightComponent",
+ "Id": 14936200426671614999,
+ "Controller": {
+ "Configuration": {
+ "diffuseImageAsset": {
+ "assetId": {
+ "guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}",
+ "subId": 3000
+ },
+ "assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_ibldiffuse.exr.streamingimage"
+ },
+ "specularImageAsset": {
+ "assetId": {
+ "guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}",
+ "subId": 2000
+ },
+ "assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_iblspecular.exr.streamingimage"
+ }
+ }
+ }
+ },
+ "Component_[14994774102579326069]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 14994774102579326069
+ },
+ "Component_[15417479889044493340]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 15417479889044493340
+ },
+ "Component_[15826613364991382688]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 15826613364991382688
+ },
+ "Component_[1665003113283562343]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 1665003113283562343
+ },
+ "Component_[3704934735944502280]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 3704934735944502280
+ },
+ "Component_[5698542331457326479]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 5698542331457326479
+ },
+ "Component_[6644513399057217122]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 6644513399057217122,
+ "Parent Entity": "Entity_[1176639161715]"
+ },
+ "Component_[931091830724002070]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 931091830724002070
+ }
+ }
+ }
+ },
+ "Instances": {
+ "Instance_[425258647110]": {
+ "Source": "assets/simple_pot_fbx.procprefab"
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Levels/TestDependenciesLevel/filelist.xml b/AutomatedTesting/Levels/TestDependenciesLevel/filelist.xml
deleted file mode 100644
index b5164a4aee..0000000000
--- a/AutomatedTesting/Levels/TestDependenciesLevel/filelist.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff --git a/AutomatedTesting/Levels/TestDependenciesLevel/level.pak b/AutomatedTesting/Levels/TestDependenciesLevel/level.pak
deleted file mode 100644
index dfba7fb4e3..0000000000
--- a/AutomatedTesting/Levels/TestDependenciesLevel/level.pak
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:2611b691998640a0e802461f47b5b876f6832fbece62d34cc25da53e135e1c38
-size 44525
diff --git a/Code/Editor/CryEdit.cpp b/Code/Editor/CryEdit.cpp
index 77099761c1..1c4e22b99e 100644
--- a/Code/Editor/CryEdit.cpp
+++ b/Code/Editor/CryEdit.cpp
@@ -1352,8 +1352,27 @@ void CCryEditApp::CompileCriticalAssets() const
}
}
assetsInQueueNotifcation.BusDisconnect();
- CCryEditApp::OutputStartupMessage(QString("Asset Processor is now ready."));
+ // Signal the "CriticalAssetsCompiled" lifecycle event
+ // Also reload the "assetcatalog.xml" if it exists
+ if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
+ {
+ AZ::ComponentApplicationLifecycle::SignalEvent(*settingsRegistry, "CriticalAssetsCompiled", R"({})");
+ // Reload the assetcatalog.xml at this point again
+ // Start Monitoring Asset changes over the network and load the AssetCatalog
+ auto LoadCatalog = [settingsRegistry](AZ::Data::AssetCatalogRequests* assetCatalogRequests)
+ {
+ if (AZ::IO::FixedMaxPath assetCatalogPath;
+ settingsRegistry->Get(assetCatalogPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_CacheRootFolder))
+ {
+ assetCatalogPath /= "assetcatalog.xml";
+ assetCatalogRequests->LoadCatalog(assetCatalogPath.c_str());
+ }
+ };
+ AZ::Data::AssetCatalogRequestBus::Broadcast(AZStd::move(LoadCatalog));
+ }
+
+ CCryEditApp::OutputStartupMessage(QString("Asset Processor is now ready."));
}
bool CCryEditApp::ConnectToAssetProcessor() const
@@ -1669,7 +1688,7 @@ bool CCryEditApp::InitInstance()
return false;
}
- if (AZ::SettingsRegistryInterface* settingsRegistry = AZ::SettingsRegistry::Get())
+ if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
{
AZ::ComponentApplicationLifecycle::SignalEvent(*settingsRegistry, "LegacySystemInterfaceCreated", R"({})");
}
diff --git a/Code/Editor/EditorViewportWidget.cpp b/Code/Editor/EditorViewportWidget.cpp
index 754ea84544..828812fb7e 100644
--- a/Code/Editor/EditorViewportWidget.cpp
+++ b/Code/Editor/EditorViewportWidget.cpp
@@ -454,9 +454,6 @@ void EditorViewportWidget::Update()
// Render
{
- // TODO: Move out this logic to a controller and refactor to work with Atom
- ProcessRenderLisneters(m_displayContext);
-
m_displayContext.Flush2D();
// Post Render Callback
diff --git a/Code/Editor/IEditor.h b/Code/Editor/IEditor.h
index c91ca62c5e..90f1b63f55 100644
--- a/Code/Editor/IEditor.h
+++ b/Code/Editor/IEditor.h
@@ -52,7 +52,6 @@ class CUIEnumsDatabase;
struct ISourceControl;
struct IEditorClassFactory;
struct ITransformManipulator;
-class IFacialEditor;
class CDialog;
#if defined(AZ_PLATFORM_WINDOWS)
class C3DConnexionDriver;
diff --git a/Code/Editor/Include/IConsoleConnectivity.h b/Code/Editor/Include/IConsoleConnectivity.h
deleted file mode 100644
index 0f5e9bf35c..0000000000
--- a/Code/Editor/Include/IConsoleConnectivity.h
+++ /dev/null
@@ -1,85 +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 : Standard interface for console connectivity plugins.
-
-
-#ifndef CRYINCLUDE_EDITOR_INCLUDE_ICONSOLECONNECTIVITY_H
-#define CRYINCLUDE_EDITOR_INCLUDE_ICONSOLECONNECTIVITY_H
-#pragma once
-
-
-//////////////////////////////////////////////////////////////////////////
-// Description
-// This interface provide access to the console connectivity
-// functionality.
-//////////////////////////////////////////////////////////////////////////
-struct IConsoleConnectivity
- : public IUnknown
-{
- DEFINE_UUID(0x4DAA85E1, 0x8498, 0x402f, 0x9B, 0x85, 0x7F, 0x62, 0x9D, 0x76, 0x79, 0x8A);
-
- //////////////////////////////////////////////////////////////////////////
- //TODO: Must add the useful interface here.
- //////////////////////////////////////////////////////////////////////////
-
- // Description:
- // Checks if a development console is connected to the development PC.
- // See Also:
- // Arguments:
- // Nothing
- // Return:
- // bool - true if it is connected, false otherwise.
- virtual bool IsConnectedToConsole() = 0;
-
- // Description:
- // Send a file from the specified local filename to the console platform creating the full path
- // as required so it can copy to the remote filename.
- // See Also:
- // Nothing
- // Arguments:
- // szLocalFileName - is the local filename from which you want to copy the file.
- // szRemoteFilename - is the full path and filename to where you want to copy the file.
- // Return:
- // bool - true if the copy succeeded, false otherwise.
- virtual bool SendFile(const char* szLocalFileName, const char* szRemoteFilename) = 0;
-
- // Description:
- // Notifies to the console that a file has been changed, typically uploaded.
- // This will be usually called after a SendFile (see above) call, so that the
- // system running on the console may decide what to do with this new file.
- // Typically the system will have to load or reloads this new file.
- // See Also:
- // SendFile
- // Arguments:
- // szRemoteFilename - is the full path and filename in the console of the changed
- // file.
- // Return:
- // bool - true if succeeded sending the notification, false otherwise.
- virtual bool NotifyFileChange(const char* szRemoteFilename) = 0;
-
-
- // Description:
- // Gets the the title IP for the connected console .
- // Arguments:
- // dwConsoleAddressPlaceholder - is the pointer to the placeholder of the variable
- // which will contain the title IP of the console.
- // Return:
- // bool - true if dwConsoleAddressPlaceholder now contains the IP address, else false.
- virtual bool GetConsoleAddress(DWORD* dwConsoleAddressPlaceholder) = 0;
- //////////////////////////////////////////////////////////////////////////
- // IUnknown
- //////////////////////////////////////////////////////////////////////////
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) { return E_NOINTERFACE; };
- virtual ULONG STDMETHODCALLTYPE AddRef() { return 0; };
- virtual ULONG STDMETHODCALLTYPE Release() { return 0; };
- //////////////////////////////////////////////////////////////////////////
-};
-
-#endif // CRYINCLUDE_EDITOR_INCLUDE_ICONSOLECONNECTIVITY_H
diff --git a/Code/Editor/Include/IFacialEditor.h b/Code/Editor/Include/IFacialEditor.h
deleted file mode 100644
index 5dfa9ab03f..0000000000
--- a/Code/Editor/Include/IFacialEditor.h
+++ /dev/null
@@ -1,43 +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_INCLUDE_IFACIALEDITOR_H
-#define CRYINCLUDE_EDITOR_INCLUDE_IFACIALEDITOR_H
-#pragma once
-
-
-class IFacialEditor
-{
-public:
- enum EyeType
- {
- EYE_LEFT,
- EYE_RIGHT
- };
-
- virtual int GetNumMorphTargets() const = 0;
- virtual const char* GetMorphTargetName(int index) const = 0;
- virtual void PreviewEffector(int index, float value) = 0;
- virtual void ClearAllPreviewEffectors() = 0;
- virtual void SetForcedNeckRotation(const Quat& rotation) = 0;
- virtual void SetForcedEyeRotation(const Quat& rotation, EyeType eye) = 0;
- virtual int GetJoystickCount() const = 0;
- virtual const char* GetJoystickName(int joystickIndex) const = 0;
- virtual void SetJoystickPosition(int joystickIndex, float x, float y) = 0;
- virtual void GetJoystickPosition(int joystickIndex, float& x, float& y) const = 0;
- virtual void LoadJoystickFile(const char* filename) = 0;
- virtual void LoadCharacter(const char* filename) = 0;
- virtual void LoadSequence(const char* filename) = 0;
- virtual void SetVideoFrameResolution(int width, int height, int bpp) = 0;
- virtual int GetVideoFramePitch() = 0;
- virtual void* GetVideoFrameBits() = 0;
- virtual void ShowVideoFramePane() = 0;
-};
-
-#endif // CRYINCLUDE_EDITOR_INCLUDE_IFACIALEDITOR_H
diff --git a/Code/Editor/Include/IRenderListener.h b/Code/Editor/Include/IRenderListener.h
deleted file mode 100644
index 892a42b701..0000000000
--- a/Code/Editor/Include/IRenderListener.h
+++ /dev/null
@@ -1,29 +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 : Interface for rendering custom 3D elements in the main
-// render viewport. Particularly usefull for debug geometries.
-
-
-#ifndef CRYINCLUDE_EDITOR_INCLUDE_IRENDERLISTENER_H
-#define CRYINCLUDE_EDITOR_INCLUDE_IRENDERLISTENER_H
-#pragma once
-
-
-struct DisplayContext;
-
-struct IRenderListener
- : public IUnknown
-{
- DEFINE_UUID(0x8D52F857, 0x1027, 0x4346, 0xAC, 0x7B, 0xF6, 0x20, 0xDA, 0x7C, 0xCE, 0x42)
-
- virtual void Render(DisplayContext& rDisplayContext) = 0;
-};
-
-#endif // CRYINCLUDE_EDITOR_INCLUDE_IRENDERLISTENER_H
diff --git a/Code/Editor/Include/ITextureDatabaseUpdater.h b/Code/Editor/Include/ITextureDatabaseUpdater.h
deleted file mode 100644
index 4482135b47..0000000000
--- a/Code/Editor/Include/ITextureDatabaseUpdater.h
+++ /dev/null
@@ -1,38 +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 : This file declares the interface used by the texture viewer
-// and (implemented first implemented by the Texture Database Creator) to
-// syncronize their threads. A thread interace could be useful there.
-
-#ifndef CRYINCLUDE_EDITOR_INCLUDE_ITEXTUREDATABASEUPDATER_H
-#define CRYINCLUDE_EDITOR_INCLUDE_ITEXTUREDATABASEUPDATER_H
-#pragma once
-
-
-class CTextureDatabaseItem;
-
-struct ITextureDatabaseUpdater
-{
-public:
- //////////////////////////////////////////////////////////////////////////
- // Thread control
- virtual void NotifyShutDown() = 0;
- virtual void Lock() = 0;
- virtual void Unlock() = 0;
- virtual void WaitForThread() = 0;
- //////////////////////////////////////////////////////////////////////////
-
- //////////////////////////////////////////////////////////////////////////
- // Data access
- virtual CTextureDatabaseItem* GetItem(const char* szAddItem) = 0;
- //////////////////////////////////////////////////////////////////////////
-};
-
-#endif // CRYINCLUDE_EDITOR_INCLUDE_ITEXTUREDATABASEUPDATER_H
diff --git a/Code/Editor/MainWindow.qrc b/Code/Editor/MainWindow.qrc
index 4506a4a2a8..c68e05ef41 100644
--- a/Code/Editor/MainWindow.qrc
+++ b/Code/Editor/MainWindow.qrc
@@ -166,7 +166,6 @@
arhitype_tree_01.png
arhitype_tree_02.png
arhitype_tree_03.png
- water.png
bmp00005_00.png
bmp00005_01.png
bmp00005_02.png
diff --git a/Code/Editor/Resource.h b/Code/Editor/Resource.h
index 432f07a531..ef72bfc9be 100644
--- a/Code/Editor/Resource.h
+++ b/Code/Editor/Resource.h
@@ -196,7 +196,6 @@
#define ID_FILE_EXPORT_TERRAINAREA 33904
#define ID_FILE_EXPORT_TERRAINAREAWITHOBJECTS 33910
#define ID_FILE_EXPORT_SELECTEDOBJECTS 33911
-#define ID_TERRAIN_TIMEOFDAY 33912
#define ID_SPLINE_PREVIOUS_KEY 33916
#define ID_SPLINE_NEXT_KEY 33917
#define ID_SPLINE_FLATTEN_ALL 33918
@@ -290,7 +289,6 @@
#define ID_TV_TRACKS_TOOLBAR_LAST 35183 // for up to 100 "Add Tracks..." dynamically added Track View Track buttons
#define ID_OPEN_TERRAIN_EDITOR 36007
#define ID_OPEN_UICANVASEDITOR 36010
-#define ID_TERRAIN_TIMEOFDAYBUTTON 36011
#define ID_OPEN_TERRAINTEXTURE_EDITOR 36012
#define ID_SKINS_REFRESH 36014
#define ID_FILE_GENERATETERRAIN 36016
diff --git a/Code/Editor/TimeOfDay/main-00.png b/Code/Editor/TimeOfDay/main-00.png
deleted file mode 100644
index 2c44fec541..0000000000
--- a/Code/Editor/TimeOfDay/main-00.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:5201dbba6c8114914ed680b04b72a5e18e22c0519a514bcccdc7ae8d32670b4e
-size 993
diff --git a/Code/Editor/TimeOfDay/main-01.png b/Code/Editor/TimeOfDay/main-01.png
deleted file mode 100644
index 5cc1bf33d8..0000000000
--- a/Code/Editor/TimeOfDay/main-01.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:48a7250ad41c5e298079ddd13910b58baca2ef592defcc162ccc9df542d28905
-size 981
diff --git a/Code/Editor/TimeOfDay/main-02.png b/Code/Editor/TimeOfDay/main-02.png
deleted file mode 100644
index b7d90648a3..0000000000
--- a/Code/Editor/TimeOfDay/main-02.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:98b9e9abcc54b4f3e6903ad74bb50f364bfe4c8cd9fedc9653a6603d64a1ee0a
-size 838
diff --git a/Code/Editor/TimeOfDay/main-03.png b/Code/Editor/TimeOfDay/main-03.png
deleted file mode 100644
index e073dbf60b..0000000000
--- a/Code/Editor/TimeOfDay/main-03.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:1199c834fc8de69f9d7c76e8c7fbd84e9b92713b9f07b513137085e5089432cb
-size 857
diff --git a/Code/Editor/TimeOfDay/main-04.png b/Code/Editor/TimeOfDay/main-04.png
deleted file mode 100644
index 6049dbfe18..0000000000
--- a/Code/Editor/TimeOfDay/main-04.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:79b44be1dbe5518e06dc8c8823d00462136d39ffe60a32ef4f64dc0712654d33
-size 646
diff --git a/Code/Editor/TimeOfDay/main-05.png b/Code/Editor/TimeOfDay/main-05.png
deleted file mode 100644
index 054419f39a..0000000000
--- a/Code/Editor/TimeOfDay/main-05.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:6ea7450c1a278570e2a1dba3a8b4d7d4e5f0d054e8371139ebdb5220c405d355
-size 537
diff --git a/Code/Editor/TimeOfDay/main-06.png b/Code/Editor/TimeOfDay/main-06.png
deleted file mode 100644
index 35f8afdae2..0000000000
--- a/Code/Editor/TimeOfDay/main-06.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:bc73f0720f2ff877aff5c6646938b7fc509a69d92e766fecb9fa010eecadee7b
-size 606
diff --git a/Code/Editor/TimeOfDay/main-07.png b/Code/Editor/TimeOfDay/main-07.png
deleted file mode 100644
index aca9597355..0000000000
--- a/Code/Editor/TimeOfDay/main-07.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:e63519ed54fc19a4b4a2a38cb2c5f148b7404ac614d4aab039b71fee64cd7425
-size 569
diff --git a/Code/Editor/TimeOfDay/main-08.png b/Code/Editor/TimeOfDay/main-08.png
deleted file mode 100644
index abeb114fc2..0000000000
--- a/Code/Editor/TimeOfDay/main-08.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:8742cad4b8f8f5bba59abb9cc028db84de222ed8b393398f6837fea16bb4a1d8
-size 563
diff --git a/Code/Editor/TimeOfDay/main-09.png b/Code/Editor/TimeOfDay/main-09.png
deleted file mode 100644
index cc77b8c9e2..0000000000
--- a/Code/Editor/TimeOfDay/main-09.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:ef85628301b4edc4f858f0988e4f072772be3feb92d27a2ec33b72a27bcee7ff
-size 583
diff --git a/Code/Editor/TimeOfDay/main-10.png b/Code/Editor/TimeOfDay/main-10.png
deleted file mode 100644
index dc463c6497..0000000000
--- a/Code/Editor/TimeOfDay/main-10.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:d17bfbdee6d37566b241adf64241ef47b62145aaac3e9e8f9691d1fb866b5fcb
-size 717
diff --git a/Code/Editor/TimeOfDay/main-11.png b/Code/Editor/TimeOfDay/main-11.png
deleted file mode 100644
index d686ab18c8..0000000000
--- a/Code/Editor/TimeOfDay/main-11.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:98b629abf927bcea41d8857b1761d12a37836471d7106b2f5210337c0ace0d9c
-size 1103
diff --git a/Code/Editor/TimeOfDay/main-12.png b/Code/Editor/TimeOfDay/main-12.png
deleted file mode 100644
index 069510ab24..0000000000
--- a/Code/Editor/TimeOfDay/main-12.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:e949111b33e28834995807cab30ecb58d988a81a2d58fa166117962c85b8e149
-size 849
diff --git a/Code/Editor/Viewport.cpp b/Code/Editor/Viewport.cpp
index 437dcead3b..dcf86abb02 100644
--- a/Code/Editor/Viewport.cpp
+++ b/Code/Editor/Viewport.cpp
@@ -30,7 +30,6 @@
#include "Objects/ObjectManager.h"
#include "Util/3DConnexionDriver.h"
#include "PluginManager.h"
-#include "Include/IRenderListener.h"
#include "GameEngine.h"
#include "Settings.h"
@@ -227,61 +226,6 @@ void QtViewport::GetDimensions(int* pWidth, int* pHeight) const
}
}
-//////////////////////////////////////////////////////////////////////////
-void QtViewport::RegisterRenderListener(IRenderListener* piListener)
-{
-#ifdef _DEBUG
- size_t nCount(0);
- size_t nTotal(0);
-
- nTotal = m_cRenderListeners.size();
- for (nCount = 0; nCount < nTotal; ++nCount)
- {
- if (m_cRenderListeners[nCount] == piListener)
- {
- assert(!"Registered the same RenderListener multiple times.");
- break;
- }
- }
-#endif //_DEBUG
- m_cRenderListeners.push_back(piListener);
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool QtViewport::UnregisterRenderListener(IRenderListener* piListener)
-{
- size_t nCount(0);
- size_t nTotal(0);
-
- nTotal = m_cRenderListeners.size();
- for (nCount = 0; nCount < nTotal; ++nCount)
- {
- if (m_cRenderListeners[nCount] == piListener)
- {
- m_cRenderListeners.erase(m_cRenderListeners.begin() + nCount);
- return true;
- }
- }
- return false;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool QtViewport::IsRenderListenerRegistered(IRenderListener* piListener)
-{
- size_t nCount(0);
- size_t nTotal(0);
-
- nTotal = m_cRenderListeners.size();
- for (nCount = 0; nCount < nTotal; ++nCount)
- {
- if (m_cRenderListeners[nCount] == piListener)
- {
- return true;
- }
- }
- return false;
-}
-
//////////////////////////////////////////////////////////////////////////
void QtViewport::AddPostRenderer(IPostRenderer* pPostRenderer)
{
@@ -1164,18 +1108,6 @@ bool QtViewport::GetAdvancedSelectModeFlag()
return m_bAdvancedSelectMode;
}
-//////////////////////////////////////////////////////////////////////////
-void QtViewport::ProcessRenderLisneters(DisplayContext& rstDisplayContext)
-{
- size_t nCount(0);
- size_t nTotal(0);
-
- nTotal = m_cRenderListeners.size();
- for (nCount = 0; nCount < nTotal; ++nCount)
- {
- m_cRenderListeners[nCount]->Render(rstDisplayContext);
- }
-}
//////////////////////////////////////////////////////////////////////////
#if defined(AZ_PLATFORM_WINDOWS)
// Note: Both CreateAnglesYPR and CreateOrientationYPR were copied verbatim from Cry_Camera.h which has been removed.
diff --git a/Code/Editor/Viewport.h b/Code/Editor/Viewport.h
index 1b0e5a4d93..d992eb4cb0 100644
--- a/Code/Editor/Viewport.h
+++ b/Code/Editor/Viewport.h
@@ -43,7 +43,6 @@ class CLayoutViewPane;
class CViewManager;
class CBaseObjectsCache;
struct HitContext;
-struct IRenderListener;
class CImageEx;
class QMenu;
@@ -104,10 +103,6 @@ public:
//! Access to view manager.
CViewManager* GetViewManager() const { return m_viewManager; };
- virtual void RegisterRenderListener(IRenderListener* piListener) = 0;
- virtual bool UnregisterRenderListener(IRenderListener* piListener) = 0;
- virtual bool IsRenderListenerRegistered(IRenderListener* piListener) = 0;
-
virtual void AddPostRenderer(IPostRenderer* pPostRenderer) = 0;
virtual bool RemovePostRenderer(IPostRenderer* pPostRenderer) = 0;
@@ -477,10 +472,6 @@ public:
void ResetCursor() override;
void SetSupplementaryCursorStr(const QString& str) override;
- void RegisterRenderListener(IRenderListener* piListener) override;
- bool UnregisterRenderListener(IRenderListener* piListener) override;
- bool IsRenderListenerRegistered(IRenderListener* piListener) override;
-
void AddPostRenderer(IPostRenderer* pPostRenderer) override;
bool RemovePostRenderer(IPostRenderer* pPostRenderer) override;
@@ -508,8 +499,6 @@ protected:
void setRenderOverlayVisible(bool);
bool isRenderOverlayVisible() const;
- void ProcessRenderLisneters(DisplayContext& rstDisplayContext);
-
void mousePressEvent(QMouseEvent* event) override;
void mouseReleaseEvent(QMouseEvent* event) override;
void mouseDoubleClickEvent(QMouseEvent* event) override;
@@ -597,8 +586,6 @@ protected:
// Same construction matrix is shared by all viewports.
Matrix34 m_constructionMatrix[LAST_COORD_SYSTEM];
- std::vector m_cRenderListeners;
-
typedef std::vector<_smart_ptr > PostRenderers;
PostRenderers m_postRenderers;
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
diff --git a/Code/Editor/editor_lib_files.cmake b/Code/Editor/editor_lib_files.cmake
index 59a1a91647..345a8e15e1 100644
--- a/Code/Editor/editor_lib_files.cmake
+++ b/Code/Editor/editor_lib_files.cmake
@@ -270,7 +270,6 @@ set(FILES
Include/Command.h
Include/HitContext.h
Include/ICommandManager.h
- Include/IConsoleConnectivity.h
Include/IDisplayViewport.h
Include/IEditorClassFactory.h
Include/IEventLoopHook.h
@@ -282,9 +281,7 @@ set(FILES
Include/IObjectManager.h
Include/IPlugin.h
Include/IPreferencesPage.h
- Include/IRenderListener.h
Include/ISourceControl.h
- Include/ITextureDatabaseUpdater.h
Include/ITransformManipulator.h
Include/IViewPane.h
Include/ObjectEvent.h
diff --git a/Code/Editor/water.png b/Code/Editor/water.png
deleted file mode 100644
index 342dee81e3..0000000000
--- a/Code/Editor/water.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:4abde33fa9c29e927e403e275979536e7defbb6476eb375e85f847396645953f
-size 41419
diff --git a/Code/Framework/AzCore/AzCore/PlatformDef.h b/Code/Framework/AzCore/AzCore/PlatformDef.h
index 8d28d27959..7f00f7e90e 100644
--- a/Code/Framework/AzCore/AzCore/PlatformDef.h
+++ b/Code/Framework/AzCore/AzCore/PlatformDef.h
@@ -149,3 +149,79 @@
#if !defined(AZ_COMMAND_LINE_LEN)
# define AZ_COMMAND_LINE_LEN 2048
#endif
+
+#include
+#include
+#include
+#include
+#include
+
+// First check if the feature if is_constant_evaluated is available via the feature test macro
+// https://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros#C.2B.2B20
+#if __cpp_lib_is_constant_evaluated
+ #define az_builtin_is_constant_evaluated() std::is_constant_evaluated()
+#endif
+
+// Next check if there is a __builtin_is_constant_evaluated that can be used
+// This works on MSVC 19.28+ toolsets when using C++17, as well as
+// clang 9.0.0+ when using C++17.
+// Finally it works on gcc 9.0+ when using C++17
+#if !defined(az_builtin_is_constant_evaluated)
+ #if defined(__has_builtin)
+ #if __has_builtin(__builtin_is_constant_evaluated)
+ #define az_builtin_is_constant_evaluated() __builtin_is_constant_evaluated()
+ #define az_has_builtin_is_constant_evaluated() true
+ #endif
+ #elif AZ_COMPILER_MSVC >= 1928
+ #define az_builtin_is_constant_evaluated() __builtin_is_constant_evaluated()
+ #define az_has_builtin_is_constant_evaluated() true
+ #elif AZ_COMPILER_GCC
+ #define az_builtin_is_constant_evaluated() __builtin_is_constant_evaluated()
+ #define az_has_builtin_is_constant_evaluated() true
+ #endif
+#endif
+
+// In this case no support for the determining whether an operation is occuring
+// at compile time is supported so assume that evaluation is always occuring at compile time
+// in order to make sure the "safe" operation is being performed
+#if !defined(az_builtin_is_constant_evaluated)
+ namespace AZ::Internal
+ {
+ constexpr bool builtin_is_constant_evaluated()
+ {
+ return true;
+ }
+ }
+ #define az_builtin_is_constant_evaluated() AZ::Internal::builtin_is_constant_evaluated()
+ #define az_has_builtin_is_constant_evaluated() false
+#endif
+
+// define builtin functions used by char_traits class for efficient compile time and runtime
+// operations
+#if defined(__has_builtin)
+ #if __has_builtin(__builtin_memcpy)
+ #define az_has_builtin_memcpy true
+ #endif
+ #if __has_builtin(__builtin_wmemcpy)
+ #define az_has_builtin_wmemcpy true
+ #endif
+ #if __has_builtin(__builtin_memmove)
+ #define az_has_builtin_memmove true
+ #endif
+ #if __has_builtin(__builtin_wmemmove)
+ #define az_has_builtin_wmemmove true
+ #endif
+#endif
+
+#if !defined(az_has_builtin_memcpy)
+ #define az_has_builtin_memcpy false
+#endif
+#if !defined(az_has_builtin_wmemcpy)
+ #define az_has_builtin_wmemcpy false
+#endif
+#if !defined(az_has_builtin_memmove)
+ #define az_has_builtin_memmove false
+#endif
+#if !defined(az_has_builtin_wmemmove)
+ #define az_has_builtin_wmemmove false
+#endif
diff --git a/Code/Framework/AzCore/AzCore/std/allocator_stateless.cpp b/Code/Framework/AzCore/AzCore/std/allocator_stateless.cpp
index 5806cc485c..baf650a560 100644
--- a/Code/Framework/AzCore/AzCore/std/allocator_stateless.cpp
+++ b/Code/Framework/AzCore/AzCore/std/allocator_stateless.cpp
@@ -11,17 +11,17 @@
namespace AZStd
{
- stateless_allocator::stateless_allocator(const char* name)
- : m_name(name) {}
+ stateless_allocator::stateless_allocator() = default;
+ stateless_allocator::stateless_allocator(const char*)
+ {}
const char* stateless_allocator::get_name() const
{
- return m_name;
+ return "AZStd::stateless_allocator";
}
- void stateless_allocator::set_name(const char* name)
+ void stateless_allocator::set_name(const char*)
{
- m_name = name;
}
auto stateless_allocator::allocate(size_type byteSize) -> pointer_type
diff --git a/Code/Framework/AzCore/AzCore/std/allocator_stateless.h b/Code/Framework/AzCore/AzCore/std/allocator_stateless.h
index b73c680c32..6b78aca53d 100644
--- a/Code/Framework/AzCore/AzCore/std/allocator_stateless.h
+++ b/Code/Framework/AzCore/AzCore/std/allocator_stateless.h
@@ -26,7 +26,8 @@ namespace AZStd
using difference_type = ptrdiff_t;
using allow_memory_leaks = AZStd::true_type;
- stateless_allocator(const char* name = "AZStd::stateless_allocator");
+ stateless_allocator();
+ explicit stateless_allocator(const char*); // Stateless allocator does not store a name
stateless_allocator(const stateless_allocator& rhs) = default;
stateless_allocator& operator=(const stateless_allocator& rhs) = default;
@@ -51,9 +52,6 @@ namespace AZStd
bool is_lock_free();
bool is_stale_read_allowed();
bool is_delayed_recycling();
-
- private:
- const char* m_name;
};
bool operator==(const stateless_allocator& left, const stateless_allocator& right);
diff --git a/Code/Framework/AzCore/AzCore/std/containers/compressed_pair.h b/Code/Framework/AzCore/AzCore/std/containers/compressed_pair.h
index 066ec7be5e..c79ddf11ee 100644
--- a/Code/Framework/AzCore/AzCore/std/containers/compressed_pair.h
+++ b/Code/Framework/AzCore/AzCore/std/containers/compressed_pair.h
@@ -8,6 +8,7 @@
#pragma once
#include
+#include
#include
/* Microsoft C++ ABI puts 1 byte of padding between each empty base class when multiple inheritance is being used
@@ -20,7 +21,7 @@
#if defined(AZ_COMPILER_MSVC)
#define AZSTD_COMPRESSED_PAIR_EMPTY_BASE_OPTIMIZATION __declspec(empty_bases)
#else
-#define AZSTD_COMPRESSED_PAIR_EMPTY_BASE_OPTIMIZATION
+#define AZSTD_COMPRESSED_PAIR_EMPTY_BASE_OPTIMIZATION
#endif
namespace AZStd
@@ -97,16 +98,14 @@ namespace AZStd
using second_base_value_type = typename second_base_type::value_type;
public:
- // First template argument is a placeholder argument of void as MSVC examines the types
- // of a templated function to determine if they are the same template
- // Due to the "template compressed_pair(skip_element_tag, T&&)"
- // constructor below, the default constructor template types needs to be distinguished from it
- template ::value
- && AZStd::is_default_constructible::value>>
+ // First template argument is used to perform a substitution into AZStd::enable_if_t
+ // so that SFINAE can trigger
+ template
+ && AZStd::is_default_constructible_v, Unused>>
constexpr compressed_pair();
- template , compressed_pair>::value, bool> = true>
+ template , compressed_pair>, bool> = true>
constexpr explicit compressed_pair(T&& firstElement);
template
diff --git a/Code/Framework/AzCore/AzCore/std/containers/compressed_pair.inl b/Code/Framework/AzCore/AzCore/std/containers/compressed_pair.inl
index 9fb5eb87fb..8e585a1467 100644
--- a/Code/Framework/AzCore/AzCore/std/containers/compressed_pair.inl
+++ b/Code/Framework/AzCore/AzCore/std/containers/compressed_pair.inl
@@ -75,7 +75,7 @@ namespace AZStd
}
template
- template , compressed_pair>::value, bool>>
+ template , compressed_pair>, bool>>
inline constexpr compressed_pair::compressed_pair(T&& firstElement)
: first_base_type{ AZStd::forward(firstElement) }
, second_base_type{}
@@ -117,7 +117,7 @@ namespace AZStd
{
return static_cast(*this).get();
}
-
+
template
inline constexpr auto compressed_pair::second() -> second_base_value_type&
{
diff --git a/Code/Framework/AzCore/AzCore/std/string/fixed_string.h b/Code/Framework/AzCore/AzCore/std/string/fixed_string.h
index a8e0f96988..ea841bc4ca 100644
--- a/Code/Framework/AzCore/AzCore/std/string/fixed_string.h
+++ b/Code/Framework/AzCore/AzCore/std/string/fixed_string.h
@@ -343,26 +343,6 @@ namespace AZStd
static decltype(auto) format(const wchar_t* format, ...);
protected:
- template
- constexpr auto append_iter(InputIt first, InputIt last)
- -> enable_if_t && !is_convertible_v, basic_fixed_string&>;
-
- template
- constexpr auto construct_iter(InputIt first, InputIt last)
- -> enable_if_t && !is_convertible_v>;
-
- template
- constexpr auto assign_iter(InputIt first, InputIt last)
- -> enable_if_t && !is_convertible_v, basic_fixed_string&>;
-
- template
- constexpr auto insert_iter(const_iterator insertPos, InputIt first, InputIt last)
- -> enable_if_t && !is_convertible_v, iterator>;
-
- template
- constexpr auto replace_iter(const_iterator first, const_iterator last, InputIt first2, InputIt last2)
- -> enable_if_t && !is_convertible_v, basic_fixed_string&>;
-
constexpr auto fits_in_capacity(size_type newSize) -> bool;
inline static constexpr size_type Capacity = MaxElementCount; // current storage reserved for string not including null-terminator
diff --git a/Code/Framework/AzCore/AzCore/std/string/fixed_string.inl b/Code/Framework/AzCore/AzCore/std/string/fixed_string.inl
index 8b973d3b2c..15d2acf7a1 100644
--- a/Code/Framework/AzCore/AzCore/std/string/fixed_string.inl
+++ b/Code/Framework/AzCore/AzCore/std/string/fixed_string.inl
@@ -62,14 +62,7 @@ namespace AZStd
template
inline constexpr basic_fixed_string::basic_fixed_string(InputIt first, InputIt last)
{ // construct from [first, last)
- if (first == last)
- {
- Traits::assign(m_buffer[0], Element()); // terminate
- }
- else
- {
- construct_iter(first, last);
- }
+ assign(first, last);
}
// #7
@@ -98,8 +91,7 @@ namespace AZStd
template
inline constexpr basic_fixed_string::basic_fixed_string(const T& convertibleToView)
{
- AZStd::basic_string_view view = convertibleToView;
- assign(view.begin(), view.end());
+ assign(convertibleToView);
}
// #11
@@ -313,15 +305,7 @@ namespace AZStd
if (count > 0 && fits_in_capacity(num))
{
pointer data = m_buffer;
- // make room and append new stuff using assign
- if (count == 1)
- {
- Traits::assign(*(data + m_size), ch);
- }
- else
- {
- Traits::assign(data + m_size, count, ch);
- }
+ Traits::assign(data + m_size, count, ch);
m_size = static_cast(num);
Traits::assign(data[num], Element()); // terminate
}
@@ -332,13 +316,47 @@ namespace AZStd
template
inline constexpr auto basic_fixed_string::append(InputIt first, InputIt last)
-> enable_if_t && !is_convertible_v, basic_fixed_string&>
- { // append [first, last)
- return append_iter(first, last);
+ {
+ if constexpr (Internal::satisfies_contiguous_iterator_concept_v
+ && is_same_v::value_type, value_type>)
+ {
+ return append(AZStd::to_address(first), AZStd::distance(first, last));
+ }
+ else if constexpr (Internal::is_forward_iterator_v)
+ {
+ // Input Iterator pointer type doesn't match the const_pointer type
+ // So the elements need to be appended one by one into the buffer
+ size_type newSize = m_size + AZStd::distance(first, last);
+ if (fits_in_capacity(newSize))
+ {
+ for (size_t updateIndex = m_size; first != last; ++first, ++updateIndex)
+ {
+ Traits::assign(m_buffer[updateIndex], static_cast(*first));
+ }
+ m_size = static_cast(newSize);
+ Traits::assign(m_buffer[newSize], Element()); // terminate
+ }
+ return *this;
+ }
+ else
+ {
+ // input iterator that aren't forward iterators can only be used in a single pass
+ // algorithm. Therefore AZStd::distance can't be used
+ // So the input is copied into a local string and then delegated
+ // to use the (const_pointer, size_type) overload
+ basic_fixed_string inputCopy;
+ for (; first != last; ++first)
+ {
+ inputCopy.push_back(static_cast(*first));
+ }
+
+ return append(inputCopy.c_str(), inputCopy.size());
+ }
}
template
inline constexpr auto basic_fixed_string::append(AZStd::initializer_list ilist) -> basic_fixed_string&
- { // append [first, last)
- return append_iter(ilist.begin(), ilist.end());
+ {
+ return append(ilist.begin(), ilist.size());
}
template
@@ -420,18 +438,10 @@ namespace AZStd
inline constexpr auto basic_fixed_string::assign(size_type count, Element ch) -> basic_fixed_string&
{
// assign count * ch
- AZSTD_CONTAINER_ASSERT(count != npos, "result is too long!");
if (fits_in_capacity(count))
{ // make room and assign new stuff
pointer data = m_buffer;
- if (count == 1)
- {
- Traits::assign(*(data), ch);
- }
- else
- {
- Traits::assign(data, count, ch);
- }
+ Traits::assign(data, count, ch);
m_size = static_cast(count);
Traits::assign(data[count], Element()); // terminate
}
@@ -443,12 +453,46 @@ namespace AZStd
inline constexpr auto basic_fixed_string::assign(InputIt first, InputIt last)
-> enable_if_t && !is_convertible_v, basic_fixed_string&>
{
- return assign_iter(first, last);
+ if constexpr (Internal::satisfies_contiguous_iterator_concept_v
+ && is_same_v::value_type, value_type>)
+ {
+ return assign(AZStd::to_address(first), AZStd::distance(first, last));
+ }
+ else if constexpr (Internal::is_forward_iterator_v)
+ {
+ // Input Iterator pointer type doesn't match the const_pointer type
+ // So the elements need to be assigned one by one into the buffer
+ size_type newSize = AZStd::distance(first, last);
+ if (fits_in_capacity(newSize))
+ {
+ for (size_t updateIndex = 0; first != last; ++first, ++updateIndex)
+ {
+ Traits::assign(m_buffer[updateIndex], static_cast(*first));
+ }
+ m_size = static_cast(newSize);
+ Traits::assign(m_buffer[newSize], Element()); // terminate
+ }
+ return *this;
+ }
+ else
+ {
+ // input iterator that aren't forward iterators can only be used in a single pass
+ // algorithm. Therefore AZStd::distance can't be used
+ // So the input is copied into a local string and then delegated
+ // to use the (const_pointer, size_type) overload
+ basic_fixed_string inputCopy;
+ for (; first != last; ++first)
+ {
+ inputCopy.push_back(static_cast(*first));
+ }
+
+ return assign(inputCopy.c_str(), inputCopy.size());
+ }
}
template
inline constexpr auto basic_fixed_string::assign(AZStd::initializer_list ilist) -> basic_fixed_string&
{
- return assign_iter(ilist.begin(), ilist.end());
+ return assign(ilist.begin(), ilist.size());
}
template
@@ -536,14 +580,7 @@ namespace AZStd
pointer data = m_buffer;
// make room and insert new stuff
Traits::copy_backward(data + offset + count, data + offset, m_size - offset); // empty out hole
- if (count == 1)
- {
- Traits::assign(*(data + offset), ch);
- }
- else
- {
- Traits::assign(data + offset, count, ch);
- }
+ Traits::assign(data + offset, count, ch);
m_size = static_cast(num);
Traits::assign(data[num], Element()); // terminate
}
@@ -582,14 +619,51 @@ namespace AZStd
inline constexpr auto basic_fixed_string::insert(const_iterator insertPos,
InputIt first, InputIt last)-> enable_if_t && !is_convertible_v, iterator>
{ // insert [_First, _Last) at _Where
- return insert_iter(insertPos, first, last);
+ size_type insertOffset = AZStd::distance(cbegin(), insertPos);
+ if constexpr (Internal::satisfies_contiguous_iterator_concept_v
+ && is_same_v::value_type, value_type>)
+ {
+ insert(insertOffset, AZStd::to_address(first), AZStd::distance(first, last));
+ }
+ else if constexpr (Internal::is_forward_iterator_v)
+ {
+ // Input Iterator pointer type doesn't match the const_pointer type
+ // So the elements need to be inserted one by one into the buffer
+ size_type count = AZStd::distance(first, last);
+ size_type newSize = m_size + count;
+ if (fits_in_capacity(newSize))
+ {
+ Traits::copy_backward(m_buffer + insertOffset + count, m_buffer + insertOffset, m_size - insertOffset); // empty out hole
+ for (size_t updateIndex = insertOffset; first != last; ++first, ++updateIndex)
+ {
+ Traits::assign(m_buffer[updateIndex], static_cast(*first));
+ }
+ m_size = static_cast(newSize);
+ Traits::assign(m_buffer[newSize], Element()); // terminate
+ }
+ }
+ else
+ {
+ // input iterator that aren't forward iterators can only be used in a single pass
+ // algorithm. Therefore AZStd::distance can't be used
+ // So the input is copied into a local string and then delegated
+ // to use the (const_pointer, size_type) overload
+ basic_fixed_string inputCopy;
+ for (; first != last; ++first)
+ {
+ inputCopy.push_back(static_cast(*first));
+ }
+
+ insert(insertOffset, inputCopy.c_str(), inputCopy.size());
+ }
+ return begin() + insertOffset;
}
template
inline constexpr auto basic_fixed_string::insert(const_iterator insertPos,
AZStd::initializer_list ilist) -> iterator
{ // insert [_First, _Last) at _Where
- return insert_iter(insertPos, ilist.begin(), ilist.end());
+ return insert(insertPos, ilist.begin(), ilist.end());
}
template
@@ -604,7 +678,7 @@ namespace AZStd
{
// move elements down
pointer data = m_buffer;
- Traits::copy(data + offset, data + offset + count, m_size - offset - count);
+ Traits::move(data + offset, data + offset + count, m_size - offset - count);
m_size = static_cast(m_size - count);
Traits::assign(data[m_size], Element()); // terminate
}
@@ -643,7 +717,7 @@ namespace AZStd
const basic_fixed_string& rhs) -> basic_fixed_string&
{
// replace [offset, offset + count) with rhs
- return replace(offset, count, rhs, size_type(0), npos);
+ return replace(offset, count, rhs.c_str(), rhs.size());
}
template
@@ -651,56 +725,7 @@ namespace AZStd
const basic_fixed_string& rhs, size_type rhsOffset, size_type rhsCount) -> basic_fixed_string&
{
// replace [offset, offset + count) with rhs [rhsOffset, rhsOffset + rhsCount)
- AZSTD_CONTAINER_ASSERT(m_size >= offset && rhs.m_size >= rhsOffset, "Invalid offsets");
- if (m_size - offset < count)
- {
- count = m_size - offset; // trim count to size
- }
- size_type num = rhs.m_size - rhsOffset;
- if (num < rhsCount)
- {
- rhsCount = num; // trim rhsCount to size
- }
- AZSTD_CONTAINER_ASSERT(npos - rhsCount > m_size - count, "Result is too long");
-
- size_type nm = m_size - count - offset; // length of preserved tail
- size_type newSize = m_size + rhsCount - count;
- if (fits_in_capacity(newSize))
- {
- pointer data = m_buffer;
- const_pointer rhsData = rhs.m_buffer;
-
- if (this != &rhs)
- { // no overlap, just move down and copy in new stuff
- Traits::copy_backward(data + offset + rhsCount, data + offset + count, nm); // empty hole
- Traits::copy(data + offset, rhsData + rhsOffset, rhsCount); // fill hole
- }
- else if (rhsCount <= count)
- { // hole doesn't get larger, just copy in substring
- Traits::copy(data + offset, data + rhsOffset, rhsCount); // fill hole
- Traits::copy_backward(data + offset + rhsCount, data + offset + count, nm); // move tail down
- }
- else if (rhsOffset <= offset)
- { // hole gets larger, substring begins before hole
- Traits::copy_backward(data + offset + rhsCount, data + offset + count, nm); // move tail down
- Traits::copy(data + offset, data + rhsOffset, rhsCount); // fill hole
- }
- else if (offset + count <= rhsOffset)
- { // hole gets larger, substring begins after hole
- Traits::copy_backward(data + offset + rhsCount, data + offset + count, nm); // move tail down
- Traits::copy(data + offset, data + (rhsOffset + rhsCount - count), rhsCount); // fill hole
- }
- else
- { // hole gets larger, substring begins in hole
- Traits::copy(data + offset, data + rhsOffset, count); // fill old hole
- Traits::copy_backward(data + offset + rhsCount, data + offset + count, nm); // move tail down
- Traits::copy(data + offset + count, data + rhsOffset + rhsCount, rhsCount - count); // fill rest of new hole
- }
-
- m_size = static_cast(newSize);
- Traits::assign(data[newSize], Element()); // terminate
- }
- return *this;
+ return replace(offset, count, rhs.c_str() + rhsOffset, AZStd::min(rhsCount, rhs.size() - rhsOffset));
}
template
template
@@ -720,35 +745,83 @@ namespace AZStd
pointer data = m_buffer;
// replace [offset, offset + count) with [ptr, ptr + ptrCount)
AZSTD_CONTAINER_ASSERT(m_size >= offset, "Invalid offset");
- if (m_size - offset < count)
- {
- count = m_size - offset; // trim _N0 to size
- }
- AZSTD_CONTAINER_ASSERT(npos - ptrCount > m_size - count, "Result too long");
+ // Make sure count is within is no larger than the distance from the offset
+ // to the end of this string
+ count = AZStd::min(count, m_size - offset);
- size_type nm = m_size - count - offset;
- if (ptrCount < count)
+ size_type newSize = m_size + ptrCount - count;
+ if (fits_in_capacity(newSize))
{
- Traits::copy(data + offset + ptrCount, data + offset + count, nm); // smaller hole, move tail up
- }
- size_type num = m_size + ptrCount - count;
- if ((0 != ptrCount || 0 != count) && fits_in_capacity(num))
- {
- data = m_buffer;
- // make room and rearrange
- if (count < ptrCount)
+ // The code assumes that compile time evaluation will not need to deal with overlapping input
+ size_type charsAfterCountToMove = m_size - count - offset;
+ if (az_builtin_is_constant_evaluated() || !((ptr >= data + offset && ptr < data + offset + count)
+ || (ptr + ptrCount > data + offset && ptr + ptrCount <= data + offset + count)))
{
- Traits::copy_backward(data + offset + ptrCount, data + offset + count, nm); // move tail down
+ // Ex1. this = "ABCDEFG", offset = 1, count = 4
+ // Input string is "CDE"
+ // First the text post offset + count is moved to right after the input string will be copied
+ // "ABCDFG"
+ // ^^^
+ // Next the input string is copied into the buffer
+ // "ACDEFG"
+ //
+ // Ex2. this = "ABCDEFG", offset = 1, count = 2
+ // Input string is "CDE"
+ // Performing the same two steps above, the string transform as follows
+ // "ABCDEFG" -> "ABCDDEFG" -> "ACDEDEFG"
+ // ^^^
+ if (count != ptrCount)
+ {
+ Traits::move(data + offset + ptrCount, data + offset + count, charsAfterCountToMove);
+ }
+ if (ptrCount > 0)
+ {
+ // Copy bytes up to the minimum of this string count and input string count
+ Traits::copy(data + offset, ptr, ptrCount);
+ }
}
-
- if (ptrCount > 0)
+ else
{
- Traits::copy(data + offset, ptr, ptrCount); // fill hole
+ // Overlap checks for fixed_string only needs to check between this string
+ // [offset, offset + count) due to fixed_string never moving memory
+ //
+ // Ex. this = "ABCDEFG", offset = 1, count=4
+ // substring is "CDE"
+ // The text from offset 1 for 4 chars "BCDE": should be replaced with "CDE"
+ // making a whole for the bytes results in output = "ABCDFG"
+ // Afterwards output = "ACDEFG"
+ // The input string overlaps with this string in this case
+ // So the string is copied piecewise
+ if (ptrCount <= count)
+ { // hole doesn't get larger, just copy in substring
+ Traits::move(data + offset, ptr, ptrCount); // fill hole
+ Traits::copy(data + offset + ptrCount, data + offset + count, charsAfterCountToMove); // move tail down
+ }
+ else
+ {
+ if (ptr <= data + offset)
+ { // hole gets larger, substring begins before hole
+ Traits::copy_backward(data + offset + ptrCount, data + offset + count, charsAfterCountToMove); // move tail down
+ Traits::copy(data + offset, ptr, ptrCount); // fill hole
+ }
+ else if (data + offset + count <= ptr)
+ { // hole gets larger, substring begins after hole
+ Traits::copy_backward(data + offset + ptrCount, data + offset + count, charsAfterCountToMove); // move tail down
+ Traits::copy(data + offset, ptr + (ptrCount - count), ptrCount); // fill hole
+ }
+ else
+ { // hole gets larger, substring begins in hole
+ Traits::copy(data + offset, ptr, count); // fill old hole
+ Traits::copy_backward(data + offset + ptrCount, data + offset + count, charsAfterCountToMove); // move tail down
+ Traits::copy(data + offset + count, ptr + ptrCount, ptrCount - count); // fill rest of new hole
+ }
+ }
}
-
- m_size = static_cast(num);
- Traits::assign(data[num], Element()); // terminate
}
+
+ m_size = static_cast(newSize);
+ Traits::assign(data[newSize], Element()); // terminate
+
return *this;
}
@@ -793,14 +866,7 @@ namespace AZStd
{
Traits::copy_backward(data + offset + num, data + offset + count, nm); // move tail down
}
- if (count == 1)
- {
- Traits::assign(*(data + offset), ch);
- }
- else
- {
- Traits::assign(data + offset, num, ch);
- }
+ Traits::assign(data + offset, num, ch);
m_size = static_cast(numToGrow);
Traits::assign(data[numToGrow], Element()); // terminate
}
@@ -851,15 +917,54 @@ namespace AZStd
template
template
inline constexpr auto basic_fixed_string::replace(const_iterator first, const_iterator last,
- InputIt first2, InputIt last2) -> enable_if_t && !is_convertible_v, basic_fixed_string&>
- { // replace [first, last) with [first2,last2)
- return replace_iter(first, last, first2, last2);
+ InputIt replaceFirst, InputIt replaceLast) -> enable_if_t && !is_convertible_v, basic_fixed_string&>
+ { // replace [first, last) with [replaceFirst,replaceLast)
+ if constexpr (Internal::satisfies_contiguous_iterator_concept_v
+ && is_same_v::value_type, value_type>)
+ {
+ return replace(first, last, AZStd::to_address(replaceFirst), AZStd::distance(replaceFirst, replaceLast));
+ }
+ else if constexpr (Internal::is_forward_iterator_v)
+ {
+ // Input Iterator pointer type doesn't match the const_pointer type
+ // So the elements need to be appended one by one into the buffer
+
+ size_type insertOffset = AZStd::distance(cbegin(), first);
+ size_type postInsertOffset = AZStd::distance(cbegin(), last);
+ size_type count = AZStd::distance(replaceFirst, replaceLast);
+ size_type newSize = m_size + count - AZStd::distance(first, last);
+ if (fits_in_capacity(newSize))
+ {
+ Traits::move(first + count, last, m_size - postInsertOffset); // empty out hole
+ for (size_t updateIndex = insertOffset; replaceFirst != replaceLast; ++replaceFirst, ++updateIndex)
+ {
+ Traits::assign(m_buffer[updateIndex], static_cast(*replaceFirst));
+ }
+ m_size = static_cast(newSize);
+ Traits::assign(m_buffer[newSize], Element()); // terminate
+ }
+ return *this;
+ }
+ else
+ {
+ // input iterator that aren't forward iterators can only be used in a single pass
+ // algorithm. Therefore AZStd::distance can't be used
+ // So the input is copied into a local string and then delegated
+ // to use the (const_pointer, size_type) overload
+ basic_fixed_string inputCopy;
+ for (; replaceFirst != replaceLast; ++replaceFirst)
+ {
+ inputCopy.push_back(static_cast(*replaceFirst));
+ }
+
+ return replace(first, last, inputCopy.c_str(), inputCopy.size());
+ }
}
template
inline constexpr auto basic_fixed_string::replace(const_iterator first, const_iterator last,
AZStd::initializer_list ilist) -> basic_fixed_string&
- { // replace [first, last) with [first2,last2)
- return replace_iter(first, last, ilist.begin(), ilist.end());
+ {
+ return replace(first, last, ilist.begin(), ilist.end());
}
template
@@ -1411,54 +1516,6 @@ namespace AZStd
return result;
}
- template
- template
- inline constexpr auto basic_fixed_string::construct_iter(InputIt first, InputIt last)
- -> enable_if_t && !is_convertible_v>
- {
- // initialize from [first, last), input iterators
- for (; first != last; ++first)
- {
- append((size_type)1, (Element)* first);
- }
- }
-
- template
- template
- inline constexpr auto basic_fixed_string::append_iter(InputIt first, InputIt last)
- -> enable_if_t && !is_convertible_v, basic_fixed_string&>
- { // append [first, last), input iterators
- return replace(end(), end(), first, last);
- }
-
- template
- template
- inline constexpr auto basic_fixed_string::assign_iter(InputIt first, InputIt last)
- -> enable_if_t && !is_convertible_v, basic_fixed_string&>
- {
- return replace(begin(), end(), first, last);
- }
-
- template
- template
- inline constexpr auto basic_fixed_string::insert_iter(const_iterator insertPos, InputIt first,
- InputIt last) -> enable_if_t && !is_convertible_v, iterator>
- { // insert [first, last) at insertPos, input iterators
- difference_type offset = insertPos - cbegin();
- replace(insertPos, insertPos, first, last);
- return iterator(m_buffer + offset);
- }
-
- template
- template
- inline constexpr auto basic_fixed_string::replace_iter(const_iterator first, const_iterator last,
- InputIt first2, InputIt last2) -> enable_if_t && !is_convertible_v, basic_fixed_string&>
- { // replace [first, last) with [first2, last2), input iterators
- basic_fixed_string rhs(first2, last2);
- replace(first, last, rhs);
- return *this;
- }
-
template
inline constexpr auto basic_fixed_string::fits_in_capacity(size_type newSize)-> bool
{
diff --git a/Code/Framework/AzCore/AzCore/std/string/string.h b/Code/Framework/AzCore/AzCore/std/string/string.h
index e107c4657d..7dd6dd7065 100644
--- a/Code/Framework/AzCore/AzCore/std/string/string.h
+++ b/Code/Framework/AzCore/AzCore/std/string/string.h
@@ -5,24 +5,43 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
-#ifndef AZSTD_STRING_H
-#define AZSTD_STRING_H
+#pragma once
#include
#include
#include
#include
+#include
#include
#include
#include
#include
#include
-#include
#include
#include
+namespace AZStd::StringInternal
+{
+ template
+ struct Padding
+ {
+ AZ::u8 m_padding[ElementSize - 1];
+ };
+
+ template
+ struct Padding
+ {};
+}
+
+#if defined(HAVE_BENCHMARK)
+namespace Benchmark
+{
+ class StringBenchmarkFixture;
+}
+#endif
+
namespace AZStd
{
/**
@@ -35,130 +54,95 @@ namespace AZStd
: public Debug::checked_container_base
#endif
{
- typedef basic_string this_type;
+ using this_type = basic_string;
public:
- typedef Element* pointer;
- typedef const Element* const_pointer;
+ using pointer = Element*;
+ using const_pointer = const Element*;
- typedef Element& reference;
- typedef const Element& const_reference;
- typedef typename Allocator::difference_type difference_type;
- typedef typename Allocator::size_type size_type;
+ using reference = Element&;
+ using const_reference = const Element&;
+ using difference_type = typename Allocator::difference_type;
+ using size_type = typename Allocator::size_type;
- typedef pointer iterator_impl;
- typedef const_pointer const_iterator_impl;
+ using iterator_impl = pointer;
+ using const_iterator_impl = const_pointer;
#ifdef AZSTD_HAS_CHECKED_ITERATORS
- typedef Debug::checked_randomaccess_iterator iterator;
- typedef Debug::checked_randomaccess_iterator const_iterator;
+ using iterator = Debug::checked_randomaccess_iterator;
+ using const_iterator = Debug::checked_randomaccess_iterator;
#else
- typedef iterator_impl iterator;
- typedef const_iterator_impl const_iterator;
+ using iterator = iterator_impl;
+ using const_iterator = const_iterator_impl;
#endif
- typedef AZStd::reverse_iterator reverse_iterator;
- typedef AZStd::reverse_iterator const_reverse_iterator;
- typedef Element value_type;
- typedef Traits traits_type;
- typedef Allocator allocator_type;
+ using reverse_iterator = AZStd::reverse_iterator;
+ using const_reverse_iterator = AZStd::reverse_iterator;
+ using value_type = Element;
+ using traits_type = Traits;
+ using allocator_type = Allocator;
// AZSTD extension.
/**
* \brief Allocation node type. Common for all AZStd containers.
* In vectors case we allocate always "sizeof(node_type)*capacity" block.
*/
- typedef value_type node_type;
+ using node_type = value_type;
- static const size_type npos = size_type(-1);
+ inline static constexpr size_type npos = size_type(-1);
inline basic_string(const Allocator& alloc = Allocator())
- : m_size(0)
- , m_capacity(SSO_BUF_SIZE - 1)
- , m_allocator(alloc)
+ : m_storage{ skip_element_tag{}, alloc }
{
- Traits::assign(m_buffer[0], Element());
+ Traits::assign(m_storage.first().GetData()[0], Element());
}
inline basic_string(const_pointer ptr, size_type count, const Allocator& alloc = Allocator())
- : m_size(0)
- , m_capacity(SSO_BUF_SIZE - 1)
- , m_allocator(alloc)
+ : m_storage{ skip_element_tag{}, alloc }
{ // construct from [ptr, ptr + count)
assign(ptr, count);
}
inline basic_string(const_pointer ptr, const Allocator& alloc = Allocator())
- : m_size(0)
- , m_capacity(SSO_BUF_SIZE - 1)
- , m_allocator(alloc)
+ : m_storage{ skip_element_tag{}, alloc }
{ // construct from [ptr, )
assign(ptr);
}
inline basic_string(size_type count, Element ch, const Allocator& alloc = Allocator())
- : m_size(0)
- , m_capacity(SSO_BUF_SIZE - 1)
- , m_allocator(alloc)
+ : m_storage{ skip_element_tag{}, alloc }
{ // construct from count * ch
assign(count, ch);
}
- template
- inline basic_string(InputIterator first, InputIterator last, const Allocator& alloc = Allocator())
- : m_size(0)
- , m_capacity(SSO_BUF_SIZE - 1)
- , m_allocator(alloc)
+ template && !is_convertible_v>>
+ inline basic_string(InputIt first, InputIt last, const Allocator& alloc = Allocator())
+ : m_storage{ skip_element_tag{}, alloc }
{ // construct from [first, last)
- if (first == last)
- {
- Traits::assign(m_buffer[0], Element()); // terminate
- }
- else
- {
- construct_iter(first, last, is_integral());
- }
+ assign(first, last);
}
inline basic_string(const_pointer first, const_pointer last)
- : m_size(0)
- , m_capacity(SSO_BUF_SIZE - 1)
{ // construct from [first, last), const pointers
- assign(&*first, last - first);
+ assign(first, last - first);
}
- //inline basic_string(const_iterator _First, const_iterator _Last)
- // : m_size(0)
- // , m_capacity(SSO_BUF_SIZE-1)
- //{ // construct from [_First, _Last), const_iterators
- // if (first != last)
- // assign(&*first, last - first);
- //}
-
inline basic_string(const this_type& rhs)
- : m_size(0)
- , m_capacity(SSO_BUF_SIZE - 1)
- , m_allocator(rhs.m_allocator)
+ : m_storage{ skip_element_tag{}, rhs.m_storage.second() }
{
assign(rhs, 0, npos);
}
inline basic_string(this_type&& rhs)
- : m_size(0)
- , m_capacity(SSO_BUF_SIZE - 1)
- , m_allocator(AZStd::move(rhs.m_allocator))
+ : m_storage{ skip_element_tag{}, AZStd::move(rhs.m_storage.second()) }
{
assign(AZStd::forward(rhs));
}
inline basic_string(const this_type& rhs, size_type rhsOffset, size_type count = npos)
- : m_size(0)
- , m_capacity(SSO_BUF_SIZE - 1)
{ // construct from rhs [rhsOffset, rhsOffset + count)
assign(rhs, rhsOffset, count);
}
inline basic_string(const this_type& rhs, size_type rhsOffset, size_type count, const Allocator& alloc)
- : m_size(0)
- , m_capacity(SSO_BUF_SIZE - 1)
- , m_allocator(alloc)
+ : m_storage{ skip_element_tag{}, alloc }
{ // construct from rhs [rhsOffset, rhsOffset + count) with allocator
assign(rhs, rhsOffset, count);
}
@@ -174,7 +158,7 @@ namespace AZStd
inline ~basic_string()
{
// destroy the string
- deallocate_memory(m_data, 0, typename allocator_type::allow_memory_leaks());
+ deallocate_memory(m_storage.first().GetData(), 0, typename allocator_type::allow_memory_leaks());
}
operator AZStd::basic_string_view() const
@@ -182,12 +166,12 @@ namespace AZStd
return AZStd::basic_string_view(data(), size());
}
- inline iterator begin() { return iterator(AZSTD_CHECKED_ITERATOR(iterator_impl, SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer)); }
- inline const_iterator begin() const { return const_iterator(AZSTD_CHECKED_ITERATOR(const_iterator_impl, SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer)); }
- inline const_iterator cbegin() const { return const_iterator(AZSTD_CHECKED_ITERATOR(const_iterator_impl, SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer)); }
- inline iterator end() { return iterator(AZSTD_CHECKED_ITERATOR(iterator_impl, (SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer) + m_size)); }
- inline const_iterator end() const { return const_iterator(AZSTD_CHECKED_ITERATOR(const_iterator_impl, (SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer) + m_size)); }
- inline const_iterator cend() const { return const_iterator(AZSTD_CHECKED_ITERATOR(const_iterator_impl, (SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer) + m_size)); }
+ inline iterator begin() { return iterator(AZSTD_CHECKED_ITERATOR(iterator_impl, m_storage.first().GetData())); }
+ inline const_iterator begin() const { return const_iterator(AZSTD_CHECKED_ITERATOR(const_iterator_impl, m_storage.first().GetData())); }
+ inline const_iterator cbegin() const { return const_iterator(AZSTD_CHECKED_ITERATOR(const_iterator_impl, m_storage.first().GetData())); }
+ inline iterator end() { return iterator(AZSTD_CHECKED_ITERATOR(iterator_impl, (m_storage.first().GetData()) + m_storage.first().GetSize())); }
+ inline const_iterator end() const { return const_iterator(AZSTD_CHECKED_ITERATOR(const_iterator_impl, (m_storage.first().GetData()) + m_storage.first().GetSize())); }
+ inline const_iterator cend() const { return const_iterator(AZSTD_CHECKED_ITERATOR(const_iterator_impl, (m_storage.first().GetData()) + m_storage.first().GetSize())); }
inline reverse_iterator rbegin() { return reverse_iterator(end()); }
inline const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
inline const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); }
@@ -196,7 +180,7 @@ namespace AZStd
inline const_reverse_iterator crend() const { return const_reverse_iterator(begin()); }
inline this_type& operator=(const this_type& rhs) { return assign(rhs); }
- inline this_type& operator=(this_type&& rhs) { return assign(AZStd::forward(rhs)); }
+ inline this_type& operator=(this_type&& rhs) { return assign(AZStd::move(rhs)); }
inline this_type& operator=(AZStd::basic_string_view view) { return assign(view); }
inline this_type& operator=(const_pointer ptr) { return assign(ptr); }
inline this_type& operator=(Element ch) { return assign(1, ch); }
@@ -208,21 +192,18 @@ namespace AZStd
this_type& append(const this_type& rhs, size_type rhsOffset, size_type count)
{ // append rhs [rhsOffset, rhsOffset + count)
AZSTD_CONTAINER_ASSERT(rhs.size() >= rhsOffset, "Invalid offset!");
- size_type num = rhs.m_size - rhsOffset;
- if (num < count)
+ count = AZStd::min(count, rhs.size() - rhsOffset);
+
+ size_type oldSize = size();
+ size_type newSize = oldSize + count;
+ if (count > 0 && grow(newSize))
{
- count = num; // trim count to size
- }
- AZSTD_CONTAINER_ASSERT(npos - m_size > count && m_size + count >= m_size, "result is too long!");
- num = m_size + count;
- if (count > 0 && grow(num))
- {
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer;
+ pointer data = m_storage.first().GetData();
+ const_pointer rhsData = rhs.data();
// make room and append new stuff
- Traits::copy(data + m_size /*, m_capacity - m_size*/, rhsData + rhsOffset, count);
- m_size = num;
- Traits::assign(data[num], Element()); // terminate
+ Traits::copy(data + oldSize, rhsData + rhsOffset, count);
+ m_storage.first().SetSize(newSize);
+ Traits::assign(data[newSize], Element()); // terminate
}
return *this;
}
@@ -230,20 +211,21 @@ namespace AZStd
this_type& append(const_pointer ptr, size_type count)
{
// append [ptr, ptr + count)
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- if (ptr != 0 && ptr >= data && (data + m_size) > ptr)
+ pointer data = m_storage.first().GetData();
+ if (ptr != nullptr && ptr >= data && (data + size()) > ptr)
{
return append(*this, ptr - data, count); // substring
}
- AZSTD_CONTAINER_ASSERT(npos - m_size > count && m_size + count >= m_size, "result is too long!");
- size_type num = m_size + count;
- if (count > 0 && grow(num))
+ AZSTD_CONTAINER_ASSERT(npos - size() > count && size() + count >= size(), "result is too long!");
+ size_type oldSize = size();
+ size_type newSize = oldSize + count;
+ if (count > 0 && grow(newSize))
{
// make room and append new stuff
- data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- Traits::copy(data + m_size /*, m_capacity - m_size*/, ptr, count);
- m_size = num;
- Traits::assign(data[num], Element()); // terminate
+ data = m_storage.first().GetData();
+ Traits::copy(data + oldSize , ptr, count);
+ m_storage.first().SetSize(newSize);
+ Traits::assign(data[newSize], Element()); // terminate
}
return *this;
}
@@ -252,30 +234,60 @@ namespace AZStd
this_type& append(size_type count, Element ch)
{
// append count * ch
- AZSTD_CONTAINER_ASSERT(npos - m_size > count, "result is too long");
- size_type num = m_size + count;
+ AZSTD_CONTAINER_ASSERT(npos - size() > count, "result is too long");
+ size_type num = size() + count;
if (count > 0 && grow(num))
{
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ pointer data = m_storage.first().GetData();
// make room and append new stuff using assign
- if (count == 1)
- {
- Traits::assign(*(data + m_size), ch);
- }
- else
- {
- Traits::assign(data + m_size, count, ch);
- }
- m_size = num;
+ Traits::assign(data + size(), count, ch);
+ m_storage.first().SetSize(num);
Traits::assign(data[num], Element()); // terminate
}
return *this;
}
- template
- inline this_type& append(InputIterator first, InputIterator last)
+ template
+ inline auto append(InputIt first, InputIt last)
+ -> enable_if_t && !is_convertible_v, this_type&>
{ // append [first, last)
- return append_iter(first, last, AZStd::is_integral());
+ if constexpr (Internal::satisfies_contiguous_iterator_concept_v
+ && is_same_v::value_type, value_type>)
+ {
+ return append(AZStd::to_address(first), AZStd::distance(first, last));
+ }
+ else if constexpr (Internal::is_forward_iterator_v)
+ {
+ // Input Iterator pointer type doesn't match the const_pointer type
+ // So the elements need to be appended one by one into the buffer
+ size_type oldSize = size();
+ size_type newSize = oldSize + AZStd::distance(first, last);
+ if (grow(newSize))
+ {
+ pointer buffer = data();
+ for (size_t updateIndex = oldSize; first != last; ++first, ++updateIndex)
+ {
+ Traits::assign(buffer[updateIndex], static_cast(*first));
+ }
+ m_storage.first().SetSize(newSize);
+ Traits::assign(buffer[newSize], Element()); // terminate
+ }
+ return *this;
+ }
+ else
+ {
+ // input iterator that aren't forward iterators can only be used in a single pass
+ // algorithm. Therefore AZStd::distance can't be used
+ // So the input is copied into a local string and then delegated
+ // to use the (const_pointer, size_type) overload
+ basic_string inputCopy;
+ for (; first != last; ++first)
+ {
+ inputCopy.push_back(static_cast(*first));
+ }
+
+ return append(inputCopy.c_str(), inputCopy.size());
+ }
}
inline this_type& append(const_pointer first, const_pointer last)
@@ -283,11 +295,6 @@ namespace AZStd
return replace(end(), end(), first, last);
}
- //inline this_type& append(const_iterator first, const_iterator last)
- //{ // append [first, last), const_iterators
- // return replace(end(), end(), first, last);
- //}
-
inline this_type& assign(const this_type& rhs)
{
return assign(rhs, 0, npos);
@@ -302,27 +309,34 @@ namespace AZStd
{
if (this != &rhs)
{
- if (SSO_BUF_SIZE <= m_capacity)
+ deallocate_memory(m_storage.first().GetData(), 0, typename allocator_type::allow_memory_leaks());
+
+ m_storage.first().SetCapacity(rhs.capacity());
+
+ pointer data = m_storage.first().GetData();
+ pointer rhsData = rhs.data();
+ // Memmove the right hand side string data if it is using the short string optimization
+ // Otherwise set the pointer to the right hand side
+ if (rhs.m_storage.first().ShortStringOptimizationActive())
{
- deallocate_memory(m_data, 0, typename allocator_type::allow_memory_leaks());
+ Traits::move(data, rhsData, rhs.size() + 1); // string + null-terminator
}
+ else
+ {
+ m_storage.first().SetData(rhsData);
+ }
+ m_storage.first().SetSize(rhs.size());
+ m_storage.second() = rhs.m_storage.second();
- Traits::move(m_buffer, rhs.m_buffer, sizeof(m_buffer));
- m_size = rhs.m_size;
- m_capacity = rhs.m_capacity;
- m_allocator = rhs.m_allocator;
-
- rhs.m_data = nullptr;
- rhs.m_size = 0;
- rhs.m_capacity = SSO_BUF_SIZE - 1;
+ rhs.leak_and_reset();
}
return *this;
}
this_type& assign(const this_type& rhs, size_type rhsOffset, size_type count)
{ // assign rhs [rhsOffset, rhsOffset + count)
- AZSTD_CONTAINER_ASSERT(rhs.m_size >= rhsOffset, "Invalid offset");
- size_type num = rhs.m_size - rhsOffset;
+ AZSTD_CONTAINER_ASSERT(rhs.size() >= rhsOffset, "Invalid offset");
+ size_type num = rhs.size() - rhsOffset;
if (count < num)
{
num = count; // trim num to size
@@ -334,10 +348,10 @@ namespace AZStd
}
else if (grow(num))
{ // make room and assign new stuff
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer;
- Traits::copy(data /*, m_capacity*/, rhsData + rhsOffset, num);
- m_size = num;
+ pointer data = m_storage.first().GetData();
+ const_pointer rhsData = rhs.data();
+ Traits::copy(data, rhsData + rhsOffset, num);
+ m_storage.first().SetSize(num);
Traits::assign(data[num], Element()); // terminate
}
return *this;
@@ -345,20 +359,20 @@ namespace AZStd
this_type& assign(const_pointer ptr, size_type count)
{ // assign [ptr, ptr + count)
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- if (ptr != 0 && ptr >= data && (data + m_size) > ptr)
+ pointer data = m_storage.first().GetData();
+ if (ptr != nullptr && ptr >= data && (data + size()) > ptr)
{
return assign(*this, ptr - data, count); // substring
}
if (grow(count))
{
// make room and assign new stuff
- data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ data = m_storage.first().GetData();
if (count > 0)
{
Traits::copy(data, ptr, count);
}
- m_size = count;
+ m_storage.first().SetSize(count);
Traits::assign(data[count], Element()); // terminate
}
return *this;
@@ -367,109 +381,132 @@ namespace AZStd
this_type& assign(size_type count, Element ch)
{
// assign count * ch
- AZSTD_CONTAINER_ASSERT(count != npos, "result is too long!");
if (grow(count))
{ // make room and assign new stuff
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- if (count == 1)
- {
- Traits::assign(*(data), ch);
- }
- else
- {
- Traits::assign(data, count, ch);
- }
- m_size = count;
+ pointer data = m_storage.first().GetData();
+ Traits::assign(data, count, ch);
+ m_storage.first().SetSize(count);
Traits::assign(data[count], Element()); // terminate
}
return *this;
}
- template
- inline this_type& assign(InputIterator first, InputIterator last) { return assign_iter(first, last, AZStd::is_integral()); }
- inline this_type& assign(const_pointer first, const_pointer last) { return replace(begin(), end(), first, last); }
- inline this_type& insert(size_type offset, const this_type& rhs) { return insert(offset, rhs, 0, npos); }
+ template
+ auto assign(InputIt first, InputIt last)
+ -> enable_if_t && !is_convertible_v, this_type&>
+ {
+ if constexpr (Internal::satisfies_contiguous_iterator_concept_v
+ && is_same_v::value_type, value_type>)
+ {
+ return assign(AZStd::to_address(first), AZStd::distance(first, last));
+ }
+ else if constexpr (Internal::is_forward_iterator_v)
+ {
+ // forward iterator pointer type doesn't match the const_pointer type
+ // So the elements need to be assigned one by one into the buffer
+ size_type newSize = AZStd::distance(first, last);
+ if (grow(newSize))
+ {
+ pointer buffer = data();
+ for (size_t updateIndex = 0; first != last; ++first, ++updateIndex)
+ {
+ Traits::assign(buffer[updateIndex], static_cast(*first));
+ }
+ m_storage.first().SetSize(newSize);
+ Traits::assign(buffer[newSize], Element()); // terminate
+ }
+ return *this;
+ }
+ else
+ {
+ // input iterator that aren't forward iterators can only be used in a single pass
+ // algorithm. Therefore AZStd::distance can't be used
+ // So the input is copied into a local string and then delegated
+ // to use the (const_pointer, size_type) overload
+ basic_string inputCopy;
+ for (; first != last; ++first)
+ {
+ inputCopy.push_back(static_cast(*first));
+ }
+
+ return assign(inputCopy.c_str(), inputCopy.size());
+ }
+ }
+ inline this_type& insert(size_type offset, const this_type& rhs) { return insert(offset, rhs, 0, npos); }
this_type& insert(size_type offset, const this_type& rhs, size_type rhsOffset, size_type count)
{
// insert rhs [rhsOffset, rhsOffset + count) at offset
- AZSTD_CONTAINER_ASSERT(m_size >= offset && rhs.m_size >= rhsOffset, "Invalid offset(s)");
- size_type num = rhs.m_size - rhsOffset;
+ AZSTD_CONTAINER_ASSERT(size() >= offset && rhs.size() >= rhsOffset, "Invalid offset(s)");
+ size_type num = rhs.size() - rhsOffset;
if (num < count)
{
count = num; // trim _Count to size
}
- AZSTD_CONTAINER_ASSERT(npos - m_size > count, "Result is too long");
- num = m_size + count;
+ AZSTD_CONTAINER_ASSERT(npos - size() > count, "Result is too long");
+ num = size() + count;
if (count > 0 && grow(num))
{
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ pointer data = m_storage.first().GetData();
// make room and insert new stuff
- Traits::move(data + offset + count /*, m_capacity - offset - count*/, data + offset, m_size - offset); // empty out hole
+ Traits::move(data + offset + count, data + offset, size() - offset); // empty out hole
if (this == &rhs)
{
- Traits::move(data + offset /*, m_capacity - offset*/, data + (offset < rhsOffset ? rhsOffset + count : rhsOffset), count); // substring
+ Traits::move(data + offset, data + (offset < rhsOffset ? rhsOffset + count : rhsOffset), count); // substring
}
else
{
- const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer;
- Traits::copy(data + offset /*, m_capacity - offset*/, rhsData + rhsOffset, count); // fill hole
+ const_pointer rhsData = rhs.data();
+ Traits::copy(data + offset, rhsData + rhsOffset, count); // fill hole
}
- m_size = num;
+ m_storage.first().SetSize(num);
Traits::assign(data[num], Element()); // terminate
}
return (*this);
}
- this_type& insert(size_type offset, const_pointer ptr, size_type count)
+ this_type& insert(size_type offset, const_pointer ptr, size_type count)
{
// insert [ptr, ptr + count) at offset
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- if (ptr != 0 && ptr >= data && (data + m_size) > ptr)
+ pointer data = m_storage.first().GetData();
+ if (ptr != nullptr && ptr >= data && (data + size()) > ptr)
{
- return insert(offset, *this, ptr - data, count); // substring
+ return insert(offset, *this, ptr - data, count); // substring
}
- AZSTD_CONTAINER_ASSERT(m_size >= offset, "Invalid offset");
- AZSTD_CONTAINER_ASSERT(npos - m_size > count, "Result is too long");
- size_type num = m_size + count;
+ AZSTD_CONTAINER_ASSERT(size() >= offset, "Invalid offset");
+ AZSTD_CONTAINER_ASSERT(npos - size() > count, "Result is too long");
+ size_type num = size() + count;
if (count > 0 && grow(num))
{ // make room and insert new stuff
- data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- Traits::move(data + offset + count /*, m_capacity - offset - count*/, data + offset, m_size - offset); // empty out hole
- Traits::copy(data + offset /*, m_capacity - offset*/, ptr, count); // fill hole
- m_size = num;
+ data = m_storage.first().GetData();
+ Traits::move(data + offset + count, data + offset, size() - offset); // empty out hole
+ Traits::copy(data + offset, ptr, count); // fill hole
+ m_storage.first().SetSize(num);
Traits::assign(data[num], Element()); // terminate
}
return *this;
}
- inline this_type& insert(size_type offset, const_pointer ptr) { return insert(offset, ptr, Traits::length(ptr)); }
+ inline this_type& insert(size_type offset, const_pointer ptr) { return insert(offset, ptr, Traits::length(ptr)); }
this_type& insert(size_type offset, size_type count, Element ch)
{
// insert count * ch at offset
- AZSTD_CONTAINER_ASSERT(m_size >= offset, "Invalid offset");
- AZSTD_CONTAINER_ASSERT(npos - m_size > count, "Result is too long");
- size_type num = m_size + count;
+ AZSTD_CONTAINER_ASSERT(size() >= offset, "Invalid offset");
+ AZSTD_CONTAINER_ASSERT(npos - size() > count, "Result is too long");
+ size_type num = size() + count;
if (count > 0 && grow(num))
{
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ pointer data = m_storage.first().GetData();
// make room and insert new stuff
- Traits::move(data + offset + count /*, m_capacity - offset - count*/, data + offset, m_size - offset); // empty out hole
- if (count == 1)
- {
- Traits::assign(*(data + offset), ch);
- }
- else
- {
- Traits::assign(data + offset, count, ch);
- }
- m_size = num;
+ Traits::move(data + offset + count, data + offset, size() - offset); // empty out hole
+ Traits::assign(data + offset, count, ch);
+ m_storage.first().SetSize(num);
Traits::assign(data[num], Element()); // terminate
}
return *this;
}
- inline iterator insert(const_iterator insertPos) { return insert(insertPos, Element()); }
+ inline iterator insert(const_iterator insertPos) { return insert(insertPos, Element()); }
iterator insert(const_iterator insertPos, Element ch)
{
@@ -479,54 +516,89 @@ namespace AZStd
const_pointer insertPosPtr = insertPos;
#endif
- const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ const_pointer data = m_storage.first().GetData();
size_type offset = insertPosPtr - data;
insert(offset, 1, ch);
return iterator(AZSTD_CHECKED_ITERATOR(iterator_impl, data + offset));
}
- void insert(const_iterator insertPos, size_type count, Element ch)
+ iterator insert(const_iterator insertPos, size_type count, Element ch)
{ // insert count * elem at insertPos
#ifdef AZSTD_HAS_CHECKED_ITERATORS
const_pointer insertPosPtr = insertPos.get_iterator();
#else
const_pointer insertPosPtr = insertPos;
#endif
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ pointer data = m_storage.first().GetData();
size_type offset = insertPosPtr - data;
insert(offset, count, ch);
+ return begin() + offset;
}
- template
- inline void insert(const_iterator insertPos, InputIterator first, InputIterator last)
+ template
+ auto insert(const_iterator insertPos, InputIt first, InputIt last)
+ -> enable_if_t && !is_convertible_v, iterator>
{ // insert [_First, _Last) at _Where
- insert_iter(insertPos, first, last, is_integral());
- }
+ size_type insertOffset = AZStd::distance(cbegin(), insertPos);
+ if constexpr (Internal::satisfies_contiguous_iterator_concept_v
+ && is_same_v::value_type, value_type>)
+ {
+ insert(insertOffset, AZStd::to_address(first), AZStd::distance(first, last));
+ }
+ else if constexpr (Internal::is_forward_iterator_v)
+ {
+ // Input Iterator pointer type doesn't match the const_pointer type
+ // So the elements need to be inserted one by one into the buffer
+ size_type count = AZStd::distance(first, last);
+ size_type oldSize = size();
+ size_type newSize = oldSize + count;
+ if (grow(newSize))
+ {
+ pointer buffer = m_storage.first().GetData();
+ Traits::copy_backward(buffer + insertOffset + count, buffer + insertOffset, oldSize - insertOffset); // empty out hole
+ for (size_t updateIndex = insertOffset; first != last; ++first, ++updateIndex)
+ {
+ Traits::assign(buffer[updateIndex], static_cast(*first));
+ }
+ m_storage.first().SetSize(newSize);
+ Traits::assign(buffer[newSize], Element()); // terminate
+ }
+ }
+ else
+ {
+ // input iterator that aren't forward iterators can only be used in a single pass
+ // algorithm. Therefore AZStd::distance can't be used
+ // So the input is copied into a local string and then delegated
+ // to use the (const_pointer, size_type) overload
+ basic_string inputCopy;
+ for (; first != last; ++first)
+ {
+ inputCopy.push_back(static_cast(*first));
+ }
- inline void insert(const_iterator insertPos, const_pointer first, const_pointer last)
- { // insert [first, last) at insertPos, const pointers
- replace(insertPos, insertPos, first, last);
+ insert(insertOffset, inputCopy.c_str(), inputCopy.size());
+ }
+ return begin() + insertOffset;
}
-
this_type& erase(size_type offset = 0, size_type count = npos)
{ // erase elements [offset, offset + count)
- AZSTD_CONTAINER_ASSERT(m_size >= offset, "Invalid offset");
- if (m_size - offset < count)
+ AZSTD_CONTAINER_ASSERT(size() >= offset, "Invalid offset");
+ if (size() - offset < count)
{
- count = m_size - offset; // trim count
+ count = size() - offset; // trim count
}
if (count > 0)
{
// move elements down
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ pointer data = m_storage.first().GetData();
#ifdef AZSTD_HAS_CHECKED_ITERATORS
orphan_range(data + offset, data + offset + count);
#endif
- Traits::move(data + offset /*, m_capacity - offset*/, data + offset + count, m_size - offset - count);
- m_size = m_size - count;
- Traits::assign(data[m_size], Element()); // terminate
- }
+ Traits::move(data + offset, data + offset + count, size() - offset - count);
+ m_storage.first().SetSize(size() - count);
+ Traits::assign(data[size()], Element()); // terminate
+ }
return *this;
}
@@ -538,10 +610,10 @@ namespace AZStd
const_pointer erasePtr = erasePos;
#endif
// erase element at insertPos
- const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ const_pointer data = m_storage.first().GetData();
size_type count = erasePtr - data;
erase(count, 1);
- data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ data = m_storage.first().GetData();
return iterator(AZSTD_CHECKED_ITERATOR(iterator_impl, data + count));
}
@@ -554,159 +626,152 @@ namespace AZStd
const_pointer firstPtr = first;
const_pointer lastPtr = last;
#endif
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ pointer data = m_storage.first().GetData();
size_type count = firstPtr - data;
erase(count, lastPtr - firstPtr);
- data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ data = m_storage.first().GetData();
return iterator(AZSTD_CHECKED_ITERATOR(iterator_impl, data + count));
}
- inline void clear() { erase(begin(), end()); }
- inline this_type& replace(size_type offset, size_type count, const this_type& rhs)
+ inline void clear() { erase(begin(), end()); }
+ this_type& replace(size_type offset, size_type count, const this_type& rhs)
{
- // replace [offset, offset + count) with rhs
- return replace(offset, count, rhs, 0, npos);
+ return replace(offset, count, rhs.c_str(), rhs.size());
}
this_type& replace(size_type offset, size_type count, const this_type& rhs, size_type rhsOffset, size_type rhsCount)
{
- // replace [offset, offset + count) with rhs [rhsOffset, rhsOffset + rhsCount)
- AZSTD_CONTAINER_ASSERT(m_size >= offset && rhs.m_size >= rhsOffset, "Invalid offsets");
- if (m_size - offset < count)
- {
- count = m_size - offset; // trim count to size
- }
- size_type num = rhs.m_size - rhsOffset;
- if (num < rhsCount)
- {
- rhsCount = num; // trim rhsCount to size
- }
- AZSTD_CONTAINER_ASSERT(npos - rhsCount > m_size - count, "Result is too long");
-
- size_type nm = m_size - count - offset; // length of preserved tail
- size_type newSize = m_size + rhsCount - count;
- if (m_size < newSize)
- {
- grow(newSize);
- }
-
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer;
-
-#ifdef AZSTD_HAS_CHECKED_ITERATORS
- orphan_range(data + offset, data + offset + count);
-#endif
- if (this != &rhs)
- { // no overlap, just move down and copy in new stuff
- Traits::move(data + offset + rhsCount /*, m_capacity - offset - rhsCount*/, data + offset + count, nm); // empty hole
- Traits::copy(data + offset /*, m_capacity - offset*/, rhsData + rhsOffset, rhsCount); // fill hole
- }
- else if (rhsCount <= count)
- { // hole doesn't get larger, just copy in substring
- Traits::move(data + offset /*, m_capacity - offset*/, data + rhsOffset, rhsCount); // fill hole
- Traits::move(data + offset + rhsCount /*, m_capacity - offset - rhsCount*/, data + offset + count, nm); // move tail down
- }
- else if (rhsOffset <= offset)
- { // hole gets larger, substring begins before hole
- Traits::move(data + offset + rhsCount /*, m_capacity - offset - rhsCount*/, data + offset + count, nm); // move tail down
- Traits::move(data + offset /*, m_capacity - offset*/, data + rhsOffset, rhsCount); // fill hole
- }
- else if (offset + count <= rhsOffset)
- { // hole gets larger, substring begins after hole
- Traits::move(data + offset + rhsCount /*, m_capacity - offset - rhsCount*/, data + offset + count, nm); // move tail down
- Traits::move(data + offset /*, m_capacity - offset*/, data + (rhsOffset + rhsCount - count), rhsCount); // fill hole
- }
- else
- { // hole gets larger, substring begins in hole
- Traits::move(data + offset /*, m_capacity - offset*/, data + rhsOffset, count); // fill old hole
- Traits::move(data + offset + rhsCount /*, m_capacity - offset - rhsCount*/, data + offset + count, nm); // move tail down
- Traits::move(data + offset + count /*, m_capacity - offset - count*/, data + rhsOffset + rhsCount, rhsCount - count); // fill rest of new hole
- }
-
- m_size = newSize;
- Traits::assign(data[newSize], Element()); // terminate
- return (*this);
+ return replace(offset, count, rhs.c_str() + rhsOffset, AZStd::min(rhsCount, rhs.size() - rhsOffset));
}
this_type& replace(size_type offset, size_type count, const_pointer ptr, size_type ptrCount)
{
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
// replace [offset, offset + count) with [ptr, ptr + ptrCount)
- if (ptr != 0 && ptr >= data && (data + m_size) > ptr)
- {
- return (replace(offset, count, *this, ptr - data, ptrCount)); // substring, replace carefully
- }
- AZSTD_CONTAINER_ASSERT(m_size >= offset, "Invalid offset");
- if (m_size - offset < count)
- {
- count = m_size - offset; // trim _N0 to size
- }
- AZSTD_CONTAINER_ASSERT(npos - ptrCount > m_size - count, "Result too long");
+ AZSTD_CONTAINER_ASSERT(size() >= offset, "Invalid offset");
+ // Make sure count is within is no larger than the distance from the offset
+ // to the end of this string
+ count = AZStd::min(count, size() - offset);
-#ifdef AZSTD_HAS_CHECKED_ITERATORS
- orphan_range(data + offset, data + offset + count);
-#endif
- size_type nm = m_size - count - offset;
- if (ptrCount < count)
+ size_type newSize = size() + ptrCount - count;
+ size_type charsAfterCountToMove = size() - count - offset;
+ pointer inputStringCopy{};
+
+ if (pointer thisBuffer = m_storage.first().GetData();
+ (ptr >= thisBuffer && ptr < thisBuffer + size())
+ || (ptr + ptrCount > thisBuffer && ptr + ptrCount <= thisBuffer + size()))
{
- Traits::move(data + offset + ptrCount, data + offset + count, nm); // smaller hole, move tail up
- }
- size_type num = m_size + ptrCount - count;
- if ((0 < ptrCount || 0 < count) && grow(num))
- {
- data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- // make room and rearrange
- if (count < ptrCount)
+ // Overlap checks for tring needs if the input pointer is anywhere within the string
+ // even if it is outside of the range of [offset, offset + count) as a growing
+ // the string buffer could cause a realloc to occur
+ if (!fits_in_capacity(newSize))
{
- Traits::move(data + offset + ptrCount /*, m_capacity - offset - ptrCount*/, data + offset + count, nm); // move tail down
+ // If the input string is a sub-string and it would cause
+ // this string to need to re-allocated as it doesn't fit in the capacity
+ // Then the input string is needs to be copied into a local buffer
+ inputStringCopy = reinterpret_cast(get_allocator().allocate(ptrCount * sizeof(value_type), alignof(value_type)));
+ Traits::copy(inputStringCopy, ptr, ptrCount);
+ // Updated the input string pointer to point to the local buffer
+ ptr = inputStringCopy;
+ // Now this string buffer can now be safely resized and the non-overlapping string logic below can be used
+ }
+ else
+ {
+ // overlapping string in-place logic
+ // Ex. this = "ABCDEFG", offset = 1, count=4
+ // substring is "CDE"
+ // The text from offset 1 for 4 chars "BCDE": should be replaced with "CDE"
+ // making a whole for the bytes results in output = "ABCDFG"
+ // Afterwards output = "ACDEFG"
+ // The input string overlaps with this string in this case
+ // So the string is copied piecewise
+ if (ptrCount <= count)
+ { // hole doesn't get larger, just copy in substring
+ Traits::move(thisBuffer + offset, ptr, ptrCount); // fill hole
+ Traits::copy(thisBuffer + offset + ptrCount, thisBuffer + offset + count, charsAfterCountToMove); // move tail down
+ }
+ else
+ {
+ if (ptr <= thisBuffer + offset)
+ { // hole gets larger, substring begins before hole
+ Traits::copy_backward(thisBuffer + offset + ptrCount, thisBuffer + offset + count, charsAfterCountToMove); // move tail down
+ Traits::copy(thisBuffer + offset, ptr, ptrCount); // fill hole
+ }
+ else if (thisBuffer + offset + count <= ptr)
+ { // hole gets larger, substring begins after hole
+ Traits::copy_backward(thisBuffer + offset + ptrCount, thisBuffer + offset + count, charsAfterCountToMove); // move tail down
+ Traits::copy(thisBuffer + offset, ptr + (ptrCount - count), ptrCount); // fill hole
+ }
+ else
+ { // hole gets larger, substring begins in hole
+ Traits::copy(thisBuffer + offset, ptr, count); // fill old hole
+ Traits::copy_backward(thisBuffer + offset + ptrCount, thisBuffer + offset + count, charsAfterCountToMove); // move tail down
+ Traits::copy(thisBuffer + offset + count, ptr + ptrCount, ptrCount - count); // fill rest of new hole
+ }
+ }
+ m_storage.first().SetSize(newSize);
+ Traits::assign(thisBuffer[newSize], Element()); // terminate
+ return *this;
+ }
+ }
+
+ // input string doesn't overlap, so this string can be re-allocated safely
+ if (grow(newSize))
+ {
+ // Need to regrab the memory address for the storage buffer
+ // in case the grow re-allocated memory
+ pointer thisBuffer = m_storage.first().GetData();
+ if (count != ptrCount)
+ {
+ Traits::move(thisBuffer + offset + ptrCount, thisBuffer + offset + count, charsAfterCountToMove);
}
if (ptrCount > 0)
{
- Traits::copy(data + offset /*, m_capacity - offset*/, ptr, ptrCount); // fill hole
+ // Copy bytes up to the minimum of this string count and input string count
+ Traits::copy(thisBuffer + offset, ptr, ptrCount);
}
-
- m_size = num;
- Traits::assign(data[num], Element()); // terminate
+ // input string doesn't overlap, so this string can be re-allocated safely
+ m_storage.first().SetSize(newSize);
+ Traits::assign(thisBuffer[newSize], Element()); // terminate
}
+
+ // If a local string was allocated, then de-allocate its memory
+ if (inputStringCopy != nullptr)
+ {
+ get_allocator().deallocate(inputStringCopy, 0, alignof(value_type));
+ }
+
return *this;
}
inline this_type& replace(size_type offset, size_type count, const_pointer ptr) { return replace(offset, count, ptr, Traits::length(ptr)); }
this_type& replace(size_type offset, size_type count, size_type num, Element ch)
{ // replace [offset, offset + count) with num * ch
- AZSTD_CONTAINER_ASSERT(m_size > offset, "Invalid offset");
- if (m_size - offset < count)
+ AZSTD_CONTAINER_ASSERT(size() > offset, "Invalid offset");
+ if (size() - offset < count)
{
- count = m_size - offset; // trim count to size
+ count = size() - offset; // trim count to size
}
- AZSTD_CONTAINER_ASSERT(npos - num > m_size - count, "Result is too long");
- size_type nm = m_size - count - offset;
+ AZSTD_CONTAINER_ASSERT(npos - num > size() - count, "Result is too long");
+ size_type nm = size() - count - offset;
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ pointer data = m_storage.first().GetData();
#ifdef AZSTD_HAS_CHECKED_ITERATORS
orphan_range(data + offset, data + offset + count);
#endif
if (num < count)
{
- Traits::move(data + offset + num /*, m_capacity - offset - num*/, data + offset + count, nm); // smaller hole, move tail up
+ Traits::move(data + offset + num, data + offset + count, nm); // smaller hole, move tail up
}
- size_type numToGrow = m_size + num - count;
+ size_type numToGrow = size() + num - count;
if ((0 < num || 0 < count) && grow(numToGrow))
{ // make room and rearrange
- data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ data = m_storage.first().GetData();
if (count < num)
{
- Traits::move(data + offset + num /*, m_capacity - offset - num*/, data + offset + count, nm); // move tail down
+ Traits::move(data + offset + num, data + offset + count, nm); // move tail down
}
- if (count == 1)
- {
- Traits::assign(*(data + offset), ch);
- }
- else
- {
- Traits::assign(data + offset, num, ch);
- }
- m_size = numToGrow;
+ Traits::assign(data + offset, num, ch);
+ m_storage.first().SetSize(numToGrow);
Traits::assign(data[numToGrow], Element()); // terminate
}
return *this;
@@ -722,7 +787,7 @@ namespace AZStd
const_pointer firstPtr = first;
const_pointer lastPtr = last;
#endif
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ pointer data = m_storage.first().GetData();
return replace(firstPtr - data, lastPtr - firstPtr, rhs);
}
@@ -735,7 +800,7 @@ namespace AZStd
const_pointer firstPtr = first;
const_pointer lastPtr = last;
#endif
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ pointer data = m_storage.first().GetData();
return replace(firstPtr - data, lastPtr - firstPtr, ptr, count);
}
@@ -748,7 +813,7 @@ namespace AZStd
const_pointer firstPtr = first;
const_pointer lastPtr = last;
#endif
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ pointer data = m_storage.first().GetData();
return replace(firstPtr - data, lastPtr - firstPtr, ptr);
}
@@ -761,113 +826,133 @@ namespace AZStd
const_pointer firstPtr = first;
const_pointer lastPtr = last;
#endif
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ pointer data = m_storage.first().GetData();
return replace(firstPtr - data, lastPtr - firstPtr, count, ch);
}
- template
- inline this_type& replace(const_iterator first, const_iterator last, InputIterator first2, InputIterator last2)
- { // replace [first, last) with [first2,last2)
- return replace_iter(first, last, first2, last2, is_integral());
- }
-
- this_type& replace(const_iterator first, const_iterator last, const_pointer first2, const_pointer last2)
+ template
+ inline auto replace(const_iterator first, const_iterator last, InputIt replaceFirst, InputIt replaceLast)
+ -> enable_if_t && !is_convertible_v, this_type&>
{
-#ifdef AZSTD_HAS_CHECKED_ITERATORS
- const_pointer first1 = first.get_iterator();
- const_pointer last1 = last.get_iterator();
-#else
- const_pointer first1 = first;
- const_pointer last1 = last;
-#endif
- // replace [first, last) with [first2, last2), const pointers
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- if (first2 == last2)
+ if constexpr (Internal::satisfies_contiguous_iterator_concept_v
+ && is_same_v::value_type, value_type>)
{
- erase(first1 - data, last1 - first1);
+ return replace(first, last, AZStd::to_address(replaceFirst), AZStd::distance(replaceFirst, replaceLast));
+ }
+ else if constexpr (Internal::is_forward_iterator_v)
+ {
+ // Input Iterator pointer type doesn't match the const_pointer type
+ // So the elements need to be appended one by one into the buffer
+
+ size_type insertOffset = AZStd::distance(cbegin(), first);
+ size_type postInsertOffset = AZStd::distance(cbegin(), last);
+ size_type count = AZStd::distance(replaceFirst, replaceLast);
+ size_type oldSize = size();
+ size_type newSize = oldSize + count - AZStd::distance(first, last);
+ if (grow(newSize))
+ {
+ pointer buffer = data();
+ Traits::move(first + count, last, oldSize - postInsertOffset); // empty out hole
+ for (size_t updateIndex = insertOffset; replaceFirst != replaceLast; ++replaceFirst, ++updateIndex)
+ {
+ Traits::assign(buffer[updateIndex], static_cast(*replaceFirst));
+ }
+ m_storage.first().SetSize(newSize);
+ Traits::assign(buffer[newSize], Element()); // terminate
+ }
+ return *this;
}
else
{
- replace(first1 - data, last1 - first1, &*first2, last2 - first2);
+ // input iterator that aren't forward iterators can only be used in a single pass
+ // algorithm. Therefore AZStd::distance can't be used
+ // So the input is copied into a local string and then delegated
+ // to use the (const_pointer, size_type) overload
+ basic_string inputCopy;
+ for (; replaceFirst != replaceLast; ++replaceFirst)
+ {
+ inputCopy.push_back(static_cast(*replaceFirst));
+ }
+
+ return replace(first, last, inputCopy.c_str(), inputCopy.size());
}
- return *this;
}
inline reference at(size_type offset)
{
// subscript mutable sequence with checking
- AZSTD_CONTAINER_ASSERT(m_size > offset, "Invalid offset");
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ AZSTD_CONTAINER_ASSERT(size() > offset, "Invalid offset");
+ pointer data = m_storage.first().GetData();
return data[offset];
}
inline const_reference at(size_type offset) const
{
// subscript nonmutable sequence with checking
- AZSTD_CONTAINER_ASSERT(m_size > offset, "Invalid offset");
- const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ AZSTD_CONTAINER_ASSERT(size() > offset, "Invalid offset");
+ const_pointer data = m_storage.first().GetData();
return data[offset];
}
inline reference operator[](size_type offset)
{
// subscript mutable sequence with checking
- AZSTD_CONTAINER_ASSERT(m_size > offset, "Invalid offset");
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ AZSTD_CONTAINER_ASSERT(size() > offset, "Invalid offset");
+ pointer data = m_storage.first().GetData();
return data[offset];
}
inline const_reference operator[](size_type offset) const
{
// subscript nonmutable sequence with checking
- AZSTD_CONTAINER_ASSERT(m_size > offset, "Invalid offset");
- const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ AZSTD_CONTAINER_ASSERT(size() > offset, "Invalid offset");
+ const_pointer data = m_storage.first().GetData();
return data[offset];
}
inline reference front()
{
- AZSTD_CONTAINER_ASSERT(m_size != 0, "AZStd::string::front - string is empty!");
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ AZSTD_CONTAINER_ASSERT(size() != 0, "AZStd::string::front - string is empty!");
+ pointer data = m_storage.first().GetData();
return data[0];
}
inline const_reference front() const
{
- AZSTD_CONTAINER_ASSERT(m_size != 0, "AZStd::string::front - string is empty!");
- const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ AZSTD_CONTAINER_ASSERT(size() != 0, "AZStd::string::front - string is empty!");
+ const_pointer data = m_storage.first().GetData();
return data[0];
}
inline reference back()
{
- AZSTD_CONTAINER_ASSERT(m_size != 0, "AZStd::string::back - string is empty!");
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- return data[m_size - 1];
+ AZSTD_CONTAINER_ASSERT(size() != 0, "AZStd::string::back - string is empty!");
+ pointer data = m_storage.first().GetData();
+ return data[size() - 1];
}
inline const_reference back() const
{
- AZSTD_CONTAINER_ASSERT(m_size != 0, "AZStd::string::back - string is empty!");
- const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- return data[m_size - 1];
+ AZSTD_CONTAINER_ASSERT(size() != 0, "AZStd::string::back - string is empty!");
+ const_pointer data = m_storage.first().GetData();
+ return data[size() - 1];
}
inline void push_back(Element ch)
{
- const_pointer end = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- end += m_size;
+ const_pointer end = data();
+ end += size();
insert(end, ch);
}
- inline const_pointer c_str() const { return (SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer); }
- inline size_type length() const { return m_size; }
- inline size_type size() const { return m_size; }
- inline size_type capacity() const { return m_capacity; }
+ inline const_pointer c_str() const { return (data()); }
+ inline size_type length() const { return m_storage.first().GetSize(); }
+ inline size_type size() const { return m_storage.first().GetSize(); }
+ inline size_type capacity() const { return m_storage.first().GetCapacity(); }
inline size_type max_size() const
{
// return maximum possible length of sequence
- return AZStd::allocator_traits::max_size(m_allocator) / sizeof(value_type);
+ return AZStd::allocator_traits::max_size(m_storage.second()) / sizeof(value_type);
}
inline void resize(size_type newSize)
@@ -877,58 +962,58 @@ namespace AZStd
inline void resize_no_construct(size_type newSize)
{
- if (newSize <= m_size)
+ if (newSize <= size())
{
erase(newSize);
}
else
{
reserve(newSize);
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- m_size = newSize;
- Traits::assign(data[m_size], Element()); // terminate
+ pointer data = m_storage.first().GetData();
+ m_storage.first().SetSize(newSize);
+ Traits::assign(data[newSize], Element()); // terminate
}
}
inline void resize(size_type newSize, Element ch)
{ // determine new length, padding with ch elements as needed
- if (newSize <= m_size)
+ if (newSize <= size())
{
erase(newSize);
}
else
{
- append(newSize - m_size, ch);
+ append(newSize - size(), ch);
}
}
void reserve(size_type newCapacity = 0)
{ // determine new minimum length of allocated storage
- if (m_size <= newCapacity && m_capacity != newCapacity)
+ if (size() <= newCapacity && capacity() != newCapacity)
{
// change reservation
- size_type size = m_size;
+ size_type curSize = size();
if (grow(newCapacity))
{
- m_size = size;
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- Traits::assign(data[size], Element()); // terminate
+ m_storage.first().SetSize(curSize);
+ pointer data = m_storage.first().GetData();
+ Traits::assign(data[curSize], Element()); // terminate
}
}
}
- inline bool empty() const { return (m_size == 0); }
- size_type copy(Element* dest /*, size_type destSize */, size_type count, size_type offset = 0) const
+ inline bool empty() const { return size() == 0; }
+ size_type copy(Element* dest, size_type count, size_type offset = 0) const
{
// copy [offset, offset + count) to [dest, dest + count)
// assume there is enough space in _Ptr
- AZSTD_CONTAINER_ASSERT(m_size >= offset, "Invalid offset");
- if (m_size - offset < count)
+ AZSTD_CONTAINER_ASSERT(size() >= offset, "Invalid offset");
+ if (size() - offset < count)
{
- count = m_size - offset;
+ count = size() - offset;
}
- const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- Traits::copy(dest /*, destSize*/, data + offset, count);
+ const_pointer data = m_storage.first().GetData();
+ Traits::copy(dest, data + offset, count);
return count;
}
@@ -939,19 +1024,10 @@ namespace AZStd
return;
}
- if (m_allocator == rhs.m_allocator)
+ if (m_storage.second() == rhs.m_storage.second())
{
- // same allocator, swap control information
-#ifdef AZSTD_HAS_CHECKED_ITERATORS
- swap_all(rhs);
-#endif
- Element temp[SSO_BUF_SIZE];
- ::memcpy(temp, rhs.m_buffer, sizeof(m_buffer));
- ::memcpy(rhs.m_buffer, m_buffer, sizeof(m_buffer));
- ::memcpy(m_buffer, temp, sizeof(m_buffer));
-
- AZStd::swap(m_size, rhs.m_size);
- AZStd::swap(m_capacity, rhs.m_capacity);
+ // same allocator, swap storage
+ m_storage.first().swap(rhs.m_storage.first());
}
else
{
@@ -980,174 +1056,76 @@ namespace AZStd
inline size_type find(const this_type& rhs, size_type offset = 0) const
{
- const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer;
- return find(rhsData, offset, rhs.m_size);
+ const_pointer rhsData = rhs.data();
+ return find(rhsData, offset, rhs.size());
}
size_type find(const_pointer ptr, size_type offset, size_type count) const
{
- AZ_Assert(ptr != NULL, "Invalid input!");
-
- // look for [ptr, ptr + count) beginning at or after offset
- if (count == 0 && offset <= m_size)
- {
- return offset; // null string always matches (if inside string)
- }
- size_type nm;
- if (offset < m_size && count <= (nm = m_size - offset))
- { // room for match, look for it
- const_pointer uptr, vptr;
- const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- for (nm -= count - 1, vptr = data + offset; (uptr = Traits::find(vptr, nm, *ptr)) != 0; nm -= uptr - vptr + 1, vptr = uptr + 1)
- {
- if (Traits::compare(uptr, ptr, count) == 0)
- {
- return (uptr - data); // found a match
- }
- }
- }
-
- return (npos); // no match
+ return StringInternal::find(data(), size(), ptr, offset, count, npos);
}
inline size_type find(const_pointer ptr, size_type offset = 0) const { return find(ptr, offset, Traits::length(ptr)); }
inline size_type find(Element ch, size_type offset = 0) const { return find((const_pointer) & ch, offset, 1); }
inline size_type rfind(const this_type& rhs, size_type offset = npos) const
{
- const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer;
- return rfind(rhsData, offset, rhs.m_size);
+ const_pointer rhsData = rhs.data();
+ return rfind(rhsData, offset, rhs.size());
}
size_type rfind(const_pointer ptr, size_type offset, size_type count) const
- { // look for [ptr, ptr + count) beginning before offset
- if (count == 0)
- {
- return (offset < m_size ? offset : m_size); // null always matches
- }
- if (count <= m_size)
- { // room for match, look for it
- const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- const_pointer uptr = data + (offset < m_size - count ? offset : m_size - count);
- for (;; --uptr)
- {
- if (Traits::eq(*uptr, *ptr) && Traits::compare(uptr, ptr, count) == 0)
- {
- return (uptr - data); // found a match
- }
- else if (uptr == data)
- {
- break; // at beginning, no more chance for match
- }
- }
- }
-
- return npos; // no match
+ {
+ return StringInternal::rfind(data(), size(), ptr, offset, count, npos);
}
inline size_type rfind(const_pointer ptr, size_type offset = npos) const { return rfind(ptr, offset, Traits::length(ptr)); }
inline size_type rfind(Element ch, size_type offset = npos) const { return rfind((const_pointer) & ch, offset, 1); }
inline size_type find_first_of(const this_type& rhs, size_type offset = 0) const
{
- const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer;
- return find_first_of(rhsData, offset, rhs.m_size);
+ const_pointer rhsData = rhs.data();
+ return find_first_of(rhsData, offset, rhs.size());
}
size_type find_first_of(const_pointer ptr, size_type offset, size_type count) const
- { // look for one of [ptr, ptr + count) at or after offset
- if (0 < count && offset < m_size)
- { // room for match, look for it
- const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- const Element* const vptr = data + m_size;
- for (const_pointer uptr = data + offset; uptr < vptr; ++uptr)
- {
- if (Traits::find(ptr, count, *uptr) != 0)
- {
- return uptr - data; // found a match
- }
- }
- }
- return npos; // no match
+ {
+ return StringInternal::find_first_of(data(), size(), ptr, offset, count, npos);
}
inline size_type find_first_of(const_pointer ptr, size_type offset = 0) const { return find_first_of(ptr, offset, Traits::length(ptr)); }
inline size_type find_first_of(Element ch, size_type offset = 0) const { return find((const_pointer) & ch, offset, 1); }
inline size_type find_last_of(const this_type& rhs, size_type offset = npos) const
{
- const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer;
- return find_last_of(rhsData, offset, rhs.m_size);
+ const_pointer rhsData = rhs.data();
+ return find_last_of(rhsData, offset, rhs.size());
}
size_type find_last_of(const_pointer ptr, size_type offset, size_type count) const
- { // look for one of [ptr, ptr + count) before offset
- if (0 < count && 0 < m_size)
- {
- const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- for (const_pointer uptr = data + (offset < m_size ? offset : m_size - 1);; --uptr)
- {
- if (Traits::find(ptr, count, *uptr) != 0)
- {
- return uptr - data; // found a match
- }
- else if (uptr == data)
- {
- break; // at beginning, no more chance for match
- }
- }
- }
-
- return npos; // no match
+ {
+ return StringInternal::find_last_of(data(), size(), ptr, offset, count, npos);
}
inline size_type find_last_of(const_pointer ptr, size_type offset = npos) const { return find_last_of(ptr, offset, Traits::length(ptr)); }
inline size_type find_last_of(Element ch, size_type offset = npos) const { return rfind((const_pointer) & ch, offset, 1); }
inline size_type find_first_not_of(const this_type& rhs, size_type offset = 0) const
{ // look for none of rhs at or after offset
- const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer;
- return find_first_not_of(rhsData, offset, rhs.m_size);
+ const_pointer rhsData = rhs.data();
+ return find_first_not_of(rhsData, offset, rhs.size());
}
size_type find_first_not_of(const_pointer ptr, size_type offset, size_type count) const
{
- // look for none of [ptr, ptr + count) at or after offset
- if (offset < m_size)
- { // room for match, look for it
- const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- const Element* const vptr = data + m_size;
- for (const_pointer uptr = data + offset; uptr < vptr; ++uptr)
- {
- if (Traits::find(ptr, count, *uptr) == 0)
- {
- return uptr - data;
- }
- }
- }
- return npos;
+ return StringInternal::find_first_not_of(data(), size(), ptr, offset, count, npos);
}
inline size_type find_first_not_of(const_pointer ptr, size_type offset = 0) const { return find_first_not_of(ptr, offset, Traits::length(ptr)); }
inline size_type find_first_not_of(Element ch, size_type offset = 0) const { return find_first_not_of((const_pointer) & ch, offset, 1); }
inline size_type find_last_not_of(const this_type& rhs, size_type offset = npos) const
{ // look for none of rhs before offset
- const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer;
- return find_last_not_of(rhsData, offset, rhs.m_size);
+ const_pointer rhsData = rhs.data();
+ return find_last_not_of(rhsData, offset, rhs.size());
}
size_type find_last_not_of(const_pointer ptr, size_type offset, size_type count) const
- { // look for none of [ptr, ptr + count) before offset
- if (0 < m_size)
- {
- const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- for (const_pointer uptr = data + (offset < m_size ? offset : m_size - 1);; --uptr)
- {
- if (Traits::find(ptr, count, *uptr) == 0)
- {
- return uptr - data;
- }
- else if (uptr == data)
- {
- break;
- }
- }
- }
- return npos;
+ {
+ return StringInternal::find_last_not_of(data(), size(), ptr, offset, count, npos);
}
inline size_type find_last_not_of(const_pointer ptr, size_type offset = npos) const { return find_last_not_of(ptr, offset, Traits::length(ptr)); }
@@ -1161,8 +1139,8 @@ namespace AZStd
inline int compare(const this_type& rhs) const
{
- const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer;
- return compare(0, m_size, rhsData, rhs.m_size);
+ const_pointer rhsData = rhs.data();
+ return compare(0, size(), rhsData, rhs.size());
}
inline int compare(size_type offset, size_type count, const this_type& rhs) const
@@ -1173,26 +1151,26 @@ namespace AZStd
int compare(size_type offset, size_type count, const this_type& rhs, size_type rhsOffset, size_type rhsCount) const
{
// compare [offset, offset + count) with rhs [rhsOffset, rhsOffset + rhsCount)
- AZSTD_CONTAINER_ASSERT(rhs.m_size >= rhsOffset, "Invalid offset");
- if (rhs.m_size - rhsOffset < rhsCount)
+ AZSTD_CONTAINER_ASSERT(rhs.size() >= rhsOffset, "Invalid offset");
+ if (rhs.size() - rhsOffset < rhsCount)
{
- rhsCount = rhs.m_size - rhsOffset; // trim rhsCount to size
+ rhsCount = rhs.size() - rhsOffset; // trim rhsCount to size
}
- const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer;
+ const_pointer rhsData = rhs.data();
return compare(offset, count, rhsData + rhsOffset, rhsCount);
}
- inline int compare(const_pointer ptr) const { return compare(0, m_size, ptr, Traits::length(ptr)); }
+ inline int compare(const_pointer ptr) const { return compare(0, size(), ptr, Traits::length(ptr)); }
inline int compare(size_type offset, size_type count, const_pointer ptr) const { return compare(offset, count, ptr, Traits::length(ptr)); }
int compare(size_type offset, size_type count, const_pointer ptr, size_type ptrCount) const
{
// compare [offset, offset + _N0) with [_Ptr, _Ptr + _Count)
- AZSTD_CONTAINER_ASSERT(m_size >= offset, "Invalid offset");
- if (m_size - offset < count)
+ AZSTD_CONTAINER_ASSERT(size() >= offset, "Invalid offset");
+ if (size() - offset < count)
{
- count = m_size - offset; // trim count to size
+ count = size() - offset; // trim count to size
}
- const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ const_pointer data = m_storage.first().GetData();
size_type ans = Traits::compare(data + offset, ptr, count < ptrCount ? count : ptrCount);
return (ans != 0 ? (int)ans : count < ptrCount ? -1 : count == ptrCount ? 0 : +1);
}
@@ -1231,11 +1209,11 @@ namespace AZStd
inline void pop_back()
{
- if (m_size > 0)
+ if (!empty())
{
- pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- --m_size;
- Traits::assign(data[m_size], Element()); // terminate
+ pointer data = m_storage.first().GetData();
+ m_storage.first().SetSize(m_storage.first().GetSize() - 1);
+ Traits::assign(data[size()], Element()); // terminate
}
}
@@ -1245,39 +1223,35 @@ namespace AZStd
* @{
*/
/// TR1 Extension. Return pointer to the vector data. The vector data is guaranteed to be stored as an array.
- inline pointer data() { return (SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer); }
- inline const_pointer data() const { return (SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer); }
+ inline pointer data() { return m_storage.first().GetData(); }
+ inline const_pointer data() const { return m_storage.first().GetData(); }
///
/// The only difference from the standard is that we return the allocator instance, not a copy.
- inline allocator_type& get_allocator() { return m_allocator; }
- inline const allocator_type& get_allocator() const { return m_allocator; }
+ inline allocator_type& get_allocator() { return m_storage.second(); }
+ inline const allocator_type& get_allocator() const { return m_storage.second(); }
/// Set the vector allocator. If different than then current all elements will be reallocated.
void set_allocator(const allocator_type& allocator)
{
- if (m_allocator != allocator)
+ if (m_storage.second() != allocator)
{
- if (m_size > 0 && SSO_BUF_SIZE <= m_capacity)
+ if (!empty() && !m_storage.first().ShortStringOptimizationActive())
{
allocator_type newAllocator = allocator;
- pointer data = m_data;
+ pointer data = m_storage.first().GetData();
- pointer newData = reinterpret_cast(newAllocator.allocate(sizeof(node_type) * (m_capacity + 1), alignment_of::value));
+ pointer newData = reinterpret_cast(newAllocator.allocate(sizeof(node_type) * (capacity() + 1), alignof(node_type)));
- Traits::copy(newData, data, m_size + 1); // copy elements and terminator
+ Traits::copy(newData, data, size() + 1); // copy elements and terminator
// Free memory (if needed).
deallocate_memory(data, 0, typename allocator_type::allow_memory_leaks());
- m_allocator = newAllocator;
-
-#ifdef AZSTD_HAS_CHECKED_ITERATORS
- orphan_all();
-#endif
+ m_storage.second() = newAllocator;
}
else
{
- m_allocator = allocator;
+ m_storage.second() = allocator;
}
}
}
@@ -1296,12 +1270,12 @@ namespace AZStd
#else
pointer iterPtr = iter;
#endif
- const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- if (iterPtr < data || iterPtr > (data + m_size))
+ const_pointer data = m_storage.first().GetData();
+ if (iterPtr < data || iterPtr > (data + size()))
{
return isf_none;
}
- else if (iterPtr == (data + m_size))
+ else if (iterPtr == (data + size()))
{
return isf_valid;
}
@@ -1316,12 +1290,12 @@ namespace AZStd
#else
const_pointer iterPtr = iter;
#endif
- const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
- if (iterPtr < data || iterPtr > (data + m_size))
+ const_pointer data = m_storage.first().GetData();
+ if (iterPtr < data || iterPtr > (data + size()))
{
return isf_none;
}
- else if (iterPtr == (data + m_size))
+ else if (iterPtr == (data + size()))
{
return isf_valid;
}
@@ -1337,86 +1311,74 @@ namespace AZStd
* \note This function is added to the vector for consistency. In the vector case we have only one allocation, and if the allocator allows memory leaks
* it can just leave deallocate function empty, which performance wise will be the same. For more complex containers this will make big difference.
*/
- void leak_and_reset()
+ void leak_and_reset()
{
- m_size = 0;
- m_capacity = SSO_BUF_SIZE - 1;
- Traits::assign(m_buffer[0], Element());
-
-#ifdef AZSTD_HAS_CHECKED_ITERATORS
- orphan_all();
-#endif
+ m_storage.first() = {};
}
/**
* Set the capacity, if necessary it will erase elements at the end of the container to match the new capacity.
*/
- void set_capacity(size_type numElements)
+ void set_capacity(size_type numElements)
{
// sets the new capacity of the vector, can be smaller than size()
- if (m_capacity != numElements)
+ if (capacity() != numElements)
{
- if (numElements < SSO_BUF_SIZE)
+ if (numElements < ShortStringData::Capacity)
{
- if (m_capacity >= SSO_BUF_SIZE)
+ if (!m_storage.first().ShortStringOptimizationActive())
{
// copy any leftovers to small buffer and deallocate
- pointer ptr = m_data;
- numElements = numElements < m_size ? numElements : m_size;
+ pointer ptr = m_storage.first().GetData();
+ numElements = numElements < size() ? numElements : size();
+ m_storage.first().SetCapacity(ShortStringData::Capacity);
if (0 < numElements)
{
- Traits::copy(m_buffer /*, SSO_BUF_SIZE*/, ptr, numElements);
+ Traits::copy(m_storage.first().GetData(), ptr, numElements);
}
- deallocate_memory(ptr, 0, typename allocator_type::allow_memory_leaks());
- m_capacity = SSO_BUF_SIZE - 1;
+ // deallocate_memory functione examines the current
+ // m_storage short string optimization state was changed to true
+ // by the SetCapacity call above. Therefore m_storage.second().deallocate
+ // is used directly
+ m_storage.second().deallocate(ptr, 0, alignof(node_type));
}
- m_size = numElements;
- Traits::assign(m_buffer[numElements], Element()); // terminate
+ m_storage.first().SetSize(numElements);
+ Traits::assign(m_storage.first().GetData()[numElements], Element()); // terminate
}
else
{
size_type expandedSize = 0;
- if (m_capacity >= SSO_BUF_SIZE)
+ if (!m_storage.first().ShortStringOptimizationActive())
{
- expandedSize = m_allocator.resize(m_data, sizeof(node_type) * (numElements + 1));
+ expandedSize = m_storage.second().resize(m_storage.first().GetData(), sizeof(node_type) * (numElements + 1));
// our memory managers allocate on 8+ bytes boundary and our node type should be less than that in general, otherwise
// we need to take care when we compute the size on deallocate.
AZ_Assert(expandedSize % sizeof(node_type) == 0, "Expanded size not a multiply of node type. This should not happen");
size_type expandedCapacity = expandedSize / sizeof(node_type);
if (expandedCapacity > numElements)
{
- m_capacity = expandedCapacity - 1;
+ m_storage.first().SetCapacity(expandedCapacity - 1);
return;
}
}
- pointer newData = reinterpret_cast(m_allocator.allocate(sizeof(node_type) * (numElements + 1), alignment_of::value));
- AZSTD_CONTAINER_ASSERT(newData != 0, "AZStd::string allocation failed!");
+ pointer newData = reinterpret_cast(m_storage.second().allocate(sizeof(node_type) * (numElements + 1), alignof(node_type)));
+ AZSTD_CONTAINER_ASSERT(newData != nullptr, "AZStd::string allocation failed!");
- size_type newSize = numElements < m_size ? numElements : m_size;
- const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer;
+ size_type newSize = numElements < m_storage.first().GetSize() ? numElements : m_storage.first().GetSize();
+ pointer data = m_storage.first().GetData();
if (newSize > 0)
{
- Traits::copy(newData /*, newSize + 1*/, data, newSize); // copy existing elements
- }
- if (m_capacity >= SSO_BUF_SIZE)
- {
- deallocate_memory(m_data, expandedSize, typename allocator_type::allow_memory_leaks());
+ Traits::copy(newData, data, newSize); // copy existing elements
}
+ deallocate_memory(data, expandedSize, typename allocator_type::allow_memory_leaks());
- m_data = newData;
- m_capacity = numElements;
- m_size = newSize;
- Traits::assign(m_data[newSize], Element()); // terminate
+ Traits::assign(newData[newSize], Element()); // terminate
+ m_storage.first().SetCapacity(numElements);
+ m_storage.first().SetData(newData);
+ m_storage.first().SetSize(newSize);
}
-
-#ifdef AZSTD_HAS_CHECKED_ITERATORS
- // when we move data in the buffer we don't really need to make invalid all iterators, but it's
- // very important that we are consistent, so people don't have different behavior when they have
- // short strings
- orphan_all();
-#endif
}
}
@@ -1521,9 +1483,9 @@ namespace AZStd
}
};
-// Clang supports compile-time check for printf-like signatures
-// On MSVC, *only* if /analyze flag is enabled(defines _PREFAST_) we can also do a compile-time check
-// For not affecting final release binary size, we don't use the templated version on Release configuration either
+ // Clang supports compile-time check for printf-like signatures
+ // On MSVC, *only* if /analyze flag is enabled(defines _PREFAST_) we can also do a compile-time check
+ // For not affecting final release binary size, we don't use the templated version on Release configuration either
#if AZ_COMPILER_CLANG || defined(_PREFAST_) || defined(_RELEASE)
# if AZ_COMPILER_CLANG
# define FORMAT_FUNC __attribute__((format(printf, 1, 2)))
@@ -1597,137 +1559,70 @@ namespace AZStd
template
inline basic_string(const basic_string& rhs)
- : m_size(0)
- , m_capacity(SSO_BUF_SIZE - 1)
{
assign(rhs.c_str());
}
template
inline this_type& operator=(const basic_string& rhs) { return assign(rhs.c_str()); }
template
- inline this_type& append(const basic_string& rhs) { return append(rhs.c_str()); }
+ inline this_type& append(const basic_string& rhs) { return append(rhs.c_str()); }
template
inline this_type& insert(size_type offset, const basic_string& rhs) { return insert(offset, rhs.c_str()); }
template
inline this_type& replace(size_type offset, size_type count, const basic_string& rhs) { return replace(offset, count, rhs.c_str()); }
template
- inline int compare(const basic_string& rhs) { return compare(rhs.c_str()); }
+ inline int compare(const basic_string& rhs) { return compare(rhs.c_str()); }
// @}
protected:
- enum
- { // length of internal buffer, [1, 16]
- SSO_BUF_SIZE = 16 / sizeof (Element) < 1 ? 1 : 16 / sizeof(Element)
- };
enum
{ // roundup mask for allocated buffers, [0, 15]
- _ALLOC_MASK = sizeof (Element) <= 1 ? 15 : sizeof (Element) <= 2 ? 7 : sizeof (Element) <= 4 ? 3 : sizeof (Element) <= 8 ? 1 : 0
+ _ALLOC_MASK = sizeof(Element) <= 1 ? 15
+ : sizeof(Element) <= 2 ? 7
+ : sizeof(Element) <= 4 ? 3
+ : sizeof(Element) <= 8 ? 1 : 0
};
- template
- inline this_type& append_iter(InputIterator count, InputIterator ch, const true_type& /* is_integral */)
- { // append count * ch
- return append((size_type)count, (Element)ch);
- }
-
- template
- inline void construct_iter(InputIterator count, InputIterator ch, const true_type& /* is_integral */)
- { // initialize from count * ch
- assign((size_type)count, (Element)ch);
- }
-
- template
- inline void construct_iter(InputIterator first, InputIterator last, const false_type& /*, const input_iterator_tag&*/)
- {
- // initialize from [first, last), input iterators
- // \todo use insert ?
- for (; first != last; ++first)
- {
- append((size_type)1, (Element) * first);
- }
- }
-
-
- template