Merge branch 'development' into Atom/jromnoa/assert-for-screenshot-comparisons
This commit is contained in:
@@ -37,6 +37,10 @@ class TestAutomation(EditorTestSuite):
|
||||
@pytest.mark.test_case_id("C32078115")
|
||||
class AtomEditorComponents_GlobalSkylightIBLAdded(EditorSharedTest):
|
||||
from Atom.tests import hydra_AtomEditorComponents_GlobalSkylightIBLAdded as test_module
|
||||
|
||||
@pytest.mark.test_case_id("C32078122")
|
||||
class AtomEditorComponents_GridAdded(EditorSharedTest):
|
||||
from Atom.tests import hydra_AtomEditorComponents_GridAdded as test_module
|
||||
|
||||
@pytest.mark.test_case_id("C32078117")
|
||||
class AtomEditorComponents_LightAdded(EditorSharedTest):
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
"""
|
||||
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
|
||||
"""
|
||||
|
||||
class Tests:
|
||||
creation_undo = (
|
||||
"UNDO Entity creation success",
|
||||
"UNDO Entity creation failed")
|
||||
creation_redo = (
|
||||
"REDO Entity creation success",
|
||||
"REDO Entity creation failed")
|
||||
grid_entity_creation = (
|
||||
"Grid Entity successfully created",
|
||||
"Grid Entity failed to be created")
|
||||
grid_component_added = (
|
||||
"Entity has a Grid component",
|
||||
"Entity failed to find Grid component")
|
||||
enter_game_mode = (
|
||||
"Entered game mode",
|
||||
"Failed to enter game mode")
|
||||
exit_game_mode = (
|
||||
"Exited game mode",
|
||||
"Couldn't exit game mode")
|
||||
is_visible = (
|
||||
"Entity is visible",
|
||||
"Entity was not visible")
|
||||
is_hidden = (
|
||||
"Entity is hidden",
|
||||
"Entity was not hidden")
|
||||
entity_deleted = (
|
||||
"Entity deleted",
|
||||
"Entity was not deleted")
|
||||
deletion_undo = (
|
||||
"UNDO deletion success",
|
||||
"UNDO deletion failed")
|
||||
deletion_redo = (
|
||||
"REDO deletion success",
|
||||
"REDO deletion failed")
|
||||
|
||||
|
||||
def AtomEditorComponents_Grid_AddedToEntity():
|
||||
"""
|
||||
Summary:
|
||||
Tests the Grid component can be added to an entity and has the expected functionality.
|
||||
|
||||
Test setup:
|
||||
- Wait for Editor idle loop.
|
||||
- Open the "Base" level.
|
||||
|
||||
Expected Behavior:
|
||||
The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components.
|
||||
Creation and deletion undo/redo should also work.
|
||||
|
||||
Test Steps:
|
||||
1) Create a Grid entity with no components.
|
||||
2) Add a Grid component to Grid entity.
|
||||
3) UNDO the entity creation and component addition.
|
||||
4) REDO the entity creation and component addition.
|
||||
5) Enter/Exit game mode.
|
||||
6) Test IsHidden.
|
||||
7) Test IsVisible.
|
||||
8) Delete Grid entity.
|
||||
9) UNDO deletion.
|
||||
10) REDO deletion.
|
||||
11) Look for errors.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity
|
||||
from editor_python_test_tools.utils import Report, Tracer, TestHelper
|
||||
from Atom.atom_utils.atom_constants import AtomComponentProperties
|
||||
|
||||
with Tracer() as error_tracer:
|
||||
# Test setup begins.
|
||||
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
|
||||
TestHelper.init_idle()
|
||||
TestHelper.open_level("", "Base")
|
||||
|
||||
# Test steps begin.
|
||||
# 1. Create a Grid entity with no components.
|
||||
grid_entity = EditorEntity.create_editor_entity(AtomComponentProperties.grid())
|
||||
Report.critical_result(Tests.grid_entity_creation, grid_entity.exists())
|
||||
|
||||
# 2. Add a Grid component to Grid entity.
|
||||
grid_component = grid_entity.add_component(AtomComponentProperties.grid())
|
||||
Report.critical_result(
|
||||
Tests.grid_component_added,
|
||||
grid_entity.has_component(AtomComponentProperties.grid()))
|
||||
|
||||
# 3. UNDO the entity creation and component addition.
|
||||
# -> UNDO component addition.
|
||||
general.undo()
|
||||
# -> UNDO naming entity.
|
||||
general.undo()
|
||||
# -> UNDO selecting entity.
|
||||
general.undo()
|
||||
# -> UNDO entity creation.
|
||||
general.undo()
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.creation_undo, not grid_entity.exists())
|
||||
|
||||
# 4. REDO the entity creation and component addition.
|
||||
# -> REDO entity creation.
|
||||
general.redo()
|
||||
# -> REDO selecting entity.
|
||||
general.redo()
|
||||
# -> REDO naming entity.
|
||||
general.redo()
|
||||
# -> REDO component addition.
|
||||
general.redo()
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.creation_redo, grid_entity.exists())
|
||||
|
||||
# 5. Enter/Exit game mode.
|
||||
TestHelper.enter_game_mode(Tests.enter_game_mode)
|
||||
general.idle_wait_frames(1)
|
||||
TestHelper.exit_game_mode(Tests.exit_game_mode)
|
||||
|
||||
# 6. Test IsHidden.
|
||||
grid_entity.set_visibility_state(False)
|
||||
Report.result(Tests.is_hidden, grid_entity.is_hidden() is True)
|
||||
|
||||
# 7. Test IsVisible.
|
||||
grid_entity.set_visibility_state(True)
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.is_visible, grid_entity.is_visible() is True)
|
||||
|
||||
# 8. Delete Grid entity.
|
||||
grid_entity.delete()
|
||||
Report.result(Tests.entity_deleted, not grid_entity.exists())
|
||||
|
||||
# 9. UNDO deletion.
|
||||
general.undo()
|
||||
Report.result(Tests.deletion_undo, grid_entity.exists())
|
||||
|
||||
# 10. REDO deletion.
|
||||
general.redo()
|
||||
Report.result(Tests.deletion_redo, not grid_entity.exists())
|
||||
|
||||
# 11. Look for errors or asserts.
|
||||
TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
|
||||
for error_info in error_tracer.errors:
|
||||
Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
|
||||
for assert_info in error_tracer.asserts:
|
||||
Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(AtomEditorComponents_Grid_AddedToEntity)
|
||||
-2
@@ -70,8 +70,6 @@ def AtomEditorComponents_postfx_layer_AddedToEntity():
|
||||
:return: None
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity
|
||||
|
||||
+76
-15
@@ -107,6 +107,19 @@ class EditorComponent:
|
||||
return type_ids
|
||||
|
||||
|
||||
|
||||
def convert_to_azvector3(xyz) -> azlmbr.math.Vector3:
|
||||
"""
|
||||
Converts a vector3-like element into a azlmbr.math.Vector3
|
||||
"""
|
||||
if isinstance(xyz, Tuple) or isinstance(xyz, List):
|
||||
assert len(xyz) == 3, ValueError("vector must be a 3 element list/tuple or azlmbr.math.Vector3")
|
||||
return math.Vector3(float(xyz[0]), float(xyz[1]), float(xyz[2]))
|
||||
elif isinstance(xyz, type(math.Vector3())):
|
||||
return xyz
|
||||
else:
|
||||
raise ValueError("vector must be a 3 element list/tuple or azlmbr.math.Vector3")
|
||||
|
||||
class EditorEntity:
|
||||
"""
|
||||
Entity class is used to create and interact with Editor Entities.
|
||||
@@ -183,15 +196,6 @@ class EditorEntity:
|
||||
:return: EditorEntity class object
|
||||
"""
|
||||
|
||||
def convert_to_azvector3(xyz) -> math.Vector3:
|
||||
if isinstance(xyz, Tuple) or isinstance(xyz, List):
|
||||
assert len(xyz) == 3, ValueError("vector must be a 3 element list/tuple or azlmbr.math.Vector3")
|
||||
return math.Vector3(*xyz)
|
||||
elif isinstance(xyz, type(math.Vector3())):
|
||||
return xyz
|
||||
else:
|
||||
raise ValueError("vector must be a 3 element list/tuple or azlmbr.math.Vector3")
|
||||
|
||||
if parent_id is None:
|
||||
parent_id = azlmbr.entity.EntityId()
|
||||
|
||||
@@ -206,7 +210,7 @@ class EditorEntity:
|
||||
return entity
|
||||
|
||||
# Methods
|
||||
def set_name(self, entity_name: str):
|
||||
def set_name(self, entity_name: str) -> None:
|
||||
"""
|
||||
Given entity_name, sets name to Entity
|
||||
:param: entity_name: Name of the entity to set
|
||||
@@ -324,7 +328,7 @@ class EditorEntity:
|
||||
self.start_status = status
|
||||
return status
|
||||
|
||||
def set_start_status(self, desired_start_status: str):
|
||||
def set_start_status(self, desired_start_status: str) -> None:
|
||||
"""
|
||||
Set an entity as active/inactive at beginning of runtime or it is editor-only,
|
||||
given its entity id and the start status then return set success
|
||||
@@ -382,18 +386,75 @@ class EditorEntity:
|
||||
"""
|
||||
return editor.EditorEntityInfoRequestBus(bus.Event, "IsVisible", self.id)
|
||||
|
||||
# World Transform Functions
|
||||
def get_world_translation(self) -> azlmbr.math.Vector3:
|
||||
"""
|
||||
Gets the world translation of the entity
|
||||
"""
|
||||
return azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
|
||||
|
||||
def set_world_translation(self, new_translation) -> None:
|
||||
"""
|
||||
Sets the new world translation of the current entity
|
||||
"""
|
||||
new_translation = convert_to_azvector3(new_translation)
|
||||
azlmbr.components.TransformBus(azlmbr.bus.Event, "SetWorldTranslation", self.id, new_translation)
|
||||
|
||||
def get_world_rotation(self) -> azlmbr.math.Quaternion:
|
||||
"""
|
||||
Gets the world rotation of the entity
|
||||
"""
|
||||
return azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldRotation", self.id)
|
||||
|
||||
def set_world_rotation(self, new_rotation):
|
||||
"""
|
||||
Sets the new world rotation of the current entity
|
||||
"""
|
||||
new_rotation = convert_to_azvector3(new_rotation)
|
||||
azlmbr.components.TransformBus(azlmbr.bus.Event, "SetWorldRotation", self.id, new_rotation)
|
||||
|
||||
# Local Transform Functions
|
||||
def get_local_uniform_scale(self) -> float:
|
||||
"""
|
||||
Gets the local uniform scale of the entity
|
||||
"""
|
||||
return azlmbr.components.TransformBus(azlmbr.bus.Event, "GetLocalUniformScale", self.id)
|
||||
|
||||
def set_local_uniform_scale(self, scale_float) -> None:
|
||||
"""
|
||||
Sets the "SetLocalUniformScale" value on the entity.
|
||||
Sets the local uniform scale value(relative to the parent) on the entity.
|
||||
:param scale_float: value for "SetLocalUniformScale" to set to.
|
||||
:return: None
|
||||
"""
|
||||
azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalUniformScale", self.id, scale_float)
|
||||
|
||||
def set_local_rotation(self, vector3_rotation) -> None:
|
||||
def get_local_rotation(self) -> azlmbr.math.Quaternion:
|
||||
"""
|
||||
Sets the "SetLocalRotation" value on the entity.
|
||||
Gets the local rotation of the entity
|
||||
"""
|
||||
return azlmbr.components.TransformBus(azlmbr.bus.Event, "GetLocalRotation", self.id)
|
||||
|
||||
def set_local_rotation(self, new_rotation) -> None:
|
||||
"""
|
||||
Sets the set the local rotation(relative to the parent) of the current entity.
|
||||
:param vector3_rotation: The math.Vector3 value to use for rotation on the entity (uses radians).
|
||||
:return: None
|
||||
"""
|
||||
azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", self.id, vector3_rotation)
|
||||
new_rotation = convert_to_azvector3(new_rotation)
|
||||
azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", self.id, new_rotation)
|
||||
|
||||
def get_local_translation(self) -> azlmbr.math.Vector3:
|
||||
"""
|
||||
Gets the local translation of the current entity.
|
||||
:return: The math.Vector3 value of the local translation.
|
||||
"""
|
||||
return azlmbr.components.TransformBus(azlmbr.bus.Event, "GetLocalTranslation", self.id)
|
||||
|
||||
def set_local_translation(self, new_translation) -> None:
|
||||
"""
|
||||
Sets the local translation(relative to the parent) of the current entity.
|
||||
:param vector3_translation: The math.Vector3 value to use for translation on the entity.
|
||||
:return: None
|
||||
"""
|
||||
new_translation = convert_to_azvector3(new_translation)
|
||||
azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalTranslation", self.id, new_translation)
|
||||
|
||||
+8
@@ -138,6 +138,14 @@ class PrefabInstance:
|
||||
self.container_entity = reparented_container_entity
|
||||
current_instance_prefab.instances.add(self)
|
||||
|
||||
def get_direct_child_entities(self):
|
||||
"""
|
||||
Returns the entities only contained in the current prefab instance.
|
||||
This function does not return entities contained in other child instances
|
||||
"""
|
||||
return self.container_entity.get_children()
|
||||
|
||||
|
||||
# This is a helper class which contains some of the useful information about a prefab template.
|
||||
class Prefab:
|
||||
|
||||
|
||||
@@ -55,3 +55,11 @@ class TestAutomation(TestAutomationBase):
|
||||
def test_PrefabBasicWorkflow_CreateAndDuplicatePrefab(self, request, workspace, editor, launcher_platform):
|
||||
from .tests import PrefabBasicWorkflow_CreateAndDuplicatePrefab as test_module
|
||||
self._run_prefab_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_PrefabComplexWorflow_CreatePrefabOfChildEntity(self, request, workspace, editor, launcher_platform):
|
||||
from .tests import PrefabComplexWorflow_CreatePrefabOfChildEntity as test_module
|
||||
self._run_prefab_test(request, workspace, editor, test_module, autotest_mode=False)
|
||||
|
||||
def test_PrefabComplexWorflow_CreatePrefabInsidePrefab(self, request, workspace, editor, launcher_platform):
|
||||
from .tests import PrefabComplexWorflow_CreatePrefabInsidePrefab as test_module
|
||||
self._run_prefab_test(request, workspace, editor, test_module, autotest_mode=False)
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
"""
|
||||
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
|
||||
"""
|
||||
|
||||
def PrefabComplexWorflow_CreatePrefabInsidePrefab():
|
||||
"""
|
||||
Test description:
|
||||
- Creates an entity with a physx collider
|
||||
- Creates a prefab "Outer_prefab" and an instance based of that entity
|
||||
- Creates a prefab "Inner_prefab" inside "Outer_prefab" based the entity contained inside of it
|
||||
Checks that the entity is correctly handlded by the prefab system checking the name and that it contains the physx collider
|
||||
"""
|
||||
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity
|
||||
from editor_python_test_tools.prefab_utils import Prefab
|
||||
|
||||
import PrefabTestUtils as prefab_test_utils
|
||||
|
||||
prefab_test_utils.open_base_tests_level()
|
||||
|
||||
# Creates a new Entity at the root level
|
||||
# Asserts if creation didn't succeed
|
||||
entity = EditorEntity.create_editor_entity_at((100.0, 100.0, 100.0), name = "TestEntity")
|
||||
assert entity.id.IsValid(), "Couldn't create entity"
|
||||
entity.add_component("PhysX Collider")
|
||||
assert entity.has_component("PhysX Collider"), "Attempted to add a PhysX Collider but no physx collider collider was found afterwards"
|
||||
|
||||
# Create a prefab based on that entity
|
||||
outer_prefab, outer_instance = Prefab.create_prefab([entity], "Outer_prefab")
|
||||
# The test should be now inside the outer prefab instance.
|
||||
entity = outer_instance.get_direct_child_entities()[0]
|
||||
# We track if that is the same entity by checking the name and if it still contains the component that we created before
|
||||
assert entity.get_name() == "TestEntity", f"Entity name inside outer_prefab doesn't match the original name, original:'TestEntity' current:'{entity.get_name()}'"
|
||||
assert entity.has_component("PhysX Collider"), "Entity name inside outer_prefab doesn't have the collider component it should"
|
||||
|
||||
# Now, create another prefab, based on the entity that is inside outer_prefab
|
||||
inner_prefab, inner_instance = Prefab.create_prefab([entity], "Inner_prefab")
|
||||
# The test entity should now be inside the inner prefab instance
|
||||
entity = inner_instance.get_direct_child_entities()[0]
|
||||
# We track if that is the same entity by checking the name and if it still contains the component that we created before
|
||||
assert entity.get_name() == "TestEntity", f"Entity name inside inner_prefab doesn't match the original name, original:'TestEntity' current:'{entity.get_name()}'"
|
||||
assert entity.has_component("PhysX Collider"), "Entity name inside inner_prefab doesn't have the collider component it should"
|
||||
|
||||
# Verify hierarchy of entities:
|
||||
# Outer_prefab
|
||||
# |- Inner_prefab
|
||||
# | |- TestEntity
|
||||
assert entity.get_parent_id() == inner_instance.container_entity.id
|
||||
assert inner_instance.container_entity.get_parent_id() == outer_instance.container_entity.id
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(PrefabComplexWorflow_CreatePrefabInsidePrefab)
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
"""
|
||||
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
|
||||
"""
|
||||
|
||||
def PrefabComplexWorflow_CreatePrefabOfChildEntity():
|
||||
"""
|
||||
Test description:
|
||||
- Creates two entities, parent and child. Child entity has Parent entity as its parent.
|
||||
- Creates a prefab of the child entity.
|
||||
Test is successful if the new instanced prefab of the child has the parent entity id
|
||||
"""
|
||||
|
||||
CAR_PREFAB_FILE_NAME = 'car_prefab'
|
||||
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity
|
||||
from editor_python_test_tools.prefab_utils import Prefab
|
||||
|
||||
import PrefabTestUtils as prefab_test_utils
|
||||
|
||||
prefab_test_utils.open_base_tests_level()
|
||||
|
||||
# Creates a new Entity at the root level
|
||||
# Asserts if creation didn't succeed
|
||||
parent_entity = EditorEntity.create_editor_entity_at((100.0, 100.0, 100.0))
|
||||
assert parent_entity.id.IsValid(), "Couldn't create parent entity"
|
||||
|
||||
child_entity = EditorEntity.create_editor_entity(parent_id=parent_entity.id)
|
||||
assert child_entity.id.IsValid(), "Couldn't create child entity"
|
||||
assert child_entity.get_world_translation().IsClose(parent_entity.get_world_translation()), f"Child entity position{child_entity.get_world_translation().ToString()}" \
|
||||
f" is not located at the same position as the parent{parent_entity.get_world_translation().ToString()}"
|
||||
|
||||
# Asserts if prefab creation doesn't succeed
|
||||
child_prefab, child_instance = Prefab.create_prefab([child_entity], CAR_PREFAB_FILE_NAME)
|
||||
child_entity_on_child_instance = child_instance.get_direct_child_entities()[0]
|
||||
assert child_instance.container_entity.get_parent_id().IsValid(), "Newly instanced entity has no parent"
|
||||
assert child_instance.container_entity.get_parent_id() == parent_entity.id, "Newly instanced entity parent does not match the expected parent"
|
||||
assert child_instance.container_entity.get_world_translation().IsClose(parent_entity.get_world_translation()), "Newly instanced entity position is not located at the same position as the parent"
|
||||
# Move the parent position, it should update the child position
|
||||
parent_entity.set_world_translation((200.0, 200.0, 200.0))
|
||||
child_instance_translation = child_instance.container_entity.get_world_translation()
|
||||
assert child_instance_translation.IsClose(azlmbr.math.Vector3(200.0, 200.0, 200.0)), f"Instance position position{child_instance_translation.ToString()} didn't get updated" \
|
||||
f" to the same position as the parent{parent_entity.get_world_translation().ToString()}"
|
||||
child_translation = child_entity_on_child_instance.get_world_translation()
|
||||
assert child_translation.IsClose(azlmbr.math.Vector3(200.0, 200.0, 200.0)), f"Entity position{child_translation.ToString()} of the instance didn't get updated" \
|
||||
f" to the same position as the parent{parent_entity.get_world_translation().ToString()}"
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(PrefabComplexWorflow_CreatePrefabOfChildEntity)
|
||||
@@ -23,7 +23,7 @@ def create_jobs(request):
|
||||
jobDescriptorList = []
|
||||
for platformInfo in request.enabledPlatforms:
|
||||
jobDesc = azlmbr.asset.builder.JobDescriptor()
|
||||
jobDesc.jobKey = jobKeyName
|
||||
jobDesc.jobKey = f'{jobKeyName}-{platformInfo.identifier}'
|
||||
jobDesc.set_platform_identifier(platformInfo.identifier)
|
||||
jobDescriptorList.append(jobDesc)
|
||||
|
||||
@@ -38,7 +38,7 @@ def on_create_jobs(args):
|
||||
return create_jobs(request)
|
||||
except:
|
||||
log_exception_traceback()
|
||||
# returing back a default CreateJobsResponse() records an asset error
|
||||
# returning back a default CreateJobsResponse() records an asset error
|
||||
return azlmbr.asset.builder.CreateJobsResponse()
|
||||
|
||||
def process_file(request):
|
||||
@@ -58,6 +58,7 @@ def process_file(request):
|
||||
fileOutput = open(tempFilename, "w")
|
||||
fileOutput.write('{}')
|
||||
fileOutput.close()
|
||||
print(f'Wrote mock asset file: {tempFilename}')
|
||||
|
||||
# generate a product asset file entry
|
||||
subId = binascii.crc32(mockFilename.encode())
|
||||
|
||||
+3
@@ -29,6 +29,9 @@ def ap_fast_scan_setting_backup_fixture(request, workspace) -> PlatformSetting:
|
||||
if workspace.asset_processor_platform == 'mac':
|
||||
pytest.skip("Mac plist file editing not implemented yet")
|
||||
|
||||
if workspace.asset_processor_platform == 'linux':
|
||||
pytest.skip("Linux system settings not implemented yet")
|
||||
|
||||
key = fast_scan_key
|
||||
subkey = fast_scan_subkey
|
||||
|
||||
|
||||
+1
-1
@@ -79,7 +79,7 @@ class TestsAssetProcessorBatch_DependenycyTests(object):
|
||||
env = ap_setup_fixture
|
||||
BATCH_LOG_PATH = env["ap_batch_log_file"]
|
||||
asset_processor.create_temp_asset_root()
|
||||
asset_processor.add_relative_source_asset(os.path.join("Assets", "Engine", "engine_dependencies.xml"))
|
||||
asset_processor.add_relative_source_asset(os.path.join("Assets", "Engine", "Engine_Dependencies.xml"))
|
||||
asset_processor.add_scan_folder(os.path.join("Assets", "Engine"))
|
||||
asset_processor.add_relative_source_asset(os.path.join("Assets", "Engine", "Libs", "MaterialEffects", "surfacetypes.xml"))
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import sys
|
||||
import importlib
|
||||
import re
|
||||
|
||||
import ly_test_tools
|
||||
from ly_test_tools import LAUNCHERS
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
@@ -25,8 +26,15 @@ import ly_test_tools.environment.process_utils as process_utils
|
||||
|
||||
import argparse, sys
|
||||
|
||||
@pytest.mark.SUITE_main
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
def get_editor_launcher_platform():
|
||||
if ly_test_tools.WINDOWS:
|
||||
return "windows_editor"
|
||||
elif ly_test_tools.LINUX:
|
||||
return "linux_editor"
|
||||
else:
|
||||
return None
|
||||
|
||||
@pytest.mark.parametrize("launcher_platform", [get_editor_launcher_platform()])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
class TestEditorTest:
|
||||
|
||||
@@ -69,7 +77,7 @@ class TestEditorTest:
|
||||
from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorTestSuite
|
||||
|
||||
@pytest.mark.SUITE_main
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
@pytest.mark.parametrize("launcher_platform", [{get_editor_launcher_platform()}])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
class TestAutomation(EditorTestSuite):
|
||||
class test_single(EditorSingleTest):
|
||||
@@ -123,7 +131,7 @@ class TestEditorTest:
|
||||
from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorTestSuite
|
||||
|
||||
@pytest.mark.SUITE_main
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
@pytest.mark.parametrize("launcher_platform", [{get_editor_launcher_platform()}])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
class TestAutomation(EditorTestSuite):
|
||||
{module_class_code}
|
||||
|
||||
@@ -13,18 +13,26 @@ import os
|
||||
import pytest
|
||||
import subprocess
|
||||
|
||||
import ly_test_tools
|
||||
|
||||
|
||||
@pytest.mark.SUITE_smoke
|
||||
class TestCLIToolAzTestRunnerWorks(object):
|
||||
def test_CLITool_AzTestRunner_Works(self, build_directory):
|
||||
def test_CLITool_AzTestRunner_ListSelfTests(self, build_directory):
|
||||
file_path = os.path.join(build_directory, "AzTestRunner")
|
||||
help_message = "OKAY Symbol found: AzRunUnitTests"
|
||||
# Launch AzTestRunner
|
||||
|
||||
if ly_test_tools.WINDOWS:
|
||||
target_lib = "AzTestRunner.Tests"
|
||||
else:
|
||||
target_lib = "libAzTestRunner.Tests"
|
||||
|
||||
# Launch AzTestRunner, load self-tests, print test names
|
||||
output = subprocess.run(
|
||||
[file_path, "AzTestRunner.Tests", "AzRunUnitTests", "--gtest_list_tests"], capture_output=True, timeout=10
|
||||
[file_path, target_lib, "AzRunUnitTests", "--gtest_list_tests"], capture_output=True, timeout=10
|
||||
)
|
||||
assert (
|
||||
len(output.stderr) == 0 and output.returncode == 0
|
||||
), f"Error occurred while launching {file_path}: {output.stderr}"
|
||||
# Verify help message
|
||||
assert help_message in str(output.stdout), f"Help Message: {help_message} is not present"
|
||||
assert help_message in str(output.stdout), f"Help Message: '{help_message}' unexpectedly not present"
|
||||
|
||||
@@ -16,9 +16,12 @@
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/utils.h>
|
||||
|
||||
struct ICVar;
|
||||
|
||||
class CVarMenu
|
||||
: public QMenu
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
// CVar that can be toggled on and off
|
||||
struct CVarToggle
|
||||
|
||||
+87
-95
@@ -19,10 +19,9 @@ namespace Config
|
||||
|
||||
CConfigGroup::~CConfigGroup()
|
||||
{
|
||||
for (TConfigVariables::const_iterator it = m_vars.begin();
|
||||
it != m_vars.end(); ++it)
|
||||
for (IConfigVar* var : m_vars)
|
||||
{
|
||||
delete (*it);
|
||||
delete var;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,17 +30,15 @@ namespace Config
|
||||
m_vars.push_back(var);
|
||||
}
|
||||
|
||||
uint32 CConfigGroup::GetVarCount()
|
||||
AZ::u32 CConfigGroup::GetVarCount()
|
||||
{
|
||||
return static_cast<uint32>(m_vars.size());
|
||||
return aznumeric_cast<AZ::u32>(m_vars.size());
|
||||
}
|
||||
|
||||
IConfigVar* CConfigGroup::GetVar(const char* szName)
|
||||
{
|
||||
for (TConfigVariables::const_iterator it = m_vars.begin();
|
||||
it != m_vars.end(); ++it)
|
||||
for (IConfigVar* var : m_vars)
|
||||
{
|
||||
IConfigVar* var = (*it);
|
||||
if (0 == _stricmp(szName, var->GetName().c_str()))
|
||||
{
|
||||
return var;
|
||||
@@ -53,20 +50,19 @@ namespace Config
|
||||
|
||||
const IConfigVar* CConfigGroup::GetVar(const char* szName) const
|
||||
{
|
||||
for (TConfigVariables::const_iterator it = m_vars.begin();
|
||||
it != m_vars.end(); ++it)
|
||||
for (const IConfigVar* var : m_vars)
|
||||
{
|
||||
IConfigVar* var = (*it);
|
||||
if (0 == _stricmp(szName, var->GetName().c_str()))
|
||||
{
|
||||
return var;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IConfigVar* CConfigGroup::GetVar(uint index)
|
||||
IConfigVar* CConfigGroup::GetVar(AZ::u32 index)
|
||||
{
|
||||
if (index < m_vars.size())
|
||||
{
|
||||
@@ -76,7 +72,7 @@ namespace Config
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const IConfigVar* CConfigGroup::GetVar(uint index) const
|
||||
const IConfigVar* CConfigGroup::GetVar(AZ::u32 index) const
|
||||
{
|
||||
if (index < m_vars.size())
|
||||
{
|
||||
@@ -89,114 +85,110 @@ namespace Config
|
||||
void CConfigGroup::SaveToXML(XmlNodeRef node)
|
||||
{
|
||||
// save only values that don't have default values
|
||||
for (TConfigVariables::const_iterator it = m_vars.begin();
|
||||
it != m_vars.end(); ++it)
|
||||
for (const IConfigVar* var : m_vars)
|
||||
{
|
||||
IConfigVar* var = (*it);
|
||||
if (!var->IsFlagSet(IConfigVar::eFlag_DoNotSave))
|
||||
if (var->IsFlagSet(IConfigVar::eFlag_DoNotSave) || var->IsDefault())
|
||||
{
|
||||
if (!var->IsDefault())
|
||||
{
|
||||
const char* szName = var->GetName().c_str();
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (var->GetType())
|
||||
{
|
||||
case IConfigVar::eType_BOOL:
|
||||
{
|
||||
bool currentValue = false;
|
||||
var->Get(¤tValue);
|
||||
node->setAttr(szName, currentValue);
|
||||
break;
|
||||
}
|
||||
const char* szName = var->GetName().c_str();
|
||||
|
||||
case IConfigVar::eType_INT:
|
||||
{
|
||||
int currentValue = 0;
|
||||
var->Get(¤tValue);
|
||||
node->setAttr(szName, currentValue);
|
||||
break;
|
||||
}
|
||||
switch (var->GetType())
|
||||
{
|
||||
case IConfigVar::eType_BOOL:
|
||||
{
|
||||
bool currentValue = false;
|
||||
var->Get(¤tValue);
|
||||
node->setAttr(szName, currentValue);
|
||||
break;
|
||||
}
|
||||
|
||||
case IConfigVar::eType_FLOAT:
|
||||
{
|
||||
float currentValue = 0;
|
||||
var->Get(¤tValue);
|
||||
node->setAttr(szName, currentValue);
|
||||
break;
|
||||
}
|
||||
case IConfigVar::eType_INT:
|
||||
{
|
||||
int currentValue = 0;
|
||||
var->Get(¤tValue);
|
||||
node->setAttr(szName, currentValue);
|
||||
break;
|
||||
}
|
||||
|
||||
case IConfigVar::eType_STRING:
|
||||
{
|
||||
AZStd::string currentValue;
|
||||
var->Get(¤tValue);
|
||||
node->setAttr(szName, currentValue.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
case IConfigVar::eType_FLOAT:
|
||||
{
|
||||
float currentValue = 0;
|
||||
var->Get(¤tValue);
|
||||
node->setAttr(szName, currentValue);
|
||||
break;
|
||||
}
|
||||
|
||||
case IConfigVar::eType_STRING:
|
||||
{
|
||||
AZStd::string currentValue;
|
||||
var->Get(¤tValue);
|
||||
node->setAttr(szName, currentValue.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CConfigGroup::LoadFromXML(XmlNodeRef node)
|
||||
{
|
||||
// save only values that don't have default values
|
||||
for (TConfigVariables::const_iterator it = m_vars.begin();
|
||||
it != m_vars.end(); ++it)
|
||||
// load values that are save-able
|
||||
for (IConfigVar* var : m_vars)
|
||||
{
|
||||
IConfigVar* var = (*it);
|
||||
if (!var->IsFlagSet(IConfigVar::eFlag_DoNotSave))
|
||||
if (var->IsFlagSet(IConfigVar::eFlag_DoNotSave))
|
||||
{
|
||||
const char* szName = var->GetName().c_str();
|
||||
continue;
|
||||
}
|
||||
const char* szName = var->GetName().c_str();
|
||||
|
||||
switch (var->GetType())
|
||||
switch (var->GetType())
|
||||
{
|
||||
case IConfigVar::eType_BOOL:
|
||||
{
|
||||
bool currentValue = false;
|
||||
var->GetDefault(¤tValue);
|
||||
if (node->getAttr(szName, currentValue))
|
||||
{
|
||||
case IConfigVar::eType_BOOL:
|
||||
{
|
||||
bool currentValue = false;
|
||||
var->GetDefault(¤tValue);
|
||||
if (node->getAttr(szName, currentValue))
|
||||
{
|
||||
var->Set(¤tValue);
|
||||
}
|
||||
break;
|
||||
var->Set(¤tValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case IConfigVar::eType_INT:
|
||||
case IConfigVar::eType_INT:
|
||||
{
|
||||
int currentValue = 0;
|
||||
var->GetDefault(¤tValue);
|
||||
if (node->getAttr(szName, currentValue))
|
||||
{
|
||||
int currentValue = 0;
|
||||
var->GetDefault(¤tValue);
|
||||
if (node->getAttr(szName, currentValue))
|
||||
{
|
||||
var->Set(¤tValue);
|
||||
}
|
||||
break;
|
||||
var->Set(¤tValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case IConfigVar::eType_FLOAT:
|
||||
case IConfigVar::eType_FLOAT:
|
||||
{
|
||||
float currentValue = 0;
|
||||
var->GetDefault(¤tValue);
|
||||
if (node->getAttr(szName, currentValue))
|
||||
{
|
||||
float currentValue = 0;
|
||||
var->GetDefault(¤tValue);
|
||||
if (node->getAttr(szName, currentValue))
|
||||
{
|
||||
var->Set(¤tValue);
|
||||
}
|
||||
break;
|
||||
var->Set(¤tValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case IConfigVar::eType_STRING:
|
||||
case IConfigVar::eType_STRING:
|
||||
{
|
||||
AZStd::string currentValue;
|
||||
var->GetDefault(¤tValue);
|
||||
QString readValue(currentValue.c_str());
|
||||
if (node->getAttr(szName, readValue))
|
||||
{
|
||||
AZStd::string currentValue;
|
||||
var->GetDefault(¤tValue);
|
||||
QString readValue(currentValue.c_str());
|
||||
if (node->getAttr(szName, readValue))
|
||||
{
|
||||
currentValue = readValue.toUtf8().data();
|
||||
var->Set(¤tValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
currentValue = readValue.toUtf8().data();
|
||||
var->Set(¤tValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+21
-69
@@ -8,8 +8,12 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef CRYINCLUDE_EDITOR_CONFIGGROUP_H
|
||||
#define CRYINCLUDE_EDITOR_CONFIGGROUP_H
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
|
||||
struct ICVar;
|
||||
class XmlNodeRef;
|
||||
|
||||
namespace Config
|
||||
{
|
||||
@@ -32,7 +36,7 @@ namespace Config
|
||||
eFlag_DoNotSave = 1 << 2,
|
||||
};
|
||||
|
||||
IConfigVar(const char* szName, const char* szDescription, EType varType, uint8 flags)
|
||||
IConfigVar(const char* szName, const char* szDescription, EType varType, AZ::u8 flags)
|
||||
: m_name(szName)
|
||||
, m_description(szDescription)
|
||||
, m_type(varType)
|
||||
@@ -42,22 +46,22 @@ namespace Config
|
||||
|
||||
virtual ~IConfigVar() = default;
|
||||
|
||||
ILINE EType GetType() const
|
||||
AZ_FORCE_INLINE EType GetType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
ILINE const AZStd::string& GetName() const
|
||||
AZ_FORCE_INLINE const AZStd::string& GetName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
ILINE const AZStd::string& GetDescription() const
|
||||
AZ_FORCE_INLINE const AZStd::string& GetDescription() const
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
|
||||
ILINE bool IsFlagSet(EFlags flag) const
|
||||
AZ_FORCE_INLINE bool IsFlagSet(EFlags flag) const
|
||||
{
|
||||
return 0 != (m_flags & flag);
|
||||
}
|
||||
@@ -68,73 +72,28 @@ namespace Config
|
||||
virtual void GetDefault(void* outPtr) const = 0;
|
||||
virtual void Reset() = 0;
|
||||
|
||||
static EType TranslateType(const bool&) { return eType_BOOL; }
|
||||
static EType TranslateType(const int&) { return eType_INT; }
|
||||
static EType TranslateType(const float&) { return eType_FLOAT; }
|
||||
static EType TranslateType(const AZStd::string&) { return eType_STRING; }
|
||||
static constexpr EType TranslateType(const bool&) { return eType_BOOL; }
|
||||
static constexpr EType TranslateType(const int&) { return eType_INT; }
|
||||
static constexpr EType TranslateType(const float&) { return eType_FLOAT; }
|
||||
static constexpr EType TranslateType(const AZStd::string&) { return eType_STRING; }
|
||||
|
||||
protected:
|
||||
EType m_type;
|
||||
uint8 m_flags;
|
||||
AZ::u8 m_flags;
|
||||
AZStd::string m_name;
|
||||
AZStd::string m_description;
|
||||
void* m_ptr;
|
||||
ICVar* m_pCVar;
|
||||
};
|
||||
|
||||
// Typed wrapper for config variable
|
||||
template<class T>
|
||||
class TConfigVar
|
||||
: public IConfigVar
|
||||
{
|
||||
private:
|
||||
T m_default;
|
||||
|
||||
public:
|
||||
TConfigVar(const char* szName, const char* szDescription, uint8 flags, T& ptr, const T& defaultValue)
|
||||
: IConfigVar(szName, szDescription, IConfigVar::TranslateType(ptr), flags)
|
||||
, m_default(defaultValue)
|
||||
{
|
||||
m_ptr = &ptr;
|
||||
|
||||
// reset to default value on initializations
|
||||
ptr = defaultValue;
|
||||
}
|
||||
|
||||
virtual void Get(void* outPtr) const
|
||||
{
|
||||
*reinterpret_cast<T*>(outPtr) = *reinterpret_cast<const T*>(m_ptr);
|
||||
}
|
||||
|
||||
virtual void Set(const void* ptr)
|
||||
{
|
||||
*reinterpret_cast<T*>(m_ptr) = *reinterpret_cast<const T*>(ptr);
|
||||
}
|
||||
|
||||
virtual void Reset()
|
||||
{
|
||||
*reinterpret_cast<T*>(m_ptr) = m_default;
|
||||
}
|
||||
|
||||
virtual void GetDefault(void* outPtr) const
|
||||
{
|
||||
*reinterpret_cast<T*>(outPtr) = m_default;
|
||||
}
|
||||
|
||||
virtual bool IsDefault() const
|
||||
{
|
||||
return *reinterpret_cast<const T*>(m_ptr) == m_default;
|
||||
}
|
||||
};
|
||||
|
||||
// Group of configuration variables with optional mapping to CVars
|
||||
class CConfigGroup
|
||||
{
|
||||
private:
|
||||
typedef std::vector<IConfigVar*> TConfigVariables;
|
||||
using TConfigVariables = AZStd::vector<IConfigVar*> ;
|
||||
TConfigVariables m_vars;
|
||||
|
||||
typedef std::vector<ICVar*> TConsoleVariables;
|
||||
using TConsoleVariables = AZStd::vector<ICVar*>;
|
||||
TConsoleVariables m_consoleVars;
|
||||
|
||||
public:
|
||||
@@ -142,20 +101,13 @@ namespace Config
|
||||
virtual ~CConfigGroup();
|
||||
|
||||
void AddVar(IConfigVar* var);
|
||||
uint32 GetVarCount();
|
||||
AZ::u32 GetVarCount();
|
||||
IConfigVar* GetVar(const char* szName);
|
||||
IConfigVar* GetVar(uint index);
|
||||
IConfigVar* GetVar(AZ::u32 index);
|
||||
const IConfigVar* GetVar(const char* szName) const;
|
||||
const IConfigVar* GetVar(uint index) const;
|
||||
const IConfigVar* GetVar(AZ::u32 index) const;
|
||||
|
||||
void SaveToXML(XmlNodeRef node);
|
||||
void LoadFromXML(XmlNodeRef node);
|
||||
|
||||
template<class T>
|
||||
void AddVar(const char* szName, const char* szDescription, T& var, const T& defaultValue, uint8 flags = 0)
|
||||
{
|
||||
AddVar(new TConfigVar<T>(szName, szDescription, flags, var, defaultValue));
|
||||
}
|
||||
};
|
||||
};
|
||||
#endif // CRYINCLUDE_EDITOR_CONFIGGROUP_H
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_UTILS_PROPERTYMISCCTRL_H
|
||||
#define CRYINCLUDE_EDITOR_UTILS_PROPERTYMISCCTRL_H
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
@@ -53,6 +51,7 @@ private:
|
||||
|
||||
class UserPopupWidgetHandler : public QObject, public AzToolsFramework::PropertyHandler < CReflectedVarUser, UserPropertyEditor>
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(UserPopupWidgetHandler, AZ::SystemAllocator, 0);
|
||||
bool IsDefaultHandler() const override { return false; }
|
||||
@@ -67,6 +66,7 @@ public:
|
||||
|
||||
class FloatCurveHandler : public QObject, public AzToolsFramework::PropertyHandler < CReflectedVarSpline, CSplineCtrl>
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(FloatCurveHandler, AZ::SystemAllocator, 0);
|
||||
bool IsDefaultHandler() const override { return false; }
|
||||
@@ -80,5 +80,3 @@ public:
|
||||
|
||||
void OnSplineChange(CSplineCtrl*);
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_UTILS_PROPERTYMISCCTRL_H
|
||||
|
||||
@@ -58,17 +58,9 @@ private:
|
||||
void OnClicked() override
|
||||
{
|
||||
QString tempValue("");
|
||||
QString ext("");
|
||||
if (m_path.isEmpty() == false)
|
||||
if (!m_path.isEmpty() && !Path::GetExt(m_path).isEmpty())
|
||||
{
|
||||
if (Path::GetExt(m_path) == "")
|
||||
{
|
||||
tempValue = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
tempValue = m_path;
|
||||
}
|
||||
tempValue = m_path;
|
||||
}
|
||||
|
||||
AssetSelectionModel selection;
|
||||
|
||||
@@ -99,6 +99,7 @@ class FileResourceSelectorWidgetHandler
|
||||
: QObject
|
||||
, public AzToolsFramework::PropertyHandler < CReflectedVarResource, FileResourceSelectorWidget >
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(FileResourceSelectorWidgetHandler, AZ::SystemAllocator, 0);
|
||||
|
||||
|
||||
@@ -446,41 +446,54 @@ void ReflectedVarUserAdapter::SetVariable(IVariable *pVariable)
|
||||
m_reflectedVar.reset(new CReflectedVarUser( pVariable->GetHumanName().toUtf8().data()));
|
||||
}
|
||||
|
||||
void ReflectedVarUserAdapter::SyncReflectedVarToIVar(IVariable *pVariable)
|
||||
void ReflectedVarUserAdapter::SyncReflectedVarToIVar(IVariable* pVariable)
|
||||
{
|
||||
QString value;
|
||||
pVariable->Get(value);
|
||||
m_reflectedVar->m_value = value.toUtf8().data();
|
||||
|
||||
//extract the list of custom items from the IVariable user data
|
||||
IVariable::IGetCustomItems* pGetCustomItems = static_cast<IVariable::IGetCustomItems*> (pVariable->GetUserData().value<void *>());
|
||||
if (pGetCustomItems != nullptr)
|
||||
{
|
||||
std::vector<IVariable::IGetCustomItems::SItem> items;
|
||||
QString dlgTitle;
|
||||
// call the user supplied callback to fill-in items and get dialog title
|
||||
bool bShowIt = pGetCustomItems->GetItems(pVariable, items, dlgTitle);
|
||||
if (bShowIt) // if func didn't veto, show the dialog
|
||||
{
|
||||
m_reflectedVar->m_enableEdit = true;
|
||||
m_reflectedVar->m_useTree = pGetCustomItems->UseTree();
|
||||
m_reflectedVar->m_treeSeparator = pGetCustomItems->GetTreeSeparator();
|
||||
m_reflectedVar->m_dialogTitle = dlgTitle.toUtf8().data();
|
||||
m_reflectedVar->m_itemNames.resize(items.size());
|
||||
m_reflectedVar->m_itemDescriptions.resize(items.size());
|
||||
|
||||
QByteArray ba;
|
||||
int i = -1;
|
||||
std::generate(m_reflectedVar->m_itemNames.begin(), m_reflectedVar->m_itemNames.end(), [&items, &i, &ba]() { ++i; ba = items[i].name.toUtf8(); return ba.data(); });
|
||||
i = -1;
|
||||
std::generate(m_reflectedVar->m_itemDescriptions.begin(), m_reflectedVar->m_itemDescriptions.end(), [&items, &i, &ba]() { ++i; ba = items[i].desc.toUtf8(); return ba.data(); });
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
// extract the list of custom items from the IVariable user data
|
||||
IVariable::IGetCustomItems* pGetCustomItems = static_cast<IVariable::IGetCustomItems*>(pVariable->GetUserData().value<void*>());
|
||||
if (pGetCustomItems == nullptr)
|
||||
{
|
||||
m_reflectedVar->m_enableEdit = false;
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<IVariable::IGetCustomItems::SItem> items;
|
||||
QString dlgTitle;
|
||||
// call the user supplied callback to fill-in items and get dialog title
|
||||
bool bShowIt = pGetCustomItems->GetItems(pVariable, items, dlgTitle);
|
||||
if (!bShowIt) // if func vetoed it, don't show the dialog
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_reflectedVar->m_enableEdit = true;
|
||||
m_reflectedVar->m_useTree = pGetCustomItems->UseTree();
|
||||
m_reflectedVar->m_treeSeparator = pGetCustomItems->GetTreeSeparator();
|
||||
m_reflectedVar->m_dialogTitle = dlgTitle.toUtf8().data();
|
||||
m_reflectedVar->m_itemNames.resize(items.size());
|
||||
m_reflectedVar->m_itemDescriptions.resize(items.size());
|
||||
|
||||
QByteArray ba;
|
||||
int i = -1;
|
||||
AZStd::generate(
|
||||
m_reflectedVar->m_itemNames.begin(), m_reflectedVar->m_itemNames.end(),
|
||||
[&items, &i, &ba]()
|
||||
{
|
||||
++i;
|
||||
ba = items[i].name.toUtf8();
|
||||
return ba.data();
|
||||
});
|
||||
i = -1;
|
||||
AZStd::generate(
|
||||
m_reflectedVar->m_itemDescriptions.begin(), m_reflectedVar->m_itemDescriptions.end(),
|
||||
[&items, &i, &ba]()
|
||||
{
|
||||
++i;
|
||||
ba = items[i].desc.toUtf8();
|
||||
return ba.data();
|
||||
});
|
||||
}
|
||||
|
||||
void ReflectedVarUserAdapter::SyncIVarToReflectedVar(IVariable *pVariable)
|
||||
|
||||
@@ -126,7 +126,6 @@ void TimelineWidget::DrawTicks(QPainter* painter)
|
||||
const QPen pOldPen = painter->pen();
|
||||
|
||||
const QPen ltgray(QColor(110, 110, 110));
|
||||
const QPen black(palette().color(QPalette::Normal, QPalette::Text));
|
||||
const QPen redpen(QColor(255, 0, 255));
|
||||
|
||||
// Draw time ticks every tick step seconds.
|
||||
@@ -598,7 +597,6 @@ void TimelineWidget::DrawSecondTicks(QPainter* painter)
|
||||
{
|
||||
const QPen ltgray(QColor(110, 110, 110));
|
||||
const QPen black(palette().color(QPalette::Normal, QPalette::Text));
|
||||
const QPen redpen(QColor(255, 0, 255));
|
||||
|
||||
for (int gx = m_grid.firstGridLine.x(); gx < m_grid.firstGridLine.x() + m_grid.numGridLines.x() + 1; gx++)
|
||||
{
|
||||
|
||||
@@ -4137,7 +4137,15 @@ extern "C" int AZ_DLL_EXPORT CryEditMain(int argc, char* argv[])
|
||||
AzQtComponents::Utilities::HandleDpiAwareness(AzQtComponents::Utilities::SystemDpiAware);
|
||||
Editor::EditorQtApplication* app = Editor::EditorQtApplication::newInstance(argc, argv);
|
||||
|
||||
if (app->arguments().contains("-autotest_mode"))
|
||||
QStringList qArgs = app->arguments();
|
||||
const bool is_automated_test = AZStd::any_of(qArgs.begin(), qArgs.end(),
|
||||
[](const QString& elem)
|
||||
{
|
||||
return elem.endsWith("autotest_mode") || elem.endsWith("runpythontest");
|
||||
}
|
||||
);
|
||||
|
||||
if (is_automated_test)
|
||||
{
|
||||
// Nullroute all stdout to null for automated tests, this way we make sure
|
||||
// that the test result output is not polluted with unrelated output data.
|
||||
|
||||
@@ -431,6 +431,7 @@ public:
|
||||
class CCrySingleDocTemplate
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
explicit CCrySingleDocTemplate(const QMetaObject* pDocClass)
|
||||
: QObject()
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
// Notice : Refer to ViewportTitleDlg.cpp for a use case.
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_CUSTOMRESOLUTIONDLG_H
|
||||
#define CRYINCLUDE_EDITOR_CUSTOMRESOLUTIONDLG_H
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
@@ -28,6 +26,7 @@ namespace Ui
|
||||
class CCustomResolutionDlg
|
||||
: public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CCustomResolutionDlg(int w, int h, QWidget* pParent = nullptr);
|
||||
~CCustomResolutionDlg();
|
||||
@@ -42,5 +41,3 @@ protected:
|
||||
|
||||
QScopedPointer<Ui::CustomResolutionDlg> m_ui;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_CUSTOMRESOLUTIONDLG_H
|
||||
|
||||
@@ -211,9 +211,9 @@ public:
|
||||
|
||||
void Reset(QAction& action)
|
||||
{
|
||||
emit beginResetModel();
|
||||
beginResetModel();
|
||||
m_action = &action;
|
||||
emit endResetModel();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -266,7 +266,7 @@ QStringList CustomizeKeyboardDialog::BuildModels(QWidget* parent)
|
||||
categories.append(category);
|
||||
|
||||
QMenu* menu = menuAction->menu();
|
||||
m_menuActions[category] = GetAllActionsForMenu(menu, QStringLiteral(""));
|
||||
m_menuActions[category] = GetAllActionsForMenu(menu, QString());
|
||||
}
|
||||
|
||||
return categories;
|
||||
|
||||
@@ -25,9 +25,9 @@ namespace SandboxEditor
|
||||
connect(m_ui->okButton, &QPushButton::clicked, this, &ErrorDialog::OnOK);
|
||||
connect(
|
||||
m_ui->messages,
|
||||
SIGNAL(itemSelectionChanged()),
|
||||
&QTreeWidget::itemSelectionChanged,
|
||||
this,
|
||||
SLOT(MessageSelectionChanged()));
|
||||
&ErrorDialog::MessageSelectionChanged);
|
||||
}
|
||||
|
||||
ErrorDialog::~ErrorDialog()
|
||||
|
||||
@@ -240,7 +240,7 @@ QJsonObject KeyboardCustomizationSettings::ExportGroup()
|
||||
|
||||
void KeyboardCustomizationSettings::ImportFromFile(QWidget* parent)
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(parent, QObject::tr("Export Keyboard Shortcuts"), QStringLiteral(""), QObject::tr("Keyboard Settings (*.keys)"));
|
||||
QString fileName = QFileDialog::getOpenFileName(parent, QObject::tr("Export Keyboard Shortcuts"), QString(), QObject::tr("Keyboard Settings (*.keys)"));
|
||||
if (fileName.isEmpty())
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -419,7 +419,7 @@ void MemoryStatusItem::updateStatus()
|
||||
GeneralStatusItem::GeneralStatusItem(QString name, MainStatusBar* parent)
|
||||
: StatusBarItem(name, parent)
|
||||
{
|
||||
connect(parent, SIGNAL(messageChanged(QString)), this, SLOT(update()));
|
||||
connect(parent, &MainStatusBar::messageChanged, this, [this](const QString&) { update(); });
|
||||
}
|
||||
|
||||
QString GeneralStatusItem::CurrentText() const
|
||||
|
||||
@@ -100,9 +100,10 @@ CNewLevelDialog::CNewLevelDialog(QWidget* pParent /*=nullptr*/)
|
||||
m_level = "";
|
||||
// First of all, keyboard focus is related to widget tab order, and the default tab order is based on the order in which
|
||||
// widgets are constructed. Therefore, creating more widgets changes the keyboard focus. That is why setFocus() is called last.
|
||||
// Secondly, using singleShot() allows setFocus() slot of the QLineEdit instance to be invoked right after the event system
|
||||
// is ready to do so. Therefore, it is better to use singleShot() than directly call setFocus().
|
||||
QTimer::singleShot(0, ui->LEVEL, SLOT(OnStartup()));
|
||||
// in OnStartup()
|
||||
// Secondly, using singleShot() allows OnStartup() slot of the QLineEdit instance to be invoked right after the event system
|
||||
// is ready to do so. Therefore, it is better to use singleShot() than directly call OnStartup().
|
||||
QTimer::singleShot(0, this, &CNewLevelDialog::OnStartup);
|
||||
|
||||
ReloadLevelFolder();
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#import <AppKit/NSEvent.h>
|
||||
|
||||
#include "EditorDefs.h"
|
||||
#include "QtEditorApplication.h"
|
||||
#include "QtEditorApplication_mac.h"
|
||||
|
||||
// AzFramework
|
||||
#include <AzFramework/Input/Buses/Notifications/RawInputNotificationBus_Platform.h>
|
||||
|
||||
@@ -1788,6 +1788,11 @@ AZStd::string SandboxIntegrationManager::GetComponentEditorIcon(const AZ::Uuid&
|
||||
return iconPath;
|
||||
}
|
||||
|
||||
AZStd::string SandboxIntegrationManager::GetComponentTypeEditorIcon(const AZ::Uuid& componentType)
|
||||
{
|
||||
return GetComponentEditorIcon(componentType, nullptr);
|
||||
}
|
||||
|
||||
AZStd::string SandboxIntegrationManager::GetComponentIconPath(const AZ::Uuid& componentType,
|
||||
AZ::Crc32 componentIconAttrib, AZ::Component* component)
|
||||
{
|
||||
|
||||
@@ -233,6 +233,7 @@ private:
|
||||
}
|
||||
|
||||
AZStd::string GetComponentEditorIcon(const AZ::Uuid& componentType, AZ::Component* component) override;
|
||||
AZStd::string GetComponentTypeEditorIcon(const AZ::Uuid& componentType) override;
|
||||
AZStd::string GetComponentIconPath(const AZ::Uuid& componentType, AZ::Crc32 componentIconAttrib, AZ::Component* component) override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -197,48 +197,46 @@ AssetCatalogModel::~AssetCatalogModel()
|
||||
AzFramework::AssetCatalogEventBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
AZ::Data::AssetType AssetCatalogModel::GetAssetType(QString filename) const
|
||||
AZ::Data::AssetType AssetCatalogModel::GetAssetType(const QString &filename) const
|
||||
{
|
||||
AZ::Data::AssetType returnType = AZ::Uuid::CreateNull();
|
||||
|
||||
// Compare file extensions with the map created from the asset database.
|
||||
int dotIndex = filename.lastIndexOf('.');
|
||||
if (dotIndex >= 0)
|
||||
if (dotIndex < 0)
|
||||
{
|
||||
QString extension = filename.mid(dotIndex);
|
||||
for (auto pair : m_extensionToAssetType)
|
||||
{
|
||||
QString qExtensions = pair.first.c_str();
|
||||
if (qExtensions.indexOf(extension) >= 0)
|
||||
{
|
||||
if (pair.second.size() > 1)
|
||||
{
|
||||
// There are multiple types with this extension. Check each handler to see if they can handle this data type.
|
||||
AZStd::string azFilename = filename.toStdString().c_str();
|
||||
EBUS_EVENT(AzFramework::ApplicationRequests::Bus, MakePathAssetRootRelative, azFilename);
|
||||
AZ::Data::AssetId assetId;
|
||||
EBUS_EVENT_RESULT(assetId, AZ::Data::AssetCatalogRequestBus, GetAssetIdByPath, azFilename.c_str(), AZ::Data::s_invalidAssetType, false);
|
||||
return AZ::Uuid::CreateNull();
|
||||
}
|
||||
|
||||
for (AZ::Uuid type : pair.second)
|
||||
{
|
||||
const AZ::Data::AssetHandler* handler = AZ::Data::AssetManager::Instance().GetHandler(type);
|
||||
if (handler && handler->CanHandleAsset(assetId))
|
||||
{
|
||||
returnType = type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
returnType = pair.second[0];
|
||||
break;
|
||||
}
|
||||
QStringRef extension = filename.midRef(dotIndex);
|
||||
for (const auto& pair : m_extensionToAssetType)
|
||||
{
|
||||
QString qExtensions = pair.first.c_str();
|
||||
if (qExtensions.indexOf(extension) < 0 || pair.second.empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (pair.second.size() == 1)
|
||||
{
|
||||
return pair.second[0];
|
||||
}
|
||||
|
||||
// There are multiple types with this extension. Search for a handler that can handle this data type.
|
||||
AZStd::string azFilename = filename.toStdString().c_str();
|
||||
EBUS_EVENT(AzFramework::ApplicationRequests::Bus, MakePathAssetRootRelative, azFilename);
|
||||
AZ::Data::AssetId assetId;
|
||||
EBUS_EVENT_RESULT(assetId, AZ::Data::AssetCatalogRequestBus, GetAssetIdByPath, azFilename.c_str(), AZ::Data::s_invalidAssetType, false);
|
||||
|
||||
for (const AZ::Uuid& type : pair.second)
|
||||
{
|
||||
const AZ::Data::AssetHandler* handler = AZ::Data::AssetManager::Instance().GetHandler(type);
|
||||
if (handler && handler->CanHandleAsset(assetId))
|
||||
{
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnType;
|
||||
return AZ::Uuid::CreateNull();
|
||||
}
|
||||
|
||||
QStandardItem* AssetCatalogModel::GetPath(QString& path, bool createIfNeeded, QStandardItem* parent)
|
||||
@@ -419,7 +417,7 @@ AssetCatalogEntry* AssetCatalogModel::AddAsset(QString assetPath, AZ::Data::Asse
|
||||
// icons' memory being reclaimed and crashing the Editor.
|
||||
QSize size = fileIcon.actualSize(QSize(16, 16));
|
||||
QIcon deepCopy = fileIcon.pixmap(size).copy(0, 0, size.width(), size.height());
|
||||
|
||||
|
||||
if (!fileIcon.isNull())
|
||||
{
|
||||
m_assetTypeToIcon[assetType] = deepCopy;
|
||||
|
||||
@@ -110,7 +110,7 @@ protected:
|
||||
void SetFilterRegExp(const AZStd::string& filterType, const QRegExp& regExp);
|
||||
void ClearFilterRegExp(const AZStd::string& filterType = AZStd::string());
|
||||
|
||||
AZ::Data::AssetType GetAssetType(QString filename) const;
|
||||
AZ::Data::AssetType GetAssetType(const QString &filename) const;
|
||||
QStandardItem* GetPath(QString& path, bool createIfNeeded, QStandardItem* parent = nullptr);
|
||||
|
||||
void ApplyFilter(QStandardItem* parent);
|
||||
|
||||
+1
-1
@@ -139,7 +139,7 @@ ComponentDataModel::ComponentDataModel(QObject* parent)
|
||||
if (element.m_elementId == AZ::Edit::ClassElements::EditorData)
|
||||
{
|
||||
AZStd::string iconPath;
|
||||
EBUS_EVENT_RESULT(iconPath, AzToolsFramework::EditorRequests::Bus, GetComponentEditorIcon, classData->m_typeId, nullptr);
|
||||
AzToolsFramework::EditorRequestBus::BroadcastResult(iconPath, &AzToolsFramework::EditorRequests::GetComponentTypeEditorIcon, classData->m_typeId);
|
||||
if (!iconPath.empty())
|
||||
{
|
||||
m_componentIcons[classData->m_typeId] = QIcon(iconPath.c_str());
|
||||
|
||||
@@ -408,7 +408,7 @@ CTrackViewNodesCtrl::CTrackViewNodesCtrl(QWidget* hParentWnd, CTrackViewDialog*
|
||||
serializeContext->EnumerateDerived<AZ::Component>([this](const AZ::SerializeContext::ClassData* classData, const AZ::Uuid&) -> bool
|
||||
{
|
||||
AZStd::string iconPath;
|
||||
EBUS_EVENT_RESULT(iconPath, AzToolsFramework::EditorRequests::Bus, GetComponentEditorIcon, classData->m_typeId, nullptr);
|
||||
AzToolsFramework::EditorRequestBus::BroadcastResult(iconPath, &AzToolsFramework::EditorRequests::GetComponentTypeEditorIcon, classData->m_typeId);
|
||||
if (!iconPath.empty())
|
||||
{
|
||||
m_componentTypeToIconMap[classData->m_typeId] = QIcon(iconPath.c_str());
|
||||
|
||||
@@ -215,11 +215,6 @@ namespace AZ
|
||||
m_oldProjectPath = newProjectPath;
|
||||
|
||||
// Merge the project.json file into settings registry under ProjectSettingsRootKey path.
|
||||
AZ::IO::FixedMaxPath projectMetadataFile{ AZ::SettingsRegistryMergeUtils::FindEngineRoot(m_registry) / newProjectPath };
|
||||
projectMetadataFile /= "project.json";
|
||||
m_registry.MergeSettingsFile(projectMetadataFile.Native(),
|
||||
AZ::SettingsRegistryInterface::Format::JsonMergePatch, AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey);
|
||||
|
||||
// Update all the runtime file paths based on the new "project_path" value.
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(m_registry);
|
||||
}
|
||||
|
||||
@@ -168,6 +168,11 @@ namespace AZ
|
||||
|
||||
//! Rotation modifiers
|
||||
//! @{
|
||||
//! Set the world rotation matrix using the composition of rotations around
|
||||
//! the principle axes in the order of z-axis first and y-axis and then x-axis.
|
||||
//! @param eulerRadianAngles A Vector3 denoting radian angles of the rotations around each principle axis.
|
||||
virtual void SetWorldRotation([[maybe_unused]] const AZ::Vector3& eulerAnglesRadian) {}
|
||||
|
||||
//! Sets the entity's rotation in the world in quaternion notation.
|
||||
//! The origin of the axes is the entity's position in world space.
|
||||
//! @param quaternion A quaternion that represents the rotation to use for the entity.
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/DOM/DomVisitor.h>
|
||||
|
||||
namespace AZ::DOM
|
||||
{
|
||||
const char* VisitorError::CodeToString(VisitorErrorCode code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case VisitorErrorCode::UnsupportedOperation:
|
||||
return "operation not supported";
|
||||
case VisitorErrorCode::InvalidData:
|
||||
return "invalid data specified";
|
||||
case VisitorErrorCode::InternalError:
|
||||
return "internal error";
|
||||
default:
|
||||
return "unknown error";
|
||||
}
|
||||
}
|
||||
|
||||
VisitorError::VisitorError(VisitorErrorCode code)
|
||||
: m_code(code)
|
||||
{
|
||||
}
|
||||
|
||||
VisitorError::VisitorError(VisitorErrorCode code, AZStd::string additionalInfo)
|
||||
: m_code(code)
|
||||
, m_additionalInfo(AZStd::move(additionalInfo))
|
||||
{
|
||||
}
|
||||
|
||||
VisitorErrorCode VisitorError::GetCode() const
|
||||
{
|
||||
return m_code;
|
||||
}
|
||||
|
||||
const AZStd::string& VisitorError::GetAdditionalInfo() const
|
||||
{
|
||||
return m_additionalInfo;
|
||||
}
|
||||
|
||||
AZStd::string VisitorError::FormatVisitorErrorMessage() const
|
||||
{
|
||||
if (m_additionalInfo.empty())
|
||||
{
|
||||
return AZStd::string::format("VisitorError: %s.", CodeToString(m_code));
|
||||
}
|
||||
return AZStd::string::format("VisitorError: %s. %s.", CodeToString(m_code), m_additionalInfo.c_str());
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::VisitorFailure(VisitorErrorCode code)
|
||||
{
|
||||
return AZ::Failure(VisitorError(code));
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::VisitorFailure(VisitorErrorCode code, AZStd::string additionalInfo)
|
||||
{
|
||||
return AZ::Failure(VisitorError(code, AZStd::move(additionalInfo)));
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::VisitorFailure(VisitorError error)
|
||||
{
|
||||
return AZ::Failure(error);
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::VisitorSuccess()
|
||||
{
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::Null()
|
||||
{
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::Bool([[maybe_unused]] bool value)
|
||||
{
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::Int64([[maybe_unused]] AZ::s64 value)
|
||||
{
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::Uint64([[maybe_unused]] AZ::u64 value)
|
||||
{
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::Double([[maybe_unused]] double value)
|
||||
{
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::String([[maybe_unused]] AZStd::string_view value, [[maybe_unused]] Lifetime lifetime)
|
||||
{
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::OpaqueValue([[maybe_unused]] const OpaqueType& value, [[maybe_unused]] Lifetime lifetime)
|
||||
{
|
||||
if (!SupportsOpaqueValues())
|
||||
{
|
||||
return VisitorFailure(VisitorErrorCode::UnsupportedOperation, "Opaque values are not supported by this visitor");
|
||||
}
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::RawValue([[maybe_unused]] AZStd::string_view value, [[maybe_unused]] Lifetime lifetime)
|
||||
{
|
||||
if (!SupportsRawValues())
|
||||
{
|
||||
return VisitorFailure(VisitorErrorCode::UnsupportedOperation, "Raw values are not supported by this visitor");
|
||||
}
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::StartObject()
|
||||
{
|
||||
if (!SupportsObjects())
|
||||
{
|
||||
return VisitorFailure(VisitorErrorCode::UnsupportedOperation, "Objects are not supported by this visitor");
|
||||
}
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::EndObject([[maybe_unused]] AZ::u64 attributeCount)
|
||||
{
|
||||
if (!SupportsObjects())
|
||||
{
|
||||
return VisitorFailure(VisitorErrorCode::UnsupportedOperation, "Objects are not supported by this visitor");
|
||||
}
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::Key([[maybe_unused]] AZ::Name key)
|
||||
{
|
||||
if (!SupportsObjects() && !SupportsNodes())
|
||||
{
|
||||
return VisitorFailure(VisitorErrorCode::UnsupportedOperation, "Keys are not supported by this visitor");
|
||||
}
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::RawKey(AZStd::string_view key, [[maybe_unused]] Lifetime lifetime)
|
||||
{
|
||||
if (!SupportsRawKeys())
|
||||
{
|
||||
return VisitorFailure(VisitorErrorCode::UnsupportedOperation, "Raw keys are not supported by this visitor");
|
||||
}
|
||||
return Key(AZ::Name(key));
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::StartArray()
|
||||
{
|
||||
if (!SupportsArrays())
|
||||
{
|
||||
return VisitorFailure(VisitorErrorCode::UnsupportedOperation, "Arrays are not supported by this visitor");
|
||||
}
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::EndArray([[maybe_unused]] AZ::u64 elementCount)
|
||||
{
|
||||
if (!SupportsArrays())
|
||||
{
|
||||
return VisitorFailure(VisitorErrorCode::UnsupportedOperation, "Arrays are not supported by this visitor");
|
||||
}
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::StartNode([[maybe_unused]] AZ::Name name)
|
||||
{
|
||||
if (!SupportsNodes())
|
||||
{
|
||||
return VisitorFailure(VisitorErrorCode::UnsupportedOperation, "Nodes are not supported by this visitor");
|
||||
}
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::RawStartNode(AZStd::string_view name, [[maybe_unused]] Lifetime lifetime)
|
||||
{
|
||||
return StartNode(AZ::Name(name));
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::EndNode([[maybe_unused]] AZ::u64 attributeCount, [[maybe_unused]] AZ::u64 elementCount)
|
||||
{
|
||||
if (!SupportsNodes())
|
||||
{
|
||||
return VisitorFailure(VisitorErrorCode::UnsupportedOperation, "Nodes are not supported by this visitor");
|
||||
}
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
VisitorFlags Visitor::GetVisitorFlags() const
|
||||
{
|
||||
// By default support raw keys (promoting them to AZ::Name) and support Array / Object / Node
|
||||
// We leave Opaque type support and Raw Values to more specialized, implementation-specific cases
|
||||
return VisitorFlags::SupportsRawKeys | VisitorFlags::SupportsArrays | VisitorFlags::SupportsObjects | VisitorFlags::SupportsNodes;
|
||||
}
|
||||
|
||||
bool Visitor::SupportsRawValues() const
|
||||
{
|
||||
return (GetVisitorFlags() & VisitorFlags::SupportsRawValues) != VisitorFlags::Null;
|
||||
}
|
||||
|
||||
bool Visitor::SupportsRawKeys() const
|
||||
{
|
||||
return (GetVisitorFlags() & VisitorFlags::SupportsRawKeys) != VisitorFlags::Null;
|
||||
}
|
||||
|
||||
bool Visitor::SupportsObjects() const
|
||||
{
|
||||
return (GetVisitorFlags() & VisitorFlags::SupportsObjects) != VisitorFlags::Null;
|
||||
}
|
||||
|
||||
bool Visitor::SupportsArrays() const
|
||||
{
|
||||
return (GetVisitorFlags() & VisitorFlags::SupportsArrays) != VisitorFlags::Null;
|
||||
}
|
||||
|
||||
bool Visitor::SupportsNodes() const
|
||||
{
|
||||
return (GetVisitorFlags() & VisitorFlags::SupportsNodes) != VisitorFlags::Null;
|
||||
}
|
||||
|
||||
bool Visitor::SupportsOpaqueValues() const
|
||||
{
|
||||
return (GetVisitorFlags() & VisitorFlags::SupportsOpaqueValues) != VisitorFlags::Null;
|
||||
}
|
||||
} // namespace AZ::DOM
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Name/Name.h>
|
||||
#include <AzCore/Outcome/Outcome.h>
|
||||
#include <AzCore/std/any.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
|
||||
namespace AZ::DOM
|
||||
{
|
||||
//
|
||||
// Lifetime enum
|
||||
//
|
||||
//! Specifies the period in which a reference value will still be alive and safe to read.
|
||||
enum class Lifetime
|
||||
{
|
||||
//! Specifies that the value is safe to read and will remain so indefinitely.
|
||||
//! This implies that the value will not be mutated for the duration of this storage.
|
||||
Persistent,
|
||||
//! Specifies that the value may change or be deallocated, and must be copied to be safely stored.
|
||||
Temporary,
|
||||
};
|
||||
|
||||
//
|
||||
// VisitorErrorCode enum
|
||||
//
|
||||
//! Error code specifying the reason a Visitor operation failed.
|
||||
enum class VisitorErrorCode
|
||||
{
|
||||
//! Set when a Visitor doesn't have an implementation for a given attribute type.
|
||||
//! A pure-JSON serializer might reject a Node attribute, for example, and serialization visitors
|
||||
//! can forbid non-serializable Opaque types.
|
||||
UnsupportedOperation,
|
||||
//! Set when a Visitor has received malformed or invalid data.
|
||||
//! Potential sources include mismatching Begin/End call pairs or invalid attribute or element counts
|
||||
//! being sent to End methods.
|
||||
InvalidData,
|
||||
//! The Visitor failed for some other reason not caused by invalid input.
|
||||
//! If returning a custom error with this code, it's preferrable to also provide supplemental info
|
||||
//! in the form of an explanatory string.
|
||||
InternalError
|
||||
};
|
||||
|
||||
//
|
||||
// VisitorError class
|
||||
//
|
||||
//! Details of the reason for failure within a VisitorInterface operation.
|
||||
class VisitorError final
|
||||
{
|
||||
public:
|
||||
explicit VisitorError(VisitorErrorCode code);
|
||||
VisitorError(VisitorErrorCode code, AZStd::string additionalInfo);
|
||||
|
||||
//! Gets the error code associated with this error.
|
||||
VisitorErrorCode GetCode() const;
|
||||
//! Gets a supplemental error info string from the error.
|
||||
//! Returns an empty string if no additional information was provided to the error.
|
||||
const AZStd::string& GetAdditionalInfo() const;
|
||||
//! Provides a formatted, human-readable error description that can be used for logging purposes.
|
||||
AZStd::string FormatVisitorErrorMessage() const;
|
||||
|
||||
//! Helper method, translates a VisitorErrorCode to a human readable string.
|
||||
static const char* CodeToString(VisitorErrorCode code);
|
||||
|
||||
private:
|
||||
VisitorErrorCode m_code;
|
||||
AZStd::string m_additionalInfo;
|
||||
};
|
||||
|
||||
//! A type alias for opaque DOM types that aren't meant to be serializable.
|
||||
//! /see VisitorInterface::OpaqueValue
|
||||
using OpaqueType = AZStd::any;
|
||||
|
||||
//
|
||||
// VisitorFlags enum
|
||||
//
|
||||
//! Flags representning capabilities of a \ref Visitor.
|
||||
enum class VisitorFlags : AZ::u16
|
||||
{
|
||||
//! No flags are set. This can be used in conjunction with bitwise operators to check a flag.
|
||||
Null = 0,
|
||||
//! If set, this Visitor interface supports raw strings in place of specific value types.
|
||||
//! Visitors with this flag accept RawValue calls in lieu of more specific value calls such as Int64 or String.
|
||||
SupportsRawValues = (1 << 1),
|
||||
//! If set, this Visitor interface supports raw strings in place of Name types for keys and Node names.
|
||||
//! Visitors with this flag accept RawKey and RawStartNode in lieu of Key and StartNode calls.
|
||||
SupportsRawKeys = (1 << 2),
|
||||
//! If set, this Visitor interface supports Object types described via BeginObject and EndObject.
|
||||
SupportsObjects = (1 << 3),
|
||||
//! If set, this Visitor interface supports Array types described via BeginArray and EndArray.
|
||||
SupportsArrays = (1 << 4),
|
||||
//! If set, this Visitor interface supports Node types described BeginNode and EndNode.
|
||||
SupportsNodes = (1 << 4),
|
||||
//! If set, this Visitor interface supports opaque values described via OpaqueValue.
|
||||
SupportsOpaqueValues = (1 << 5),
|
||||
};
|
||||
|
||||
AZ_DEFINE_ENUM_BITWISE_OPERATORS(VisitorFlags);
|
||||
|
||||
//
|
||||
// Visitor class
|
||||
//
|
||||
//! An interface for performing operations on elements of a generic DOM (Document Object Model).
|
||||
//! A Document Object Model is defined here as a tree structure comprised of one of the following values:
|
||||
//! - Primitives: plain data types, including
|
||||
//! - \ref Int64: 64 bit signed integer
|
||||
//! - \ref Uint64: 64 bit unsigned integer
|
||||
//! - \ref Bool: boolean value
|
||||
//! - \ref Double: 64 bit double precision float
|
||||
//! - \ref Null: sentinel "empty" type with no value representation
|
||||
//! - \ref String: UTF8 encoded string
|
||||
//! - \ref Object: an ordered container of key/value pairs where keys are AZ::Names and values may be any DOM type
|
||||
//! (including Object)
|
||||
//! - \ref Array: an ordered container of values, in which values are any DOM value type (including Array)
|
||||
//! - \ref Node: a container
|
||||
//! - \ref OpaqueValue: An arbitrary value stored in an AZStd::any. This is a non-serializable representation of an
|
||||
//! entry useful for in-memory options. This is intended to be used as an intermediate value over the course of DOM
|
||||
//! transformation and as a proxy to pass through types of which the DOM has no knowledge to other systems.
|
||||
//!
|
||||
//! Opaque values are rejected by the default VisitorInterface implementation.
|
||||
//!
|
||||
//! Care should be ensured that DOMs representing opaque types are only visited by consumers that understand them.
|
||||
class Visitor
|
||||
{
|
||||
public:
|
||||
virtual ~Visitor() = default;
|
||||
|
||||
//! The result of a Visitor operation.
|
||||
//! A failure indicates a non-recoverable issue and signals that no further visit calls may be made in the
|
||||
//! current state.
|
||||
using Result = AZ::Outcome<void, VisitorError>;
|
||||
|
||||
//! Returns a set of flags representing the operations this Visitor supports.
|
||||
//! The base implementation supports raw keys (\see VisitorFlags::SupportsRawKeys) and
|
||||
//! arrays (\see VisitorFlags::SupportsArrays), objects (\see VisitorFlags::SupportsObjects), and
|
||||
//! nodes (\see VisitorFlags::SupportsNodes).
|
||||
//! Raw (\see VisitorFlags::SupportsRawValues) and opaque values (\see VisitorFlags::SupportsOpaqueValues)
|
||||
//! are disallowed by default, as their handling is intended to be implementation-specific.
|
||||
virtual VisitorFlags GetVisitorFlags() const;
|
||||
//! /see VisitorFlags::SupportsRawValues
|
||||
bool SupportsRawValues() const;
|
||||
//! /see VisitorFlags::SupportsRawKeys
|
||||
bool SupportsRawKeys() const;
|
||||
//! /see VisitorFlags::SupportsObjects
|
||||
bool SupportsObjects() const;
|
||||
//! /see VisitorFlags::SupportsArrays
|
||||
bool SupportsArrays() const;
|
||||
//! /see VisitorFlags::SupportsNodes
|
||||
bool SupportsNodes() const;
|
||||
//! /see VisitorFlags::SupportsOpaqueValues
|
||||
bool SupportsOpaqueValues() const;
|
||||
|
||||
//! Operates on an empty null value.
|
||||
virtual Result Null();
|
||||
//! Operates on a bool value.
|
||||
virtual Result Bool(bool value);
|
||||
//! Operates on a signed, 64 bit integer value.
|
||||
virtual Result Int64(AZ::s64 value);
|
||||
//! Operates on an unsigned, 64 bit integer value.
|
||||
virtual Result Uint64(AZ::u64 value);
|
||||
//! Operates on a double precision, 64 bit floating point value.
|
||||
virtual Result Double(double value);
|
||||
//! Operates on a string value. As strings are a reference type.
|
||||
//! Storage semantics are provided to indicate where the value may be stored persistently or requires a copy.
|
||||
virtual Result String(AZStd::string_view value, Lifetime lifetime);
|
||||
//! Operates on an opaque value. As opaque values are a reference type, storage semantics are provided to
|
||||
//! indicate where the value may be stored persistently or requires a copy.
|
||||
//! The base implementation of OpaqueValue rejects the operation, as opaque values are meant for special
|
||||
//! cases with specific implementations, not generic usage.
|
||||
//! Storage semantics are provided to indicate where the value may be stored persistently or requires a copy.
|
||||
virtual Result OpaqueValue(const OpaqueType& value, Lifetime lifetime);
|
||||
//! Operates on a raw value encoded as a UTF-8 string that hasn't had its type deduced.
|
||||
//! Visitors that support raw values (\see VisitorFlags::SupportsRawValues) may parse the raw value and
|
||||
//! forward it to the corresponding value call or calls of their choice.
|
||||
//! The base implementation of RawValue rejects the operation, as raw values are meant to be handled on
|
||||
//! a per-implementation basis.
|
||||
virtual Result RawValue(AZStd::string_view value, Lifetime lifetime);
|
||||
|
||||
//! Operates on an Object.
|
||||
//! Callers may make any number of Key calls, followed by calls representing a value (including a nested
|
||||
//! StartObject call) and then must call EndObject.
|
||||
virtual Result StartObject();
|
||||
//! Finishes operating on an Object.
|
||||
//! Callers must provide the number of attributes that were provided to the object, i.e. the number of key
|
||||
//! and value calls made within the direct context of this object (but not any nested objects / nodes).
|
||||
virtual Result EndObject(AZ::u64 attributeCount);
|
||||
|
||||
//! Specifies a key for a key/value pair.
|
||||
//! Key must be called subsequent to a call to \ref StartObject or \ref StartNode and immediately followed by
|
||||
//! calls representing the key's associated value.
|
||||
virtual Result Key(AZ::Name key);
|
||||
//! Specifies a key for a key/value pair using a raw string instead of \ref AZ::Name.
|
||||
//! \see Key
|
||||
virtual Result RawKey(AZStd::string_view key, Lifetime lifetime);
|
||||
|
||||
//! Operates on an Array.
|
||||
//! Callers may make any number of subsequent value calls to represent the elements of the array, and then must
|
||||
//! call EndArray.
|
||||
virtual Result StartArray();
|
||||
//! Finishes operating on an Array.
|
||||
//! Callers must provide the number of elements that were provided to the array, i.e. the number of value calls
|
||||
//! made within the direct context of this array (but not any nested arrays / nodes).
|
||||
virtual Result EndArray(AZ::u64 elementCount);
|
||||
|
||||
//! Operates on a Node.
|
||||
//! Callers may make any number of Key calls followed by value calls or value calls not prefixed with a Key
|
||||
//! call, and then must call EndNode. See \ref StartObject and \ref StartArray as Node types combine the
|
||||
//! functionality of both structures into a named Node structure.
|
||||
virtual Result StartNode(AZ::Name name);
|
||||
//! Operates on a Node using a raw string instead of \ref AZ::Name.
|
||||
//! \see StartNode
|
||||
virtual Result RawStartNode(AZStd::string_view name, Lifetime lifetime);
|
||||
//! Finishes operating on a Node.
|
||||
//! Callers must provide both the number of attributes the were provided and the number of elements that were
|
||||
//! provided to the node, attributes being values prefaced by a call to Key.
|
||||
virtual Result EndNode(AZ::u64 attributeCount, AZ::u64 elementCount);
|
||||
|
||||
protected:
|
||||
Visitor() = default;
|
||||
|
||||
//! Helper method, constructs a failure \ref Result with the specified code.
|
||||
static Result VisitorFailure(VisitorErrorCode code);
|
||||
//! Helper method, constructs a failure \ref Result with the specified code and supplemental info.
|
||||
static Result VisitorFailure(VisitorErrorCode code, AZStd::string additionalInfo);
|
||||
//! Helper method, constructs a failure \ref Result with the specified error.
|
||||
static Result VisitorFailure(VisitorError error);
|
||||
//! Helper method, constructs a success \ref Result.
|
||||
static Result VisitorSuccess();
|
||||
};
|
||||
} // namespace AZ::DOM
|
||||
@@ -634,12 +634,18 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
}
|
||||
|
||||
// Project name - if it was set via merging project.json use that value, otherwise use the project path's folder name.
|
||||
auto projectNameKey =
|
||||
AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey)
|
||||
constexpr auto projectNameKey =
|
||||
FixedValueString(AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey)
|
||||
+ "/project_name";
|
||||
|
||||
AZ::SettingsRegistryInterface::FixedValueString projectName;
|
||||
if (!registry.Get(projectName, projectNameKey))
|
||||
// Read the project name from the project.json file if it exists
|
||||
if (AZ::IO::FixedMaxPath projectJsonPath = normalizedProjectPath / "project.json";
|
||||
AZ::IO::SystemFile::Exists(projectJsonPath.c_str()))
|
||||
{
|
||||
registry.MergeSettingsFile(projectJsonPath.Native(),
|
||||
AZ::SettingsRegistryInterface::Format::JsonMergePatch, AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey);
|
||||
}
|
||||
if (FixedValueString projectName; !registry.Get(projectName, projectNameKey))
|
||||
{
|
||||
projectName = path.Filename().Native();
|
||||
registry.Set(projectNameKey, projectName);
|
||||
|
||||
@@ -123,6 +123,8 @@ set(FILES
|
||||
Debug/TraceMessagesDrillerBus.h
|
||||
Debug/TraceReflection.cpp
|
||||
Debug/TraceReflection.h
|
||||
DOM/DomVisitor.cpp
|
||||
DOM/DomVisitor.h
|
||||
Driller/DefaultStringPool.h
|
||||
Driller/Driller.cpp
|
||||
Driller/Driller.h
|
||||
|
||||
@@ -323,6 +323,13 @@ namespace AzFramework
|
||||
return localZ;
|
||||
}
|
||||
|
||||
void TransformComponent::SetWorldRotation(const AZ::Vector3& eulerAnglesRadian)
|
||||
{
|
||||
AZ::Transform newWorldTransform = m_worldTM;
|
||||
newWorldTransform.SetRotation(AZ::Quaternion::CreateFromEulerAnglesRadians(eulerAnglesRadian));
|
||||
SetWorldTM(newWorldTransform);
|
||||
}
|
||||
|
||||
void TransformComponent::SetWorldRotationQuaternion(const AZ::Quaternion& quaternion)
|
||||
{
|
||||
AZ::Transform newWorldTransform = m_worldTM;
|
||||
|
||||
@@ -108,6 +108,7 @@ namespace AzFramework
|
||||
float GetLocalZ() override;
|
||||
|
||||
// Rotation modifiers
|
||||
void SetWorldRotation(const AZ::Vector3& eulerAnglesRadian) override;
|
||||
void SetWorldRotationQuaternion(const AZ::Quaternion& quaternion) override;
|
||||
|
||||
AZ::Vector3 GetWorldRotation() override;
|
||||
|
||||
+67
-1
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
|
||||
namespace AzPhysics
|
||||
{
|
||||
@@ -28,6 +29,71 @@ namespace AzPhysics
|
||||
->Field("ChildLocalPosition", &JointConfiguration::m_childLocalPosition)
|
||||
->Field("StartSimulationEnabled", &JointConfiguration::m_startSimulationEnabled)
|
||||
;
|
||||
|
||||
if (auto* editContext = serializeContext->GetEditContext())
|
||||
{
|
||||
editContext->Class<JointConfiguration>("Joint Configuration", "Joint configuration.")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &JointConfiguration::m_parentLocalRotation,
|
||||
"Parent local rotation", "Parent joint frame relative to parent body.")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, &JointConfiguration::GetParentLocalRotationVisibility)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &JointConfiguration::m_parentLocalPosition,
|
||||
"Parent local position", "Joint position relative to parent body.")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, &JointConfiguration::GetParentLocalPositionVisibility)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &JointConfiguration::m_childLocalRotation,
|
||||
"Child local rotation", "Child joint frame relative to child body.")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, &JointConfiguration::GetChildLocalRotationVisibility)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &JointConfiguration::m_childLocalPosition,
|
||||
"Child local position", "Joint position relative to child body.")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, &JointConfiguration::GetChildLocalPositionVisibility)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &JointConfiguration::m_startSimulationEnabled,
|
||||
"Start simulation enabled", "When active, the joint will be enabled when the simulation begins.")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, &JointConfiguration::GetStartSimulationEnabledVisibility)
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AZ::Crc32 JointConfiguration::GetPropertyVisibility(JointConfiguration::PropertyVisibility property) const
|
||||
{
|
||||
return (m_propertyVisibilityFlags & property) != 0 ? AZ::Edit::PropertyVisibility::Show : AZ::Edit::PropertyVisibility::Hide;
|
||||
}
|
||||
|
||||
void JointConfiguration::SetPropertyVisibility(JointConfiguration::PropertyVisibility property, bool isVisible)
|
||||
{
|
||||
if (isVisible)
|
||||
{
|
||||
m_propertyVisibilityFlags |= property;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_propertyVisibilityFlags &= ~property;
|
||||
}
|
||||
}
|
||||
|
||||
AZ::Crc32 JointConfiguration::GetParentLocalRotationVisibility() const
|
||||
{
|
||||
return GetPropertyVisibility(JointConfiguration::PropertyVisibility::ParentLocalRotation);
|
||||
}
|
||||
|
||||
AZ::Crc32 JointConfiguration::GetParentLocalPositionVisibility() const
|
||||
{
|
||||
return GetPropertyVisibility(JointConfiguration::PropertyVisibility::ParentLocalPosition);
|
||||
}
|
||||
|
||||
AZ::Crc32 JointConfiguration::GetChildLocalRotationVisibility() const
|
||||
{
|
||||
return GetPropertyVisibility(JointConfiguration::PropertyVisibility::ChildLocalRotation);
|
||||
}
|
||||
|
||||
AZ::Crc32 JointConfiguration::GetChildLocalPositionVisibility() const
|
||||
{
|
||||
return GetPropertyVisibility(JointConfiguration::PropertyVisibility::ChildLocalPosition);
|
||||
}
|
||||
|
||||
AZ::Crc32 JointConfiguration::GetStartSimulationEnabledVisibility() const
|
||||
{
|
||||
return GetPropertyVisibility(JointConfiguration::PropertyVisibility::StartSimulationEnabled);
|
||||
}
|
||||
} // namespace AzPhysics
|
||||
|
||||
@@ -31,6 +31,25 @@ namespace AzPhysics
|
||||
JointConfiguration() = default;
|
||||
virtual ~JointConfiguration() = default;
|
||||
|
||||
// Visibility helpers for use in the Editor when reflected.
|
||||
enum PropertyVisibility : AZ::u8
|
||||
{
|
||||
ParentLocalRotation = 1 << 0, //!< Whether the parent local rotation is visible.
|
||||
ParentLocalPosition = 1 << 1, //!< Whether the parent local position is visible.
|
||||
ChildLocalRotation = 1 << 2, //!< Whether the child local rotation is visible.
|
||||
ChildLocalPosition = 1 << 3, //!< Whether the child local position is visible.
|
||||
StartSimulationEnabled = 1 << 4 //!< Whether the start simulation enabled setting is visible.
|
||||
};
|
||||
|
||||
AZ::Crc32 GetPropertyVisibility(PropertyVisibility property) const;
|
||||
void SetPropertyVisibility(PropertyVisibility property, bool isVisible);
|
||||
|
||||
AZ::Crc32 GetParentLocalRotationVisibility() const;
|
||||
AZ::Crc32 GetParentLocalPositionVisibility() const;
|
||||
AZ::Crc32 GetChildLocalRotationVisibility() const;
|
||||
AZ::Crc32 GetChildLocalPositionVisibility() const;
|
||||
AZ::Crc32 GetStartSimulationEnabledVisibility() const;
|
||||
|
||||
// Entity/object association.
|
||||
void* m_customUserData = nullptr;
|
||||
|
||||
@@ -40,8 +59,11 @@ namespace AzPhysics
|
||||
AZ::Quaternion m_childLocalRotation = AZ::Quaternion::CreateIdentity(); ///< Child joint frame relative to child body.
|
||||
AZ::Vector3 m_childLocalPosition = AZ::Vector3::CreateZero(); ///< Joint position relative to child body.
|
||||
bool m_startSimulationEnabled = true;
|
||||
|
||||
|
||||
// For debugging/tracking purposes only.
|
||||
AZStd::string m_debugName;
|
||||
|
||||
// Default all visibility settings to invisible, since most joint configurations don't need to display these.
|
||||
AZ::u8 m_propertyVisibilityFlags = 0;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -258,10 +258,17 @@ namespace AzFramework
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void XcbNativeWindow::SetWindowTitle(const AZStd::string& title)
|
||||
{
|
||||
// Set the title of both the window and the task bar by using
|
||||
// a buffer to hold the title twice, separated by a null-terminator
|
||||
auto doubleTitleSize = (title.size() + 1) * 2;
|
||||
AZStd::string doubleTitle(doubleTitleSize, '\0');
|
||||
azstrncpy(doubleTitle.data(), doubleTitleSize, title.c_str(), title.size());
|
||||
azstrncpy(&doubleTitle.data()[title.size() + 1], title.size(), title.c_str(), title.size());
|
||||
|
||||
xcb_void_cookie_t xcbCheckResult;
|
||||
xcbCheckResult = xcb_change_property(
|
||||
m_xcbConnection, XCB_PROP_MODE_REPLACE, m_xcbWindow, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, static_cast<uint32_t>(title.size()),
|
||||
title.c_str());
|
||||
m_xcbConnection, XCB_PROP_MODE_REPLACE, m_xcbWindow, XCB_ATOM_WM_CLASS, XCB_ATOM_STRING, 8, static_cast<uint32_t>(doubleTitle.size()),
|
||||
doubleTitle.c_str());
|
||||
AZ_Assert(ValidateXcbResult(xcbCheckResult), "Failed to set window title.");
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace AzGameFramework
|
||||
|
||||
// Used the lowercase the platform name since the bootstrap.game.<config>.<platform>.setreg is being loaded
|
||||
// from the asset cache root where all the files are in lowercased from regardless of the filesystem case-sensitivity
|
||||
static constexpr char filename[] = "bootstrap.game." AZ_BUILD_CONFIGURATION_TYPE "." AZ_TRAIT_OS_PLATFORM_CODENAME_LOWER ".setreg";
|
||||
static constexpr char filename[] = "bootstrap.game." AZ_BUILD_CONFIGURATION_TYPE ".setreg";
|
||||
|
||||
AZ::IO::FixedMaxPath cacheRootPath;
|
||||
if (registry.Get(cacheRootPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_CacheRootFolder))
|
||||
|
||||
@@ -826,6 +826,10 @@ namespace AzToolsFramework
|
||||
/// Path will be empty if component should have no icon.
|
||||
virtual AZStd::string GetComponentEditorIcon(const AZ::Uuid& /*componentType*/, AZ::Component* /*component*/) { return AZStd::string(); }
|
||||
|
||||
//! Return path to icon for component type.
|
||||
//! Path will be empty if component type should have no icon.
|
||||
virtual AZStd::string GetComponentTypeEditorIcon(const AZ::Uuid& /*componentType*/) { return AZStd::string(); }
|
||||
|
||||
/**
|
||||
* Return the icon image path based on the component type and where it is used.
|
||||
* \param componentType component type
|
||||
|
||||
+2
@@ -43,6 +43,8 @@ namespace AzToolsFramework
|
||||
};
|
||||
|
||||
//! Provides a bus to notify when the different editor modes are entered/exit.
|
||||
//! @note The editor modes are not discrete states but rather each progression of mode retain the active the parent
|
||||
//! mode that the new mode progressed from.
|
||||
class ViewportEditorModeNotifications : public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
|
||||
+27
-2
@@ -9,9 +9,27 @@
|
||||
#include <AzToolsFramework/Application/EditorEntityManager.h>
|
||||
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
static bool AreEntitiesValidForDuplication(const EntityIdList& entityIds)
|
||||
{
|
||||
for (AZ::EntityId entityId : entityIds)
|
||||
{
|
||||
if (GetEntityById(entityId) == nullptr)
|
||||
{
|
||||
AZ_Error(
|
||||
"Entity", false,
|
||||
"Entity with id '%llu' is not found. This can happen when you try to duplicate the entity before it is created. Please "
|
||||
"ensure entities are created before trying to duplicate them.",
|
||||
static_cast<AZ::u64>(entityId));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void EditorEntityManager::Start()
|
||||
{
|
||||
m_prefabPublicInterface = AZ::Interface<Prefab::PrefabPublicInterface>::Get();
|
||||
@@ -62,7 +80,11 @@ namespace AzToolsFramework
|
||||
EntityIdList selectedEntities;
|
||||
ToolsApplicationRequestBus::BroadcastResult(selectedEntities, &ToolsApplicationRequests::GetSelectedEntities);
|
||||
|
||||
m_prefabPublicInterface->DuplicateEntitiesInInstance(selectedEntities);
|
||||
if (AreEntitiesValidForDuplication(selectedEntities))
|
||||
{
|
||||
m_prefabPublicInterface->DuplicateEntitiesInInstance(selectedEntities);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void EditorEntityManager::DuplicateEntityById(AZ::EntityId entityId)
|
||||
@@ -72,7 +94,10 @@ namespace AzToolsFramework
|
||||
|
||||
void EditorEntityManager::DuplicateEntities(const EntityIdList& entities)
|
||||
{
|
||||
m_prefabPublicInterface->DuplicateEntitiesInInstance(entities);
|
||||
if (AreEntitiesValidForDuplication(entities))
|
||||
{
|
||||
m_prefabPublicInterface->DuplicateEntitiesInInstance(entities);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,5 +34,4 @@ namespace AzToolsFramework
|
||||
private:
|
||||
Prefab::PrefabPublicInterface* m_prefabPublicInterface = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ namespace AzToolsFramework
|
||||
, public AZ::BehaviorEBusHandler
|
||||
{
|
||||
AZ_EBUS_BEHAVIOR_BINDER(ToolsApplicationNotificationBusHandler, "{7EB67956-FF86-461A-91E2-7B08279CFACF}", AZ::SystemAllocator,
|
||||
EntityRegistered, EntityDeregistered);
|
||||
EntityRegistered, EntityDeregistered, AfterEntitySelectionChanged);
|
||||
|
||||
void EntityRegistered(AZ::EntityId entityId) override
|
||||
{
|
||||
@@ -187,6 +187,11 @@ namespace AzToolsFramework
|
||||
{
|
||||
Call(FN_EntityDeregistered, entityId);
|
||||
}
|
||||
|
||||
void AfterEntitySelectionChanged(const EntityIdList& newlySelectedEntities, const EntityIdList& newlyDeselectedEntities) override
|
||||
{
|
||||
Call(FN_AfterEntitySelectionChanged, newlySelectedEntities, newlyDeselectedEntities);
|
||||
}
|
||||
};
|
||||
|
||||
struct ViewPaneCallbackBusHandler final
|
||||
@@ -410,6 +415,7 @@ namespace AzToolsFramework
|
||||
->Handler<Internal::ToolsApplicationNotificationBusHandler>()
|
||||
->Event("EntityRegistered", &ToolsApplicationEvents::EntityRegistered)
|
||||
->Event("EntityDeregistered", &ToolsApplicationEvents::EntityDeregistered)
|
||||
->Event("AfterEntitySelectionChanged", &ToolsApplicationEvents::AfterEntitySelectionChanged)
|
||||
;
|
||||
|
||||
behaviorContext->Class<ViewPaneOptions>()
|
||||
@@ -428,6 +434,7 @@ namespace AzToolsFramework
|
||||
->Attribute(AZ::Script::Attributes::Module, "editor")
|
||||
->Event("RegisterCustomViewPane", &EditorRequests::RegisterCustomViewPane)
|
||||
->Event("UnregisterViewPane", &EditorRequests::UnregisterViewPane)
|
||||
->Event("GetComponentTypeEditorIcon", &EditorRequests::GetComponentTypeEditorIcon)
|
||||
;
|
||||
|
||||
behaviorContext->EBus<EditorEventsBus>("EditorEventBus")
|
||||
|
||||
@@ -1110,7 +1110,8 @@ namespace AzToolsFramework
|
||||
// Select the duplicated entities/instances
|
||||
auto selectionUndo = aznew SelectionCommand(duplicatedEntityAndInstanceIds, "Select Duplicated Entities/Instances");
|
||||
selectionUndo->SetParent(undoBatch.GetUndoBatch());
|
||||
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequestBus::Events::SetSelectedEntities, duplicatedEntityAndInstanceIds);
|
||||
ToolsApplicationRequestBus::Broadcast(
|
||||
&ToolsApplicationRequestBus::Events::SetSelectedEntities, duplicatedEntityAndInstanceIds);
|
||||
}
|
||||
|
||||
return AZ::Success(AZStd::move(duplicatedEntityAndInstanceIds));
|
||||
|
||||
+1
-1
@@ -90,7 +90,7 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
AZStd::string componentIconPath;
|
||||
EBUS_EVENT_RESULT(componentIconPath, AzToolsFramework::EditorRequests::Bus, GetComponentEditorIcon, componentClass->m_typeId, nullptr);
|
||||
AzToolsFramework::EditorRequestBus::BroadcastResult(componentIconPath, &AzToolsFramework::EditorRequests::GetComponentTypeEditorIcon, componentClass->m_typeId);
|
||||
componentIconTable[componentClass] = QString::fromUtf8(componentIconPath.c_str());
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -72,7 +72,7 @@ namespace AzToolsFramework
|
||||
|
||||
void EntityOutlinerTreeView::leaveEvent([[maybe_unused]] QEvent* event)
|
||||
{
|
||||
m_mousePosition = QPoint();
|
||||
m_mousePosition = QPoint(-1, -1);
|
||||
m_currentHoveredIndex = QModelIndex();
|
||||
update();
|
||||
}
|
||||
@@ -200,7 +200,7 @@ namespace AzToolsFramework
|
||||
const bool isEnabled = (this->model()->flags(index) & Qt::ItemIsEnabled);
|
||||
|
||||
const bool isSelected = selectionModel()->isSelected(index);
|
||||
const bool isHovered = (index == indexAt(m_mousePosition)) && isEnabled;
|
||||
const bool isHovered = (index == indexAt(m_mousePosition).siblingAtColumn(0)) && isEnabled;
|
||||
|
||||
// Paint the branch Selection/Hover Rect
|
||||
PaintBranchSelectionHoverRect(painter, rect, isSelected, isHovered);
|
||||
|
||||
+3
-6
@@ -153,6 +153,9 @@ namespace AzToolsFramework
|
||||
{
|
||||
initEntityOutlinerWidgetResources();
|
||||
|
||||
m_editorEntityUiInterface = AZ::Interface<AzToolsFramework::EditorEntityUiInterface>::Get();
|
||||
AZ_Assert(m_editorEntityUiInterface != nullptr, "EntityOutlinerWidget requires a EditorEntityUiInterface instance on Initialize.");
|
||||
|
||||
m_gui = new Ui::EntityOutlinerWidgetUI();
|
||||
m_gui->setupUi(this);
|
||||
|
||||
@@ -282,12 +285,6 @@ namespace AzToolsFramework
|
||||
|
||||
m_listModel->Initialize();
|
||||
|
||||
m_editorEntityUiInterface = AZ::Interface<AzToolsFramework::EditorEntityUiInterface>::Get();
|
||||
|
||||
AZ_Assert(
|
||||
m_editorEntityUiInterface != nullptr,
|
||||
"EntityOutlinerWidget requires a EditorEntityUiInterface instance on Initialize.");
|
||||
|
||||
EditorPickModeNotificationBus::Handler::BusConnect(GetEntityContextId());
|
||||
EntityHighlightMessages::Bus::Handler::BusConnect();
|
||||
EntityOutlinerModelNotificationBus::Handler::BusConnect();
|
||||
|
||||
+1
-1
@@ -583,7 +583,7 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
AZStd::string iconPath;
|
||||
EBUS_EVENT_RESULT(iconPath, AzToolsFramework::EditorRequests::Bus, GetComponentEditorIcon, componentType, const_cast<AZ::Component*>(&componentInstance));
|
||||
AzToolsFramework::EditorRequestBus::BroadcastResult(iconPath, &AzToolsFramework::EditorRequests::GetComponentEditorIcon, componentType, const_cast<AZ::Component*>(&componentInstance));
|
||||
GetHeader()->SetIcon(QIcon(iconPath.c_str()));
|
||||
|
||||
bool isExpanded = true;
|
||||
|
||||
+11
-3
@@ -1387,7 +1387,10 @@ namespace AzToolsFramework
|
||||
QDataStream stream(&pixmapBytes, QIODevice::ReadOnly);
|
||||
QPixmap pixmap;
|
||||
stream >> pixmap;
|
||||
GUI->SetBrowseButtonIcon(pixmap);
|
||||
if (!pixmap.isNull())
|
||||
{
|
||||
GUI->SetBrowseButtonIcon(pixmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1417,6 +1420,8 @@ namespace AzToolsFramework
|
||||
}
|
||||
else if (attrib == AZ_CRC_CE("ThumbnailIcon"))
|
||||
{
|
||||
GUI->SetCustomThumbnailEnabled(false);
|
||||
|
||||
AZStd::string iconPath;
|
||||
if (attrValue->Read<AZStd::string>(iconPath) && !iconPath.empty())
|
||||
{
|
||||
@@ -1434,8 +1439,11 @@ namespace AzToolsFramework
|
||||
QDataStream stream(&pixmapBytes, QIODevice::ReadOnly);
|
||||
QPixmap pixmap;
|
||||
stream >> pixmap;
|
||||
GUI->SetCustomThumbnailEnabled(true);
|
||||
GUI->SetCustomThumbnailPixmap(pixmap);
|
||||
if (!pixmap.isNull())
|
||||
{
|
||||
GUI->SetCustomThumbnailEnabled(true);
|
||||
GUI->SetCustomThumbnailPixmap(pixmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-10
@@ -67,16 +67,9 @@ namespace AzToolsFramework
|
||||
|
||||
void ThumbnailPropertyCtrl::SetThumbnailKey(Thumbnailer::SharedThumbnailKey key, const char* contextName)
|
||||
{
|
||||
if (m_customThumbnailEnabled)
|
||||
{
|
||||
ClearThumbnail();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_key = key;
|
||||
m_thumbnail->SetThumbnailKey(m_key, contextName);
|
||||
m_thumbnailEnlarged->SetThumbnailKey(m_key, contextName);
|
||||
}
|
||||
m_key = key;
|
||||
m_thumbnail->SetThumbnailKey(m_key, contextName);
|
||||
m_thumbnailEnlarged->SetThumbnailKey(m_key, contextName);
|
||||
UpdateVisibility();
|
||||
}
|
||||
|
||||
|
||||
@@ -301,6 +301,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
HighlightBorderSize + ViewportUiOverlayMargin, HighlightBorderSize + ViewportUiOverlayMargin);
|
||||
m_componentModeBorderText.setVisible(true);
|
||||
m_componentModeBorderText.setText(borderTitle.c_str());
|
||||
UpdateUiOverlayGeometry();
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::RemoveViewportBorder()
|
||||
@@ -427,8 +428,8 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
void ViewportUiDisplay::PositionUiOverlayOverRenderViewport()
|
||||
{
|
||||
QPoint offset = m_renderOverlay->mapToGlobal(QPoint());
|
||||
m_uiMainWindow.move(offset);
|
||||
m_uiOverlay.setFixedSize(m_renderOverlay->width(), m_renderOverlay->height());
|
||||
m_uiMainWindow.setGeometry(offset.x(), offset.y(), m_renderOverlay->width(), m_renderOverlay->height());
|
||||
m_uiOverlay.setGeometry(m_uiMainWindow.rect());
|
||||
UpdateUiOverlayGeometry();
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <AzTest/AzTest.h>
|
||||
#include <AzToolsFramework/ComponentMode/EditorComponentModeBus.h>
|
||||
#include <AzToolsFramework/FocusMode/FocusModeInterface.h>
|
||||
#include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportMessages.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorPickEntitySelection.h>
|
||||
@@ -187,10 +188,13 @@ namespace UnitTest
|
||||
ASSERT_NE(m_viewportEditorModeTracker, nullptr);
|
||||
m_viewportEditorModes = m_viewportEditorModeTracker->GetViewportEditorModes({AzToolsFramework::GetEntityContextId()});
|
||||
ASSERT_NE(m_viewportEditorModes, nullptr);
|
||||
m_focusModeInterface = AZ::Interface<AzToolsFramework::FocusModeInterface>::Get();
|
||||
ASSERT_NE(m_focusModeInterface, nullptr);
|
||||
}
|
||||
|
||||
ViewportEditorModeTrackerInterface* m_viewportEditorModeTracker = nullptr;
|
||||
const ViewportEditorModesInterface* m_viewportEditorModes = nullptr;
|
||||
AzToolsFramework::FocusModeInterface* m_focusModeInterface = nullptr;
|
||||
};
|
||||
|
||||
TEST_F(ViewportEditorModesTestsFixture, NumberOfEditorModesIsEqualTo4)
|
||||
@@ -522,32 +526,48 @@ namespace UnitTest
|
||||
}
|
||||
|
||||
TEST_F(
|
||||
ViewportEditorModeTrackerIntegrationTestFixture, EnteringComponentModeAfterInitialStateHasViewportEditorModesDefaultAndComponentModeActive)
|
||||
ViewportEditorModeTrackerIntegrationTestFixture,
|
||||
EnteringComponentModeAfterInitialStateHasViewportEditorModesDefaultAndComponentModeActive)
|
||||
{
|
||||
// When component mode is entered
|
||||
AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequestBus::Broadcast(
|
||||
&AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequests::BeginComponentMode,
|
||||
AZStd::vector<AzToolsFramework::ComponentModeFramework::EntityAndComponentModeBuilders>{});
|
||||
|
||||
bool inComponentMode = false;
|
||||
AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequestBus::BroadcastResult(
|
||||
inComponentMode, &AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequests::InComponentMode);
|
||||
|
||||
// Expect to be in component mode
|
||||
EXPECT_TRUE(inComponentMode);
|
||||
EXPECT_TRUE(AzToolsFramework::ComponentModeFramework::InComponentMode());
|
||||
|
||||
// Expect the default and component viewport editor modes to be active
|
||||
EXPECT_TRUE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Default));
|
||||
EXPECT_TRUE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Component));
|
||||
|
||||
// Do not expect the pick and focus viewport editor modes to be active
|
||||
EXPECT_FALSE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Pick));
|
||||
EXPECT_FALSE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Focus));
|
||||
}
|
||||
|
||||
TEST_F(
|
||||
ViewportEditorModeTrackerIntegrationTestFixture,
|
||||
EnteringEditorPickEntitySelectionAfterInitialStateHasOnlyViewportEditorModePickModeActive)
|
||||
ExitingComponentModeAfterEnteringFrominitialStateHasViewportEditorModesDefaultActive)
|
||||
{
|
||||
// When component mode is entered and exited
|
||||
AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequestBus::Broadcast(
|
||||
&AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequests::BeginComponentMode,
|
||||
AZStd::vector<AzToolsFramework::ComponentModeFramework::EntityAndComponentModeBuilders>{});
|
||||
|
||||
EXPECT_TRUE(AzToolsFramework::ComponentModeFramework::InComponentMode());
|
||||
|
||||
AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequestBus::Broadcast(
|
||||
&AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequests::EndComponentMode);
|
||||
|
||||
// Expect to not be in component mode
|
||||
EXPECT_FALSE(AzToolsFramework::ComponentModeFramework::InComponentMode());
|
||||
|
||||
// Expect only the default viewport editor mode to be active
|
||||
ExpectOnlyModeActive(*m_viewportEditorModes, ViewportEditorMode::Default);
|
||||
}
|
||||
|
||||
TEST_F(
|
||||
ViewportEditorModeTrackerIntegrationTestFixture,
|
||||
EnteringEditorPickEntitySelectionAfterInitialStateHasOnlyViewportEditorModePickActive)
|
||||
{
|
||||
// When entering pick mode
|
||||
using AzToolsFramework::EditorInteractionSystemViewportSelectionRequestBus;
|
||||
@@ -563,6 +583,96 @@ namespace UnitTest
|
||||
ExpectOnlyModeActive(*m_viewportEditorModes, ViewportEditorMode::Pick);
|
||||
}
|
||||
|
||||
// FocusMode integration tests will follow (LYN-6995)
|
||||
TEST_F(
|
||||
ViewportEditorModeTrackerIntegrationTestFixture,
|
||||
EnteringEditorDefaultEntitySelectionFromEditorPickEntitySelectionHasOnlyViewportEditorModeDefaultActive)
|
||||
{
|
||||
// When pick mode is entered and exited
|
||||
using AzToolsFramework::EditorInteractionSystemViewportSelectionRequestBus;
|
||||
EditorInteractionSystemViewportSelectionRequestBus::Event(
|
||||
AzToolsFramework::GetEntityContextId(), &EditorInteractionSystemViewportSelectionRequestBus::Events::SetHandler,
|
||||
[](const AzToolsFramework::EditorVisibleEntityDataCache* entityDataCache,
|
||||
[[maybe_unused]] AzToolsFramework::ViewportEditorModeTrackerInterface* viewportEditorModeTracker)
|
||||
{
|
||||
return AZStd::make_unique<AzToolsFramework::EditorPickEntitySelection>(entityDataCache, viewportEditorModeTracker);
|
||||
});
|
||||
|
||||
EditorInteractionSystemViewportSelectionRequestBus::Event(
|
||||
AzToolsFramework::GetEntityContextId(), &EditorInteractionSystemViewportSelectionRequestBus::Events::SetHandler,
|
||||
[](const AzToolsFramework::EditorVisibleEntityDataCache* entityDataCache,
|
||||
[[maybe_unused]] AzToolsFramework::ViewportEditorModeTrackerInterface* viewportEditorModeTracker)
|
||||
{
|
||||
return AZStd::make_unique<AzToolsFramework::EditorDefaultSelection>(entityDataCache, viewportEditorModeTracker);
|
||||
});
|
||||
|
||||
// Expect only the default viewport editor mode to be active
|
||||
ExpectOnlyModeActive(*m_viewportEditorModes, ViewportEditorMode::Default);
|
||||
}
|
||||
|
||||
TEST_F(ViewportEditorModeTrackerIntegrationTestFixture, EnteringFocusModeAfterInitialStateHasViewportEditorModeDefaultAndPickActive)
|
||||
{
|
||||
// When entering focus mode
|
||||
m_focusModeInterface->SetFocusRoot(AZ::EntityId{ 1 });
|
||||
|
||||
// Expect the default and focus viewport editor modes to be active
|
||||
EXPECT_TRUE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Default));
|
||||
EXPECT_TRUE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Focus));
|
||||
EXPECT_FALSE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Pick));
|
||||
EXPECT_FALSE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Component));
|
||||
}
|
||||
|
||||
TEST_F(
|
||||
ViewportEditorModeTrackerIntegrationTestFixture,
|
||||
ExitingFocusModeAfterEnteringFromInitialStateHasOnlyViewportEditorModeDefaultActive)
|
||||
{
|
||||
// When entering and leaving focus mode
|
||||
m_focusModeInterface->SetFocusRoot(AZ::EntityId{ 1 });
|
||||
m_focusModeInterface->SetFocusRoot(AZ::EntityId());
|
||||
|
||||
// Expect only the default mode to be active
|
||||
ExpectOnlyModeActive(*m_viewportEditorModes, ViewportEditorMode::Default);
|
||||
}
|
||||
|
||||
TEST_F(ViewportEditorModeTrackerIntegrationTestFixture, EnteringComponentModeFromFocusModeStateHasViewportEditorModeDefaultAndFocusAndComponentActive)
|
||||
{
|
||||
// When entering component mode from focus mode
|
||||
m_focusModeInterface->SetFocusRoot(AZ::EntityId{ 1 });
|
||||
AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequestBus::Broadcast(
|
||||
&AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequests::BeginComponentMode,
|
||||
AZStd::vector<AzToolsFramework::ComponentModeFramework::EntityAndComponentModeBuilders>{});
|
||||
|
||||
// Expect to be in component mode
|
||||
EXPECT_TRUE(AzToolsFramework::ComponentModeFramework::InComponentMode());
|
||||
|
||||
// Expect the default, focus and component viewport editor modes to be active
|
||||
EXPECT_TRUE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Default));
|
||||
EXPECT_TRUE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Focus));
|
||||
EXPECT_TRUE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Component));
|
||||
EXPECT_FALSE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Pick));
|
||||
}
|
||||
|
||||
TEST_F(
|
||||
ViewportEditorModeTrackerIntegrationTestFixture,
|
||||
ExitingComponentModeAfterEnteringFromFocusModeHasViewportEditorModeDefaultAndFocusActive)
|
||||
{
|
||||
// When entering and leaving component mode from focus mode
|
||||
m_focusModeInterface->SetFocusRoot(AZ::EntityId{ 1 });
|
||||
AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequestBus::Broadcast(
|
||||
&AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequests::BeginComponentMode,
|
||||
AZStd::vector<AzToolsFramework::ComponentModeFramework::EntityAndComponentModeBuilders>{});
|
||||
|
||||
EXPECT_TRUE(AzToolsFramework::ComponentModeFramework::InComponentMode());
|
||||
|
||||
AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequestBus::Broadcast(
|
||||
&AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequests::EndComponentMode);
|
||||
|
||||
// Expect to not be in component mode
|
||||
EXPECT_FALSE(AzToolsFramework::ComponentModeFramework::InComponentMode());
|
||||
|
||||
// Expect the default and focus viewport editor modes to be active
|
||||
EXPECT_TRUE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Default));
|
||||
EXPECT_TRUE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Focus));
|
||||
EXPECT_FALSE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Component));
|
||||
EXPECT_FALSE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Pick));
|
||||
}
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -60,13 +60,6 @@
|
||||
|
||||
#include <platform.h>
|
||||
|
||||
#if defined(WIN32) || defined(WIN64) || defined(APPLE) || defined(LINUX)
|
||||
#if defined(DEDICATED_SERVER)
|
||||
// enable/disable map load slicing functionality from the build
|
||||
#define MAP_LOADING_SLICING
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <AzCore/PlatformIncl.h>
|
||||
#include <tlhelp32.h>
|
||||
|
||||
@@ -115,17 +115,20 @@ CViewSystem::CViewSystem(ISystem* pSystem)
|
||||
, m_useDeferredViewSystemUpdate(false)
|
||||
, m_bControlsAudioListeners(true)
|
||||
{
|
||||
#if !defined(_RELEASE) && !defined(DEDICATED_SERVER)
|
||||
if (!s_debugCamera)
|
||||
#if !defined(_RELEASE)
|
||||
if (!gEnv->IsDedicated())
|
||||
{
|
||||
s_debugCamera = new DebugCamera;
|
||||
}
|
||||
if (!s_debugCamera)
|
||||
{
|
||||
s_debugCamera = new DebugCamera;
|
||||
}
|
||||
|
||||
REGISTER_COMMAND("debugCameraToggle", ToggleDebugCamera, VF_DEV_ONLY, "Toggle the debug camera.\n");
|
||||
REGISTER_COMMAND("debugCameraInvertY", ToggleDebugCameraInvertY, VF_DEV_ONLY, "Toggle debug camera Y-axis inversion.\n");
|
||||
REGISTER_COMMAND("debugCameraMove", DebugCameraMove, VF_DEV_ONLY, "Move the debug camera the specified distance (x y z).\n");
|
||||
gEnv->pConsole->CreateKeyBind("ctrl_keyboard_key_punctuation_backslash", "debugCameraToggle");
|
||||
gEnv->pConsole->CreateKeyBind("alt_keyboard_key_punctuation_backslash", "debugCameraInvertY");
|
||||
REGISTER_COMMAND("debugCameraToggle", ToggleDebugCamera, VF_DEV_ONLY, "Toggle the debug camera.\n");
|
||||
REGISTER_COMMAND("debugCameraInvertY", ToggleDebugCameraInvertY, VF_DEV_ONLY, "Toggle debug camera Y-axis inversion.\n");
|
||||
REGISTER_COMMAND("debugCameraMove", DebugCameraMove, VF_DEV_ONLY, "Move the debug camera the specified distance (x y z).\n");
|
||||
gEnv->pConsole->CreateKeyBind("ctrl_keyboard_key_punctuation_backslash", "debugCameraToggle");
|
||||
gEnv->pConsole->CreateKeyBind("alt_keyboard_key_punctuation_backslash", "debugCameraInvertY");
|
||||
}
|
||||
#endif
|
||||
|
||||
REGISTER_CVAR2("cl_camera_noise", &m_fCameraNoise, -1, 0,
|
||||
@@ -167,6 +170,21 @@ CViewSystem::~CViewSystem()
|
||||
{
|
||||
m_pSystem->GetILevelSystem()->RemoveListener(this);
|
||||
}
|
||||
|
||||
#if !defined(_RELEASE)
|
||||
if (!gEnv->IsDedicated())
|
||||
{
|
||||
UNREGISTER_COMMAND("debugCameraToggle");
|
||||
UNREGISTER_COMMAND("debugCameraInvertY");
|
||||
UNREGISTER_COMMAND("debugCameraMove");
|
||||
|
||||
if (s_debugCamera)
|
||||
{
|
||||
delete s_debugCamera;
|
||||
s_debugCamera = nullptr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
@@ -47,6 +47,10 @@ ly_add_target(
|
||||
AZ::AssetBundlerBatch.Static
|
||||
)
|
||||
|
||||
# Adds a specialized .setreg to identify gems enabled in the active project.
|
||||
# This associates the AssetBundlerBatch target with the .Builders gem variants.
|
||||
ly_set_gem_variant_to_load(TARGETS AssetBundlerBatch VARIANTS Builders)
|
||||
|
||||
# AssetBundler - Qt GUI Application
|
||||
ly_add_target(
|
||||
NAME AssetBundler ${PAL_TRAIT_BUILD_ASSETBUNDLER_APPLICATION_TYPE}
|
||||
@@ -73,6 +77,10 @@ ly_add_target(
|
||||
${additional_dependencies}
|
||||
)
|
||||
|
||||
# Adds a specialized .setreg to identify gems enabled in the active project.
|
||||
# This associates the AssetBundler target with the .Builders gem variants.
|
||||
ly_set_gem_variant_to_load(TARGETS AssetBundler VARIANTS Builders)
|
||||
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
|
||||
|
||||
ly_add_target(
|
||||
|
||||
@@ -54,7 +54,12 @@ namespace AssetBundler
|
||||
bool ApplicationManager::Init()
|
||||
{
|
||||
AZ::Debug::TraceMessageBus::Handler::BusConnect();
|
||||
Start(AzFramework::Application::Descriptor());
|
||||
|
||||
ComponentApplication::StartupParameters startupParameters;
|
||||
// The AssetBundler does not need to load gems
|
||||
startupParameters.m_loadDynamicModules = false;
|
||||
Start(AzFramework::Application::Descriptor(), startupParameters);
|
||||
|
||||
AZ::SerializeContext* context;
|
||||
EBUS_EVENT_RESULT(context, AZ::ComponentApplicationBus, GetSerializeContext);
|
||||
AZ_Assert(context, "No serialize context");
|
||||
|
||||
@@ -71,7 +71,11 @@ namespace AssetBundler
|
||||
|
||||
|
||||
m_data->m_applicationManager.reset(aznew MockApplicationManagerTest(0, 0));
|
||||
m_data->m_applicationManager->Start(AzFramework::Application::Descriptor());
|
||||
|
||||
AZ::ComponentApplication::StartupParameters startupParameters;
|
||||
// The AssetBundler does not need to load gems
|
||||
startupParameters.m_loadDynamicModules = false;
|
||||
m_data->m_applicationManager->Start(AzFramework::Application::Descriptor(), startupParameters);
|
||||
|
||||
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
|
||||
// shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash
|
||||
|
||||
@@ -259,6 +259,11 @@ namespace AssetProcessor
|
||||
scratchBuffer.reserve(512 * 1024); // Reserve 512kb to avoid repeatedly resizing the buffer;
|
||||
AZStd::fixed_vector<AZStd::string_view, AzFramework::MaxPlatformCodeNames> platformCodes;
|
||||
AzFramework::PlatformHelper::AppendPlatformCodeNames(platformCodes, request.m_platformInfo.m_identifier);
|
||||
AZ_Assert(platformCodes.size() <= 1, "A one-to-one mapping of asset type platform identifier"
|
||||
" to platform codename is required in the SettingsRegistryBuilder."
|
||||
" The bootstrap.game is now only produced per build configuration and doesn't take into account"
|
||||
" different platforms names");
|
||||
|
||||
const AZStd::string& assetPlatformIdentifier = request.m_jobDescription.GetPlatformIdentifier();
|
||||
// Determines the suffix that will be used for the launcher based on processing server vs non-server assets
|
||||
const char* launcherType = assetPlatformIdentifier != AzFramework::PlatformHelper::GetPlatformName(AzFramework::PlatformId::SERVER)
|
||||
@@ -293,9 +298,10 @@ namespace AssetProcessor
|
||||
outputBuffer.Reserve(512 * 1024); // Reserve 512kb to avoid repeatedly resizing the buffer;
|
||||
SettingsExporter exporter(outputBuffer, excludes);
|
||||
|
||||
for (AZStd::string_view platform : platformCodes)
|
||||
if (!platformCodes.empty())
|
||||
{
|
||||
AZ::u32 productSubID = static_cast<AZ::u32>(AZStd::hash<AZStd::string_view>{}(platform)); // Deliberately ignoring half the bits.
|
||||
AZStd::string_view platform = platformCodes.front();
|
||||
constexpr AZ::u32 productSubID = 0;
|
||||
for (size_t i = 0; i < AZStd::size(specializations); ++i)
|
||||
{
|
||||
const AZ::SettingsRegistryInterface::Specializations& specialization = specializations[i];
|
||||
@@ -337,7 +343,7 @@ namespace AssetProcessor
|
||||
// The purpose of this section is to copy the Gem's SourcePaths from the Global Settings Registry
|
||||
// the local SettingsRegistry. The reason this is needed is so that the call to
|
||||
// `MergeSettingsToRegistry_GemRegistries` below is able to locate each gem's "<gem-root>/Registry" folder
|
||||
// that will be merged into the bootstrap.game.<configuration>.<platform>.setreg file
|
||||
// that will be merged into the bootstrap.game.<configuration>.setreg file
|
||||
// This is used by the GameLauncher applications to read from a single merged .setreg file
|
||||
// containing the settings needed to run a game/simulation without have access to the source code base registry
|
||||
AZStd::vector<AzFramework::GemInfo> gemInfos;
|
||||
@@ -408,8 +414,6 @@ namespace AssetProcessor
|
||||
}
|
||||
|
||||
outputPath += specialization.GetSpecialization(0); // Append configuration
|
||||
outputPath += '.';
|
||||
outputPath += platform;
|
||||
outputPath += ".setreg";
|
||||
|
||||
AZ::IO::SystemFile file;
|
||||
|
||||
@@ -4447,7 +4447,9 @@ AssetBuilderSDK::AssetBuilderDesc MockBuilderInfoHandler::CreateBuilderDesc(cons
|
||||
|
||||
void FingerprintTest::SetUp()
|
||||
{
|
||||
AZ_Printf("FingerprintTest", "SetUp start");
|
||||
AssetProcessorManagerTest::SetUp();
|
||||
AZ_Printf("FingerprintTest", "SetUp self");
|
||||
|
||||
// We don't want the mock application manager to provide builder descriptors, mockBuilderInfoHandler will provide our own
|
||||
m_mockApplicationManager->BusDisconnect();
|
||||
@@ -4466,18 +4468,23 @@ void FingerprintTest::SetUp()
|
||||
});
|
||||
|
||||
ASSERT_TRUE(UnitTestUtils::CreateDummyFile(m_absolutePath, ""));
|
||||
AZ_Printf("FingerprintTest", "SetUp end");
|
||||
}
|
||||
|
||||
void FingerprintTest::TearDown()
|
||||
{
|
||||
AZ_Printf("FingerprintTest", "TearDown start");
|
||||
m_jobResults = AZStd::vector<AssetProcessor::JobDetails>{};
|
||||
m_mockBuilderInfoHandler = {};
|
||||
|
||||
AZ_Printf("FingerprintTest", "TearDown parent");
|
||||
AssetProcessorManagerTest::TearDown();
|
||||
AZ_Printf("FingerprintTest", "TearDown end");
|
||||
}
|
||||
|
||||
void FingerprintTest::RunFingerprintTest(QString builderFingerprint, QString jobFingerprint, bool expectedResult)
|
||||
{
|
||||
AZ_Printf("FingerprintTest", "Fingerprint Test Start");
|
||||
m_mockBuilderInfoHandler.m_builderDesc.m_analysisFingerprint = builderFingerprint.toUtf8().data();
|
||||
m_mockBuilderInfoHandler.m_jobFingerprint = jobFingerprint;
|
||||
QMetaObject::invokeMethod(m_assetProcessorManager.get(), "AssessModifiedFile", Qt::QueuedConnection, Q_ARG(QString, m_absolutePath));
|
||||
@@ -4486,6 +4493,7 @@ void FingerprintTest::RunFingerprintTest(QString builderFingerprint, QString job
|
||||
ASSERT_EQ(m_mockBuilderInfoHandler.m_createJobsCount, 1);
|
||||
ASSERT_EQ(m_jobResults.size(), 1);
|
||||
ASSERT_EQ(m_jobResults[0].m_autoFail, expectedResult);
|
||||
AZ_Printf("FingerprintTest", "Fingerprint Test End");
|
||||
}
|
||||
|
||||
TEST_F(FingerprintTest, FingerprintChecking_JobFingerprint_NoBuilderFingerprint)
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#endif
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <AzCore/UnitTest/UnitTest.h>
|
||||
|
||||
//! These macros can be used for checking your unit tests,
|
||||
//! you can check AssetScannerUnitTest.cpp for usage
|
||||
@@ -155,6 +156,7 @@ namespace UnitTestUtils
|
||||
|
||||
bool OnPreWarning([[maybe_unused]] const char* window, [[maybe_unused]] const char* fileName, [[maybe_unused]] int line, [[maybe_unused]] const char* func, [[maybe_unused]] const char* message) override
|
||||
{
|
||||
UnitTest::ColoredPrintf(UnitTest::COLOR_YELLOW, message);
|
||||
++m_numWarningsAbsorbed;
|
||||
if (m_debugMessages)
|
||||
{
|
||||
@@ -165,6 +167,7 @@ namespace UnitTestUtils
|
||||
|
||||
bool OnPreAssert([[maybe_unused]] const char* fileName, [[maybe_unused]] int line, [[maybe_unused]] const char* func, [[maybe_unused]] const char* message) override
|
||||
{
|
||||
UnitTest::ColoredPrintf(UnitTest::COLOR_YELLOW, message);
|
||||
++m_numAssertsAbsorbed;
|
||||
if (m_debugMessages)
|
||||
{
|
||||
@@ -175,6 +178,7 @@ namespace UnitTestUtils
|
||||
|
||||
bool OnPreError([[maybe_unused]] const char* window, [[maybe_unused]] const char* fileName, [[maybe_unused]] int line, [[maybe_unused]] const char* func, [[maybe_unused]] const char* message) override
|
||||
{
|
||||
UnitTest::ColoredPrintf(UnitTest::COLOR_YELLOW, message);
|
||||
++m_numErrorsAbsorbed;
|
||||
if (m_debugMessages)
|
||||
{
|
||||
@@ -183,8 +187,9 @@ namespace UnitTestUtils
|
||||
return true; // I handled this, do not forward it
|
||||
}
|
||||
|
||||
bool OnPrintf(const char* /*window*/, const char* /*message*/) override
|
||||
bool OnPrintf(const char* /*window*/, const char* message) override
|
||||
{
|
||||
UnitTest::ColoredPrintf(UnitTest::COLOR_YELLOW, message);
|
||||
++m_numMessagesAbsorbed;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -21,8 +21,7 @@ namespace O3DE::ProjectManager
|
||||
return AZ::Success(QStringList{ ProjectCMakeCommand,
|
||||
"-B", targetBuildPath,
|
||||
"-S", m_projectInfo.m_path,
|
||||
QString("-DLY_3RDPARTY_PATH=").append(thirdPartyPath),
|
||||
"-DLY_UNITY_BUILD=ON" } );
|
||||
QString("-DLY_3RDPARTY_PATH=").append(thirdPartyPath) } );
|
||||
}
|
||||
|
||||
AZ::Outcome<QStringList, QString> ProjectBuilderWorker::ConstructCmakeBuildCommandArguments() const
|
||||
|
||||
@@ -242,11 +242,15 @@ QTabBar::tab:focus {
|
||||
|
||||
/************** Project Settings **************/
|
||||
#projectSettings {
|
||||
margin-top:42px;
|
||||
margin-top:30px;
|
||||
}
|
||||
|
||||
#projectPreviewLabel {
|
||||
margin: 10px 0 5px 0;
|
||||
}
|
||||
|
||||
#projectTemplate {
|
||||
margin: 55px 0 0 50px;
|
||||
margin: 25px 0 0 50px;
|
||||
}
|
||||
#projectTemplateLabel {
|
||||
font-size:16px;
|
||||
@@ -691,6 +695,12 @@ QProgressBar::chunk {
|
||||
|
||||
#gemRepoAddDialogInstructionTitleLabel {
|
||||
font-size:14px;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
#gemRepoAddDialogWarningLabel {
|
||||
font-size:12px;
|
||||
font-style:italic;
|
||||
}
|
||||
|
||||
#addGemRepoDialog #formFrame {
|
||||
|
||||
@@ -11,19 +11,28 @@
|
||||
#include <FormFolderBrowseEditWidget.h>
|
||||
#include <PythonBindingsInterface.h>
|
||||
#include <PathValidator.h>
|
||||
#include <AzQtComponents/Utilities/DesktopUtilities.h>
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
#include <QScrollArea>
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
EngineSettingsScreen::EngineSettingsScreen(QWidget* parent)
|
||||
: ScreenWidget(parent)
|
||||
{
|
||||
auto* layout = new QVBoxLayout();
|
||||
QScrollArea* scrollArea = new QScrollArea(this);
|
||||
scrollArea->setWidgetResizable(true);
|
||||
|
||||
QWidget* scrollWidget = new QWidget(this);
|
||||
scrollArea->setWidget(scrollWidget);
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout(scrollWidget);
|
||||
layout->setAlignment(Qt::AlignTop);
|
||||
scrollWidget->setLayout(layout);
|
||||
|
||||
setObjectName("engineSettingsScreen");
|
||||
|
||||
@@ -39,9 +48,18 @@ namespace O3DE::ProjectManager
|
||||
formTitleLabel->setObjectName("formTitleLabel");
|
||||
layout->addWidget(formTitleLabel);
|
||||
|
||||
m_engineVersion = new FormLineEditWidget(tr("Engine Version"), engineInfo.m_version, this);
|
||||
m_engineVersion->lineEdit()->setReadOnly(true);
|
||||
layout->addWidget(m_engineVersion);
|
||||
FormLineEditWidget* engineName = new FormLineEditWidget(tr("Engine Name"), engineInfo.m_name, this);
|
||||
engineName->lineEdit()->setReadOnly(true);
|
||||
layout->addWidget(engineName);
|
||||
|
||||
FormLineEditWidget* engineVersion = new FormLineEditWidget(tr("Engine Version"), engineInfo.m_version, this);
|
||||
engineVersion->lineEdit()->setReadOnly(true);
|
||||
layout->addWidget(engineVersion);
|
||||
|
||||
FormBrowseEditWidget* engineFolder = new FormBrowseEditWidget(tr("Engine Folder"), engineInfo.m_path, this);
|
||||
engineFolder->lineEdit()->setReadOnly(true);
|
||||
connect( engineFolder, &FormBrowseEditWidget::OnBrowse, [engineInfo]{ AzQtComponents::ShowFileOnDesktop(engineInfo.m_path); });
|
||||
layout->addWidget(engineFolder);
|
||||
|
||||
m_thirdParty = new FormFolderBrowseEditWidget(tr("3rd Party Software Folder"), engineInfo.m_thirdPartyPath, this);
|
||||
m_thirdParty->lineEdit()->setValidator(new PathValidator(PathValidator::PathMode::ExistingFolder, this));
|
||||
@@ -71,7 +89,11 @@ namespace O3DE::ProjectManager
|
||||
connect(m_defaultProjectTemplates->lineEdit(), &QLineEdit::textChanged, this, &EngineSettingsScreen::OnTextChanged);
|
||||
layout->addWidget(m_defaultProjectTemplates);
|
||||
|
||||
setLayout(layout);
|
||||
QVBoxLayout* mainLayout = new QVBoxLayout();
|
||||
mainLayout->setAlignment(Qt::AlignTop);
|
||||
mainLayout->setMargin(0);
|
||||
mainLayout->addWidget(scrollArea);
|
||||
setLayout(mainLayout);
|
||||
}
|
||||
|
||||
ProjectManagerScreen EngineSettingsScreen::GetScreenEnum()
|
||||
|
||||
@@ -29,7 +29,6 @@ namespace O3DE::ProjectManager
|
||||
void OnTextChanged();
|
||||
|
||||
private:
|
||||
FormLineEditWidget* m_engineVersion;
|
||||
FormBrowseEditWidget* m_thirdParty;
|
||||
FormBrowseEditWidget* m_defaultProjects;
|
||||
FormBrowseEditWidget* m_defaultGems;
|
||||
|
||||
@@ -20,7 +20,8 @@ namespace O3DE::ProjectManager
|
||||
setObjectName("formBrowseEditWidget");
|
||||
|
||||
QPushButton* browseButton = new QPushButton(this);
|
||||
connect(browseButton, &QPushButton::pressed, this, &FormBrowseEditWidget::HandleBrowseButton);
|
||||
connect( browseButton, &QPushButton::pressed, [this]{ emit OnBrowse(); });
|
||||
connect( this, &FormBrowseEditWidget::OnBrowse, this, &FormBrowseEditWidget::HandleBrowseButton);
|
||||
m_frameLayout->addWidget(browseButton);
|
||||
}
|
||||
|
||||
@@ -34,7 +35,7 @@ namespace O3DE::ProjectManager
|
||||
int key = event->key();
|
||||
if (key == Qt::Key_Return || key == Qt::Key_Enter)
|
||||
{
|
||||
HandleBrowseButton();
|
||||
emit OnBrowse();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,10 +24,13 @@ namespace O3DE::ProjectManager
|
||||
explicit FormBrowseEditWidget(const QString& labelText = "", QWidget* parent = nullptr);
|
||||
~FormBrowseEditWidget() = default;
|
||||
|
||||
signals:
|
||||
void OnBrowse();
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent* event) override;
|
||||
|
||||
protected slots:
|
||||
virtual void HandleBrowseButton() = 0;
|
||||
virtual void HandleBrowseButton() {};
|
||||
};
|
||||
} // namespace O3DE::ProjectManager
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace O3DE::ProjectManager
|
||||
|
||||
void GemCatalogScreen::ReinitForProject(const QString& projectPath)
|
||||
{
|
||||
m_gemModel->clear();
|
||||
m_gemModel->Clear();
|
||||
m_gemsToRegisterWithProject.clear();
|
||||
FillModel(projectPath);
|
||||
|
||||
@@ -145,10 +145,11 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
}
|
||||
|
||||
void GemCatalogScreen::OnGemStatusChanged(const QModelIndex& modelIndex, uint32_t numChangedDependencies)
|
||||
void GemCatalogScreen::OnGemStatusChanged(const QString& gemName, uint32_t numChangedDependencies)
|
||||
{
|
||||
if (m_notificationsEnabled)
|
||||
{
|
||||
QModelIndex modelIndex = m_gemModel->FindIndexByNameString(gemName);
|
||||
bool added = GemModel::IsAdded(modelIndex);
|
||||
bool dependency = GemModel::IsAddedDependency(modelIndex);
|
||||
|
||||
@@ -167,6 +168,10 @@ namespace O3DE::ProjectManager
|
||||
{
|
||||
notification += " " + tr("and") + " ";
|
||||
}
|
||||
if (added && GemModel::GetDownloadStatus(modelIndex) == GemInfo::DownloadStatus::NotDownloaded)
|
||||
{
|
||||
m_downloadController->AddGemDownload(GemModel::GetName(modelIndex));
|
||||
}
|
||||
}
|
||||
|
||||
if (numChangedDependencies == 1 )
|
||||
@@ -229,7 +234,11 @@ namespace O3DE::ProjectManager
|
||||
const QVector<GemInfo> allRepoGemInfos = allRepoGemInfosResult.GetValue();
|
||||
for (const GemInfo& gemInfo : allRepoGemInfos)
|
||||
{
|
||||
m_gemModel->AddGem(gemInfo);
|
||||
// do not add gems that have already been downloaded
|
||||
if (!m_gemModel->FindIndexByNameString(gemInfo.m_name).isValid())
|
||||
{
|
||||
m_gemModel->AddGem(gemInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -253,7 +262,8 @@ namespace O3DE::ProjectManager
|
||||
GemModel::SetWasPreviouslyAdded(*m_gemModel, modelIndex, true);
|
||||
GemModel::SetIsAdded(*m_gemModel, modelIndex, true);
|
||||
}
|
||||
else
|
||||
// ${Name} is a special name used in templates and is not really an error
|
||||
else if (enabledGemName != "${Name}")
|
||||
{
|
||||
AZ_Warning("ProjectManager::GemCatalog", false,
|
||||
"Cannot find entry for gem with name '%s'. The CMake target name probably does not match the specified name in the gem.json.",
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace O3DE::ProjectManager
|
||||
DownloadController* GetDownloadController() const { return m_downloadController; }
|
||||
|
||||
public slots:
|
||||
void OnGemStatusChanged(const QModelIndex& modelIndex, uint32_t numChangedDependencies);
|
||||
void OnGemStatusChanged(const QString& gemName, uint32_t numChangedDependencies);
|
||||
void OnAddGemClicked();
|
||||
|
||||
protected:
|
||||
|
||||
@@ -225,21 +225,22 @@ namespace O3DE::ProjectManager
|
||||
QVector<QString> elementNames;
|
||||
QVector<int> elementCounts;
|
||||
const int totalGems = m_gemModel->rowCount();
|
||||
const int selectedGemTotal = m_gemModel->TotalAddedGems();
|
||||
const int selectedGemTotal = m_gemModel->GatherGemsToBeAdded(/*includeDependencies=*/true).size();
|
||||
const int unselectedGemTotal = m_gemModel->GatherGemsToBeRemoved(/*includeDependencies=*/true).size();
|
||||
const int enabledGemTotal = m_gemModel->TotalAddedGems(/*includeDependencies=*/true);
|
||||
|
||||
elementNames.push_back(GemSortFilterProxyModel::GetGemSelectedString(GemSortFilterProxyModel::GemSelected::Unselected));
|
||||
elementCounts.push_back(totalGems - selectedGemTotal);
|
||||
|
||||
elementNames.push_back(GemSortFilterProxyModel::GetGemSelectedString(GemSortFilterProxyModel::GemSelected::Selected));
|
||||
elementCounts.push_back(selectedGemTotal);
|
||||
|
||||
elementNames.push_back(GemSortFilterProxyModel::GetGemActiveString(GemSortFilterProxyModel::GemActive::Inactive));
|
||||
elementCounts.push_back(totalGems - enabledGemTotal);
|
||||
elementNames.push_back(GemSortFilterProxyModel::GetGemSelectedString(GemSortFilterProxyModel::GemSelected::Unselected));
|
||||
elementCounts.push_back(unselectedGemTotal);
|
||||
|
||||
elementNames.push_back(GemSortFilterProxyModel::GetGemActiveString(GemSortFilterProxyModel::GemActive::Active));
|
||||
elementCounts.push_back(enabledGemTotal);
|
||||
|
||||
elementNames.push_back(GemSortFilterProxyModel::GetGemActiveString(GemSortFilterProxyModel::GemActive::Inactive));
|
||||
elementCounts.push_back(totalGems - enabledGemTotal);
|
||||
|
||||
bool wasCollapsed = false;
|
||||
if (m_statusFilter)
|
||||
{
|
||||
@@ -262,44 +263,51 @@ namespace O3DE::ProjectManager
|
||||
|
||||
const QList<QAbstractButton*> buttons = m_statusFilter->GetButtonGroup()->buttons();
|
||||
|
||||
QAbstractButton* unselectedButton = buttons[0];
|
||||
QAbstractButton* selectedButton = buttons[1];
|
||||
unselectedButton->setChecked(m_filterProxyModel->GetGemSelected() == GemSortFilterProxyModel::GemSelected::Unselected);
|
||||
selectedButton->setChecked(m_filterProxyModel->GetGemSelected() == GemSortFilterProxyModel::GemSelected::Selected);
|
||||
QAbstractButton* selectedButton = buttons[0];
|
||||
QAbstractButton* unselectedButton = buttons[1];
|
||||
selectedButton->setChecked(m_filterProxyModel->GetGemSelected() == GemSortFilterProxyModel::GemSelected::Selected);
|
||||
unselectedButton->setChecked(m_filterProxyModel->GetGemSelected() == GemSortFilterProxyModel::GemSelected::Unselected);
|
||||
|
||||
auto updateGemSelection = [=]([[maybe_unused]] bool checked)
|
||||
{
|
||||
if (unselectedButton->isChecked() && !selectedButton->isChecked())
|
||||
{
|
||||
m_filterProxyModel->SetGemSelected(GemSortFilterProxyModel::GemSelected::Unselected);
|
||||
}
|
||||
else if (!unselectedButton->isChecked() && selectedButton->isChecked())
|
||||
if (!unselectedButton->isChecked() && selectedButton->isChecked())
|
||||
{
|
||||
m_filterProxyModel->SetGemSelected(GemSortFilterProxyModel::GemSelected::Selected);
|
||||
}
|
||||
else if (unselectedButton->isChecked() && !selectedButton->isChecked())
|
||||
{
|
||||
m_filterProxyModel->SetGemSelected(GemSortFilterProxyModel::GemSelected::Unselected);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_filterProxyModel->SetGemSelected(GemSortFilterProxyModel::GemSelected::NoFilter);
|
||||
if (unselectedButton->isChecked() && selectedButton->isChecked())
|
||||
{
|
||||
m_filterProxyModel->SetGemSelected(GemSortFilterProxyModel::GemSelected::Both);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_filterProxyModel->SetGemSelected(GemSortFilterProxyModel::GemSelected::NoFilter);
|
||||
}
|
||||
}
|
||||
};
|
||||
connect(unselectedButton, &QAbstractButton::toggled, this, updateGemSelection);
|
||||
connect(selectedButton, &QAbstractButton::toggled, this, updateGemSelection);
|
||||
|
||||
QAbstractButton* inactiveButton = buttons[2];
|
||||
QAbstractButton* activeButton = buttons[3];
|
||||
inactiveButton->setChecked(m_filterProxyModel->GetGemActive() == GemSortFilterProxyModel::GemActive::Inactive);
|
||||
activeButton->setChecked(m_filterProxyModel->GetGemActive() == GemSortFilterProxyModel::GemActive::Active);
|
||||
QAbstractButton* activeButton = buttons[2];
|
||||
QAbstractButton* inactiveButton = buttons[3];
|
||||
activeButton->setChecked(m_filterProxyModel->GetGemActive() == GemSortFilterProxyModel::GemActive::Active);
|
||||
inactiveButton->setChecked(m_filterProxyModel->GetGemActive() == GemSortFilterProxyModel::GemActive::Inactive);
|
||||
|
||||
auto updateGemActive = [=]([[maybe_unused]] bool checked)
|
||||
{
|
||||
if (inactiveButton->isChecked() && !activeButton->isChecked())
|
||||
{
|
||||
m_filterProxyModel->SetGemActive(GemSortFilterProxyModel::GemActive::Inactive);
|
||||
}
|
||||
else if (!inactiveButton->isChecked() && activeButton->isChecked())
|
||||
if (!inactiveButton->isChecked() && activeButton->isChecked())
|
||||
{
|
||||
m_filterProxyModel->SetGemActive(GemSortFilterProxyModel::GemActive::Active);
|
||||
}
|
||||
else if (inactiveButton->isChecked() && !activeButton->isChecked())
|
||||
{
|
||||
m_filterProxyModel->SetGemActive(GemSortFilterProxyModel::GemActive::Inactive);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_filterProxyModel->SetGemActive(GemSortFilterProxyModel::GemActive::NoFilter);
|
||||
|
||||
@@ -27,6 +27,14 @@ namespace O3DE::ProjectManager
|
||||
|
||||
void GemModel::AddGem(const GemInfo& gemInfo)
|
||||
{
|
||||
if (FindIndexByNameString(gemInfo.m_name).isValid())
|
||||
{
|
||||
// do not add gems with duplicate names
|
||||
// this can happen by mistake or when a gem repo has a gem with the same name as a local gem
|
||||
AZ_TracePrintf("GemModel", "Ignoring duplicate gem: %s", gemInfo.m_name.toUtf8().constData());
|
||||
return;
|
||||
}
|
||||
|
||||
QStandardItem* item = new QStandardItem();
|
||||
|
||||
item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
|
||||
@@ -60,6 +68,7 @@ namespace O3DE::ProjectManager
|
||||
void GemModel::Clear()
|
||||
{
|
||||
clear();
|
||||
m_nameToIndexMap.clear();
|
||||
}
|
||||
|
||||
void GemModel::UpdateGemDependencies()
|
||||
@@ -276,9 +285,11 @@ namespace O3DE::ProjectManager
|
||||
|
||||
void GemModel::SetIsAdded(QAbstractItemModel& model, const QModelIndex& modelIndex, bool isAdded)
|
||||
{
|
||||
// get the gemName first, because the modelIndex data change after adding because of filters
|
||||
QString gemName = modelIndex.data(RoleName).toString();
|
||||
model.setData(modelIndex, isAdded, RoleIsAdded);
|
||||
|
||||
UpdateDependencies(model, modelIndex);
|
||||
UpdateDependencies(model, gemName, isAdded);
|
||||
}
|
||||
|
||||
bool GemModel::HasDependentGems(const QModelIndex& modelIndex) const
|
||||
@@ -294,15 +305,17 @@ namespace O3DE::ProjectManager
|
||||
return false;
|
||||
}
|
||||
|
||||
void GemModel::UpdateDependencies(QAbstractItemModel& model, const QModelIndex& modelIndex)
|
||||
void GemModel::UpdateDependencies(QAbstractItemModel& model, const QString& gemName, bool isAdded)
|
||||
{
|
||||
GemModel* gemModel = GetSourceModel(&model);
|
||||
AZ_Assert(gemModel, "Failed to obtain GemModel");
|
||||
|
||||
QModelIndex modelIndex = gemModel->FindIndexByNameString(gemName);
|
||||
|
||||
QVector<QModelIndex> dependencies = gemModel->GatherGemDependencies(modelIndex);
|
||||
uint32_t numChangedDependencies = 0;
|
||||
|
||||
if (IsAdded(modelIndex))
|
||||
if (isAdded)
|
||||
{
|
||||
for (const QModelIndex& dependency : dependencies)
|
||||
{
|
||||
@@ -324,7 +337,7 @@ namespace O3DE::ProjectManager
|
||||
bool hasDependentGems = gemModel->HasDependentGems(modelIndex);
|
||||
if (IsAddedDependency(modelIndex) != hasDependentGems)
|
||||
{
|
||||
SetIsAddedDependency(model, modelIndex, hasDependentGems);
|
||||
SetIsAddedDependency(*gemModel, modelIndex, hasDependentGems);
|
||||
}
|
||||
|
||||
for (const QModelIndex& dependency : dependencies)
|
||||
@@ -343,7 +356,7 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
}
|
||||
|
||||
gemModel->emit gemStatusChanged(modelIndex, numChangedDependencies);
|
||||
gemModel->emit gemStatusChanged(gemName, numChangedDependencies);
|
||||
}
|
||||
|
||||
void GemModel::SetIsAddedDependency(QAbstractItemModel& model, const QModelIndex& modelIndex, bool isAdded)
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace O3DE::ProjectManager
|
||||
static bool NeedsToBeAdded(const QModelIndex& modelIndex, bool includeDependencies = false);
|
||||
static bool NeedsToBeRemoved(const QModelIndex& modelIndex, bool includeDependencies = false);
|
||||
static bool HasRequirement(const QModelIndex& modelIndex);
|
||||
static void UpdateDependencies(QAbstractItemModel& model, const QModelIndex& modelIndex);
|
||||
static void UpdateDependencies(QAbstractItemModel& model, const QString& gemName, bool isAdded);
|
||||
static void SetDownloadStatus(QAbstractItemModel& model, const QModelIndex& modelIndex, GemInfo::DownloadStatus status);
|
||||
|
||||
bool DoGemsToBeAddedHaveRequirements() const;
|
||||
@@ -78,7 +78,7 @@ namespace O3DE::ProjectManager
|
||||
int TotalAddedGems(bool includeDependencies = false) const;
|
||||
|
||||
signals:
|
||||
void gemStatusChanged(const QModelIndex& modelIndex, uint32_t numChangedDependencies);
|
||||
void gemStatusChanged(const QString& gemName, uint32_t numChangedDependencies);
|
||||
|
||||
private:
|
||||
void FindGemDisplayNamesByNameStrings(QStringList& inOutGemNames);
|
||||
|
||||
@@ -50,11 +50,26 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
}
|
||||
|
||||
// Gem selected
|
||||
if (m_gemSelectedFilter != GemSelected::NoFilter)
|
||||
// Gem selected
|
||||
if (m_gemSelectedFilter == GemSelected::Selected)
|
||||
{
|
||||
const GemSelected sourceGemStatus = static_cast<GemSelected>(GemModel::IsAdded(sourceIndex));
|
||||
if (m_gemSelectedFilter != sourceGemStatus)
|
||||
if (!GemModel::NeedsToBeAdded(sourceIndex, true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Gem unselected
|
||||
else if (m_gemSelectedFilter == GemSelected::Unselected)
|
||||
{
|
||||
if (!GemModel::NeedsToBeRemoved(sourceIndex, true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Gem selected or unselected
|
||||
else if (m_gemSelectedFilter == GemSelected::Both)
|
||||
{
|
||||
if (!GemModel::NeedsToBeAdded(sourceIndex, true) && !GemModel::NeedsToBeRemoved(sourceIndex, true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@ namespace O3DE::ProjectManager
|
||||
{
|
||||
NoFilter = -1,
|
||||
Unselected,
|
||||
Selected
|
||||
Selected,
|
||||
Both
|
||||
};
|
||||
enum class GemActive
|
||||
{
|
||||
|
||||
@@ -27,6 +27,7 @@ namespace O3DE::ProjectManager
|
||||
QVBoxLayout* vLayout = new QVBoxLayout();
|
||||
vLayout->setContentsMargins(30, 30, 25, 10);
|
||||
vLayout->setSpacing(0);
|
||||
vLayout->setAlignment(Qt::AlignTop);
|
||||
setLayout(vLayout);
|
||||
|
||||
QLabel* instructionTitleLabel = new QLabel(tr("Enter a valid path to add a new user repository"));
|
||||
@@ -41,9 +42,18 @@ namespace O3DE::ProjectManager
|
||||
vLayout->addWidget(instructionContextLabel);
|
||||
|
||||
m_repoPath = new FormFolderBrowseEditWidget(tr("Repository Path"), "", this);
|
||||
m_repoPath->setFixedWidth(600);
|
||||
m_repoPath->setFixedSize(QSize(600, 100));
|
||||
vLayout->addWidget(m_repoPath);
|
||||
|
||||
vLayout->addSpacing(10);
|
||||
|
||||
QLabel* warningLabel = new QLabel(tr("Online repositories may contain files that could potentially harm your computer,"
|
||||
" please ensure you understand the risks before downloading Gems from third-party sources."));
|
||||
warningLabel->setObjectName("gemRepoAddDialogWarningLabel");
|
||||
warningLabel->setWordWrap(true);
|
||||
warningLabel->setAlignment(Qt::AlignLeft);
|
||||
vLayout->addWidget(warningLabel);
|
||||
|
||||
vLayout->addSpacing(40);
|
||||
|
||||
QDialogButtonBox* dialogButtons = new QDialogButtonBox();
|
||||
|
||||
@@ -133,6 +133,11 @@ namespace O3DE::ProjectManager
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we are already on this screen still notify we are on this screen to refresh it
|
||||
newScreen->NotifyCurrentScreen();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace O3DE::ProjectManager
|
||||
|
||||
QLabel* projectPreviewLabel = new QLabel(tr("Select an image (PNG). Minimum %1 x %2 pixels.")
|
||||
.arg(QString::number(ProjectPreviewImageWidth), QString::number(ProjectPreviewImageHeight)));
|
||||
projectPreviewLabel->setObjectName("projectPreviewLabel");
|
||||
previewExtrasLayout->addWidget(projectPreviewLabel);
|
||||
|
||||
m_projectPreviewImage = new QLabel(this);
|
||||
|
||||
+4
-4
@@ -108,7 +108,7 @@ TEST_F(AWSGameLiftClientLocalTicketTrackerTest, StartPolling_CallWithoutClientSe
|
||||
MatchmakingNotificationsHandlerMock matchmakingHandlerMock;
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
m_gameliftClientTicketTracker->StartPolling("ticket1", "player1");
|
||||
WaitForProcessFinish([](){ return ::UnitTest::TestRunner::Instance().m_numAssertsFailed == 1; });
|
||||
WaitForProcessFinish([&](){ return matchmakingHandlerMock.m_numMatchError == 1; });
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
ASSERT_TRUE(matchmakingHandlerMock.m_numMatchError == 1);
|
||||
ASSERT_FALSE(m_gameliftClientTicketTracker->IsTrackerIdle());
|
||||
@@ -122,7 +122,7 @@ TEST_F(AWSGameLiftClientLocalTicketTrackerTest, StartPolling_MultipleCallsWithou
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
m_gameliftClientTicketTracker->StartPolling("ticket1", "player1");
|
||||
m_gameliftClientTicketTracker->StartPolling("ticket1", "player1");
|
||||
WaitForProcessFinish([](){ return ::UnitTest::TestRunner::Instance().m_numAssertsFailed == 1; });
|
||||
WaitForProcessFinish([&](){ return matchmakingHandlerMock.m_numMatchError == 1; });
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
ASSERT_TRUE(matchmakingHandlerMock.m_numMatchError == 1);
|
||||
ASSERT_FALSE(m_gameliftClientTicketTracker->IsTrackerIdle());
|
||||
@@ -140,7 +140,7 @@ TEST_F(AWSGameLiftClientLocalTicketTrackerTest, StartPolling_CallButWithFailedOu
|
||||
MatchmakingNotificationsHandlerMock matchmakingHandlerMock;
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
m_gameliftClientTicketTracker->StartPolling("ticket1", "player1");
|
||||
WaitForProcessFinish([](){ return ::UnitTest::TestRunner::Instance().m_numAssertsFailed == 1; });
|
||||
WaitForProcessFinish([&](){ return matchmakingHandlerMock.m_numMatchError == 1; });
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
ASSERT_TRUE(matchmakingHandlerMock.m_numMatchError == 1);
|
||||
ASSERT_FALSE(m_gameliftClientTicketTracker->IsTrackerIdle());
|
||||
@@ -160,7 +160,7 @@ TEST_F(AWSGameLiftClientLocalTicketTrackerTest, StartPolling_CallWithMoreThanOne
|
||||
MatchmakingNotificationsHandlerMock matchmakingHandlerMock;
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
m_gameliftClientTicketTracker->StartPolling("ticket1", "player1");
|
||||
WaitForProcessFinish([](){ return ::UnitTest::TestRunner::Instance().m_numAssertsFailed == 1; });
|
||||
WaitForProcessFinish([&](){ return matchmakingHandlerMock.m_numMatchError == 1; });
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
ASSERT_TRUE(matchmakingHandlerMock.m_numMatchError == 1);
|
||||
ASSERT_FALSE(m_gameliftClientTicketTracker->IsTrackerIdle());
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Settings/SettingsRegistry.h>
|
||||
|
||||
#include <CommonFiles/Preprocessor.h>
|
||||
#include <CommonFiles/GlobalBuildOptions.h>
|
||||
@@ -91,19 +92,31 @@ namespace AZ
|
||||
m_shaderAssetBuilder.BusConnect(shaderAssetBuilderDescriptor.m_busId);
|
||||
AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBus::Handler::RegisterBuilderInformation, shaderAssetBuilderDescriptor);
|
||||
|
||||
// Register Shader Variant Asset Builder
|
||||
AssetBuilderSDK::AssetBuilderDesc shaderVariantAssetBuilderDescriptor;
|
||||
shaderVariantAssetBuilderDescriptor.m_name = "Shader Variant Asset Builder";
|
||||
// Both "Shader Variant Asset Builder" and "Shader Asset Builder" produce ShaderVariantAsset products. If you update
|
||||
// ShaderVariantAsset you will need to update BOTH version numbers, not just "Shader Variant Asset Builder".
|
||||
shaderVariantAssetBuilderDescriptor.m_version = 26; // [AZSL] Changing inlineConstant to rootConstant keyword work.
|
||||
shaderVariantAssetBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern(AZStd::string::format("*.%s", RPI::ShaderVariantListSourceData::Extension), AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
|
||||
shaderVariantAssetBuilderDescriptor.m_busId = azrtti_typeid<ShaderVariantAssetBuilder>();
|
||||
shaderVariantAssetBuilderDescriptor.m_createJobFunction = AZStd::bind(&ShaderVariantAssetBuilder::CreateJobs, &m_shaderVariantAssetBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
|
||||
shaderVariantAssetBuilderDescriptor.m_processJobFunction = AZStd::bind(&ShaderVariantAssetBuilder::ProcessJob, &m_shaderVariantAssetBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
|
||||
// If, either the SettingsRegistry doesn't exist, or the property @EnableShaderVariantAssetBuilderRegistryKey is not found,
|
||||
// the default is to enable the ShaderVariantAssetBuilder.
|
||||
m_enableShaderVariantAssetBuilder = true;
|
||||
auto settingsRegistry = AZ::SettingsRegistry::Get();
|
||||
if (settingsRegistry)
|
||||
{
|
||||
settingsRegistry->Get(m_enableShaderVariantAssetBuilder, EnableShaderVariantAssetBuilderRegistryKey);
|
||||
}
|
||||
|
||||
m_shaderVariantAssetBuilder.BusConnect(shaderVariantAssetBuilderDescriptor.m_busId);
|
||||
AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBus::Handler::RegisterBuilderInformation, shaderVariantAssetBuilderDescriptor);
|
||||
if (m_enableShaderVariantAssetBuilder)
|
||||
{
|
||||
// Register Shader Variant Asset Builder
|
||||
AssetBuilderSDK::AssetBuilderDesc shaderVariantAssetBuilderDescriptor;
|
||||
shaderVariantAssetBuilderDescriptor.m_name = "Shader Variant Asset Builder";
|
||||
// Both "Shader Variant Asset Builder" and "Shader Asset Builder" produce ShaderVariantAsset products. If you update
|
||||
// ShaderVariantAsset you will need to update BOTH version numbers, not just "Shader Variant Asset Builder".
|
||||
shaderVariantAssetBuilderDescriptor.m_version = 26; // [AZSL] Changing inlineConstant to rootConstant keyword work.
|
||||
shaderVariantAssetBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern(AZStd::string::format("*.%s", RPI::ShaderVariantListSourceData::Extension), AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
|
||||
shaderVariantAssetBuilderDescriptor.m_busId = azrtti_typeid<ShaderVariantAssetBuilder>();
|
||||
shaderVariantAssetBuilderDescriptor.m_createJobFunction = AZStd::bind(&ShaderVariantAssetBuilder::CreateJobs, &m_shaderVariantAssetBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
|
||||
shaderVariantAssetBuilderDescriptor.m_processJobFunction = AZStd::bind(&ShaderVariantAssetBuilder::ProcessJob, &m_shaderVariantAssetBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
|
||||
|
||||
m_shaderVariantAssetBuilder.BusConnect(shaderVariantAssetBuilderDescriptor.m_busId);
|
||||
AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBus::Handler::RegisterBuilderInformation, shaderVariantAssetBuilderDescriptor);
|
||||
}
|
||||
|
||||
// Register Precompiled Shader Builder
|
||||
AssetBuilderSDK::AssetBuilderDesc precompiledShaderBuilderDescriptor;
|
||||
@@ -121,7 +134,10 @@ namespace AZ
|
||||
void AzslShaderBuilderSystemComponent::Deactivate()
|
||||
{
|
||||
m_shaderAssetBuilder.BusDisconnect();
|
||||
m_shaderVariantAssetBuilder.BusDisconnect();
|
||||
if (m_enableShaderVariantAssetBuilder)
|
||||
{
|
||||
m_shaderVariantAssetBuilder.BusDisconnect();
|
||||
}
|
||||
m_precompiledShaderBuilder.BusDisconnect();
|
||||
|
||||
RHI::ShaderPlatformInterfaceRegisterBus::Handler::BusDisconnect();
|
||||
|
||||
@@ -61,7 +61,17 @@ namespace AZ
|
||||
|
||||
private:
|
||||
ShaderAssetBuilder m_shaderAssetBuilder;
|
||||
|
||||
// The ShaderVariantAssetBuilder can be disabled with this registry key.
|
||||
// By default it is enabled. A user might want to disable it when doing look development
|
||||
// work with shaders or doing lots of iterative changes to shaders. In these cases
|
||||
// GPU performance doesn't matter at all so it is important to not waste time
|
||||
// building ShaderVariantAssets (Other than the Root ShaderVariantAsset, of course.).
|
||||
static constexpr char EnableShaderVariantAssetBuilderRegistryKey[] = "/O3DE/Atom/Shaders/BuildVariants";
|
||||
bool m_enableShaderVariantAssetBuilder = true;
|
||||
|
||||
ShaderVariantAssetBuilder m_shaderVariantAssetBuilder;
|
||||
|
||||
PrecompiledShaderBuilder m_precompiledShaderBuilder;
|
||||
|
||||
/// Contains the ShaderPlatformInterface for all registered RHIs
|
||||
|
||||
@@ -477,8 +477,8 @@ namespace AZ
|
||||
preprocessorOptions.m_predefinedMacros.end(), macroDefinitionsToAdd.begin(), macroDefinitionsToAdd.end());
|
||||
// Run the preprocessor.
|
||||
PreprocessorData output;
|
||||
PreprocessFile(prependedAzslFilePath, output, preprocessorOptions, true, true);
|
||||
RHI::ReportErrorMessages(ShaderAssetBuilderName, output.diagnostics);
|
||||
const bool preprocessorSuccess = PreprocessFile(prependedAzslFilePath, output, preprocessorOptions, true, true);
|
||||
RHI::ReportMessages(ShaderAssetBuilderName, output.diagnostics, !preprocessorSuccess);
|
||||
// Dump the preprocessed string as a flat AZSL file with extension .azslin, which will be given to AZSLc to generate the HLSL file.
|
||||
AZStd::string superVariantAzslinStemName = shaderFileName;
|
||||
if (!supervariantInfo.m_name.IsEmpty())
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"O3DE": {
|
||||
"Atom": {
|
||||
"Shaders": {
|
||||
"BuildVariants": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <AzCore/NativeUI/NativeUIRequests.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
#include <AzFramework/Components/TransformComponent.h>
|
||||
@@ -115,7 +116,9 @@ namespace AZ
|
||||
{
|
||||
// GFX TODO - investigate window creation being part of the GameApplication.
|
||||
|
||||
m_nativeWindow = AZStd::make_unique<AzFramework::NativeWindow>("O3DELauncher", AzFramework::WindowGeometry(0, 0, 1920, 1080));
|
||||
auto projectTitle = AZ::Utils::GetProjectName();
|
||||
|
||||
m_nativeWindow = AZStd::make_unique<AzFramework::NativeWindow>(projectTitle.c_str(), AzFramework::WindowGeometry(0, 0, 1920, 1080));
|
||||
AZ_Assert(m_nativeWindow, "Failed to create the game window\n");
|
||||
|
||||
m_nativeWindow->Activate();
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
{
|
||||
"description": "Material Type with properties used to define Enhanced PBR, a metallic-roughness Physically-Based Rendering (PBR) material shading model, with advanced features like subsurface scattering, transmission, and anisotropy.",
|
||||
"version": 3,
|
||||
"version": 4,
|
||||
"versionUpdates": [
|
||||
{
|
||||
"toVersion": 4,
|
||||
"actions": [
|
||||
{"op": "rename", "from": "opacity.doubleSided", "to": "general.doubleSided"}
|
||||
]
|
||||
}
|
||||
],
|
||||
"propertyLayout": {
|
||||
"groups": [
|
||||
{
|
||||
@@ -92,6 +100,12 @@
|
||||
],
|
||||
"properties": {
|
||||
"general": [
|
||||
{
|
||||
"name": "doubleSided",
|
||||
"displayName": "Double-sided",
|
||||
"description": "Whether to render back-faces or just front-faces.",
|
||||
"type": "Bool"
|
||||
},
|
||||
{
|
||||
"name": "applySpecularAA",
|
||||
"displayName": "Apply Specular AA",
|
||||
@@ -709,12 +723,6 @@
|
||||
"name": "m_opacityFactor"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "doubleSided",
|
||||
"displayName": "Double-sided",
|
||||
"description": "Whether to render back-faces or just front-faces.",
|
||||
"type": "Bool"
|
||||
},
|
||||
{
|
||||
"name": "alphaAffectsSpecular",
|
||||
"displayName": "Alpha affects specular",
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
{
|
||||
"description": "Material Type with properties used to define Standard PBR, a metallic-roughness Physically-Based Rendering (PBR) material shading model.",
|
||||
"version": 3,
|
||||
"version": 4,
|
||||
"versionUpdates": [
|
||||
{
|
||||
"toVersion": 4,
|
||||
"actions": [
|
||||
{"op": "rename", "from": "opacity.doubleSided", "to": "general.doubleSided"}
|
||||
]
|
||||
}
|
||||
],
|
||||
"propertyLayout": {
|
||||
"groups": [
|
||||
{
|
||||
@@ -72,6 +80,12 @@
|
||||
],
|
||||
"properties": {
|
||||
"general": [
|
||||
{
|
||||
"name": "doubleSided",
|
||||
"displayName": "Double-sided",
|
||||
"description": "Whether to render back-faces or just front-faces.",
|
||||
"type": "Bool"
|
||||
},
|
||||
{
|
||||
"name": "applySpecularAA",
|
||||
"displayName": "Apply Specular AA",
|
||||
@@ -650,12 +664,6 @@
|
||||
"name": "m_opacityFactor"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "doubleSided",
|
||||
"displayName": "Double-sided",
|
||||
"description": "Whether to render back-faces or just front-faces.",
|
||||
"type": "Bool"
|
||||
},
|
||||
{
|
||||
"name": "alphaAffectsSpecular",
|
||||
"displayName": "Alpha affects specular",
|
||||
|
||||
+2
-2
@@ -10,14 +10,14 @@
|
||||
----------------------------------------------------------------------------------------------------
|
||||
|
||||
function GetMaterialPropertyDependencies()
|
||||
return {"opacity.doubleSided"}
|
||||
return {"general.doubleSided"}
|
||||
end
|
||||
|
||||
ForwardPassIndex = 0
|
||||
ForwardPassEdsIndex = 1
|
||||
|
||||
function Process(context)
|
||||
local doubleSided = context:GetMaterialPropertyValue_bool("opacity.doubleSided")
|
||||
local doubleSided = context:GetMaterialPropertyValue_bool("general.doubleSided")
|
||||
local lastShader = context:GetShaderCount() - 1;
|
||||
|
||||
if(doubleSided) then
|
||||
|
||||
@@ -81,7 +81,6 @@ function ProcessEditor(context)
|
||||
context:SetMaterialPropertyVisibility("opacity.textureMap", mainVisibility)
|
||||
context:SetMaterialPropertyVisibility("opacity.textureMapUv", mainVisibility)
|
||||
context:SetMaterialPropertyVisibility("opacity.factor", mainVisibility)
|
||||
context:SetMaterialPropertyVisibility("opacity.doubleSided", mainVisibility)
|
||||
|
||||
if(opacityMode == OpacityMode_Blended or opacityMode == OpacityMode_TintedTransparent) then
|
||||
context:SetMaterialPropertyVisibility("opacity.alphaAffectsSpecular", MaterialPropertyVisibility_Enabled)
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
"DrawList" : "forward",
|
||||
|
||||
"CompilerHints" : {
|
||||
"DxcDisableOptimizations" : false,
|
||||
"DxcGenerateDebugInfo" : false
|
||||
"DisableOptimizations" : false,
|
||||
"GenerateDebugInfo" : false
|
||||
},
|
||||
|
||||
"ProgramSettings":
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:57d6744696768f9fb8a5fe5fee9aa36fee1eb87a9dbc1e60d4a35ed3c39d68e6
|
||||
size 810620
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:513f47f6fea5105f603170a8881b7e3b1cd2c4258636d64a6399c725032b500d
|
||||
size 38689
|
||||
@@ -78,5 +78,10 @@ namespace AZ
|
||||
//! Find an assignment id corresponding to the lod and label substring filters
|
||||
MaterialAssignmentId FindMaterialAssignmentIdInModel(
|
||||
const Data::Instance<AZ::RPI::Model>& model, const MaterialAssignmentLodIndex lodFilter, const AZStd::string& labelFilter);
|
||||
|
||||
//! Special case handling to convert script values to supported types
|
||||
AZ::RPI::MaterialPropertyValue ConvertMaterialPropertyValueFromScript(
|
||||
const AZ::RPI::MaterialPropertyDescriptor* propertyDescriptor, const AZStd::any& value);
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user