Merge branch 'development' into cmake/SPEC-7179

monroegm-disable-blank-issue-2
Esteban Papp 4 years ago
commit 074518454c

@ -6,13 +6,13 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
import logging
import os
import tempfile
import psutil
import ly_test_tools.log.log_monitor
import ly_test_tools.environment.process_utils as process_utils
import ly_test_tools.environment.waiter as waiter
from ly_remote_console.remote_console_commands import RemoteConsole as RemoteConsole
from ly_remote_console.remote_console_commands import send_command_and_expect_response as send_command_and_expect_response
logger = logging.getLogger(__name__)
@ -95,7 +95,7 @@ def launch_and_validate_results_launcher(launcher, level, remote_console_instanc
return port_listening
if null_renderer:
launcher.args.extend(["-NullRenderer"])
launcher.args.extend(["-rhi=Null"])
# Start the Launcher
with launcher.start():
@ -110,8 +110,8 @@ def launch_and_validate_results_launcher(launcher, level, remote_console_instanc
# Load the specified level in the launcher
send_command_and_expect_response(remote_console_instance,
f"map {level}",
"LEVEL_LOAD_COMPLETE", timeout=30)
f"LoadLevel {level}",
"LEVEL_LOAD_END", timeout=30)
# Monitor the console for expected lines
for line in expected_lines:

@ -77,7 +77,6 @@ class TestAllComponentsIndepthTests(object):
unexpected_lines=unexpected_lines,
halt_on_unexpected=True,
cfg_args=[level],
auto_test_mode=False,
null_renderer=False,
)

@ -36,8 +36,8 @@ class TestAltitudeFilterFilterStageToggle(EditorTestHelper):
:return: None
"""
PREPROCESS_INSTANCE_COUNT = 24
POSTPROCESS_INSTANCE_COUNT = 18
PREPROCESS_INSTANCE_COUNT = 44
POSTPROCESS_INSTANCE_COUNT = 34
# Create empty level
self.test_success = self.create_level(
@ -62,25 +62,7 @@ class TestAltitudeFilterFilterStageToggle(EditorTestHelper):
dynveg.create_surface_entity("Surface_Entity_Parent", position, 16.0, 16.0, 1.0)
# Add entity with Mesh to replicate creation of hills
hill_entity = dynveg.create_mesh_surface_entity_with_slopes("hill", position, 40.0, 40.0, 40.0)
# Disable/Re-enable Mesh component due to ATOM-14299
general.idle_wait(1.0)
editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [hill_entity.components[0]])
is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', hill_entity.components[0])
if is_enabled:
print("Mesh component is still enabled")
else:
print("Mesh component was disabled")
editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [hill_entity.components[0]])
is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', hill_entity.components[0])
if is_enabled:
print("Mesh component is now enabled")
else:
print("Mesh component is still disabled")
# Increase Box Shape size to encompass the hills
vegetation.get_set_test(1, "Box Shape|Box Configuration|Dimensions", math.Vector3(100.0, 100.0, 100.0))
hill_entity = dynveg.create_mesh_surface_entity_with_slopes("hill", position, 10.0)
# Set a Min Altitude of 38 and Max of 40 in Vegetation Altitude Filter
vegetation.get_set_test(3, "Configuration|Altitude Min", 38.0)

@ -9,9 +9,10 @@ import sys
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
import azlmbr.asset as asset
import azlmbr.components as components
import azlmbr.legacy.general as general
import azlmbr.bus as bus
import azlmbr.entity as EntityId
import azlmbr.entity as entity
import azlmbr.editor as editor
import azlmbr.math as math
import azlmbr.paths
@ -83,18 +84,12 @@ class TestDynamicSliceInstanceSpawnerEmbeddedEditor(EditorTestHelper):
self.log(f"Expected {num_expected_instances} instances - Found {num_found} instances")
self.test_success = self.test_success and num_found == num_expected_instances
# 5) Create a new entity with a Camera component for testing in the launcher
# 5) Move the default Camera entity for testing in the launcher
cam_position = math.Vector3(512.0, 500.0, 35.0)
camera_component = ["Camera"]
new_entity_id2 = editor.ToolsApplicationRequestBus(
bus.Broadcast, "CreateNewEntityAtPosition", cam_position, EntityId.EntityId()
)
if new_entity_id2.IsValid():
self.log("Camera entity created")
camera_entity = hydra.Entity("Camera Entity", new_entity_id2)
camera_entity.components = []
for component in camera_component:
camera_entity.components.append(hydra.add_component(component, new_entity_id2))
search_filter = entity.SearchFilter()
search_filter.names = ["Camera"]
search_entity_ids = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
components.TransformBus(bus.Event, "MoveEntity", search_entity_ids[0], cam_position)
# 6) Save and export to engine
general.save_level()

@ -11,7 +11,8 @@ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
import azlmbr.legacy.general as general
import azlmbr.asset as asset
import azlmbr.bus as bus
import azlmbr.entity as EntityId
import azlmbr.components as components
import azlmbr.entity as entity
import azlmbr.editor as editor
import azlmbr.math as math
import azlmbr.paths
@ -68,7 +69,7 @@ class TestDynamicSliceInstanceSpawnerExternalEditor(EditorTestHelper):
veg_area_required_components = ["Vegetation Layer Spawner", "Box Shape", "Vegetation Asset List",
"Script Canvas"]
new_entity_id = editor.ToolsApplicationRequestBus(
bus.Broadcast, "CreateNewEntityAtPosition", entity_position, EntityId.EntityId()
bus.Broadcast, "CreateNewEntityAtPosition", entity_position, entity.EntityId()
)
if new_entity_id.IsValid():
self.log("Spawner entity created")
@ -106,18 +107,12 @@ class TestDynamicSliceInstanceSpawnerExternalEditor(EditorTestHelper):
self.log(f"Expected {num_expected_instances} instances - Found {num_found} instances")
self.test_success = self.test_success and num_found == num_expected_instances
# 5) Create a new entity with a Camera component for testing in the launcher
entity_position = math.Vector3(512.0, 500.0, 35.0)
camera_component = ["Camera"]
new_entity_id2 = editor.ToolsApplicationRequestBus(
bus.Broadcast, "CreateNewEntityAtPosition", entity_position, EntityId.EntityId()
)
if new_entity_id2.IsValid():
self.log("Camera entity created")
camera_entity = hydra.Entity("Camera Entity", new_entity_id2)
camera_entity.components = []
for component in camera_component:
camera_entity.components.append(hydra.add_component(component, new_entity_id2))
# 5) Move the default Camera entity for testing in the launcher
cam_position = math.Vector3(512.0, 500.0, 35.0)
search_filter = entity.SearchFilter()
search_filter.names = ["Camera"]
search_entity_ids = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
components.TransformBus(bus.Event, "MoveEntity", search_entity_ids[0], cam_position)
# 6) Save and export to engine
general.save_level()

@ -18,9 +18,9 @@ import azlmbr.areasystem as areasystem
import azlmbr.legacy.general as general
import azlmbr
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.components as components
import azlmbr.math as math
import azlmbr.entity as EntityId
import azlmbr.entity as entity
import azlmbr.paths
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
@ -134,20 +134,14 @@ class TestVegLayerBlenderCreated(EditorTestHelper):
purple_count += 1
self.test_success = pink_count == purple_count and (pink_count + purple_count == num_expected) and self.test_success
# 5) Create a new entity with a Camera component for testing in the launcher
entity_position = math.Vector3(500.0, 500.0, 47.0)
rot_degrees_vector = math.Vector3(radians(-55.0), radians(28.5), radians(-17.0))
camera_component = ["Camera"]
camera_id = editor.ToolsApplicationRequestBus(
bus.Broadcast, "CreateNewEntityAtPosition", entity_position, EntityId.EntityId()
)
if camera_id.IsValid():
self.log("Camera entity created")
camera_entity = hydra.Entity("Camera Entity", camera_id)
camera_entity.components = []
for component in camera_component:
camera_entity.components.append(hydra.add_component(component, camera_id))
azlmbr.components.TransformBus(bus.Event, "SetLocalRotation", camera_id, rot_degrees_vector)
# 5) Move the default Camera entity for testing in the launcher
cam_position = math.Vector3(500.0, 500.0, 47.0)
cam_rot_degrees_vector = math.Vector3(radians(-55.0), radians(28.5), radians(-17.0))
search_filter = entity.SearchFilter()
search_filter.names = ["Camera"]
search_entity_ids = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
components.TransformBus(bus.Event, "MoveEntity", search_entity_ids[0], cam_position)
azlmbr.components.TransformBus(bus.Event, "SetLocalRotation", search_entity_ids[0], cam_rot_degrees_vector)
# 6) Save and export level
general.save_level()

@ -34,8 +34,8 @@ class TestLayerSpawnerFilterStageToggle(EditorTestHelper):
:return: None
"""
PREPROCESS_INSTANCE_COUNT = 425
POSTPROCESS_INSTANCE_COUNT = 430
PREPROCESS_INSTANCE_COUNT = 21
POSTPROCESS_INSTANCE_COUNT = 19
# Create empty level
self.test_success = self.create_level(
@ -56,7 +56,6 @@ class TestLayerSpawnerFilterStageToggle(EditorTestHelper):
vegetation_entity.add_component("Vegetation Altitude Filter")
vegetation_entity.add_component("Vegetation Position Modifier")
# Create a child entity under vegetation area
child_entity = hydra.Entity("child_entity")
components_to_add = ["Random Noise Gradient", "Gradient Transform Modifier", "Box Shape"]
@ -66,29 +65,13 @@ class TestLayerSpawnerFilterStageToggle(EditorTestHelper):
vegetation_entity.get_set_test(4, "Configuration|Position X|Gradient|Gradient Entity Id", child_entity.id)
vegetation_entity.get_set_test(4, "Configuration|Position Y|Gradient|Gradient Entity Id", child_entity.id)
# Set the min and max values for Altitude Filter
vegetation_entity.get_set_test(3, "Configuration|Altitude Min", 32.0)
vegetation_entity.get_set_test(3, "Configuration|Altitude Max", 35.0)
vegetation_entity.get_set_test(3, "Configuration|Altitude Min", 34.0)
vegetation_entity.get_set_test(3, "Configuration|Altitude Max", 38.0)
# Add entity with Mesh to replicate creation of hills and a flat surface to plant on
dynveg.create_surface_entity("Flat Surface", position, 32.0, 32.0, 1.0)
hill_entity = dynveg.create_mesh_surface_entity_with_slopes("hill", position, 4.0, 4.0, 4.0)
# Disable/Re-enable Mesh component due to ATOM-14299
general.idle_wait(1.0)
editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [hill_entity.components[0]])
is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', hill_entity.components[0])
if is_enabled:
print("Mesh component is still enabled")
else:
print("Mesh component was disabled")
editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [hill_entity.components[0]])
is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', hill_entity.components[0])
if is_enabled:
print("Mesh component is now enabled")
else:
print("Mesh component is still disabled")
hill_entity = dynveg.create_mesh_surface_entity_with_slopes("hill", position, 4.0)
# Set the filter stage to preprocess and postprocess respectively and verify instance count
vegetation_entity.get_set_test(0, "Configuration|Filter Stage", 1)

@ -13,7 +13,7 @@ import azlmbr.legacy.general as general
import azlmbr.math as math
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
from automatedtesting_shared.editor_test_helper import EditorTestHelper
from editor_python_test_tools.editor_test_helper import EditorTestHelper
from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg

@ -82,22 +82,7 @@ class test_MeshBlocker_InstancesBlockedByMesh(EditorTestHelper):
bus.Broadcast, "GetAssetIdByPath", os.path.join("objects", "_primitives", "_box_1x1.azmodel"), math.Uuid(),
False)
blocker_entity.get_set_test(1, "Controller|Configuration|Mesh Asset", cubeId)
components.TransformBus(bus.Event, "SetLocalScale", blocker_entity.id, math.Vector3(2.0, 2.0, 2.0))
# Disable/Re-enable Mesh component due to ATOM-14299
general.idle_wait(1.0)
editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [blocker_entity.components[1]])
is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', blocker_entity.components[1])
if is_enabled:
print("Mesh component is still enabled")
else:
print("Mesh component was disabled")
editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [blocker_entity.components[1]])
is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', blocker_entity.components[1])
if is_enabled:
print("Mesh component is now enabled")
else:
print("Mesh component is still disabled")
components.TransformBus(bus.Event, "SetLocalUniformScale", blocker_entity.id, 2.0)
# Verify spawned instance counts are accurate after addition of Blocker Entity
num_expected = 160 # Number of "PurpleFlower"s that plant on a 10 x 10 surface minus 2m blocker cube

@ -88,24 +88,9 @@ class test_MeshBlocker_InstancesBlockedByMeshHeightTuning(EditorTestHelper):
bus.Broadcast, "GetAssetIdByPath", os.path.join("objects", "_primitives", "_box_1x1.azmodel"), math.Uuid(),
False)
blocker_entity.get_set_test(1, "Controller|Configuration|Mesh Asset", sphere_id)
components.TransformBus(bus.Event, "SetLocalScale", blocker_entity.id, math.Vector3(5.0, 5.0, 5.0))
components.TransformBus(bus.Event, "SetLocalUniformScale", blocker_entity.id, 5.0)
components.TransformBus(bus.Event, "SetLocalRotation", blocker_entity.id, math.Vector3(0.0, y_rotation, 0.0))
# Disable/Re-enable Mesh component due to ATOM-14299
general.idle_wait(1.0)
editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [blocker_entity.components[1]])
is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', blocker_entity.components[1])
if is_enabled:
print("Mesh component is still enabled")
else:
print("Mesh component was disabled")
editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [blocker_entity.components[1]])
is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', blocker_entity.components[1])
if is_enabled:
print("Mesh component is now enabled")
else:
print("Mesh component is still disabled")
# 5) Adjust the height Max percentage values of blocker
blocker_entity.get_set_test(0, "Configuration|Mesh Height Percent Max", 0.8)

@ -90,7 +90,6 @@ class TestDynamicSliceInstanceSpawner(object):
@pytest.mark.SUITE_periodic
@pytest.mark.dynveg_area
@pytest.mark.parametrize("launcher_platform", ['windows'])
@pytest.mark.skip # ATOM-14703
def test_DynamicSliceInstanceSpawner_Embedded_E2E_Launcher(self, workspace, launcher, level,
remote_console_instance, project, launcher_platform):
@ -126,7 +125,6 @@ class TestDynamicSliceInstanceSpawner(object):
@pytest.mark.SUITE_periodic
@pytest.mark.dynveg_area
@pytest.mark.parametrize("launcher_platform", ['windows'])
@pytest.mark.skip # ATOM-14703
def test_DynamicSliceInstanceSpawner_External_E2E_Launcher(self, workspace, launcher, level,
remote_console_instance, project, launcher_platform):

@ -68,7 +68,6 @@ class TestLayerBlender(object):
"Entity has a Box Shape component",
"Blender Configuration|Vegetation Areas: SUCCESS",
"Blender Box Shape|Box Configuration|Dimensions: SUCCESS",
"Camera entity created",
"LayerBlender_E2E_Editor: result=SUCCESS"
]
@ -85,12 +84,11 @@ class TestLayerBlender(object):
@pytest.mark.BAT
@pytest.mark.SUITE_periodic
@pytest.mark.dynveg_area
@pytest.mark.xfail
@pytest.mark.parametrize("launcher_platform", ['windows'])
def test_LayerBlender_E2E_Launcher(self, workspace, project, launcher, level, remote_console_instance,
launcher_platform):
launcher.args.extend(["-NullRenderer"])
launcher.args.extend(["-rhi=Null"])
launcher.start()
assert launcher.is_alive(), "Launcher failed to start"

@ -121,7 +121,7 @@ class TestLayerSpawner(object):
@pytest.mark.test_case_id("C30000751")
@pytest.mark.SUITE_sandbox
@pytest.mark.dynveg_misc
@pytest.mark.skip # ATOM-14828
@pytest.mark.skip # https://github.com/o3de/o3de/issues/2038
def test_LayerSpawner_InstancesRefreshUsingCorrectViewportCamera(self, request, editor, level, launcher_platform):
expected_lines = [
@ -136,5 +136,6 @@ class TestLayerSpawner(object):
editor,
"LayerSpawner_InstancesRefreshUsingCorrectViewportCamera.py",
expected_lines,
cfg_args=[level]
cfg_args=[level],
null_renderer=False
)

@ -34,7 +34,7 @@ def create_surface_entity(name, center_point, box_size_x, box_size_y, box_size_z
return surface_entity
def create_mesh_surface_entity_with_slopes(name, center_point, scale_x, scale_y, scale_z):
def create_mesh_surface_entity_with_slopes(name, center_point, uniform_scale):
# Creates an entity with the assigned mesh_asset as the specified scale and sets up as a planting surface
mesh_asset_path = os.path.join("models", "sphere.azmodel")
mesh_asset = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", mesh_asset_path, math.Uuid(),
@ -47,7 +47,7 @@ def create_mesh_surface_entity_with_slopes(name, center_point, scale_x, scale_y,
if surface_entity.id.IsValid():
print(f"'{surface_entity.name}' created")
hydra.get_set_test(surface_entity, 0, "Controller|Configuration|Mesh Asset", mesh_asset)
components.TransformBus(bus.Event, "SetLocalScale", surface_entity.id, math.Vector3(scale_x, scale_y, scale_z))
components.TransformBus(bus.Event, "SetLocalUniformScale", surface_entity.id, uniform_scale)
return surface_entity

@ -5,6 +5,13 @@
#
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
include(${LY_ROOT_FOLDER}/Code/Tools/SerializeContextTools/Platform/${PAL_PLATFORM_NAME}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
if (PAL_TRAIT_BUILD_SERIALIZECONTEXTTOOLS)
list(APPEND additional_dependencies AZ::SerializeContextTools) # test_CLITool_SerializeContextTools depends on it
endif()
list(APPEND additional_dependencies AZ::AssetBundlerBatch) # test_CLITool_AssetBundlerBatch_Works depends on it
ly_add_pytest(
NAME AutomatedTesting::SmokeTest
TEST_SUITE smoke
@ -18,6 +25,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
Legacy::Editor
AutomatedTesting.GameLauncher
AutomatedTesting.Assets
${aditional_dependencies}
COMPONENT
Smoke
)

@ -742,14 +742,14 @@
</Class>
<Class name="int" field="methodType" value="2" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
<Class name="AZStd::string" field="methodName" value="GetOnPostsimulateEvent" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="className" value="System Interface" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="className" value="PhysicsSystemInterface" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::vector" field="namespaces" type="{99DAD0BC-740E-5E82-826B-8FC7968CC02C}"/>
<Class name="AZStd::vector" field="resultSlotIDs" type="{D0B13803-101B-54D8-914C-0DA49FDFA268}">
<Class name="SlotId" field="element" version="2" type="{14C629F6-467B-46FE-8B63-48FDFCA42175}">
<Class name="AZ::Uuid" field="m_id" value="{00000000-0000-0000-0000-000000000000}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
</Class>
</Class>
<Class name="AZStd::string" field="prettyClassName" value="System Interface" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="prettyClassName" value="PhysicsSystemInterface" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
</Class>
</Class>
<Class name="bool" field="IsDependencyReady" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>

@ -1045,14 +1045,14 @@
</Class>
<Class name="int" field="methodType" value="2" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
<Class name="AZStd::string" field="methodName" value="GetOnPostsimulateEvent" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="className" value="System Interface" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="className" value="PhysicsSystemInterface" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::vector" field="namespaces" type="{99DAD0BC-740E-5E82-826B-8FC7968CC02C}"/>
<Class name="AZStd::vector" field="resultSlotIDs" type="{D0B13803-101B-54D8-914C-0DA49FDFA268}">
<Class name="SlotId" field="element" version="2" type="{14C629F6-467B-46FE-8B63-48FDFCA42175}">
<Class name="AZ::Uuid" field="m_id" value="{00000000-0000-0000-0000-000000000000}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
</Class>
</Class>
<Class name="AZStd::string" field="prettyClassName" value="System Interface" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="prettyClassName" value="PhysicsSystemInterface" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
</Class>
</Class>
<Class name="bool" field="IsDependencyReady" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>

@ -1085,14 +1085,14 @@
</Class>
<Class name="int" field="methodType" value="2" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
<Class name="AZStd::string" field="methodName" value="GetOnPresimulateEvent" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="className" value="System Interface" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="className" value="PhysicsSystemInterface" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::vector" field="namespaces" type="{99DAD0BC-740E-5E82-826B-8FC7968CC02C}"/>
<Class name="AZStd::vector" field="resultSlotIDs" type="{D0B13803-101B-54D8-914C-0DA49FDFA268}">
<Class name="SlotId" field="element" version="2" type="{14C629F6-467B-46FE-8B63-48FDFCA42175}">
<Class name="AZ::Uuid" field="m_id" value="{00000000-0000-0000-0000-000000000000}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
</Class>
</Class>
<Class name="AZStd::string" field="prettyClassName" value="System Interface" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="prettyClassName" value="PhysicsSystemInterface" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
</Class>
</Class>
<Class name="bool" field="IsDependencyReady" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>

@ -497,9 +497,15 @@ void LevelEditorMenuHandler::PopulateEditMenu(ActionManager::MenuWrapper& editMe
// Hide Selection
editMenu.AddAction(AzToolsFramework::HideSelection);
// Unhide All
// Show All
editMenu.AddAction(AzToolsFramework::ShowAll);
// Lock Selection
editMenu.AddAction(AzToolsFramework::LockSelection);
// UnLock All
editMenu.AddAction(AzToolsFramework::UnlockAll);
/*
* The following block of code is part of the feature "Isolation Mode" and is temporarily
* disabled for 1.10 release.

@ -1896,7 +1896,7 @@ void EditorViewportWidget::SetViewTM(const Matrix34& viewTM, bool bMoveOnly)
if (m_pressedKeyState != KeyPressedState::PressedInPreviousFrame)
{
CUndo undo("Move Camera");
AzToolsFramework::ScopedUndoBatch undo("Move Camera");
if (bMoveOnly)
{
// specify eObjectUpdateFlags_UserInput so that an undo command gets logged
@ -1932,7 +1932,7 @@ void EditorViewportWidget::SetViewTM(const Matrix34& viewTM, bool bMoveOnly)
if (m_pressedKeyState != KeyPressedState::PressedInPreviousFrame)
{
CUndo undo("Move Camera");
AzToolsFramework::ScopedUndoBatch undo("Move Camera");
if (bMoveOnly)
{
AZ::TransformBus::Event(
@ -1945,6 +1945,8 @@ void EditorViewportWidget::SetViewTM(const Matrix34& viewTM, bool bMoveOnly)
m_viewEntityId, &AZ::TransformInterface::SetWorldTM,
LYTransformToAZTransform(camMatrix));
}
AzToolsFramework::ToolsApplicationRequestBus::Broadcast(&AzToolsFramework::ToolsApplicationRequests::AddDirtyEntity, m_viewEntityId);
}
else
{

@ -83,9 +83,9 @@ AZ::RPI::ViewportContextPtr LegacyViewportCameraControllerInstance::GetViewportC
}
bool LegacyViewportCameraControllerInstance::HandleMouseMove(
const AzFramework::ScreenPoint& currentMousePos, const AzFramework::ScreenPoint& previousMousePos)
int dx, int dy)
{
if (previousMousePos == currentMousePos)
if (dx == 0 && dy == 0)
{
return false;
}
@ -105,7 +105,7 @@ bool LegacyViewportCameraControllerInstance::HandleMouseMove(
if (m_inMoveMode || m_inOrbitMode || m_inRotateMode || m_inZoomMode)
{
m_totalMouseMoveDelta += (QPoint(currentMousePos.m_x, currentMousePos.m_y)-QPoint(previousMousePos.m_x, previousMousePos.m_y)).manhattanLength();
m_totalMouseMoveDelta += AZStd::abs(dx) + AZStd::abs(dy);
}
if ((m_inRotateMode && m_inMoveMode) || m_inZoomMode)
@ -115,7 +115,7 @@ bool LegacyViewportCameraControllerInstance::HandleMouseMove(
Vec3 ydir = m.GetColumn1().GetNormalized();
Vec3 pos = m.GetTranslation();
const float posDelta = 0.2f * (previousMousePos.m_y - currentMousePos.m_y) * speedScale;
const float posDelta = 0.2f * dy * speedScale;
pos = pos - ydir * posDelta;
m_orbitDistance = m_orbitDistance + posDelta;
m_orbitDistance = fabs(m_orbitDistance);
@ -126,7 +126,7 @@ bool LegacyViewportCameraControllerInstance::HandleMouseMove(
}
else if (m_inRotateMode)
{
Ang3 angles(-currentMousePos.m_y + previousMousePos.m_y, 0, -currentMousePos.m_x + previousMousePos.m_x);
Ang3 angles(dy, 0, dx);
angles = angles * 0.002f * gSettings.cameraRotateSpeed;
if (gSettings.invertYRotation)
{
@ -158,7 +158,7 @@ bool LegacyViewportCameraControllerInstance::HandleMouseMove(
}
Vec3 pos = m.GetTranslation();
pos += 0.1f * xdir * (currentMousePos.m_x - previousMousePos.m_x) * speedScale + 0.1f * zdir * (previousMousePos.m_y - currentMousePos.m_y) * speedScale;
pos += 0.1f * xdir * dx * speedScale + 0.1f * zdir * dy * speedScale;
m.SetTranslation(pos);
AZ::Transform transform = viewportContext->GetCameraTransform();
@ -168,7 +168,7 @@ bool LegacyViewportCameraControllerInstance::HandleMouseMove(
}
else if (m_inOrbitMode)
{
Ang3 angles(-currentMousePos.m_y + previousMousePos.m_y, 0, -currentMousePos.m_x + previousMousePos.m_x);
Ang3 angles(dy, 0, dx);
angles = angles * 0.002f * gSettings.cameraRotateSpeed;
if (gSettings.invertPan)
@ -302,20 +302,19 @@ bool LegacyViewportCameraControllerInstance::HandleInputChannelEvent(const AzFra
bool shouldCaptureCursor = m_capturingCursor;
bool shouldConsumeEvent = false;
if (id == AzFramework::InputDeviceMouse::SystemCursorPosition)
if (id == AzFramework::InputDeviceMouse::Movement::X || id == AzFramework::InputDeviceMouse::Movement::Y)
{
bool result = false;
AzToolsFramework::ViewportInteraction::ViewportMouseCursorRequestBus::Event(
GetViewportId(),
[this, &result](AzToolsFramework::ViewportInteraction::ViewportMouseCursorRequests* mouseRequests)
{
if (auto previousMousePosition = mouseRequests->PreviousViewportCursorScreenPosition();
previousMousePosition.has_value())
{
result = HandleMouseMove(mouseRequests->ViewportCursorScreenPosition(), previousMousePosition.value());
}
});
return result;
int dx = 0;
int dy = 0;
if (id == AzFramework::InputDeviceMouse::Movement::X)
{
dx = -aznumeric_cast<int>(event.m_inputChannel.GetValue());
}
else
{
dy = -aznumeric_cast<int>(event.m_inputChannel.GetValue());
}
return HandleMouseMove(dx, dy);
}
else if (id == MouseButton::Left)
{

@ -69,7 +69,7 @@ namespace SandboxEditor
AZ::RPI::ViewportContextPtr GetViewportContext();
bool HandleMouseMove(const AzFramework::ScreenPoint& currentMousePos, const AzFramework::ScreenPoint& previousMousePos);
bool HandleMouseMove(int dx, int dy);
bool HandleMouseWheel(float zDelta);
bool IsKeyDown(Qt::Key key) const;
void UpdateCursorCapture(bool shouldCaptureCursor);

@ -5,7 +5,7 @@
<key>CFBundleExecutable</key>
<string>Editor</string>
<key>CFBundleIdentifier</key>
<string>com.Amazon.Lumberyard.Editor</string>
<string>org.O3DE.Editor</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>

@ -46,4 +46,8 @@ ly_add_target(
AZ::AzCore
AZ::AzToolsFramework
AZ::AzQtComponents
RUNTIME_DEPENDENCIES
AZ::AzCore
AZ::AzToolsFramework
AZ::AzQtComponents
)

@ -20,12 +20,12 @@
#include "ValidationHandler.h"
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/IO/Path/Path.h>
#include "AzToolsFramework/UI/PropertyEditor/InstanceDataHierarchy.h"
#include <AzToolsFramework/UI/PropertyEditor/InstanceDataHierarchy.h>
#include <AzToolsFramework/UI/PropertyEditor/PropertyManagerComponent.h>
#include <AzToolsFramework/UI/PropertyEditor/ReflectedPropertyEditor.hxx>
#include <AzToolsFramework/UI/UICore/WidgetHelpers.h>
#include <Util/FileUtil.h>
#include <QMessageBox>
#include <QCloseEvent>
@ -52,7 +52,7 @@ namespace ProjectSettingsTool
PlatformEnabled(PlatformId::Ios) ?
ProjectSettingsContainer::PlistInitVector({
ProjectSettingsContainer::PlatformAndPath
{ PlatformId::Ios, m_projectRoot + PlatformResourcesFolder(PlatformId::Ios) }
{ PlatformId::Ios, GetPlatformResource(PlatformId::Ios) }
})
:
ProjectSettingsContainer::PlistInitVector())
@ -647,33 +647,38 @@ namespace ProjectSettingsTool
// iOS can be disabled if the plist file is missing
if (platformId == PlatformId::Ios)
{
const AZStd::string filename = m_projectRoot + PlatformResourcesFolder(platformId);
return CFileUtil::FileExists(filename.c_str());
AZStd::string plistPath = GetPlatformResource(platformId);
return !plistPath.empty();
}
return true;
}
const char* ProjectSettingsToolWindow::PlatformResourcesFolder(PlatformId platformId)
AZStd::string ProjectSettingsToolWindow::GetPlatformResource(PlatformId platformId)
{
if (platformId == PlatformId::Ios)
{
const AZStd::string firstfilename = m_projectRoot + "/Gem/Resources/Platform/iOS/Info.plist";
if (CFileUtil::FileExists(firstfilename.c_str()))
{
return "/Gem/Resources/Platform/iOS/Info.plist";
}
else
const char* searchPaths[] = {
"Resources/Platform/iOS/Info.plist",
// legacy paths
"Gem/Resources/Platform/iOS/Info.plist",
"Gem/Resources/IOSLauncher/Info.plist",
};
for (auto relPath : searchPaths)
{
const AZStd::string filename = m_projectRoot + "/Gem/Resources/IOSLauncher/Info.plist";
if (CFileUtil::FileExists(filename.c_str()))
AZ::IO::FixedMaxPath projectPlist{ m_projectRoot };
projectPlist /= relPath;
if (AZ::IO::SystemFile::Exists(projectPlist.c_str()))
{
return "/Gem/Resources/IOSLauncher/Info.plist";
return projectPlist.LexicallyNormal().String();
}
}
}
return nullptr;
return AZStd::string();
}
#include <moc_ProjectSettingsToolWindow.cpp>

@ -137,8 +137,8 @@ namespace ProjectSettingsTool
// returns true if the platform is enabled
bool PlatformEnabled(PlatformId platformId);
// returns the resource folder
const char* PlatformResourcesFolder(PlatformId platformId);
// returns the main platform specific resource file e.g. for iOS it would be the Info.plist
AZStd::string GetPlatformResource(PlatformId platformId);
// The ui for the window
QScopedPointer<Ui::ProjectSettingsToolWidget> m_ui;

@ -116,7 +116,7 @@ namespace AZ
{
const char* uuidString = nullptr;
unsigned int uuidStringLength = 0;
if (dc.ReadArg(0, uuidString) && dc.ReadValue(1, uuidStringLength))
if (dc.ReadArg(0, uuidString) && dc.ReadArg(1, uuidStringLength))
{
dc.PushResult(Uuid(uuidString, uuidStringLength));
}

@ -157,8 +157,11 @@ ScriptContextDebug::EnumRegisteredClasses(EnumClass enumClass, EnumMethod enumMe
lua_pop(l, 2); // pop the Class name and behaviorClass
lua_pushnil(l);
// iterate over the key/value pairs
while (lua_next(l, -2) != 0)
{
// if key: string value: function
if (lua_isstring(l, -2) && lua_isfunction(l, -1))
{
const char* name = lua_tostring(l, -2);
@ -167,6 +170,7 @@ ScriptContextDebug::EnumRegisteredClasses(EnumClass enumClass, EnumMethod enumMe
bool isRead = true;
bool isWrite = true;
// check if there is a getter provided
lua_getupvalue(l, -1, 1);
if (lua_isnil(l, -1))
{
@ -174,6 +178,7 @@ ScriptContextDebug::EnumRegisteredClasses(EnumClass enumClass, EnumMethod enumMe
}
lua_pop(l, 1);
// check if there is a setter provided
lua_getupvalue(l, -1, 2);
if (lua_isnil(l, -1))
{
@ -181,6 +186,7 @@ ScriptContextDebug::EnumRegisteredClasses(EnumClass enumClass, EnumMethod enumMe
}
lua_pop(l, 1);
// enumerate the remaining property
if (!enumProperty(&behaviorClass->m_typeId, name, isRead, isWrite, userData))
{
lua_pop(l, 5);
@ -189,21 +195,30 @@ ScriptContextDebug::EnumRegisteredClasses(EnumClass enumClass, EnumMethod enumMe
}
else
{
// for any non-built in methods
if (strncmp(name, "__", 2) != 0)
{
const char* dbgParamInfo = NULL;
lua_getupvalue(l, -1, 2);
// attempt to get the name
bool popDebugName = lua_getupvalue(l, -1, 2) != nullptr;
if (lua_isstring(l, -1))
{
dbgParamInfo = lua_tostring(l, -1);
}
// enumerate the method's parameters
if (!enumMethod(&behaviorClass->m_typeId, name, dbgParamInfo, userData))
{
lua_pop(l, 6);
return;
}
lua_pop(l, 1); // pop the DBG name
// if we were able to get the name, pop it from the stack
if (popDebugName)
{
lua_pop(l, 1);
}
}
}
}

@ -7,9 +7,9 @@
*/
#include <AZTestShared/Utils/Utils.h>
#include "AzCore/Component/Entity.h"
#include "AzCore/Asset/AssetManager.h"
#include "AzCore/Slice/SliceComponent.h"
#include <AzCore/Component/Entity.h>
#include <AzCore/Asset/AssetManager.h>
#include <AzCore/Slice/SliceComponent.h>
namespace UnitTest
{

@ -6,6 +6,7 @@
*/
#include <AzCore/Math/Vector3.h>
#include <AzCore/Serialization/Json/JsonSerializationSettings.h>
#include <AzCore/std/string/string_view.h>
#include <Tests/Serialization/Json/JsonSerializationTests.h>
@ -43,7 +44,9 @@ namespace JsonSerializationTests
}
void CheckApplyPatchOutcome(const char* target, const char* patch,
AZ::JsonSerializationResult::Outcomes outcome, AZ::JsonSerializationResult::Processing processing)
AZ::JsonSerializationResult::Outcomes outcome,
AZ::JsonSerializationResult::Processing processing,
const AZ::JsonApplyPatchSettings& settings = AZ::JsonApplyPatchSettings{})
{
m_jsonDocument->Parse(target);
ASSERT_FALSE(m_jsonDocument->HasParseError());
@ -53,12 +56,24 @@ namespace JsonSerializationTests
ASSERT_FALSE(patchDocument.HasParseError());
AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::ApplyPatch(*m_jsonDocument,
m_jsonDocument->GetAllocator(), patchDocument, AZ::JsonMergeApproach::JsonPatch);
m_jsonDocument->GetAllocator(), patchDocument, AZ::JsonMergeApproach::JsonPatch, settings);
EXPECT_EQ(result.GetTask(), AZ::JsonSerializationResult::Tasks::Merge);
EXPECT_EQ(result.GetOutcome(), outcome);
EXPECT_EQ(result.GetProcessing(), processing);
}
void CheckApplyPatchOutcome(
const char* target,
const char* patch,
const char* expectedPatchedResult,
AZ::JsonSerializationResult::Outcomes outcome,
AZ::JsonSerializationResult::Processing processing,
const AZ::JsonApplyPatchSettings& settings = AZ::JsonApplyPatchSettings{})
{
CheckApplyPatchOutcome(target, patch, outcome, processing, settings);
Expect_DocStrEq(expectedPatchedResult);
}
void CheckCreatePatch_Core(const char* source, AZStd::string_view patch, const char* target,
AZ::JsonMergeApproach approach)
{
@ -262,6 +277,36 @@ namespace JsonSerializationTests
Outcomes::TypeMismatch, Processing::Halted);
}
TEST_F(JsonPatchingSerializationTests, ApplyPatch_UseJsonPatchWithCustomReportingCallback_ReportPartialSkip)
{
using namespace AZ::JsonSerializationResult;
auto issueReportingCallback = [](AZStd::string_view, AZ::JsonSerializationResult::ResultCode result,
AZStd::string_view) -> AZ::JsonSerializationResult::ResultCode
{
using namespace AZ::JsonSerializationResult;
if (result.GetProcessing() == Processing::Halted)
{
return ResultCode(result.GetTask(), Outcomes::PartialSkip);
}
return result;
};
AZ::JsonApplyPatchSettings applyPatchSettings;
applyPatchSettings.m_reporting = AZStd::move(issueReportingCallback);
CheckApplyPatchOutcome(
R"({})",
R"([
{ "op": "add", "path": "/nonexistent_key/new_member", "value": "someValue" },
{ "op": "add", "path": "/test", "value": "someValue" }
])",
R"(
{ "test": "someValue" }
)",
Outcomes::PartialSkip,
Processing::Completed,
AZStd::move(applyPatchSettings));
}
TEST_F(JsonPatchingSerializationTests, ApplyPatch_UseJsonPatchAddUnnamedMember_ReportsSuccess)
{
CheckApplyPatch(

@ -279,14 +279,11 @@ namespace AZ
return SystemFile::Exists(resolvedPath);
}
void LocalFileIO::CheckInvalidWrite(const char* path)
void LocalFileIO::CheckInvalidWrite([[maybe_unused]] const char* path)
{
(void)path;
#if defined(AZ_ENABLE_TRACING)
const char* assetsAlias = GetAlias("@assets@");
if (((path) && (assetsAlias) && (azstrnicmp(path, assetsAlias, strlen(assetsAlias)) == 0)))
if (path && assetsAlias && AZ::IO::PathView(path).IsRelativeTo(assetsAlias))
{
AZ_Error("FileIO", false, "You may not alter data inside the asset cache. Please check the call stack and consider writing into the source asset folder instead.\n"
"Attempted write location: %s", path);

@ -205,6 +205,25 @@ namespace AzFramework
class InputDeviceImplementationRequest : public AZ::EBusTraits
{
public:
////////////////////////////////////////////////////////////////////////////////////////////
//! EBus Trait: requests can be addressed to a specific InputDeviceId so that they are only
//! handled by one input device that has connected to the bus using that unique id, or they
//! can be broadcast to all input devices that have connected to the bus, regardless of id.
//! Connected input devices are ordered by their local player index from lowest to highest.
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ByIdAndOrdered;
////////////////////////////////////////////////////////////////////////////////////////////
//! EBus Trait: requests should be handled by only one input device connected to each id
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
////////////////////////////////////////////////////////////////////////////////////////////
//! EBus Trait: requests can be addressed to a specific InputDeviceId
using BusIdType = InputDeviceId;
////////////////////////////////////////////////////////////////////////////////////////////
//! EBus Trait: requests are handled by connected devices in the order of local player index
using BusIdOrderCompare = AZStd::less<BusIdType>;
////////////////////////////////////////////////////////////////////////////////////////////
//! Alias for the EBus implementation of this interface
using Bus = AZ::EBus<InputDeviceImplementationRequest<InputDeviceType>>;
@ -214,11 +233,12 @@ namespace AzFramework
using CreateFunctionType = typename InputDeviceType::Implementation*(*)(InputDeviceType&);
////////////////////////////////////////////////////////////////////////////////////////////
//! Create a custom implementation for all the existing instances of this input device type.
//! Set a custom implementation for this input device type, either for a specific instance
//! by addressing the call to an InputDeviceId, or for all existing instances by broadcast.
//! Passing InputDeviceType::Implementation::Create as the argument will create the default
//! device implementation, while passing nullptr will delete any existing implementation.
//! \param[in] createFunction Pointer to the function that will create the implementation.
virtual void CreateCustomImplementation(CreateFunctionType createFunction) = 0;
virtual void SetCustomImplementation(CreateFunctionType createFunction) = 0;
};
////////////////////////////////////////////////////////////////////////////////////////////////
@ -238,7 +258,7 @@ namespace AzFramework
AZ_INLINE InputDeviceImplementationRequestHandler(InputDeviceType& inputDevice)
: m_inputDevice(inputDevice)
{
InputDeviceImplementationRequest<InputDeviceType>::Bus::Handler::BusConnect();
InputDeviceImplementationRequest<InputDeviceType>::Bus::Handler::BusConnect(m_inputDevice.GetInputDeviceId());
}
////////////////////////////////////////////////////////////////////////////////////////////
@ -251,8 +271,8 @@ namespace AzFramework
using CreateFunctionType = typename InputDeviceType::Implementation*(*)(InputDeviceType&);
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref InputDeviceImplementationRequest<InputDeviceType>::CreateCustomImplementation
AZ_INLINE void CreateCustomImplementation(CreateFunctionType createFunction) override
//! \ref InputDeviceImplementationRequest<InputDeviceType>::SetCustomImplementation
AZ_INLINE void SetCustomImplementation(CreateFunctionType createFunction) override
{
AZStd::unique_ptr<typename InputDeviceType::Implementation> newImplementation;
if (createFunction)

@ -97,6 +97,9 @@ namespace AzFramework
//! This is called when the window is deactivated from code or if the user closes the window.
virtual void OnWindowClosed() {};
//! This is called when vsync interval is changed.
virtual void OnVsyncIntervalChanged(uint32_t interval) { AZ_UNUSED(interval); };
};
using WindowNotificationBus = AZ::EBus<WindowNotifications>;

@ -52,3 +52,63 @@ ly_add_source_properties(
PROPERTY COMPILE_DEFINITIONS
VALUES TOUCHBENDING_LAYER_BIT=${LY_TOUCHBENDING_LAYER_BIT}
)
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Tests/Platform/${PAL_PLATFORM_NAME})
ly_add_target(
NAME AzFrameworkTestShared STATIC
NAMESPACE AZ
FILES_CMAKE
Tests/framework_shared_tests_files.cmake
INCLUDE_DIRECTORIES
PUBLIC
Tests
BUILD_DEPENDENCIES
PRIVATE
AZ::AzCore
AZ::AzFramework
)
if(PAL_TRAIT_BUILD_HOST_TOOLS)
ly_add_target(
NAME ProcessLaunchTest EXECUTABLE
NAMESPACE AZ
FILES_CMAKE
Tests/process_launch_test_files.cmake
INCLUDE_DIRECTORIES
PRIVATE
Tests
BUILD_DEPENDENCIES
PRIVATE
AZ::AzCore
AZ::AzFramework
)
ly_add_target(
NAME AzFramework.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
NAMESPACE AZ
FILES_CMAKE
Tests/frameworktests_files.cmake
INCLUDE_DIRECTORIES
PRIVATE
Tests
${pal_dir}
BUILD_DEPENDENCIES
PRIVATE
AZ::AzFramework
AZ::AzTest
AZ::AzTestShared
AZ::AzFrameworkTestShared
RUNTIME_DEPENDENCIES
AZ::ProcessLaunchTest
)
ly_add_googletest(
NAME AZ::AzFramework.Tests
)
endif()
endif()

@ -15,16 +15,16 @@ namespace UnitTest
{
using namespace AZ;
class SetRestoreFileIOBaseRAII
class FileIOBaseRAII
{
public:
SetRestoreFileIOBaseRAII(AZ::IO::FileIOBase& fileIO)
FileIOBaseRAII(AZ::IO::FileIOBase& fileIO)
: m_prevFileIO(AZ::IO::FileIOBase::GetInstance())
{
AZ::IO::FileIOBase::SetInstance(&fileIO);
}
~SetRestoreFileIOBaseRAII()
~FileIOBaseRAII()
{
AZ::IO::FileIOBase::SetInstance(m_prevFileIO);
}
@ -102,7 +102,7 @@ namespace UnitTest
TEST_F(GenAppDescriptors, Test)
{
AZ::IO::LocalFileIO fileIO;
SetRestoreFileIOBaseRAII restoreFileIOScope(fileIO);
FileIOBaseRAII restoreFileIOScope(fileIO);
run();
}
}

@ -9,7 +9,6 @@
AZ_PUSH_DISABLE_WARNING(, "-Wdelete-non-virtual-dtor")
#include <FrameworkApplicationFixture.h>
#include <AzCore/Component/ComponentApplication.h>
#include <AzCore/Component/Entity.h>
#include <AzCore/Component/Component.h>

@ -9,4 +9,5 @@ set(FILES
Mocks/MockSpawnableEntitiesInterface.h
Utils/Utils.h
Utils/Utils.cpp
FrameworkApplicationFixture.h
)

@ -6,44 +6,28 @@
#
set(FILES
../AzCore/Tests/Main.cpp
../../AzCore/Tests/Main.cpp
Spawnable/SpawnableEntitiesManagerTests.cpp
ArchiveCompressionTests.cpp
ArchiveTests.cpp
BehaviorEntityTests.cpp
BinToTextEncode.cpp
ComponentAddRemove.cpp
ComponentAdapterTests.cpp
CameraInputTests.cpp
ClickDetectorTests.cpp
CursorStateTests.cpp
EntityContext.cpp
EntityTestbed.h
FileFunc.cpp
FileIO.cpp
FileTagTests.cpp
FrameworkApplicationFixture.h
GenAppDescriptors.cpp
GenericComponentWrapperTest.cpp
InstanceDataHierarchy.cpp
OctreePerformanceTests.cpp
OctreeTests.cpp
Slices.cpp
Script/ScriptComponentTests.cpp
Script/ScriptEntityTests.cpp
AssetCatalog.cpp
AssetProcessorConnection.cpp
NativeWindow.cpp
TransformComponent.cpp
SQLiteConnectionTests.cpp
ProcessLaunchParseTests.cpp
Application.cpp
PlatformHelper.cpp
Scene.cpp
EntityOwnershipService/EntityOwnershipServiceTestFixture.h
EntityOwnershipService/EntityOwnershipServiceTestFixture.cpp
EntityOwnershipService/SliceEditorEntityOwnershipTests.cpp
EntityOwnershipService/SliceEntityOwnershipTests.cpp
CameraState.cpp
InputTests.cpp
)

@ -41,7 +41,7 @@ namespace AzNetworking
void TcpSocketManager::ProcessEvents(AZ::TimeMs maxBlockMs, const SocketEventCallback& readCallback, const SocketEventCallback& writeCallback)
{
if(static_cast<int32_t>(m_maxFd) <= 0 && m_socketFds.empty())
if(static_cast<int32_t>(m_maxFd) <= 0 || m_socketFds.empty())
{
// There are no available sockets to process
return;

@ -63,6 +63,9 @@ namespace AzToolsFramework
//! Signal the Python handler to stop
virtual bool StopPython(bool silenceWarnings = false) = 0;
//! Query to determine if the Python VM has been initialized indicating an active state
virtual bool IsPythonActive() = 0;
//! Determines if the caller needs to wait for the Python VM to initialize (non-main thread only)
virtual void WaitForInitialization() {}

@ -11,6 +11,7 @@
#include <AzFramework/Input/Buses/Notifications/InputChannelNotificationBus.h>
#include <AzFramework/Input/Buses/Requests/InputChannelRequestBus.h>
#include <AzQtComponents/Utilities/QtWindowUtilities.h>
#include <QApplication>
#include <QCursor>
@ -187,12 +188,6 @@ namespace AzToolsFramework
bool QtEventToAzInputMapper::HandlesInputEvent(const AzFramework::InputChannel& channel) const
{
const AzFramework::InputChannelId& channelId = channel.GetInputChannelId();
if (channelId == AzFramework::InputDeviceMouse::Movement::X || channelId == AzFramework::InputDeviceMouse::Movement::Y)
{
return false;
}
// We map keyboard and mouse events from Qt, so flag all events coming from those devices
// as handled by our synthetic event system.
const AzFramework::InputDeviceId& deviceId = channel.GetInputDevice().GetInputDeviceId();
@ -210,6 +205,22 @@ namespace AzToolsFramework
}
}
void QtEventToAzInputMapper::SetCursorCaptureEnabled(bool enabled)
{
if (m_capturingCursor != enabled)
{
m_capturingCursor = enabled;
if (m_capturingCursor)
{
qApp->setOverrideCursor(Qt::BlankCursor);
}
else
{
qApp->restoreOverrideCursor();
}
}
}
bool QtEventToAzInputMapper::eventFilter(QObject* object, QEvent* event)
{
// Abort if processing isn't enabled.
@ -284,13 +295,25 @@ namespace AzToolsFramework
{
auto systemCursorChannel =
GetInputChannel<AzFramework::InputChannelDeltaWithSharedPosition2D>(AzFramework::InputDeviceMouse::SystemCursorPosition);
auto movementXChannel =
GetInputChannel<AzFramework::InputChannelDeltaWithSharedPosition2D>(AzFramework::InputDeviceMouse::Movement::X);
auto movementYChannel =
GetInputChannel<AzFramework::InputChannelDeltaWithSharedPosition2D>(AzFramework::InputDeviceMouse::Movement::Y);
auto mouseWheelChannel =
GetInputChannel<AzFramework::InputChannelDeltaWithSharedPosition2D>(AzFramework::InputDeviceMouse::Movement::Z);
systemCursorChannel->ProcessRawInputEvent(m_cursorPosition->m_normalizedPositionDelta.GetLength());
// Generate movement events based on the pixel delta divided by the DPI scaling factor, to calculate a rough approximation
// of cursor movement velocity.
movementXChannel->ProcessRawInputEvent(
m_cursorPosition->m_normalizedPositionDelta.GetX() * aznumeric_cast<float>(m_sourceWidget->width()) / m_sourceWidget->devicePixelRatioF());
movementYChannel->ProcessRawInputEvent(
m_cursorPosition->m_normalizedPositionDelta.GetY() * aznumeric_cast<float>(m_sourceWidget->height()) / m_sourceWidget->devicePixelRatioF());
mouseWheelChannel->ProcessRawInputEvent(0.f);
NotifyUpdateChannelIfNotIdle(systemCursorChannel, nullptr);
NotifyUpdateChannelIfNotIdle(movementXChannel, nullptr);
NotifyUpdateChannelIfNotIdle(movementYChannel, nullptr);
NotifyUpdateChannelIfNotIdle(mouseWheelChannel, nullptr);
}
@ -318,16 +341,42 @@ namespace AzToolsFramework
}
}
AZ::Vector2 QtEventToAzInputMapper::WidgetPositionToNormalizedPosition(QPoint position)
{
const float normalizedX = aznumeric_cast<float>(position.x()) / aznumeric_cast<float>(m_sourceWidget->width());
const float normalizedY = aznumeric_cast<float>(position.y()) / aznumeric_cast<float>(m_sourceWidget->height());
return AZ::Vector2{normalizedX, normalizedY};
}
QPoint QtEventToAzInputMapper::NormalizedPositionToWidgetPosition(AZ::Vector2 normalizedPosition)
{
const int denormalizedX = aznumeric_cast<int>(normalizedPosition.GetX() * m_sourceWidget->width());
const int denormalizedY = aznumeric_cast<int>(normalizedPosition.GetY() * m_sourceWidget->height());
return QPoint{denormalizedX, denormalizedY};
}
void QtEventToAzInputMapper::HandleMouseMoveEvent(QMouseEvent* mouseEvent)
{
AZ::Vector2 lastCursorPosition = m_cursorPosition->m_normalizedPosition;
const QPoint mousePos = mouseEvent->pos();
const float normalizedX = aznumeric_cast<float>(mousePos.x()) / aznumeric_cast<float>(m_sourceWidget->width());
const float normalizedY = aznumeric_cast<float>(mousePos.y()) / aznumeric_cast<float>(m_sourceWidget->height());
const AZ::Vector2 normalizedPosition(normalizedX, normalizedY);
const AZ::Vector2 normalizedPosition = WidgetPositionToNormalizedPosition(mousePos);
m_cursorPosition->m_normalizedPositionDelta = normalizedPosition - m_cursorPosition->m_normalizedPosition;
m_cursorPosition->m_normalizedPosition = normalizedPosition;
ProcessPendingMouseEvents();
m_mouseChannelsNeedUpdate = true;
if (m_capturingCursor)
{
// Reset our cursor position to the previous point.
QPoint targetScreenPosition = m_sourceWidget->mapToGlobal(NormalizedPositionToWidgetPosition(lastCursorPosition));
AzQtComponents::SetCursorPos(targetScreenPosition);
// Even though we just set the cursor position, there are edge cases such as remote desktop that will leave
// the cursor position unchanged. For safety, we re-cache our last cursor position for delta generation.
QPoint actualWidgetPosition = m_sourceWidget->mapFromGlobal(QCursor::pos());
m_cursorPosition->m_normalizedPosition = WidgetPositionToNormalizedPosition(actualWidgetPosition);
}
}
void QtEventToAzInputMapper::HandleKeyEvent(QKeyEvent* keyEvent)

@ -47,6 +47,12 @@ namespace AzToolsFramework
//! Sets whether or not this input mapper should be updating its input channels from Qt events.
void SetEnabled(bool enabled);
//! Sets whether or not the cursor should be constrained to the source widget and invisible.
//! Internally, this will reset the cursor position after each move event to ensure movement
//! events don't allow the cursor to escape. This can be used for typical camera controls
//! like a dolly or rotation, where mouse movement is important but cursor location is not.
void SetCursorCaptureEnabled(bool enabled);
// QObject overrides...
bool eventFilter(QObject* object, QEvent* event) override;
@ -106,6 +112,11 @@ namespace AzToolsFramework
// Processes any pending mouse movement events, this allows mouse movement channels to close themselves.
void ProcessPendingMouseEvents();
// Converts a point in logical source widget space [0..m_sourceWidget->size()] to normalized [0..1] space.
AZ::Vector2 WidgetPositionToNormalizedPosition(QPoint position);
// Converts a point in normalized [0..1] space to logical source widget space [0..m_sourceWidget->size()].
QPoint NormalizedPositionToWidgetPosition(AZ::Vector2 normalizedPosition);
// Handle mouse click events.
void HandleMouseButtonEvent(QMouseEvent* mouseEvent);
// Handle mouse move events.
@ -144,6 +155,8 @@ namespace AzToolsFramework
bool m_mouseChannelsNeedUpdate = false;
// Flags whether or not Qt events should currently be processed.
bool m_enabled = true;
// Flags whether or not the cursor is being constrained to the source widget (for invisible mouse movement).
bool m_capturingCursor = false;
// Our viewport-specific AZ devices. We control their internal input channel states.
AZStd::unique_ptr<EditorQtMouseDevice> m_mouseDevice;

@ -172,20 +172,23 @@ namespace AzToolsFramework
PrefabDom& templateDomReference = m_prefabSystemComponentInterface->FindTemplateDom(templateId);
//apply patch to template
AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::ApplyPatch(templateDomReference,
templateDomReference.GetAllocator(), providedPatch, AZ::JsonMergeApproach::JsonPatch);
AZ::JsonSerializationResult::ResultCode result =
PrefabDomUtils::ApplyPatches(templateDomReference, templateDomReference.GetAllocator(), providedPatch);
//trigger propagation
if (result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success)
if (result.GetOutcome() != AZ::JsonSerializationResult::Outcomes::Success)
{
m_prefabSystemComponentInterface->SetTemplateDirtyFlag(templateId, true);
m_prefabSystemComponentInterface->PropagateTemplateChanges(templateId, instanceToExclude);
return true;
AZ_Error("Prefab", false, "Patch was not successfully applied.");
return false;
}
else
{
AZ_Error("Prefab", false, "Patch was not successfully applied");
return false;
AZ_Error(
"Prefab", result.GetOutcome() != AZ::JsonSerializationResult::Outcomes::PartialSkip,
"Some of the patches are not successfully applied.");
m_prefabSystemComponentInterface->SetTemplateDirtyFlag(templateId, true);
m_prefabSystemComponentInterface->PropagateTemplateChanges(templateId, instanceToExclude);
return true;
}
}

@ -176,12 +176,17 @@ namespace AzToolsFramework
}
else
{
AZ::JsonSerializationResult::ResultCode applyPatchResult = AZ::JsonSerialization::ApplyPatch(
sourceTemplateDomCopy,
targetTemplatePrefabDom.GetAllocator(),
patchesReference->get(),
AZ::JsonMergeApproach::JsonPatch);
AZ::JsonSerializationResult::ResultCode applyPatchResult =
PrefabDomUtils::ApplyPatches(sourceTemplateDomCopy, targetTemplatePrefabDom.GetAllocator(), patchesReference->get());
linkedInstanceDom.CopyFrom(sourceTemplateDomCopy, targetTemplatePrefabDom.GetAllocator());
PrefabDomValueReference sourceTemplateName =
PrefabDomUtils::FindPrefabDomValue(sourceTemplateDomCopy, PrefabDomUtils::SourceName);
AZ_Assert(sourceTemplateName && sourceTemplateName->get().IsString(), "A valid source template name couldn't be found");
PrefabDomValueReference targetTemplateName =
PrefabDomUtils::FindPrefabDomValue(targetTemplatePrefabDom, PrefabDomUtils::SourceName);
AZ_Assert(targetTemplateName && targetTemplateName->get().IsString(), "A valid target template name couldn't be found");
if (applyPatchResult.GetProcessing() != AZ::JsonSerializationResult::Processing::Completed)
{
AZ_Error(
@ -190,6 +195,14 @@ namespace AzToolsFramework
m_sourceTemplateId, m_targetTemplateId);
return false;
}
if (applyPatchResult.GetOutcome() == AZ::JsonSerializationResult::Outcomes::PartialSkip)
{
AZ_Error(
"Prefab", false,
"Link::UpdateTarget - Some of the patches couldn't be applied on the source template '%s' present under the "
"target Template '%s'.",
sourceTemplateName->get().GetString(), targetTemplateName->get().GetString());
}
}
// This is a guardrail to ensure the linked instance dom always has the LinkId value

@ -236,6 +236,26 @@ namespace AzToolsFramework
return findInstancesResult->get();
}
AZ::JsonSerializationResult::ResultCode ApplyPatches(
PrefabDomValue& prefabDomToApplyPatchesOn, PrefabDom::AllocatorType& allocator, const PrefabDomValue& patches)
{
auto issueReportingCallback = [](AZStd::string_view, AZ::JsonSerializationResult::ResultCode result,
AZStd::string_view) -> AZ::JsonSerializationResult::ResultCode
{
using namespace AZ::JsonSerializationResult;
if (result.GetProcessing() == Processing::Halted)
{
return ResultCode(result.GetTask(), Outcomes::PartialSkip);
}
return result;
};
AZ::JsonApplyPatchSettings applyPatchSettings;
applyPatchSettings.m_reporting = AZStd::move(issueReportingCallback);
return AZ::JsonSerialization::ApplyPatch(
prefabDomToApplyPatchesOn, allocator, patches, AZ::JsonMergeApproach::JsonPatch, applyPatchSettings);
}
void PrintPrefabDomValue(
[[maybe_unused]] const AZStd::string_view printMessage,
[[maybe_unused]] const PrefabDomValue& prefabDomValue)

@ -7,6 +7,7 @@
#pragma once
#include <AzCore/Serialization/Json/JsonSerializationResult.h>
#include <AzCore/std/optional.h>
#include <AzCore/Asset/AssetCommon.h>
#include <AzToolsFramework/Prefab/Instance/Instance.h>
@ -122,6 +123,11 @@ namespace AzToolsFramework
*/
PrefabDomValueConstReference GetInstancesValue(const PrefabDomValue& prefabDom);
AZ::JsonSerializationResult::ResultCode ApplyPatches(
PrefabDomValue& prefabDomToApplyPatchesOn,
PrefabDom::AllocatorType& allocator,
const PrefabDomValue& patches);
/**
* Prints the contents of the given prefab DOM value to the debug output console in a readable format.
* @param printMessage The message that will be printed before printing the PrefabDomValue

@ -261,8 +261,13 @@ namespace AzToolsFramework
instanceDom.CopyFrom(instanceDomRef->get(), instanceDom.GetAllocator());
//apply the patch to the template within the target
AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::ApplyPatch(instanceDom,
instanceDom.GetAllocator(), patch, AZ::JsonMergeApproach::JsonPatch);
AZ::JsonSerializationResult::ResultCode result = PrefabDomUtils::ApplyPatches(instanceDom, instanceDom.GetAllocator(), patch);
AZ_Error(
"Prefab",
result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::PartialSkip ||
result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success,
"Some of the patches are not successfully applied.");
//remove the link id placed into the instance
auto linkIdIter = instanceDom.FindMember(PrefabDomUtils::LinkIdName);

@ -22,11 +22,11 @@ namespace AzToolsFramework
/// @name Reverse URLs.
/// Used to identify common actions and override them when necessary.
//@{
static const AZ::Crc32 s_backAction = AZ_CRC("com.amazon.action.common.back", 0xd772a2af);
static const AZ::Crc32 s_deleteAction = AZ_CRC("com.amazon.action.common.delete", 0x5731f6cb);
static const AZ::Crc32 s_duplicateAction = AZ_CRC("com.amazon.action.common.duplicate", 0x08ccf461);
static const AZ::Crc32 s_nextComponentMode = AZ_CRC("com.amazon.action.common.nextComponentMode", 0xcc26094f);
static const AZ::Crc32 s_previousComponentMode = AZ_CRC("com.amazon.action.common.previousComponentMode", 0x0d18ff39);
static const AZ::Crc32 s_backAction = AZ_CRC("com.o3de.action.common.back", 0xd772a2af);
static const AZ::Crc32 s_deleteAction = AZ_CRC("com.o3de.action.common.delete", 0x5731f6cb);
static const AZ::Crc32 s_duplicateAction = AZ_CRC("com.o3de.action.common.duplicate", 0x08ccf461);
static const AZ::Crc32 s_nextComponentMode = AZ_CRC("com.o3de.action.common.nextComponentMode", 0xcc26094f);
static const AZ::Crc32 s_previousComponentMode = AZ_CRC("com.o3de.action.common.previousComponentMode", 0x0d18ff39);
//@}
/// Specific Action properties to be sent to a type implementing

@ -276,11 +276,6 @@ namespace AzToolsFramework
virtual void EndCursorCapture() = 0;
//! Gets the most recent recorded cursor position in the viewport in screen space coordinates.
virtual AzFramework::ScreenPoint ViewportCursorScreenPosition() = 0;
//! Gets the cursor position recorded prior to the most recent cursor position.
//! Note: The cursor may be captured by the viewport, in which case this may not correspond to the last result
//! from ViewportCursorScreenPosition. This method will always return the correct position to generate a mouse
//! position delta.
virtual AZStd::optional<AzFramework::ScreenPoint> PreviousViewportCursorScreenPosition() = 0;
//! Is mouse over viewport.
virtual bool IsMouseOver() const = 0;

@ -98,7 +98,7 @@ namespace AzToolsFramework
{
}
AZ::Crc32 m_uri; //!< Unique identifier for the Action. (In the form 'com.amazon.action.---").
AZ::Crc32 m_uri; //!< Unique identifier for the Action. (In the form 'com.o3de.action.---").
AZStd::vector<AZStd::function<void()>> m_callbacks; //!< Callbacks associated with this Action (note: with multi-selections
//!< there will be a callback per Entity/Component).
AZStd::unique_ptr<QAction> m_action; //!< The QAction associated with the overrideWidget for all ComponentMode actions.

@ -76,6 +76,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
PRIVATE
AZ::AzTestShared
3rdParty::Qt::Test
AZ::AzFrameworkTestShared
AZ::AzToolsFramework
AZ::AzToolsFrameworkTestCommon
AZ::AzManipulatorTestFramework.Static

@ -11,6 +11,7 @@
#include <AzCore/Memory/Memory.h>
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <AzCore/UserSettings/UserSettingsComponent.h>
#include <AzCore/IO/FileIO.h>
#include <Tests/AZTestShared/Utils/Utils.h>
#include <AzToolsFramework/Archive/ArchiveAPI.h>
#include <AzFramework/StringFunc/StringFunc.h>
@ -23,6 +24,7 @@
#include <QStandardPaths>
#include <QTemporaryDir>
#include <QTextStream>
#include <Utils/Utils.h>
namespace UnitTest
{
@ -72,7 +74,7 @@ namespace UnitTest
void CreateArchiveFolder( QString archiveFolderName, QStringList fileList )
{
QDir tempPath = QDir(m_tempDir.path()).filePath(archiveFolderName);
QDir tempPath = QDir(m_tempDir.GetDirectory()).filePath(archiveFolderName);
for (const auto& thisFile : fileList)
{
@ -88,12 +90,12 @@ namespace UnitTest
QString GetArchivePath()
{
return QDir(m_tempDir.path()).filePath("TestArchive.pak");
return QDir(m_tempDir.GetDirectory()).filePath("TestArchive.pak");
}
QString GetArchiveFolder()
{
return QDir(m_tempDir.path()).filePath(GetArchiveFolderName());
return QDir(m_tempDir.GetDirectory()).filePath(GetArchiveFolderName());
}
bool CreateArchive()
@ -111,6 +113,11 @@ namespace UnitTest
// shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash
// in the unit tests.
AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize);
if (auto fileIoBase = AZ::IO::FileIOBase::GetInstance(); fileIoBase != nullptr)
{
fileIoBase->SetAlias("@assets@", m_tempDir.GetDirectory());
}
}
void TearDown() override
@ -120,7 +127,7 @@ namespace UnitTest
}
AZStd::unique_ptr<ToolsTestApplication> m_app;
QTemporaryDir m_tempDir {QDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation)).filePath("ArchiveTests-")};
UnitTest::ScopedTemporaryDirectory m_tempDir;
};
#if AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS
@ -129,7 +136,7 @@ namespace UnitTest
TEST_F(ArchiveTest, CreateArchiveBlocking_FilesAtThreeDepths_ArchiveCreated)
#endif // AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS
{
EXPECT_TRUE(m_tempDir.isValid());
EXPECT_TRUE(m_tempDir.IsValid());
CreateArchiveFolder();
bool createResult = CreateArchive();
@ -143,7 +150,7 @@ namespace UnitTest
TEST_F(ArchiveTest, ListFilesInArchiveBlocking_FilesAtThreeDepths_FilesFound)
#endif // AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS
{
EXPECT_TRUE(m_tempDir.isValid());
EXPECT_TRUE(m_tempDir.IsValid());
CreateArchiveFolder();
EXPECT_EQ(CreateArchive(), true);
@ -203,7 +210,9 @@ namespace UnitTest
}
bool catalogCreated{ false };
AZ_TEST_START_TRACE_SUPPRESSION;
AzToolsFramework::AssetBundleCommandsBus::BroadcastResult(catalogCreated, &AzToolsFramework::AssetBundleCommandsBus::Events::CreateDeltaCatalog, GetArchivePath().toStdString().c_str(), true);
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // produces different counts in different platforms
EXPECT_EQ(catalogCreated, true);
}
}

@ -21,6 +21,7 @@
#include <AzToolsFramework/AssetCatalog/PlatformAddressedAssetCatalog.h>
#include <AzToolsFramework/UnitTest/ToolsTestApplication.h>
#include <AzCore/UserSettings/UserSettingsComponent.h>
#include <Utils/Utils.h>
namespace // anonymous
{
@ -54,9 +55,11 @@ namespace UnitTest
m_localFileIO = aznew AZ::IO::LocalFileIO();
m_priorFileIO = AZ::IO::FileIOBase::GetInstance();
AZ::IO::FileIOBase::SetInstance(nullptr);
AZ::IO::FileIOBase::SetInstance(m_localFileIO);
AZ::IO::FileIOBase::GetInstance()->SetAlias("@assets@", GetTestFolderPath().c_str());
AZ::IO::FileIOBase::GetInstance()->SetAlias("@assets@", m_tempDir.GetDirectory());
AZStd::string assetRoot = AzToolsFramework::PlatformAddressedAssetCatalog::GetAssetRootForPlatform(AzFramework::PlatformId::PC);
for (int idx = 0; idx < TotalAssets; idx++)
@ -68,9 +71,11 @@ namespace UnitTest
assetRegistry.RegisterAsset(m_assets[idx], info);
AzFramework::StringFunc::Path::Join(assetRoot.c_str(), info.m_relativePath.c_str(), m_assetsPath[idx]);
AZ_TEST_START_TRACE_SUPPRESSION;
if (m_fileStreams[idx].Open(m_assetsPath[idx].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath))
{
m_fileStreams[idx].Write(info.m_relativePath.size(), info.m_relativePath.data());
AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder
}
else
{
@ -114,10 +119,12 @@ namespace UnitTest
// Modify contents of asset2
int fileIndex = 2;
AZ_TEST_START_TRACE_SUPPRESSION;
if (m_fileStreams[fileIndex].Open(m_assetsPath[fileIndex].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath))
{
AZStd::string fileContent = AZStd::string::format("new Asset%d.txt", fileIndex);// changing file content
m_fileStreams[fileIndex].Write(fileContent.size(), fileContent.c_str());
AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder
}
else
{
@ -126,10 +133,12 @@ namespace UnitTest
// Modify contents of asset 4
fileIndex = 4;
AZ_TEST_START_TRACE_SUPPRESSION;
if (m_fileStreams[fileIndex].Open(m_assetsPath[fileIndex].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath))
{
AZStd::string fileContent = AZStd::string::format("new Asset%d.txt", fileIndex);// changing file content
m_fileStreams[fileIndex].Write(fileContent.size(), fileContent.c_str());
AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder
}
else
{
@ -151,7 +160,9 @@ namespace UnitTest
{
if (fileIO->Exists(TempFiles[idx]))
{
AZ_TEST_START_TRACE_SUPPRESSION;
fileIO->Remove(TempFiles[idx]);
AZ_TEST_STOP_TRACE_SUPPRESSION(1); // deleting from asset cache folder
}
}
@ -162,19 +173,24 @@ namespace UnitTest
m_fileStreams[idx].Close();
if (fileIO->Exists(m_assetsPath[idx].c_str()))
{
AZ_TEST_START_TRACE_SUPPRESSION;
fileIO->Remove(m_assetsPath[idx].c_str());
AZ_TEST_STOP_TRACE_SUPPRESSION(1); // deleting from asset cache folder
}
}
auto pcCatalogFile = AzToolsFramework::PlatformAddressedAssetCatalog::GetCatalogRegistryPathForPlatform(AzFramework::PlatformId::PC);
if (fileIO->Exists(pcCatalogFile.c_str()))
{
AZ_TEST_START_TRACE_SUPPRESSION;
fileIO->Remove(pcCatalogFile.c_str());
AZ_TEST_STOP_TRACE_SUPPRESSION(1); // deleting from asset cache folder
}
delete m_pcCatalog;
delete m_localFileIO;
m_localFileIO = nullptr;
AZ::IO::FileIOBase::SetInstance(nullptr);
AZ::IO::FileIOBase::SetInstance(m_priorFileIO);
m_application->Stop();
delete m_application;
@ -726,6 +742,7 @@ namespace UnitTest
}
ToolsTestApplication* m_application;
UnitTest::ScopedTemporaryDirectory m_tempDir;
AzToolsFramework::PlatformAddressedAssetCatalog* m_pcCatalog;
AZ::IO::FileIOBase* m_priorFileIO = nullptr;
AZ::IO::FileIOBase* m_localFileIO = nullptr;

@ -87,10 +87,12 @@ namespace UnitTest
for (int idx = 0; idx < s_totalAssets; idx++)
{
AzFramework::StringFunc::Path::Join(assetRoot.c_str(), m_assetsPath[idx].c_str(), m_assetsPathFull[platformCount][idx]);
AZ_TEST_START_TRACE_SUPPRESSION;
if (m_fileStreams[platformCount][idx].Open(m_assetsPathFull[platformCount][idx].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath))
{
m_fileStreams[platformCount][idx].Write(m_assetsPath[idx].size(), m_assetsPath[idx].data());
m_fileStreams[platformCount][idx].Close();
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, only invalid for PC, not invalid in Jenkins
}
else
{
@ -112,7 +114,9 @@ namespace UnitTest
m_testDynamicSliceAssetId = testDynamicSliceAsset;
m_assetRegistry->RegisterAsset(testDynamicSliceAsset, dynamicSliceAssetInfo);
AZ_TEST_START_TRACE_SUPPRESSION;
AZ::IO::FileIOStream dynamicSliceFileIOStream(TestDynamicSliceAssetPath, AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeText);
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins
AZ::Data::AssetInfo sliceAssetInfo;
sliceAssetInfo.m_relativePath = TestSliceAssetPath;
@ -124,7 +128,9 @@ namespace UnitTest
secondSliceAssetInfo.m_assetId = secondTestSliceAsset;
m_assetRegistry->RegisterAsset(secondTestSliceAsset, secondSliceAssetInfo);
AZ_TEST_START_TRACE_SUPPRESSION;
AZ::IO::FileIOStream sliceFileIOStream(TestSliceAssetPath, AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeText);
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins
// asset0 -> asset1 -> asset2 -> asset4
// --> asset3
@ -186,7 +192,6 @@ namespace UnitTest
AZ::IO::Path assetRoot(AZ::Utils::GetProjectPath());
assetRoot /= "Cache";
AZ::IO::FileIOBase::GetInstance()->SetAlias("@root@", assetRoot.c_str());
}
void TearDown() override
@ -195,7 +200,9 @@ namespace UnitTest
if (fileIO->Exists(s_catalogFile))
{
AZ_TEST_START_TRACE_SUPPRESSION;
fileIO->Remove(s_catalogFile);
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins
}
for (size_t platformCount = 0; platformCount < s_totalTestPlatforms; ++platformCount)
@ -206,26 +213,34 @@ namespace UnitTest
// we need to close the handle before we try to remove the file
if (fileIO->Exists(m_assetsPathFull[platformCount][idx].c_str()))
{
AZ_TEST_START_TRACE_SUPPRESSION;
fileIO->Remove(m_assetsPathFull[platformCount][idx].c_str());
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins
}
}
}
if (fileIO->Exists(TestSliceAssetPath))
{
AZ_TEST_START_TRACE_SUPPRESSION;
fileIO->Remove(TestSliceAssetPath);
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins
}
if (fileIO->Exists(TestDynamicSliceAssetPath))
{
AZ_TEST_START_TRACE_SUPPRESSION;
fileIO->Remove(TestDynamicSliceAssetPath);
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins
}
auto pcCatalogFile = AzToolsFramework::PlatformAddressedAssetCatalog::GetCatalogRegistryPathForPlatform(AzFramework::PlatformId::PC);
auto androidCatalogFile = AzToolsFramework::PlatformAddressedAssetCatalog::GetCatalogRegistryPathForPlatform(AzFramework::PlatformId::ANDROID_ID);
if (fileIO->Exists(pcCatalogFile.c_str()))
{
AZ_TEST_START_TRACE_SUPPRESSION;
fileIO->Remove(pcCatalogFile.c_str());
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins
}
if (fileIO->Exists(androidCatalogFile.c_str()))
@ -266,7 +281,9 @@ namespace UnitTest
AZ::IO::SystemFile::SetWritable(filePath.c_str(), false);
// Attempt to save to the same file. Should not be allowed.
AZ_TEST_START_TRACE_SUPPRESSION;
EXPECT_FALSE(m_assetSeedManager->Save(filePath));
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins
// Clean up the test environment
AZ::IO::SystemFile::SetWritable(filePath.c_str(), true);
@ -290,7 +307,9 @@ namespace UnitTest
AZ::IO::SystemFile::SetWritable(filePath.c_str(), false);
// Attempt to save to the same file. Should not be allowed.
AZ_TEST_START_TRACE_SUPPRESSION;
EXPECT_FALSE(m_assetSeedManager->SaveAssetFileInfo(filePath, AzFramework::PlatformFlags::Platform_PC, {}));
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins
// Clean up the test environment
AZ::IO::SystemFile::SetWritable(filePath.c_str(), true);
@ -357,7 +376,9 @@ namespace UnitTest
m_assetSeedManager->AddSeedAsset(assets[2], AzFramework::PlatformFlags::Platform_PC);
// Step we are testing
AZ_TEST_START_TRACE_SUPPRESSION;
m_assetSeedManager->AddPlatformToAllSeeds(AzFramework::PlatformId::ANDROID_ID);
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins
// Verification
AzFramework::PlatformFlags expectedPlatformFlags = AzFramework::PlatformFlags::Platform_PC | AzFramework::PlatformFlags::Platform_ANDROID;
@ -623,11 +644,13 @@ namespace UnitTest
EXPECT_EQ(assetList1.m_fileInfoList.size(), 1);
EXPECT_TRUE(Search(assetList1, assets[fileIndex]));
AZ_TEST_START_TRACE_SUPPRESSION;
if (m_fileStreams[0][fileIndex].Open(m_assetsPathFull[0][fileIndex].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath))
{
AZStd::string fileContent = AZStd::string::format("asset%d.txt", fileIndex);
m_fileStreams[0][fileIndex].Write(fileContent.size(), fileContent.c_str());
m_fileStreams[0][fileIndex].Close();
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins
}
AzToolsFramework::AssetFileInfoList assetList2 = m_assetSeedManager->GetDependencyList(AzFramework::PlatformId::PC);
@ -654,11 +677,13 @@ namespace UnitTest
EXPECT_EQ(assetList1.m_fileInfoList.size(), 1);
EXPECT_TRUE(Search(assetList1, assets[fileIndex]));
AZ_TEST_START_TRACE_SUPPRESSION;
if (m_fileStreams[0][fileIndex].Open(m_assetsPathFull[0][fileIndex].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath))
{
AZStd::string fileContent = AZStd::string::format("asset%d.txt", fileIndex + 1);// changing file content
m_fileStreams[0][fileIndex].Write(fileContent.size(), fileContent.c_str());
m_fileStreams[0][fileIndex].Close();
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins
}
AzToolsFramework::AssetFileInfoList assetList2 = m_assetSeedManager->GetDependencyList(AzFramework::PlatformId::PC);

@ -196,7 +196,7 @@ namespace AzToolsFramework
AZStd::vector<AzToolsFramework::ActionOverride> PlaceHolderComponentMode::PopulateActionsImpl()
{
const AZ::Crc32 placeHolderComponentModeAction = AZ_CRC_CE("com.amazon.action.placeholder.test");
const AZ::Crc32 placeHolderComponentModeAction = AZ_CRC_CE("com.o3de.action.placeholder.test");
return AZStd::vector<AzToolsFramework::ActionOverride>
{

@ -493,7 +493,10 @@ namespace UnitTest
// Add placeholder component which implements component mode.
entity->CreateComponent<PlaceHolderComponent>();
AZ_TEST_START_TRACE_SUPPRESSION;
entity->Activate();
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save