diff --git a/Assets/Editor/Icons/AssetBrowser/Collapse_All.svg b/Assets/Editor/Icons/AssetBrowser/Collapse_All.svg new file mode 100644 index 0000000000..7c7a7b85bd --- /dev/null +++ b/Assets/Editor/Icons/AssetBrowser/Collapse_All.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/AutomatedTesting/Assets/Destruction/cinder_wall_complex.blast b/AutomatedTesting/Assets/Destruction/cinder_wall_complex.blast new file mode 100644 index 0000000000..fcf67594c7 Binary files /dev/null and b/AutomatedTesting/Assets/Destruction/cinder_wall_complex.blast differ diff --git a/AutomatedTesting/Assets/Destruction/cinder_wall_complex.fbx b/AutomatedTesting/Assets/Destruction/cinder_wall_complex.fbx new file mode 100644 index 0000000000..62c305c35e --- /dev/null +++ b/AutomatedTesting/Assets/Destruction/cinder_wall_complex.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7f94f2634eacb4d7bee20dacc45edef96e4d268f1adb7960b8aa8f3b6e2906ed +size 6867609 diff --git a/AutomatedTesting/Assets/Prefabs/Bush.prefab b/AutomatedTesting/Assets/Prefabs/Bush.prefab new file mode 100644 index 0000000000..ef497bdcd0 --- /dev/null +++ b/AutomatedTesting/Assets/Prefabs/Bush.prefab @@ -0,0 +1,129 @@ +{ + "ContainerEntity": { + "Id": "ContainerEntity", + "Name": "Bush", + "Components": { + "Component_[1140272189295067758]": { + "$type": "EditorInspectorComponent", + "Id": 1140272189295067758 + }, + "Component_[13437832196484687256]": { + "$type": "EditorOnlyEntityComponent", + "Id": 13437832196484687256 + }, + "Component_[1553903646452669645]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 1553903646452669645 + }, + "Component_[15914009348632444632]": { + "$type": "EditorEntitySortComponent", + "Id": 15914009348632444632, + "Child Entity Order": [ + "Entity_[7511491868318]" + ] + }, + "Component_[18046340308818780248]": { + "$type": "EditorPrefabComponent", + "Id": 18046340308818780248 + }, + "Component_[1948833233489872938]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 1948833233489872938, + "Parent Entity": "" + }, + "Component_[2903632350157981339]": { + "$type": "SelectionComponent", + "Id": 2903632350157981339 + }, + "Component_[48827510535192710]": { + "$type": "EditorPendingCompositionComponent", + "Id": 48827510535192710 + }, + "Component_[5609536793322429681]": { + "$type": "EditorLockComponent", + "Id": 5609536793322429681 + }, + "Component_[5859168386298620990]": { + "$type": "EditorEntityIconComponent", + "Id": 5859168386298620990 + }, + "Component_[6604616929271524505]": { + "$type": "EditorVisibilityComponent", + "Id": 6604616929271524505 + } + } + }, + "Entities": { + "Entity_[7511491868318]": { + "Id": "Entity_[7511491868318]", + "Name": "Bush", + "Components": { + "Component_[10227459330338484901]": { + "$type": "EditorInspectorComponent", + "Id": 10227459330338484901, + "ComponentOrderEntryArray": [ + { + "ComponentId": 4998941225335869157 + }, + { + "ComponentId": 9922994635792843826, + "SortIndex": 1 + } + ] + }, + "Component_[10972351222359420947]": { + "$type": "EditorOnlyEntityComponent", + "Id": 10972351222359420947 + }, + "Component_[12101122374155214392]": { + "$type": "EditorPendingCompositionComponent", + "Id": 12101122374155214392 + }, + "Component_[1535264614652988260]": { + "$type": "SelectionComponent", + "Id": 1535264614652988260 + }, + "Component_[16367811417907891218]": { + "$type": "EditorVisibilityComponent", + "Id": 16367811417907891218 + }, + "Component_[17044216787716682880]": { + "$type": "EditorEntitySortComponent", + "Id": 17044216787716682880 + }, + "Component_[2129822594969629430]": { + "$type": "EditorEntityIconComponent", + "Id": 2129822594969629430 + }, + "Component_[2838015156782745450]": { + "$type": "EditorLockComponent", + "Id": 2838015156782745450 + }, + "Component_[4998941225335869157]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 4998941225335869157, + "Parent Entity": "ContainerEntity" + }, + "Component_[8773358049076362578]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 8773358049076362578 + }, + "Component_[9922994635792843826]": { + "$type": "AZ::Render::EditorMeshComponent", + "Id": 9922994635792843826, + "Controller": { + "Configuration": { + "ModelAsset": { + "assetId": { + "guid": "{1201406D-FB20-5B5F-B9B5-6A6E8DE00A14}", + "subId": 276506120 + }, + "assetHint": "assets/objects/foliage/bush_privet_01.azmodel" + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/AutomatedTesting/Assets/Prefabs/BushFlowerBlender.prefab b/AutomatedTesting/Assets/Prefabs/BushFlowerBlender.prefab new file mode 100644 index 0000000000..b938701b6a --- /dev/null +++ b/AutomatedTesting/Assets/Prefabs/BushFlowerBlender.prefab @@ -0,0 +1,2249 @@ +{ + "ContainerEntity": { + "Id": "ContainerEntity", + "Name": "BushFlowerBlender", + "Components": { + "Component_[10351434005293588180]": { + "$type": "EditorLockComponent", + "Id": 10351434005293588180 + }, + "Component_[10967554916960846519]": { + "$type": "EditorOnlyEntityComponent", + "Id": 10967554916960846519 + }, + "Component_[14400678265986305456]": { + "$type": "EditorEntityIconComponent", + "Id": 14400678265986305456 + }, + "Component_[15365520792759708998]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 15365520792759708998 + }, + "Component_[16281192066639198814]": { + "$type": "EditorEntitySortComponent", + "Id": 16281192066639198814, + "Child Entity Order": [ + "Entity_[263598916892318]" + ] + }, + "Component_[16356049875968660722]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 16356049875968660722, + "Parent Entity": "" + }, + "Component_[16391695178646515457]": { + "$type": "SelectionComponent", + "Id": 16391695178646515457 + }, + "Component_[16407238476365087382]": { + "$type": "EditorVisibilityComponent", + "Id": 16407238476365087382 + }, + "Component_[3542701736829700396]": { + "$type": "EditorPendingCompositionComponent", + "Id": 3542701736829700396 + }, + "Component_[5160094530340900971]": { + "$type": "EditorInspectorComponent", + "Id": 5160094530340900971 + }, + "Component_[6432428663776737136]": { + "$type": "EditorPrefabComponent", + "Id": 6432428663776737136 + } + } + }, + "Entities": { + "Entity_[263573147088542]": { + "Id": "Entity_[263573147088542]", + "Name": "BushSpawner", + "Components": { + "Component_[11886309121583108836]": { + "$type": "EditorPositionModifierComponent", + "Id": 11886309121583108836, + "Configuration": { + "GradientX": { + "GradientId": "Entity_[263590326957726]" + }, + "GradientY": { + "GradientId": "Entity_[263590326957726]" + }, + "GradientZ": { + "GradientId": "" + } + } + }, + "Component_[1240444912193942742]": { + "$type": "{DD96FD51-A86B-48BC-A6AB-89183B538269} EditorSpawnerComponent", + "Id": 1240444912193942742, + "PreviewEntity": "Entity_[263573147088542]" + }, + "Component_[12813702285187817973]": { + "$type": "EditorInspectorComponent", + "Id": 12813702285187817973, + "ComponentOrderEntryArray": [ + { + "ComponentId": 18133156195370267728 + }, + { + "ComponentId": 13450250419263773680, + "SortIndex": 1 + }, + { + "ComponentId": 8841963751527151666, + "SortIndex": 2 + }, + { + "ComponentId": 1240444912193942742, + "SortIndex": 3 + }, + { + "ComponentId": 17991239182321715249, + "SortIndex": 4 + }, + { + "ComponentId": 14175761523159824993, + "SortIndex": 5 + }, + { + "ComponentId": 2884829698060689565, + "SortIndex": 6 + }, + { + "ComponentId": 11886309121583108836, + "SortIndex": 7 + } + ] + }, + "Component_[13179606361687972691]": { + "$type": "EditorEntityIconComponent", + "Id": 13179606361687972691 + }, + "Component_[13450250419263773680]": { + "$type": "EditorReferenceShapeComponent", + "Id": 13450250419263773680, + "Configuration": { + "ShapeEntityId": "Entity_[263607506826910]" + } + }, + "Component_[13688014277574607552]": { + "$type": "EditorOnlyEntityComponent", + "Id": 13688014277574607552 + }, + "Component_[14175761523159824993]": { + "$type": "EditorDistributionFilterComponent", + "Id": 14175761523159824993, + "Configuration": { + "ThresholdMin": 0.289000004529953, + "ThresholdMax": 0.5690000057220459, + "Gradient": { + "GradientId": "Entity_[263603211859614]" + } + } + }, + "Component_[14232774271081092639]": { + "$type": "EditorLockComponent", + "Id": 14232774271081092639 + }, + "Component_[14811533745267383811]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 14811533745267383811 + }, + "Component_[17540078415915694273]": { + "$type": "EditorVisibilityComponent", + "Id": 17540078415915694273 + }, + "Component_[17991239182321715249]": { + "$type": "EditorRotationModifierComponent", + "Id": 17991239182321715249, + "Configuration": { + "GradientX": { + "GradientId": "" + }, + "GradientY": { + "GradientId": "" + }, + "GradientZ": { + "GradientId": "Entity_[263590326957726]" + } + } + }, + "Component_[18133156195370267728]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 18133156195370267728, + "Parent Entity": "Entity_[263607506826910]" + }, + "Component_[2884829698060689565]": { + "$type": "EditorScaleModifierComponent", + "Id": 2884829698060689565, + "Configuration": { + "RangeMin": 0.75, + "RangeMax": 1.25, + "Gradient": { + "GradientId": "Entity_[263590326957726]" + } + } + }, + "Component_[50628676751372416]": { + "$type": "EditorEntitySortComponent", + "Id": 50628676751372416, + "Child Entity Order": [ + "Entity_[263603211859614]", + "Entity_[263590326957726]" + ] + }, + "Component_[5689270312836823309]": { + "$type": "SelectionComponent", + "Id": 5689270312836823309 + }, + "Component_[7105803915999711758]": { + "$type": "EditorPendingCompositionComponent", + "Id": 7105803915999711758 + }, + "Component_[8841963751527151666]": { + "$type": "EditorDescriptorListComponent", + "Id": 8841963751527151666, + "Configuration": { + "Descriptors": [ + { + "SpawnerType": "{74BEEDB5-81CF-409F-B375-0D93D81EF2E3}", + "InstanceSpawner": { + "$type": "PrefabInstanceSpawner", + "SpawnableAsset": { + "assetId": { + "guid": "{EE51E73C-D753-54AC-A1C0-4F29844FB6C3}", + "subId": 2740536329 + }, + "assetHint": "assets/prefabs/bush.spawnable" + } + } + } + ] + } + } + } + }, + "Entity_[263577442055838]": { + "Id": "Entity_[263577442055838]", + "Name": "RandomNoise", + "Components": { + "Component_[13412023990029767074]": { + "$type": "EditorRandomGradientComponent", + "Id": 13412023990029767074, + "PreviewEntity": "Entity_[263577442055838]" + }, + "Component_[14048059127502350032]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 14048059127502350032, + "Parent Entity": "Entity_[263581737023134]" + }, + "Component_[15585968636846328006]": { + "$type": "EditorEntitySortComponent", + "Id": 15585968636846328006 + }, + "Component_[17356242264256499333]": { + "$type": "EditorOnlyEntityComponent", + "Id": 17356242264256499333 + }, + "Component_[2157320692130316849]": { + "$type": "EditorLockComponent", + "Id": 2157320692130316849 + }, + "Component_[2167582872687341084]": { + "$type": "EditorReferenceShapeComponent", + "Id": 2167582872687341084, + "Configuration": { + "ShapeEntityId": "Entity_[263607506826910]" + } + }, + "Component_[2794166072748175035]": { + "$type": "SelectionComponent", + "Id": 2794166072748175035 + }, + "Component_[4784966656524567789]": { + "$type": "EditorVisibilityComponent", + "Id": 4784966656524567789 + }, + "Component_[6185400249317227261]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 6185400249317227261 + }, + "Component_[639949486729001685]": { + "$type": "EditorGradientTransformComponent", + "Id": 639949486729001685, + "Configuration": { + "ShapeReference": "", + "Bounds": [ + 50.0, + 50.0, + 1.0 + ] + } + }, + "Component_[7347819195697153472]": { + "$type": "EditorEntityIconComponent", + "Id": 7347819195697153472 + }, + "Component_[9225409585951117678]": { + "$type": "EditorInspectorComponent", + "Id": 9225409585951117678, + "ComponentOrderEntryArray": [ + { + "ComponentId": 14048059127502350032 + }, + { + "ComponentId": 2167582872687341084, + "SortIndex": 1 + }, + { + "ComponentId": 639949486729001685, + "SortIndex": 2 + }, + { + "ComponentId": 13412023990029767074, + "SortIndex": 3 + } + ] + }, + "Component_[9667056664436803603]": { + "$type": "EditorPendingCompositionComponent", + "Id": 9667056664436803603 + } + } + }, + "Entity_[263581737023134]": { + "Id": "Entity_[263581737023134]", + "Name": "FlowerSpawner", + "Components": { + "Component_[10064436441176637741]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 10064436441176637741 + }, + "Component_[10418076448308581948]": { + "$type": "EditorRotationModifierComponent", + "Id": 10418076448308581948, + "Configuration": { + "GradientX": { + "GradientId": "" + }, + "GradientY": { + "GradientId": "" + }, + "GradientZ": { + "GradientId": "Entity_[263577442055838]" + } + } + }, + "Component_[12484622175138429315]": { + "$type": "EditorOnlyEntityComponent", + "Id": 12484622175138429315 + }, + "Component_[12590590072231203407]": { + "$type": "EditorLockComponent", + "Id": 12590590072231203407 + }, + "Component_[13079591667184987458]": { + "$type": "EditorScaleModifierComponent", + "Id": 13079591667184987458, + "Configuration": { + "RangeMin": 0.75, + "RangeMax": 1.25, + "Gradient": { + "GradientId": "Entity_[263577442055838]" + } + } + }, + "Component_[13174773394274524631]": { + "$type": "EditorInspectorComponent", + "Id": 13174773394274524631, + "ComponentOrderEntryArray": [ + { + "ComponentId": 1915862229814997128 + }, + { + "ComponentId": 582800388831726963, + "SortIndex": 1 + }, + { + "ComponentId": 18006385801184712266, + "SortIndex": 2 + }, + { + "ComponentId": 6902499453501456890, + "SortIndex": 3 + }, + { + "ComponentId": 10418076448308581948, + "SortIndex": 4 + }, + { + "ComponentId": 13983302912005698250, + "SortIndex": 5 + }, + { + "ComponentId": 13079591667184987458, + "SortIndex": 6 + }, + { + "ComponentId": 7912787520673119502, + "SortIndex": 7 + } + ] + }, + "Component_[13200009872392504010]": { + "$type": "EditorEntitySortComponent", + "Id": 13200009872392504010, + "Child Entity Order": [ + "Entity_[263594621925022]", + "Entity_[263577442055838]" + ] + }, + "Component_[13983302912005698250]": { + "$type": "EditorDistributionFilterComponent", + "Id": 13983302912005698250, + "Configuration": { + "ThresholdMin": 0.2879999876022339, + "ThresholdMax": 0.5680000185966492, + "Gradient": { + "GradientId": "Entity_[263586031990430]" + } + } + }, + "Component_[14726174657215669218]": { + "$type": "EditorPendingCompositionComponent", + "Id": 14726174657215669218 + }, + "Component_[18006385801184712266]": { + "$type": "EditorDescriptorListComponent", + "Id": 18006385801184712266, + "Configuration": { + "Descriptors": [ + { + "SpawnerType": "{74BEEDB5-81CF-409F-B375-0D93D81EF2E3}", + "InstanceSpawner": { + "$type": "PrefabInstanceSpawner", + "SpawnableAsset": { + "assetId": { + "guid": "{80C0CF4E-9A5E-544B-B89E-BC980175A259}", + "subId": 3875079122 + }, + "assetHint": "assets/prefabs/pinkflower.spawnable" + } + } + }, + { + "SpawnerType": "{74BEEDB5-81CF-409F-B375-0D93D81EF2E3}", + "InstanceSpawner": { + "$type": "PrefabInstanceSpawner", + "SpawnableAsset": { + "assetId": { + "guid": "{20DD1202-A434-5482-9FB9-AED4C78F6CBF}", + "subId": 2669863854 + }, + "assetHint": "assets/prefabs/purpleflower.spawnable" + } + } + }, + { + "SpawnerType": "{23C40FD4-A55F-4BD3-BE5B-DC5423F217C2}", + "InstanceSpawner": { + "$type": "EmptyInstanceSpawner" + } + } + ] + } + }, + "Component_[1915862229814997128]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 1915862229814997128, + "Parent Entity": "Entity_[263607506826910]" + }, + "Component_[2123416208548010747]": { + "$type": "SelectionComponent", + "Id": 2123416208548010747 + }, + "Component_[4172073657954183661]": { + "$type": "EditorVisibilityComponent", + "Id": 4172073657954183661 + }, + "Component_[4297556504463195307]": { + "$type": "EditorEntityIconComponent", + "Id": 4297556504463195307 + }, + "Component_[582800388831726963]": { + "$type": "EditorReferenceShapeComponent", + "Id": 582800388831726963, + "Configuration": { + "ShapeEntityId": "Entity_[263607506826910]" + } + }, + "Component_[6902499453501456890]": { + "$type": "{DD96FD51-A86B-48BC-A6AB-89183B538269} EditorSpawnerComponent", + "Id": 6902499453501456890, + "PreviewEntity": "Entity_[263581737023134]" + }, + "Component_[7912787520673119502]": { + "$type": "EditorPositionModifierComponent", + "Id": 7912787520673119502, + "Configuration": { + "GradientX": { + "GradientId": "Entity_[263577442055838]" + }, + "GradientY": { + "GradientId": "Entity_[263577442055838]" + }, + "GradientZ": { + "GradientId": "" + } + } + } + } + }, + "Entity_[263586031990430]": { + "Id": "Entity_[263586031990430]", + "Name": "Invert", + "Components": { + "Component_[11123278080744920525]": { + "$type": "EditorEntitySortComponent", + "Id": 11123278080744920525 + }, + "Component_[1199715693160400161]": { + "$type": "EditorInspectorComponent", + "Id": 1199715693160400161, + "ComponentOrderEntryArray": [ + { + "ComponentId": 7438979211266329827 + }, + { + "ComponentId": 6027557066164356793, + "SortIndex": 1 + }, + { + "ComponentId": 8903771095804438921, + "SortIndex": 2 + } + ] + }, + "Component_[12162816428693886169]": { + "$type": "EditorEntityIconComponent", + "Id": 12162816428693886169 + }, + "Component_[14493180089799969074]": { + "$type": "EditorVisibilityComponent", + "Id": 14493180089799969074 + }, + "Component_[16206759293595766479]": { + "$type": "EditorPendingCompositionComponent", + "Id": 16206759293595766479 + }, + "Component_[17566144032052847628]": { + "$type": "SelectionComponent", + "Id": 17566144032052847628 + }, + "Component_[17784057508127919200]": { + "$type": "EditorLockComponent", + "Id": 17784057508127919200 + }, + "Component_[18377773171420051348]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 18377773171420051348 + }, + "Component_[6027557066164356793]": { + "$type": "EditorReferenceShapeComponent", + "Id": 6027557066164356793, + "Configuration": { + "ShapeEntityId": "Entity_[263607506826910]" + } + }, + "Component_[7438979211266329827]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 7438979211266329827, + "Parent Entity": "Entity_[263594621925022]" + }, + "Component_[8421650081106982664]": { + "$type": "EditorOnlyEntityComponent", + "Id": 8421650081106982664 + }, + "Component_[8903771095804438921]": { + "$type": "EditorInvertGradientComponent", + "Id": 8903771095804438921, + "Configuration": { + "Gradient": { + "GradientId": "Entity_[263594621925022]" + } + }, + "PreviewEntity": "Entity_[263586031990430]" + } + } + }, + "Entity_[263590326957726]": { + "Id": "Entity_[263590326957726]", + "Name": "RandomNoise", + "Components": { + "Component_[10420548607186596407]": { + "$type": "SelectionComponent", + "Id": 10420548607186596407 + }, + "Component_[11351507264577024072]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 11351507264577024072, + "Parent Entity": "Entity_[263573147088542]" + }, + "Component_[11576941520191560445]": { + "$type": "EditorEntityIconComponent", + "Id": 11576941520191560445 + }, + "Component_[11787535428542045683]": { + "$type": "EditorPendingCompositionComponent", + "Id": 11787535428542045683 + }, + "Component_[11946132649485953311]": { + "$type": "EditorEntitySortComponent", + "Id": 11946132649485953311 + }, + "Component_[11970417753234451570]": { + "$type": "EditorOnlyEntityComponent", + "Id": 11970417753234451570 + }, + "Component_[13743879269876214143]": { + "$type": "EditorVisibilityComponent", + "Id": 13743879269876214143 + }, + "Component_[15614946697365576378]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 15614946697365576378 + }, + "Component_[17045174842161759045]": { + "$type": "EditorLockComponent", + "Id": 17045174842161759045 + }, + "Component_[3107716031616536910]": { + "$type": "EditorInspectorComponent", + "Id": 3107716031616536910, + "ComponentOrderEntryArray": [ + { + "ComponentId": 11351507264577024072 + }, + { + "ComponentId": 6316453818295975755, + "SortIndex": 1 + }, + { + "ComponentId": 4846745402056100407, + "SortIndex": 2 + }, + { + "ComponentId": 8967153379180885152, + "SortIndex": 3 + } + ] + }, + "Component_[4846745402056100407]": { + "$type": "EditorGradientTransformComponent", + "Id": 4846745402056100407, + "Configuration": { + "ShapeReference": "", + "Bounds": [ + 50.0, + 50.0, + 1.0 + ] + } + }, + "Component_[6316453818295975755]": { + "$type": "EditorReferenceShapeComponent", + "Id": 6316453818295975755, + "Configuration": { + "ShapeEntityId": "Entity_[263573147088542]" + } + }, + "Component_[8967153379180885152]": { + "$type": "EditorRandomGradientComponent", + "Id": 8967153379180885152, + "PreviewEntity": "Entity_[263590326957726]" + } + } + }, + "Entity_[263594621925022]": { + "Id": "Entity_[263594621925022]", + "Name": "PerlinNoise", + "Components": { + "Component_[15798567753940523121]": { + "$type": "EditorPerlinGradientComponent", + "Id": 15798567753940523121, + "Configuration": { + "randomSeed": 33, + "frequency": 0.25 + }, + "PreviewEntity": "Entity_[263594621925022]" + }, + "Component_[16035848776632936419]": { + "$type": "EditorPendingCompositionComponent", + "Id": 16035848776632936419 + }, + "Component_[16434108759160050253]": { + "$type": "EditorVisibilityComponent", + "Id": 16434108759160050253 + }, + "Component_[16805003046507210760]": { + "$type": "EditorReferenceShapeComponent", + "Id": 16805003046507210760, + "Configuration": { + "ShapeEntityId": "Entity_[263607506826910]" + } + }, + "Component_[17679463569742913027]": { + "$type": "EditorOnlyEntityComponent", + "Id": 17679463569742913027 + }, + "Component_[18285870860955961523]": { + "$type": "SelectionComponent", + "Id": 18285870860955961523 + }, + "Component_[2330427084045350198]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 2330427084045350198 + }, + "Component_[5921906930080711994]": { + "$type": "EditorEntitySortComponent", + "Id": 5921906930080711994, + "Child Entity Order": [ + "Entity_[263586031990430]" + ] + }, + "Component_[764117453152842781]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 764117453152842781, + "Parent Entity": "Entity_[263581737023134]" + }, + "Component_[7701931249281891300]": { + "$type": "EditorEntityIconComponent", + "Id": 7701931249281891300 + }, + "Component_[7967070680905543315]": { + "$type": "EditorInspectorComponent", + "Id": 7967070680905543315, + "ComponentOrderEntryArray": [ + { + "ComponentId": 764117453152842781 + }, + { + "ComponentId": 16805003046507210760, + "SortIndex": 1 + }, + { + "ComponentId": 8029154041194694200, + "SortIndex": 2 + }, + { + "ComponentId": 15798567753940523121, + "SortIndex": 3 + } + ] + }, + "Component_[8029154041194694200]": { + "$type": "EditorGradientTransformComponent", + "Id": 8029154041194694200, + "Configuration": { + "ShapeReference": "", + "Bounds": [ + 50.0, + 50.0, + 1.0 + ] + } + }, + "Component_[8660028910391135744]": { + "$type": "EditorLockComponent", + "Id": 8660028910391135744 + } + } + }, + "Entity_[263598916892318]": { + "Id": "Entity_[263598916892318]", + "Name": "LandscapeCanvas", + "Components": { + "Component_[12967746135199800648]": { + "$type": "EditorVisibilityComponent", + "Id": 12967746135199800648 + }, + "Component_[13081062505162225823]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 13081062505162225823 + }, + "Component_[16021195931295059075]": { + "$type": "EditorPendingCompositionComponent", + "Id": 16021195931295059075 + }, + "Component_[16134261272053586014]": { + "$type": "EditorEntityIconComponent", + "Id": 16134261272053586014 + }, + "Component_[17500735767968801510]": { + "$type": "EditorLandscapeCanvasComponent", + "Id": 17500735767968801510, + "Graph": { + "m_nodes": [ + { + "Key": 1, + "Value": { + "$type": "CylinderShapeNode", + "m_propertySlots": [ + { + "Key": { + "m_name": "EntityName" + }, + "Value": { + "m_value": { + "$type": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9} AZStd::string", + "Value": "BushFlowerBlender" + } + } + } + ], + "m_vegetationEntityId": "Entity_[263607506826910]", + "m_componentId": 6683290476113150719 + } + }, + { + "Key": 2, + "Value": { + "$type": "RandomNoiseGradientNode", + "m_propertySlots": [ + { + "Key": { + "m_name": "EntityName" + }, + "Value": { + "m_value": { + "$type": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9} AZStd::string", + "Value": "RandomNoise" + } + } + } + ], + "m_inputDataSlots": [ + { + "Key": { + "m_name": "PreviewBounds" + }, + "Value": { + "m_value": { + "$type": "EntityId", + "Value": "" + } + } + } + ], + "m_vegetationEntityId": "Entity_[263590326957726]", + "m_componentId": 8967153379180885152 + } + }, + { + "Key": 3, + "Value": { + "$type": "SpawnerAreaNode", + "m_propertySlots": [ + { + "Key": { + "m_name": "EntityName" + }, + "Value": { + "m_value": { + "$type": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9} AZStd::string", + "Value": "BushSpawner" + } + } + } + ], + "m_inputDataSlots": [ + { + "Key": { + "m_name": "PlacementBounds" + }, + "Value": { + "m_value": { + "$type": "EntityId", + "Value": "" + } + } + } + ], + "m_vegetationEntityId": "Entity_[263573147088542]", + "m_componentId": 1240444912193942742 + } + }, + { + "Key": 4, + "Value": { + "$type": "PerlinNoiseGradientNode", + "m_propertySlots": [ + { + "Key": { + "m_name": "EntityName" + }, + "Value": { + "m_value": { + "$type": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9} AZStd::string", + "Value": "PerlinNoise" + } + } + } + ], + "m_inputDataSlots": [ + { + "Key": { + "m_name": "PreviewBounds" + }, + "Value": { + "m_value": { + "$type": "EntityId", + "Value": "" + } + } + } + ], + "m_vegetationEntityId": "Entity_[263603211859614]", + "m_componentId": 10160640699095155981 + } + }, + { + "Key": 5, + "Value": { + "$type": "RandomNoiseGradientNode", + "m_propertySlots": [ + { + "Key": { + "m_name": "EntityName" + }, + "Value": { + "m_value": { + "$type": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9} AZStd::string", + "Value": "RandomNoise" + } + } + } + ], + "m_inputDataSlots": [ + { + "Key": { + "m_name": "PreviewBounds" + }, + "Value": { + "m_value": { + "$type": "EntityId", + "Value": "" + } + } + } + ], + "m_vegetationEntityId": "Entity_[263577442055838]", + "m_componentId": 13412023990029767074 + } + }, + { + "Key": 6, + "Value": { + "$type": "SpawnerAreaNode", + "m_propertySlots": [ + { + "Key": { + "m_name": "EntityName" + }, + "Value": { + "m_value": { + "$type": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9} AZStd::string", + "Value": "FlowerSpawner" + } + } + } + ], + "m_inputDataSlots": [ + { + "Key": { + "m_name": "PlacementBounds" + }, + "Value": { + "m_value": { + "$type": "EntityId", + "Value": "" + } + } + } + ], + "m_vegetationEntityId": "Entity_[263581737023134]", + "m_componentId": 6902499453501456890 + } + }, + { + "Key": 7, + "Value": { + "$type": "AreaBlenderNode", + "m_propertySlots": [ + { + "Key": { + "m_name": "EntityName" + }, + "Value": { + "m_value": { + "$type": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9} AZStd::string", + "Value": "BushFlowerBlender" + } + } + } + ], + "m_extendableSlots": { + "InboundArea": [ + { + "m_value": { + "$type": "EntityId", + "Value": "" + } + }, + { + "m_value": { + "$type": "EntityId", + "Value": "" + }, + "m_subId": 1 + } + ] + }, + "m_vegetationEntityId": "Entity_[263607506826910]", + "m_componentId": 7229206794941734410 + } + }, + { + "Key": 8, + "Value": { + "$type": "PerlinNoiseGradientNode", + "m_propertySlots": [ + { + "Key": { + "m_name": "EntityName" + }, + "Value": { + "m_value": { + "$type": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9} AZStd::string", + "Value": "PerlinNoise" + } + } + } + ], + "m_inputDataSlots": [ + { + "Key": { + "m_name": "PreviewBounds" + }, + "Value": { + "m_value": { + "$type": "EntityId", + "Value": "" + } + } + } + ], + "m_vegetationEntityId": "Entity_[263594621925022]", + "m_componentId": 15798567753940523121 + } + }, + { + "Key": 9, + "Value": { + "$type": "InvertGradientModifierNode", + "m_propertySlots": [ + { + "Key": { + "m_name": "EntityName" + }, + "Value": { + "m_value": { + "$type": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9} AZStd::string", + "Value": "Invert" + } + } + } + ], + "m_inputDataSlots": [ + { + "Key": { + "m_name": "InboundGradient" + }, + "Value": { + "m_value": { + "$type": "EntityId", + "Value": "" + } + } + }, + { + "Key": { + "m_name": "PreviewBounds" + }, + "Value": { + "m_value": { + "$type": "EntityId", + "Value": "" + } + } + } + ], + "m_vegetationEntityId": "Entity_[263586031990430]", + "m_componentId": 8903771095804438921 + } + }, + { + "Key": 10, + "Value": { + "$type": "RotationModifierNode", + "m_inputDataSlots": [ + { + "Key": { + "m_name": "InboundGradientX" + }, + "Value": { + "m_value": { + "$type": "EntityId", + "Value": "" + } + } + }, + { + "Key": { + "m_name": "InboundGradientY" + }, + "Value": { + "m_value": { + "$type": "EntityId", + "Value": "" + } + } + }, + { + "Key": { + "m_name": "InboundGradientZ" + }, + "Value": { + "m_value": { + "$type": "EntityId", + "Value": "" + } + } + } + ], + "m_vegetationEntityId": "Entity_[263573147088542]", + "m_componentId": 17991239182321715249 + } + }, + { + "Key": 11, + "Value": { + "$type": "DistributionFilterNode", + "m_inputDataSlots": [ + { + "Key": { + "m_name": "InboundGradient" + }, + "Value": { + "m_value": { + "$type": "EntityId", + "Value": "" + } + } + } + ], + "m_vegetationEntityId": "Entity_[263573147088542]", + "m_componentId": 14175761523159824993 + } + }, + { + "Key": 12, + "Value": { + "$type": "ScaleModifierNode", + "m_inputDataSlots": [ + { + "Key": { + "m_name": "InboundGradient" + }, + "Value": { + "m_value": { + "$type": "EntityId", + "Value": "" + } + } + } + ], + "m_vegetationEntityId": "Entity_[263573147088542]", + "m_componentId": 2884829698060689565 + } + }, + { + "Key": 13, + "Value": { + "$type": "PositionModifierNode", + "m_inputDataSlots": [ + { + "Key": { + "m_name": "InboundGradientX" + }, + "Value": { + "m_value": { + "$type": "EntityId", + "Value": "" + } + } + }, + { + "Key": { + "m_name": "InboundGradientY" + }, + "Value": { + "m_value": { + "$type": "EntityId", + "Value": "" + } + } + }, + { + "Key": { + "m_name": "InboundGradientZ" + }, + "Value": { + "m_value": { + "$type": "EntityId", + "Value": "" + } + } + } + ], + "m_vegetationEntityId": "Entity_[263573147088542]", + "m_componentId": 11886309121583108836 + } + }, + { + "Key": 14, + "Value": { + "$type": "RotationModifierNode", + "m_inputDataSlots": [ + { + "Key": { + "m_name": "InboundGradientX" + }, + "Value": { + "m_value": { + "$type": "EntityId", + "Value": "" + } + } + }, + { + "Key": { + "m_name": "InboundGradientY" + }, + "Value": { + "m_value": { + "$type": "EntityId", + "Value": "" + } + } + }, + { + "Key": { + "m_name": "InboundGradientZ" + }, + "Value": { + "m_value": { + "$type": "EntityId", + "Value": "" + } + } + } + ], + "m_vegetationEntityId": "Entity_[263581737023134]", + "m_componentId": 10418076448308581948 + } + }, + { + "Key": 15, + "Value": { + "$type": "DistributionFilterNode", + "m_inputDataSlots": [ + { + "Key": { + "m_name": "InboundGradient" + }, + "Value": { + "m_value": { + "$type": "EntityId", + "Value": "" + } + } + } + ], + "m_vegetationEntityId": "Entity_[263581737023134]", + "m_componentId": 13983302912005698250 + } + }, + { + "Key": 16, + "Value": { + "$type": "ScaleModifierNode", + "m_inputDataSlots": [ + { + "Key": { + "m_name": "InboundGradient" + }, + "Value": { + "m_value": { + "$type": "EntityId", + "Value": "" + } + } + } + ], + "m_vegetationEntityId": "Entity_[263581737023134]", + "m_componentId": 13079591667184987458 + } + }, + { + "Key": 17, + "Value": { + "$type": "PositionModifierNode", + "m_inputDataSlots": [ + { + "Key": { + "m_name": "InboundGradientX" + }, + "Value": { + "m_value": { + "$type": "EntityId", + "Value": "" + } + } + }, + { + "Key": { + "m_name": "InboundGradientY" + }, + "Value": { + "m_value": { + "$type": "EntityId", + "Value": "" + } + } + }, + { + "Key": { + "m_name": "InboundGradientZ" + }, + "Value": { + "m_value": { + "$type": "EntityId", + "Value": "" + } + } + } + ], + "m_vegetationEntityId": "Entity_[263581737023134]", + "m_componentId": 7912787520673119502 + } + } + ], + "m_connections": [ + { + "m_sourceEndpoint": [ + 8, + { + "m_name": "OutboundGradient" + } + ], + "m_targetEndpoint": [ + 9, + { + "m_name": "InboundGradient" + } + ] + }, + { + "m_sourceEndpoint": [ + 3, + { + "m_name": "OutboundArea" + } + ], + "m_targetEndpoint": [ + 7, + { + "m_name": "InboundArea" + } + ] + }, + { + "m_sourceEndpoint": [ + 6, + { + "m_name": "OutboundArea" + } + ], + "m_targetEndpoint": [ + 7, + { + "m_name": "InboundArea", + "m_subId": 1 + } + ] + }, + { + "m_sourceEndpoint": [ + 1, + { + "m_name": "Bounds" + } + ], + "m_targetEndpoint": [ + 3, + { + "m_name": "PlacementBounds" + } + ] + }, + { + "m_sourceEndpoint": [ + 1, + { + "m_name": "Bounds" + } + ], + "m_targetEndpoint": [ + 6, + { + "m_name": "PlacementBounds" + } + ] + }, + { + "m_sourceEndpoint": [ + 2, + { + "m_name": "OutboundGradient" + } + ], + "m_targetEndpoint": [ + 10, + { + "m_name": "InboundGradientZ" + } + ] + }, + { + "m_sourceEndpoint": [ + 4, + { + "m_name": "OutboundGradient" + } + ], + "m_targetEndpoint": [ + 11, + { + "m_name": "InboundGradient" + } + ] + }, + { + "m_sourceEndpoint": [ + 2, + { + "m_name": "OutboundGradient" + } + ], + "m_targetEndpoint": [ + 12, + { + "m_name": "InboundGradient" + } + ] + }, + { + "m_sourceEndpoint": [ + 2, + { + "m_name": "OutboundGradient" + } + ], + "m_targetEndpoint": [ + 13, + { + "m_name": "InboundGradientX" + } + ] + }, + { + "m_sourceEndpoint": [ + 2, + { + "m_name": "OutboundGradient" + } + ], + "m_targetEndpoint": [ + 13, + { + "m_name": "InboundGradientY" + } + ] + }, + { + "m_sourceEndpoint": [ + 5, + { + "m_name": "OutboundGradient" + } + ], + "m_targetEndpoint": [ + 14, + { + "m_name": "InboundGradientZ" + } + ] + }, + { + "m_sourceEndpoint": [ + 9, + { + "m_name": "OutboundGradient" + } + ], + "m_targetEndpoint": [ + 15, + { + "m_name": "InboundGradient" + } + ] + }, + { + "m_sourceEndpoint": [ + 5, + { + "m_name": "OutboundGradient" + } + ], + "m_targetEndpoint": [ + 16, + { + "m_name": "InboundGradient" + } + ] + }, + { + "m_sourceEndpoint": [ + 5, + { + "m_name": "OutboundGradient" + } + ], + "m_targetEndpoint": [ + 17, + { + "m_name": "InboundGradientX" + } + ] + }, + { + "m_sourceEndpoint": [ + 5, + { + "m_name": "OutboundGradient" + } + ], + "m_targetEndpoint": [ + 17, + { + "m_name": "InboundGradientY" + } + ] + } + ], + "m_uiMetadata": { + "m_sceneMetadata": { + "ComponentData": { + "{5F84B500-8C45-40D1-8EFC-A5306B241444}": { + "$type": "SceneComponentSaveData", + "ViewParams": { + "Scale": 0.3771495156249999, + "AnchorX": -498.4760437011719, + "AnchorY": 808.6978149414063 + } + } + } + }, + "m_nodeMetadata": [ + { + "Key": 2, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "GradientNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 100.0, + 580.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{2D583FA2-5659-491F-8914-6302420E3F0B}" + } + } + } + }, + { + "Key": 3, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "VegetationAreaNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 480.0, + 600.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{A26480C4-A80B-4B36-ADE1-918E4541EA2B}" + } + } + } + }, + { + "Key": 5, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "GradientNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 100.0, + 1540.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{6CE9EA8B-85E7-4E17-B1D6-CA97D9D65276}" + } + } + } + }, + { + "Key": 6, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "VegetationAreaNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 480.0, + 1560.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{8FABE49F-1D73-46FE-8616-A982EEE46DDD}" + } + } + } + }, + { + "Key": 7, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "VegetationAreaNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 840.0, + 1580.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{C5EEBC1D-B91B-4852-A41D-425C6FED3FB9}" + } + } + } + }, + { + "Key": 9, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "GradientModifierNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 480.0, + 2060.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{5EB76670-0CBE-4F2A-9AE7-F65709D0BE92}" + } + } + } + }, + { + "Key": 10, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "VegetationAreaNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 6.0, + 147.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{5CB69A73-F7BA-4F76-AB86-F343052C3D7D}" + } + } + } + }, + { + "Key": 11, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "VegetationAreaNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 6.0, + 367.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{235DEBEC-E3F8-43C1-BA7E-41475B834D70}" + } + } + } + }, + { + "Key": 12, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "VegetationAreaNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 6.0, + 288.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{9E56E7B6-2ECE-42F9-9A23-FF7D192209D2}" + } + } + } + }, + { + "Key": 13, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "VegetationAreaNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 6.0, + 6.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{61759FE6-E6F7-4F4B-819B-FBFE125D7389}" + } + } + } + }, + { + "Key": 14, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "VegetationAreaNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 6.0, + 147.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{0AC1C6C8-7CC1-4068-A87D-F4B92AE8FCAF}" + } + } + } + }, + { + "Key": 15, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "VegetationAreaNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 6.0, + 367.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{5D698B90-830F-46FE-ADD8-6164EA098C3E}" + } + } + } + }, + { + "Key": 16, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "VegetationAreaNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 6.0, + 288.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{9DE6DE4A-2E6F-44BA-B292-3CD2215C1D5B}" + } + } + } + }, + { + "Key": 17, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "VegetationAreaNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 6.0, + 6.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{57FA822D-629F-4949-A8D7-D675544EBC0A}" + } + } + } + } + ] + }, + "m_nodeWrappings": [ + { + "Key": 10, + "Value": [ + 3, + 1 + ] + }, + { + "Key": 11, + "Value": [ + 3, + 6 + ] + }, + { + "Key": 12, + "Value": [ + 3, + 2 + ] + }, + { + "Key": 13, + "Value": [ + 3, + {} + ] + }, + { + "Key": 14, + "Value": [ + 6, + 1 + ] + }, + { + "Key": 15, + "Value": [ + 6, + 6 + ] + }, + { + "Key": 16, + "Value": [ + 6, + 2 + ] + }, + { + "Key": 17, + "Value": [ + 6, + {} + ] + } + ] + } + }, + "Component_[17574651838531525263]": { + "$type": "EditorEntitySortComponent", + "Id": 17574651838531525263, + "Child Entity Order": [ + "Entity_[263607506826910]" + ] + }, + "Component_[3086205760978540160]": { + "$type": "EditorLockComponent", + "Id": 3086205760978540160 + }, + "Component_[3102230753208284750]": { + "$type": "EditorInspectorComponent", + "Id": 3102230753208284750, + "ComponentOrderEntryArray": [ + { + "ComponentId": 5796173638130327223 + }, + { + "ComponentId": 17500735767968801510, + "SortIndex": 1 + } + ] + }, + "Component_[4695341524212000585]": { + "$type": "EditorOnlyEntityComponent", + "Id": 4695341524212000585 + }, + "Component_[5796173638130327223]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 5796173638130327223, + "Parent Entity": "ContainerEntity" + }, + "Component_[8278362871021770878]": { + "$type": "SelectionComponent", + "Id": 8278362871021770878 + } + } + }, + "Entity_[263603211859614]": { + "Id": "Entity_[263603211859614]", + "Name": "PerlinNoise", + "Components": { + "Component_[10006546776757889020]": { + "$type": "EditorVisibilityComponent", + "Id": 10006546776757889020 + }, + "Component_[10160640699095155981]": { + "$type": "EditorPerlinGradientComponent", + "Id": 10160640699095155981, + "Configuration": { + "randomSeed": 33, + "frequency": 0.25 + }, + "PreviewEntity": "Entity_[263603211859614]" + }, + "Component_[11506183926478566822]": { + "$type": "EditorEntitySortComponent", + "Id": 11506183926478566822 + }, + "Component_[13160180411150366392]": { + "$type": "EditorLockComponent", + "Id": 13160180411150366392 + }, + "Component_[15083697380300161163]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 15083697380300161163 + }, + "Component_[15404456223257061245]": { + "$type": "EditorInspectorComponent", + "Id": 15404456223257061245, + "ComponentOrderEntryArray": [ + { + "ComponentId": 6484803030406851652 + }, + { + "ComponentId": 4912800286535654244, + "SortIndex": 1 + }, + { + "ComponentId": 2395166459126906105, + "SortIndex": 2 + }, + { + "ComponentId": 10160640699095155981, + "SortIndex": 3 + } + ] + }, + "Component_[2395166459126906105]": { + "$type": "EditorGradientTransformComponent", + "Id": 2395166459126906105, + "Configuration": { + "ShapeReference": "", + "Bounds": [ + 50.0, + 50.0, + 1.0 + ] + } + }, + "Component_[4417011400526470160]": { + "$type": "EditorEntityIconComponent", + "Id": 4417011400526470160 + }, + "Component_[4601061670472962302]": { + "$type": "EditorPendingCompositionComponent", + "Id": 4601061670472962302 + }, + "Component_[4912800286535654244]": { + "$type": "EditorReferenceShapeComponent", + "Id": 4912800286535654244, + "Configuration": { + "ShapeEntityId": "Entity_[263607506826910]" + } + }, + "Component_[6233982345083723563]": { + "$type": "SelectionComponent", + "Id": 6233982345083723563 + }, + "Component_[6484803030406851652]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 6484803030406851652, + "Parent Entity": "Entity_[263573147088542]" + }, + "Component_[6813813525871080299]": { + "$type": "EditorOnlyEntityComponent", + "Id": 6813813525871080299 + } + } + }, + "Entity_[263607506826910]": { + "Id": "Entity_[263607506826910]", + "Name": "BushFlowerBlender", + "Components": { + "Component_[13725600808872754587]": { + "$type": "EditorEntityIconComponent", + "Id": 13725600808872754587 + }, + "Component_[15959807606564505710]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 15959807606564505710, + "Parent Entity": "Entity_[263598916892318]" + }, + "Component_[1596826146661515925]": { + "$type": "EditorPendingCompositionComponent", + "Id": 1596826146661515925 + }, + "Component_[4525591661239956058]": { + "$type": "EditorVisibilityComponent", + "Id": 4525591661239956058 + }, + "Component_[6683290476113150719]": { + "$type": "EditorCylinderShapeComponent", + "Id": 6683290476113150719, + "CylinderShape": { + "Configuration": { + "Radius": 25.0 + } + } + }, + "Component_[6879394931668195375]": { + "$type": "EditorEntitySortComponent", + "Id": 6879394931668195375, + "Child Entity Order": [ + "Entity_[263573147088542]", + "Entity_[263581737023134]" + ] + }, + "Component_[7229206794941734410]": { + "$type": "EditorAreaBlenderComponent", + "Id": 7229206794941734410, + "Configuration": { + "Operations": [ + "Entity_[263573147088542]", + "Entity_[263581737023134]" + ] + }, + "PreviewEntity": "Entity_[263607506826910]" + }, + "Component_[8772711204845372843]": { + "$type": "EditorLockComponent", + "Id": 8772711204845372843 + }, + "Component_[8959345022109725835]": { + "$type": "SelectionComponent", + "Id": 8959345022109725835 + }, + "Component_[9094488642973843583]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 9094488642973843583 + }, + "Component_[9112960617967513749]": { + "$type": "EditorInspectorComponent", + "Id": 9112960617967513749, + "ComponentOrderEntryArray": [ + { + "ComponentId": 15959807606564505710 + }, + { + "ComponentId": 7229206794941734410, + "SortIndex": 1 + }, + { + "ComponentId": 6683290476113150719, + "SortIndex": 2 + } + ] + }, + "Component_[9541665258597207652]": { + "$type": "EditorOnlyEntityComponent", + "Id": 9541665258597207652 + } + } + } + } +} \ No newline at end of file diff --git a/AutomatedTesting/Assets/Prefabs/PurpleFlower.prefab b/AutomatedTesting/Assets/Prefabs/PurpleFlower.prefab new file mode 100644 index 0000000000..a8716ec099 --- /dev/null +++ b/AutomatedTesting/Assets/Prefabs/PurpleFlower.prefab @@ -0,0 +1,129 @@ +{ + "ContainerEntity": { + "Id": "ContainerEntity", + "Name": "PurpleFlower", + "Components": { + "Component_[10519928302743666073]": { + "$type": "EditorPrefabComponent", + "Id": 10519928302743666073 + }, + "Component_[13894087802180240181]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 13894087802180240181, + "Parent Entity": "" + }, + "Component_[15788541052719571801]": { + "$type": "EditorEntityIconComponent", + "Id": 15788541052719571801 + }, + "Component_[15842981265136092481]": { + "$type": "SelectionComponent", + "Id": 15842981265136092481 + }, + "Component_[16360384897559021149]": { + "$type": "EditorInspectorComponent", + "Id": 16360384897559021149 + }, + "Component_[16713545675046303279]": { + "$type": "EditorVisibilityComponent", + "Id": 16713545675046303279 + }, + "Component_[1806734194268113785]": { + "$type": "EditorPendingCompositionComponent", + "Id": 1806734194268113785 + }, + "Component_[5392020700593853313]": { + "$type": "EditorEntitySortComponent", + "Id": 5392020700593853313, + "Child Entity Order": [ + "Entity_[14335611090324]" + ] + }, + "Component_[5995854518752659458]": { + "$type": "EditorLockComponent", + "Id": 5995854518752659458 + }, + "Component_[6963022284400845376]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 6963022284400845376 + }, + "Component_[8055275578170091546]": { + "$type": "EditorOnlyEntityComponent", + "Id": 8055275578170091546 + } + } + }, + "Entities": { + "Entity_[14335611090324]": { + "Id": "Entity_[14335611090324]", + "Name": "PurpleFlower", + "Components": { + "Component_[10887353073528055802]": { + "$type": "EditorPendingCompositionComponent", + "Id": 10887353073528055802 + }, + "Component_[12641127425852859189]": { + "$type": "AZ::Render::EditorMeshComponent", + "Id": 12641127425852859189, + "Controller": { + "Configuration": { + "ModelAsset": { + "assetId": { + "guid": "{D493A670-6D82-5AE9-A2C8-A2EB02684F71}", + "subId": 284799939 + }, + "assetHint": "assets/objects/foliage/grass_flower_purple.azmodel" + } + } + } + }, + "Component_[14406733303466080015]": { + "$type": "EditorInspectorComponent", + "Id": 14406733303466080015, + "ComponentOrderEntryArray": [ + { + "ComponentId": 9231452352781000222 + }, + { + "ComponentId": 12641127425852859189, + "SortIndex": 1 + } + ] + }, + "Component_[1452384341905923012]": { + "$type": "EditorLockComponent", + "Id": 1452384341905923012 + }, + "Component_[2215454016415585892]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 2215454016415585892 + }, + "Component_[4104108067383423623]": { + "$type": "EditorVisibilityComponent", + "Id": 4104108067383423623 + }, + "Component_[4197335450471807917]": { + "$type": "SelectionComponent", + "Id": 4197335450471807917 + }, + "Component_[6877680739064997650]": { + "$type": "EditorOnlyEntityComponent", + "Id": 6877680739064997650 + }, + "Component_[7372550507186490390]": { + "$type": "EditorEntityIconComponent", + "Id": 7372550507186490390 + }, + "Component_[7673532337364366244]": { + "$type": "EditorEntitySortComponent", + "Id": 7673532337364366244 + }, + "Component_[9231452352781000222]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 9231452352781000222, + "Parent Entity": "ContainerEntity" + } + } + } + } +} \ No newline at end of file diff --git a/AutomatedTesting/Assets/VegDescriptorLists/flower_pink.vegdescriptorlist b/AutomatedTesting/Assets/VegDescriptorLists/flower_pink.vegdescriptorlist index 372cafbdce..9120d992c7 100644 --- a/AutomatedTesting/Assets/VegDescriptorLists/flower_pink.vegdescriptorlist +++ b/AutomatedTesting/Assets/VegDescriptorLists/flower_pink.vegdescriptorlist @@ -2,11 +2,11 @@ - + - + - + diff --git a/AutomatedTesting/Gem/PythonTests/AWS/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/AWS/CMakeLists.txt index c8629bbe8b..10e90ecbfc 100644 --- a/AutomatedTesting/Gem/PythonTests/AWS/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/AWS/CMakeLists.txt @@ -12,12 +12,6 @@ ################################################################################ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) - # Only enable AWS automated tests on Windows - set(SUPPORTED_PLATFORMS "Windows" "Linux") - if (NOT "${PAL_PLATFORM_NAME}" IN_LIST SUPPORTED_PLATFORMS) - return() - endif() - ly_add_pytest( NAME AutomatedTesting::AWSTests TEST_SUITE awsi diff --git a/AutomatedTesting/Gem/PythonTests/AWS/README.md b/AutomatedTesting/Gem/PythonTests/AWS/README.md index a25f39d9c2..73ef685261 100644 --- a/AutomatedTesting/Gem/PythonTests/AWS/README.md +++ b/AutomatedTesting/Gem/PythonTests/AWS/README.md @@ -3,7 +3,7 @@ ## Prerequisites 1. Build the O3DE Editor and AutomatedTesting.GameLauncher in Profile. 2. Install the latest version of NodeJs. -3. AWS CLI is installed and configured following [Configuration and Credential File Settings](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html). +3. AWS CLI is installed and AWS crendentials are configured via [environment variables](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html) or [default profile](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html). 4. [AWS Cloud Development Kit (CDK)](https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html#getting_started_install) is installed. ## Deploy CDK Applications diff --git a/AutomatedTesting/Gem/PythonTests/AWS/common/aws_credentials.py b/AutomatedTesting/Gem/PythonTests/AWS/common/aws_credentials.py index c6401f2828..d0bbfe7c3e 100644 --- a/AutomatedTesting/Gem/PythonTests/AWS/common/aws_credentials.py +++ b/AutomatedTesting/Gem/PythonTests/AWS/common/aws_credentials.py @@ -68,6 +68,10 @@ class AwsCredentials: if (len(self._credentials.sections()) == 0) and (not self._credentials_file_exists): os.remove(self._credentials_path) return + + credentials_file_dir = os.path.dirname(self._credentials_path) + if not os.path.isdir(credentials_file_dir): + os.makedirs(credentials_file_dir) with open(self._credentials_path, 'w+') as credential_file: self._credentials.write(credential_file) diff --git a/AutomatedTesting/Gem/PythonTests/AWS/common/aws_utils.py b/AutomatedTesting/Gem/PythonTests/AWS/common/aws_utils.py index 92f3762e71..2a5efbd03f 100644 --- a/AutomatedTesting/Gem/PythonTests/AWS/common/aws_utils.py +++ b/AutomatedTesting/Gem/PythonTests/AWS/common/aws_utils.py @@ -16,7 +16,7 @@ logging.getLogger('nose').setLevel(logging.WARNING) class AwsUtils: def __init__(self, arn: str, session_name: str, region_name: str): - local_session = boto3.Session(profile_name='default') + local_session = boto3.Session() local_sts_client = local_session.client('sts') self._local_account_id = local_sts_client.get_caller_identity()["Account"] logger.info(f'Local Account Id: {self._local_account_id}') diff --git a/AutomatedTesting/Gem/PythonTests/AWS/common/constants.py b/AutomatedTesting/Gem/PythonTests/AWS/common/constants.py index b12aca5f29..a38974073a 100644 --- a/AutomatedTesting/Gem/PythonTests/AWS/common/constants.py +++ b/AutomatedTesting/Gem/PythonTests/AWS/common/constants.py @@ -6,11 +6,13 @@ SPDX-License-Identifier: Apache-2.0 OR MIT """ import os +import platform # ARN of the IAM role to assume for retrieving temporary AWS credentials ASSUME_ROLE_ARN = os.environ.get('ASSUME_ROLE_ARN', 'arn:aws:iam::645075835648:role/o3de-automation-tests') # Name of the AWS project deployed by the CDK applications -AWS_PROJECT_NAME = os.environ.get('O3DE_AWS_PROJECT_NAME', 'AWSAUTO') +AWS_PROJECT_NAME = os.environ.get('O3DE_AWS_PROJECT_NAME').upper() if os.environ.get('O3DE_AWS_PROJECT_NAME') else \ + (os.environ.get('BRANCH_NAME', '') + '-' + os.environ.get('PIPELINE_NAME', '') + '-' + platform.system()).upper() # Region for the existing CloudFormation stacks used by the automation tests AWS_REGION = os.environ.get('O3DE_AWS_DEPLOY_REGION', 'us-east-1') # Name of the default resource mapping config file used by the automation tests diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py index 7051b9983c..cca20bbf8c 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py @@ -21,7 +21,7 @@ TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests") @pytest.mark.parametrize("launcher_platform", ['windows_editor']) class TestAutomation(EditorTestSuite): - enable_prefab_system = False + enable_prefab_system = True @pytest.mark.test_case_id("C36525657") class AtomEditorComponents_BloomAdded(EditorSharedTest): @@ -120,6 +120,14 @@ class TestAutomation(EditorTestSuite): class AtomEditorComponents_SSAOAdded(EditorSharedTest): from Atom.tests import hydra_AtomEditorComponents_SSAOAdded as test_module + @pytest.mark.test_case_id("C36529666") + class AtomEditorComponentsLevel_DiffuseGlobalIlluminationAdded(EditorSharedTest): + from Atom.tests import hydra_AtomEditorComponentsLevel_DiffuseGlobalIlluminationAdded as test_module + + @pytest.mark.test_case_id("C36525660") + class AtomEditorComponentsLevel_DisplayMapperAdded(EditorSharedTest): + from Atom.tests import hydra_AtomEditorComponentsLevel_DisplayMapperAdded as test_module + class ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges(EditorSharedTest): from Atom.tests import hydra_ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges as test_module @@ -173,9 +181,11 @@ class TestMaterialEditorBasicTests(object): "Document saved as copy is saved with changes: True", "Document saved as child is saved with changes: True", "Save All worked as expected: True", + "P1: Asset Browser visibility working as expected: True", + "P1: Inspector visibility working as expected: True", ] unexpected_lines = [ - "Traceback (most recent call last):" + # Including any lines in unexpected_lines will cause the test to run for the duration of the timeout ] hydra.launch_and_validate_results( diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py index c9182070f6..5299e55a2b 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py @@ -9,97 +9,20 @@ import os import pytest -import ly_test_tools.environment.file_system as file_system -import editor_python_test_tools.hydra_test_utils as hydra from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite -from Atom.atom_utils.atom_constants import LIGHT_TYPES logger = logging.getLogger(__name__) TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests") -@pytest.mark.parametrize("project", ["AutomatedTesting"]) -@pytest.mark.parametrize("launcher_platform", ['windows_editor']) -@pytest.mark.parametrize("level", ["auto_test"]) -class TestAtomEditorComponentsMain(object): - """Holds tests for Atom components.""" - - @pytest.mark.test_case_id("C34525095") - def test_AtomEditorComponents_LightComponent( - self, request, editor, workspace, project, launcher_platform, level): - """ - Please review the hydra script run by this test for more specific test info. - Tests that the Light component has the expected property options available to it. - """ - cfg_args = [level] - - expected_lines = [ - "light_entity Entity successfully created", - "Entity has a Light component", - "light_entity_test: Component added to the entity: True", - f"light_entity_test: Property value is {LIGHT_TYPES['sphere']} which matches {LIGHT_TYPES['sphere']}", - "Controller|Configuration|Shadows|Enable shadow set to True", - "light_entity Controller|Configuration|Shadows|Shadowmap size: SUCCESS", - "Controller|Configuration|Shadows|Shadow filter method set to 1", # PCF - "Controller|Configuration|Shadows|Filtering sample count set to 4", - "Controller|Configuration|Shadows|Filtering sample count set to 64", - "Controller|Configuration|Shadows|Shadow filter method set to 2", # ESM - "Controller|Configuration|Shadows|ESM exponent set to 50.0", - "Controller|Configuration|Shadows|ESM exponent set to 5000.0", - "Controller|Configuration|Shadows|Shadow filter method set to 3", # ESM+PCF - f"light_entity_test: Property value is {LIGHT_TYPES['spot_disk']} which matches {LIGHT_TYPES['spot_disk']}", - f"light_entity_test: Property value is {LIGHT_TYPES['capsule']} which matches {LIGHT_TYPES['capsule']}", - f"light_entity_test: Property value is {LIGHT_TYPES['quad']} which matches {LIGHT_TYPES['quad']}", - "light_entity Controller|Configuration|Fast approximation: SUCCESS", - "light_entity Controller|Configuration|Both directions: SUCCESS", - f"light_entity_test: Property value is {LIGHT_TYPES['polygon']} which matches {LIGHT_TYPES['polygon']}", - f"light_entity_test: Property value is {LIGHT_TYPES['simple_point']} " - f"which matches {LIGHT_TYPES['simple_point']}", - "Controller|Configuration|Attenuation radius|Mode set to 0", - "Controller|Configuration|Attenuation radius|Radius set to 100.0", - f"light_entity_test: Property value is {LIGHT_TYPES['simple_spot']} " - f"which matches {LIGHT_TYPES['simple_spot']}", - "Controller|Configuration|Shutters|Outer angle set to 45.0", - "Controller|Configuration|Shutters|Outer angle set to 90.0", - "light_entity_test: Component added to the entity: True", - "Light component test (non-GPU) completed.", - ] - - unexpected_lines = ["Traceback (most recent call last):"] - - hydra.launch_and_validate_results( - request, - TEST_DIRECTORY, - editor, - "hydra_AtomEditorComponents_LightComponent.py", - timeout=120, - expected_lines=expected_lines, - unexpected_lines=unexpected_lines, - halt_on_unexpected=True, - null_renderer=True, - cfg_args=cfg_args, - enable_prefab_system=False, - ) - - @pytest.mark.parametrize("project", ["AutomatedTesting"]) @pytest.mark.parametrize("launcher_platform", ['windows_editor']) class TestAutomation(EditorTestSuite): enable_prefab_system = False - #this test is intermittently timing out without ever having executed. sandboxing while we investigate cause. + # this test is intermittently timing out without ever having executed. sandboxing while we investigate cause. @pytest.mark.test_case_id("C36525660") class AtomEditorComponents_DisplayMapperAdded(EditorSharedTest): from Atom.tests import hydra_AtomEditorComponents_DisplayMapperAdded as test_module - - # this test causes editor to crash when using slices. once automation transitions to prefabs it should pass - @pytest.mark.test_case_id("C36529666") - class AtomEditorComponentsLevel_DiffuseGlobalIlluminationAdded(EditorSharedTest): - from Atom.tests import hydra_AtomEditorComponentsLevel_DiffuseGlobalIlluminationAdded as test_module - - # this test causes editor to crash when using slices. once automation transitions to prefabs it should pass - @pytest.mark.test_case_id("C36525660") - class AtomEditorComponentsLevel_DisplayMapperAdded(EditorSharedTest): - from Atom.tests import hydra_AtomEditorComponentsLevel_DisplayMapperAdded as test_module diff --git a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/material_editor_utils.py b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/material_editor_utils.py index f7ff970541..96eeb4279e 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/material_editor_utils.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/material_editor_utils.py @@ -125,11 +125,11 @@ def is_pane_visible(pane_name): """ :return: bool """ - return atomtools.AtomToolsWindowRequestBus(bus.Broadcast, "IsDockWidgetVisible", pane_name) + return atomtools.AtomToolsMainWindowRequestBus(bus.Broadcast, "IsDockWidgetVisible", pane_name) def set_pane_visibility(pane_name, value): - atomtools.AtomToolsWindowRequestBus(bus.Broadcast, "SetDockWidgetVisible", pane_name, value) + atomtools.AtomToolsMainWindowRequestBus(bus.Broadcast, "SetDockWidgetVisible", pane_name, value) def select_lighting_config(config_name): diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponentsLevel_DiffuseGlobalIlluminationAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponentsLevel_DiffuseGlobalIlluminationAdded.py index ddcd5c3c46..0c9b39e354 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponentsLevel_DiffuseGlobalIlluminationAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponentsLevel_DiffuseGlobalIlluminationAdded.py @@ -60,7 +60,7 @@ def AtomEditorComponentsLevel_DiffuseGlobalIllumination_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Add Diffuse Global Illumination level component to the level entity. @@ -86,10 +86,10 @@ def AtomEditorComponentsLevel_DiffuseGlobalIllumination_AddedToEntity(): # 4. Set Quality Level property to Low diffuse_global_illumination_component.set_component_property_value( - AtomComponentProperties.diffuse_global_illumination('Quality Level', GLOBAL_ILLUMINATION_QUALITY['Low'])) + AtomComponentProperties.diffuse_global_illumination('Quality Level'), GLOBAL_ILLUMINATION_QUALITY['Low']) quality = diffuse_global_illumination_component.get_component_property_value( AtomComponentProperties.diffuse_global_illumination('Quality Level')) - Report.result(diffuse_global_illumination_quality, quality == GLOBAL_ILLUMINATION_QUALITY['Low']) + Report.result(Tests.diffuse_global_illumination_quality, quality == GLOBAL_ILLUMINATION_QUALITY['Low']) # 5. Enter/Exit game mode. TestHelper.enter_game_mode(Tests.enter_game_mode) diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponentsLevel_DisplayMapperAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponentsLevel_DisplayMapperAdded.py index c050dd76d4..f9660957bb 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponentsLevel_DisplayMapperAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponentsLevel_DisplayMapperAdded.py @@ -67,7 +67,7 @@ def AtomEditorComponentsLevel_DisplayMapper_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Add Display Mapper level component to the level entity. @@ -102,7 +102,7 @@ def AtomEditorComponentsLevel_DisplayMapper_AddedToEntity(): display_mapper_component.set_component_property_value( AtomComponentProperties.display_mapper('Enable LDR color grading LUT'), True) Report.result( - Test.enable_ldr_color_grading_lut, + Tests.enable_ldr_color_grading_lut, display_mapper_component.get_component_property_value( AtomComponentProperties.display_mapper('Enable LDR color grading LUT')) is True) diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_BloomAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_BloomAdded.py index 56b22eb20d..ce29a1de88 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_BloomAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_BloomAdded.py @@ -97,7 +97,7 @@ def AtomEditorComponents_Bloom_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Create an Bloom entity with no components. @@ -170,10 +170,12 @@ def AtomEditorComponents_Bloom_AddedToEntity(): # 13. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, bloom_entity.exists()) # 14. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not bloom_entity.exists()) # 15. Look for errors and asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DecalAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DecalAdded.py index e840cf3cf1..eb5e24e3a6 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DecalAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DecalAdded.py @@ -95,7 +95,7 @@ def AtomEditorComponents_Decal_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Create a Decal entity with no components. @@ -162,6 +162,7 @@ def AtomEditorComponents_Decal_AddedToEntity(): # 11. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not decal_entity.exists()) # 12. Look for errors and asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DeferredFogAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DeferredFogAdded.py index 71163ece94..f1578cbf8d 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DeferredFogAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DeferredFogAdded.py @@ -97,7 +97,7 @@ def AtomEditorComponents_DeferredFog_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Create an Deferred Fog entity with no components. @@ -174,10 +174,12 @@ def AtomEditorComponents_DeferredFog_AddedToEntity(): # 13. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, deferred_fog_entity.exists()) # 14. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not deferred_fog_entity.exists()) # 15. Look for errors and asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DepthOfFieldAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DepthOfFieldAdded.py index e2c5f9c77d..3913420981 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DepthOfFieldAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DepthOfFieldAdded.py @@ -107,7 +107,7 @@ def AtomEditorComponents_DepthOfField_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Create a DepthOfField entity with no components. @@ -189,10 +189,12 @@ def AtomEditorComponents_DepthOfField_AddedToEntity(): # 15. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, depth_of_field_entity.exists()) # 16. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not depth_of_field_entity.exists()) # 17. Look for errors and asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DiffuseProbeGridAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DiffuseProbeGridAdded.py index f42c091057..04b4f7876b 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DiffuseProbeGridAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DiffuseProbeGridAdded.py @@ -90,7 +90,7 @@ def AtomEditorComponents_DiffuseProbeGrid_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Create a Diffuse Probe Grid entity with no components. @@ -168,10 +168,12 @@ def AtomEditorComponents_DiffuseProbeGrid_AddedToEntity(): # 12. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, diffuse_probe_grid_entity.exists()) # 13. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not diffuse_probe_grid_entity.exists()) # 14. Look for errors or asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DirectionalLightAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DirectionalLightAdded.py index f3ffc0f366..19cfbedcd5 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DirectionalLightAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DirectionalLightAdded.py @@ -95,7 +95,7 @@ def AtomEditorComponents_DirectionalLight_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Create a Directional Light entity with no components. @@ -168,10 +168,12 @@ def AtomEditorComponents_DirectionalLight_AddedToEntity(): # 12. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, directional_light_entity.exists()) # 13. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not directional_light_entity.exists()) # 14. Look for errors and asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DisplayMapperAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DisplayMapperAdded.py index 558d69046e..d3ea669eab 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DisplayMapperAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DisplayMapperAdded.py @@ -91,7 +91,7 @@ def AtomEditorComponents_DisplayMapper_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Create a Display Mapper entity with no components. @@ -166,10 +166,12 @@ def AtomEditorComponents_DisplayMapper_AddedToEntity(): # 11. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, display_mapper_entity.exists()) # 12. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not display_mapper_entity.exists()) # 13. Look for errors and asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_EntityReferenceAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_EntityReferenceAdded.py index dddcca64fa..ec402f0f5f 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_EntityReferenceAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_EntityReferenceAdded.py @@ -81,7 +81,7 @@ def AtomEditorComponents_EntityReference_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Create an Entity Reference entity with no components. @@ -139,10 +139,12 @@ def AtomEditorComponents_EntityReference_AddedToEntity(): # 9. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, entity_reference_entity.exists()) # 10. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not entity_reference_entity.exists()) # 11. Look for errors and asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_ExposureControlAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_ExposureControlAdded.py index 6fa9660539..f60f0e18be 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_ExposureControlAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_ExposureControlAdded.py @@ -101,7 +101,7 @@ def AtomEditorComponents_ExposureControl_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Creation of Exposure Control entity with no components. @@ -169,10 +169,12 @@ def AtomEditorComponents_ExposureControl_AddedToEntity(): # 12. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, exposure_control_entity.exists()) # 13. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not exposure_control_entity.exists()) # 14. Look for errors and asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_GlobalSkylightIBLAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_GlobalSkylightIBLAdded.py index 7f0c38e289..0e8e6fa43e 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_GlobalSkylightIBLAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_GlobalSkylightIBLAdded.py @@ -99,7 +99,7 @@ def AtomEditorComponents_GlobalSkylightIBL_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Create a Global Skylight (IBL) entity with no components. @@ -176,10 +176,12 @@ def AtomEditorComponents_GlobalSkylightIBL_AddedToEntity(): # 11. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, global_skylight_entity.exists()) # 12. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not global_skylight_entity.exists()) # 13. Look for errors and asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_GridAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_GridAdded.py index a77a1f50a4..3c6d261f22 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_GridAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_GridAdded.py @@ -82,7 +82,7 @@ def AtomEditorComponents_Grid_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Create a Grid entity with no components. @@ -139,10 +139,12 @@ def AtomEditorComponents_Grid_AddedToEntity(): # 9. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, grid_entity.exists()) # 10. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not grid_entity.exists()) # 11. Look for errors or asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_HDRColorGradingAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_HDRColorGradingAdded.py index 4972079fcd..5846206e50 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_HDRColorGradingAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_HDRColorGradingAdded.py @@ -96,7 +96,7 @@ def AtomEditorComponents_HDRColorGrading_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Create an HDR Color Grading entity with no components. @@ -173,10 +173,12 @@ def AtomEditorComponents_HDRColorGrading_AddedToEntity(): # 13. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, hdr_color_grading_entity.exists()) # 14. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not hdr_color_grading_entity.exists()) # 15. Look for errors and asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_HDRiSkyboxAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_HDRiSkyboxAdded.py index 0f96bc5424..fc093b60db 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_HDRiSkyboxAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_HDRiSkyboxAdded.py @@ -87,7 +87,7 @@ def AtomEditorComponents_HDRiSkybox_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Create an HDRi Skybox with no components. @@ -158,10 +158,12 @@ def AtomEditorComponents_HDRiSkybox_AddedToEntity(): # 10. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, hdri_skybox_entity.exists()) # 11. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not hdri_skybox_entity.exists()) # 12. Look for errors or asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LightAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LightAdded.py index 249671556d..75a04612a3 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LightAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LightAdded.py @@ -89,7 +89,7 @@ def AtomEditorComponents_Light_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Create a Light entity with no components. @@ -144,10 +144,12 @@ def AtomEditorComponents_Light_AddedToEntity(): # 9. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, light_entity.exists()) # 10. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not light_entity.exists()) # 11. Look for errors asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LightComponent.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LightComponent.py deleted file mode 100644 index 7ecdc6859b..0000000000 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LightComponent.py +++ /dev/null @@ -1,213 +0,0 @@ -""" -Copyright (c) Contributors to the Open 3D Engine Project. -For complete copyright and license terms please see the LICENSE at the root of this distribution. - -SPDX-License-Identifier: Apache-2.0 OR MIT -""" - -import os -import sys - -import azlmbr.bus as bus -import azlmbr.editor as editor -import azlmbr.math as math -import azlmbr.paths -import azlmbr.legacy.general as general - -sys.path.append(os.path.join(azlmbr.paths.projectroot, "Gem", "PythonTests")) - -import editor_python_test_tools.hydra_editor_utils as hydra -from Atom.atom_utils.atom_constants import LIGHT_TYPES - -LIGHT_TYPE_PROPERTY = 'Controller|Configuration|Light type' -SPHERE_AND_SPOT_DISK_LIGHT_PROPERTIES = [ - ("Controller|Configuration|Shadows|Enable shadow", True), - ("Controller|Configuration|Shadows|Shadowmap size", 0), # 256 - ("Controller|Configuration|Shadows|Shadowmap size", 1), # 512 - ("Controller|Configuration|Shadows|Shadowmap size", 2), # 1024 - ("Controller|Configuration|Shadows|Shadowmap size", 3), # 2048 - ("Controller|Configuration|Shadows|Shadow filter method", 1), # PCF - ("Controller|Configuration|Shadows|Filtering sample count", 4.0), - ("Controller|Configuration|Shadows|Filtering sample count", 64.0), - ("Controller|Configuration|Shadows|Shadow filter method", 2), # ECM - ("Controller|Configuration|Shadows|ESM exponent", 50), - ("Controller|Configuration|Shadows|ESM exponent", 5000), - ("Controller|Configuration|Shadows|Shadow filter method", 3), # ESM+PCF -] -QUAD_LIGHT_PROPERTIES = [ - ("Controller|Configuration|Both directions", True), - ("Controller|Configuration|Fast approximation", True), -] -SIMPLE_POINT_LIGHT_PROPERTIES = [ - ("Controller|Configuration|Attenuation radius|Mode", 0), - ("Controller|Configuration|Attenuation radius|Radius", 100.0), -] -SIMPLE_SPOT_LIGHT_PROPERTIES = [ - ("Controller|Configuration|Shutters|Inner angle", 45.0), - ("Controller|Configuration|Shutters|Outer angle", 90.0), -] - - -def verify_required_component_property_value(entity_name, component, property_path, expected_property_value): - """ - Compares the property value of component against the expected_property_value. - :param entity_name: name of the entity to use (for test verification purposes). - :param component: component to check on a given entity for its current property value. - :param property_path: the path to the property inside the component. - :param expected_property_value: The value expected from the value inside property_path. - :return: None, but prints to general.log() which the test uses to verify against. - """ - property_value = editor.EditorComponentAPIBus( - bus.Broadcast, "GetComponentProperty", component, property_path).GetValue() - general.log(f"{entity_name}_test: Property value is {property_value} " - f"which matches {expected_property_value}") - - -def run(): - """ - Test Case - Light Component - 1. Creates a "light_entity" Entity and attaches a "Light" component to it. - 2. Updates the Light component to each light type option from the LIGHT_TYPES constant. - 3. The test will check the Editor log to ensure each light type was selected. - 4. Prints the string "Light component test (non-GPU) completed" after completion. - - Tests will fail immediately if any of these log lines are found: - 1. Trace::Assert - 2. Trace::Error - 3. Traceback (most recent call last): - - :return: None - """ - # Create a "light_entity" entity with "Light" component. - light_entity_name = "light_entity" - light_component = "Light" - light_entity = hydra.Entity(light_entity_name) - light_entity.create_entity(math.Vector3(-1.0, -2.0, 3.0), [light_component]) - general.log( - f"{light_entity_name}_test: Component added to the entity: " - f"{hydra.has_components(light_entity.id, [light_component])}") - - # Populate the light_component_id_pair value so that it can be used to select all Light component options. - light_component_id_pair = None - component_type_id_list = azlmbr.editor.EditorComponentAPIBus( - azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', [light_component], 0) - if len(component_type_id_list) < 1: - general.log(f"ERROR: A component class with name {light_component} doesn't exist") - light_component_id_pair = None - elif len(component_type_id_list) > 1: - general.log(f"ERROR: Found more than one component classes with same name: {light_component}") - light_component_id_pair = None - entity_component_id_pair = azlmbr.editor.EditorComponentAPIBus( - azlmbr.bus.Broadcast, 'GetComponentOfType', light_entity.id, component_type_id_list[0]) - if entity_component_id_pair.IsSuccess(): - light_component_id_pair = entity_component_id_pair.GetValue() - - # Test each Light component option can be selected and it's properties updated. - # Point (sphere) light type checks. - light_type_property_test( - light_type=LIGHT_TYPES['sphere'], - light_properties=SPHERE_AND_SPOT_DISK_LIGHT_PROPERTIES, - light_component_id_pair=light_component_id_pair, - light_entity_name=light_entity_name, - light_entity=light_entity - ) - - # Spot (disk) light type checks. - light_type_property_test( - light_type=LIGHT_TYPES['spot_disk'], - light_properties=SPHERE_AND_SPOT_DISK_LIGHT_PROPERTIES, - light_component_id_pair=light_component_id_pair, - light_entity_name=light_entity_name, - light_entity=light_entity - ) - - # Capsule light type checks. - azlmbr.editor.EditorComponentAPIBus( - azlmbr.bus.Broadcast, - 'SetComponentProperty', - light_component_id_pair, - LIGHT_TYPE_PROPERTY, - LIGHT_TYPES['capsule'] - ) - verify_required_component_property_value( - entity_name=light_entity_name, - component=light_entity.components[0], - property_path=LIGHT_TYPE_PROPERTY, - expected_property_value=LIGHT_TYPES['capsule'] - ) - - # Quad light type checks. - light_type_property_test( - light_type=LIGHT_TYPES['quad'], - light_properties=QUAD_LIGHT_PROPERTIES, - light_component_id_pair=light_component_id_pair, - light_entity_name=light_entity_name, - light_entity=light_entity - ) - - # Polygon light type checks. - azlmbr.editor.EditorComponentAPIBus( - azlmbr.bus.Broadcast, - 'SetComponentProperty', - light_component_id_pair, - LIGHT_TYPE_PROPERTY, - LIGHT_TYPES['polygon'] - ) - verify_required_component_property_value( - entity_name=light_entity_name, - component=light_entity.components[0], - property_path=LIGHT_TYPE_PROPERTY, - expected_property_value=LIGHT_TYPES['polygon'] - ) - - # Point (simple punctual) light type checks. - light_type_property_test( - light_type=LIGHT_TYPES['simple_point'], - light_properties=SIMPLE_POINT_LIGHT_PROPERTIES, - light_component_id_pair=light_component_id_pair, - light_entity_name=light_entity_name, - light_entity=light_entity - ) - - # Spot (simple punctual) light type checks. - light_type_property_test( - light_type=LIGHT_TYPES['simple_spot'], - light_properties=SIMPLE_SPOT_LIGHT_PROPERTIES, - light_component_id_pair=light_component_id_pair, - light_entity_name=light_entity_name, - light_entity=light_entity - ) - - general.log("Light component test (non-GPU) completed.") - - -def light_type_property_test(light_type, light_properties, light_component_id_pair, light_entity_name, light_entity): - """ - Updates the current light type and modifies its properties, then verifies they are accurate to what was set. - :param light_type: The type of light to update, must match a value in LIGHT_TYPES - :param light_properties: List of tuples detailing properties to modify with update values. - :param light_component_id_pair: Entity + component ID pair for updating the light component on a given entity. - :param light_entity_name: the name of the Entity holding the light component. - :param light_entity: the Entity object containing the light component. - :return: None - """ - azlmbr.editor.EditorComponentAPIBus( - azlmbr.bus.Broadcast, - 'SetComponentProperty', - light_component_id_pair, - LIGHT_TYPE_PROPERTY, - light_type - ) - verify_required_component_property_value( - entity_name=light_entity_name, - component=light_entity.components[0], - property_path=LIGHT_TYPE_PROPERTY, - expected_property_value=light_type - ) - - for light_property in light_properties: - light_entity.get_set_test(0, light_property[0], light_property[1]) - - -if __name__ == "__main__": - run() diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LookModificationAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LookModificationAdded.py index afb8033426..149af73151 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LookModificationAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LookModificationAdded.py @@ -104,7 +104,7 @@ def AtomEditorComponents_LookModification_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Create an Look Modification entity with no components. @@ -192,10 +192,12 @@ def AtomEditorComponents_LookModification_AddedToEntity(): # 14. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, look_modification_entity.exists()) # 15. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not look_modification_entity.exists()) # 16. Look for errors and asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MaterialAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MaterialAdded.py index c613bb23e7..919a6753f4 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MaterialAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MaterialAdded.py @@ -102,7 +102,7 @@ def AtomEditorComponents_Material_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Create a Material entity with no components. @@ -184,10 +184,12 @@ def AtomEditorComponents_Material_AddedToEntity(): # 16. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, material_entity.exists()) # 17. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not material_entity.exists()) # 18. Look for errors or asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MeshAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MeshAdded.py index 9d56753961..a87ee75b53 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MeshAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MeshAdded.py @@ -87,7 +87,7 @@ def AtomEditorComponents_Mesh_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Create a Mesh entity with no components. @@ -151,10 +151,12 @@ def AtomEditorComponents_Mesh_AddedToEntity(): # 10. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, mesh_entity.exists()) # 11. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not mesh_entity.exists()) # 12. Look for errors or asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_OcclusionCullingPlaneAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_OcclusionCullingPlaneAdded.py index 4226ae3dfe..56bb5eb68c 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_OcclusionCullingPlaneAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_OcclusionCullingPlaneAdded.py @@ -80,7 +80,7 @@ def AtomEditorComponents_OcclusionCullingPlane_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Create a occlusion culling plane entity with no components. @@ -140,10 +140,12 @@ def AtomEditorComponents_OcclusionCullingPlane_AddedToEntity(): # 9. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, occlusion_culling_plane_entity.exists()) # 10. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not occlusion_culling_plane_entity.exists()) # 11. Look for errors or asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PhysicalSkyAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PhysicalSkyAdded.py index fa8c626016..e0c558811e 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PhysicalSkyAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PhysicalSkyAdded.py @@ -89,7 +89,7 @@ def AtomEditorComponents_PhysicalSky_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Create a Physical Sky entity with no components. @@ -146,10 +146,12 @@ def AtomEditorComponents_PhysicalSky_AddedToEntity(): # 9. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, physical_sky_entity.exists()) # 10. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not physical_sky_entity.exists()) # 11. Look for errors and asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXGradientWeightModifierAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXGradientWeightModifierAdded.py index 6e4ae2d9ac..b36267433f 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXGradientWeightModifierAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXGradientWeightModifierAdded.py @@ -92,7 +92,7 @@ def AtomEditorComponents_PostFXGradientWeightModifier_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Create a PostFX Gradient Weight Modifier entity with no components. @@ -162,10 +162,12 @@ def AtomEditorComponents_PostFXGradientWeightModifier_AddedToEntity(): # 12. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, postfx_gradient_weight_entity.exists()) # 13. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not postfx_gradient_weight_entity.exists()) # 14. Look for errors or asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXLayerAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXLayerAdded.py index efef4c0a43..07fffb9bde 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXLayerAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXLayerAdded.py @@ -80,7 +80,7 @@ def AtomEditorComponents_postfx_layer_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Create a PostFX Layer entity with no components. @@ -137,10 +137,12 @@ def AtomEditorComponents_postfx_layer_AddedToEntity(): # 9. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, postfx_layer_entity.exists()) # 10. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not postfx_layer_entity.exists()) # 11. Look for errors or asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXRadiusWeightModifierAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXRadiusWeightModifierAdded.py index 228ddfcdc5..616233d2d2 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXRadiusWeightModifierAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXRadiusWeightModifierAdded.py @@ -92,7 +92,7 @@ def AtomEditorComponents_PostFXRadiusWeightModifier_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Create a Post FX Radius Weight Modifier entity with no components. @@ -161,10 +161,12 @@ def AtomEditorComponents_PostFXRadiusWeightModifier_AddedToEntity(): # 12. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, postfx_radius_weight_entity.exists()) # 13. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not postfx_radius_weight_entity.exists()) # 14. Look for errors and asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFxShapeWeightModifierAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFxShapeWeightModifierAdded.py index 0a37ac6bf7..5f7d571a18 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFxShapeWeightModifierAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFxShapeWeightModifierAdded.py @@ -98,7 +98,7 @@ def AtomEditorComponents_postfx_shape_weight_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Create a PostFx Shape Weight Modifier entity with no components. @@ -188,10 +188,12 @@ def AtomEditorComponents_postfx_shape_weight_AddedToEntity(): # 15. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, postfx_shape_weight_entity.exists()) # 16. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not postfx_shape_weight_entity.exists()) # 17. Look for errors or asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_ReflectionProbeAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_ReflectionProbeAdded.py index 70adf9143a..85156b4db6 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_ReflectionProbeAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_ReflectionProbeAdded.py @@ -97,7 +97,7 @@ def AtomEditorComponents_ReflectionProbe_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Create a Reflection Probe entity with no components. @@ -183,10 +183,12 @@ def AtomEditorComponents_ReflectionProbe_AddedToEntity(): # 13. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, reflection_probe_entity.exists()) # 14. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not reflection_probe_entity.exists()) # 15. Look for errors or asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_SSAOAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_SSAOAdded.py index 15f40f8b70..09f77c4a9f 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_SSAOAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_SSAOAdded.py @@ -94,7 +94,7 @@ def AtomEditorComponents_SSAO_AddedToEntity(): # 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") + TestHelper.open_level("Graphics", "base_empty") # Test steps begin. # 1. Create a SSAO entity with no components. @@ -163,10 +163,12 @@ def AtomEditorComponents_SSAO_AddedToEntity(): # 12. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, ssao_entity.exists()) # 13. REDO deletion. general.redo() + general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not ssao_entity.exists()) # 14. Look for errors and asserts. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomMaterialEditor_BasicTests.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomMaterialEditor_BasicTests.py index baad02318d..bd00a84919 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomMaterialEditor_BasicTests.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomMaterialEditor_BasicTests.py @@ -36,6 +36,19 @@ MATERIAL_TYPE_PATH = os.path.join( CACHE_FILE_EXTENSION = ".azmaterial" +def verify_pane_visibility(pane_name: str): + """ + print log lines indicating Material Editor pane visibility function + :param pane_name: Name of the pane to be tested + """ + initial_value = material_editor.is_pane_visible(pane_name) + material_editor.set_pane_visibility(pane_name, not initial_value) + result = (material_editor.is_pane_visible(pane_name) is not initial_value) + material_editor.set_pane_visibility(pane_name, initial_value) + result = result and (initial_value is material_editor.is_pane_visible(pane_name)) + print(f"P1: {pane_name} visibility working as expected: {result}") + + def run(): """ Summary: @@ -49,9 +62,12 @@ def run(): 7. Saving as a New Material 8. Saving as a Child Material 9. Saving all Open Materials + 10. Verify Asset Browser pane visibility + 11. Verify Material Inspector pane visibility Expected Result: All the above functions work as expected in Material Editor. + Pane visibility functions as expected :return: None """ @@ -186,6 +202,14 @@ def run(): material_editor.set_property(document2_id, property2_name, initial_color) material_editor.save_all() material_editor.close_all_documents() + + # 10) Verify Asset Browser pane visibility + verify_pane_visibility("Asset Browser") + + # 11) Verify Material Inspector pane visibility + verify_pane_visibility("Inspector") + + # Confirm documents closed and exit Material Editor material_editor.wait_for_condition(lambda: (not material_editor.is_open(document1_id)) and (not material_editor.is_open(document2_id)) and diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_editor_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_editor_utils.py index 36fc6003f7..ac74c611a2 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_editor_utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_editor_utils.py @@ -5,9 +5,9 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT """ +import collections.abc from typing import List from math import isclose -import collections.abc import azlmbr.bus as bus import azlmbr.editor as editor diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt index ba607ede32..2e3e72883c 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt @@ -14,7 +14,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ NAME AutomatedTesting::DynamicVegetationTests_Main_Optimized TEST_SERIAL TEST_SUITE main - PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Main_Optimized.py + PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Main.py RUNTIME_DEPENDENCIES AZ::AssetProcessor Legacy::Editor @@ -27,7 +27,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ NAME AutomatedTesting::DynamicVegetationTests_Periodic_Optimized TEST_SERIAL TEST_SUITE periodic - PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Periodic_Optimized.py + PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Periodic.py RUNTIME_DEPENDENCIES AZ::AssetProcessor Legacy::Editor @@ -58,7 +58,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ NAME AutomatedTesting::GradientSignalTests_Periodic_Optimized TEST_SERIAL TEST_SUITE periodic - PATH ${CMAKE_CURRENT_LIST_DIR}/gradient_signal/TestSuite_Periodic_Optimized.py + PATH ${CMAKE_CURRENT_LIST_DIR}/gradient_signal/TestSuite_Periodic.py RUNTIME_DEPENDENCIES AZ::AssetProcessor Legacy::Editor diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude.py index 66aa6d27ad..aa5e5e4f9c 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude.py @@ -51,22 +51,18 @@ def AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude(): import os - import azlmbr.asset as asset import azlmbr.editor as editor import azlmbr.legacy.general as general import azlmbr.bus as bus import azlmbr.math as math - import azlmbr.prefab as prefab import editor_python_test_tools.hydra_editor_utils as hydra - from editor_python_test_tools.prefab_utils import Prefab from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg from editor_python_test_tools.utils import Report from editor_python_test_tools.utils import TestHelper as helper # 1) Open an existing simple level - helper.init_idle() - helper.open_level("", "Base") + hydra.open_base_level() # Set view of planting area for visual debugging general.set_current_view_position(512.0, 500.0, 38.0) @@ -76,9 +72,9 @@ def AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude(): center_point = math.Vector3(512.0, 512.0, 32.0) flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") - flower_prefab = dynveg.create_temp_mesh_prefab(flower_asset_path, "PinkFlower")[0] + flower_prefab = dynveg.create_temp_mesh_prefab(flower_asset_path, "AltFilter_PinkFlower")[0] - spawner_entity = dynveg.create_prefab_vegetation_area("Instance Spawner", center_point, 32.0, 32.0, 32.0, flower_prefab) + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", center_point, 32.0, 32.0, 32.0, flower_prefab) # Add a Vegetation Altitude Filter spawner_entity.add_component("Vegetation Altitude Filter") diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_FilterStageToggle.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_FilterStageToggle.py index 06f6c2a7b4..be2c5e4d8c 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_FilterStageToggle.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_FilterStageToggle.py @@ -32,9 +32,7 @@ def AltitudeFilter_FilterStageToggle(): import os import azlmbr.legacy.general as general - import azlmbr.bus as bus import azlmbr.math as math - import azlmbr.prefab as prefab import editor_python_test_tools.hydra_editor_utils as hydra from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg @@ -45,17 +43,16 @@ def AltitudeFilter_FilterStageToggle(): POSTPROCESS_INSTANCE_COUNT = 34 # Open an existing simple level - helper.init_idle() - helper.open_level("", "Base") + hydra.open_base_level() general.set_current_view_position(512.0, 480.0, 38.0) # Create basic vegetation entity position = math.Vector3(512.0, 512.0, 32.0) flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") - flower_prefab = dynveg.create_temp_mesh_prefab(flower_asset_path, "PinkFlower")[0] + flower_prefab = dynveg.create_temp_mesh_prefab(flower_asset_path, "AltFilter_PinkFlower2")[0] - vegetation = dynveg.create_prefab_vegetation_area("vegetation", position, 16.0, 16.0, 16.0, flower_prefab) + vegetation = dynveg.create_temp_prefab_vegetation_area("vegetation", position, 16.0, 16.0, 16.0, flower_prefab) # Add a Vegetation Altitude Filter to the vegetation area entity vegetation.add_component("Vegetation Altitude Filter") diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude.py index 544a58e242..1e9762d7d8 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude.py @@ -56,8 +56,7 @@ def AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude(): from editor_python_test_tools.utils import TestHelper as helper # 1) Open an existing simple level - helper.init_idle() - helper.open_level("", "Base") + hydra.open_base_level() # Set view of planting area for visual debugging general.set_current_view_position(512.0, 500.0, 38.0) @@ -67,9 +66,9 @@ def AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude(): center_point = math.Vector3(512.0, 512.0, 32.0) flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") - flower_prefab = dynveg.create_temp_mesh_prefab(flower_asset_path, "PinkFlower")[0] + flower_prefab = dynveg.create_temp_mesh_prefab(flower_asset_path, "AltFilter_PinkFlower3")[0] - spawner_entity = dynveg.create_prefab_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 16.0, flower_prefab) + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 16.0, flower_prefab) # Add a Vegetation Altitude Filter spawner_entity.add_component("Vegetation Altitude Filter") diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea.py index a856256929..7242b0b629 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea.py @@ -56,19 +56,21 @@ def AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea(): """ import os + from pathlib import Path import azlmbr.bus as bus import azlmbr.editor as editor import azlmbr.legacy.general as general import azlmbr.math as math import azlmbr.vegetation as vegetation + import azlmbr.prefab as prefab import editor_python_test_tools.hydra_editor_utils as hydra from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg from editor_python_test_tools.utils import Report from editor_python_test_tools.utils import TestHelper as helper - def create_asset_list_entity(name, center, dynamic_slice_asset_path): + def create_asset_list_entity(name, center, target_prefab): asset_list_entity = hydra.Entity(name) asset_list_entity.create_entity( center, @@ -77,18 +79,34 @@ def AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea(): if asset_list_entity.id.IsValid(): print(f"'{asset_list_entity.name}' created") - # Set the Asset List to a Dynamic Slice spawner with a specific slice asset selected - dynamic_slice_spawner = vegetation.DynamicSliceInstanceSpawner() - dynamic_slice_spawner.SetSliceAssetPath(dynamic_slice_asset_path) + if target_prefab: + # Get the in-memory spawnable asset id if exists + spawnable_name = Path(target_prefab.file_path).stem + spawnable_asset_id = prefab.PrefabPublicRequestBus(bus.Broadcast, 'GetInMemorySpawnableAssetId', + spawnable_name) + + # Create the in-memory spawnable asset from given prefab if the spawnable does not exist + if not spawnable_asset_id.is_valid(): + create_spawnable_result = prefab.PrefabPublicRequestBus(bus.Broadcast, 'CreateInMemorySpawnableAsset', + target_prefab.file_path, + spawnable_name) + assert create_spawnable_result.IsSuccess(), \ + f"Prefab operation 'CreateInMemorySpawnableAssets' failed. Error: {create_spawnable_result.GetError()}" + spawnable_asset_id = create_spawnable_result.GetValue() + else: + spawnable_asset_id = None + + # Set the vegetation area to a prefab instance spawner with a specific prefab asset selected descriptor = hydra.get_component_property_value(asset_list_entity.components[0], - "Configuration|Embedded Assets|[0]") - descriptor.spawner = dynamic_slice_spawner + 'Configuration|Embedded Assets|[0]') + prefab_spawner = vegetation.PrefabInstanceSpawner() + prefab_spawner.SetPrefabAssetId(spawnable_asset_id) + descriptor.spawner = prefab_spawner asset_list_entity.get_set_test(0, "Configuration|Embedded Assets|[0]", descriptor) return asset_list_entity # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Set view of planting area for visual debugging general.set_current_view_position(512.0, 500.0, 38.0) @@ -96,11 +114,13 @@ def AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea(): # 2) Create 3 entities with Vegetation Asset List components set to spawn different descriptors center_point = math.Vector3(512.0, 512.0, 32.0) - asset_path = os.path.join("Slices", "PinkFlower.dynamicslice") - asset_path2 = os.path.join("Slices", "PurpleFlower.dynamicslice") - asset_list_entity = create_asset_list_entity("Asset List 1", center_point, asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "AssetList_PinkFlower")[0] + purple_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + purple_flower_prefab = dynveg.create_temp_mesh_prefab(purple_flower_asset_path, "AssetList_PurpleFlower")[0] + asset_list_entity = create_asset_list_entity("Asset List 1", center_point, pink_flower_prefab) asset_list_entity2 = create_asset_list_entity("Asset List 2", center_point, None) - asset_list_entity3 = create_asset_list_entity("Asset List 3", center_point, asset_path2) + asset_list_entity3 = create_asset_list_entity("Asset List 3", center_point, purple_flower_prefab) # 3) Create a planting surface and add a Vegetation System Settings level component with instances set to spawn # on center instead of corner diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AssetWeightSelector_InstancesExpressBasedOnWeight.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AssetWeightSelector_InstancesExpressBasedOnWeight.py index b8b50f8110..8ea0b6b23d 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AssetWeightSelector_InstancesExpressBasedOnWeight.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AssetWeightSelector_InstancesExpressBasedOnWeight.py @@ -56,8 +56,7 @@ def AssetWeightSelector_InstancesExpressBasedOnWeight(): from editor_python_test_tools.utils import TestHelper as helper # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Set view of planting area for visual debugging general.set_current_view_position(512.0, 500.0, 38.0) @@ -66,14 +65,15 @@ def AssetWeightSelector_InstancesExpressBasedOnWeight(): # 2) Create a new instance spawner entity with multiple Dynamic Slice Instance Spawner descriptors, one set to a # valid slice entity, and one set to None spawner_center_point = math.Vector3(512.0, 512.0, 32.0) - asset_path = os.path.join("Slices", "PinkFlower.dynamicslice") - spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 16.0, - asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "AssetWeight_PinkFlower")[0] + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 16.0, + pink_flower_prefab) desc_asset = hydra.get_component_property_value(spawner_entity.components[2], "Configuration|Embedded Assets")[0] desc_list = [desc_asset, desc_asset] spawner_entity.get_set_test(2, "Configuration|Embedded Assets", desc_list) - spawner_entity.get_set_test(2, "Configuration|Embedded Assets|[1]|Instance|Slice Asset", None) + spawner_entity.get_set_test(2, "Configuration|Embedded Assets|[1]|Instance|Prefab Asset", None) # Add an Asset Weight Selector component to the spawner entity spawner_entity.add_component("Vegetation Asset Weight Selector") diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius.py index ed5501d719..be0fe8dba7 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius.py @@ -64,16 +64,15 @@ def DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius(): instance_query_point_c = math.Vector3(515.0, 512.5, 32.0) # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") - + hydra.open_base_level() general.set_current_view_position(512.0, 480.0, 38.0) # 2) Create a new entity with required vegetation area components spawner_center_point = math.Vector3(520.0, 520.0, 32.0) - asset_path = os.path.join("Slices", "1m_cube.dynamicslice") - spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 16.0, - asset_path) + cube_asset_path = os.path.join("testdata", "multi-mat_fbx", "multi-mat_1m_cube.azmodel") + cube_prefab = dynveg.create_temp_mesh_prefab(cube_asset_path, "DistanceBetween_1m_cube2")[0] + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 16.0, + cube_prefab) # 3) Create a surface to plant on surface_center_point = math.Vector3(512.0, 512.0, 32.0) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius.py index c24ec3c314..b2244fdfa7 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius.py @@ -62,16 +62,15 @@ def DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius(): instance_query_point_c = math.Vector3(515.0, 512.5, 32.0) # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") - + hydra.open_base_level() general.set_current_view_position(512.0, 480.0, 38.0) # 2) Create a new entity with required vegetation area components spawner_center_point = math.Vector3(520.0, 520.0, 32.0) - asset_path = os.path.join("Slices", "1m_cube.dynamicslice") - spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 16.0, - asset_path) + cube_asset_path = os.path.join("testdata", "multi-mat_fbx", "multi-mat_1m_cube.azmodel") + cube_prefab = dynveg.create_temp_mesh_prefab(cube_asset_path, "DistanceBetween_1m_cube")[0] + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", spawner_center_point, + 16.0, 16.0, 16.0, cube_prefab) # 3) Create a surface to plant on surface_center_point = math.Vector3(512.0, 512.0, 32.0) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py index d016473d5e..c1ca3cbfc6 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py @@ -39,11 +39,11 @@ def DynVegUtils_TempPrefabCreationWorks(): with Tracer() as error_tracer: # Create dictionary for prefab filenames and paths to create using helper function mesh_prefabs = { - "PinkFlower": os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel"), - "PurpleFlower": os.path.join("assets", "objects", "foliage", "grass_flower_purple.azmodel"), - "1m_Cube": os.path.join("objects", "_primitives", "_box_1x1.azmodel"), - "CedarTree": os.path.join("assets", "objects", "foliage", "cedar.azmodel"), - "Bush": os.path.join("assets", "objects", "foliage", "bush_privet_01.azmodel"), + "UtilsTest_PinkFlower": os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel"), + "UtilsTest_PurpleFlower": os.path.join("assets", "objects", "foliage", "grass_flower_purple.azmodel"), + "UtilsTest_1m_Cube": os.path.join("objects", "_primitives", "_box_1x1.azmodel"), + "UtilsTest_CedarTree": os.path.join("assets", "objects", "foliage", "cedar.azmodel"), + "UtilsTest_Bush": os.path.join("assets", "objects", "foliage", "bush_privet_01.azmodel"), } # 1) Open an existing simple level diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks.py index fcbf85c59d..c8581ad275 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks.py @@ -71,8 +71,7 @@ def DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks(): from editor_python_test_tools.utils import TestHelper as helper # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() general.set_current_view_position(512.0, 480.0, 38.0) # Grab the UUID that we need for creating an Dynamic Slice Instance Spawner diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/EmptyInstanceSpawner_EmptySpawnerWorks.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/EmptyInstanceSpawner_EmptySpawnerWorks.py index d0a51809b4..91315a6971 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/EmptyInstanceSpawner_EmptySpawnerWorks.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/EmptyInstanceSpawner_EmptySpawnerWorks.py @@ -57,8 +57,7 @@ def EmptyInstanceSpawner_EmptySpawnerWorks(): from editor_python_test_tools.utils import TestHelper as helper # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() general.set_current_view_position(512.0, 480.0, 38.0) # Grab the UUID that we need for creating an Empty Spawner diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/InstanceSpawnerPriority_LayerAndSubPriority.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/InstanceSpawnerPriority_LayerAndSubPriority.py index 471c8862fd..f83807a62b 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/InstanceSpawnerPriority_LayerAndSubPriority.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/InstanceSpawnerPriority_LayerAndSubPriority.py @@ -60,8 +60,7 @@ def InstanceSpawnerPriority_LayerAndSubPriority(): from editor_python_test_tools.utils import TestHelper as helper # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Set view of planting area for visual debugging general.set_current_view_position(512.0, 500.0, 38.0) @@ -69,9 +68,10 @@ def InstanceSpawnerPriority_LayerAndSubPriority(): # 2) Create overlapping areas: 1 instance spawner area, and 1 blocker area spawner_center_point = math.Vector3(508.0, 508.0, 32.0) - asset_path = os.path.join("Slices", "PinkFlower.dynamicslice") - spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 1.0, - asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "Priority_PinkFlower")[0] + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 1.0, + pink_flower_prefab) blocker_center_point = math.Vector3(516.0, 516.0, 32.0) blocker_entity = dynveg.create_blocker_area("Instance Blocker", blocker_center_point, 16.0, 16.0, 1.0) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py index 6b5a80ee8e..79f2e4169b 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py @@ -85,18 +85,14 @@ def LayerBlender_E2E_Editor(): # 2) Create 2 vegetation areas with different meshes purple_position = math.Vector3(504.0, 512.0, 32.0) - purple_asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice") - spawner_entity_1 = dynveg.create_dynamic_slice_vegetation_area("Purple Spawner", - purple_position, - 16.0, 16.0, 1.0, - purple_asset_path) + purple_flower_prefab_path = os.path.join("assets", "prefabs", "PurpleFlower.spawnable") + spawner_entity_1 = dynveg.create_prefab_vegetation_area("Purple Spawner", purple_position, 16.0, 16.0, 1.0, + purple_flower_prefab_path) pink_position = math.Vector3(520.0, 512.0, 32.0) - pink_asset_path = os.path.join("Slices", "PinkFlower.dynamicslice") - spawner_entity_2 = dynveg.create_dynamic_slice_vegetation_area("Pink Spawner", - pink_position, - 16.0, 16.0, 1.0, - pink_asset_path) + pink_flower_prefab_path = os.path.join("assets", "prefabs", "PinkFlower.spawnable") + spawner_entity_2 = dynveg.create_prefab_vegetation_area("Pink Spawner", pink_position, 16.0, 16.0, 1.0, + pink_flower_prefab_path) base_position = math.Vector3(512.0, 512.0, 32.0) dynveg.create_surface_entity("Surface Entity", @@ -135,11 +131,11 @@ def LayerBlender_E2E_Editor(): pink_count = 0 purple_count = 0 for instance in instances: - purple_asset_path = purple_asset_path.replace("\\", "/").lower() - pink_asset_path = pink_asset_path.replace("\\", "/").lower() - if instance.descriptor.spawner.GetSliceAssetPath() == pink_asset_path: + purple_flower_prefab_path = purple_flower_prefab_path.replace("\\", "/").lower() + pink_flower_prefab_path = pink_flower_prefab_path.replace("\\", "/").lower() + if instance.descriptor.spawner.GetPrefabAssetPath() == pink_flower_prefab_path: pink_count += 1 - elif instance.descriptor.spawner.GetSliceAssetPath() == purple_asset_path: + elif instance.descriptor.spawner.GetPrefabAssetPath() == purple_flower_prefab_path: purple_count += 1 Report.result(Tests.instances_blended, pink_count == purple_count and (pink_count + purple_count == num_expected)) @@ -152,11 +148,10 @@ def LayerBlender_E2E_Editor(): components.TransformBus(bus.Event, "MoveEntity", search_entity_ids[0], cam_position) azlmbr.components.TransformBus(bus.Event, "SetLocalRotation", search_entity_ids[0], cam_rot_degrees_vector) - # 6) Save and export to engine + # 6) Save the created level general.save_level() - general.export_to_engine() - pak_path = os.path.join(paths.products, "levels", lvl_name, "level.pak") - success = helper.wait_for_condition(lambda: os.path.exists(pak_path), 10.0) + level_prefab_path = os.path.join(paths.products, "levels", lvl_name, f"{lvl_name}.spawnable") + success = helper.wait_for_condition(lambda: os.path.exists(level_prefab_path), 5.0) Report.result(Tests.saved_and_exported, success) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlocker_InstancesBlockedInConfiguredArea.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlocker_InstancesBlockedInConfiguredArea.py index b89edcdeb7..5c3083ee3d 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlocker_InstancesBlockedInConfiguredArea.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlocker_InstancesBlockedInConfiguredArea.py @@ -17,7 +17,6 @@ class Tests: ) - def LayerBlocker_InstancesBlockedInConfiguredArea(): """ Summary: @@ -58,8 +57,7 @@ def LayerBlocker_InstancesBlockedInConfiguredArea(): from editor_python_test_tools.utils import TestHelper as helper # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Set view of planting area for visual debugging general.set_current_view_position(512.0, 500.0, 38.0) @@ -67,9 +65,10 @@ def LayerBlocker_InstancesBlockedInConfiguredArea(): # 2) Create a new instance spawner entity spawner_center_point = math.Vector3(512.0, 512.0, 32.0) - asset_path = os.path.join("Slices", "PinkFlower.dynamicslice") - spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 16.0, - asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "Blocker_PinkFlower")[0] + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", spawner_center_point, + 16.0, 16.0, 16.0, pink_flower_prefab) # 3) Create surface for planting on dynveg.create_surface_entity("Surface Entity", spawner_center_point, 32.0, 32.0, 1.0) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_FilterStageToggle.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_FilterStageToggle.py index 6796f56b11..a277f14a41 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_FilterStageToggle.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_FilterStageToggle.py @@ -42,16 +42,17 @@ def LayerSpawner_FilterStageToggle(): POSTPROCESS_INSTANCE_COUNT = 19 # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() general.set_current_view_position(500.49, 498.69, 46.66) general.set_current_view_rotation(-42.05, 0.00, -36.33) # Create a vegetation area with all needed components position = math.Vector3(512.0, 512.0, 32.0) - asset_path = os.path.join("Slices", "PinkFlower.dynamicslice") - vegetation_entity = dynveg.create_dynamic_slice_vegetation_area("vegetation", position, 16.0, 16.0, 16.0, asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SpawnerFilter_PinkFlower")[0] + vegetation_entity = dynveg.create_temp_prefab_vegetation_area("vegetation", position, 16.0, 16.0, 16.0, + pink_flower_prefab) vegetation_entity.add_component("Vegetation Altitude Filter") vegetation_entity.add_component("Vegetation Position Modifier") diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InheritBehaviorFlag.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InheritBehaviorFlag.py index 1153ae2657..dc06c298d1 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InheritBehaviorFlag.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InheritBehaviorFlag.py @@ -42,19 +42,16 @@ def LayerSpawner_InheritBehaviorFlag(): SURFACE_TAG = "test_tag" - def set_dynamic_slice_asset(entity_obj, component_index, dynamic_slice_asset_path): - dynamic_slice_spawner = vegetation.DynamicSliceInstanceSpawner() - dynamic_slice_spawner.SetSliceAssetPath(dynamic_slice_asset_path) - descriptor = hydra.get_component_property_value( - entity_obj.components[component_index], "Configuration|Embedded Assets|[0]" - ) - descriptor.spawner = dynamic_slice_spawner + def set_prefab_asset(entity_obj, component_index, spawnable_prefab): + descriptor = hydra.get_component_property_value(entity_obj.components[component_index], + "Configuration|Embedded Assets|[0]") + prefab_spawner = vegetation.PrefabInstanceSpawner() + prefab_spawner.SetPrefabAssetId(spawnable_prefab) + descriptor.spawner = prefab_spawner entity_obj.get_set_test(2, "Configuration|Embedded Assets|[0]", descriptor) # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") - + hydra.open_base_level() general.set_current_view_position(512.0, 480.0, 38.0) # Create Emitter entity and add the required components @@ -80,7 +77,9 @@ def LayerSpawner_InheritBehaviorFlag(): veg_1.create_entity( position, ["Vegetation Layer Spawner", "Shape Reference", "Vegetation Asset List"] ) - set_dynamic_slice_asset(veg_1, 2, os.path.join("Slices", "PinkFlower.dynamicslice")) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SpawnerInheritBehavior_PinkFlower")[0] + set_prefab_asset(veg_1, 2, pink_flower_prefab) veg_1.get_set_test(1, "Configuration|Shape Entity Id", blender_entity.id) # Create second vegetation area and assign a valid asset @@ -88,7 +87,9 @@ def LayerSpawner_InheritBehaviorFlag(): veg_2.create_entity( position, ["Vegetation Layer Spawner", "Shape Reference", "Vegetation Asset List"] ) - set_dynamic_slice_asset(veg_2, 2, os.path.join("Slices", "PurpleFlower.dynamicslice")) + purple_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + purple_flower_prefab = dynveg.create_temp_mesh_prefab(purple_flower_asset_path, "temp_PurpleFlower")[0] + set_prefab_asset(veg_2, 2, purple_flower_prefab) veg_2.get_set_test(1, "Configuration|Shape Entity Id", blender_entity.id) # Assign the vegetation areas to the Blender entity diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InstancesPlantInAllSupportedShapes.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InstancesPlantInAllSupportedShapes.py index beec54b4eb..662ac63714 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InstancesPlantInAllSupportedShapes.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InstancesPlantInAllSupportedShapes.py @@ -56,16 +56,14 @@ def LayerSpawner_InstancesPlantInAllSupportedShapes(): Report.result(success, result) # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # 2) Create basic vegetation area entity and set the properties entity_position = math.Vector3(125.0, 136.0, 32.0) - asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice") - vegetation = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", - entity_position, - 10.0, 10.0, 10.0, - asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SpawnerShapePlant_PinkFlower")[0] + vegetation = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_position, 10.0, 10.0, 10.0, + pink_flower_prefab) vegetation.remove_component("Box Shape") vegetation.add_component("Shape Reference") diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InstancesRefreshUsingCorrectViewportCamera.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InstancesRefreshUsingCorrectViewportCamera.py index fe8863c625..deb0376c9b 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InstancesRefreshUsingCorrectViewportCamera.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InstancesRefreshUsingCorrectViewportCamera.py @@ -43,13 +43,13 @@ def LayerSpawner_InstancesRefreshUsingCorrectViewportCamera(): import azlmbr.legacy.general as general import azlmbr.math as math + import editor_python_test_tools.hydra_editor_utils as hydra from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg from editor_python_test_tools.utils import Report from editor_python_test_tools.utils import TestHelper as helper # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Set up a test environment to validate that switching viewports correctly changes which camera # the vegetation system uses. @@ -100,11 +100,12 @@ def LayerSpawner_InstancesRefreshUsingCorrectViewportCamera(): surface_height) # Create the two vegetation areas - test_slice_asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice") - first_veg_entity = dynveg.create_dynamic_slice_vegetation_area("Veg Area 1", first_entity_center_point, box_size, box_size, - box_size, test_slice_asset_path) - second_veg_entity = dynveg.create_dynamic_slice_vegetation_area("Veg Area 2", second_entity_center_point, box_size, box_size, - box_size, test_slice_asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SpawnerViewportRefresh_PinkFlower")[0] + first_veg_entity = dynveg.create_temp_prefab_vegetation_area("Veg Area 1", first_entity_center_point, box_size, box_size, + box_size, pink_flower_prefab) + second_veg_entity = dynveg.create_temp_prefab_vegetation_area("Veg Area 2", second_entity_center_point, box_size, box_size, + box_size, pink_flower_prefab) # When the first viewport is active, the first area should be full of instances, and the second should be empty general.set_active_viewport(0) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMesh.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMesh.py index 9777a52c82..7c365d0ee5 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMesh.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMesh.py @@ -50,19 +50,17 @@ def MeshBlocker_InstancesBlockedByMesh(): from editor_python_test_tools.utils import TestHelper as helper # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() general.set_current_view_position(500.49, 498.69, 46.66) general.set_current_view_rotation(-42.05, 0.00, -36.33) # Create entity with components "Vegetation Layer Spawner", "Vegetation Asset List", "Box Shape" entity_position = math.Vector3(512.0, 512.0, 32.0) - asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice") - spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", - entity_position, - 10.0, 10.0, 10.0, - asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "MeshBlocker_PinkFlower")[0] + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_position, 10.0, 10.0, 10.0, + pink_flower_prefab) # Create surface entity to plant on dynveg.create_surface_entity("Surface Entity", entity_position, 10.0, 10.0, 1.0) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMeshHeightTuning.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMeshHeightTuning.py index 3c47edeb91..a54a8653f0 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMeshHeightTuning.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMeshHeightTuning.py @@ -53,19 +53,17 @@ def MeshBlocker_InstancesBlockedByMeshHeightTuning(): from editor_python_test_tools.utils import TestHelper as helper # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() general.set_current_view_position(500.49, 498.69, 46.66) general.set_current_view_rotation(-42.05, 0.00, -36.33) # 2) Create entity with components "Vegetation Layer Spawner", "Vegetation Asset List", "Box Shape" entity_position = math.Vector3(512.0, 512.0, 32.0) - asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice") - spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", - entity_position, - 10.0, 10.0, 10.0, - asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "MeshBlocker_PinkFlower2")[0] + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_position, 10.0, 10.0, 10.0, + pink_flower_prefab) # 3) Create surface entity to plant on dynveg.create_surface_entity("Surface Entity", entity_position, 10.0, 10.0, 1.0) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshSurfaceTagEmitter_DependentOnMeshComponent.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshSurfaceTagEmitter_DependentOnMeshComponent.py index cee8ebe5b6..9af17b0cd5 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshSurfaceTagEmitter_DependentOnMeshComponent.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshSurfaceTagEmitter_DependentOnMeshComponent.py @@ -58,8 +58,7 @@ def MeshSurfaceTagEmitter_DependentOnMeshComponent(): return editor.EditorComponentAPIBus(bus.Broadcast, "IsComponentEnabled", EntityComponentIdPair) # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # 2) Create a new entity with component "Mesh Surface Tag Emitter" entity_position = math.Vector3(125.0, 136.0, 32.0) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully.py index d7abc66106..cd9963e844 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully.py @@ -47,8 +47,7 @@ def MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully(): from editor_python_test_tools.utils import TestHelper as helper # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # 2) Create a new entity with components "Mesh Surface Tag Emitter", "Mesh" entity_position = math.Vector3(125.0, 136.0, 32.0) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PhysXColliderSurfaceTagEmitter_E2E_Editor.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PhysXColliderSurfaceTagEmitter_E2E_Editor.py index 6232cd374d..cdb2fac80b 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PhysXColliderSurfaceTagEmitter_E2E_Editor.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PhysXColliderSurfaceTagEmitter_E2E_Editor.py @@ -55,8 +55,7 @@ def PhysXColliderSurfaceTagEmitter_E2E_Editor(): return behavior_context_test_success # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Verify all of the BehaviorContext API: behavior_context = ( @@ -90,8 +89,10 @@ def PhysXColliderSurfaceTagEmitter_E2E_Editor(): dynveg.create_surface_entity("Baseline Surface", entity_center_point, 32.0, 32.0, 1.0) # Create a new entity with required vegetation area components - asset_path = os.path.join("Slices", "PinkFlower.dynamicslice") - spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Veg Area", entity_center_point, 32.0, 32.0, 32.0, asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "PhysXCollider_PinkFlower")[0] + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_center_point, test_box_size, + test_box_size, test_box_size, pink_flower_prefab) # Add a Vegetation Surface Mask Filter component to the spawner entity and set it to include the "test" tag spawner_entity.add_component("Vegetation Surface Mask Filter") diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PositionModifier_AutoSnapToSurfaceWorks.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PositionModifier_AutoSnapToSurfaceWorks.py index be7e8ad754..85a1cddb95 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PositionModifier_AutoSnapToSurfaceWorks.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PositionModifier_AutoSnapToSurfaceWorks.py @@ -64,8 +64,7 @@ def PositionModifier_AutoSnapToSurfaceWorks(): 'Configuration|Position Z|Range Min', 'Configuration|Position Z|Range Max'] # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Set view of planting area for visual debugging general.set_current_view_position(512.0, 500.0, 38.0) @@ -73,9 +72,10 @@ def PositionModifier_AutoSnapToSurfaceWorks(): # 2) Create a new entity with required vegetation area components and a Position Modifier spawner_center_point = math.Vector3(512.0, 512.0, 32.0) - asset_path = os.path.join("Slices", "PinkFlower.dynamicslice") - spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 16.0, - asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "PosMod_PinkFlower")[0] + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, + 16.0, pink_flower_prefab) # Add a Vegetation Position Modifier and set offset values to 0 spawner_entity.add_component("Vegetation Position Modifier") diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets.py index 07d4fbd067..6be3dc31f7 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets.py @@ -102,16 +102,17 @@ def PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets(): return offset_success and offset_success2 # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Set view of planting area for visual debugging general.set_current_view_position(16.0, -5.0, 32.0) # 2) Create a new entity with required vegetation area components spawner_center_point = math.Vector3(16.0, 16.0, 32.0) - asset_path = os.path.join("Slices", "PinkFlower.dynamicslice") - spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", spawner_center_point, 1.0, 1.0, 1.0, asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "PosMod_PinkFlower2")[0] + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", spawner_center_point, 1.0, 1.0, + 1.0, pink_flower_prefab) # Add a Vegetation Position Modifier and set offset values to 0 spawner_entity.add_component("Vegetation Position Modifier") diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PrefabInstanceSpawner_Embedded_E2E.py similarity index 87% rename from AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py rename to AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PrefabInstanceSpawner_Embedded_E2E.py index b4650c782e..8ce865b5d2 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PrefabInstanceSpawner_Embedded_E2E.py @@ -63,12 +63,14 @@ def DynamicSliceInstanceSpawner_Embedded_E2E(): import azlmbr.entity as entity import azlmbr.math as math import azlmbr.paths as paths + import azlmbr.vegetation as vegetation import editor_python_test_tools.hydra_editor_utils as hydra from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg from editor_python_test_tools.utils import Report from editor_python_test_tools.utils import TestHelper as helper + # 1) Create a new, temporary level lvl_name = "tmp_level" helper.init_idle() @@ -79,13 +81,14 @@ def DynamicSliceInstanceSpawner_Embedded_E2E(): # 2) Create a new entity with required vegetation area components and Script Canvas component for launcher test center_point = math.Vector3(512.0, 512.0, 32.0) - asset_path = os.path.join("Slices", "PinkFlower.dynamicslice") - spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 1.0, asset_path) + pink_flower_prefab_path = os.path.join("assets", "prefabs", "PinkFlower.spawnable") + spawner_entity = dynveg.create_prefab_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 1.0, + pink_flower_prefab_path) spawner_entity.add_component("Script Canvas") instance_counter_path = os.path.join("scriptcanvas", "instance_counter.scriptcanvas") instance_counter_script = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", instance_counter_path, math.Uuid(), False) - spawner_entity.get_set_test(3, "Script Canvas Asset|Script Canvas Asset", instance_counter_script) + spawner_entity.get_set_test(3, "Properties", instance_counter_script) Report.result(Tests.spawner_entity_created, spawner_entity.id.IsValid() and hydra.has_components(spawner_entity.id, ["Script Canvas"])) @@ -106,11 +109,10 @@ def DynamicSliceInstanceSpawner_Embedded_E2E(): search_entity_ids = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter) components.TransformBus(bus.Event, "MoveEntity", search_entity_ids[0], cam_position) - # 6) Save and export to engine + # 6) Save the created level general.save_level() - general.export_to_engine() - pak_path = os.path.join(paths.products, "levels", lvl_name, "level.pak") - success = helper.wait_for_condition(lambda: os.path.exists(pak_path), 10.0) + level_prefab_path = os.path.join(paths.products, "levels", lvl_name, f"{lvl_name}.spawnable") + success = helper.wait_for_condition(lambda: os.path.exists(level_prefab_path), 5.0) Report.result(Tests.saved_and_exported, success) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PrefabInstanceSpawner_External_E2E.py similarity index 96% rename from AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py rename to AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PrefabInstanceSpawner_External_E2E.py index a5e7e90ce2..a3e60f6337 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PrefabInstanceSpawner_External_E2E.py @@ -128,11 +128,10 @@ def DynamicSliceInstanceSpawner_External_E2E(): search_entity_ids = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter) components.TransformBus(bus.Event, "MoveEntity", search_entity_ids[0], cam_position) - # 6) Save and export to engine + # 6) Save the created level general.save_level() - general.export_to_engine() - pak_path = os.path.join(paths.products, "levels", lvl_name, "level.pak") - success = helper.wait_for_condition(lambda: os.path.exists(pak_path), 10.0) + level_prefab_path = os.path.join(paths.products, "levels", lvl_name, f"{lvl_name}.spawnable") + success = helper.wait_for_condition(lambda: os.path.exists(level_prefab_path), 5.0) Report.result(Tests.saved_and_exported, success) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/RotationModifierOverrides_InstancesRotateWithinRange.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/RotationModifierOverrides_InstancesRotateWithinRange.py index c1ea8e03d1..877a38c231 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/RotationModifierOverrides_InstancesRotateWithinRange.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/RotationModifierOverrides_InstancesRotateWithinRange.py @@ -81,14 +81,15 @@ def RotationModifierOverrides_InstancesRotateWithinRange(): return result # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() general.set_current_view_position(512.0, 480.0, 38.0) # 2) Create vegetation entity and add components entity_position = math.Vector3(512.0, 512.0, 32.0) - asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice") - spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Spawner Entity", entity_position, 16.0, 16.0, 16.0, asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "RotMod_PinkFlower2")[0] + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_position, 16.0, 16.0, 16.0, + pink_flower_prefab) spawner_entity.add_component("Vegetation Rotation Modifier") # Our default vegetation settings places 20 instances per 16 meters, so we expect 20 * 20 total instances. num_expected = 20 * 20 diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/RotationModifier_InstancesRotateWithinRange.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/RotationModifier_InstancesRotateWithinRange.py index 518c11a0cf..b0999f3195 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/RotationModifier_InstancesRotateWithinRange.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/RotationModifier_InstancesRotateWithinRange.py @@ -120,13 +120,14 @@ def RotationModifier_InstancesRotateWithinRange(): # Main Script # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() general.set_current_view_position(512.0, 480.0, 38.0) # 2) Set up vegetation entities - asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice") - spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Spawner Entity", LEVEL_CENTER, 2.0, 2.0, 2.0, asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "RotMod_PinkFlower")[0] + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", LEVEL_CENTER, 2.0, 2.0, 2.0, + pink_flower_prefab) additional_components = [ "Vegetation Rotation Modifier" diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ScaleModifierOverrides_InstancesProperlyScale.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ScaleModifierOverrides_InstancesProperlyScale.py index b2ce6d8afa..42b042e26e 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ScaleModifierOverrides_InstancesProperlyScale.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ScaleModifierOverrides_InstancesProperlyScale.py @@ -91,16 +91,17 @@ def ScaleModifierOverrides_InstancesProperlyScale(): return False # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() general.set_current_view_position(500.49, 498.69, 46.66) general.set_current_view_rotation(-42.05, 0.00, -36.33) # 2) Create a new entity with components "Vegetation Layer Spawner", "Vegetation Asset List", "Box Shape" entity_position = math.Vector3(512.0, 512.0, 32.0) - asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice") - spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Spawner Entity", entity_position, 16.0, 16.0, 10.0, asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "ScaleMod_PinkFlower2")[0] + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_position, 16.0, 16.0, 16.0, + pink_flower_prefab) # Create a surface to plant on and add a Vegetation Debugger Level component to allow refreshes dynveg.create_surface_entity("Surface Entity", entity_position, 20.0, 20.0, 1.0) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ScaleModifier_InstancesProperlyScale.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ScaleModifier_InstancesProperlyScale.py index fd0df1c83d..8008224e3e 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ScaleModifier_InstancesProperlyScale.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ScaleModifier_InstancesProperlyScale.py @@ -84,8 +84,7 @@ def ScaleModifier_InstancesProperlyScale(): return False # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() general.set_current_view_position(500.49, 498.69, 46.66) general.set_current_view_rotation(-42.05, 0.00, -36.33) @@ -93,9 +92,10 @@ def ScaleModifier_InstancesProperlyScale(): # 2) Create a new entity with components Vegetation Layer Spawner, Vegetation Asset List, Box Shape and # Vegetation Scale Modifier entity_position = math.Vector3(512.0, 512.0, 32.0) - asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice") - spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Spawner Entity", entity_position, 16.0, 16.0, 16.0, - asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "ScaleMod_PinkFlower")[0] + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_position, 16.0, 16.0, 16.0, + pink_flower_prefab) spawner_entity.add_component("Vegetation Scale Modifier") # Create a surface to plant on and add a Vegetation Debugger Level component to allow refreshes diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ShapeIntersectionFilter_FilterStageToggle.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ShapeIntersectionFilter_FilterStageToggle.py index 8f179f7f50..5436855433 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ShapeIntersectionFilter_FilterStageToggle.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ShapeIntersectionFilter_FilterStageToggle.py @@ -49,15 +49,16 @@ def ShapeIntersectionFilter_FilterStageToggle(): from editor_python_test_tools.utils import TestHelper as helper # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() general.set_current_view_position(512.0, 480.0, 38.0) # Create basic vegetation entity position = math.Vector3(512.0, 512.0, 32.0) - asset_path = os.path.join("Slices", "PinkFlower.dynamicslice") - vegetation = dynveg.create_dynamic_slice_vegetation_area("vegetation", position, 16.0, 16.0, 16.0, asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "ShapeIntersection_PinkFlower")[0] + vegetation = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", position, 16.0, 16.0, 16.0, + pink_flower_prefab) # Create Surface for instances to plant on dynveg.create_surface_entity("Surface_Entity_Parent", position, 16.0, 16.0, 1.0) @@ -68,7 +69,7 @@ def ShapeIntersectionFilter_FilterStageToggle(): # Create a new entity as a child of the vegetation area entity with Box Shape box = hydra.Entity("box") box.create_entity(position, ["Box Shape"]) - box.get_set_test(0, "Box Shape|Box Configuration|Dimensions", math.Vector3(8.0, 8.0, 1.0)) + box.get_set_test(0, "Box Shape|Box Configuration|Dimensions", math.Vector3(5.0, 5.0, 1.0)) # Create a new entity as a child of the vegetation area entity with Cylinder Shape. cylinder = hydra.Entity("cylinder") @@ -80,10 +81,10 @@ def ShapeIntersectionFilter_FilterStageToggle(): # On the Shape Intersection Filter component, click the crosshair button, and add child entities one by one vegetation.get_set_test(3, "Configuration|Shape Entity Id", box.id) - result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 8.0, 100), 2.0) + result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 49), 2.0) Report.result(Tests.instance_count_in_box_shape, result) vegetation.get_set_test(3, "Configuration|Shape Entity Id", cylinder.id) - result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 100), 2.0) + result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 121), 2.0) Report.result(Tests.instance_count_in_cylinder_shape, result) # Create a new entity as a child of the area entity with Random Noise Gradient, Gradient Transform Modifier, @@ -98,12 +99,13 @@ def ShapeIntersectionFilter_FilterStageToggle(): # Pin the Random Noise entity to the Gradient Entity Id field of the Position Modifier's Gradient X vegetation.get_set_test(4, "Configuration|Position X|Gradient|Gradient Entity Id", random_noise.id) - # Toggle between PreProcess and PostProcess + # Toggle between PreProcess and PostProcess and validate instances. Validate in a 0.3m wider radius due to position + # offsets vegetation.get_set_test(3, "Configuration|Filter Stage", 1) - result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 117), 2.0) + result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.3, 121), 2.0) Report.result(Tests.preprocess_instance_count, result) vegetation.get_set_test(3, "Configuration|Filter Stage", 2) - result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 122), 2.0) + result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.3, 122), 2.0) Report.result(Tests.postprocess_instance_count, result) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ShapeIntersectionFilter_InstancesPlantInAssignedShape.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ShapeIntersectionFilter_InstancesPlantInAssignedShape.py index 6678a620af..e9e4c722f1 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ShapeIntersectionFilter_InstancesPlantInAssignedShape.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ShapeIntersectionFilter_InstancesPlantInAssignedShape.py @@ -60,8 +60,7 @@ def ShapeIntersectionFilter_InstancesPlantInAssignedShape(): from editor_python_test_tools.utils import TestHelper as helper # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Set view of planting area for visual debugging general.set_current_view_position(512.0, 500.0, 38.0) @@ -69,9 +68,10 @@ def ShapeIntersectionFilter_InstancesPlantInAssignedShape(): # 2) Create a new entity with required vegetation area components and Vegetation Shape Intersection Filter center_point = math.Vector3(512.0, 512.0, 32.0) - asset_path = os.path.join("Slices", "PinkFlower.dynamicslice") - spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 1.0, - asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "ShapeIntersection_PinkFlower2")[0] + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 1.0, + pink_flower_prefab) spawner_entity.add_component("Vegetation Shape Intersection Filter") # Create a planting surface diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment.py index c9233d15ea..07dbb3f977 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment.py @@ -58,15 +58,16 @@ def SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment(): return False # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() general.set_current_view_position(512.0, 480.0, 38.0) # Create a spawner entity setup with all needed components center_point = math.Vector3(512.0, 512.0, 32.0) - asset_path = os.path.join("Slices", "PinkFlower.dynamicslice") - spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 32.0, asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SlopeAlign_PinkFlower2")[0] + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 32.0, + pink_flower_prefab) # Create a sloped mesh surface for the instances to plant on center_point = math.Vector3(502.0, 512.0, 24.0) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SlopeAlignmentModifier_InstanceSurfaceAlignment.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SlopeAlignmentModifier_InstanceSurfaceAlignment.py index d92babffa4..088728480b 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SlopeAlignmentModifier_InstanceSurfaceAlignment.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SlopeAlignmentModifier_InstanceSurfaceAlignment.py @@ -59,15 +59,16 @@ def SlopeAlignmentModifier_InstanceSurfaceAlignment(): return False # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() general.set_current_view_position(512.0, 480.0, 38.0) # Create a spawner entity setup with all needed components center_point = math.Vector3(512.0, 512.0, 32.0) - asset_path = os.path.join("Slices", "PinkFlower.dynamicslice") - spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 32.0, asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SlopeAlign_PinkFlower")[0] + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 32.0, + pink_flower_prefab) # Create a sloped mesh surface for the instances to plant on center_point = math.Vector3(502.0, 512.0, 24.0) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlope.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlope.py index 0f95853156..cc04dc4cb1 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlope.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlope.py @@ -63,16 +63,17 @@ def SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlopes(): from editor_python_test_tools.utils import TestHelper as helper # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Set view of planting area for visual debugging general.set_current_view_position(512.0, 475.0, 38.0) # 2) Create a new entity with required vegetation area components center_point = math.Vector3(512.0, 512.0, 32.0) - asset_path = os.path.join("Slices", "PinkFlower.dynamicslice") - spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", center_point, 32.0, 32.0, 32.0, asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "Slope_PinkFlower")[0] + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", center_point, 32.0, 32.0, 32.0, + pink_flower_prefab) # Add a Vegetation Slope Filter spawner_entity.add_component("Vegetation Slope Filter") diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SpawnerSlices_SliceCreationAndVisibilityToggleWorks.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SpawnerPrefabs_PrefabCreationAndVisibilityToggleWorks.py similarity index 52% rename from AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SpawnerSlices_SliceCreationAndVisibilityToggleWorks.py rename to AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SpawnerPrefabs_PrefabCreationAndVisibilityToggleWorks.py index fc55080cec..182bd5510a 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SpawnerSlices_SliceCreationAndVisibilityToggleWorks.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SpawnerPrefabs_PrefabCreationAndVisibilityToggleWorks.py @@ -7,21 +7,21 @@ SPDX-License-Identifier: Apache-2.0 OR MIT class Tests: - spawner_slice_created = ( - "Spawner slice created successfully", - "Failed to create Spawner slice" + spawner_prefab_created = ( + "Spawner prefab created successfully", + "Failed to create Spawner prefab" ) instance_count_unhidden = ( "Initial instance counts are as expected", "Found an unexpected number of initial instances" ) instance_count_hidden = ( - "Instance counts upon hiding the Spawner slice are as expected", - "Unexpectedly found instances with the Spawner slice hidden" + "Instance counts upon hiding the Spawner prefab are as expected", + "Unexpectedly found instances with the Spawner prefab hidden" ) - blender_slice_created = ( - "Blender slice created successfully", - "Failed to create Blender slice" + blender_prefab_created = ( + "Blender prefab created successfully", + "Failed to create Blender prefab" ) @@ -43,81 +43,76 @@ def SpawnerSlices_SliceCreationAndVisibilityToggleWorks(): import azlmbr.math as math import azlmbr.legacy.general as general - import azlmbr.slice as slice import azlmbr.bus as bus import azlmbr.editor as editor - import azlmbr.asset as asset import editor_python_test_tools.hydra_editor_utils as hydra from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg + from editor_python_test_tools.editor_entity_utils import EditorEntity from editor_python_test_tools.utils import Report from editor_python_test_tools.utils import TestHelper as helper - - def path_is_valid_asset(asset_path): - asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", asset_path, math.Uuid(), False) - return asset_id.invoke("IsValid") + from editor_python_test_tools.prefab_utils import Prefab # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() general.set_current_view_position(512.0, 480.0, 38.0) - # 2) C2627900 Verifies if a slice containing the Vegetation Layer Spawner component can be created. + # 2) Verifies if a prefab containing the Vegetation Layer Spawner component can be created. # 2.1) Create basic vegetation entity position = math.Vector3(512.0, 512.0, 32.0) - asset_path = os.path.join("Slices", "PinkFlower.dynamicslice") - veg_1 = dynveg.create_dynamic_slice_vegetation_area("vegetation_1", position, 16.0, 16.0, 16.0, asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SpawnerPrefab_PinkFlower")[0] + veg_1 = dynveg.create_temp_prefab_vegetation_area("vegetation_1", position, 16.0, 16.0, 16.0, + pink_flower_prefab) - # 2.2) Create slice from the entity - slice_path = os.path.join("slices", "TestSlice_1.slice") - slice.SliceRequestBus(bus.Broadcast, "CreateNewSlice", veg_1.id, slice_path) + # 2.2) Create prefab from the entity + spawner_prefab_filename = "TestPrefab_1" + spawner_prefab, spawner_prefab_instance = Prefab.create_prefab([veg_1], spawner_prefab_filename) - # 2.3) Verify if the slice has been created successfully - spawner_slice_success = helper.wait_for_condition(lambda: path_is_valid_asset(slice_path), 10.0) - Report.result(Tests.spawner_slice_created, spawner_slice_success) + # Verify if prefab is created + Report.result(Tests.spawner_prefab_created, spawner_prefab.is_prefab_loaded(spawner_prefab_filename)) - # 3) C2627904: Hiding a slice containing the component clears any visuals from the Viewport + # 3) Hiding a prefab containing the component clears any visuals from the Viewport # 3.1) Create Surface for instances to plant on dynveg.create_surface_entity("Surface_Entity", position, 16.0, 16.0, 1.0) - # 3.2) Initially verify instance count before hiding slice + # 3.2) Initially verify instance count before hiding prefab initial_count_success = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 16.0, 400), 5.0) Report.result(Tests.instance_count_unhidden, initial_count_success) - # 3.3) Hide the slice and verify instance count - editor.EditorEntityAPIBus(bus.Event, "SetVisibilityState", veg_1.id, False) + # 3.3) Hide the prefab and verify instance count + editor.EditorEntityAPIBus(bus.Event, "SetVisibilityState", spawner_prefab_instance.container_entity.id, False) hidden_instance_count = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 16.0, 0), 5.0) Report.result(Tests.instance_count_hidden, hidden_instance_count) # 3.4) Unhide the slice - editor.EditorEntityAPIBus(bus.Event, "SetVisibilityState", veg_1.id, True) + editor.EditorEntityAPIBus(bus.Event, "SetVisibilityState", spawner_prefab_instance.container_entity.id, True) - # 4) C2627905 A slice containing the Vegetation Layer Blender component can be created. + # 4) A slice containing the Vegetation Layer Blender component can be created. # 4.1) Create another vegetation entity to add to blender component - veg_2 = dynveg.create_dynamic_slice_vegetation_area("vegetation_2", position, 1.0, 1.0, 1.0, "") + veg_2 = dynveg.create_empty_vegetation_area("vegetation_2", position, 1.0, 1.0, 1.0) # 4.2) Create entity with Vegetation Layer Blender components_to_add = ["Box Shape", "Vegetation Layer Blender"] - blender_entity = hydra.Entity("blender_entity") - blender_entity.create_entity(position, components_to_add) + blender_entity = EditorEntity.create_editor_entity("blender_entity") + blender_entity.add_components(components_to_add) # 4.3) Pin both the vegetation areas to the blender entity - pte = hydra.get_property_tree(blender_entity.components[1]) + pte = blender_entity.components[1].get_property_tree() path = "Configuration|Vegetation Areas" pte.update_container_item(path, 0, veg_1.id) pte.add_container_item(path, 1, veg_2.id) # 4.4) Drag the simple vegetation areas under the Vegetation Layer Blender entity to create an entity hierarchy. veg_1.set_test_parent_entity(blender_entity) - veg_2.set_test_parent_entity(blender_entity) + veg_2.set_parent_entity(blender_entity.id) - # 4.5) Create slice from blender entity - slice_path = os.path.join("slices", "TestSlice_2.slice") - slice.SliceRequestBus(bus.Broadcast, "CreateNewSlice", blender_entity.id, slice_path) + # 4.5) Create prefab from blender entity + blender_prefab_filename = "TestPrefab_2" + blender_prefab, blender_prefab_instance = Prefab.create_prefab([veg_2], blender_prefab_filename) - # 4.6) Verify if the slice has been created successfully - blender_slice_success = helper.wait_for_condition(lambda: path_is_valid_asset(slice_path), 5.0) - Report.result(Tests.blender_slice_created, blender_slice_success) + # 4.6) Verify if the prefab has been created successfully + Report.result(Tests.blender_prefab_created, blender_prefab.is_prefab_loaded(blender_prefab_filename)) if __name__ == "__main__": diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceDataRefreshes_RemainsStable.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceDataRefreshes_RemainsStable.py index 1ad4f305c3..3612e03bcc 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceDataRefreshes_RemainsStable.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceDataRefreshes_RemainsStable.py @@ -34,13 +34,12 @@ def SurfaceDataRefreshes_RemainsStable(): import azlmbr.legacy.general as general import azlmbr.math as math + import editor_python_test_tools.hydra_editor_utils as hydra from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg from editor_python_test_tools.utils import Report - from editor_python_test_tools.utils import TestHelper as helper # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() world_center = math.Vector3(512.0, 512.0, 32.0) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected.py index 3e76a03c53..b98b0f0546 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected.py @@ -67,8 +67,7 @@ def SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected(): surface_data.SurfaceTag("test_tag3")] # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Set view of planting area for visual debugging general.set_current_view_position(512.0, 500.0, 38.0) @@ -76,9 +75,10 @@ def SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected(): # 2) Create a new instance spawner entity with multiple Dynamic Slice Instance Spawner descriptors spawner_center_point = math.Vector3(512.0, 512.0, 32.0) - asset_path = os.path.join("Slices", "PinkFlower.dynamicslice") - spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 16.0, - asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SurfaceMaskOverrides_PinkFlower")[0] + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, + 16.0, pink_flower_prefab) asset_list_component = spawner_entity.components[2] desc_asset = hydra.get_component_property_value(asset_list_component, "Configuration|Embedded Assets")[0] diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilter_BasicSurfaceTagCreation.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilter_BasicSurfaceTagCreation.py index fee62c04d1..fe17b03c6f 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilter_BasicSurfaceTagCreation.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilter_BasicSurfaceTagCreation.py @@ -39,12 +39,12 @@ def SurfaceMaskFilter_BasicSurfaceTagCreation(): """ import azlmbr.surface_data as surface_data + + import editor_python_test_tools.hydra_editor_utils as hydra from editor_python_test_tools.utils import Report - from editor_python_test_tools.utils import TestHelper as helper # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() tag1 = surface_data.SurfaceTag() tag2 = surface_data.SurfaceTag() diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilter_ExclusionList.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilter_ExclusionList.py index 3f298e793e..f5174af3bb 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilter_ExclusionList.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilter_ExclusionList.py @@ -91,18 +91,16 @@ def SurfaceMaskFilter_ExclusionList(): Report.info(f"Failed to add Generated surface tag of {surface_tag}") # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() general.set_current_view_position(512.0, 480.0, 38.0) # 2) Create entity with components "Vegetation Layer Spawner", "Vegetation Asset List", "Box Shape" entity_position = math.Vector3(512.0, 512.0, 32.0) - asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice") - spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", - entity_position, - 10.0, 10.0, 10.0, - asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SurfaceMaskTagExclusion_PinkFlower")[0] + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_position, 10.0, 10.0, 10.0, + pink_flower_prefab) # 3) Add a Vegetation Surface Mask Filter component to the entity. spawner_entity.add_component("Vegetation Surface Mask Filter") diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilter_InclusionList.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilter_InclusionList.py index 39b72ff4a9..34d22d3d9b 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilter_InclusionList.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilter_InclusionList.py @@ -92,18 +92,16 @@ def SurfaceMaskFilter_InclusionList(): Report.info(f"Failed to add Generated surface tag of {surface_tag}") # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() general.set_current_view_position(512.0, 480.0, 38.0) # 2) Create entity with components "Vegetation Layer Spawner", "Vegetation Asset List", "Box Shape" entity_position = math.Vector3(512.0, 512.0, 32.0) - asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice") - spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", - entity_position, - 10.0, 10.0, 10.0, - asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SurfaceMaskTagInclusion_PinkFlower")[0] + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_position, 10.0, 10.0, 10.0, + pink_flower_prefab) # 3) Add a Vegetation Surface Mask Filter component to the entity. spawner_entity.add_component("Vegetation Surface Mask Filter") diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SystemSettings_SectorPointDensity.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SystemSettings_SectorPointDensity.py index 167fb8901c..7516bfb31d 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SystemSettings_SectorPointDensity.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SystemSettings_SectorPointDensity.py @@ -47,15 +47,16 @@ def SystemSettings_SectorPointDensity(): INSTANCE_COUNT_AFTER_DENSITY_CHANGE = 100 # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() general.set_current_view_position(512.0, 480.0, 38.0) # Create basic vegetation entity position = math.Vector3(512.0, 512.0, 32.0) - asset_path = os.path.join("Slices", "PinkFlower.dynamicslice") - dynveg.create_dynamic_slice_vegetation_area("vegetation", position, 16.0, 16.0, 1.0, asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SectorPoint_PinkFlower")[0] + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", position, 16.0, 16.0, 1.0, + pink_flower_prefab) dynveg.create_surface_entity("Surface_Entity", position, 16.0, 16.0, 1.0) # Count the number of vegetation instances in the vegetation area diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SystemSettings_SectorSize.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SystemSettings_SectorSize.py index 7bb78ac3e0..ef7959a3e7 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SystemSettings_SectorSize.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SystemSettings_SectorSize.py @@ -43,15 +43,16 @@ def SystemSettings_SectorSize(): VEGETATION_INSTANCE_COUNT = 400 # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() general.set_current_view_position(512.0, 480.0, 38.0) # Create basic vegetation entity position = math.Vector3(512.0, 512.0, 32.0) - asset_path = os.path.join("Slices", "PinkFlower.dynamicslice") - vegetation = dynveg.create_dynamic_slice_vegetation_area("vegetation", position, 16.0, 16.0, 1.0, asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SectorSize_PinkFlower")[0] + vegetation = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", position, 16.0, 16.0, 1.0, + pink_flower_prefab) dynveg.create_surface_entity("Surface_Entity", position, 16.0, 16.0, 1.0) # Add the Vegetation Debugger component to the Level Inspector diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/VegetationInstances_DespawnWhenOutOfRange.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/VegetationInstances_DespawnWhenOutOfRange.py index 8a6c4d9a17..b6069d1ef5 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/VegetationInstances_DespawnWhenOutOfRange.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/VegetationInstances_DespawnWhenOutOfRange.py @@ -43,18 +43,20 @@ def VegetationInstances_DespawnWhenOutOfRange(): import azlmbr.legacy.general as general import azlmbr.math as math + import editor_python_test_tools.hydra_editor_utils as hydra from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg from editor_python_test_tools.utils import Report from editor_python_test_tools.utils import TestHelper as helper # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Create vegetation layer spawner world_center = math.Vector3(512.0, 512.0, 32.0) - asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice") - spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Spawner Instance", world_center, 16.0, 16.0, 16.0, asset_path) + pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel") + pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "RangeDespawn_PinkFlower")[0] + spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", world_center, 16.0, 16.0, 16.0, + pink_flower_prefab) # Create a surface to spawn on dynveg.create_surface_entity("Spawner Entity", world_center, 16.0, 16.0, 1.0) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main.py index 06c9c5f615..d508e390cb 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main.py @@ -7,21 +7,171 @@ SPDX-License-Identifier: Apache-2.0 OR MIT import os import pytest -import sys -sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../automatedtesting_shared') -from base import TestAutomationBase +import ly_test_tools.environment.file_system as file_system +from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite @pytest.mark.SUITE_main @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("project", ["AutomatedTesting"]) -class TestAutomation(TestAutomationBase): +class TestAutomation(EditorTestSuite): - def test_DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks(self, request, workspace, editor, launcher_platform): + # Helpers for test asset cleanup + def cleanup_test_level(self, workspace): + file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")], + True, True) + + class test_AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude(EditorSharedTest): + from .EditorScripts import AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude as test_module + + class test_AltitudeFilter_FilterStageToggle(EditorSharedTest): + from .EditorScripts import AltitudeFilter_FilterStageToggle as test_module + + class test_AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude(EditorSharedTest): + from .EditorScripts import AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude as test_module + + class test_AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea(EditorSharedTest): + from .EditorScripts import AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea as test_module + + class test_AssetWeightSelector_InstancesExpressBasedOnWeight(EditorSharedTest): + from .EditorScripts import AssetWeightSelector_InstancesExpressBasedOnWeight as test_module + + @pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/4155") + class test_DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius(EditorSharedTest): + from .EditorScripts import DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius as test_module + + @pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/4155") + class test_DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius(EditorSharedTest): + from .EditorScripts import DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius as test_module + + class test_DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks(EditorSharedTest): from .EditorScripts import DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - def test_EmptyInstanceSpawner_EmptySpawnerWorks(self, request, workspace, editor, launcher_platform): + class test_EmptyInstanceSpawner_EmptySpawnerWorks(EditorSharedTest): from .EditorScripts import EmptyInstanceSpawner_EmptySpawnerWorks as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) + + class test_InstanceSpawnerPriority_LayerAndSubPriority_HigherValuesPlantOverLower(EditorSharedTest): + from .EditorScripts import InstanceSpawnerPriority_LayerAndSubPriority as test_module + + class test_LayerBlender_E2E_Editor(EditorSingleTest): + from .EditorScripts import LayerBlender_E2E_Editor as test_module + + # Custom setup/teardown to remove test level created during test + def setup(self, request, workspace, editor, editor_test_results, launcher_platform): + TestAutomation.cleanup_test_level(self, workspace) + + def teardown(self, request, workspace, editor, editor_test_results, launcher_platform): + TestAutomation.cleanup_test_level(self, workspace) + + class test_LayerBlocker_InstancesBlockedInConfiguredArea(EditorSharedTest): + from .EditorScripts import LayerBlocker_InstancesBlockedInConfiguredArea as test_module + + class test_LayerSpawner_FilterStageToggle(EditorSharedTest): + from .EditorScripts import LayerSpawner_FilterStageToggle as test_module + + class test_LayerSpawner_InheritBehaviorFlag(EditorSharedTest): + from .EditorScripts import LayerSpawner_InheritBehaviorFlag as test_module + + class test_LayerSpawner_InstancesPlantInAllSupportedShapes(EditorSharedTest): + from .EditorScripts import LayerSpawner_InstancesPlantInAllSupportedShapes as test_module + + @pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/6549") + class test_LayerSpawner_InstancesRefreshUsingCorrectViewportCamera(EditorSharedTest): + from .EditorScripts import LayerSpawner_InstancesRefreshUsingCorrectViewportCamera as test_module + + class test_MeshBlocker_InstancesBlockedByMesh(EditorSharedTest): + from .EditorScripts import MeshBlocker_InstancesBlockedByMesh as test_module + + class test_MeshBlocker_InstancesBlockedByMeshHeightTuning(EditorSharedTest): + from .EditorScripts import MeshBlocker_InstancesBlockedByMeshHeightTuning as test_module + + class test_MeshSurfaceTagEmitter_DependentOnMeshComponent(EditorSharedTest): + from .EditorScripts import MeshSurfaceTagEmitter_DependentOnMeshComponent as test_module + + class test_MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully(EditorSharedTest): + from .EditorScripts import MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully as test_module + + class test_PhysXColliderSurfaceTagEmitter_E2E_Editor(EditorSharedTest): + from .EditorScripts import PhysXColliderSurfaceTagEmitter_E2E_Editor as test_module + + class test_PositionModifier_AutoSnapToSurfaceWorks(EditorSharedTest): + from .EditorScripts import PositionModifier_AutoSnapToSurfaceWorks as test_module + + class test_PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets(EditorSharedTest): + from .EditorScripts import \ + PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets as test_module + + class test_PrefabInstanceSpawner_Embedded_E2E_Editor(EditorSingleTest): + from .EditorScripts import PrefabInstanceSpawner_Embedded_E2E as test_module + + # Custom setup/teardown to remove test level created during test + def setup(self, request, workspace, editor, editor_test_results, launcher_platform): + TestAutomation.cleanup_test_level(self, workspace) + + def teardown(self, request, workspace, editor, editor_test_results, launcher_platform): + TestAutomation.cleanup_test_level(self, workspace) + + class test_PrefabInstanceSpawner_External_E2E_Editor(EditorSingleTest): + from .EditorScripts import PrefabInstanceSpawner_External_E2E as test_module + + # Custom setup/teardown to remove test level created during test + def setup(self, request, workspace, editor, editor_test_results, launcher_platform): + TestAutomation.cleanup_test_level(self, workspace) + + def teardown(self, request, workspace, editor, editor_test_results, launcher_platform): + TestAutomation.cleanup_test_level(self, workspace) + + class test_RotationModifier_InstancesRotateWithinRange(EditorSharedTest): + from .EditorScripts import RotationModifier_InstancesRotateWithinRange as test_module + + class test_RotationModifierOverrides_InstancesRotateWithinRange(EditorSharedTest): + from .EditorScripts import RotationModifierOverrides_InstancesRotateWithinRange as test_module + + class test_ScaleModifier_InstancesProperlyScale(EditorSharedTest): + from .EditorScripts import ScaleModifier_InstancesProperlyScale as test_module + + class test_ScaleModifierOverrides_InstancesProperlyScale(EditorSharedTest): + from .EditorScripts import ScaleModifierOverrides_InstancesProperlyScale as test_module + + class test_ShapeIntersectionFilter_FilterStageToggle(EditorSharedTest): + from .EditorScripts import ShapeIntersectionFilter_FilterStageToggle as test_module + + class test_ShapeIntersectionFilter_InstancesPlantInAssignedShape(EditorSharedTest): + from .EditorScripts import ShapeIntersectionFilter_InstancesPlantInAssignedShape as test_module + + class test_SlopeAlignmentModifier_InstanceSurfaceAlignment(EditorSharedTest): + from .EditorScripts import SlopeAlignmentModifier_InstanceSurfaceAlignment as test_module + + class test_SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment(EditorSharedTest): + from .EditorScripts import SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment as test_module + + class test_SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlopes(EditorSharedTest): + from .EditorScripts import SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlope as test_module + + class test_SpawnerPrefabs_PrefabCreationAndVisibilityToggleWorks(EditorSharedTest): + from .EditorScripts import SpawnerPrefabs_PrefabCreationAndVisibilityToggleWorks as test_module + + class test_SurfaceDataRefreshes_RemainsStable(EditorSharedTest): + from .EditorScripts import SurfaceDataRefreshes_RemainsStable as test_module + + class test_SurfaceMaskFilter_BasicSurfaceTagCreation(EditorSharedTest): + from .EditorScripts import SurfaceMaskFilter_BasicSurfaceTagCreation as test_module + + class test_SurfaceMaskFilter_ExclusiveSurfaceTags_Function(EditorSharedTest): + from .EditorScripts import SurfaceMaskFilter_ExclusionList as test_module + + class test_SurfaceMaskFilter_InclusiveSurfaceTags_Function(EditorSharedTest): + from .EditorScripts import SurfaceMaskFilter_InclusionList as test_module + + class test_SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected(EditorSharedTest): + from .EditorScripts import SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected as test_module + + class test_SystemSettings_SectorPointDensity(EditorSharedTest): + from .EditorScripts import SystemSettings_SectorPointDensity as test_module + + class test_SystemSettings_SectorSize(EditorSharedTest): + from .EditorScripts import SystemSettings_SectorSize as test_module + + class test_VegetationInstances_DespawnWhenOutOfRange(EditorSharedTest): + from .EditorScripts import VegetationInstances_DespawnWhenOutOfRange as test_module diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py deleted file mode 100644 index 5b1e504442..0000000000 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py +++ /dev/null @@ -1,192 +0,0 @@ -""" -Copyright (c) Contributors to the Open 3D Engine Project. -For complete copyright and license terms please see the LICENSE at the root of this distribution. - -SPDX-License-Identifier: Apache-2.0 OR MIT -""" - -import os -import pytest - -import ly_test_tools.environment.file_system as file_system -from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite - - -@pytest.mark.SUITE_main -@pytest.mark.parametrize("launcher_platform", ['windows_editor']) -@pytest.mark.parametrize("project", ["AutomatedTesting"]) -class TestAutomation(EditorTestSuite): - class test_AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude(EditorParallelTest): - from .EditorScripts import AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude as test_module - - class test_AltitudeFilter_FilterStageToggle(EditorParallelTest): - from .EditorScripts import AltitudeFilter_FilterStageToggle as test_module - - class test_AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude(EditorParallelTest): - from .EditorScripts import AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude as test_module - - -@pytest.mark.SUITE_main -@pytest.mark.parametrize("launcher_platform", ['windows_editor']) -@pytest.mark.parametrize("project", ["AutomatedTesting"]) -class TestAutomation_PrefabNotEnabled(EditorTestSuite): - - enable_prefab_system = False - - # Helpers for test asset cleanup - def cleanup_test_level(self, workspace): - file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")], - True, True) - - def cleanup_test_slices(self, workspace): - file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "slices", - "TestSlice_1.slice")], True, True) - file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "slices", - "TestSlice_2.slice")], True, True) - - class test_DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks(EditorParallelTest): - from .EditorScripts import DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks as test_module - - class test_EmptyInstanceSpawner_EmptySpawnerWorks(EditorParallelTest): - from .EditorScripts import EmptyInstanceSpawner_EmptySpawnerWorks as test_module - - class test_SpawnerSlices_SliceCreationAndVisibilityToggleWorks(EditorSingleTest): - # Custom teardown to remove slice asset created during test - def teardown(self, request, workspace, editor, editor_test_results, launcher_platform): - TestAutomation_PrefabNotEnabled.cleanup_test_slices(self, workspace) - from .EditorScripts import SpawnerSlices_SliceCreationAndVisibilityToggleWorks as test_module - - class test_AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea(EditorParallelTest): - from .EditorScripts import AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea as test_module - - class test_AssetWeightSelector_InstancesExpressBasedOnWeight(EditorParallelTest): - from .EditorScripts import AssetWeightSelector_InstancesExpressBasedOnWeight as test_module - - @pytest.mark.skip(reason="https://github.com/o3de/o3de/issues/4155") - class test_DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius(EditorParallelTest): - from .EditorScripts import DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius as test_module - - @pytest.mark.skip(reason="https://github.com/o3de/o3de/issues/4155") - class test_DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius(EditorParallelTest): - from .EditorScripts import DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius as test_module - - class test_SurfaceDataRefreshes_RemainsStable(EditorParallelTest): - from .EditorScripts import SurfaceDataRefreshes_RemainsStable as test_module - - class test_VegetationInstances_DespawnWhenOutOfRange(EditorParallelTest): - from .EditorScripts import VegetationInstances_DespawnWhenOutOfRange as test_module - - class test_InstanceSpawnerPriority_LayerAndSubPriority_HigherValuesPlantOverLower(EditorParallelTest): - from .EditorScripts import InstanceSpawnerPriority_LayerAndSubPriority as test_module - - class test_LayerBlocker_InstancesBlockedInConfiguredArea(EditorParallelTest): - from .EditorScripts import LayerBlocker_InstancesBlockedInConfiguredArea as test_module - - class test_LayerSpawner_InheritBehaviorFlag(EditorParallelTest): - from .EditorScripts import LayerSpawner_InheritBehaviorFlag as test_module - - class test_LayerSpawner_InstancesPlantInAllSupportedShapes(EditorParallelTest): - from .EditorScripts import LayerSpawner_InstancesPlantInAllSupportedShapes as test_module - - class test_LayerSpawner_FilterStageToggle(EditorParallelTest): - from .EditorScripts import LayerSpawner_FilterStageToggle as test_module - - @pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/2038") - class test_LayerSpawner_InstancesRefreshUsingCorrectViewportCamera(EditorParallelTest): - from .EditorScripts import LayerSpawner_InstancesRefreshUsingCorrectViewportCamera as test_module - - class test_MeshBlocker_InstancesBlockedByMesh(EditorParallelTest): - from .EditorScripts import MeshBlocker_InstancesBlockedByMesh as test_module - - class test_MeshBlocker_InstancesBlockedByMeshHeightTuning(EditorParallelTest): - from .EditorScripts import MeshBlocker_InstancesBlockedByMeshHeightTuning as test_module - - class test_MeshSurfaceTagEmitter_DependentOnMeshComponent(EditorParallelTest): - from .EditorScripts import MeshSurfaceTagEmitter_DependentOnMeshComponent as test_module - - class test_MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully(EditorParallelTest): - from .EditorScripts import MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully as test_module - - class test_PhysXColliderSurfaceTagEmitter_E2E_Editor(EditorParallelTest): - from .EditorScripts import PhysXColliderSurfaceTagEmitter_E2E_Editor as test_module - - class test_PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets(EditorParallelTest): - from .EditorScripts import PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets as test_module - - class test_PositionModifier_AutoSnapToSurfaceWorks(EditorParallelTest): - from .EditorScripts import PositionModifier_AutoSnapToSurfaceWorks as test_module - - class test_RotationModifier_InstancesRotateWithinRange(EditorParallelTest): - from .EditorScripts import RotationModifier_InstancesRotateWithinRange as test_module - - class test_RotationModifierOverrides_InstancesRotateWithinRange(EditorParallelTest): - from .EditorScripts import RotationModifierOverrides_InstancesRotateWithinRange as test_module - - class test_ScaleModifier_InstancesProperlyScale(EditorParallelTest): - from .EditorScripts import ScaleModifier_InstancesProperlyScale as test_module - - class test_ScaleModifierOverrides_InstancesProperlyScale(EditorParallelTest): - from .EditorScripts import ScaleModifierOverrides_InstancesProperlyScale as test_module - - class test_ShapeIntersectionFilter_InstancesPlantInAssignedShape(EditorParallelTest): - from .EditorScripts import ShapeIntersectionFilter_InstancesPlantInAssignedShape as test_module - - class test_ShapeIntersectionFilter_FilterStageToggle(EditorParallelTest): - from .EditorScripts import ShapeIntersectionFilter_FilterStageToggle as test_module - - class test_SlopeAlignmentModifier_InstanceSurfaceAlignment(EditorParallelTest): - from .EditorScripts import SlopeAlignmentModifier_InstanceSurfaceAlignment as test_module - - class test_SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment(EditorParallelTest): - from .EditorScripts import SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment as test_module - - class test_SurfaceMaskFilter_BasicSurfaceTagCreation(EditorParallelTest): - from .EditorScripts import SurfaceMaskFilter_BasicSurfaceTagCreation as test_module - - class test_SurfaceMaskFilter_ExclusiveSurfaceTags_Function(EditorParallelTest): - from .EditorScripts import SurfaceMaskFilter_ExclusionList as test_module - - class test_SurfaceMaskFilter_InclusiveSurfaceTags_Function(EditorParallelTest): - from .EditorScripts import SurfaceMaskFilter_InclusionList as test_module - - class test_SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected(EditorParallelTest): - from .EditorScripts import SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected as test_module - - class test_SystemSettings_SectorPointDensity(EditorParallelTest): - from .EditorScripts import SystemSettings_SectorPointDensity as test_module - - class test_SystemSettings_SectorSize(EditorParallelTest): - from .EditorScripts import SystemSettings_SectorSize as test_module - - class test_SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlopes(EditorParallelTest): - from .EditorScripts import SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlope as test_module - - class test_DynamicSliceInstanceSpawner_Embedded_E2E_Editor(EditorSingleTest): - from .EditorScripts import DynamicSliceInstanceSpawner_Embedded_E2E as test_module - - # Custom setup/teardown to remove test level created during test - def setup(self, request, workspace, editor, editor_test_results, launcher_platform): - TestAutomation_PrefabNotEnabled.cleanup_test_level(self, workspace) - - def teardown(self, request, workspace, editor, editor_test_results, launcher_platform): - TestAutomation_PrefabNotEnabled.cleanup_test_level(self, workspace) - - class test_DynamicSliceInstanceSpawner_External_E2E_Editor(EditorSingleTest): - from .EditorScripts import DynamicSliceInstanceSpawner_External_E2E as test_module - - # Custom setup/teardown to remove test level created during test - def setup(self, request, workspace, editor, editor_test_results, launcher_platform): - TestAutomation_PrefabNotEnabled.cleanup_test_level(self, workspace) - - def teardown(self, request, workspace, editor, editor_test_results, launcher_platform): - TestAutomation_PrefabNotEnabled.cleanup_test_level(self, workspace) - - class test_LayerBlender_E2E_Editor(EditorSingleTest): - from .EditorScripts import LayerBlender_E2E_Editor as test_module - - # Custom setup/teardown to remove test level created during test - def setup(self, request, workspace, editor, editor_test_results, launcher_platform): - TestAutomation_PrefabNotEnabled.cleanup_test_level(self, workspace) - - def teardown(self, request, workspace, editor, editor_test_results, launcher_platform): - TestAutomation_PrefabNotEnabled.cleanup_test_level(self, workspace) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic.py index 64f6cfdf30..bf7e76f973 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic.py @@ -7,277 +7,17 @@ SPDX-License-Identifier: Apache-2.0 OR MIT import os import pytest -import sys -import ly_test_tools.environment.waiter as waiter import ly_test_tools.environment.file_system as file_system -import editor_python_test_tools.hydra_test_utils as hydra -from ly_remote_console.remote_console_commands import RemoteConsole as RemoteConsole - -sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../automatedtesting_shared') -from base import TestAutomationBase - - -@pytest.fixture -def remove_test_slice(request, workspace, project): - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice_1.slice")], True, - True) - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice_2.slice")], True, - True) - - def teardown(): - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice_1.slice")], True, - True) - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice_2.slice")], True, - True) - request.addfinalizer(teardown) - - -@pytest.fixture -def remote_console_instance(request): - console = RemoteConsole() - - def teardown(): - if console.connected: - console.stop() - - request.addfinalizer(teardown) - return console +from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite @pytest.mark.SUITE_periodic @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("project", ["AutomatedTesting"]) -class TestAutomation(TestAutomationBase): +class TestAutomation(EditorTestSuite): - def test_AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude(self, request, workspace, editor, launcher_platform): - from .EditorScripts import AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude as test_module - self._run_test(request, workspace, editor, test_module) + global_extra_cmdline_args = ["-BatchMode", "-autotest_mode"] - def test_AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude(self, request, workspace, editor, launcher_platform): - from .EditorScripts import AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude as test_module - self._run_test(request, workspace, editor, test_module) - - def test_AltitudeFilter_FilterStageToggle(self, request, workspace, editor, launcher_platform): - from .EditorScripts import AltitudeFilter_FilterStageToggle as test_module - self._run_test(request, workspace, editor, test_module) - - def test_SpawnerSlices_SliceCreationAndVisibilityToggleWorks(self, request, workspace, editor, remove_test_slice, launcher_platform): - from .EditorScripts import SpawnerSlices_SliceCreationAndVisibilityToggleWorks as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea(self, request, workspace, editor, launcher_platform): - from .EditorScripts import AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_AssetWeightSelector_InstancesExpressBasedOnWeight(self, request, workspace, editor, launcher_platform): - from .EditorScripts import AssetWeightSelector_InstancesExpressBasedOnWeight as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - @pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/4155") - def test_DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius(self, request, workspace, editor, launcher_platform): - from .EditorScripts import DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - @pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/4155") - def test_DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius(self, request, workspace, editor, launcher_platform): - from .EditorScripts import DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_SurfaceDataRefreshes_RemainsStable(self, request, workspace, editor, launcher_platform): - from .EditorScripts import SurfaceDataRefreshes_RemainsStable as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_VegetationInstances_DespawnWhenOutOfRange(self, request, workspace, editor, launcher_platform): - from .EditorScripts import VegetationInstances_DespawnWhenOutOfRange as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_InstanceSpawnerPriority_LayerAndSubPriority_HigherValuesPlantOverLower(self, request, workspace, editor, launcher_platform): - from .EditorScripts import InstanceSpawnerPriority_LayerAndSubPriority as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_LayerBlocker_InstancesBlockedInConfiguredArea(self, request, workspace, editor, launcher_platform): - from .EditorScripts import LayerBlocker_InstancesBlockedInConfiguredArea as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_LayerSpawner_InheritBehaviorFlag(self, request, workspace, editor, launcher_platform): - from .EditorScripts import LayerSpawner_InheritBehaviorFlag as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_LayerSpawner_InstancesPlantInAllSupportedShapes(self, request, workspace, editor, launcher_platform): - from .EditorScripts import LayerSpawner_InstancesPlantInAllSupportedShapes as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_LayerSpawner_FilterStageToggle(self, request, workspace, editor, launcher_platform): - from .EditorScripts import LayerSpawner_FilterStageToggle as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - @pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/2038") - def test_LayerSpawner_InstancesRefreshUsingCorrectViewportCamera(self, request, workspace, editor, launcher_platform): - from .EditorScripts import LayerSpawner_InstancesRefreshUsingCorrectViewportCamera as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_MeshBlocker_InstancesBlockedByMesh(self, request, workspace, editor, launcher_platform): - from .EditorScripts import MeshBlocker_InstancesBlockedByMesh as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_MeshBlocker_InstancesBlockedByMeshHeightTuning(self, request, workspace, editor, launcher_platform): - from .EditorScripts import MeshBlocker_InstancesBlockedByMeshHeightTuning as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_MeshSurfaceTagEmitter_DependentOnMeshComponent(self, request, workspace, editor, launcher_platform): - from .EditorScripts import MeshSurfaceTagEmitter_DependentOnMeshComponent as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully(self, request, workspace, editor, launcher_platform): - from .EditorScripts import MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_PhysXColliderSurfaceTagEmitter_E2E_Editor(self, request, workspace, editor, launcher_platform): - from .EditorScripts import PhysXColliderSurfaceTagEmitter_E2E_Editor as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets(self, request, workspace, editor, launcher_platform): - from .EditorScripts import PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_PositionModifier_AutoSnapToSurfaceWorks(self, request, workspace, editor, launcher_platform): - from .EditorScripts import PositionModifier_AutoSnapToSurfaceWorks as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_RotationModifier_InstancesRotateWithinRange(self, request, workspace, editor, launcher_platform): - from .EditorScripts import RotationModifier_InstancesRotateWithinRange as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_RotationModifierOverrides_InstancesRotateWithinRange(self, request, workspace, editor, launcher_platform): - from .EditorScripts import RotationModifierOverrides_InstancesRotateWithinRange as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_ScaleModifier_InstancesProperlyScale(self, request, workspace, editor, launcher_platform): - from .EditorScripts import ScaleModifier_InstancesProperlyScale as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_ScaleModifierOverrides_InstancesProperlyScale(self, request, workspace, editor, launcher_platform): - from .EditorScripts import ScaleModifierOverrides_InstancesProperlyScale as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_ShapeIntersectionFilter_InstancesPlantInAssignedShape(self, request, workspace, editor, launcher_platform): - from .EditorScripts import ShapeIntersectionFilter_InstancesPlantInAssignedShape as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_ShapeIntersectionFilter_FilterStageToggle(self, request, workspace, editor, launcher_platform): - from .EditorScripts import ShapeIntersectionFilter_FilterStageToggle as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_SlopeAlignmentModifier_InstanceSurfaceAlignment(self, request, workspace, editor, launcher_platform): - from .EditorScripts import SlopeAlignmentModifier_InstanceSurfaceAlignment as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment(self, request, workspace, editor, launcher_platform): - from .EditorScripts import SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_SurfaceMaskFilter_BasicSurfaceTagCreation(self, request, workspace, editor, launcher_platform): - from .EditorScripts import SurfaceMaskFilter_BasicSurfaceTagCreation as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_SurfaceMaskFilter_ExclusiveSurfaceTags_Function(self, request, workspace, editor, launcher_platform): - from .EditorScripts import SurfaceMaskFilter_ExclusionList as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_SurfaceMaskFilter_InclusiveSurfaceTags_Function(self, request, workspace, editor, launcher_platform): - from .EditorScripts import SurfaceMaskFilter_InclusionList as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected(self, request, workspace, editor, launcher_platform): - from .EditorScripts import SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_SystemSettings_SectorPointDensity(self, request, workspace, editor, launcher_platform): - from .EditorScripts import SystemSettings_SectorPointDensity as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_SystemSettings_SectorSize(self, request, workspace, editor, launcher_platform): - from .EditorScripts import SystemSettings_SectorSize as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlopes(self, request, workspace, editor, launcher_platform): - from .EditorScripts import SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlope as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - -@pytest.mark.SUITE_periodic -@pytest.mark.parametrize("project", ["AutomatedTesting"]) -@pytest.mark.parametrize("level", ["tmp_level"]) -class TestAutomationE2E(TestAutomationBase): - - # The following tests must run in order, please do not move tests out of order - - @pytest.mark.parametrize("launcher_platform", ['windows_editor']) - def test_DynamicSliceInstanceSpawner_Embedded_E2E_Editor(self, request, workspace, project, level, editor, launcher_platform): - # Ensure our test level does not already exist - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) - - from .EditorScripts import DynamicSliceInstanceSpawner_Embedded_E2E as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - @pytest.mark.parametrize("launcher_platform", ['windows']) - def test_DynamicSliceInstanceSpawner_Embedded_E2E_Launcher(self, workspace, launcher, level, - remote_console_instance, project, launcher_platform): - - expected_lines = [ - "Instances found in area = 400" - ] - - hydra.launch_and_validate_results_launcher(launcher, level, remote_console_instance, expected_lines, launch_ap=False) - - # Cleanup our temp level - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) - - @pytest.mark.parametrize("launcher_platform", ['windows_editor']) - def test_DynamicSliceInstanceSpawner_External_E2E_Editor(self, request, workspace, project, level, editor, launcher_platform): - # Ensure our test level does not already exist - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) - - from .EditorScripts import DynamicSliceInstanceSpawner_External_E2E as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - @pytest.mark.parametrize("launcher_platform", ['windows']) - def test_DynamicSliceInstanceSpawner_External_E2E_Launcher(self, workspace, launcher, level, - remote_console_instance, project, launcher_platform): - - expected_lines = [ - "Instances found in area = 400" - ] - - hydra.launch_and_validate_results_launcher(launcher, level, remote_console_instance, expected_lines, launch_ap=False) - - # Cleanup our temp level - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) - - @pytest.mark.parametrize("launcher_platform", ['windows_editor']) - def test_LayerBlender_E2E_Editor(self, request, workspace, project, level, editor, launcher_platform): - # Ensure our test level does not already exist - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) - - from .EditorScripts import LayerBlender_E2E_Editor as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - @pytest.mark.parametrize("launcher_platform", ['windows']) - @pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/4170") - def test_LayerBlender_E2E_Launcher(self, workspace, launcher, level, - remote_console_instance, project, launcher_platform): - - launcher.args.extend(["-rhi=Null"]) - launcher.start(launch_ap=False) - assert launcher.is_alive(), "Launcher failed to start" - - # Wait for test script to quit the launcher. If wait_for returns exc, test was not successful - waiter.wait_for(lambda: not launcher.is_alive(), timeout=300) - - # Verify launcher quit successfully and did not crash - ret_code = launcher.get_returncode() - assert ret_code == 0, "Test failed. See Game.log for details" - - # Cleanup our temp level - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) + class test_DynVegUtils_TempPrefabCreationWorks(EditorSharedTest): + from .EditorScripts import DynVegUtils_TempPrefabCreationWorks as test_module diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic_Optimized.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic_Optimized.py deleted file mode 100644 index f87d6567ef..0000000000 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic_Optimized.py +++ /dev/null @@ -1,23 +0,0 @@ -""" -Copyright (c) Contributors to the Open 3D Engine Project. -For complete copyright and license terms please see the LICENSE at the root of this distribution. - -SPDX-License-Identifier: Apache-2.0 OR MIT -""" - -import os -import pytest - -import ly_test_tools.environment.file_system as file_system -from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite - - -@pytest.mark.SUITE_main -@pytest.mark.parametrize("launcher_platform", ['windows_editor']) -@pytest.mark.parametrize("project", ["AutomatedTesting"]) -class TestAutomation(EditorTestSuite): - - global_extra_cmdline_args = ["-BatchMode", "-autotest_mode"] - - class test_DynVegUtils_TempPrefabCreationWorks(EditorSharedTest): - from .EditorScripts import DynVegUtils_TempPrefabCreationWorks as test_module diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientGenerators_Incompatibilities.py b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientGenerators_Incompatibilities.py index 09cd760647..6979ff1dee 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientGenerators_Incompatibilities.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientGenerators_Incompatibilities.py @@ -65,8 +65,7 @@ def GradientGenerators_Incompatibilities(): } # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # For every gradient generator component, verify that they are incompatible # which each vegetation area component diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientModifiers_Incompatibilities.py b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientModifiers_Incompatibilities.py index a4d9181744..962a0004f9 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientModifiers_Incompatibilities.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientModifiers_Incompatibilities.py @@ -74,8 +74,7 @@ def GradientModifiers_Incompatibilities(): } # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # For every gradient modifier component, verify that they are incompatible # which each vegetation area and gradient generator/modifier component diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin.py b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin.py index 3749f93bf5..87f9e1a9b1 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin.py @@ -86,8 +86,7 @@ def GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin(): return entity # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # 2) Create entity with Random Noise gradient and verify gradient position after clearing pinned entity clear_entityid_check_position( diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientPreviewSettings_DefaultPinnedEntityIsSelf.py b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientPreviewSettings_DefaultPinnedEntityIsSelf.py index 3756452710..cd3fd7e1ee 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientPreviewSettings_DefaultPinnedEntityIsSelf.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientPreviewSettings_DefaultPinnedEntityIsSelf.py @@ -90,8 +90,7 @@ def GradientPreviewSettings_DefaultPinnedEntityIsSelf(): ] # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() for param in param_list: execute_test(param.required_components[param.accessed_component], diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientSampling_GradientReferencesAddRemoveSuccessfully.py b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientSampling_GradientReferencesAddRemoveSuccessfully.py index 8e85345a6f..f2980d9634 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientSampling_GradientReferencesAddRemoveSuccessfully.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientSampling_GradientReferencesAddRemoveSuccessfully.py @@ -61,8 +61,7 @@ def GradientSampling_GradientReferencesAddRemoveSuccessfully(): Report.result(gradient_cleared_from_modifier, entity.Equal(EntityId.EntityId())) # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # 2) Create a new entity with components "Random Noise Gradient", "Gradient Transform Modifier" and "Box Shape" entity_position = math.Vector3(125.0, 136.0, 32.0) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientSurfaceTagEmitter_ComponentDependencies.py b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientSurfaceTagEmitter_ComponentDependencies.py index f653515a39..0cc325efd1 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientSurfaceTagEmitter_ComponentDependencies.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientSurfaceTagEmitter_ComponentDependencies.py @@ -42,8 +42,7 @@ def GradientSurfaceTagEmitter_ComponentDependencies(): return editor.EditorComponentAPIBus(bus.Broadcast, "IsComponentEnabled", EntityComponentIdPair) # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Create an entity with Gradient Surface Tag Emitter component position = math.Vector3(512.0, 512.0, 32.0) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully.py b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully.py index 90840a135d..cf48096a31 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully.py @@ -36,8 +36,7 @@ def GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully(): from editor_python_test_tools.utils import TestHelper as helper # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # 2) Create an entity with Gradient Surface Tag Emitter and Reference Gradient components. entity_position = math.Vector3(125.0, 136.0, 32.0) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_ComponentIncompatibleWithExpectedGradients.py b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_ComponentIncompatibleWithExpectedGradients.py index 5e6df4d52f..27ef248d6c 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_ComponentIncompatibleWithExpectedGradients.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_ComponentIncompatibleWithExpectedGradients.py @@ -46,8 +46,7 @@ def GradientTransform_ComponentIncompatibleWithExpectedGradients(): return editor.EditorComponentAPIBus(bus.Broadcast, "IsComponentEnabled", EntityComponentIdPair) # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # 2) Create a new entity with components Gradient Transform Modifier and Box Shape entity_position = math.Vector3(125.0, 136.0, 32.0) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_ComponentIncompatibleWithSpawners.py b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_ComponentIncompatibleWithSpawners.py index fd65996fdd..9c23cdea75 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_ComponentIncompatibleWithSpawners.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_ComponentIncompatibleWithSpawners.py @@ -44,8 +44,7 @@ def GradientTransform_ComponentIncompatibleWithSpawners(): return editor.EditorComponentAPIBus(bus.Broadcast, "IsComponentEnabled", EntityComponentIdPair) # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # 2) Create a new entity with components Gradient Transform Modifier and Box Shape entity_position = math.Vector3(125.0, 136.0, 32.0) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange.py b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange.py index 530503db86..6d6911ff3a 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange.py @@ -54,8 +54,7 @@ def GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange(): from editor_python_test_tools.utils import TestHelper as helper # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # 2) Create entity entity_position = math.Vector3(125.0, 136.0, 32.0) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_RequiresShape.py b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_RequiresShape.py index 09cce359d5..ec142f92d2 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_RequiresShape.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_RequiresShape.py @@ -47,8 +47,7 @@ def GradientTransform_RequiresShape(): from editor_python_test_tools.utils import TestHelper as helper # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Create a new Entity in the level entity_id = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId()) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/ImageGradient_ProcessedImageAssignedSuccessfully.py b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/ImageGradient_ProcessedImageAssignedSuccessfully.py index 42458665e1..afe0893da9 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/ImageGradient_ProcessedImageAssignedSuccessfully.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/ImageGradient_ProcessedImageAssignedSuccessfully.py @@ -56,8 +56,7 @@ def ImageGradient_ProcessedImageAssignedSuccessfully(): from editor_python_test_tools.utils import TestHelper as helper # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # 2) Create an entity with Image Gradient and Gradient Transform Modifier components components_to_add = ["Image Gradient", "Gradient Transform Modifier", "Box Shape"] diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/ImageGradient_RequiresShape.py b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/ImageGradient_RequiresShape.py index 3b832d160a..85582d198a 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/ImageGradient_RequiresShape.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/ImageGradient_RequiresShape.py @@ -47,8 +47,7 @@ def ImageGradient_RequiresShape(): from editor_python_test_tools.utils import TestHelper as helper # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Create a new Entity in the level entity_id = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId()) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/TestSuite_Periodic.py b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/TestSuite_Periodic.py index 3ad27eb973..d4199c31f6 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/TestSuite_Periodic.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/TestSuite_Periodic.py @@ -5,67 +5,51 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT """ -import os import pytest -import sys -sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../automatedtesting_shared') -from base import TestAutomationBase +from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite @pytest.mark.SUITE_periodic @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("project", ["AutomatedTesting"]) -class TestAutomation(TestAutomationBase): +class TestAutomation(EditorTestSuite): - def test_GradientGenerators_Incompatibilities(self, request, workspace, editor, launcher_platform): + class test_GradientGenerators_Incompatibilities(EditorSharedTest): from .EditorScripts import GradientGenerators_Incompatibilities as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - def test_GradientModifiers_Incompatibilities(self, request, workspace, editor, launcher_platform): + class test_GradientModifiers_Incompatibilities(EditorSharedTest): from .EditorScripts import GradientModifiers_Incompatibilities as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - def test_GradientPreviewSettings_DefaultPinnedEntityIsSelf(self, request, workspace, editor, launcher_platform): - from .EditorScripts import GradientPreviewSettings_DefaultPinnedEntityIsSelf as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin(self, request, workspace, editor, launcher_platform): + class test_GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin(EditorSharedTest): from .EditorScripts import GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - def test_GradientSampling_GradientReferencesAddRemoveSuccessfully(self, request, workspace, editor, launcher_platform): + class test_GradientPreviewSettings_DefaultPinnedEntityIsSelf(EditorSharedTest): + from .EditorScripts import GradientPreviewSettings_DefaultPinnedEntityIsSelf as test_module + + class test_GradientSampling_GradientReferencesAddRemoveSuccessfully(EditorSharedTest): from .EditorScripts import GradientSampling_GradientReferencesAddRemoveSuccessfully as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - def test_GradientSurfaceTagEmitter_ComponentDependencies(self, request, workspace, editor, launcher_platform): + class test_GradientSurfaceTagEmitter_ComponentDependencies(EditorSharedTest): from .EditorScripts import GradientSurfaceTagEmitter_ComponentDependencies as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - def test_GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully(self, request, workspace, editor, launcher_platform): + class test_GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully(EditorSharedTest): from .EditorScripts import GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - def test_GradientTransform_RequiresShape(self, request, workspace, editor, launcher_platform): - from .EditorScripts import GradientTransform_RequiresShape as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange(self, request, workspace, editor, launcher_platform): - from .EditorScripts import GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_GradientTransform_ComponentIncompatibleWithSpawners(self, request, workspace, editor, launcher_platform): - from .EditorScripts import GradientTransform_ComponentIncompatibleWithSpawners as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_GradientTransform_ComponentIncompatibleWithExpectedGradients(self, request, workspace, editor, launcher_platform): + class test_GradientTransform_ComponentIncompatibleWithExpectedGradients(EditorSharedTest): from .EditorScripts import GradientTransform_ComponentIncompatibleWithExpectedGradients as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - def test_ImageGradient_RequiresShape(self, request, workspace, editor, launcher_platform): - from .EditorScripts import ImageGradient_RequiresShape as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) + class test_GradientTransform_ComponentIncompatibleWithSpawners(EditorSharedTest): + from .EditorScripts import GradientTransform_ComponentIncompatibleWithSpawners as test_module - def test_ImageGradient_ProcessedImageAssignedSuccessfully(self, request, workspace, editor, launcher_platform): + class test_GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange(EditorSharedTest): + from .EditorScripts import GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange as test_module + + class test_GradientTransform_RequiresShape(EditorSharedTest): + from .EditorScripts import GradientTransform_RequiresShape as test_module + + class test_ImageGradient_ProcessedImageAssignedSuccessfully(EditorSharedTest): from .EditorScripts import ImageGradient_ProcessedImageAssignedSuccessfully as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) + + class test_ImageGradient_RequiresShape(EditorSharedTest): + from .EditorScripts import ImageGradient_RequiresShape as test_module diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/TestSuite_Periodic_Optimized.py b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/TestSuite_Periodic_Optimized.py deleted file mode 100644 index 6ac0658b4d..0000000000 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/TestSuite_Periodic_Optimized.py +++ /dev/null @@ -1,57 +0,0 @@ -""" -Copyright (c) Contributors to the Open 3D Engine Project. -For complete copyright and license terms please see the LICENSE at the root of this distribution. - -SPDX-License-Identifier: Apache-2.0 OR MIT -""" - -import pytest - -from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite - - -@pytest.mark.SUITE_periodic -@pytest.mark.parametrize("launcher_platform", ['windows_editor']) -@pytest.mark.parametrize("project", ["AutomatedTesting"]) -class TestAutomation(EditorTestSuite): - - enable_prefab_system = False - - class test_GradientGenerators_Incompatibilities(EditorSharedTest): - from .EditorScripts import GradientGenerators_Incompatibilities as test_module - - class test_GradientModifiers_Incompatibilities(EditorSharedTest): - from .EditorScripts import GradientModifiers_Incompatibilities as test_module - - class test_GradientPreviewSettings_DefaultPinnedEntityIsSelf(EditorSharedTest): - from .EditorScripts import GradientPreviewSettings_DefaultPinnedEntityIsSelf as test_module - - class test_GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin(EditorSharedTest): - from .EditorScripts import GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin as test_module - - class test_GradientSampling_GradientReferencesAddRemoveSuccessfully(EditorSharedTest): - from .EditorScripts import GradientSampling_GradientReferencesAddRemoveSuccessfully as test_module - - class test_GradientSurfaceTagEmitter_ComponentDependencies(EditorSharedTest): - from .EditorScripts import GradientSurfaceTagEmitter_ComponentDependencies as test_module - - class test_GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully(EditorSharedTest): - from .EditorScripts import GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully as test_module - - class test_GradientTransform_RequiresShape(EditorSharedTest): - from .EditorScripts import GradientTransform_RequiresShape as test_module - - class test_GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange(EditorSharedTest): - from .EditorScripts import GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange as test_module - - class test_GradientTransform_ComponentIncompatibleWithSpawners(EditorSharedTest): - from .EditorScripts import GradientTransform_ComponentIncompatibleWithSpawners as test_module - - class test_GradientTransform_ComponentIncompatibleWithExpectedGradients(EditorSharedTest): - from .EditorScripts import GradientTransform_ComponentIncompatibleWithExpectedGradients as test_module - - class test_ImageGradient_RequiresShape(EditorSharedTest): - from .EditorScripts import ImageGradient_RequiresShape as test_module - - class test_ImageGradient_ProcessedImageAssignedSuccessfully(EditorSharedTest): - from .EditorScripts import ImageGradient_ProcessedImageAssignedSuccessfully as test_module diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_DependentComponentsAdded.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_DependentComponentsAdded.py index c69ce77041..8151299cea 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_DependentComponentsAdded.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_DependentComponentsAdded.py @@ -69,7 +69,7 @@ def AreaNodes_DependentComponentsAdded(): # Open an existing simple level helper.init_idle() - helper.open_level("Physics", "Base") + helper.open_level("", "Base") # Open Landscape Canvas tool and verify general.open_pane('Landscape Canvas') diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Main_Optimized.py index 402df133cb..e501b3ad3b 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Main_Optimized.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Main_Optimized.py @@ -12,6 +12,13 @@ import ly_test_tools.environment.file_system as file_system import ly_test_tools._internal.pytest_plugin as internal_plugin from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite +@pytest.mark.SUITE_periodic +@pytest.mark.parametrize("launcher_platform", ['windows_editor']) +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +class TestAutomationWithPrefabSystemEnabled(EditorTestSuite): + + class test_LandscapeCanvas_AreaNodes_DependentComponentsAdded(EditorSharedTest): + from .EditorScripts import AreaNodes_DependentComponentsAdded as test_module @pytest.mark.SUITE_periodic @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @@ -26,9 +33,6 @@ class TestAutomation(EditorTestSuite): class test_LandscapeCanvas_GradientMixer_NodeConstruction(EditorSharedTest): from .EditorScripts import GradientMixer_NodeConstruction as test_module - class test_LandscapeCanvas_AreaNodes_DependentComponentsAdded(EditorSharedTest): - from .EditorScripts import AreaNodes_DependentComponentsAdded as test_module - class test_LandscapeCanvas_AreaNodes_EntityCreatedOnNodeAdd(EditorSharedTest): from .EditorScripts import AreaNodes_EntityCreatedOnNodeAdd as test_module diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py b/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py index 37afeff8c0..fd6a907b2e 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py @@ -114,7 +114,8 @@ def create_dynamic_slice_vegetation_area(name, center_point, box_size_x, box_siz return spawner_entity -def create_prefab_vegetation_area(name, center_point, box_size_x, box_size_y, box_size_z, target_prefab): +def create_temp_prefab_vegetation_area(name, center_point, box_size_x, box_size_y, box_size_z, target_prefab): + """Creates a vegetation area using in-memory prefabs. Use when test is solely contained to Editor""" # Create a vegetation area entity to use as our test vegetation spawner spawner_entity = hydra.Entity(name) spawner_entity.create_entity( @@ -148,6 +149,31 @@ def create_prefab_vegetation_area(name, center_point, box_size_x, box_size_y, bo return spawner_entity +def create_prefab_vegetation_area(name, center_point, box_size_x, box_size_y, box_size_z, prefab_path): + """Creates a vegetation area using on-disk spawnable prefabs. Use when test requires saving/loading in Launcher""" + # Create a vegetation area entity to use as our test vegetation spawner + prefab_asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", prefab_path, math.Uuid(), + False) + spawner_entity = hydra.Entity(name) + spawner_entity.create_entity( + center_point, + ["Vegetation Layer Spawner", "Box Shape", "Vegetation Asset List"] + ) + if spawner_entity.id.IsValid(): + print(f"'{spawner_entity.name}' created") + spawner_entity.get_set_test(1, "Box Shape|Box Configuration|Dimensions", math.Vector3(box_size_x, box_size_y, + box_size_z)) + + # Set the vegetation area to a prefab instance spawner with a specific prefab asset selected + descriptor = hydra.get_component_property_value(spawner_entity.components[2], + 'Configuration|Embedded Assets|[0]') + prefab_spawner = vegetation.PrefabInstanceSpawner() + prefab_spawner.SetPrefabAssetId(prefab_asset_id) + descriptor.spawner = prefab_spawner + spawner_entity.get_set_test(2, "Configuration|Embedded Assets|[0]", descriptor) + return spawner_entity + + def create_blocker_area(name, center_point, box_size_x, box_size_y, box_size_z): # Create a Vegetation Layer Blocker area blocker_entity = hydra.Entity(name) @@ -162,6 +188,23 @@ def create_blocker_area(name, center_point, box_size_x, box_size_y, box_size_z): return blocker_entity +def create_empty_vegetation_area(name, center_point, box_size_x, box_size_y, box_size_z): + # Create a vegetation area entity to use as our test vegetation spawner + spawner_entity = EditorEntity.create_editor_entity_at(center_point, name=name) + spawner_entity.add_components(["Vegetation Layer Spawner", "Box Shape", "Vegetation Asset List"]) + if spawner_entity.id.IsValid(): + print(f"'{spawner_entity.get_name()}' created") + spawner_entity.components[1].set_component_property_value("Box Shape|Box Configuration|Dimensions", + math.Vector3(box_size_x, box_size_y, box_size_z)) + + # Set the vegetation area to an empty spawner + empty_spawner = vegetation.EmptyInstanceSpawner() + descriptor = spawner_entity.components[2].get_component_property_value("Configuration|Embedded Assets|[0]") + descriptor.spawner = empty_spawner + spawner_entity.components[2].set_component_property_value("Configuration|Embedded Assets|[0]", descriptor) + return spawner_entity + + def validate_instance_count(center, radius, num_expected): # Verify that we have the correct number of instances in the given area. This creates a bounding box based on a # sphere radius diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_black.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_black.material index cc2c9e785b..d15aa620c7 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_black.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_black.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_green.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_green.material index a4bfb73d12..579359b085 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_green.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_green.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_arch.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_arch.material index fe9c54bc02..88d5fc0fc6 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_arch.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_arch.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_bricks.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_bricks.material index a19afa33e2..7244397ee9 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_bricks.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_bricks.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_floor.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_floor.material index 0c1208d8fb..8a3f289c26 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_floor.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_floor.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_roof.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_roof.material index 6aad4d644a..7bc193978f 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_roof.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_roof.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_phong5.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_phong5.material index 302589dc85..a53cbef4e4 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_phong5.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_phong5.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_red.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_red.material index 5217a4e4be..6ddb645319 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_red.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_red.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_white.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_white.material index dba44f7b49..e3d310cd15 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_white.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_white.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "emissive": { "color": [ diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/lightBlocker_lambert1.material b/AutomatedTesting/Gem/Sponza/Assets/objects/lightBlocker_lambert1.material index c8e9f1f8f7..35677a81c6 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/lightBlocker_lambert1.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/lightBlocker_lambert1.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "emissive": { "color": [ diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic.material index 32ac8dfd10..6af3ceb0c1 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic.material @@ -1,6 +1,6 @@ { "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "baseColor": { "color": [ 1.0, 1.0, 1.0 ], diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r00.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r00.material index 1c1096bf12..541bd83981 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r00.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r00.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 0.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r01.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r01.material index 33148f3f73..19691258e0 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r01.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r01.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 0.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r02.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r02.material index 38339454cb..46fda2aab1 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r02.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r02.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 0.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r03.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r03.material index e21ab5775a..79cf4bf401 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r03.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r03.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 0.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r04.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r04.material index 0272e66081..9aabf3e158 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r04.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r04.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 0.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r05.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r05.material index 67d51777a4..8b02f225fc 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r05.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r05.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 0.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r06.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r06.material index 3136f654e6..5b089da4bd 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r06.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r06.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 0.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r07.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r07.material index a79744ea11..25741cf689 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r07.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r07.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 0.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r08.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r08.material index 1372283500..04103273f2 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r08.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r08.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 0.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r09.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r09.material index d1c951e53c..74eb68da99 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r09.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r09.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 0.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r10.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r10.material index d34fc46530..3533ca6676 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r10.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r10.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 0.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r00.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r00.material index 92ddfec7c4..d2ce0fadc9 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r00.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r00.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 1.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r01.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r01.material index 874422384a..8d96ea6217 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r01.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r01.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 1.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r02.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r02.material index b017add10b..e8feb87283 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r02.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r02.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 1.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r03.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r03.material index 5353d651c8..c14591bd52 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r03.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r03.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 1.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r04.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r04.material index 6dd47e4e3b..60a3167f02 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r04.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r04.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 1.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r05.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r05.material index 04912cbfd4..d71ff06961 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r05.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r05.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 1.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r06.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r06.material index 27f7f6ff42..6fa8cfe1a6 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r06.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r06.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 1.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r07.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r07.material index e2b5df681c..773cc66f03 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r07.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r07.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 1.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r08.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r08.material index 5418f9c855..6971597d1d 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r08.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r08.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 1.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r09.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r09.material index dd1ec3489a..c2d8cc47bd 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r09.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r09.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 1.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r10.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r10.material index 5f9317d2cc..906879b0ea 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r10.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r10.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 1.0 diff --git a/AutomatedTesting/Levels/Graphics/base_empty/base_empty.prefab b/AutomatedTesting/Levels/Graphics/base_empty/base_empty.prefab new file mode 100644 index 0000000000..f7e42e7731 --- /dev/null +++ b/AutomatedTesting/Levels/Graphics/base_empty/base_empty.prefab @@ -0,0 +1,53 @@ +{ + "ContainerEntity": { + "Id": "Entity_[1146574390643]", + "Name": "Level", + "Components": { + "Component_[10641544592923449938]": { + "$type": "EditorInspectorComponent", + "Id": 10641544592923449938 + }, + "Component_[12039882709170782873]": { + "$type": "EditorOnlyEntityComponent", + "Id": 12039882709170782873 + }, + "Component_[12265484671603697631]": { + "$type": "EditorPendingCompositionComponent", + "Id": 12265484671603697631 + }, + "Component_[14126657869720434043]": { + "$type": "EditorEntitySortComponent", + "Id": 14126657869720434043 + }, + "Component_[15230859088967841193]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 15230859088967841193, + "Parent Entity": "" + }, + "Component_[16239496886950819870]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 16239496886950819870 + }, + "Component_[5688118765544765547]": { + "$type": "EditorEntityIconComponent", + "Id": 5688118765544765547 + }, + "Component_[6545738857812235305]": { + "$type": "SelectionComponent", + "Id": 6545738857812235305 + }, + "Component_[7247035804068349658]": { + "$type": "EditorPrefabComponent", + "Id": 7247035804068349658 + }, + "Component_[9307224322037797205]": { + "$type": "EditorLockComponent", + "Id": 9307224322037797205 + }, + "Component_[9562516168917670048]": { + "$type": "EditorVisibilityComponent", + "Id": 9562516168917670048 + } + } + } +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/base_empty/tags.txt b/AutomatedTesting/Levels/Graphics/base_empty/tags.txt new file mode 100644 index 0000000000..0d6c1880e7 --- /dev/null +++ b/AutomatedTesting/Levels/Graphics/base_empty/tags.txt @@ -0,0 +1,12 @@ +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 diff --git a/AutomatedTesting/Materials/DefaultPBRTransparent.material b/AutomatedTesting/Materials/DefaultPBRTransparent.material index 7c8aa6cf94..a7000d5371 100644 --- a/AutomatedTesting/Materials/DefaultPBRTransparent.material +++ b/AutomatedTesting/Materials/DefaultPBRTransparent.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "Materials/Presets/PBR/default_grid.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "opacity": { "mode": "Blended" diff --git a/AutomatedTesting/Materials/basic_grey.material b/AutomatedTesting/Materials/basic_grey.material index 0b890db4c6..6ecc1e029a 100644 --- a/AutomatedTesting/Materials/basic_grey.material +++ b/AutomatedTesting/Materials/basic_grey.material @@ -1,6 +1,6 @@ { "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "baseColor": { "color": [ 0.18, 0.18, 0.18 ], diff --git a/AutomatedTesting/Objects/MorphTargets/DisplayWrinkleMaskBlendValues.material b/AutomatedTesting/Objects/MorphTargets/DisplayWrinkleMaskBlendValues.material index 878b3ac39f..52c323b454 100644 --- a/AutomatedTesting/Objects/MorphTargets/DisplayWrinkleMaskBlendValues.material +++ b/AutomatedTesting/Objects/MorphTargets/DisplayWrinkleMaskBlendValues.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/Skin.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "wrinkleLayers": { "count": 3, diff --git a/Gems/ScriptCanvas/Assets/TranslationAssets/AZEvents/AuthorityToAutonomousNoParamsNotifyEvent.names b/AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/AuthorityToAutonomousNoParamsNotifyEvent.names similarity index 100% rename from Gems/ScriptCanvas/Assets/TranslationAssets/AZEvents/AuthorityToAutonomousNoParamsNotifyEvent.names rename to AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/AuthorityToAutonomousNoParamsNotifyEvent.names diff --git a/Gems/ScriptCanvas/Assets/TranslationAssets/AZEvents/AuthorityToAutonomousNotifyEvent.names b/AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/AuthorityToAutonomousNotifyEvent.names similarity index 100% rename from Gems/ScriptCanvas/Assets/TranslationAssets/AZEvents/AuthorityToAutonomousNotifyEvent.names rename to AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/AuthorityToAutonomousNotifyEvent.names diff --git a/AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/AuthorityToAutonomous_PlayerNumberNotifyEvent.names b/AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/AuthorityToAutonomous_PlayerNumberNotifyEvent.names new file mode 100644 index 0000000000..7255c61d23 --- /dev/null +++ b/AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/AuthorityToAutonomous_PlayerNumberNotifyEvent.names @@ -0,0 +1,56 @@ +{ + "entries": [ + { + "base": "AuthorityToAutonomous_PlayerNumber Notify Event", + "context": "AZEventHandler", + "variant": "", + "details": { + "name": "Authority To Autonomous_ Player Number Notify Event" + }, + "slots": [ + { + "base": "player_number", + "details": { + "name": "player_number" + } + }, + { + "base": "AuthorityToAutonomous_PlayerNumber Notify Event", + "details": { + "name": "AuthorityToAutonomous_PlayerNumber Notify Event" + } + }, + { + "base": "Connect", + "details": { + "name": "Connect" + } + }, + { + "base": "Disconnect", + "details": { + "name": "Disconnect" + } + }, + { + "base": "On Connected", + "details": { + "name": "On Connected" + } + }, + { + "base": "On Disconnected", + "details": { + "name": "On Disconnected" + } + }, + { + "base": "OnEvent", + "details": { + "name": "OnEvent" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/Gems/ScriptCanvas/Assets/TranslationAssets/AZEvents/AuthorityToClientNoParamsNotifyEvent.names b/AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/AuthorityToClientNoParamsNotifyEvent.names similarity index 100% rename from Gems/ScriptCanvas/Assets/TranslationAssets/AZEvents/AuthorityToClientNoParamsNotifyEvent.names rename to AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/AuthorityToClientNoParamsNotifyEvent.names diff --git a/AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/AuthorityToClientNoParams_PlayFxNotifyEvent.names b/AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/AuthorityToClientNoParams_PlayFxNotifyEvent.names new file mode 100644 index 0000000000..3e0207a705 --- /dev/null +++ b/AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/AuthorityToClientNoParams_PlayFxNotifyEvent.names @@ -0,0 +1,50 @@ +{ + "entries": [ + { + "base": "AuthorityToClientNoParams_PlayFx Notify Event", + "context": "AZEventHandler", + "variant": "", + "details": { + "name": "Authority To Client No Params_ Play Fx Notify Event" + }, + "slots": [ + { + "base": "AuthorityToClientNoParams_PlayFx Notify Event", + "details": { + "name": "AuthorityToClientNoParams_PlayFx Notify Event" + } + }, + { + "base": "Connect", + "details": { + "name": "Connect" + } + }, + { + "base": "Disconnect", + "details": { + "name": "Disconnect" + } + }, + { + "base": "On Connected", + "details": { + "name": "On Connected" + } + }, + { + "base": "On Disconnected", + "details": { + "name": "On Disconnected" + } + }, + { + "base": "OnEvent", + "details": { + "name": "OnEvent" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/Gems/ScriptCanvas/Assets/TranslationAssets/AZEvents/AuthorityToClientNotifyEvent.names b/AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/AuthorityToClientNotifyEvent.names similarity index 100% rename from Gems/ScriptCanvas/Assets/TranslationAssets/AZEvents/AuthorityToClientNotifyEvent.names rename to AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/AuthorityToClientNotifyEvent.names diff --git a/Gems/ScriptCanvas/Assets/TranslationAssets/AZEvents/AutonomousToAuthorityNoParamsNotifyEvent.names b/AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/AutonomousToAuthorityNoParamsNotifyEvent.names similarity index 100% rename from Gems/ScriptCanvas/Assets/TranslationAssets/AZEvents/AutonomousToAuthorityNoParamsNotifyEvent.names rename to AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/AutonomousToAuthorityNoParamsNotifyEvent.names diff --git a/Gems/ScriptCanvas/Assets/TranslationAssets/AZEvents/AutonomousToAuthorityNotifyEvent.names b/AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/AutonomousToAuthorityNotifyEvent.names similarity index 100% rename from Gems/ScriptCanvas/Assets/TranslationAssets/AZEvents/AutonomousToAuthorityNotifyEvent.names rename to AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/AutonomousToAuthorityNotifyEvent.names diff --git a/Gems/ScriptCanvas/Assets/TranslationAssets/AZEvents/ServerToAuthorityNoParamNotifyEvent.names b/AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/ServerToAuthorityNoParamNotifyEvent.names similarity index 100% rename from Gems/ScriptCanvas/Assets/TranslationAssets/AZEvents/ServerToAuthorityNoParamNotifyEvent.names rename to AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/ServerToAuthorityNoParamNotifyEvent.names diff --git a/Gems/ScriptCanvas/Assets/TranslationAssets/AZEvents/ServerToAuthorityNotifyEvent.names b/AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/ServerToAuthorityNotifyEvent.names similarity index 100% rename from Gems/ScriptCanvas/Assets/TranslationAssets/AZEvents/ServerToAuthorityNotifyEvent.names rename to AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/ServerToAuthorityNotifyEvent.names diff --git a/AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/ServerToAuthority_DealDamageNotifyEvent.names b/AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/ServerToAuthority_DealDamageNotifyEvent.names new file mode 100644 index 0000000000..2505d9593a --- /dev/null +++ b/AutomatedTesting/ScriptCanvas/TranslationAssets/AZEvents/ServerToAuthority_DealDamageNotifyEvent.names @@ -0,0 +1,56 @@ +{ + "entries": [ + { + "base": "ServerToAuthority_DealDamage Notify Event", + "context": "AZEventHandler", + "variant": "", + "details": { + "name": "Server To Authority_ Deal Damage Notify Event" + }, + "slots": [ + { + "base": "damage", + "details": { + "name": "damage" + } + }, + { + "base": "ServerToAuthority_DealDamage Notify Event", + "details": { + "name": "ServerToAuthority_DealDamage Notify Event" + } + }, + { + "base": "Connect", + "details": { + "name": "Connect" + } + }, + { + "base": "Disconnect", + "details": { + "name": "Disconnect" + } + }, + { + "base": "On Connected", + "details": { + "name": "On Connected" + } + }, + { + "base": "On Disconnected", + "details": { + "name": "On Disconnected" + } + }, + { + "base": "OnEvent", + "details": { + "name": "OnEvent" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/Gems/ScriptCanvas/Assets/TranslationAssets/Classes/NetworkTestPlayerComponent.names b/AutomatedTesting/ScriptCanvas/TranslationAssets/Classes/NetworkTestPlayerComponent.names similarity index 90% rename from Gems/ScriptCanvas/Assets/TranslationAssets/Classes/NetworkTestPlayerComponent.names rename to AutomatedTesting/ScriptCanvas/TranslationAssets/Classes/NetworkTestPlayerComponent.names index 22636e0453..03e949f784 100644 --- a/Gems/ScriptCanvas/Assets/TranslationAssets/Classes/NetworkTestPlayerComponent.names +++ b/AutomatedTesting/ScriptCanvas/TranslationAssets/Classes/NetworkTestPlayerComponent.names @@ -8,64 +8,6 @@ "name": "Network Test Player Component" }, "methods": [ - { - "base": "AutonomousToAuthority", - "context": "NetworkTestPlayerComponent", - "entry": { - "name": "In", - "tooltip": "When signaled, this will invoke Autonomous To Authority" - }, - "exit": { - "name": "Out", - "tooltip": "Signaled after Autonomous To Authority is invoked" - }, - "details": { - "name": "Autonomous To Authority" - }, - "params": [ - { - "typeid": "{CA5E5C37-98A6-04D2-E15C-1B4BFEE4C7DD}", - "details": { - "name": "Network Test Player Component" - } - }, - { - "typeid": "{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}", - "details": { - "name": "float" - } - } - ] - }, - { - "base": "ServerToAuthority", - "context": "NetworkTestPlayerComponent", - "entry": { - "name": "In", - "tooltip": "When signaled, this will invoke Server To Authority" - }, - "exit": { - "name": "Out", - "tooltip": "Signaled after Server To Authority is invoked" - }, - "details": { - "name": "Server To Authority" - }, - "params": [ - { - "typeid": "{CA5E5C37-98A6-04D2-E15C-1B4BFEE4C7DD}", - "details": { - "name": "Network Test Player Component" - } - }, - { - "typeid": "{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}", - "details": { - "name": "float" - } - } - ] - }, { "base": "AutonomousToAuthorityByEntityId", "context": "NetworkTestPlayerComponent", @@ -97,18 +39,72 @@ ] }, { - "base": "ServerToAuthorityByEntityId", + "base": "AuthorityToClientNoParams_PlayFxByEntityId", "context": "NetworkTestPlayerComponent", "entry": { "name": "In", - "tooltip": "When signaled, this will invoke Server To Authority By Entity Id" + "tooltip": "When signaled, this will invoke Authority To Client No Params_ Play Fx By Entity Id" }, "exit": { "name": "Out", - "tooltip": "Signaled after Server To Authority By Entity Id is invoked" + "tooltip": "Signaled after Authority To Client No Params_ Play Fx By Entity Id is invoked" }, "details": { - "name": "Server To Authority By Entity Id" + "name": "Authority To Client No Params_ Play Fx By Entity Id" + }, + "params": [ + { + "typeid": "{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}", + "details": { + "name": "Source", + "tooltip": "The Source containing the NetworkTestPlayerComponentController" + } + } + ] + }, + { + "base": "AuthorityToAutonomous_PlayerNumberByEntityId", + "context": "NetworkTestPlayerComponent", + "entry": { + "name": "In", + "tooltip": "When signaled, this will invoke Authority To Autonomous_ Player Number By Entity Id" + }, + "exit": { + "name": "Out", + "tooltip": "Signaled after Authority To Autonomous_ Player Number By Entity Id is invoked" + }, + "details": { + "name": "Authority To Autonomous_ Player Number By Entity Id" + }, + "params": [ + { + "typeid": "{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}", + "details": { + "name": "Source", + "tooltip": "The Source containing the NetworkTestPlayerComponentController" + } + }, + { + "typeid": "{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}", + "details": { + "name": "player_number" + } + } + ] + }, + { + "base": "ServerToAuthority_DealDamageByEntityId", + "context": "NetworkTestPlayerComponent", + "entry": { + "name": "In", + "tooltip": "When signaled, this will invoke Server To Authority_ Deal Damage By Entity Id" + }, + "exit": { + "name": "Out", + "tooltip": "Signaled after Server To Authority_ Deal Damage By Entity Id is invoked" + }, + "details": { + "name": "Server To Authority_ Deal Damage By Entity Id" }, "params": [ { @@ -121,47 +117,48 @@ { "typeid": "{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}", "details": { - "name": "some Float" + "name": "damage" } } ] }, { - "base": "AutonomousToAuthorityNoParams", + "base": "AutonomousToAuthorityNoParamsByEntityId", "context": "NetworkTestPlayerComponent", "entry": { "name": "In", - "tooltip": "When signaled, this will invoke Autonomous To Authority No Params" + "tooltip": "When signaled, this will invoke Autonomous To Authority No Params By Entity Id" }, "exit": { "name": "Out", - "tooltip": "Signaled after Autonomous To Authority No Params is invoked" + "tooltip": "Signaled after Autonomous To Authority No Params By Entity Id is invoked" }, "details": { - "name": "Autonomous To Authority No Params" + "name": "Autonomous To Authority No Params By Entity Id" }, "params": [ { - "typeid": "{CA5E5C37-98A6-04D2-E15C-1B4BFEE4C7DD}", + "typeid": "{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}", "details": { - "name": "Network Test Player Component" + "name": "Source", + "tooltip": "The Source containing the NetworkTestPlayerComponentController" } } ] }, { - "base": "AuthorityToAutonomous", + "base": "ServerToAuthority_DealDamage", "context": "NetworkTestPlayerComponent", "entry": { "name": "In", - "tooltip": "When signaled, this will invoke Authority To Autonomous" + "tooltip": "When signaled, this will invoke Server To Authority_ Deal Damage" }, "exit": { "name": "Out", - "tooltip": "Signaled after Authority To Autonomous is invoked" + "tooltip": "Signaled after Server To Authority_ Deal Damage is invoked" }, "details": { - "name": "Authority To Autonomous" + "name": "Server To Authority_ Deal Damage" }, "params": [ { @@ -179,18 +176,18 @@ ] }, { - "base": "AuthorityToClientNoParams", + "base": "AutonomousToAuthority", "context": "NetworkTestPlayerComponent", "entry": { "name": "In", - "tooltip": "When signaled, this will invoke Authority To Client No Params" + "tooltip": "When signaled, this will invoke Autonomous To Authority" }, "exit": { "name": "Out", - "tooltip": "Signaled after Authority To Client No Params is invoked" + "tooltip": "Signaled after Autonomous To Authority is invoked" }, "details": { - "name": "Authority To Client No Params" + "name": "Autonomous To Authority" }, "params": [ { @@ -198,6 +195,41 @@ "details": { "name": "Network Test Player Component" } + }, + { + "typeid": "{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}", + "details": { + "name": "float" + } + } + ] + }, + { + "base": "AuthorityToAutonomous_PlayerNumber", + "context": "NetworkTestPlayerComponent", + "entry": { + "name": "In", + "tooltip": "When signaled, this will invoke Authority To Autonomous_ Player Number" + }, + "exit": { + "name": "Out", + "tooltip": "Signaled after Authority To Autonomous_ Player Number is invoked" + }, + "details": { + "name": "Authority To Autonomous_ Player Number" + }, + "params": [ + { + "typeid": "{CA5E5C37-98A6-04D2-E15C-1B4BFEE4C7DD}", + "details": { + "name": "Network Test Player Component" + } + }, + { + "typeid": "{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}", + "details": { + "name": "int" + } } ] }, @@ -308,79 +340,47 @@ ] }, { - "base": "AuthorityToClientNoParamsByEntityId", + "base": "AutonomousToAuthorityNoParams", "context": "NetworkTestPlayerComponent", "entry": { "name": "In", - "tooltip": "When signaled, this will invoke Authority To Client No Params By Entity Id" + "tooltip": "When signaled, this will invoke Autonomous To Authority No Params" }, "exit": { "name": "Out", - "tooltip": "Signaled after Authority To Client No Params By Entity Id is invoked" + "tooltip": "Signaled after Autonomous To Authority No Params is invoked" }, "details": { - "name": "Authority To Client No Params By Entity Id" + "name": "Autonomous To Authority No Params" }, "params": [ { - "typeid": "{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}", + "typeid": "{CA5E5C37-98A6-04D2-E15C-1B4BFEE4C7DD}", "details": { - "name": "Source", - "tooltip": "The Source containing the NetworkTestPlayerComponentController" + "name": "Network Test Player Component" } } ] }, { - "base": "AuthorityToAutonomousByEntityId", + "base": "AuthorityToClientNoParams_PlayFx", "context": "NetworkTestPlayerComponent", "entry": { "name": "In", - "tooltip": "When signaled, this will invoke Authority To Autonomous By Entity Id" + "tooltip": "When signaled, this will invoke Authority To Client No Params_ Play Fx" }, "exit": { "name": "Out", - "tooltip": "Signaled after Authority To Autonomous By Entity Id is invoked" + "tooltip": "Signaled after Authority To Client No Params_ Play Fx is invoked" }, "details": { - "name": "Authority To Autonomous By Entity Id" + "name": "Authority To Client No Params_ Play Fx" }, "params": [ { - "typeid": "{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}", + "typeid": "{CA5E5C37-98A6-04D2-E15C-1B4BFEE4C7DD}", "details": { - "name": "Source", - "tooltip": "The Source containing the NetworkTestPlayerComponentController" - } - }, - { - "typeid": "{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}", - "details": { - "name": "some Float" - } - } - ] - }, - { - "base": "AutonomousToAuthorityNoParamsByEntityId", - "context": "NetworkTestPlayerComponent", - "entry": { - "name": "In", - "tooltip": "When signaled, this will invoke Autonomous To Authority No Params By Entity Id" - }, - "exit": { - "name": "Out", - "tooltip": "Signaled after Autonomous To Authority No Params By Entity Id is invoked" - }, - "details": { - "name": "Autonomous To Authority No Params By Entity Id" - }, - "params": [ - { - "typeid": "{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}", - "details": { - "name": "Source", - "tooltip": "The Source containing the NetworkTestPlayerComponentController" + "name": "Network Test Player Component" } } ] diff --git a/Gems/ScriptCanvas/Assets/TranslationAssets/Classes/NetworkTestPlayerComponentNetworkInput.names b/AutomatedTesting/ScriptCanvas/TranslationAssets/Classes/NetworkTestPlayerComponentNetworkInput.names similarity index 100% rename from Gems/ScriptCanvas/Assets/TranslationAssets/Classes/NetworkTestPlayerComponentNetworkInput.names rename to AutomatedTesting/ScriptCanvas/TranslationAssets/Classes/NetworkTestPlayerComponentNetworkInput.names diff --git a/AutomatedTesting/ScriptCanvas/instance_counter.scriptcanvas b/AutomatedTesting/ScriptCanvas/instance_counter.scriptcanvas index 0e5524273c..4ef5f0a8d5 100644 --- a/AutomatedTesting/ScriptCanvas/instance_counter.scriptcanvas +++ b/AutomatedTesting/ScriptCanvas/instance_counter.scriptcanvas @@ -5,7 +5,7 @@ "ClassData": { "m_scriptCanvas": { "Id": { - "id": 3744110453276 + "id": 337666590525276931 }, "Name": "instance_counter", "Components": { @@ -87,7 +87,6 @@ ], "Datums": [ { - "isOverloadedStorage": false, "scriptCanvasType": { "m_type": 3 }, @@ -228,7 +227,6 @@ ], "Datums": [ { - "isOverloadedStorage": false, "scriptCanvasType": { "m_type": 1 }, @@ -237,7 +235,7 @@ "value": { "id": 2901262558 }, - "label": "Source" + "label": "EntityID: 0" } ], "methodType": 0, @@ -340,7 +338,6 @@ ], "Datums": [ { - "isOverloadedStorage": false, "scriptCanvasType": { "m_type": 3 }, @@ -587,26 +584,10 @@ "m_assetType": "{3E2AC8CD-713F-453E-967F-29517F331784}", "versionData": { "_grammarVersion": 1, - "_runtimeVersion": 1 + "_runtimeVersion": 1, + "_fileVersion": 1 }, "GraphCanvasData": [ - { - "Key": { - "id": 3744110453276 - }, - "Value": { - "ComponentData": { - "{5F84B500-8C45-40D1-8EFC-A5306B241444}": { - "$type": "SceneComponentSaveData", - "ViewParams": { - "Scale": 0.9218543514249998, - "AnchorX": 50.98419189453125, - "AnchorY": -272.27728271484375 - } - } - } - } - }, { "Key": { "id": 3748405420572 @@ -757,6 +738,18 @@ } } } + }, + { + "Key": { + "id": 337666590525276931 + }, + "Value": { + "ComponentData": { + "{5F84B500-8C45-40D1-8EFC-A5306B241444}": { + "$type": "SceneComponentSaveData" + } + } + } } ], "StatisticsHelper": { diff --git a/CMakeLists.txt b/CMakeLists.txt index c81581fe0f..efcc866195 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,6 +93,10 @@ endfunction() # Add the projects first so the Launcher can find them include(cmake/Projects.cmake) +if(LY_EXTERNAL_SUBDIRS) + set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS ${LY_EXTERNAL_SUBDIRS}) +endif() + if(NOT INSTALLED_ENGINE) # Add external subdirectories listed in the engine.json. LY_EXTERNAL_SUBDIRS is a cache variable so the user can add extra # external subdirectories. This should go before adding the rest of the targets so the targets are availbe to the launcher. diff --git a/Code/Editor/AssetImporter/AssetImporterManager/AssetImporterManager.cpp b/Code/Editor/AssetImporter/AssetImporterManager/AssetImporterManager.cpp index baa287e47f..73c3d6f9ed 100644 --- a/Code/Editor/AssetImporter/AssetImporterManager/AssetImporterManager.cpp +++ b/Code/Editor/AssetImporter/AssetImporterManager/AssetImporterManager.cpp @@ -191,6 +191,7 @@ void AssetImporterManager::OnBrowseDestinationFilePath(QLineEdit* destinationLin fileDialog.setViewMode(QFileDialog::List); fileDialog.setWindowModality(Qt::WindowModality::ApplicationModal); fileDialog.setWindowTitle(tr("Select import destination")); + fileDialog.setFileMode(QFileDialog::Directory); QSettings settings; QString currentDestination = settings.value(AssetImporterManagerPrivate::g_selectDestinationFilesPath).toString(); diff --git a/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp b/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp index bcaaa02b67..36e08982a7 100644 --- a/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp +++ b/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp @@ -17,6 +17,7 @@ #include #include #include +#include // AzQtComponents #include @@ -31,6 +32,15 @@ AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING AZ_CVAR_EXTERNED(bool, ed_useNewAssetBrowserTableView); +namespace AzToolsFramework +{ + namespace AssetBrowser + { + static constexpr const char* CollapseAllIcon = "Assets/Editor/Icons/AssetBrowser/Collapse_All.svg"; + static constexpr const char* MenuIcon = ":/Menu/menu.svg"; + } // namespace AssetBrowser +} // namespace AzToolsFramework + class ListenerForShowAssetEditorEvent : public QObject , private AzToolsFramework::EditorEvents::Bus::Handler @@ -83,10 +93,24 @@ AzAssetBrowserWindow::AzAssetBrowserWindow(QWidget* parent) m_ui->m_assetBrowserTableViewWidget->setVisible(false); m_ui->m_toggleDisplayViewBtn->setVisible(false); m_ui->m_searchWidget->SetFilterInputInterval(AZStd::chrono::milliseconds(250)); + + m_assetBrowserModel->SetFilterModel(m_filterModel.data()); + + m_ui->m_collapseAllButton->setAutoRaise(true); // hover highlight + m_ui->m_collapseAllButton->setIcon(QIcon(AzAssetBrowser::CollapseAllIcon)); + + connect( + m_ui->m_collapseAllButton, &QToolButton::clicked, this, + [this]() + { + m_ui->m_assetBrowserTreeViewWidget->collapseAll(); + }); + if (ed_useNewAssetBrowserTableView) { m_ui->m_toggleDisplayViewBtn->setVisible(true); - m_ui->m_toggleDisplayViewBtn->setIcon(QIcon(":/Menu/menu.svg")); + m_ui->m_toggleDisplayViewBtn->setAutoRaise(true); + m_ui->m_toggleDisplayViewBtn->setIcon(QIcon(AzAssetBrowser::MenuIcon)); m_tableModel->setFilterRole(Qt::DisplayRole); m_tableModel->setSourceModel(m_filterModel.data()); diff --git a/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.ui b/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.ui index a345438aed..2cc7c57ccd 100644 --- a/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.ui +++ b/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.ui @@ -72,6 +72,22 @@ + + + + Qt::ClickFocus + + + + + + 3 + + + + + + @@ -143,15 +159,6 @@ true - - false - - - true - - - false - diff --git a/Code/Editor/CMakeLists.txt b/Code/Editor/CMakeLists.txt index 9d74f8e3a2..3f340e37d8 100644 --- a/Code/Editor/CMakeLists.txt +++ b/Code/Editor/CMakeLists.txt @@ -104,13 +104,11 @@ ly_add_target( 3rdParty::Qt::Concurrent 3rdParty::TIFF 3rdParty::squish-ccr - 3rdParty::AWSNativeSDK::STS Legacy::CryCommon Legacy::EditorCommon AZ::AzCore AZ::AzToolsFramework Gem::LmbrCentral.Static - AZ::AWSNativeSDKInit AZ::AtomCore Gem::Atom_RPI.Edit Gem::Atom_RPI.Public @@ -119,7 +117,6 @@ ly_add_target( Gem::AtomViewportDisplayInfo ${additional_dependencies} PUBLIC - 3rdParty::AWSNativeSDK::Core 3rdParty::Qt::Network Legacy::EditorCore RUNTIME_DEPENDENCIES diff --git a/Code/Editor/Controls/ReflectedPropertyControl/PropertyGenericCtrl.cpp b/Code/Editor/Controls/ReflectedPropertyControl/PropertyGenericCtrl.cpp index 8ff83dd894..9609fb5014 100644 --- a/Code/Editor/Controls/ReflectedPropertyControl/PropertyGenericCtrl.cpp +++ b/Code/Editor/Controls/ReflectedPropertyControl/PropertyGenericCtrl.cpp @@ -24,7 +24,6 @@ // Editor #include "SelectLightAnimationDialog.h" #include "SelectSequenceDialog.h" -#include "SelectEAXPresetDlg.h" #include "QtViewPaneManager.h" AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING diff --git a/Code/Editor/CrtDebug.cpp b/Code/Editor/CrtDebug.cpp deleted file mode 100644 index f9335373da..0000000000 --- a/Code/Editor/CrtDebug.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#include "EditorDefs.h" - - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -//#ifdef _CRTDBG_MAP_ALLOC -#ifdef CRTDBG_MAP_ALLOC -#pragma pack (push,1) -#define nNoMansLandSize 4 -typedef struct MyCrtMemBlockHeader -{ - struct MyCrtMemBlockHeader* pBlockHeaderNext; - struct MyCrtMemBlockHeader* pBlockHeaderPrev; - char* szFileName; - int nLine; - size_t nDataSize; - int nBlockUse; - long lRequest; - unsigned char gap[nNoMansLandSize]; - /* followed by: - * unsigned char data[nDataSize]; - * unsigned char anotherGap[nNoMansLandSize]; - */ -} MyCrtMemBlockHeader; -#pragma pack (pop) - -#define pbData(pblock) ((unsigned char*)((MyCrtMemBlockHeader*)pblock + 1)) -#define pHdr(pbData) (((MyCrtMemBlockHeader*)pbData) - 1) - - -void crtdebug(const char* s, ...) -{ - char str[32768]; - va_list arg_ptr; - va_start(arg_ptr, s); - vsprintf(str, s, arg_ptr); - va_end(arg_ptr); - - FILE* l = nullptr; - azfopen(&l, "crtdump.txt", "a+t"); - if (l) - { - fprintf(l, "%s", str); - fclose(l); - } -} - -int crtAllocHook(int nAllocType, void* pvData, - size_t nSize, int nBlockUse, long lRequest, - const unsigned char* szFileName, int nLine) -{ - if (nBlockUse == _CRT_BLOCK) - { - return TRUE; - } - - static int total_cnt = 0; - static int total_mem = 0; - if (nAllocType == _HOOK_ALLOC) - { - //total_mem += nSize; - //total_cnt++; - //_CrtMemState mem_state; - //_CrtMemCheckpoint( &mem_state ); - //total_cnt = mem_state.lCounts[_NORMAL_BLOCK]; - //total_mem = mem_state.lTotalCount; - if ((total_cnt & 0xF) == 0) - { - //_CrtCheckMemory(); - } - - total_cnt++; - total_mem += nSize; - - //crtdebug( " Alloc %d,size=%d,in: %s %d (total size=%d,num=%d)\n",lRequest,nSize,szFileName,nLine,total_mem,total_cnt ); - crtdebug("Size=%d, [Total=%d,N=%d] [%s:%d]\n", nSize, total_mem, total_cnt, szFileName, nLine); - } - else if (nAllocType == _HOOK_FREE) - { - MyCrtMemBlockHeader* pHead; - pHead = pHdr(pvData); - - total_cnt--; - total_mem -= pHead->nDataSize; - - crtdebug("Size=%d, [Total=%d,N=%d] [%s:%d]\n", pHead->nDataSize, total_mem, total_cnt, pHead->szFileName, pHead->nLine); - //crtdebug( " Free size=%d,in: %s %d (total size=%d,num=%d)\n",pHead->nDataSize,pHead->szFileName,pHead->nLine,total_mem,total_cnt ); - //total_mem -= nSize; - //total_cnt--; - } - return TRUE; -} - -int crtReportHook(int nRptType, char* szMsg, int* retVal) -{ - static int gl_num_asserts = 0; - if (gl_num_asserts != 0) - { - return TRUE; - } - gl_num_asserts++; - switch (nRptType) - { - case _CRT_WARN: - crtdebug(" %s\n", szMsg); - break; - case _CRT_ERROR: - crtdebug(" %s\n", szMsg); - break; - case _CRT_ASSERT: - crtdebug(" %s\n", szMsg); - break; - } - gl_num_asserts--; - return TRUE; -} - -void InitCrt() -{ - FILE* l = nullptr; - azfopen(&l, "crtdump.txt", "w"); - if (l) - { - fclose(l); - } - - //_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_DEBUG ); - //_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG ); - //_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_DEBUG ); - - _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_WNDW); - _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_WNDW); - _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_WNDW); - - //_CrtSetDbgFlag( _CRTDBG_CHECK_ALWAYS_DF|_CRTDBG_CHECK_CRT_DF|_CRTDBG_LEAK_CHECK_DF|_CRTDBG_DELAY_FREE_MEM_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) ); - //_CrtSetDbgFlag( _CRTDBG_CHECK_CRT_DF|_CRTDBG_LEAK_CHECK_DF/*|_CRTDBG_DELAY_FREE_MEM_DF*/ | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) ); - int flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); - flags &= ~_CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_CRT_DF; - - _CrtSetDbgFlag(flags); - - _CrtSetAllocHook (crtAllocHook); - _CrtSetReportHook(crtReportHook); -} - -void DoneCrt() -{ - //_CrtCheckMemory(); - //_CrtDumpMemoryLeaks(); -} - -// Autoinit CRT. -//struct __autoinit_crt { __autoinit_crt() { InitCrt(); }; ~__autoinit_crt() { DoneCrt(); } } __autoinit_crt_var; -#endif - - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// diff --git a/Code/Editor/CryEdit.cpp b/Code/Editor/CryEdit.cpp index 1c4e22b99e..805a22e880 100644 --- a/Code/Editor/CryEdit.cpp +++ b/Code/Editor/CryEdit.cpp @@ -36,14 +36,6 @@ AZ_POP_DISABLE_WARNING #include #include -// Aws Native SDK -#include -#include -#include -#include -#include -#include - // AzCore #include #include @@ -124,9 +116,6 @@ AZ_POP_DISABLE_WARNING #include "ScopedVariableSetter.h" #include "Util/3DConnexionDriver.h" - -#include "DimensionsDialog.h" - #include "Util/AutoDirectoryRestoreFileDialog.h" #include "Util/EditorAutoLevelLoadTest.h" #include "AboutDialog.h" @@ -147,9 +136,7 @@ AZ_POP_DISABLE_WARNING #include "Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.h" -// AWSNativeSDK #include -#include #if defined(AZ_PLATFORM_WINDOWS) @@ -1806,12 +1793,6 @@ bool CCryEditApp::InitInstance() InitLevel(cmdInfo); }); -#ifdef USE_WIP_FEATURES_MANAGER - // load the WIP features file - CWipFeatureManager::Instance()->EnableManager(!cmdInfo.m_bDeveloperMode); - CWipFeatureManager::Init(); -#endif - if (!m_bConsoleMode && !m_bPreviewMode) { GetIEditor()->UpdateViews(); @@ -2134,21 +2115,12 @@ bool CCryEditApp::FixDanglingSharedMemory(const QString& sharedMemName) const int CCryEditApp::ExitInstance(int exitCode) { - AZ_TracePrintf("Exit", "Called ExitInstance() with exit code: 0x%x", exitCode); - if (m_pEditor) { m_pEditor->OnBeginShutdownSequence(); } qobject_cast(qApp)->UnloadSettings(); - #ifdef USE_WIP_FEATURES_MANAGER - // - // close wip features manager - // - CWipFeatureManager::Shutdown(); - #endif - if (IsInRegularEditorMode()) { if (GetIEditor()) @@ -3379,6 +3351,10 @@ CCryEditDoc* CCryEditApp::OpenDocumentFile(const char* filename, bool addToMostR return GetIEditor()->GetDocument(); } + bool usePrefabSystemForLevels = false; + AzFramework::ApplicationRequests::Bus::BroadcastResult( + usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled); + // If we are loading and we're in simulate mode, then switch it off before we do anything else if (GetIEditor()->GetGameEngine() && GetIEditor()->GetGameEngine()->GetSimulationMode()) { @@ -3386,6 +3362,15 @@ CCryEditDoc* CCryEditApp::OpenDocumentFile(const char* filename, bool addToMostR bool bIsDocModified = GetIEditor()->GetDocument()->IsModified(); OnSwitchPhysics(); GetIEditor()->GetDocument()->SetModifiedFlag(bIsDocModified); + + if (usePrefabSystemForLevels) + { + auto* rootSpawnableInterface = AzFramework::RootSpawnableInterface::Get(); + if (rootSpawnableInterface) + { + rootSpawnableInterface->ProcessSpawnableQueue(); + } + } } // We're about to start loading a level, so start recording errors to display at the end. diff --git a/Code/Editor/CryEdit.h b/Code/Editor/CryEdit.h index 97fcde8f34..48f362003c 100644 --- a/Code/Editor/CryEdit.h +++ b/Code/Editor/CryEdit.h @@ -14,7 +14,6 @@ #if !defined(Q_MOC_RUN) #include #include -#include "WipFeatureManager.h" #include "CryEditDoc.h" #include "ViewPane.h" diff --git a/Code/Editor/CryEditDoc.cpp b/Code/Editor/CryEditDoc.cpp index 3bcba4d5e0..9d93fd5f5b 100644 --- a/Code/Editor/CryEditDoc.cpp +++ b/Code/Editor/CryEditDoc.cpp @@ -45,7 +45,6 @@ #include "ActionManager.h" #include "Include/IObjectManager.h" #include "ErrorReportDialog.h" -#include "SurfaceTypeValidator.h" #include "Util/AutoLogTime.h" #include "CheckOutDialog.h" #include "GameExporter.h" @@ -99,8 +98,7 @@ namespace Internal // CCryEditDoc construction/destruction CCryEditDoc::CCryEditDoc() - : doc_validate_surface_types(nullptr) - , m_modifiedModuleFlags(eModifiedNothing) + : m_modifiedModuleFlags(eModifiedNothing) { //////////////////////////////////////////////////////////////////////// // Set member variables to initial values @@ -120,7 +118,6 @@ CCryEditDoc::CCryEditDoc() GetIEditor()->SetDocument(this); CLogFile::WriteLine("Document created"); - RegisterConsoleVariables(); MainWindow::instance()->GetActionManager()->RegisterActionHandler(ID_FILE_SAVE_AS, this, &CCryEditDoc::OnFileSaveAs); bool isPrefabSystemEnabled = false; @@ -459,8 +456,6 @@ void CCryEditDoc::Load(TDocMultiArchive& arrXmlAr, const QString& szFilename) } } - CSurfaceTypeValidator().Validate(); - LogLoadTime(GetTickCount() - t0); // Loaded with success, remove event from log file GetIEditor()->GetSettingsManager()->UnregisterEvent(loadEvent); @@ -1910,25 +1905,6 @@ void CCryEditDoc::SetDocumentReady(bool bReady) m_bDocumentReady = bReady; } -void CCryEditDoc::RegisterConsoleVariables() -{ - doc_validate_surface_types = gEnv->pConsole->GetCVar("doc_validate_surface_types"); - - if (!doc_validate_surface_types) - { - doc_validate_surface_types = REGISTER_INT_CB("doc_validate_surface_types", 0, 0, - "Flag indicating whether icons are displayed on the animation graph.\n" - "Default is 1.\n", - OnValidateSurfaceTypesChanged); - } -} - -void CCryEditDoc::OnValidateSurfaceTypesChanged(ICVar*) -{ - CErrorsRecorder errorsRecorder(GetIEditor()); - CSurfaceTypeValidator().Validate(); -} - void CCryEditDoc::OnStartLevelResourceList() { // after loading another level we clear the RFOM_Level list, the first time the list should be empty diff --git a/Code/Editor/CryEditDoc.h b/Code/Editor/CryEditDoc.h index f7e97d308e..5d20bddf45 100644 --- a/Code/Editor/CryEditDoc.h +++ b/Code/Editor/CryEditDoc.h @@ -176,9 +176,7 @@ protected: virtual void OnFileSaveAs(); //! called immediately after saving the level. void AfterSave(); - void RegisterConsoleVariables(); void OnStartLevelResourceList(); - static void OnValidateSurfaceTypesChanged(ICVar*); QString GetCryIndexPath(const char* levelFilePath) const; @@ -194,7 +192,6 @@ protected: XmlNodeRef m_environmentTemplate; std::list m_listeners; bool m_bDocumentReady = false; - ICVar* doc_validate_surface_types = nullptr; int m_modifiedModuleFlags; // On construction, it assumes loaded levels have already been exported. Can be a big fat lie, though. // The right way would require us to save to the level folder the export status of the level. diff --git a/Code/Editor/CryEditLiveCreate.rc b/Code/Editor/CryEditLiveCreate.rc deleted file mode 100644 index 3dac96d682..0000000000 --- a/Code/Editor/CryEditLiveCreate.rc +++ /dev/null @@ -1,213 +0,0 @@ -ÿþ// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" -#include "resource.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\r\n" - "#include ""resource.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -IDR_MENU_LIVECREATE MENU -BEGIN - POPUP "&File" - BEGIN - MENUITEM "Save settings", ID_FILE_SAVESETTINGS - MENUITEM "Close", ID_FILE_CLOSE_LIVECREATE_VIEW - END - POPUP "&View" - BEGIN - MENUITEM "LiveCreate Logger", ID_VIEW_LIVECREATELOGGER, CHECKED - MENUITEM "LiveCreate Profile Editor", ID_VIEW_LIVECREATEPROFILEEDITOR, CHECKED - MENUITEM "LiveCreate File Sync Settings", ID_VIEW_LIVECREATEFILESYNCSETTINGS, CHECKED - END -END - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_LIVECREATE_PICKER DIALOGEX 0, 0, 316, 259 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Select game build directory" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - DEFPUSHBUTTON "OK",IDOK,200,238,50,14 - PUSHBUTTON "Cancel",IDCANCEL,259,238,50,14 - CONTROL "",IDC_DIRECTORY_TREE,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_SHOWSELALWAYS | WS_BORDER | WS_HSCROLL | WS_TABSTOP,7,7,302,227 -END - -IDD_LIVECREATE_ADD_TARGETS DIALOGEX 0, 0, 500, 400 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Discover LiveCreate targets" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - PUSHBUTTON "Refresh",IDC_REFRESH,8,8,70,18 - PUSHBUTTON "Add custom...",IDC_BUTTON_ADD_PEER,82,8,70,18 - CONTROL "Use wider search (broadcast)",IDC_CHECK_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,233,12,200,10 - CONTROL "",IDC_LIST_PEERS,"XTPReport",WS_TABSTOP,8,32,484,342,WS_EX_STATICEDGE - DEFPUSHBUTTON "Use selected",IDOK,180,379,70,18 - PUSHBUTTON "Cancel",IDCANCEL,259,379,70,18 - PUSHBUTTON "Add by IP...",IDC_BUTTON_ADD_MATERIAL,157,8,70,18 -END - -IDD_LIVECREATE_PEER_LIST DIALOGEX 0, 0, 395, 213 -STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_SYSMENU -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - LTEXT "Peers:",IDC_STATIC,17,27,22,8 - PUSHBUTTON "Add...",IDC_BUTTON_ADD_PEER,56,24,56,16 - PUSHBUTTON "Edit...",IDC_BUTTON_EDIT_PEER,116,24,56,16 - PUSHBUTTON "Remove",IDC_BUTTON_DELETE_PEER,176,24,52,16 - DEFPUSHBUTTON "Start All",IDC_BUTTON_START_ALL,4,4,48,16 - PUSHBUTTON "Reset All",IDC_BUTTON_RESET_ALL,176,4,52,16 - PUSHBUTTON "Force Sync All",IDC_BUTTON_FORCE_SYNC_ALL,56,4,56,16 - PUSHBUTTON "Clean All",IDC_BUTTON_CLEAN_ALL,232,4,52,16 - PUSHBUTTON "Screenshot All",IDC_BUTTON_SCREENSHOT_ALL,116,4,56,16 - CONTROL "",IDC_LIST_PEERS,"XTPReport",WS_TABSTOP,4,44,386,164,WS_EX_STATICEDGE - CHECKBOX "LiveCreate",IDC_BUTTON_ENABLE_LIVECREATE,288,4,52,36,BS_PUSHLIKE | BS_MULTILINE - CHECKBOX "Sync\nCamera",IDC_BUTTON_CAMERA_SYNC,345,4,52,36,BS_PUSHLIKE | BS_MULTILINE - PUSHBUTTON "Discover",IDC_BUTTON_DISCOVER_PEERS,232,24,52,16 -END - -IDD_IDD_LIVECREATE_SETTINGS_PANEL DIALOGEX 0, 0, 156, 204 -STYLE DS_SETFONT | WS_CHILD -FONT 8, "MS Shell Dlg 2", 400, 0, 0x1 -BEGIN - PUSHBUTTON "Add targets...",IDC_BUTTON_DISCOVER_PEERS,4,4,80,16 -END - -IDD_LIVECREATE_EDIT_CONNECTION DIALOGEX 0, 0, 288, 183 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "LiveCreate host settings" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - DEFPUSHBUTTON "OK",IDOK,158,154,58,20 - PUSHBUTTON "Cancel",IDCANCEL,221,154,58,20 - LTEXT "Name:",IDC_STATIC,16,46,22,8 - EDITTEXT IDC_EDIT_TARGET_NAME,44,44,100,14,ES_AUTOHSCROLL - LTEXT "IP:",IDC_STATIC,152,46,10,8 - CONTROL "",IDC_TARGET_IPADDRESS,"SysIPAddress32",WS_TABSTOP,168,44,100,15 - LTEXT "Platform:",IDC_STATIC,8,26,30,8 - LTEXT "Build path (automatic):",IDC_STATIC,19,120,74,8 - PUSHBUTTON "Test IP",IDC_BUTTON_TEST_CONNECTION,168,60,100,16 - COMBOBOX IDC_COMBO_PLATFORM,44,24,100,88,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Resovle name to IP",IDC_BUTTON_REFRESH_IP,44,60,100,16 - CONTROL "Enable this peer",IDC_CHECK_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,8,67,10 - GROUPBOX "Build settings",IDC_STATIC,7,80,272,71 - LTEXT "Build executable:",IDC_STATIC,19,92,56,8 - PUSHBUTTON "...",IDC_BUTTON_PICK_GAME_DIRECTORY,249,104,22,14 - EDITTEXT IDC_EDIT_BUILD_ROOT_PATH,20,104,226,14,ES_AUTOHSCROLL - EDITTEXT IDC_EDIT_BUILD_EXECUTABLE,20,131,249,14,ES_AUTOHSCROLL -END - -IDD_LIVECREATE_TASK_WAIT DIALOGEX 0, 0, 238, 41 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Dialog" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - PUSHBUTTON "Cancel",IDCANCEL,94,20,50,14 - LTEXT "Static",IDC_TASK_PROGRESS_TEXT,7,7,224,8 -END - -IDD_LIVECREATE_ADD_BY_IP DIALOGEX 0, 0, 137, 75 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Add LiveCreate by IP" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - DEFPUSHBUTTON "OK",IDOK,7,48,58,20 - PUSHBUTTON "Cancel",IDCANCEL,71,48,58,20 - LTEXT "IP:",-1,9,12,10,8 - EDITTEXT IDC_TARGET_IPADDRESS,25,10,100,15,WS_TABSTOP - PUSHBUTTON "Test IP",IDC_BUTTON_TEST_CONNECTION,25,27,100,16 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_LIVECREATE_ADD_TARGETS, DIALOG - BEGIN - END - - IDD_LIVECREATE_EDIT_CONNECTION, DIALOG - BEGIN - END - - IDD_LIVECREATE_TASK_WAIT, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 231 - TOPMARGIN, 7 - BOTTOMMARGIN, 34 - END - - IDD_LIVECREATE_ADD_BY_IP, DIALOG - BEGIN - END -END -#endif // APSTUDIO_INVOKED - -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED \ No newline at end of file diff --git a/Code/Editor/DimensionsDialog.cpp b/Code/Editor/DimensionsDialog.cpp deleted file mode 100644 index 6c8e6a616b..0000000000 --- a/Code/Editor/DimensionsDialog.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#include "EditorDefs.h" - -#include "DimensionsDialog.h" - -// Qt -#include - -AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING -#include -AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING - - - -///////////////////////////////////////////////////////////////////////////// -CDimensionsDialog::CDimensionsDialog(QWidget* pParent /*=nullptr*/) - : QDialog(pParent) - , m_group(new QButtonGroup(this)) - , ui(new Ui::CDimensionsDialog) -{ - ui->setupUi(this); - - setWindowTitle(tr("Generate Terrain Texture")); - - m_group->addButton(ui->Dim512, 512); - m_group->addButton(ui->Dim1024, 1024); - m_group->addButton(ui->Dim2048, 2048); - m_group->addButton(ui->Dim4096, 4096); - m_group->addButton(ui->Dim8192, 8192); - m_group->addButton(ui->Dim16384, 16384); -} - - -////////////////////////////////////////////////////////////////////////// -CDimensionsDialog::~CDimensionsDialog() -{ -} - -////////////////////////////////////////////////////////////////////////// -void CDimensionsDialog::SetDimensions(unsigned int iWidth) -{ - //////////////////////////////////////////////////////////////////////// - // Select a dimension option button in the dialog - //////////////////////////////////////////////////////////////////////// - - QAbstractButton* button = m_group->button(iWidth); - assert(button); - - button->setChecked(true); -} - -UINT CDimensionsDialog::GetDimensions() -{ - //////////////////////////////////////////////////////////////////////// - // Get the currently selected dimension option button in the dialog - //////////////////////////////////////////////////////////////////////// - - assert(m_group->checkedId() != -1); - - return m_group->checkedId(); -} - -#include diff --git a/Code/Editor/DimensionsDialog.h b/Code/Editor/DimensionsDialog.h deleted file mode 100644 index b94c58bf95..0000000000 --- a/Code/Editor/DimensionsDialog.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#pragma once -#ifndef CRYINCLUDE_EDITOR_DIMENSIONSDIALOG_H -#define CRYINCLUDE_EDITOR_DIMENSIONSDIALOG_H - -#if !defined(Q_MOC_RUN) -#include - -#include -#endif - -class QButtonGroup; - -namespace Ui { - class CDimensionsDialog; -} - -class CDimensionsDialog - : public QDialog -{ - Q_OBJECT - -public: - CDimensionsDialog(QWidget* pParent = nullptr); // standard constructor - ~CDimensionsDialog(); - - UINT GetDimensions(); - void SetDimensions(unsigned int iWidth); - -protected: - void UpdateData(bool fromUi = true); // DDX/DDV support - -private: - QButtonGroup* m_group; - - QScopedPointer ui; -}; - -#endif // CRYINCLUDE_EDITOR_DIMENSIONSDIALOG_H diff --git a/Code/Editor/DimensionsDialog.ui b/Code/Editor/DimensionsDialog.ui deleted file mode 100644 index 316a060c92..0000000000 --- a/Code/Editor/DimensionsDialog.ui +++ /dev/null @@ -1,120 +0,0 @@ - - - CDimensionsDialog - - - - 0 - 0 - 465 - 237 - - - - Qt::StrongFocus - - - - - - Texture Dimensions (Texture Dimensions divided by Terrain Size = Texels per meter) - - - - - - Qt::StrongFocus - - - 512 x 512 - - - true - - - - - - - Qt::StrongFocus - - - 1024 x 1024 - - - - - - - Qt::StrongFocus - - - 2048 x 2048 - - - - - - - Qt::StrongFocus - - - 4096 x 4096 - - - - - - - Qt::StrongFocus - - - 8192 x 8192 - - - - - - - Qt::StrongFocus - - - 16384 x 16384 - - - - - - - - - - Qt::StrongFocus - - - QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - CDimensionsDialog - accept() - - - 77 - 294 - - - 7 - 296 - - - - - diff --git a/Code/Editor/EditorPreferencesDialog.cpp b/Code/Editor/EditorPreferencesDialog.cpp index 665daf52a8..42f7446716 100644 --- a/Code/Editor/EditorPreferencesDialog.cpp +++ b/Code/Editor/EditorPreferencesDialog.cpp @@ -112,29 +112,31 @@ void EditorPreferencesDialog::showEvent(QShowEvent* event) QDialog::showEvent(event); } -void WidgetHandleKeyPressEvent(QWidget* widget, QKeyEvent* event) +bool WidgetConsumesKeyPressEvent(QKeyEvent* event) { // If the enter key is pressed during any text input, the dialog box will close // making it inconvenient to do multiple edits. This routine captures the // Key_Enter or Key_Return and clears the focus to give a visible cue that - // editing of that field has finished and then doesn't propogate it. + // editing of that field has finished and then doesn't propagate it. if (event->key() != Qt::Key::Key_Enter && event->key() != Qt::Key::Key_Return) { - QApplication::sendEvent(widget, event); + return false; } - else + + if (QWidget* editWidget = QApplication::focusWidget()) { - if (QWidget* editWidget = QApplication::focusWidget()) - { - editWidget->clearFocus(); - } + editWidget->clearFocus(); } -} + return true; +} void EditorPreferencesDialog::keyPressEvent(QKeyEvent* event) { - WidgetHandleKeyPressEvent(this, event); + if (!WidgetConsumesKeyPressEvent(event)) + { + QDialog::keyPressEvent(event); + } } void EditorPreferencesDialog::OnTreeCurrentItemChanged() diff --git a/Code/Editor/EditorPreferencesDialog.h b/Code/Editor/EditorPreferencesDialog.h index a3f05ad00d..70a186375b 100644 --- a/Code/Editor/EditorPreferencesDialog.h +++ b/Code/Editor/EditorPreferencesDialog.h @@ -19,7 +19,7 @@ namespace Ui class EditorPreferencesTreeWidgetItem; -void WidgetHandleKeyPressEvent(QWidget* widget, QKeyEvent* event); +bool WidgetConsumesKeyPressEvent(QKeyEvent* event); class EditorPreferencesDialog : public QDialog diff --git a/Code/Editor/EditorPreferencesPageAWS.cpp b/Code/Editor/EditorPreferencesPageAWS.cpp index 9279dce7bc..968969245d 100644 --- a/Code/Editor/EditorPreferencesPageAWS.cpp +++ b/Code/Editor/EditorPreferencesPageAWS.cpp @@ -101,7 +101,7 @@ void CEditorPreferencesPage_AWS::SaveSettingsRegistryFile() return; } - bool saved{}; + [[maybe_unused]] bool saved{}; constexpr auto configurationMode = AZ::IO::SystemFile::SF_OPEN_CREATE | AZ::IO::SystemFile::SF_OPEN_CREATE_PATH | AZ::IO::SystemFile::SF_OPEN_WRITE_ONLY; if (AZ::IO::SystemFile outputFile; outputFile.Open(resolvedPath.data(), configurationMode)) diff --git a/Code/Editor/EditorViewportWidget.cpp b/Code/Editor/EditorViewportWidget.cpp index e9a57dba4f..a8180bcace 100644 --- a/Code/Editor/EditorViewportWidget.cpp +++ b/Code/Editor/EditorViewportWidget.cpp @@ -582,11 +582,11 @@ void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event) case eNotify_OnCloseScene: m_renderViewport->SetScene(nullptr); - SetDefaultCamera(); break; case eNotify_OnEndSceneOpen: UpdateScene(); + SetDefaultCamera(); break; case eNotify_OnBeginNewScene: diff --git a/Code/Editor/GameEngine.cpp b/Code/Editor/GameEngine.cpp index db4c587f54..8aab168b6d 100644 --- a/Code/Editor/GameEngine.cpp +++ b/Code/Editor/GameEngine.cpp @@ -18,6 +18,7 @@ // AzCore #include #include +#include #include #include @@ -42,8 +43,6 @@ #include "ViewManager.h" #include "AnimationContext.h" -#include "UndoViewPosition.h" -#include "UndoViewRotation.h" #include "MainWindow.h" #include "Include/IObjectManager.h" #include "ActionManager.h" diff --git a/Code/Editor/IEditorImpl.cpp b/Code/Editor/IEditorImpl.cpp index 38006c6fca..a2712b653d 100644 --- a/Code/Editor/IEditorImpl.cpp +++ b/Code/Editor/IEditorImpl.cpp @@ -16,12 +16,6 @@ // Qt #include -// AWS Native SDK -AZ_PUSH_DISABLE_WARNING(4251 4355 4996, "-Wunknown-warning-option") -#include -#include -AZ_POP_DISABLE_WARNING - // AzCore #include #include @@ -78,9 +72,6 @@ AZ_POP_DISABLE_WARNING // EditorCommon #include -// AWSNativeSDK -#include - #include "Core/QtEditorApplication.h" // for Editor::EditorQtApplication static CCryEditDoc * theDocument; @@ -132,7 +123,6 @@ CEditorImpl::CEditorImpl() , m_pSettingsManager(nullptr) , m_pLevelIndependentFileMan(nullptr) , m_pExportManager(nullptr) - , m_awsResourceManager(nullptr) , m_bMatEditMode(false) , m_bShowStatusText(true) , m_bInitialized(false) diff --git a/Code/Editor/IEditorImpl.h b/Code/Editor/IEditorImpl.h index 7867912941..354f631507 100644 --- a/Code/Editor/IEditorImpl.h +++ b/Code/Editor/IEditorImpl.h @@ -369,7 +369,6 @@ protected: QString m_selectFileBuffer; QString m_levelNameBuffer; - IAWSResourceManager* m_awsResourceManager; std::unique_ptr m_winWidgetManager; //! True if the editor is in material edit mode. Fast preview of materials. diff --git a/Code/Editor/Include/SandboxAPI.h b/Code/Editor/Include/SandboxAPI.h index 4e0cafea4a..757b799837 100644 --- a/Code/Editor/Include/SandboxAPI.h +++ b/Code/Editor/Include/SandboxAPI.h @@ -21,7 +21,7 @@ #endif #if defined(SANDBOX_IMPORTS) && defined(SANDBOX_EXPORTS) -#error SANDBOX_EXPORTS and SANDBOX_IMPORTS can't be defined at the same time +#error SANDBOX_EXPORTS and SANDBOX_IMPORTS cannot be defined at the same time #endif #if defined(SANDBOX_EXPORTS) diff --git a/Code/Editor/Lib/Tests/test_ModularViewportCameraController.cpp b/Code/Editor/Lib/Tests/test_ModularViewportCameraController.cpp index 67d89ad967..5009c626e2 100644 --- a/Code/Editor/Lib/Tests/test_ModularViewportCameraController.cpp +++ b/Code/Editor/Lib/Tests/test_ModularViewportCameraController.cpp @@ -47,12 +47,12 @@ namespace UnitTest void ViewportMouseCursorRequestImpl::BeginCursorCapture() { - m_inputChannelMapper->SetCursorCaptureEnabled(true); + m_inputChannelMapper->SetCursorMode(AzToolsFramework::CursorInputMode::CursorModeCaptured); } void ViewportMouseCursorRequestImpl::EndCursorCapture() { - m_inputChannelMapper->SetCursorCaptureEnabled(false); + m_inputChannelMapper->SetCursorMode(AzToolsFramework::CursorInputMode::CursorModeNone); } bool ViewportMouseCursorRequestImpl::IsMouseOver() const diff --git a/Code/Editor/MainWindow.cpp b/Code/Editor/MainWindow.cpp index bbebac96a3..63841299be 100644 --- a/Code/Editor/MainWindow.cpp +++ b/Code/Editor/MainWindow.cpp @@ -11,11 +11,6 @@ #include -// AWs Native SDK -AZ_PUSH_DISABLE_WARNING(4251 4355 4996, "-Wunknown-warning-option") -#include -AZ_POP_DISABLE_WARNING - // Qt #include #include diff --git a/Code/Editor/MainWindow.qrc b/Code/Editor/MainWindow.qrc index c68e05ef41..57afc596bb 100644 --- a/Code/Editor/MainWindow.qrc +++ b/Code/Editor/MainWindow.qrc @@ -154,36 +154,6 @@ res/error_report_warning.svg res/error_report_comment.svg res/error_report_helper.svg - particles_tree_00.png - particles_tree_01.png - particles_tree_02.png - particles_tree_03.png - particles_tree_04.png - particles_tree_05.png - particles_tree_06.png - particles_tree_07.png - arhitype_tree_00.png - arhitype_tree_01.png - arhitype_tree_02.png - arhitype_tree_03.png - bmp00005_00.png - bmp00005_01.png - bmp00005_02.png - bmp00005_03.png - bmp00005_04.png - bmp00005_05.png - bmp00005_06.png - bmp00005_07.png - bmp00005_08.png - bmp00005_09.png - bmp00006_00.png - bmp00006_01.png - bmp00006_02.png - bmp00006_03.png - bmp00006_04.png - bmp00006_05.png - bmp00006_06.png - bmp00006_07.png res/arr_addkey.cur diff --git a/Code/Editor/NewLevelDialog.cpp b/Code/Editor/NewLevelDialog.cpp index a97eb30f57..b22d9dbaf3 100644 --- a/Code/Editor/NewLevelDialog.cpp +++ b/Code/Editor/NewLevelDialog.cpp @@ -18,9 +18,6 @@ #include #include -// Editor -#include "NewTerrainDialog.h" - AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING #include AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING diff --git a/Code/Editor/NewTerrainDialog.cpp b/Code/Editor/NewTerrainDialog.cpp deleted file mode 100644 index 0e66482eb4..0000000000 --- a/Code/Editor/NewTerrainDialog.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ -// NewTerrainDialog.cpp : implementation file -// - -#include "EditorDefs.h" - -#include "NewTerrainDialog.h" - - -AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") -#include -AZ_POP_DISABLE_WARNING - - - -CNewTerrainDialog::CNewTerrainDialog(QWidget* pParent /*=nullptr*/) - : QDialog(pParent) - , m_terrainResolutionIndex(0) - , m_terrainUnitsIndex(0) - , m_bUpdate(false) - , ui(new Ui::CNewTerrainDialog) - , m_initialized(false) -{ - ui->setupUi(this); - - setWindowTitle(tr("Terrain options")); - - // Default is 1024x1024, and m_terrainResolution holds an index to the combo box - m_terrainResolutionIndex = 3; - - connect(ui->TERRAIN_RESOLUTION, SIGNAL(activated(int)), this, SLOT(OnComboBoxSelectionTerrainResolution())); - connect(ui->TERRAIN_UNITS, SIGNAL(activated(int)), this, SLOT(OnComboBoxSelectionTerrainUnits())); -} - - -CNewTerrainDialog::~CNewTerrainDialog() -{ -} - - -void CNewTerrainDialog::UpdateData(bool fromUi) -{ - if (fromUi) - { - m_terrainResolutionIndex = ui->TERRAIN_RESOLUTION->currentIndex(); - m_terrainUnitsIndex = ui->TERRAIN_UNITS->currentIndex(); - } - else - { - ui->TERRAIN_RESOLUTION->setCurrentIndex(m_terrainResolutionIndex); - ui->TERRAIN_UNITS->setCurrentIndex(m_terrainUnitsIndex); - } -} - - -void CNewTerrainDialog::OnInitDialog() -{ - // Initialize terrain values. - int resolution = Ui::START_TERRAIN_RESOLUTION; - - // Fill terrain resolution combo box - for (int i = 0; i < 6; i++) - { - ui->TERRAIN_RESOLUTION->addItem(QString("%1x%1").arg(resolution)); - resolution *= 2; - } - - UpdateTerrainUnits(); - UpdateTerrainInfo(); - - // Save data. - UpdateData(false); -} - - -void CNewTerrainDialog::UpdateTerrainUnits() -{ - uint32 terrainRes = GetTerrainResolution(); - int size = terrainRes * GetTerrainUnits(); - int maxUnit = IntegerLog2(Ui::MAXIMUM_TERRAIN_RESOLUTION / terrainRes); - int units = Ui::START_TERRAIN_UNITS; - - ui->TERRAIN_UNITS->clear(); - for (int i = 0; i <= maxUnit; i++) - { - ui->TERRAIN_UNITS->addItem(QString::number(units)); - units *= 2; - } - if (size > Ui::MAXIMUM_TERRAIN_RESOLUTION) - { - m_terrainUnitsIndex = 0; - } - ui->TERRAIN_UNITS->setCurrentText(QString::number(m_terrainUnitsIndex)); -} - - -void CNewTerrainDialog::UpdateTerrainInfo() -{ - int sizeX = GetTerrainResolution() * GetTerrainUnits(); - int sizeY = GetTerrainResolution() * GetTerrainUnits(); - - QString str; - if (sizeX >= 1000) - { - str = tr("Terrain Size: %1 x %2 Kilometers").arg((float)sizeX / 1000.0f, 0, 'f', 3).arg((float)sizeY / 1000.0f, 0, 'f', 3); - } - else if (sizeX > 0) - { - str = tr("Terrain Size: %1 x %2 Meters").arg(sizeX).arg(sizeY); - } - else - { - str = tr("Level will have no terrain"); - } - - ui->TERRAIN_INFO->setText(str); -} - - -int CNewTerrainDialog::GetTerrainResolution() const -{ - // convert combo box index into resolution value - return Ui::START_TERRAIN_RESOLUTION * (1 << m_terrainResolutionIndex); -} - - -int CNewTerrainDialog::GetTerrainUnits() const -{ - // convert combo box index into units value - return Ui::START_TERRAIN_UNITS * (1 << m_terrainUnitsIndex); -} - - -void CNewTerrainDialog::OnComboBoxSelectionTerrainResolution() -{ - UpdateData(); - - UpdateTerrainUnits(); - - UpdateTerrainInfo(); -} - - -void CNewTerrainDialog::OnComboBoxSelectionTerrainUnits() -{ - UpdateData(); - - UpdateTerrainInfo(); -} - - -void CNewTerrainDialog::showEvent(QShowEvent* event) -{ - if (!m_initialized) - { - OnInitDialog(); - m_initialized = true; - } - QDialog::showEvent(event); -} - -#include diff --git a/Code/Editor/NewTerrainDialog.h b/Code/Editor/NewTerrainDialog.h deleted file mode 100644 index 8905a8c123..0000000000 --- a/Code/Editor/NewTerrainDialog.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ -#pragma once -#ifndef CRYINCLUDE_EDITOR_NEWTERRAINDIALOG_H -#define CRYINCLUDE_EDITOR_NEWTERRAINDIALOG_H - -#if !defined(Q_MOC_RUN) -#include - -#include - -#include -#endif - -namespace Ui -{ - class CNewTerrainDialog; - - enum TerrainDialogConstants - { - START_TERRAIN_RESOLUTION_POWER_OF_TWO = 7, - START_TERRAIN_RESOLUTION = 1 << START_TERRAIN_RESOLUTION_POWER_OF_TWO, - MAXIMUM_TERRAIN_POWER_OF_TWO = 16, - MAXIMUM_TERRAIN_RESOLUTION = 1 << MAXIMUM_TERRAIN_POWER_OF_TWO, - POWER_OFFSET = (MAXIMUM_TERRAIN_POWER_OF_TWO - START_TERRAIN_RESOLUTION_POWER_OF_TWO), - START_TERRAIN_UNITS = 1 - }; -} - -class CNewTerrainDialog - : public QDialog -{ - Q_OBJECT - -public: - CNewTerrainDialog(QWidget* pParent = nullptr); // standard constructor - ~CNewTerrainDialog(); - - int GetTerrainResolution() const; - int GetTerrainUnits() const; - - void IsResize(bool bIsResize); - - -protected: - void UpdateData(bool fromUi = true); - void OnInitDialog(); - - void UpdateTerrainUnits(); - void UpdateTerrainInfo(); - - void showEvent(QShowEvent* event) override; - -protected slots: - void OnComboBoxSelectionTerrainResolution(); - void OnComboBoxSelectionTerrainUnits(); - -public: - int m_terrainResolutionIndex; - int m_terrainUnitsIndex; - bool m_bUpdate; - - QScopedPointer ui; - bool m_initialized; -}; -#endif // CRYINCLUDE_EDITOR_NEWTERRAINDIALOG_H diff --git a/Code/Editor/NewTerrainDialog.ui b/Code/Editor/NewTerrainDialog.ui deleted file mode 100644 index 977db11918..0000000000 --- a/Code/Editor/NewTerrainDialog.ui +++ /dev/null @@ -1,112 +0,0 @@ - - - CNewTerrainDialog - - - - 0 - 0 - 292 - 160 - - - - false - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - QFormLayout::AllNonFixedFieldsGrow - - - - - Heightmap Resolution: - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - TERRAIN_RESOLUTION - - - - - - - - - - Meters Per Texel: - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - TERRAIN_UNITS - - - - - - - - - - Terrain Size: 32x32 Km - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - - - - - - buttonBox - accepted() - CNewTerrainDialog - accept() - - - 164 - 176 - - - 169 - 1 - - - - - buttonBox - rejected() - CNewTerrainDialog - reject() - - - 245 - 172 - - - 247 - -1 - - - - - diff --git a/Code/Editor/PakManagerDlg.qrc b/Code/Editor/PakManagerDlg.qrc deleted file mode 100644 index bea8f8aafd..0000000000 --- a/Code/Editor/PakManagerDlg.qrc +++ /dev/null @@ -1,6 +0,0 @@ - - - res/pakmanager_file.png - res/pakmanager_folder.png - - diff --git a/Code/Editor/PakManagerDlg.ui b/Code/Editor/PakManagerDlg.ui deleted file mode 100644 index 087e5379da..0000000000 --- a/Code/Editor/PakManagerDlg.ui +++ /dev/null @@ -1,202 +0,0 @@ - - - CPakManagerDlg - - - - 0 - 0 - 661 - 494 - - - - - - - - - - 0 - 45 - - - - Open PAK... - - - - - - - - 0 - 45 - - - - Create PAK... - - - - - - - - 0 - 45 - - - - Add files... - - - - - - - - 0 - 45 - - - - Add folder... - - - - - - - - 0 - 45 - - - - Extract... - - - - - - - - 0 - 45 - - - - Delete entries - - - - - - - - 0 - 45 - - - - &Close - - - - - - - - - - - Path: - - - - - - - - 0 - 0 - - - - QFrame::Panel - - - QFrame::Sunken - - - <none> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - - - QFrame::Box - - - Qt::ScrollBarAlwaysOn - - - QAbstractItemView::NoEditTriggers - - - QAbstractItemView::SelectItems - - - 120 - - - false - - - - Filename - - - - - Size - - - - - Modified - - - - - - - - Ready - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - Qt::AlignCenter - - - - - - - - - - diff --git a/Code/Editor/Platform/Common/GCC/editor_lib_gcc.cmake b/Code/Editor/Platform/Common/GCC/editor_lib_gcc.cmake new file mode 100644 index 0000000000..bc945f55c9 --- /dev/null +++ b/Code/Editor/Platform/Common/GCC/editor_lib_gcc.cmake @@ -0,0 +1,9 @@ +# +# 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 +# +# + +set(LY_COMPILE_OPTIONS PRIVATE -fexceptions) diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerListModel.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerListModel.cpp index 08d79adcf5..39be4839e6 100644 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerListModel.cpp +++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerListModel.cpp @@ -53,6 +53,7 @@ #include #include #include +#include #include "OutlinerDisplayOptionsMenu.h" #include "OutlinerSortFilterProxyModel.hxx" @@ -252,17 +253,7 @@ QVariant OutlinerListModel::dataForName(const QModelIndex& index, int role) cons if (s_paintingName && !m_filterString.empty()) { // highlight characters in filter - int highlightTextIndex = 0; - do - { - highlightTextIndex = label.lastIndexOf(QString(m_filterString.c_str()), highlightTextIndex - 1, Qt::CaseInsensitive); - if (highlightTextIndex >= 0) - { - const QString BACKGROUND_COLOR{ "#707070" }; - label.insert(static_cast(highlightTextIndex + m_filterString.length()), ""); - label.insert(highlightTextIndex, ""); - } - } while(highlightTextIndex > 0); + label = AzToolsFramework::RichTextHighlighter::HighlightText(label, m_filterString.c_str()); } return label; } @@ -2608,17 +2599,13 @@ void OutlinerItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& optionV4.text.clear(); optionV4.widget->style()->drawControl(QStyle::CE_ItemViewItem, &optionV4, painter); - // Now we setup a Text Document so it can draw the rich text - QTextDocument textDoc; - textDoc.setDefaultFont(optionV4.font); - textDoc.setDefaultStyleSheet("body {color: white}"); - textDoc.setHtml("" + entityNameRichText + ""); int verticalOffset = GetEntityNameVerticalOffset(entityId); - painter->translate(textRect.topLeft() + QPoint(0, verticalOffset)); - textDoc.setTextWidth(textRect.width()); - textDoc.drawContents(painter, QRectF(0, 0, textRect.width(), textRect.height())); + + AzToolsFramework::RichTextHighlighter::PaintHighlightedRichText( + entityNameRichText, painter, optionV4, textRect, QPoint(0, verticalOffset)); painter->restore(); + OutlinerListModel::s_paintingName = false; } else diff --git a/Code/Editor/SelectEAXPresetDlg.cpp b/Code/Editor/SelectEAXPresetDlg.cpp deleted file mode 100644 index 733de8b9cf..0000000000 --- a/Code/Editor/SelectEAXPresetDlg.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#include "EditorDefs.h" - -#include "SelectEAXPresetDlg.h" - -AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING -#include "ui_SelectEAXPresetDlg.h" -AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING - - -CSelectEAXPresetDlg::CSelectEAXPresetDlg(QWidget* pParent) - : QDialog(pParent) - , m_ui(new Ui_CSelectEAXPresetDlg) -{ - m_ui->setupUi(this); -} - -CSelectEAXPresetDlg::~CSelectEAXPresetDlg() -{ -} - -void CSelectEAXPresetDlg::SetCurrPreset(const QString& sPreset) -{ - QAbstractListModel* model = Model(); - if (!model) - { - return; - } - - QModelIndexList indexes = model->match(QModelIndex(), Qt::DisplayRole, sPreset, 1, Qt::MatchExactly); - - if (!indexes.isEmpty()) - { - m_ui->listView->setCurrentIndex(indexes.at(0)); - } -} - -QString CSelectEAXPresetDlg::GetCurrPreset() const -{ - if (m_ui->listView->currentIndex().isValid()) - { - return m_ui->listView->currentIndex().data().toString(); - } - // EXCEPTION: OCX Property Pages should return false - return QString(); -} - - -void CSelectEAXPresetDlg::SetModel(QAbstractListModel* model) -{ - m_ui->listView->setModel(model); -} - -QAbstractListModel* CSelectEAXPresetDlg::Model() const -{ - return static_cast(m_ui->listView->model()); -} - -#include "moc_SelectEAXPresetDlg.cpp" diff --git a/Code/Editor/SelectEAXPresetDlg.h b/Code/Editor/SelectEAXPresetDlg.h deleted file mode 100644 index 9943585987..0000000000 --- a/Code/Editor/SelectEAXPresetDlg.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#pragma once - -// CSelectEAXPresetDlg dialog -#ifndef CRYINCLUDE_EDITOR_SELECTEAXPRESETDLG_H -#define CRYINCLUDE_EDITOR_SELECTEAXPRESETDLG_H - -#if !defined(Q_MOC_RUN) -#include -#endif - -class QAbstractListModel; -class Ui_CSelectEAXPresetDlg; - -class CSelectEAXPresetDlg - : public QDialog -{ - Q_OBJECT - -public: - CSelectEAXPresetDlg(QWidget* pParent = nullptr); // standard constructor - ~CSelectEAXPresetDlg(); - - void SetCurrPreset(const QString& sPreset); - QString GetCurrPreset() const; - -protected: - void SetModel(QAbstractListModel* model); - QAbstractListModel* Model() const; - -private: - Ui_CSelectEAXPresetDlg* m_ui; -}; - -#endif // CRYINCLUDE_EDITOR_SELECTEAXPRESETDLG_H diff --git a/Code/Editor/SelectEAXPresetDlg.ui b/Code/Editor/SelectEAXPresetDlg.ui deleted file mode 100644 index 3177b66c38..0000000000 --- a/Code/Editor/SelectEAXPresetDlg.ui +++ /dev/null @@ -1,67 +0,0 @@ - - - CSelectEAXPresetDlg - - - - 0 - 0 - 197 - 233 - - - - Select Preset... - - - - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - listView - - - - - buttonBox - accepted() - CSelectEAXPresetDlg - accept() - - - 51 - 207 - - - 49 - 199 - - - - - buttonBox - rejected() - CSelectEAXPresetDlg - reject() - - - 148 - 213 - - - 131 - 199 - - - - - diff --git a/Code/Editor/Settings.cpp b/Code/Editor/Settings.cpp index 8561e6dba3..9514957795 100644 --- a/Code/Editor/Settings.cpp +++ b/Code/Editor/Settings.cpp @@ -1128,7 +1128,7 @@ void SEditorSettings::SaveSettingsRegistryFile() return; } - bool saved{}; + [[maybe_unused]] bool saved{}; constexpr auto configurationMode = AZ::IO::SystemFile::SF_OPEN_CREATE | AZ::IO::SystemFile::SF_OPEN_CREATE_PATH | AZ::IO::SystemFile::SF_OPEN_WRITE_ONLY; diff --git a/Code/Editor/SurfaceTypeValidator.cpp b/Code/Editor/SurfaceTypeValidator.cpp deleted file mode 100644 index 9f246cd453..0000000000 --- a/Code/Editor/SurfaceTypeValidator.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#include "EditorDefs.h" - -#include "SurfaceTypeValidator.h" - -// Editor -#include "Include/IObjectManager.h" -#include "Objects/BaseObject.h" -#include "ErrorReport.h" - - -void CSurfaceTypeValidator::Validate() -{ -} - diff --git a/Code/Editor/SurfaceTypeValidator.h b/Code/Editor/SurfaceTypeValidator.h deleted file mode 100644 index 6b1a3fbed7..0000000000 --- a/Code/Editor/SurfaceTypeValidator.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#ifndef CRYINCLUDE_EDITOR_SURFACETYPEVALIDATOR_H -#define CRYINCLUDE_EDITOR_SURFACETYPEVALIDATOR_H -#pragma once - - - -class CSurfaceTypeValidator -{ -public: - void Validate(); - -private: -}; - -#endif // CRYINCLUDE_EDITOR_SURFACETYPEVALIDATOR_H diff --git a/Code/Editor/TopRendererWnd.h b/Code/Editor/TopRendererWnd.h index c5bc7a31f2..7bdf2eaff2 100644 --- a/Code/Editor/TopRendererWnd.h +++ b/Code/Editor/TopRendererWnd.h @@ -81,8 +81,6 @@ public: bool m_bShowStatObjects; bool m_bShowWater; bool m_bAutoScaleGreyRange; - - friend class QTopRendererWnd; }; #endif // CRYINCLUDE_EDITOR_TOPRENDERERWND_H diff --git a/Code/Editor/UndoViewPosition.cpp b/Code/Editor/UndoViewPosition.cpp deleted file mode 100644 index 1934d255d3..0000000000 --- a/Code/Editor/UndoViewPosition.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -// Description : Undo for Python function (PySetCurrentViewPosition) - - -#include "EditorDefs.h" - -#include "UndoViewPosition.h" - -// Editor -#include "ViewManager.h" - -CUndoViewPosition::CUndoViewPosition(const QString& pUndoDescription) -{ - m_undoDescription = pUndoDescription; - - CViewport* pRenderViewport = GetIEditor()->GetViewManager()->GetGameViewport(); - if (pRenderViewport) - { - Matrix34 tm = pRenderViewport->GetViewTM(); - m_undo = tm.GetTranslation(); - } -} - -int CUndoViewPosition::GetSize() -{ - return sizeof(*this); -} - -QString CUndoViewPosition::GetDescription() -{ - return m_undoDescription; -} - -void CUndoViewPosition::Undo(bool bUndo) -{ - CViewport* pRenderViewport = GetIEditor()->GetViewManager()->GetGameViewport(); - if (pRenderViewport) - { - Matrix34 tm = pRenderViewport->GetViewTM(); - if (bUndo) - { - m_redo = tm.GetTranslation(); - } - - tm.SetTranslation(m_undo); - pRenderViewport->SetViewTM(tm); - } -} - -void CUndoViewPosition::Redo() -{ - CViewport* pRenderViewport = GetIEditor()->GetViewManager()->GetGameViewport(); - if (pRenderViewport) - { - Matrix34 tm = pRenderViewport->GetViewTM(); - tm.SetTranslation(m_redo); - pRenderViewport->SetViewTM(tm); - } -} diff --git a/Code/Editor/UndoViewPosition.h b/Code/Editor/UndoViewPosition.h deleted file mode 100644 index e0c6c145e8..0000000000 --- a/Code/Editor/UndoViewPosition.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -// Description : Undo for Python function (PySetCurrentViewPosition) - -#ifndef CRYINCLUDE_EDITOR_UNDOVIEWPOSITION_H -#define CRYINCLUDE_EDITOR_UNDOVIEWPOSITION_H -#pragma once - -#include "Undo/IUndoObject.h" - -class CUndoViewPosition - : public IUndoObject -{ -public: - CUndoViewPosition(const QString& pUndoDescription = "Set Current View Position"); - -protected: - int GetSize(); - QString GetDescription(); - void Undo(bool bUndo); - void Redo(); - -private: - Vec3 m_undo; - Vec3 m_redo; - QString m_undoDescription; -}; - -#endif // CRYINCLUDE_EDITOR_UNDOVIEWPOSITION_H diff --git a/Code/Editor/UndoViewRotation.cpp b/Code/Editor/UndoViewRotation.cpp deleted file mode 100644 index a305641d3b..0000000000 --- a/Code/Editor/UndoViewRotation.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -// Description : Undo for Python function (PySetCurrentViewPosition) - - -#include "EditorDefs.h" - -#include "UndoViewRotation.h" - -// Editor -#include "ViewManager.h" - -#include -#include -#include -#include - -Ang3 CUndoViewRotation::GetActiveCameraRotation() -{ - AZ::Transform activeCameraTm = AZ::Transform::CreateIdentity(); - Camera::ActiveCameraRequestBus::BroadcastResult( - activeCameraTm, - &Camera::ActiveCameraRequestBus::Events::GetActiveCameraTransform - ); - const AZ::Matrix3x4 cameraMatrix = AZ::Matrix3x4::CreateFromTransform(activeCameraTm); - const Matrix33 cameraMatrixCry = AZMatrix3x3ToLYMatrix3x3(AZ::Matrix3x3::CreateFromMatrix3x4(cameraMatrix)); - return RAD2DEG(Ang3::GetAnglesXYZ(cameraMatrixCry)); -} - -CUndoViewRotation::CUndoViewRotation(const QString& pUndoDescription) -{ - m_undoDescription = pUndoDescription; - m_undo = GetActiveCameraRotation(); -} - -int CUndoViewRotation::GetSize() -{ - return sizeof(*this); -} - -QString CUndoViewRotation::GetDescription() -{ - return m_undoDescription; -} - -void CUndoViewRotation::Undo(bool bUndo) -{ - CViewport* pRenderViewport = GetIEditor()->GetViewManager()->GetGameViewport(); - if (pRenderViewport) - { - if (bUndo) - { - m_redo = GetActiveCameraRotation(); - } - - Matrix34 tm = pRenderViewport->GetViewTM(); - tm.SetRotationXYZ(Ang3(DEG2RAD(m_undo.x), DEG2RAD(m_undo.y), DEG2RAD(m_undo.z)), tm.GetTranslation()); - pRenderViewport->SetViewTM(tm); - } -} - -void CUndoViewRotation::Redo() -{ - CViewport* pRenderViewport = GetIEditor()->GetViewManager()->GetGameViewport(); - if (pRenderViewport) - { - Matrix34 tm = pRenderViewport->GetViewTM(); - tm.SetRotationXYZ(Ang3(DEG2RAD(m_redo.x), DEG2RAD(m_redo.y), DEG2RAD(m_redo.z)), tm.GetTranslation()); - pRenderViewport->SetViewTM(tm); - } -} diff --git a/Code/Editor/UndoViewRotation.h b/Code/Editor/UndoViewRotation.h deleted file mode 100644 index 2e086a3f05..0000000000 --- a/Code/Editor/UndoViewRotation.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -// Description : Undo for Python function (PySetCurrentViewRotation) - - -#ifndef CRYINCLUDE_EDITOR_UNDOVIEWROTATION_H -#define CRYINCLUDE_EDITOR_UNDOVIEWROTATION_H -#pragma once -#include "Undo/IUndoObject.h" - - -class CUndoViewRotation - : public IUndoObject -{ -public: - CUndoViewRotation(const QString& pUndoDescription = "Set Current View Rotation"); - -protected: - int GetSize(); - QString GetDescription(); - void Undo(bool bUndo); - void Redo(); - -private: - static Ang3 GetActiveCameraRotation(); - - Ang3 m_undo; - Ang3 m_redo; - QString m_undoDescription; -}; - -#endif // CRYINCLUDE_EDITOR_UNDOVIEWROTATION_H diff --git a/Code/Editor/UserMessageDefines.h b/Code/Editor/UserMessageDefines.h deleted file mode 100644 index 0b13d2819f..0000000000 --- a/Code/Editor/UserMessageDefines.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#ifndef CRYINCLUDE_EDITOR_USERMESSAGEDEFINES_H -#define CRYINCLUDE_EDITOR_USERMESSAGEDEFINES_H -#pragma once - - -enum ESandboxUserMessages -{ - // InPlaceComboBox - WM_USER_ON_SELECTION_CANCEL = WM_USER + 1, - WM_USER_ON_SELECTION_OK, - WM_USER_ON_NEW_SELECTION, - WM_USER_ON_EDITCHANGE, - WM_USER_ON_OPENDROPDOWN, - WM_USER_ON_EDITKEYDOWN, - WM_USER_ON_EDITCLICK, - // ACListWnd - ENAC_UPDATE, - // EditWithButton - WM_USER_EDITWITHBUTTON_CLICKED, - // FillSliderCtrl - WMU_FS_CHANGED, - WMU_FS_LBUTTONDOWN, - WMU_FS_LBUTTONUP, - FLM_EDITTEXTCHANGED, - FLM_FILTERTEXTCHANGED, - // NumberCtrlEdit - WMU_LBUTTONDOWN, - WMU_LBUTTONUP, - WM_ONWINDOWFOCUSCHANGES, - // SelectObjectDialog - IDT_TIMER_0, - IDT_TIMER_1, - // LensFlareEditor - WM_FLAREEDITOR_UPDATETREECONTROL, - // EquipPackDialog - UM_EQUIPLIST_CHECKSTATECHANGE, - // MaterialSender/MatEditMainDlg - WM_MATEDITPICK, - // GridMapWindow - WM_USER_ON_DBL_CLICK, - // LMCompDialog - WM_UPDATE_LIGHTMAP_GENERATION_PROGRESS, - WM_UPDATE_LIGHTMAP_GENERATION_MEMUSAGE, - WM_UPDATE_LIGHTMAP_GENERATION_MEMUSAGE_STATIC, - WM_UPDATE_GLM_NAME_EDIT, - // Viewport - WM_VIEWPORT_ON_TITLE_CHANGE, - // VisualLogControls - UWM_BUTTON_CLICKED, -}; -#endif // CRYINCLUDE_EDITOR_USERMESSAGEDEFINES_H diff --git a/Code/Editor/ViewPane.cpp b/Code/Editor/ViewPane.cpp index 421db8394e..99b4c5a1cc 100644 --- a/Code/Editor/ViewPane.cpp +++ b/Code/Editor/ViewPane.cpp @@ -38,7 +38,6 @@ #include "Viewport.h" #include "LayoutConfigDialog.h" #include "TopRendererWnd.h" -#include "UserMessageDefines.h" #include "MainWindow.h" #include "QtViewPaneManager.h" #include "EditorViewportWidget.h" @@ -88,29 +87,15 @@ public: } // Handle labels with submenus - if (auto toolLabel = qobject_cast(toolWidget)) + if (auto toolLabel = qobject_cast(toolWidget)) { if (!toolLabel->isVisible()) { // Manually turn the custom context menus into submenus - if (toolLabel->objectName() == "m_fovStaticCtrl") + if (toolLabel->menu()) { - QAction* newAction = menu->addMenu(m_viewportDlg->GetFovMenu()); - newAction->setText(QString("FOV: %1").arg(toolLabel->text())); - } - else if (toolLabel->objectName() == "m_ratioStaticCtrl") - { - QAction* newAction = menu->addMenu(m_viewportDlg->GetAspectMenu()); - newAction->setText(QString("Ratio: %1").arg(toolLabel->text())); - } - else if (toolLabel->objectName() == "m_sizeStaticCtrl") - { - QAction* newAction = menu->addMenu(m_viewportDlg->GetResolutionMenu()); - newAction->setText(QString("%1").arg(toolLabel->text())); - } - else - { - // Don't add actions for other Labels + QAction* action = menu->addMenu(toolLabel->menu()); + action->setText(toolLabel->text()); continue; } } @@ -180,14 +165,25 @@ CLayoutViewPane::CLayoutViewPane(QWidget* parent) toolbar->installEventFilter(&m_viewportTitleDlg); toolbar->setContextMenuPolicy(Qt::CustomContextMenu); connect(toolbar, &QWidget::customContextMenuRequested, &m_viewportTitleDlg, &QWidget::customContextMenuRequested); - setContextMenuPolicy(Qt::NoContextMenu); - + if (QToolButton* expansion = AzQtComponents::ToolBar::getToolBarExpansionButton(toolbar)) { expansion->installEventFilter(m_expanderWatcher); } + AzQtComponents::BreadCrumbs* prefabsBreadcrumbs = + qobject_cast(toolbar->findChild("m_prefabFocusPath")); + QToolButton* backButton = qobject_cast(toolbar->findChild("m_prefabFocusBackButton")); + + AZ_Assert(prefabsBreadcrumbs, "Could not find Prefabs Breadcrumbs widget on CLayoutViewPane initialization!"); + AZ_Assert(backButton, "Could not find Prefabs Breadcrumbs back button on CLayoutViewPane initialization!"); + + if (prefabsBreadcrumbs && backButton) + { + m_viewportTitleDlg.InitializePrefabViewportFocusPathHandler(prefabsBreadcrumbs, backButton); + } + m_id = -1; } @@ -746,7 +742,7 @@ namespace void PySetActiveViewport(unsigned int viewportIndex) { - bool success = false; + [[maybe_unused]] bool success = false; CLayoutWnd* layout = GetIEditor()->GetViewManager()->GetLayout(); if (layout) { diff --git a/Code/Editor/ViewportTitleDlg.cpp b/Code/Editor/ViewportTitleDlg.cpp index 90aa044d25..bbd9eaaa10 100644 --- a/Code/Editor/ViewportTitleDlg.cpp +++ b/Code/Editor/ViewportTitleDlg.cpp @@ -383,12 +383,7 @@ void CViewportTitleDlg::OnInitDialog() bool isPrefabSystemEnabled = false; AzFramework::ApplicationRequests::Bus::BroadcastResult(isPrefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled); - if (isPrefabSystemEnabled) - { - m_prefabViewportFocusPathHandler = new AzToolsFramework::Prefab::PrefabViewportFocusPathHandler(); - m_prefabViewportFocusPathHandler->Initialize(m_ui->m_prefabFocusPath, m_ui->m_prefabFocusBackButton); - } - else + if (!isPrefabSystemEnabled) { m_ui->m_prefabFocusPath->setEnabled(false); m_ui->m_prefabFocusBackButton->setEnabled(false); @@ -397,6 +392,23 @@ void CViewportTitleDlg::OnInitDialog() } } +void CViewportTitleDlg::InitializePrefabViewportFocusPathHandler(AzQtComponents::BreadCrumbs* breadcrumbsWidget, QToolButton* backButton) +{ + if (m_prefabViewportFocusPathHandler != nullptr) + { + return; + } + + bool isPrefabSystemEnabled = false; + AzFramework::ApplicationRequests::Bus::BroadcastResult(isPrefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled); + + if (isPrefabSystemEnabled) + { + m_prefabViewportFocusPathHandler = new AzToolsFramework::Prefab::PrefabViewportFocusPathHandler(); + m_prefabViewportFocusPathHandler->Initialize(breadcrumbsWidget, backButton); + } +} + ////////////////////////////////////////////////////////////////////////// void CViewportTitleDlg::SetTitle(const QString& title) { diff --git a/Code/Editor/ViewportTitleDlg.h b/Code/Editor/ViewportTitleDlg.h index b8da7f20ea..8d8b06b96d 100644 --- a/Code/Editor/ViewportTitleDlg.h +++ b/Code/Editor/ViewportTitleDlg.h @@ -70,6 +70,8 @@ public: QMenu* const GetAspectMenu(); QMenu* const GetResolutionMenu(); + void InitializePrefabViewportFocusPathHandler(AzQtComponents::BreadCrumbs* breadcrumbsWidget, QToolButton* backButton); + Q_SIGNALS: void ActionTriggered(int command); diff --git a/Code/Editor/ViewportTitleDlg.ui b/Code/Editor/ViewportTitleDlg.ui index 7ba6361cf9..1711bdaf90 100644 --- a/Code/Editor/ViewportTitleDlg.ui +++ b/Code/Editor/ViewportTitleDlg.ui @@ -80,6 +80,9 @@ Camera settings + + Camera settings + :/Menu/camera.svg:/Menu/camera.svg @@ -91,6 +94,9 @@ Debug information + + Debug information + :/Menu/debug.svg:/Menu/debug.svg @@ -105,6 +111,9 @@ Toggle viewport helpers + + Toggle viewport helpers + :/Menu/helpers.svg:/Menu/helpers.svg @@ -119,6 +128,9 @@ Viewport resolution + + Viewport resolution + :/Menu/resolution.svg:/Menu/resolution.svg @@ -130,6 +142,9 @@ Other settings + + Other settings + :/Menu/menu.svg:/Menu/menu.svg diff --git a/Code/Editor/WipFeatureManager.cpp b/Code/Editor/WipFeatureManager.cpp deleted file mode 100644 index 4fb9ed1d93..0000000000 --- a/Code/Editor/WipFeatureManager.cpp +++ /dev/null @@ -1,454 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#include "EditorDefs.h" - -#include "WipFeatureManager.h" - -#ifdef USE_WIP_FEATURES_MANAGER -#include "WipFeaturesDlg.h" - -#if defined(AZ_PLATFORM_WINDOWS) -const char* CWipFeatureManager::kWipFeaturesFilename = "@user@\\Editor\\UI\\WipFeatures.xml"; -#else -const char* CWipFeatureManager::kWipFeaturesFilename = "@user@/Editor/UI/WipFeatures.xml"; -#endif -CWipFeatureManager* CWipFeatureManager::s_pInstance = nullptr; - -static void WipFeatureVarChange(ICVar* pVar) -{ - QString strParams = pVar->GetString(); - QStringList params; - - SplitString(strParams, params, ' '); - - if (strParams == "edit") - { - static CWipFeaturesDlg dlg; - - dlg.show(); - - return; - } - - if (params.size() >= 2) - { - QString featName = params[0].trimmed(); - QString attr = params[1].trimmed(); - - if (featName.isEmpty()) - { - return; - } - - int id = featName.toInt(); - - // if all features - if (featName == "*") - { - if (attr == "enable") - { - CWipFeatureManager::Instance()->EnableAllFeatures(true); - } - else - if (attr == "disable") - { - CWipFeatureManager::Instance()->EnableAllFeatures(false); - } - else - if (attr == "hide") - { - CWipFeatureManager::Instance()->ShowAllFeatures(false); - } - else - if (attr == "show") - { - CWipFeatureManager::Instance()->ShowAllFeatures(true); - } - else - if (attr == "safemode") - { - CWipFeatureManager::Instance()->SetAllFeaturesSafeMode(true); - } - else - if (attr == "fullmode") - { - CWipFeatureManager::Instance()->SetAllFeaturesSafeMode(false); - } - else - { - CWipFeatureManager::Instance()->SetAllFeaturesParams(attr.toUtf8().data()); - } - - return; - } - - if (attr == "enable") - { - CWipFeatureManager::Instance()->EnableFeature(id, true); - } - else - if (attr == "disable") - { - CWipFeatureManager::Instance()->EnableFeature(id, false); - } - else - if (attr == "hide") - { - CWipFeatureManager::Instance()->ShowFeature(id, false); - } - else - if (attr == "show") - { - CWipFeatureManager::Instance()->ShowFeature(id, true); - } - else - if (attr == "safemode") - { - CWipFeatureManager::Instance()->SetFeatureSafeMode(id, true); - } - else - if (attr == "fullmode") - { - CWipFeatureManager::Instance()->SetFeatureSafeMode(id, false); - } - else - { - CWipFeatureManager::Instance()->SetFeatureParams(id, attr.toUtf8().data()); - } - } -} - -CWipFeatureManager::CWipFeatureManager() -{ - m_bEnabled = true; -} - -CWipFeatureManager::~CWipFeatureManager() -{ -} - -bool CWipFeatureManager::Init(bool bLoadXml) -{ - if (!gEnv) - { - return false; - } - - IConsole* pConsole = gEnv->pConsole; - - if (!pConsole) - { - return false; - } - - REGISTER_CVAR2_CB("e_wipfeature", (const char**)&CWipFeatureManager::Instance()->m_consoleCmdParams, "", VF_ALWAYSONCHANGE | VF_CHEAT, "wipfeature enable|disable|hide|show|safemode|fullmode", WipFeatureVarChange); - - if (bLoadXml) - { - CWipFeatureManager::Instance()->Load(); - } - - return true; -} - -void CWipFeatureManager::Shutdown() -{ - CWipFeatureManager::Instance()->Save(); - delete s_pInstance; - s_pInstance = nullptr; -} - -bool CWipFeatureManager::Load(const char* pFilename, bool bClearExisting) -{ - if (!GetISystem()) - { - return false; - } - - XmlNodeRef root = GetISystem()->LoadXmlFromFile(pFilename); - - if (!root) - { - return false; - } - - if (bClearExisting) - { - m_features.clear(); - } - - Log("Loading WIP features file: '%s'...", pFilename); - - for (size_t i = 0, iCount = root->getChildCount(); i < iCount; ++i) - { - SWipFeatureInfo wf; - XmlNodeRef node = root->getChild(static_cast(i)); - XmlString str; - - node->getAttr("id", wf.m_id); - node->getAttr("displayName", str); - wf.m_displayName = str; - node->getAttr("visible", wf.m_bVisible); - node->getAttr("enabled", wf.m_bEnabled); - node->getAttr("safeMode", wf.m_bSafeMode); - node->getAttr("params", str); - wf.m_params = str; - wf.m_bLoadedFromXml = true; - - TWipFeatures::iterator iter = m_features.find(wf.m_id); - - if (iter == m_features.end()) - { - m_features[wf.m_id] = wf; - } - else - { - m_features[wf.m_id].m_bVisible = wf.m_bVisible; - m_features[wf.m_id].m_bEnabled = wf.m_bEnabled; - m_features[wf.m_id].m_bSafeMode = wf.m_bSafeMode; - m_features[wf.m_id].m_params = wf.m_params; - } - } - - Log("Loaded %d WIP features.", m_features.size()); - - return true; -} - -bool CWipFeatureManager::Save(const char* pFilename) -{ - if (!gEnv) - { - return false; - } - - if (!GetISystem()) - { - return false; - } - - ISystem* pISystem = GetISystem(); - - XmlNodeRef root = pISystem->CreateXmlNode("features"); - - for (TWipFeatures::iterator iter = m_features.begin(), iterEnd = m_features.end(); iter != iterEnd; ++iter) - { - SWipFeatureInfo& wf = iter->second; - XmlNodeRef node = root->createNode("feature"); - - node->setAttr("id", wf.m_id); - node->setAttr("displayName", wf.m_displayName.c_str()); - node->setAttr("visible", wf.m_bVisible); - node->setAttr("enabled", wf.m_bEnabled); - node->setAttr("safeMode", wf.m_bSafeMode); - node->setAttr("params", wf.m_params.c_str()); - - root->addChild(node); - } - - root->saveToFile(pFilename); - - return true; -} - -int CWipFeatureManager::RegisterFeature(const char* pDisplayName, bool bVisible, bool bEnabled, bool bSafeMode, const char* pParams, bool bSaveToXml) -{ - int aMaxId = -1; - - for (TWipFeatures::iterator iter = m_features.begin(), iterEnd = m_features.end(); iter != iterEnd; ++iter) - { - if (iter->first > aMaxId) - { - aMaxId = iter->first; - } - } - - ++aMaxId; - SetFeature(aMaxId, pDisplayName, bVisible, bEnabled, bSafeMode, pParams, bSaveToXml); - - return aMaxId; -} - -void CWipFeatureManager::SetFeature(int aFeatureId, const char* pDisplayName, bool bVisible, bool bEnabled, bool bSafeMode, const char* pParams, bool bSaveToXml) -{ - m_features[aFeatureId].m_id = aFeatureId; - m_features[aFeatureId].m_displayName = pDisplayName; - m_features[aFeatureId].m_bVisible = bVisible; - m_features[aFeatureId].m_bEnabled = bEnabled; - m_features[aFeatureId].m_bSafeMode = bSafeMode; - m_features[aFeatureId].m_bSaveToXml = bSaveToXml; - m_features[aFeatureId].m_params = pParams; - - if (m_features[aFeatureId].m_pfnUpdateFeature) - { - m_features[aFeatureId].m_pfnUpdateFeature(aFeatureId, &bVisible, &bEnabled, &bSafeMode, pParams); - } -} - -void CWipFeatureManager::SetDefaultFeatureStates(int aFeatureId, const char* pDisplayName, bool bVisible, bool bEnabled, bool bSafeMode, const char* pParams) -{ - TWipFeatures::iterator iter = m_features.find(aFeatureId); - - // set feature if not existing - if (iter == m_features.end() || (iter != m_features.end() && !iter->second.m_bLoadedFromXml)) - { - m_features[aFeatureId].m_id = aFeatureId; - m_features[aFeatureId].m_displayName = pDisplayName; - m_features[aFeatureId].m_bVisible = bVisible; - m_features[aFeatureId].m_bEnabled = bEnabled; - m_features[aFeatureId].m_bSafeMode = bSafeMode; - m_features[aFeatureId].m_params = pParams; - } - else - if (iter != m_features.end() && iter->second.m_bLoadedFromXml) - { - m_features[aFeatureId].m_id = aFeatureId; - m_features[aFeatureId].m_displayName = pDisplayName; - } - - if (m_features[aFeatureId].m_pfnUpdateFeature) - { - m_features[aFeatureId].m_pfnUpdateFeature(aFeatureId, &bVisible, &bEnabled, &bSafeMode, pParams); - } -} - -bool CWipFeatureManager::IsFeatureVisible(int aFeatureId) -{ - return m_features[aFeatureId].m_bVisible || !m_bEnabled; -} - -bool CWipFeatureManager::IsFeatureEnabled(int aFeatureId) -{ - return m_features[aFeatureId].m_bEnabled || !m_bEnabled; -} - -bool CWipFeatureManager::IsFeatureInSafeMode(int aFeatureId) -{ - if (!m_bEnabled) - { - return false; - } - - return m_features[aFeatureId].m_bSafeMode; -} - -const char* CWipFeatureManager::GetFeatureParams(int aFeatureId) -{ - return m_features[aFeatureId].m_params.c_str(); -} - -void CWipFeatureManager::ShowFeature(int aFeatureId, bool bShow) -{ - m_features[aFeatureId].m_bVisible = bShow; - - if (m_features[aFeatureId].m_pfnUpdateFeature) - { - m_features[aFeatureId].m_pfnUpdateFeature(aFeatureId, &bShow, nullptr, nullptr, nullptr); - } -} - -void CWipFeatureManager::EnableFeature(int aFeatureId, bool bEnable) -{ - m_features[aFeatureId].m_bEnabled = bEnable; - - if (m_features[aFeatureId].m_pfnUpdateFeature) - { - m_features[aFeatureId].m_pfnUpdateFeature(aFeatureId, nullptr, &bEnable, nullptr, nullptr); - } -} - -void CWipFeatureManager::SetFeatureSafeMode(int aFeatureId, bool bSafeMode) -{ - m_features[aFeatureId].m_bSafeMode = bSafeMode; - - if (m_features[aFeatureId].m_pfnUpdateFeature) - { - m_features[aFeatureId].m_pfnUpdateFeature(aFeatureId, nullptr, nullptr, &bSafeMode, nullptr); - } -} - -void CWipFeatureManager::SetFeatureParams(int aFeatureId, const char* pParams) -{ - m_features[aFeatureId].m_params = pParams; - - if (m_features[aFeatureId].m_pfnUpdateFeature) - { - m_features[aFeatureId].m_pfnUpdateFeature(aFeatureId, nullptr, nullptr, nullptr, pParams); - } -} - -void CWipFeatureManager::ShowAllFeatures(bool bShow) -{ - for (TWipFeatures::iterator iter = m_features.begin(), iterEnd = m_features.end(); iter != iterEnd; ++iter) - { - iter->second.m_bVisible = bShow; - - if (iter->second.m_pfnUpdateFeature) - { - iter->second.m_pfnUpdateFeature(iter->first, &bShow, nullptr, nullptr, nullptr); - } - } -} - -void CWipFeatureManager::EnableAllFeatures(bool bEnable) -{ - for (TWipFeatures::iterator iter = m_features.begin(), iterEnd = m_features.end(); iter != iterEnd; ++iter) - { - iter->second.m_bEnabled = bEnable; - - if (iter->second.m_pfnUpdateFeature) - { - iter->second.m_pfnUpdateFeature(iter->first, nullptr, &bEnable, nullptr, nullptr); - } - } -} - -void CWipFeatureManager::SetAllFeaturesSafeMode(bool bSafeMode) -{ - for (TWipFeatures::iterator iter = m_features.begin(), iterEnd = m_features.end(); iter != iterEnd; ++iter) - { - iter->second.m_bSafeMode = bSafeMode; - - if (iter->second.m_pfnUpdateFeature) - { - iter->second.m_pfnUpdateFeature(iter->first, nullptr, nullptr, &bSafeMode, nullptr); - } - } -} - -void CWipFeatureManager::SetAllFeaturesParams(const char* pParams) -{ - for (TWipFeatures::iterator iter = m_features.begin(), iterEnd = m_features.end(); iter != iterEnd; ++iter) - { - iter->second.m_params = pParams; - - if (iter->second.m_pfnUpdateFeature) - { - iter->second.m_pfnUpdateFeature(iter->first, nullptr, nullptr, nullptr, pParams); - } - } -} - -void CWipFeatureManager::EnableManager(bool bEnable) -{ - m_bEnabled = bEnable; -} - -void CWipFeatureManager::SetFeatureUpdateCallback(int aFeatureId, TWipFeatureUpdateCallback pfnUpdate) -{ - m_features[aFeatureId].m_pfnUpdateFeature = pfnUpdate; -} - -AZStd::map& CWipFeatureManager::GetFeatures() -{ - return m_features; -} - -#endif diff --git a/Code/Editor/WipFeatureManager.h b/Code/Editor/WipFeatureManager.h deleted file mode 100644 index cd20f6d591..0000000000 --- a/Code/Editor/WipFeatureManager.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#ifndef CRYINCLUDE_EDITOR_WIPFEATUREMANAGER_H -#define CRYINCLUDE_EDITOR_WIPFEATUREMANAGER_H -#pragma once - -#include -#include - -/* - This class is used to control work in progress features at runtime, so QA can test even if the end user will not see those features - You can use the console command: e_wipfeature enable|disable|hide|show|safemode|fullmode - ****************************************************************************************************************************************** - *** GOOD TO KNOW: "e_wipfeature edit" console command will display the WIP dialog and you can control the features from there - ****************************************************************************************************************************************** -*/ - -// undef this define to spot all wip feature usages within the editor at compile time -#define USE_WIP_FEATURES_MANAGER - -#ifdef USE_WIP_FEATURES_MANAGER - -// use this to register new wip features, usage from inside functions -// @param id is the numeric unique id of the feature, its good to have all feature ids in an enum in one file -// @param bVisible is the feature visible by default -// @param bEnabled is the feature enabled (usually visual enable like non-grayed) by default -// @param bSafeMode is the feature operating in some sort of safe mode (the safe mode behavior defined by the feature itself) -// @param pTWipFeatureUpdateCallback callback of type TWipFeatureUpdateCallback for when a feature state (visible,enabled and so on) was modified -#define REGISTER_WIP_FEATURE(id, bVisible, bEnabled, bSafeMode, pTWipFeatureUpdateCallback) \ - static CWipFeatureManager::CWipFeatureRegisterer s_wipFeatureRegisterer_##id(id, ""#id, bVisible, bEnabled, bSafeMode, pTWipFeatureUpdateCallback); - -#define IS_WIP_FEATURE_VISIBLE(id) CWipFeatureManager::Instance()->IsFeatureVisible(id) -#define IS_WIP_FEATURE_ENABLED(id) CWipFeatureManager::Instance()->IsFeatureEnabled(id) -#define IS_WIP_FEATURE_SAFEMODE(id) CWipFeatureManager::Instance()->IsFeatureInSafeMode(id) - -// The feature manager singleton itself -class CWipFeatureManager -{ -public: - - static const char* kWipFeaturesFilename; - - // Used to register a callback function to update the state of features whitin the editor - // pbVisible, pbEnabled, pbSafeMode, pParams - if the pointer is nullptr, then that attribute was not changed - typedef void (* TWipFeatureUpdateCallback)(int aFeatureId, const bool* const pbVisible, const bool* const pbEnabled, const bool* const pbSafeMode, const char* pParams); - - // wip feature registerer auto create object, used for static auto feature creation with the REGISTER_WIP_FEATURE macro - class CWipFeatureRegisterer - { - public: - - CWipFeatureRegisterer(int id, const char* pDisplayName, bool bVisible, bool bEnabled, bool bSafeMode, TWipFeatureUpdateCallback pTWipFeatureUpdateCallback) - { - CWipFeatureManager::Instance()->SetFeatureUpdateCallback(id, pTWipFeatureUpdateCallback); - CWipFeatureManager::Instance()->SetDefaultFeatureStates(id, pDisplayName, bVisible, bEnabled, bSafeMode); - } - }; - - struct SWipFeatureInfo - { - SWipFeatureInfo() - : m_id(0) - , m_displayName("") - , m_bVisible(true) - , m_bEnabled(true) - , m_bSafeMode(false) - , m_pfnUpdateFeature(nullptr) - , m_bLoadedFromXml(false) - {} - - int m_id; - AZStd::string m_displayName, m_params; - bool m_bVisible, m_bEnabled, m_bSafeMode, - // if true, this feature will be saved into the xml file when Save(...) will be called - m_bSaveToXml, m_bLoadedFromXml; - TWipFeatureUpdateCallback m_pfnUpdateFeature; - }; - - typedef AZStd::map TWipFeatures; - -private: - - CWipFeatureManager(); - ~CWipFeatureManager(); - - static CWipFeatureManager* s_pInstance; - -public: - - static CWipFeatureManager* Instance() - { - if (!s_pInstance) - { - s_pInstance = new CWipFeatureManager(); - AZ_Assert(s_pInstance, "Could not construct CWipFeatureManager"); - } - - return s_pInstance; - } - - static bool Init(bool bLoadXml = true); - static void Shutdown(); - - bool Load(const char* pFilename = kWipFeaturesFilename, bool bClearExisting = true); - bool Save(const char* pFilename = kWipFeaturesFilename); - - // Register a new feature - // @return a new feature ID - int RegisterFeature(const char* pDisplayName, bool bVisible, bool bEnabled, bool bSafeMode, const char* pParams = "", bool bSaveToXml = true); - // Set an existing feature - void SetFeature(int aFeatureId, const char* pDisplayName, bool bVisible, bool bEnabled, bool bSafeMode, const char* pParams = "", bool bSaveToXml = true); - // Create a new feature, but it will take into account the existing feature info from the loaded XML file, with persistent settings, if any - void SetDefaultFeatureStates(int aFeatureId, const char* pDisplayName, bool bVisible, bool bEnabled, bool bSafeMode, const char* pParams = ""); - bool IsFeatureVisible(int aFeatureId); - bool IsFeatureEnabled(int aFeatureId); - bool IsFeatureInSafeMode(int aFeatureId); - const char* GetFeatureParams(int aFeatureId); - - void ShowFeature(int aFeatureId, bool bShow = true); - void EnableFeature(int aFeatureId, bool bEnable = true); - void SetFeatureSafeMode(int aFeatureId, bool bSafeMode); - void SetFeatureParams(int aFeatureId, const char* pParams); - - void ShowAllFeatures(bool bShow = true); - void EnableAllFeatures(bool bEnable = true); - void SetAllFeaturesSafeMode(bool bSafeMode); - void SetAllFeaturesParams(const char* pParams); - - // if manager is disabled, then all queries about feature enable/visible/fullmode states will return true always - void EnableManager(bool bEnable = true); - - void SetFeatureUpdateCallback(int aFeatureId, TWipFeatureUpdateCallback pfnUpdate); - TWipFeatures& GetFeatures(); - -private: - - static const int kMaxWipCmdSize = 200; - - TWipFeatures m_features; - char m_consoleCmdParams[kMaxWipCmdSize]; - bool m_bEnabled; -}; - -#else - -// -// no WIP feature manager in production build -// -#define REGISTER_WIP_FEATURE -#define IS_WIP_FEATURE_VISIBLE(id) true -#define IS_WIP_FEATURE_ENABLED(id) true -#define IS_WIP_FEATURE_SAFEMODE(id) true - -#endif //USE_WIP_FEATURES_MANAGER -#endif // CRYINCLUDE_EDITOR_WIPFEATUREMANAGER_H diff --git a/Code/Editor/WipFeaturesDlg.cpp b/Code/Editor/WipFeaturesDlg.cpp deleted file mode 100644 index bc4372d7fb..0000000000 --- a/Code/Editor/WipFeaturesDlg.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#include "EditorDefs.h" - -#include "WipFeatureManager.h" - -#include "WipFeaturesDlg.h" - -// Qt -#include - -AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING -#include "ui_WipFeaturesDlg.h" -AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING - -#ifdef USE_WIP_FEATURES_MANAGER - -// CWipFeaturesDlg dialog - -class WipFeaturesModel - : public QAbstractTableModel -{ -public: - WipFeaturesModel(QObject* parent = nullptr) - : QAbstractTableModel(parent) - { - } - - int rowCount(const QModelIndex& parent = QModelIndex()) const override - { - return parent.isValid() ? 0 : static_cast(CWipFeatureManager::Instance()->GetFeatures().size()); - } - - int columnCount(const QModelIndex& parent = QModelIndex()) const override - { - return parent.isValid() ? 0 : 5; - } - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override - { - if (orientation != Qt::Horizontal || section >= columnCount()) - { - return QVariant(); - } - - - switch (role) - { - case Qt::TextAlignmentRole: - return section == 0 ? Qt::AlignLeft : Qt::AlignCenter; - case Qt::DisplayRole: - switch (section) - { - case 0: - return tr("Name"); - case 1: - return tr("Id"); - case 2: - return tr("Visible"); - case 3: - return tr("Enabled"); - case 4: - return tr("SafeMode"); - default: - return QVariant(); - } - default: - return QVariant(); - } - } - - bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override - { - if (!index.isValid() || index.column() >= columnCount(index.parent()) || index.row() >= rowCount(index.parent())) - { - return false; - } - - if (role != Qt::EditRole || !value.canConvert()) - { - return false; - } - - auto it = CWipFeatureManager::Instance()->GetFeatures().begin(); - std::advance(it, index.row()); - - auto id = it->first; - - switch (index.column()) - { - case 2: - CWipFeatureManager::Instance()->ShowFeature(id, value.toBool()); - break; - case 3: - CWipFeatureManager::Instance()->EnableFeature(id, value.toBool()); - break; - case 4: - CWipFeatureManager::Instance()->SetFeatureSafeMode(id, value.toBool()); - break; - default: - return false; - } - - emit dataChanged(index, index); - return true; - } - - QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override - { - if (!index.isValid() || index.column() >= columnCount(index.parent()) || index.row() >= rowCount(index.parent())) - { - return QVariant(); - } - - if (role == Qt::TextAlignmentRole) - { - return headerData(index.column(), Qt::Horizontal, role); - } - - if (role != Qt::DisplayRole) - { - return QVariant(); - } - - auto it = CWipFeatureManager::Instance()->GetFeatures().begin(); - std::advance(it, index.row()); - - auto feature = it->second; - - switch (index.column()) - { - case 0: - return QString(feature.m_displayName.c_str()); - case 1: - return feature.m_id; - case 2: - return feature.m_bVisible ? tr("X") : QString(); - case 3: - return feature.m_bEnabled ? tr("X") : QString(); - case 4: - return feature.m_bSafeMode ? tr("X") : QString(); - default: - return QVariant(); - } - } -}; - -CWipFeaturesDlg::CWipFeaturesDlg(QWidget* pParent /*=nullptr*/) - : QDialog(pParent) - , m_ui(new Ui::WipFeaturesDlg) -{ - m_ui->setupUi(this); - setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); - setFixedSize(size()); - - OnInitDialog(); - - connect(m_ui->buttonShow, &QPushButton::clicked, this, &CWipFeaturesDlg::OnBnClickedButtonShow); - connect(m_ui->buttonHide, &QPushButton::clicked, this, &CWipFeaturesDlg::OnBnClickedButtonHide); - connect(m_ui->buttonEnable, &QPushButton::clicked, this, &CWipFeaturesDlg::OnBnClickedButtonEnable); - connect(m_ui->buttonDisable, &QPushButton::clicked, this, &CWipFeaturesDlg::OnBnClickedButtonDisable); - connect(m_ui->buttonSafeMode, &QPushButton::clicked, this, &CWipFeaturesDlg::OnBnClickedButtonSafemode); - connect(m_ui->buttonNormalMode, &QPushButton::clicked, this, &CWipFeaturesDlg::OnBnClickedButtonNormalmode); -} - -CWipFeaturesDlg::~CWipFeaturesDlg() -{ -} - -// CWipFeaturesDlg message handlers - -void CWipFeaturesDlg::OnInitDialog() -{ - m_ui->m_lstFeatures->setModel(new WipFeaturesModel(this)); - m_ui->m_lstFeatures->horizontalHeader()->resizeSection(0, 300); - m_ui->m_lstFeatures->horizontalHeader()->resizeSection(1, 70); - m_ui->m_lstFeatures->horizontalHeader()->resizeSection(2, 70); - m_ui->m_lstFeatures->horizontalHeader()->resizeSection(3, 70); - m_ui->m_lstFeatures->horizontalHeader()->resizeSection(4, 70); -} - -void CWipFeaturesDlg::OnBnClickedButtonShow() -{ - for (auto index : m_ui->m_lstFeatures->selectionModel()->selectedRows()) - { - m_ui->m_lstFeatures->model()->setData(index.sibling(index.row(), 2), true); - } -} - -void CWipFeaturesDlg::OnBnClickedButtonHide() -{ - for (auto index : m_ui->m_lstFeatures->selectionModel()->selectedRows()) - { - m_ui->m_lstFeatures->model()->setData(index.sibling(index.row(), 2), false); - } -} - -void CWipFeaturesDlg::OnBnClickedButtonEnable() -{ - for (auto index : m_ui->m_lstFeatures->selectionModel()->selectedRows()) - { - m_ui->m_lstFeatures->model()->setData(index.sibling(index.row(), 3), true); - } -} - -void CWipFeaturesDlg::OnBnClickedButtonDisable() -{ - for (auto index : m_ui->m_lstFeatures->selectionModel()->selectedRows()) - { - m_ui->m_lstFeatures->model()->setData(index.sibling(index.row(), 3), false); - } -} - -void CWipFeaturesDlg::OnBnClickedButtonSafemode() -{ - for (auto index : m_ui->m_lstFeatures->selectionModel()->selectedRows()) - { - m_ui->m_lstFeatures->model()->setData(index.sibling(index.row(), 4), true); - } -} - -void CWipFeaturesDlg::OnBnClickedButtonNormalmode() -{ - for (auto index : m_ui->m_lstFeatures->selectionModel()->selectedRows()) - { - m_ui->m_lstFeatures->model()->setData(index.sibling(index.row(), 4), false); - } -} - -#include - -#endif // USE_WIP_FEATURES_MANAGER diff --git a/Code/Editor/WipFeaturesDlg.h b/Code/Editor/WipFeaturesDlg.h deleted file mode 100644 index 28f4f43958..0000000000 --- a/Code/Editor/WipFeaturesDlg.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#pragma once -#ifndef CRYINCLUDE_EDITOR_WIPFEATURESDLG_H -#define CRYINCLUDE_EDITOR_WIPFEATURESDLG_H - -#if !defined(Q_MOC_RUN) -#include -#endif - -#ifdef USE_WIP_FEATURES_MANAGER - -// CWipFeaturesDlg dialog - -namespace Ui -{ - class WipFeaturesDlg; -} - -class CWipFeaturesDlg - : public QDialog -{ - Q_OBJECT -public: - CWipFeaturesDlg(QWidget* pParent = nullptr); // standard constructor - virtual ~CWipFeaturesDlg(); - -private: - void OnInitDialog(); - void OnBnClickedButtonShow(); - void OnBnClickedButtonHide(); - void OnBnClickedButtonEnable(); - void OnBnClickedButtonDisable(); - void OnBnClickedButtonSafemode(); - void OnBnClickedButtonNormalmode(); - -private: - QScopedPointer m_ui; -}; - -#else - -class CWipFeaturesDlg - : public QDialog -{ - Q_OBJECT -}; - -#endif // USE_WIP_FEATURES_MANAGER - -#endif // CRYINCLUDE_EDITOR_WIPFEATURESDLG_H diff --git a/Code/Editor/WipFeaturesDlg.qrc b/Code/Editor/WipFeaturesDlg.qrc deleted file mode 100644 index 1205b1063e..0000000000 --- a/Code/Editor/WipFeaturesDlg.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - res/work_in_progress_icon.png - - diff --git a/Code/Editor/WipFeaturesDlg.ui b/Code/Editor/WipFeaturesDlg.ui deleted file mode 100644 index b4bf95e2c5..0000000000 --- a/Code/Editor/WipFeaturesDlg.ui +++ /dev/null @@ -1,184 +0,0 @@ - - - WipFeaturesDlg - - - - 0 - 0 - 620 - 342 - - - - Work in Progress Features - - - - - - Work in progress features: - - - - - - Qt::ScrollBarAlwaysOff - - - QAbstractItemView::SelectRows - - - true - - - false - - - 19 - - - - - - - Show - - - - - - - Hide - - - - - - - Qt::Horizontal - - - QSizePolicy::Ignored - - - - 74 - 20 - - - - - - - - Enable - - - - - - - Disable - - - - - - - Qt::Horizontal - - - QSizePolicy::Ignored - - - - 74 - 20 - - - - - - - - Normal Mode - - - - - - - Safe Mode - - - - - - - - - - - 64 - 64 - - - - - 64 - 64 - - - - :/res/work_in_progress_icon.png - - - - - - - - 0 - 0 - - - - NOTE:<br/>The states of the WIP features will be saved in the Editor/UI/WipFeatures.xml file when the editor exits successfuly - - - true - - - - - - - QDialogButtonBox::Close - - - - - - - - - - - buttonBox - rejected() - WipFeaturesDlg - close() - - - 647 - 339 - - - 674 - 314 - - - - - diff --git a/Code/Editor/arhitype_tree_00.png b/Code/Editor/arhitype_tree_00.png deleted file mode 100644 index 274b2b0667..0000000000 --- a/Code/Editor/arhitype_tree_00.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b9cc3783ba8ccc940e89039455f2a8617a67520400ce74c9ce4c3d16d942ead8 -size 208 diff --git a/Code/Editor/arhitype_tree_01.png b/Code/Editor/arhitype_tree_01.png deleted file mode 100644 index 274b2b0667..0000000000 --- a/Code/Editor/arhitype_tree_01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b9cc3783ba8ccc940e89039455f2a8617a67520400ce74c9ce4c3d16d942ead8 -size 208 diff --git a/Code/Editor/arhitype_tree_02.png b/Code/Editor/arhitype_tree_02.png deleted file mode 100644 index f29a502de1..0000000000 --- a/Code/Editor/arhitype_tree_02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1f8b26d30e8c00514648cf72bb80fe8be3f665eb7473b6565b31a4b078816bfd -size 208 diff --git a/Code/Editor/arhitype_tree_03.png b/Code/Editor/arhitype_tree_03.png deleted file mode 100644 index f29a502de1..0000000000 --- a/Code/Editor/arhitype_tree_03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1f8b26d30e8c00514648cf72bb80fe8be3f665eb7473b6565b31a4b078816bfd -size 208 diff --git a/Code/Editor/bmp00005_00.png b/Code/Editor/bmp00005_00.png deleted file mode 100644 index 345abfaf01..0000000000 --- a/Code/Editor/bmp00005_00.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5e4a0284f8d3b2625c3f27d6505b19a0babb7af0825f08b4e08f40e647d10873 -size 388 diff --git a/Code/Editor/bmp00005_01.png b/Code/Editor/bmp00005_01.png deleted file mode 100644 index abeba83277..0000000000 --- a/Code/Editor/bmp00005_01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:43f64ba8198c197f2dd91f00947df808fa41274411934d3d1f81e3eb44f78e7a -size 532 diff --git a/Code/Editor/bmp00005_02.png b/Code/Editor/bmp00005_02.png deleted file mode 100644 index 45439597e2..0000000000 --- a/Code/Editor/bmp00005_02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:556929870bb8c26fe8ebf4e94536e74c2eb1084e6f566007ec3a5f2e6303fa53 -size 392 diff --git a/Code/Editor/bmp00005_03.png b/Code/Editor/bmp00005_03.png deleted file mode 100644 index b67ec062ff..0000000000 --- a/Code/Editor/bmp00005_03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:239843fcd5a08e260106ee6eb3f69d3606321267e94df1e64ab25573d14980e1 -size 486 diff --git a/Code/Editor/bmp00005_04.png b/Code/Editor/bmp00005_04.png deleted file mode 100644 index 565730be66..0000000000 --- a/Code/Editor/bmp00005_04.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:98baf372c91fe63c423237a2a3ae5a043a4da41095698035ce86fd13f2051e44 -size 514 diff --git a/Code/Editor/bmp00005_05.png b/Code/Editor/bmp00005_05.png deleted file mode 100644 index 232c374515..0000000000 --- a/Code/Editor/bmp00005_05.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a570ae986b5f0b7e573094a7e75a8cfcc42f88b4766c47785bab26a9e8b1c2bb -size 239 diff --git a/Code/Editor/bmp00005_06.png b/Code/Editor/bmp00005_06.png deleted file mode 100644 index 3de6336a89..0000000000 --- a/Code/Editor/bmp00005_06.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4c527f2b8c883c73aebba0b5f0df6215f73b7259db61b13fa5ff7aa7b96a7b9b -size 779 diff --git a/Code/Editor/bmp00005_07.png b/Code/Editor/bmp00005_07.png deleted file mode 100644 index a813c0ad0b..0000000000 --- a/Code/Editor/bmp00005_07.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8f7f84cb48b2f9031b3a23abeddaed95d54601de33c58057d6677073b3e083aa -size 501 diff --git a/Code/Editor/bmp00005_08.png b/Code/Editor/bmp00005_08.png deleted file mode 100644 index b9f98ffe1c..0000000000 --- a/Code/Editor/bmp00005_08.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:804491b4251adfe017f8c52e00324dd74f00ebec445eedd947dea9356865cd56 -size 682 diff --git a/Code/Editor/bmp00005_09.png b/Code/Editor/bmp00005_09.png deleted file mode 100644 index 8650cc6a9e..0000000000 --- a/Code/Editor/bmp00005_09.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ecf6333b6b402e1834f3047b13e58e4f80e17a8eed3750017219b5694d1b6f67 -size 625 diff --git a/Code/Editor/bmp00006_00.png b/Code/Editor/bmp00006_00.png deleted file mode 100644 index c48f7ede09..0000000000 --- a/Code/Editor/bmp00006_00.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:70724fdada9cecd5a8d7ee5211ee713accc8f9642415e5dd93b6d621ed7273cf -size 139 diff --git a/Code/Editor/bmp00006_01.png b/Code/Editor/bmp00006_01.png deleted file mode 100644 index 7fb55bc8a5..0000000000 --- a/Code/Editor/bmp00006_01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3d12de5789fb345c5ffe4b76246ec0ba4d7972fb14d15db3f36886f3beaed3ff -size 166 diff --git a/Code/Editor/bmp00006_02.png b/Code/Editor/bmp00006_02.png deleted file mode 100644 index 7b1ab690a3..0000000000 --- a/Code/Editor/bmp00006_02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fffdbe9b4e1630f4158c4a00985e713ddb6fae50bc71e8c100255bab04054c0a -size 235 diff --git a/Code/Editor/bmp00006_03.png b/Code/Editor/bmp00006_03.png deleted file mode 100644 index 4829767efd..0000000000 --- a/Code/Editor/bmp00006_03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d5e4092107dbc45863abe1cbecb30c48135e17155b5a85afa07a4a90b3eb1221 -size 274 diff --git a/Code/Editor/bmp00006_04.png b/Code/Editor/bmp00006_04.png deleted file mode 100644 index dc809b8a65..0000000000 --- a/Code/Editor/bmp00006_04.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bc454d6cf883b78ae4cc32bfe4a81a6d5ee64e5e1bade9f2069e7e1b405ad9b1 -size 373 diff --git a/Code/Editor/bmp00006_05.png b/Code/Editor/bmp00006_05.png deleted file mode 100644 index 2f3c67fff6..0000000000 --- a/Code/Editor/bmp00006_05.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:359236f395259b21b75f8f3fa250dfeea9ef82b9d541c7344954cf93db5c9d47 -size 616 diff --git a/Code/Editor/bmp00006_06.png b/Code/Editor/bmp00006_06.png deleted file mode 100644 index 86c43264ea..0000000000 --- a/Code/Editor/bmp00006_06.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bc8e5dd88bb78f4f63ba8618e2bf0c1fd74d2dbdcf48261cfa57883c476619fe -size 1101 diff --git a/Code/Editor/bmp00006_07.png b/Code/Editor/bmp00006_07.png deleted file mode 100644 index 067b20a5fb..0000000000 --- a/Code/Editor/bmp00006_07.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1fbfb749ecfec92f461979d15642dfb940cc7895db3d27c47d040b0a7e2a1ae4 -size 1288 diff --git a/Code/Editor/editor_lib_files.cmake b/Code/Editor/editor_lib_files.cmake index 345a8e15e1..5d45bbd853 100644 --- a/Code/Editor/editor_lib_files.cmake +++ b/Code/Editor/editor_lib_files.cmake @@ -347,7 +347,6 @@ set(FILES MainStatusBar.cpp MainStatusBar.h MainStatusBarItems.h - CrtDebug.cpp CryEdit.rc CryEditDoc.cpp CryEditDoc.h @@ -358,7 +357,6 @@ set(FILES LogFile.cpp LogFile.h Resource.h - UserMessageDefines.h ActionManager.cpp ActionManager.h ShortcutDispatcher.cpp @@ -397,9 +395,6 @@ set(FILES ResizeResolutionDialog.cpp ResizeResolutionDialog.h ResizeResolutionDialog.ui - SelectEAXPresetDlg.cpp - SelectEAXPresetDlg.h - SelectEAXPresetDlg.ui SelectLightAnimationDialog.cpp SelectLightAnimationDialog.h SelectSequenceDialog.cpp @@ -421,9 +416,6 @@ set(FILES IconListDialog.ui UndoDropDown.cpp UndoDropDown.h - DimensionsDialog.cpp - DimensionsDialog.h - DimensionsDialog.ui NewLevelDialog.cpp NewLevelDialog.h NewLevelDialog.ui @@ -456,12 +448,7 @@ set(FILES ToolBox.h TrackViewNewSequenceDialog.h UndoConfigSpec.h - UndoViewPosition.h - UndoViewRotation.h Util/GeometryUtil.h - WipFeaturesDlg.h - WipFeaturesDlg.ui - WipFeaturesDlg.qrc LevelIndependentFileMan.cpp LevelIndependentFileMan.h LogFileImpl.cpp @@ -550,11 +537,6 @@ set(FILES TrackViewNewSequenceDialog.cpp TrackViewNewSequenceDialog.ui UndoConfigSpec.cpp - UndoViewPosition.cpp - UndoViewRotation.cpp - WipFeatureManager.cpp - WipFeatureManager.h - WipFeaturesDlg.cpp Dialogs/ErrorsDlg.cpp Dialogs/ErrorsDlg.h Dialogs/ErrorsDlg.ui @@ -571,8 +553,6 @@ set(FILES ProcessInfo.cpp ProcessInfo.h Report.h - SurfaceTypeValidator.cpp - SurfaceTypeValidator.h TrackView/AtomOutputFrameCapture.cpp TrackView/AtomOutputFrameCapture.h TrackView/TrackViewDialog.qrc diff --git a/Code/Editor/particles_tree_00.png b/Code/Editor/particles_tree_00.png deleted file mode 100644 index 274b2b0667..0000000000 --- a/Code/Editor/particles_tree_00.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b9cc3783ba8ccc940e89039455f2a8617a67520400ce74c9ce4c3d16d942ead8 -size 208 diff --git a/Code/Editor/particles_tree_01.png b/Code/Editor/particles_tree_01.png deleted file mode 100644 index 274b2b0667..0000000000 --- a/Code/Editor/particles_tree_01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b9cc3783ba8ccc940e89039455f2a8617a67520400ce74c9ce4c3d16d942ead8 -size 208 diff --git a/Code/Editor/particles_tree_02.png b/Code/Editor/particles_tree_02.png deleted file mode 100644 index 96f4bec585..0000000000 --- a/Code/Editor/particles_tree_02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:19b1ee36ba28ede080ef34bd13d37a8b579ad8e106089cd1b800b15aef1b58df -size 252 diff --git a/Code/Editor/particles_tree_03.png b/Code/Editor/particles_tree_03.png deleted file mode 100644 index 3ead10b3b4..0000000000 --- a/Code/Editor/particles_tree_03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9e6ef5e26d5d1566f51824c3bfa0ed3d2653cb49e38111aaf0572590b2fd15be -size 261 diff --git a/Code/Editor/particles_tree_04.png b/Code/Editor/particles_tree_04.png deleted file mode 100644 index 0920a2667d..0000000000 --- a/Code/Editor/particles_tree_04.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:acbeaa97474bd203ac35bf87fdea49d8b3d60f18db62d64dd47c3b1b50e54816 -size 303 diff --git a/Code/Editor/particles_tree_05.png b/Code/Editor/particles_tree_05.png deleted file mode 100644 index 0a4ce61ba0..0000000000 --- a/Code/Editor/particles_tree_05.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d92fc6ec4afc582ff5d019f5b26c48e3dbe6c5f3c753271d7918cd5ca95b8b32 -size 254 diff --git a/Code/Editor/particles_tree_06.png b/Code/Editor/particles_tree_06.png deleted file mode 100644 index e0ab042cb3..0000000000 --- a/Code/Editor/particles_tree_06.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:02066aed1d53c3ffc53c0f844a88ba8870b6c2c9c846c47ef6443c21ce4b7d0c -size 224 diff --git a/Code/Editor/particles_tree_07.png b/Code/Editor/particles_tree_07.png deleted file mode 100644 index 2ab767a7e9..0000000000 --- a/Code/Editor/particles_tree_07.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:67668cc830b553605d2f9ccad57f2fcd422da6a7515cfc4e9af0f43aa8591543 -size 213 diff --git a/Code/Framework/AtomCore/AtomCore/Instance/InstanceDatabase.h b/Code/Framework/AtomCore/AtomCore/Instance/InstanceDatabase.h index 4b4ad572c2..de98ce97b9 100644 --- a/Code/Framework/AtomCore/AtomCore/Instance/InstanceDatabase.h +++ b/Code/Framework/AtomCore/AtomCore/Instance/InstanceDatabase.h @@ -17,6 +17,11 @@ #include #include +namespace AZStd +{ + class any; +} + namespace AZ { namespace Data diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h b/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h index e4d2c7612e..697ca81a49 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h +++ b/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h @@ -19,7 +19,7 @@ #include #include #include -#include +#include namespace AZ { diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetDataStream.cpp b/Code/Framework/AzCore/AzCore/Asset/AssetDataStream.cpp index 4794b04626..4303963aa8 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetDataStream.cpp +++ b/Code/Framework/AzCore/AzCore/Asset/AssetDataStream.cpp @@ -7,11 +7,62 @@ */ #include +#include +#include +#include +#include +#include + +#include +#include namespace AZ::Data { + namespace DataStreamInternal + { + struct AssetDataStreamPrivate + { + //! Optional data buffer that's been directly passed in through Open(), instead of reading data from a file. + AZStd::vector m_preloadedData; + //! The current active streamer read request - tracked in case we need to cancel it prematurely + AZ::IO::FileRequestPtr m_curReadRequest{ nullptr }; + + //! Synchronization for the read request, so that it's possible to block until completion. + AZStd::mutex m_readRequestMutex; + AZStd::condition_variable m_readRequestActive; + + void SetReadRequest(AZ::IO::FileRequestPtr&& req) + { + AZStd::scoped_lock lock(m_readRequestMutex); + // The read request finished, so stop tracking it. + m_curReadRequest = AZStd::move(req); + } + void BlockUntilReadComplete() + { + AZStd::unique_lock lock(m_readRequestMutex); + m_readRequestActive.wait( + lock, + [this] + { + return m_curReadRequest == nullptr; + }); + lock.unlock(); + } + void CancelRequest() + { + AZStd::scoped_lock lock(m_readRequestMutex); + if (m_curReadRequest) + { + auto streamer = Interface::Get(); + m_curReadRequest = streamer->Cancel(m_curReadRequest); + } + } + }; + } // namespace Internal + AssetDataStream::AssetDataStream(AZ::IO::IStreamerTypes::RequestMemoryAllocator* bufferAllocator) - : m_bufferAllocator(bufferAllocator ? bufferAllocator : &m_defaultAllocator) + : m_privateData(AZStd::make_unique()) + , m_bufferAllocator(bufferAllocator ? bufferAllocator : &m_defaultAllocator) { ClearInternalStateData(); } @@ -53,9 +104,9 @@ namespace AZ::Data OpenInternal(data.size(), "(mem buffer)"); // Directly take ownership of the provided buffer - m_preloadedData = AZStd::move(data); - m_buffer = m_preloadedData.data(); - m_loadedSize = m_preloadedData.size(); + m_privateData->m_preloadedData = AZStd::move(data); + m_buffer = m_privateData->m_preloadedData.data(); + m_loadedSize = m_privateData->m_preloadedData.size(); } void AssetDataStream::Open(const AZStd::string& filePath, size_t fileOffset, size_t assetSize, @@ -65,7 +116,7 @@ namespace AZ::Data AZ_PROFILE_FUNCTION(AzCore); AZ_Assert(!m_isOpen, "Attempting to open the stream when it is already open."); - AZ_Assert(!m_curReadRequest, "Queueing an asset stream load while one is still in progress."); + AZ_Assert(!m_privateData->m_curReadRequest, "Queueing an asset stream load while one is still in progress."); AZ_Assert(!filePath.empty(), "AssetDataStream::Open called without a valid file name."); // Initialize the state variables and start tracking the overall load timings @@ -97,11 +148,8 @@ namespace AZ::Data "Buffer for %s was expected to be %zu bytes, but is %zu bytes.", m_filePath.c_str(), m_requestedAssetSize, m_loadedSize); - { - AZStd::scoped_lock lock(m_readRequestMutex); - // The read request finished, so stop tracking it. - m_curReadRequest = nullptr; - } + // The read request finished, so stop tracking it. + m_privateData->SetReadRequest(nullptr); // Call the load callback to start processing the loaded data. if (loadCallback) @@ -115,21 +163,22 @@ namespace AZ::Data } // Notify that the load is complete, in case anyone is using BlockUntilLoadComplete to block. - m_readRequestActive.notify_one(); + m_privateData->m_readRequestActive.notify_one(); }; // Queue the raw file load with the file streamer. auto streamer = AZ::Interface::Get(); - m_curReadRequest = streamer->Read( + m_privateData->m_curReadRequest = + streamer->Read( m_filePath, *m_bufferAllocator, m_requestedAssetSize, deadline, priority, m_fileOffset); m_curDeadline = deadline; m_curPriority = priority; - streamer->SetRequestCompleteCallback(m_curReadRequest, streamerCallback); + streamer->SetRequestCompleteCallback(m_privateData->m_curReadRequest, streamerCallback); - streamer->QueueRequest(m_curReadRequest); + streamer->QueueRequest(m_privateData->m_curReadRequest); } else { @@ -139,19 +188,19 @@ namespace AZ::Data loadCallback(AZ::IO::IStreamerTypes::RequestStatus::Completed); } - m_readRequestActive.notify_one(); + m_privateData->m_readRequestActive.notify_one(); } } void AssetDataStream::Reschedule(AZStd::chrono::milliseconds newDeadline, AZ::IO::IStreamerTypes::Priority newPriority) { - if (m_curReadRequest && (newDeadline < m_curDeadline || newPriority > m_curPriority)) + if (m_privateData->m_curReadRequest && (newDeadline < m_curDeadline || newPriority > m_curPriority)) { auto deadline = AZStd::GetMin(m_curDeadline, newDeadline); auto priority = AZStd::GetMax(m_curPriority, newPriority); auto streamer = Interface::Get(); - m_curReadRequest = streamer->RescheduleRequest(m_curReadRequest, deadline, priority); + m_privateData->m_curReadRequest = streamer->RescheduleRequest(m_privateData->m_curReadRequest, deadline, priority); m_curDeadline = deadline; m_curPriority = priority; } @@ -159,15 +208,13 @@ namespace AZ::Data void AssetDataStream::BlockUntilLoadComplete() { - AZStd::unique_lock lock(m_readRequestMutex); - m_readRequestActive.wait(lock, [this] { return m_curReadRequest == nullptr; }); - lock.unlock(); + m_privateData->BlockUntilReadComplete(); } void AssetDataStream::ClearInternalStateData() { // Clear all our internal state data. - m_preloadedData.resize(0); + m_privateData->m_preloadedData.resize(0); m_buffer = nullptr; m_loadedSize = 0; m_requestedAssetSize = 0; @@ -204,10 +251,10 @@ namespace AZ::Data void AssetDataStream::Close() { AZ_Assert(m_isOpen, "Attempting to close a stream that hasn't been opened."); - AZ_Assert(m_curReadRequest == nullptr, "Attempting to close a stream with a read request in flight."); + AZ_Assert(m_privateData->m_curReadRequest == nullptr, "Attempting to close a stream with a read request in flight."); // Destroy the asset buffer and unlock the allocator, so the allocator itself knows that it is no longer needed. - if (m_buffer != m_preloadedData.data()) + if (m_buffer != m_privateData->m_preloadedData.data()) { m_bufferAllocator->Release(m_buffer); } @@ -221,12 +268,7 @@ namespace AZ::Data void AssetDataStream::RequestCancel() { - AZStd::scoped_lock lock(m_readRequestMutex); - if (m_curReadRequest) - { - auto streamer = Interface::Get(); - m_curReadRequest = streamer->Cancel(m_curReadRequest); - } + m_privateData->CancelRequest(); } void AssetDataStream::Seek(AZ::IO::OffsetType bytes, AZ::IO::GenericStream::SeekMode mode) diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetDataStream.h b/Code/Framework/AzCore/AzCore/Asset/AssetDataStream.h index 79822c8db2..43a4516344 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetDataStream.h +++ b/Code/Framework/AzCore/AzCore/Asset/AssetDataStream.h @@ -9,17 +9,26 @@ #include #include -#include -#include -#include -#include -#include +#include +#include + +namespace AZStd +{ + template + class vector; +} namespace AZ::Data { + namespace DataStreamInternal + { + struct AssetDataStreamPrivate; + } + class AssetDataStream : public AZ::IO::GenericStream { public: + using VectorDataSource = AZStd::vector; // The default Generic Stream APIs in this class will only allow for a single sequential pass // through the data, no seeking. Reads will block when pages aren't available yet, and // pages will be marked for recycling once reading has progressed beyond them. @@ -29,10 +38,10 @@ namespace AZ::Data ~AssetDataStream() override; // Open the AssetDataStream and make a copy of the provided memory buffer. - void Open(const AZStd::vector& data); + void Open(const VectorDataSource& data); // Open the AssetDataStream and directly take ownership of a pre-populated memory buffer. - void Open(AZStd::vector&& data); + void Open(VectorDataSource&& data); // Open the AssetDataStream and load it via file streaming using OnCompleteCallback = AZStd::function; @@ -91,6 +100,8 @@ namespace AZ::Data void ClearInternalStateData(); + AZStd::unique_ptr m_privateData; + //! The allocator to use for allocating / deallocating asset buffers AZ::IO::IStreamerTypes::RequestMemoryAllocator* m_bufferAllocator{ nullptr }; @@ -106,9 +117,6 @@ namespace AZ::Data //! The amount of data that's expected to be loaded. size_t m_requestedAssetSize{ 0 }; - //! Optional data buffer that's been directly passed in through Open(), instead of reading data from a file. - AZStd::vector m_preloadedData; - //! The buffer that will hold the raw data after it's loaded from the file. void* m_buffer{ nullptr }; @@ -119,19 +127,12 @@ namespace AZ::Data //! The current offset representing how far we've read into the buffer. size_t m_curOffset{ 0 }; - //! The current active streamer read request - tracked in case we need to cancel it prematurely - AZ::IO::FileRequestPtr m_curReadRequest{ nullptr }; - //! The current request deadline. Used to avoid requesting a reschedule to the same (current) deadline. AZStd::chrono::milliseconds m_curDeadline{ AZ::IO::IStreamerTypes::s_noDeadline }; //! The current request priority. Used to avoid requesting a reschedule to the same (current) priority. AZ::IO::IStreamerTypes::Priority m_curPriority{ AZ::IO::IStreamerTypes::s_priorityMedium }; - //! Synchronization for the read request, so that it's possible to block until completion. - AZStd::mutex m_readRequestMutex; - AZStd::condition_variable m_readRequestActive; - //! Track whether or not the stream is currently open bool m_isOpen{ false }; diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetManager.cpp b/Code/Framework/AzCore/AzCore/Asset/AssetManager.cpp index afe3330bd3..b4b1a0d81c 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetManager.cpp +++ b/Code/Framework/AzCore/AzCore/Asset/AssetManager.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetManager.h b/Code/Framework/AzCore/AzCore/Asset/AssetManager.h index 9666d434c1..663de2c058 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetManager.h +++ b/Code/Framework/AzCore/AzCore/Asset/AssetManager.h @@ -12,7 +12,6 @@ #include #include #include -#include #include #include // used as allocator for most components #include diff --git a/Code/Framework/AzCore/AzCore/DOM/DomPath.cpp b/Code/Framework/AzCore/AzCore/DOM/DomPath.cpp new file mode 100644 index 0000000000..bc50a8513c --- /dev/null +++ b/Code/Framework/AzCore/AzCore/DOM/DomPath.cpp @@ -0,0 +1,478 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include +#include + +namespace AZ::Dom +{ + PathEntry::PathEntry(size_t value) + : m_value(value) + { + } + + PathEntry::PathEntry(AZ::Name value) + : m_value(AZStd::move(value)) + { + } + + PathEntry::PathEntry(AZStd::string_view value) + : m_value(AZ::Name(value)) + { + } + + PathEntry& PathEntry::operator=(size_t value) + { + m_value = value; + return *this; + } + + PathEntry& PathEntry::operator=(AZ::Name value) + { + m_value = AZStd::move(value); + return *this; + } + + PathEntry& PathEntry::operator=(AZStd::string_view value) + { + m_value = AZ::Name(value); + return *this; + } + + bool PathEntry::operator==(const PathEntry& other) const + { + return m_value == other.m_value; + } + + bool PathEntry::operator==(size_t value) const + { + return IsIndex() && GetIndex() == value; + } + + bool PathEntry::operator==(const AZ::Name& key) const + { + return IsKey() && GetKey() == key; + } + + bool PathEntry::operator==(AZStd::string_view key) const + { + return IsKey() && GetKey() == AZ::Name(key); + } + + bool PathEntry::operator!=(const PathEntry& other) const + { + return m_value != other.m_value; + } + + bool PathEntry::operator!=(size_t value) const + { + return !IsIndex() || GetIndex() != value; + } + + bool PathEntry::operator!=(const AZ::Name& key) const + { + return !IsKey() || GetKey() != key; + } + + bool PathEntry::operator!=(AZStd::string_view key) const + { + return !IsKey() || GetKey() != AZ::Name(key); + } + + void PathEntry::SetEndOfArray() + { + m_value = EndOfArrayIndex; + } + + bool PathEntry::IsEndOfArray() const + { + const size_t* result = AZStd::get_if(&m_value); + return result == nullptr ? false : ((*result) == EndOfArrayIndex); + } + + bool PathEntry::IsIndex() const + { + const size_t* result = AZStd::get_if(&m_value); + return result == nullptr ? false : ((*result) != EndOfArrayIndex); + } + + bool PathEntry::IsKey() const + { + return AZStd::holds_alternative(m_value); + } + + size_t PathEntry::GetIndex() const + { + AZ_Assert(IsIndex(), "GetIndex called on PathEntry that is not an index"); + return AZStd::get(m_value); + } + + const AZ::Name& PathEntry::GetKey() const + { + AZ_Assert(IsKey(), "Key called on PathEntry that is not a key"); + return AZStd::get(m_value); + } + + Path::Path(AZStd::initializer_list init) + : m_entries(init) + { + } + + Path::Path(AZStd::string_view pathString) + { + FromString(pathString); + } + + Path Path::operator/(const PathEntry& entry) const + { + Path newPath(*this); + newPath /= entry; + return newPath; + } + + Path Path::operator/(size_t index) const + { + return *this / PathEntry(index); + } + + Path Path::operator/(AZ::Name key) const + { + return *this / PathEntry(key); + } + + Path Path::operator/(AZStd::string_view key) const + { + return *this / PathEntry(key); + } + + Path Path::operator/(const Path& other) const + { + Path newPath(*this); + newPath /= other; + return newPath; + } + + Path& Path::operator/=(const PathEntry& entry) + { + Push(entry); + return *this; + } + + Path& Path::operator/=(size_t index) + { + return *this /= PathEntry(index); + } + + Path& Path::operator/=(AZ::Name key) + { + return *this /= PathEntry(key); + } + + Path& Path::operator/=(AZStd::string_view key) + { + return *this /= PathEntry(key); + } + + Path& Path::operator/=(const Path& other) + { + for (const PathEntry& entry : other) + { + Push(entry); + } + return *this; + } + + bool Path::operator==(const Path& other) const + { + return m_entries == other.m_entries; + } + + const Path::ContainerType& Path::GetEntries() const + { + return m_entries; + } + + void Path::Push(PathEntry entry) + { + m_entries.push_back(AZStd::move(entry)); + } + + void Path::Push(size_t entry) + { + Push(PathEntry(entry)); + } + + void Path::Push(AZ::Name entry) + { + Push(PathEntry(AZStd::move(entry))); + } + + void Path::Push(AZStd::string_view entry) + { + Push(AZ::Name(entry)); + } + + void Path::Pop() + { + m_entries.pop_back(); + } + + void Path::Clear() + { + m_entries.clear(); + } + + PathEntry Path::At(size_t index) const + { + if (index < m_entries.size()) + { + return m_entries[index]; + } + return {}; + } + + size_t Path::Size() const + { + return m_entries.size(); + } + + PathEntry& Path::operator[](size_t index) + { + return m_entries[index]; + } + + const PathEntry& Path::operator[](size_t index) const + { + return m_entries[index]; + } + + Path::ContainerType::iterator Path::begin() + { + return m_entries.begin(); + } + + Path::ContainerType::iterator Path::end() + { + return m_entries.end(); + } + + Path::ContainerType::const_iterator Path::begin() const + { + return m_entries.cbegin(); + } + + Path::ContainerType::const_iterator Path::end() const + { + return m_entries.cend(); + } + + Path::ContainerType::const_iterator Path::cbegin() const + { + return m_entries.cbegin(); + } + + Path::ContainerType::const_iterator Path::cend() const + { + return m_entries.cend(); + } + + size_t Path::size() const + { + return m_entries.size(); + } + + size_t Path::GetStringLength() const + { + size_t size = 0; + for (const PathEntry& entry : m_entries) + { + ++size; + if (entry.IsEndOfArray()) + { + size += 1; + } + else if (entry.IsIndex()) + { + const size_t index = entry.GetIndex(); + const double digitCount = index > 0 ? log10(aznumeric_cast(index + 1)) : 1.0; + size += aznumeric_cast(ceil(digitCount)); + } + else + { + const char* nameBuffer = entry.GetKey().GetCStr(); + for (size_t i = 0; nameBuffer[i]; ++i) + { + if (nameBuffer[i] == EscapeCharacter || nameBuffer[i] == PathSeparator) + { + ++size; + } + ++size; + } + } + } + return size; + } + + void Path::FormatString(char* stringBuffer, size_t bufferSize) const + { + size_t bufferIndex = 0; + + auto putChar = [&](char c) + { + if (bufferIndex == bufferSize) + { + return; + } + stringBuffer[bufferIndex++] = c; + }; + + auto writeToBuffer = [&](const char* key) + { + for (size_t keyIndex = 0; key[keyIndex]; ++keyIndex) + { + const char c = key[keyIndex]; + if (c == EscapeCharacter) + { + putChar(EscapeCharacter); + putChar(TildeSequence); + } + else if (c == PathSeparator) + { + putChar(EscapeCharacter); + putChar(ForwardSlashSequence); + } + else + { + putChar(c); + } + } + }; + + for (const PathEntry& entry : m_entries) + { + putChar(PathSeparator); + if (entry.IsEndOfArray()) + { + putChar(EndOfArrayCharacter); + } + else if (entry.IsIndex()) + { + bufferIndex += azsnprintf(&stringBuffer[bufferIndex], bufferSize - bufferIndex, "%zu", entry.GetIndex()); + } + else + { + writeToBuffer(entry.GetKey().GetCStr()); + } + } + + putChar('\0'); + } + + AZStd::string Path::ToString() const + { + AZStd::string formattedString; + const size_t size = GetStringLength(); + formattedString.resize_no_construct(size); + FormatString(formattedString.data(), size + 1); + return formattedString; + } + + void Path::AppendToString(AZStd::string& output) const + { + const size_t startIndex = output.length(); + const size_t stringLength = GetStringLength(); + output.resize_no_construct(startIndex + stringLength); + FormatString(output.data() + startIndex, stringLength + 1); + } + + void Path::FromString(AZStd::string_view pathString) + { + m_entries.clear(); + if (pathString.empty()) + { + return; + } + + size_t pathEntryCount = 0; + for (size_t i = 1; i <= pathString.size(); ++i) + { + if (pathString[i] == PathSeparator) + { + ++pathEntryCount; + } + } + m_entries.reserve(pathEntryCount); + + // Ignore a preceeding path separator and start processing after it + size_t pathIndex = pathString[0] == PathSeparator ? 1 : 0; + bool isNumber = true; + AZStd::string convertedSection; + for (size_t i = pathIndex; i <= pathString.size(); ++i) + { + if (i == pathString.size() || pathString[i] == PathSeparator) + { + AZStd::string_view section = pathString.substr(pathIndex, i - pathIndex); + if (section.size() == 1 && section[0] == EndOfArrayCharacter) + { + PathEntry entry; + entry.SetEndOfArray(); + m_entries.push_back(AZStd::move(entry)); + } + else if (isNumber && !section.empty()) + { + size_t index = 0; + ConsoleTypeHelpers::StringToValue(index, section); + m_entries.push_back(PathEntry{ index }); + } + else + { + convertedSection.clear(); + size_t lastPos = 0; + size_t posToEscape = section.find(EscapeCharacter); + while (posToEscape != AZStd::string_view::npos) + { + if (convertedSection.empty()) + { + convertedSection.reserve(section.size() - 1); + } + convertedSection += section.substr(lastPos, posToEscape - lastPos); + if (section[posToEscape + 1] == ForwardSlashSequence) + { + convertedSection += '/'; + } + else + { + convertedSection += '~'; + } + + lastPos = posToEscape + 2; + posToEscape = section.find(EscapeCharacter, posToEscape + 2); + } + + if (!convertedSection.empty()) + { + convertedSection += section.substr(lastPos); + m_entries.emplace_back(convertedSection); + } + else + { + m_entries.emplace_back(section); + } + } + pathIndex = i + 1; + isNumber = true; + continue; + } + + const char c = pathString[i]; + isNumber = isNumber && c >= '0' && c <= '9'; + } + } +} // namespace AZ::Dom diff --git a/Code/Framework/AzCore/AzCore/DOM/DomPath.h b/Code/Framework/AzCore/AzCore/DOM/DomPath.h new file mode 100644 index 0000000000..39f7c7da98 --- /dev/null +++ b/Code/Framework/AzCore/AzCore/DOM/DomPath.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include + +namespace AZ::Dom +{ + //! Represents the path to a direct descendant of a Value. + //! PathEntry may be one of the following: + //! - Index, a numerical index for indexing within Arrays and Nodes + //! - Key, a name for indexing within Objects and Nodes + //! - EndOfArray, a special-case indicator for representing the end of an array + //! used by the patching system to represent push / pop back operations. + class PathEntry final + { + public: + static constexpr size_t EndOfArrayIndex = size_t(-1); + + PathEntry() = default; + PathEntry(const PathEntry&) = default; + PathEntry(PathEntry&&) = default; + explicit PathEntry(size_t value); + explicit PathEntry(AZ::Name value); + explicit PathEntry(AZStd::string_view value); + + PathEntry& operator=(const PathEntry&) = default; + PathEntry& operator=(PathEntry&&) = default; + PathEntry& operator=(size_t value); + PathEntry& operator=(AZ::Name value); + PathEntry& operator=(AZStd::string_view value); + + bool operator==(const PathEntry& other) const; + bool operator==(size_t index) const; + bool operator==(const AZ::Name& key) const; + bool operator==(AZStd::string_view key) const; + bool operator!=(const PathEntry& other) const; + bool operator!=(size_t index) const; + bool operator!=(const AZ::Name& key) const; + bool operator!=(AZStd::string_view key) const; + + void SetEndOfArray(); + + bool IsEndOfArray() const; + bool IsIndex() const; + bool IsKey() const; + + size_t GetIndex() const; + const AZ::Name& GetKey() const; + + private: + AZStd::variant m_value; + }; + + //! Represents a path, represented as a series of PathEntry values, to a position in a Value. + class Path final + { + public: + using ContainerType = AZStd::vector; + static constexpr char PathSeparator = '/'; + static constexpr char EscapeCharacter = '~'; + static constexpr char TildeSequence = '0'; + static constexpr char ForwardSlashSequence = '1'; + static constexpr char EndOfArrayCharacter = '-'; + + Path() = default; + Path(const Path&) = default; + Path(Path&&) = default; + explicit Path(AZStd::initializer_list init); + //! Creates a Path from a path string, a path string is formatted per the JSON pointer specification + //! and looks like "/path/to/value/0" + explicit Path(AZStd::string_view pathString); + + template + explicit Path(InputIterator first, InputIterator last) + : m_entries(first, last) + { + } + + Path& operator=(const Path&) = default; + Path& operator=(Path&&) = default; + + Path operator/(const PathEntry&) const; + Path operator/(size_t) const; + Path operator/(AZ::Name) const; + Path operator/(AZStd::string_view) const; + Path operator/(const Path&) const; + + Path& operator/=(const PathEntry&); + Path& operator/=(size_t); + Path& operator/=(AZ::Name); + Path& operator/=(AZStd::string_view); + Path& operator/=(const Path&); + + bool operator==(const Path&) const; + + const ContainerType& GetEntries() const; + void Push(PathEntry entry); + void Push(size_t entry); + void Push(AZ::Name entry); + void Push(AZStd::string_view key); + void Pop(); + void Clear(); + PathEntry At(size_t index) const; + size_t Size() const; + + PathEntry& operator[](size_t index); + const PathEntry& operator[](size_t index) const; + + ContainerType::iterator begin(); + ContainerType::iterator end(); + ContainerType::const_iterator begin() const; + ContainerType::const_iterator end() const; + ContainerType::const_iterator cbegin() const; + ContainerType::const_iterator cend() const; + size_t size() const; + + //! Gets the length this path would require, if string-formatted. + //! The length includes the contents of the string but not a null terminator. + size_t GetStringLength() const; + //! Formats a JSON-pointer style path string into the target buffer. + //! This operation will fail if bufferSize < GetStringLength() + 1 + void FormatString(char* stringBuffer, size_t bufferSize) const; + //! Returns a JSON-pointer style path string for this path. + AZStd::string ToString() const; + void AppendToString(AZStd::string& output) const; + //! Reads a JSON-pointer style path from pathString and replaces this path's contents. + //! Paths are accepted in the following forms: + //! "/path/to/foo/0" + //! "path/to/foo/0" + void FromString(AZStd::string_view pathString); + + private: + ContainerType m_entries; + }; +} // namespace AZ::Dom diff --git a/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp b/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp index c604373296..bc5c2b28cf 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp @@ -77,8 +77,8 @@ namespace AZ::Dom::Utils for (size_t i = 0; i < ourValues.size(); ++i) { const Object::EntryType& lhsChild = ourValues[i]; - const Object::EntryType& rhsChild = theirValues[i]; - if (lhsChild.first != rhsChild.first || !DeepCompareIsEqual(lhsChild.second, rhsChild.second)) + auto rhsIt = rhs.FindMember(lhsChild.first); + if (rhsIt == rhs.MemberEnd() || !DeepCompareIsEqual(lhsChild.second, rhsIt->second)) { return false; } @@ -144,8 +144,8 @@ namespace AZ::Dom::Utils for (size_t i = 0; i < ourProperties.size(); ++i) { const Object::EntryType& lhsChild = ourProperties[i]; - const Object::EntryType& rhsChild = theirProperties[i]; - if (lhsChild.first != rhsChild.first || !DeepCompareIsEqual(lhsChild.second, rhsChild.second)) + auto rhsIt = rhs.FindMember(lhsChild.first); + if (rhsIt == rhs.MemberEnd() || !DeepCompareIsEqual(lhsChild.second, rhsIt->second)) { return false; } diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index 6d944c9f45..793fadd092 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -6,6 +6,7 @@ * */ +#include #include #include #include @@ -283,64 +284,33 @@ namespace AZ::Dom Type Dom::Value::GetType() const { - return AZStd::visit( - [](auto&& value) -> Type - { - using CurrentType = AZStd::decay_t; - if constexpr (AZStd::is_same_v) - { - return Type::Null; - } - else if constexpr (AZStd::is_same_v) - { - return Type::Int64; - } - else if constexpr (AZStd::is_same_v) - { - return Type::Uint64; - } - else if constexpr (AZStd::is_same_v) - { - return Type::Double; - } - else if constexpr (AZStd::is_same_v) - { - return Type::Bool; - } - else if constexpr (AZStd::is_same_v) - { - return Type::String; - } - else if constexpr (AZStd::is_same_v) - { - return Type::String; - } - else if constexpr (AZStd::is_same_v) - { - return Type::String; - } - else if constexpr (AZStd::is_same_v) - { - return Type::Object; - } - else if constexpr (AZStd::is_same_v) - { - return Type::Array; - } - else if constexpr (AZStd::is_same_v) - { - return Type::Node; - } - else if constexpr (AZStd::is_same_v) - { - return Type::Opaque; - } - else - { - AZ_Assert(false, "AZ::Dom::Value::GetType: m_value has an unexpected type"); - } - }, - m_value); + switch (m_value.index()) + { + case GetTypeIndex(): + return Type::Null; + case GetTypeIndex(): + return Type::Int64; + case GetTypeIndex(): + return Type::Uint64; + case GetTypeIndex(): + return Type::Double; + case GetTypeIndex(): + return Type::Bool; + case GetTypeIndex(): + case GetTypeIndex(): + case GetTypeIndex(): + return Type::String; + case GetTypeIndex(): + return Type::Object; + case GetTypeIndex(): + return Type::Array; + case GetTypeIndex(): + return Type::Node; + case GetTypeIndex>(): + return Type::Opaque; + } + AZ_Assert(false, "AZ::Dom::Value::GetType: m_value has an unexpected type"); + return Type::Null; } bool Value::IsNull() const @@ -594,12 +564,12 @@ namespace AZ::Dom return GetObjectInternal().end(); } - Object::Iterator Value::MemberBegin() + Object::Iterator Value::MutableMemberBegin() { return GetObjectInternal().begin(); } - Object::Iterator Value::MemberEnd() + Object::Iterator Value::MutableMemberEnd() { return GetObjectInternal().end(); } @@ -725,12 +695,12 @@ namespace AZ::Dom return object.end(); } - Object::Iterator Value::EraseMember(Object::ConstIterator pos) + Object::Iterator Value::EraseMember(Object::Iterator pos) { return GetObjectInternal().erase(pos); } - Object::Iterator Value::EraseMember(Object::ConstIterator first, Object::ConstIterator last) + Object::Iterator Value::EraseMember(Object::Iterator first, Object::Iterator last) { return GetObjectInternal().erase(first, last); } @@ -811,12 +781,12 @@ namespace AZ::Dom return GetArrayInternal().end(); } - Array::Iterator Value::ArrayBegin() + Array::Iterator Value::MutableArrayBegin() { return GetArrayInternal().begin(); } - Array::Iterator Value::ArrayEnd() + Array::Iterator Value::MutableArrayEnd() { return GetArrayInternal().end(); } @@ -843,12 +813,12 @@ namespace AZ::Dom return *this; } - Array::Iterator Value::ArrayErase(Array::ConstIterator pos) + Array::Iterator Value::ArrayErase(Array::Iterator pos) { return GetArrayInternal().erase(pos); } - Array::Iterator Value::ArrayErase(Array::ConstIterator first, Array::ConstIterator last) + Array::Iterator Value::ArrayErase(Array::Iterator first, Array::Iterator last) { return GetArrayInternal().erase(first, last); } @@ -1113,6 +1083,10 @@ namespace AZ::Dom { result = visitor.RefCountedString(arg, copyStrings ? Lifetime::Temporary : Lifetime::Persistent); } + else if constexpr (AZStd::is_same_v) + { + result = visitor.String(arg, copyStrings ? Lifetime::Temporary : Lifetime::Persistent); + } else if constexpr (AZStd::is_same_v) { result = visitor.StartObject(); @@ -1204,4 +1178,124 @@ namespace AZ::Dom { return m_value; } + + Value& Value::operator[](const PathEntry& entry) + { + if (entry.IsEndOfArray()) + { + Array::ContainerType& array = GetArrayInternal(); + array.push_back(); + return array[array.size() - 1]; + } + return entry.IsIndex() ? operator[](entry.GetIndex()) : operator[](entry.GetKey()); + } + + const Value& Value::operator[](const PathEntry& entry) const + { + return entry.IsIndex() ? operator[](entry.GetIndex()) : operator[](entry.GetKey()); + } + + Value& Value::operator[](const Path& path) + { + Value* value = this; + for (const PathEntry& entry : path) + { + value = &value->operator[](entry); + } + return *value; + } + + const Value& Value::operator[](const Path& path) const + { + const Value* value = this; + for (const PathEntry& entry : path) + { + value = &value->operator[](entry); + } + return *value; + } + + const Value* Value::FindChild(const PathEntry& entry) const + { + if (entry.IsEndOfArray()) + { + return nullptr; + } + else if (entry.IsIndex()) + { + const Array::ContainerType& array = GetArrayInternal(); + const size_t index = entry.GetIndex(); + if (index < array.size()) + { + return &array[index]; + } + } + else + { + const Object::ContainerType& obj = GetObjectInternal(); + auto memberIt = FindMember(entry.GetKey()); + if (memberIt != obj.end()) + { + return &memberIt->second; + } + } + return nullptr; + } + + Value* Value::FindMutableChild(const PathEntry& entry) + { + if (entry.IsEndOfArray()) + { + Array::ContainerType& array = GetArrayInternal(); + array.push_back(); + return &array[array.size() - 1]; + } + else if (entry.IsIndex()) + { + Array::ContainerType& array = GetArrayInternal(); + const size_t index = entry.GetIndex(); + if (index < array.size()) + { + return &array[index]; + } + } + else + { + Object::ContainerType& obj = GetObjectInternal(); + auto memberIt = FindMutableMember(entry.GetKey()); + if (memberIt != obj.end()) + { + return &memberIt->second; + } + } + return nullptr; + } + + const Value* Value::FindChild(const Path& path) const + { + const Value* value = this; + for (const PathEntry& entry : path) + { + value = value->FindChild(entry); + if (value == nullptr) + { + return nullptr; + } + } + return value; + } + + Value* Value::FindMutableChild(const Path& path) + { + Value* value = this; + for (const PathEntry& entry : path) + { + value = value->FindMutableChild(entry); + if (value == nullptr) + { + return nullptr; + } + } + return value; + } } // namespace AZ::Dom diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index ecf8326525..be5d855003 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -22,6 +22,8 @@ namespace AZ::Dom { + class PathEntry; + class Path; using KeyType = AZ::Name; //! The type of underlying value stored in a value. \see Value @@ -268,8 +270,8 @@ namespace AZ::Dom Object::ConstIterator MemberBegin() const; Object::ConstIterator MemberEnd() const; - Object::Iterator MemberBegin(); - Object::Iterator MemberEnd(); + Object::Iterator MutableMemberBegin(); + Object::Iterator MutableMemberEnd(); Object::Iterator FindMutableMember(KeyType name); Object::Iterator FindMutableMember(AZStd::string_view name); @@ -289,8 +291,8 @@ namespace AZ::Dom void RemoveMember(KeyType name); void RemoveMember(AZStd::string_view name); Object::Iterator RemoveMember(Object::Iterator pos); - Object::Iterator EraseMember(Object::ConstIterator pos); - Object::Iterator EraseMember(Object::ConstIterator first, Object::ConstIterator last); + Object::Iterator EraseMember(Object::Iterator pos); + Object::Iterator EraseMember(Object::Iterator first, Object::Iterator last); Object::Iterator EraseMember(KeyType name); Object::Iterator EraseMember(AZStd::string_view name); @@ -313,15 +315,15 @@ namespace AZ::Dom Array::ConstIterator ArrayBegin() const; Array::ConstIterator ArrayEnd() const; - Array::Iterator ArrayBegin(); - Array::Iterator ArrayEnd(); + Array::Iterator MutableArrayBegin(); + Array::Iterator MutableArrayEnd(); Value& ArrayReserve(size_t newCapacity); Value& ArrayPushBack(Value value); Value& ArrayPopBack(); - Array::Iterator ArrayErase(Array::ConstIterator pos); - Array::Iterator ArrayErase(Array::ConstIterator first, Array::ConstIterator last); + Array::Iterator ArrayErase(Array::Iterator pos); + Array::Iterator ArrayErase(Array::Iterator first, Array::Iterator last); Array::ContainerType& GetMutableArray(); const Array::ContainerType& GetArray() const; @@ -380,6 +382,17 @@ namespace AZ::Dom Visitor::Result Accept(Visitor& visitor, bool copyStrings) const; AZStd::unique_ptr GetWriteHandler(); + // Path API... + Value& operator[](const PathEntry& entry); + const Value& operator[](const PathEntry& entry) const; + Value& operator[](const Path& path); + const Value& operator[](const Path& path) const; + + const Value* FindChild(const PathEntry& entry) const; + Value* FindMutableChild(const PathEntry& entry); + const Value* FindChild(const Path& path) const; + Value* FindMutableChild(const Path& path); + //! Gets the internal value of this Value. Note that this value's types may not correspond one-to-one with the Type enumeration, //! as internally the same type might have different storage mechanisms. Where possible, prefer using the typed API. const ValueType& GetInternalValue() const; diff --git a/Code/Framework/AzCore/AzCore/EBus/EBus.h b/Code/Framework/AzCore/AzCore/EBus/EBus.h index 67cffb4e41..4ab4f9a76c 100644 --- a/Code/Framework/AzCore/AzCore/EBus/EBus.h +++ b/Code/Framework/AzCore/AzCore/EBus/EBus.h @@ -23,6 +23,11 @@ #include #include + // Included for backwards compatibility purposes +#include +#include +#include + #include #include @@ -515,7 +520,7 @@ namespace AZ * This is not EBus Context Mutex when LocklessDispatch is set */ template - using DispatchLockGuard = typename ImplTraits::template DispatchLockGuard; + using DispatchLockGuardTemplate = typename ImplTraits::template DispatchLockGuard; ////////////////////////////////////////////////////////////////////////// // Check to help identify common mistakes @@ -645,7 +650,7 @@ namespace AZ * during broadcast/event dispatch. * @see EBusTraits::LocklessDispatch */ - using DispatchLockGuard = DispatchLockGuard; + using DispatchLockGuard = DispatchLockGuardTemplate; /** * The scoped lock guard to use during connection. Some specialized policies execute handler methods which diff --git a/Code/Framework/AzCore/AzCore/EBus/Internal/BusContainer.h b/Code/Framework/AzCore/AzCore/EBus/Internal/BusContainer.h index 2c57359c67..ce79b93805 100644 --- a/Code/Framework/AzCore/AzCore/EBus/Internal/BusContainer.h +++ b/Code/Framework/AzCore/AzCore/EBus/Internal/BusContainer.h @@ -93,14 +93,14 @@ namespace AZ // This struct will hold the handlers per address struct HandlerHolder; // This struct will hold each handler - using HandlerNode = HandlerNode; + using HandlerNode = AZ::Internal::HandlerNode; // Defines how handler holders are stored (will be some sort of map-like structure from id -> handler holder) using AddressStorage = AddressStoragePolicy; // Defines how handlers are stored per address (will be some sort of list) using HandlerStorage = HandlerStoragePolicy; using Handler = IdHandler; - using MultiHandler = MultiHandler; + using MultiHandler = AZ::Internal::MultiHandler; using BusPtr = AZStd::intrusive_ptr; EBusContainer() = default; @@ -774,13 +774,13 @@ namespace AZ // This struct will hold the handler per address struct HandlerHolder; // This struct will hold each handler - using HandlerNode = HandlerNode; + using HandlerNode = AZ::Internal::HandlerNode; // Defines how handler holders are stored (will be some sort of map-like structure from id -> handler holder) using AddressStorage = AddressStoragePolicy; // No need for HandlerStorage, there's only 1 so it will always just be a HandlerNode* using Handler = IdHandler; - using MultiHandler = MultiHandler; + using MultiHandler = AZ::Internal::MultiHandler; using BusPtr = AZStd::intrusive_ptr; EBusContainer() = default; @@ -1316,7 +1316,7 @@ namespace AZ // This struct will hold the handlers per address struct HandlerHolder; // This struct will hold each handler - using HandlerNode = HandlerNode; + using HandlerNode = AZ::Internal::HandlerNode; // Defines how handlers are stored per address (will be some sort of list) using HandlerStorage = HandlerStoragePolicy; // No need for AddressStorage, there's only 1 diff --git a/Code/Framework/AzCore/AzCore/EBus/Internal/CallstackEntry.h b/Code/Framework/AzCore/AzCore/EBus/Internal/CallstackEntry.h index bcda78aef8..391a0ea18e 100644 --- a/Code/Framework/AzCore/AzCore/EBus/Internal/CallstackEntry.h +++ b/Code/Framework/AzCore/AzCore/EBus/Internal/CallstackEntry.h @@ -161,7 +161,7 @@ namespace AZ template struct EBusCallstackStorage { - AZ_THREAD_LOCAL static C* s_entry; + static AZ_THREAD_LOCAL C* s_entry; EBusCallstackStorage() = default; ~EBusCallstackStorage() = default; diff --git a/Code/Framework/AzCore/AzCore/IO/IStreamer.h b/Code/Framework/AzCore/AzCore/IO/IStreamer.h index 438384e687..d59ee5007e 100644 --- a/Code/Framework/AzCore/AzCore/IO/IStreamer.h +++ b/Code/Framework/AzCore/AzCore/IO/IStreamer.h @@ -15,14 +15,18 @@ #include #include #include +#include // These Streamer includes need to be moved to Streamer internals/implementation, // and pull out only what we need for visibility at IStreamer.h interface declaration. #include -#include namespace AZ::IO { + class ExternalFileRequest; + class FileRequestHandle; + + using FileRequestPtr = AZStd::intrusive_ptr; /** * Data Streamer Interface */ diff --git a/Code/Framework/AzCore/AzCore/IO/Path/Path.inl b/Code/Framework/AzCore/AzCore/IO/Path/Path.inl index 0dc1799528..ab991e1750 100644 --- a/Code/Framework/AzCore/AzCore/IO/Path/Path.inl +++ b/Code/Framework/AzCore/AzCore/IO/Path/Path.inl @@ -13,50 +13,6 @@ #include -// extern instantiations of Path templates to prevent implicit instantiations -namespace AZ::IO -{ - // Class templates explicit declarations - extern template class BasicPath; - extern template class BasicPath; - extern template class PathIterator; - extern template class PathIterator; - extern template class PathIterator; - - // Swap function explicit declarations - extern template void swap(Path& lhs, Path& rhs) noexcept; - extern template void swap(FixedMaxPath& lhs, FixedMaxPath& rhs) noexcept; - - // Hash function explicit declarations - extern template size_t hash_value(const Path& pathToHash); - extern template size_t hash_value(const FixedMaxPath& pathToHash); - - // Append operator explicit declarations - extern template BasicPath operator/(const BasicPath& lhs, const PathView& rhs); - extern template BasicPath operator/(const BasicPath& lhs, const PathView& rhs); - extern template BasicPath operator/(const BasicPath& lhs, AZStd::string_view rhs); - extern template BasicPath operator/(const BasicPath& lhs, AZStd::string_view rhs); - extern template BasicPath operator/(const BasicPath& lhs, - const typename BasicPath::value_type* rhs); - extern template BasicPath operator/(const BasicPath& lhs, - const typename BasicPath::value_type* rhs); - - // Iterator compare explicit declarations - extern template bool operator==(const PathIterator& lhs, - const PathIterator& rhs); - extern template bool operator==(const PathIterator& lhs, - const PathIterator& rhs); - extern template bool operator==(const PathIterator& lhs, - const PathIterator& rhs); - extern template bool operator!=(const PathIterator& lhs, - const PathIterator& rhs); - extern template bool operator!=(const PathIterator& lhs, - const PathIterator& rhs); - extern template bool operator!=(const PathIterator& lhs, - const PathIterator& rhs); -} - - //! PathView implementation namespace AZ::IO { @@ -939,13 +895,13 @@ namespace AZ::IO // then it has no root directory nor filename if (rootNameView.end() == m_path.end()) { - // has_root_directory || has_filename = false - // If the root name is of the form - // # C: - then it isn't absolute unless it has a root directory C:\ - // # \\?\ = is a UNC path that can't exist without a root directory - // # \\server - Is absolute, but has no root directory - // Therefore if the rootName is larger than three characters - // then append the path separator + /* has_root_directory || has_filename = false + If the root name is of the form + C: - then it isn't absolute unless it has a root directory C:\. + \\?\ = is a UNC path that can't exist without a root directory. + \\server - Is absolute, but has no root directory. + Therefore if the rootName is larger than three characters + then append the path separator. */ if (rootNameView.size() >= 3) { m_path.push_back(m_preferred_separator); @@ -1550,3 +1506,39 @@ namespace AZ::IO return AZStd::hash{}(pathToHash); } } + +// extern instantiations of Path templates to prevent implicit instantiations +namespace AZ::IO +{ + // Swap function explicit declarations + extern template void swap(Path& lhs, Path& rhs) noexcept; + extern template void swap(FixedMaxPath& lhs, FixedMaxPath& rhs) noexcept; + + // Hash function explicit declarations + extern template size_t hash_value(const Path& pathToHash); + extern template size_t hash_value(const FixedMaxPath& pathToHash); + + // Append operator explicit declarations + extern template BasicPath operator/(const BasicPath& lhs, const PathView& rhs); + extern template BasicPath operator/(const BasicPath& lhs, const PathView& rhs); + extern template BasicPath operator/(const BasicPath& lhs, AZStd::string_view rhs); + extern template BasicPath operator/(const BasicPath& lhs, AZStd::string_view rhs); + extern template BasicPath operator/(const BasicPath& lhs, + const typename BasicPath::value_type* rhs); + extern template BasicPath operator/(const BasicPath& lhs, + const typename BasicPath::value_type* rhs); + + // Iterator compare explicit declarations + extern template bool operator==(const PathIterator& lhs, + const PathIterator& rhs); + extern template bool operator==(const PathIterator& lhs, + const PathIterator& rhs); + extern template bool operator==(const PathIterator& lhs, + const PathIterator& rhs); + extern template bool operator!=(const PathIterator& lhs, + const PathIterator& rhs); + extern template bool operator!=(const PathIterator& lhs, + const PathIterator& rhs); + extern template bool operator!=(const PathIterator& lhs, + const PathIterator& rhs); +} diff --git a/Code/Framework/AzCore/AzCore/IO/Streamer/BlockCache.cpp b/Code/Framework/AzCore/AzCore/IO/Streamer/BlockCache.cpp index 6c873f3050..ca38414eaa 100644 --- a/Code/Framework/AzCore/AzCore/IO/Streamer/BlockCache.cpp +++ b/Code/Framework/AzCore/AzCore/IO/Streamer/BlockCache.cpp @@ -137,18 +137,18 @@ namespace AZ::IO AZStd::visit([this, request](auto&& args) { using Command = AZStd::decay_t; - if constexpr (AZStd::is_same_v) + if constexpr (AZStd::is_same_v) { ReadFile(request, args); return; } else { - if constexpr (AZStd::is_same_v) + if constexpr (AZStd::is_same_v) { FlushCache(args.m_path); } - else if constexpr (AZStd::is_same_v) + else if constexpr (AZStd::is_same_v) { FlushEntireCache(); } @@ -166,7 +166,7 @@ namespace AZ::IO { Section& delayed = m_delayedSections.front(); AZ_Assert(delayed.m_parent, "Delayed section doesn't have a reference to the original request."); - auto data = AZStd::get_if(&delayed.m_parent->GetCommand()); + auto data = AZStd::get_if(&delayed.m_parent->GetCommand()); AZ_Assert(data, "A request in the delayed queue of the BlockCache didn't have a parent with read data."); // This call can add the same section to the back of the queue if there's not // enough space. Because of this the entry needs to be removed from the delayed @@ -233,7 +233,7 @@ namespace AZ::IO } } - void BlockCache::ReadFile(FileRequest* request, FileRequest::ReadData& data) + void BlockCache::ReadFile(FileRequest* request, Requests::ReadData& data) { if (!m_next) { @@ -250,7 +250,7 @@ namespace AZ::IO m_numMetaDataRetrievalInProgress--; if (fileSizeRequest.GetStatus() == IStreamerTypes::RequestStatus::Completed) { - auto& requestInfo = AZStd::get(fileSizeRequest.GetCommand()); + auto& requestInfo = AZStd::get(fileSizeRequest.GetCommand()); if (requestInfo.m_found) { ContinueReadFile(request, requestInfo.m_fileSize); @@ -272,7 +272,7 @@ namespace AZ::IO Section main; Section epilog; - auto& data = AZStd::get(request->GetCommand()); + auto& data = AZStd::get(request->GetCommand()); if (!SplitRequest(prolog, main, epilog, data.m_path, fileLength, data.m_offset, data.m_size, reinterpret_cast(data.m_output))) diff --git a/Code/Framework/AzCore/AzCore/IO/Streamer/BlockCache.h b/Code/Framework/AzCore/AzCore/IO/Streamer/BlockCache.h index 90fb7ea193..68aa2da689 100644 --- a/Code/Framework/AzCore/AzCore/IO/Streamer/BlockCache.h +++ b/Code/Framework/AzCore/AzCore/IO/Streamer/BlockCache.h @@ -21,6 +21,12 @@ namespace AZ::IO { + class RequestPath; + namespace Requests + { + struct ReadData; + } + struct BlockCacheConfig final : public IStreamerStackConfig { @@ -109,7 +115,7 @@ namespace AZ::IO using TimePoint = AZStd::chrono::system_clock::time_point; - void ReadFile(FileRequest* request, FileRequest::ReadData& data); + void ReadFile(FileRequest* request, Requests::ReadData& data); void ContinueReadFile(FileRequest* request, u64 fileLength); CacheResult ReadFromCache(FileRequest* request, Section& section, const RequestPath& filePath); CacheResult ReadFromCache(FileRequest* request, Section& section, u32 cacheBlock); diff --git a/Code/Framework/AzCore/AzCore/IO/Streamer/DedicatedCache.cpp b/Code/Framework/AzCore/AzCore/IO/Streamer/DedicatedCache.cpp index b80a1ea724..f155d26eef 100644 --- a/Code/Framework/AzCore/AzCore/IO/Streamer/DedicatedCache.cpp +++ b/Code/Framework/AzCore/AzCore/IO/Streamer/DedicatedCache.cpp @@ -101,12 +101,12 @@ namespace AZ::IO AZStd::visit([this, request](auto&& args) { using Command = AZStd::decay_t; - if constexpr (AZStd::is_same_v) + if constexpr (AZStd::is_same_v) { args.m_range = FileRange::CreateRangeForEntireFile(); m_context->PushPreparedRequest(request); } - else if constexpr (AZStd::is_same_v) + else if constexpr (AZStd::is_same_v) { args.m_range = FileRange::CreateRangeForEntireFile(); m_context->PushPreparedRequest(request); @@ -125,28 +125,28 @@ namespace AZ::IO AZStd::visit([this, request](auto&& args) { using Command = AZStd::decay_t; - if constexpr (AZStd::is_same_v) + if constexpr (AZStd::is_same_v) { ReadFile(request, args); return; } - else if constexpr (AZStd::is_same_v) + else if constexpr (AZStd::is_same_v) { CreateDedicatedCache(request, args); return; } - else if constexpr (AZStd::is_same_v) + else if constexpr (AZStd::is_same_v) { DestroyDedicatedCache(request, args); return; } else { - if constexpr (AZStd::is_same_v) + if constexpr (AZStd::is_same_v) { FlushCache(args.m_path); } - else if constexpr (AZStd::is_same_v) + else if constexpr (AZStd::is_same_v) { FlushEntireCache(); } @@ -200,7 +200,7 @@ namespace AZ::IO } } - void DedicatedCache::ReadFile(FileRequest* request, FileRequest::ReadData& data) + void DedicatedCache::ReadFile(FileRequest* request, Requests::ReadData& data) { size_t index = FindCache(data.m_path, data.m_offset); if (index == s_fileNotFound) @@ -255,7 +255,7 @@ namespace AZ::IO StreamStackEntry::CollectStatistics(statistics); } - void DedicatedCache::CreateDedicatedCache(FileRequest* request, FileRequest::CreateDedicatedCacheData& data) + void DedicatedCache::CreateDedicatedCache(FileRequest* request, Requests::CreateDedicatedCacheData& data) { size_t index = FindCache(data.m_path, data.m_range); if (index == s_fileNotFound) @@ -276,7 +276,7 @@ namespace AZ::IO m_context->MarkRequestAsCompleted(request); } - void DedicatedCache::DestroyDedicatedCache(FileRequest* request, FileRequest::DestroyDedicatedCacheData& data) + void DedicatedCache::DestroyDedicatedCache(FileRequest* request, Requests::DestroyDedicatedCacheData& data) { size_t index = FindCache(data.m_path, data.m_range); if (index != s_fileNotFound) diff --git a/Code/Framework/AzCore/AzCore/IO/Streamer/DedicatedCache.h b/Code/Framework/AzCore/AzCore/IO/Streamer/DedicatedCache.h index 0ef2d879d3..85aa29a051 100644 --- a/Code/Framework/AzCore/AzCore/IO/Streamer/DedicatedCache.h +++ b/Code/Framework/AzCore/AzCore/IO/Streamer/DedicatedCache.h @@ -11,15 +11,21 @@ #include #include #include -#include #include +#include #include -#include #include +#include #include namespace AZ::IO { + namespace Requests + { + struct CreateDedicatedCacheData; + struct DestroyDedicatedCacheData; + } // namespace Requests + struct DedicatedCacheConfig final : public IStreamerStackConfig { @@ -56,16 +62,19 @@ namespace AZ::IO void UpdateStatus(Status& status) const override; - void UpdateCompletionEstimates(AZStd::chrono::system_clock::time_point now, AZStd::vector& internalPending, - StreamerContext::PreparedQueue::iterator pendingBegin, StreamerContext::PreparedQueue::iterator pendingEnd) override; + void UpdateCompletionEstimates( + AZStd::chrono::system_clock::time_point now, + AZStd::vector& internalPending, + StreamerContext::PreparedQueue::iterator pendingBegin, + StreamerContext::PreparedQueue::iterator pendingEnd) override; void CollectStatistics(AZStd::vector& statistics) const override; private: - void CreateDedicatedCache(FileRequest* request, FileRequest::CreateDedicatedCacheData& data); - void DestroyDedicatedCache(FileRequest* request, FileRequest::DestroyDedicatedCacheData& data); + void CreateDedicatedCache(FileRequest* request, Requests::CreateDedicatedCacheData& data); + void DestroyDedicatedCache(FileRequest* request, Requests::DestroyDedicatedCacheData& data); - void ReadFile(FileRequest* request, FileRequest::ReadData& data); + void ReadFile(FileRequest* request, Requests::ReadData& data); size_t FindCache(const RequestPath& filename, FileRange range); size_t FindCache(const RequestPath& filename, u64 offset); diff --git a/Code/Framework/AzCore/AzCore/IO/Streamer/FileRequest.cpp b/Code/Framework/AzCore/AzCore/IO/Streamer/FileRequest.cpp index fc05b77b36..13c01b2efc 100644 --- a/Code/Framework/AzCore/AzCore/IO/Streamer/FileRequest.cpp +++ b/Code/Framework/AzCore/AzCore/IO/Streamer/FileRequest.cpp @@ -12,22 +12,30 @@ #include #include -namespace AZ::IO +// +// Command structures. +// + +namespace AZ::IO::Requests { - // - // Command structures. - // + ReadData::ReadData(void* output, u64 outputSize, const RequestPath& path, u64 offset, u64 size, bool sharedRead) + : m_path(path) + , m_output(output) + , m_outputSize(outputSize) + , m_offset(offset) + , m_size(size) + , m_sharedRead(sharedRead) + { + } - FileRequest::ExternalRequestData::ExternalRequestData(FileRequestPtr&& request) - : m_request(AZStd::move(request)) - {} - - FileRequest::RequestPathStoreData::RequestPathStoreData(RequestPath path) - : m_path(AZStd::move(path)) - {} - - FileRequest::ReadRequestData::ReadRequestData(RequestPath path, void* output, u64 outputSize, u64 offset, u64 size, - AZStd::chrono::system_clock::time_point deadline, IStreamerTypes::Priority priority) + ReadRequestData::ReadRequestData( + RequestPath path, + void* output, + u64 outputSize, + u64 offset, + u64 size, + AZStd::chrono::system_clock::time_point deadline, + IStreamerTypes::Priority priority) : m_path(AZStd::move(path)) , m_allocator(nullptr) , m_deadline(deadline) @@ -37,10 +45,16 @@ namespace AZ::IO , m_size(size) , m_priority(priority) , m_memoryType(IStreamerTypes::MemoryType::ReadWrite) // Only generic memory can be assigned externally. - {} + { + } - FileRequest::ReadRequestData::ReadRequestData(RequestPath path, IStreamerTypes::RequestMemoryAllocator* allocator, - u64 offset, u64 size, AZStd::chrono::system_clock::time_point deadline, IStreamerTypes::Priority priority) + ReadRequestData::ReadRequestData( + RequestPath path, + IStreamerTypes::RequestMemoryAllocator* allocator, + u64 offset, + u64 size, + AZStd::chrono::system_clock::time_point deadline, + IStreamerTypes::Priority priority) : m_path(AZStd::move(path)) , m_allocator(allocator) , m_deadline(deadline) @@ -50,9 +64,10 @@ namespace AZ::IO , m_size(size) , m_priority(priority) , m_memoryType(IStreamerTypes::MemoryType::ReadWrite) // Only generic memory can be assigned externally. - {} + { + } - FileRequest::ReadRequestData::~ReadRequestData() + ReadRequestData::~ReadRequestData() { if (m_allocator != nullptr) { @@ -64,65 +79,80 @@ namespace AZ::IO } } - FileRequest::ReadData::ReadData(void* output, u64 outputSize, const RequestPath& path, u64 offset, u64 size, bool sharedRead) - : m_output(output) - , m_outputSize(outputSize) - , m_path(path) - , m_offset(offset) - , m_size(size) - , m_sharedRead(sharedRead) - {} + CreateDedicatedCacheData::CreateDedicatedCacheData(RequestPath path, const FileRange& range) + : m_path(AZStd::move(path)) + , m_range(range) + { + } - FileRequest::CompressedReadData::CompressedReadData(CompressionInfo&& compressionInfo, void* output, u64 readOffset, u64 readSize) + DestroyDedicatedCacheData::DestroyDedicatedCacheData(RequestPath path, const FileRange& range) + : m_path(AZStd::move(path)) + , m_range(range) + { + } + + ExternalRequestData::ExternalRequestData(FileRequestPtr&& request) + : m_request(AZStd::move(request)) + { + } + + RequestPathStoreData::RequestPathStoreData(RequestPath path) + : m_path(AZStd::move(path)) + { + } + + CompressedReadData::CompressedReadData(CompressionInfo&& compressionInfo, void* output, u64 readOffset, u64 readSize) : m_compressionInfo(AZStd::move(compressionInfo)) , m_output(output) , m_readOffset(readOffset) , m_readSize(readSize) - {} + { + } - FileRequest::FileExistsCheckData::FileExistsCheckData(const RequestPath& path) + FileExistsCheckData::FileExistsCheckData(const RequestPath& path) : m_path(path) - {} + { + } - FileRequest::FileMetaDataRetrievalData::FileMetaDataRetrievalData(const RequestPath& path) + FileMetaDataRetrievalData::FileMetaDataRetrievalData(const RequestPath& path) : m_path(path) - {} + { + } - FileRequest::CancelData::CancelData(FileRequestPtr target) + CancelData::CancelData(FileRequestPtr target) : m_target(AZStd::move(target)) - {} + { + } - FileRequest::FlushData::FlushData(RequestPath path) + FlushData::FlushData(RequestPath path) : m_path(AZStd::move(path)) - {} + { + } - FileRequest::RescheduleData::RescheduleData(FileRequestPtr target, AZStd::chrono::system_clock::time_point newDeadline, + RescheduleData::RescheduleData( + FileRequestPtr target, + AZStd::chrono::system_clock::time_point newDeadline, IStreamerTypes::Priority newPriority) : m_target(AZStd::move(target)) , m_newDeadline(newDeadline) , m_newPriority(newPriority) - {} + { + } - FileRequest::CreateDedicatedCacheData::CreateDedicatedCacheData(RequestPath path, const FileRange& range) - : m_path(AZStd::move(path)) - , m_range(range) - {} - - FileRequest::DestroyDedicatedCacheData::DestroyDedicatedCacheData(RequestPath path, const FileRange& range) - : m_path(AZStd::move(path)) - , m_range(range) - {} - - FileRequest::ReportData::ReportData(ReportType reportType) + ReportData::ReportData(ReportType reportType) : m_reportType(reportType) - {} + { + } - FileRequest::CustomData::CustomData(AZStd::any data, bool failWhenUnhandled) + CustomData::CustomData(AZStd::any data, bool failWhenUnhandled) : m_data(AZStd::move(data)) , m_failWhenUnhandled(failWhenUnhandled) - {} - + { + } +} // namespace AZ::IO::Requests +namespace AZ::IO +{ // // FileRequest // @@ -145,14 +175,14 @@ namespace AZ::IO m_parent = request->m_request.m_parent; request->m_request.m_parent = this; m_dependencies++; - m_command.emplace(AZStd::move(request)); + m_command.emplace(AZStd::move(request)); } void FileRequest::CreateRequestPathStore(FileRequest* parent, RequestPath path) { AZ_Assert(AZStd::holds_alternative(m_command), "Attempting to set FileRequest to 'CreateRequestPathStore', but another task was already assigned."); - m_command.emplace(AZStd::move(path)); + m_command.emplace(AZStd::move(path)); SetOptionalParent(parent); } @@ -161,7 +191,7 @@ namespace AZ::IO { AZ_Assert(AZStd::holds_alternative(m_command), "Attempting to set FileRequest to 'ReadRequest', but another task was already assigned."); - m_command.emplace(AZStd::move(path), output, outputSize, offset, size, deadline, priority); + m_command.emplace(AZStd::move(path), output, outputSize, offset, size, deadline, priority); } void FileRequest::CreateReadRequest(RequestPath path, IStreamerTypes::RequestMemoryAllocator* allocator, u64 offset, u64 size, @@ -169,7 +199,7 @@ namespace AZ::IO { AZ_Assert(AZStd::holds_alternative(m_command), "Attempting to set FileRequest to 'ReadRequest', but another task was already assigned."); - m_command.emplace(AZStd::move(path), allocator, offset, size, deadline, priority); + m_command.emplace(AZStd::move(path), allocator, offset, size, deadline, priority); } void FileRequest::CreateRead(FileRequest* parent, void* output, u64 outputSize, const RequestPath& path, @@ -177,7 +207,7 @@ namespace AZ::IO { AZ_Assert(AZStd::holds_alternative(m_command), "Attempting to set FileRequest to 'Read', but another task was already assigned."); - m_command.emplace(output, outputSize, AZStd::move(path), offset, size, sharedRead); + m_command.emplace(output, outputSize, AZStd::move(path), offset, size, sharedRead); SetOptionalParent(parent); } @@ -192,7 +222,7 @@ namespace AZ::IO { AZ_Assert(AZStd::holds_alternative(m_command), "Attempting to set FileRequest to 'CompressedRead', but another task was already assigned."); - m_command.emplace(AZStd::move(compressionInfo), output, readOffset, readSize); + m_command.emplace(AZStd::move(compressionInfo), output, readOffset, readSize); SetOptionalParent(parent); } @@ -200,7 +230,7 @@ namespace AZ::IO { AZ_Assert(AZStd::holds_alternative(m_command), "Attempting to set FileRequest to 'Wait', but another task was already assigned."); - m_command.emplace(); + m_command.emplace(); SetOptionalParent(parent); } @@ -208,21 +238,21 @@ namespace AZ::IO { AZ_Assert(AZStd::holds_alternative(m_command), "Attempting to set FileRequest to 'FileExistsCheck', but another task was already assigned."); - m_command.emplace(path); + m_command.emplace(path); } void FileRequest::CreateFileMetaDataRetrieval(const RequestPath& path) { AZ_Assert(AZStd::holds_alternative(m_command), "Attempting to set FileRequest to 'FileMetaDataRetrieval', but another task was already assigned."); - m_command.emplace(path); + m_command.emplace(path); } void FileRequest::CreateCancel(FileRequestPtr target) { AZ_Assert(AZStd::holds_alternative(m_command), "Attempting to set FileRequest to 'Cancel', but another task was already assigned."); - m_command.emplace(AZStd::move(target)); + m_command.emplace(AZStd::move(target)); } void FileRequest::CreateReschedule(FileRequestPtr target, AZStd::chrono::system_clock::time_point newDeadline, @@ -230,28 +260,28 @@ namespace AZ::IO { AZ_Assert(AZStd::holds_alternative(m_command), "Attempting to set FileRequest to 'Reschedule', but another task was already assigned."); - m_command.emplace(AZStd::move(target), newDeadline, newPriority); + m_command.emplace(AZStd::move(target), newDeadline, newPriority); } void FileRequest::CreateFlush(RequestPath path) { AZ_Assert(AZStd::holds_alternative(m_command), "Attempting to set FileRequest to 'Flush', but another task was already assigned."); - m_command.emplace(AZStd::move(path)); + m_command.emplace(AZStd::move(path)); } void FileRequest::CreateFlushAll() { AZ_Assert(AZStd::holds_alternative(m_command), "Attempting to set FileRequest to 'FlushAll', but another task was already assigned."); - m_command.emplace(); + m_command.emplace(); } void FileRequest::CreateDedicatedCacheCreation(RequestPath path, const FileRange& range, FileRequest* parent) { AZ_Assert(AZStd::holds_alternative(m_command), "Attempting to set FileRequest to 'CreateDedicateCache', but another task was already assigned."); - m_command.emplace(AZStd::move(path), range); + m_command.emplace(AZStd::move(path), range); SetOptionalParent(parent); } @@ -259,22 +289,22 @@ namespace AZ::IO { AZ_Assert(AZStd::holds_alternative(m_command), "Attempting to set FileRequest to 'DestroyDedicateCache', but another task was already assigned."); - m_command.emplace(AZStd::move(path), range); + m_command.emplace(AZStd::move(path), range); SetOptionalParent(parent); } - void FileRequest::CreateReport(ReportData::ReportType reportType) + void FileRequest::CreateReport(Requests::ReportType reportType) { AZ_Assert(AZStd::holds_alternative(m_command), "Attempting to set FileRequest to 'Report', but another task was already assigned."); - m_command.emplace(reportType); + m_command.emplace(reportType); } void FileRequest::CreateCustom(AZStd::any data, bool failWhenUnhandled, FileRequest* parent) { AZ_Assert(AZStd::holds_alternative(m_command), "Attempting to set FileRequest to 'Custom', but another task was already assigned."); - m_command.emplace(AZStd::move(data), failWhenUnhandled); + m_command.emplace(AZStd::move(data), failWhenUnhandled); SetOptionalParent(parent); } @@ -361,7 +391,7 @@ namespace AZ::IO "Request does not contain a valid command. It may have been reset already or was never assigned a command."); return true; } - else if constexpr (AZStd::is_same_v) + else if constexpr (AZStd::is_same_v) { return args.m_failWhenUnhandled; } @@ -398,7 +428,7 @@ namespace AZ::IO const FileRequest* current = this; while (current) { - auto* link = AZStd::get_if(¤t->m_command); + auto* link = AZStd::get_if(¤t->m_command); if (!link) { current = current->m_parent; diff --git a/Code/Framework/AzCore/AzCore/IO/Streamer/FileRequest.h b/Code/Framework/AzCore/AzCore/IO/Streamer/FileRequest.h index dd4dad2387..7f5874c95d 100644 --- a/Code/Framework/AzCore/AzCore/IO/Streamer/FileRequest.h +++ b/Code/Framework/AzCore/AzCore/IO/Streamer/FileRequest.h @@ -27,7 +27,252 @@ namespace AZ::IO class ExternalFileRequest; using FileRequestPtr = AZStd::intrusive_ptr; +} // namespace AZ::IO +namespace AZ::IO::Requests +{ + //! Request to read data. This is a translated request and holds an absolute path and has been + //! resolved to the archive file if needed. + struct ReadData + { + inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium; + inline constexpr static bool s_failWhenUnhandled = true; + + ReadData(void* output, u64 outputSize, const RequestPath& path, u64 offset, u64 size, bool sharedRead); + + const RequestPath& m_path; //!< The path to the file that contains the requested data. + void* m_output; //!< Target output to write the read data to. + u64 m_outputSize; //!< Size of memory m_output points to. This needs to be at least as big as m_size, but can be bigger. + u64 m_offset; //!< The offset in bytes into the file. + u64 m_size; //!< The number of bytes to read from the file. + bool m_sharedRead; //!< True if other code will be reading from the file or the stack entry can exclusively lock. + }; + + //! Request to read data. This is an untranslated request and holds a relative path. The Scheduler + //! will translate this to the appropriate ReadData or CompressedReadData. + struct ReadRequestData + { + inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium; + inline constexpr static bool s_failWhenUnhandled = true; + + ReadRequestData( + RequestPath path, + void* output, + u64 outputSize, + u64 offset, + u64 size, + AZStd::chrono::system_clock::time_point deadline, + IStreamerTypes::Priority priority); + ReadRequestData( + RequestPath path, + IStreamerTypes::RequestMemoryAllocator* allocator, + u64 offset, + u64 size, + AZStd::chrono::system_clock::time_point deadline, + IStreamerTypes::Priority priority); + ~ReadRequestData(); + + RequestPath m_path; //!< Relative path to the target file. + IStreamerTypes::RequestMemoryAllocator* m_allocator; //!< Allocator used to manage the memory for this request. + AZStd::chrono::system_clock::time_point m_deadline; //!< Time by which this request should have been completed. + void* m_output; //!< The memory address assigned (during processing) to store the read data to. + u64 m_outputSize; //!< The memory size of the addressed used to store the read data. + u64 m_offset; //!< The offset in bytes into the file. + u64 m_size; //!< The number of bytes to read from the file. + IStreamerTypes::Priority m_priority; //!< Priority used for ordering requests. This is used when requests have the same deadline. + IStreamerTypes::MemoryType m_memoryType; //!< The type of memory provided by the allocator if used. + }; + + //! Creates a cache dedicated to a single file. This is best used for files where blocks are read from + //! periodically such as audio banks of video files. + struct CreateDedicatedCacheData + { + inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh; + inline constexpr static bool s_failWhenUnhandled = false; + + CreateDedicatedCacheData(RequestPath path, const FileRange& range); + + RequestPath m_path; + FileRange m_range; + }; + + //! Destroys a cache dedicated to a single file that was previously created by CreateDedicatedCache + struct DestroyDedicatedCacheData + { + inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh; + inline constexpr static bool s_failWhenUnhandled = false; + + DestroyDedicatedCacheData(RequestPath path, const FileRange& range); + + RequestPath m_path; + FileRange m_range; + }; + + enum class ReportType : int8_t + { + FileLocks + }; + + struct ReportData + { + inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityLow; + inline constexpr static bool s_failWhenUnhandled = false; + + explicit ReportData(ReportType reportType); + + ReportType m_reportType; + }; + + //! Stores a reference to the external request so it stays alive while the request is being processed. + //! This is needed because Streamer supports fire-and-forget requests since completion can be handled by + //! registering a callback. + struct ExternalRequestData + { + inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium; + inline constexpr static bool s_failWhenUnhandled = true; + + explicit ExternalRequestData(FileRequestPtr&& request); + + FileRequestPtr m_request; //!< The request that was send to Streamer. + }; + + //! Stores an instance of a RequestPath. To reduce copying instances of a RequestPath functions that + //! need a path take them by reference to the original request. In some cases a path originates from + //! within in the stack and temporary storage is needed. This struct allows for that temporary storage + //! so it can be safely referenced later. + struct RequestPathStoreData + { + inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium; + inline constexpr static bool s_failWhenUnhandled = true; + + explicit RequestPathStoreData(RequestPath path); + + RequestPath m_path; + }; + + //! Request to read and decompress data. + struct CompressedReadData + { + inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium; + inline constexpr static bool s_failWhenUnhandled = true; + + CompressedReadData(CompressionInfo&& compressionInfo, void* output, u64 readOffset, u64 readSize); + + CompressionInfo m_compressionInfo; + void* m_output; //!< Target output to write the read data to. + u64 m_readOffset; //!< The offset into the decompressed to start copying from. + u64 m_readSize; //!< Number of bytes to read from the decompressed file. + }; + + //! Holds the progress of an operation chain until this request is explicitly completed. + struct WaitData + { + inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium; + inline constexpr static bool s_failWhenUnhandled = true; + }; + + //! Checks to see if any node in the stack can find a file at the provided path. + struct FileExistsCheckData + { + inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh; + inline constexpr static bool s_failWhenUnhandled = false; + + explicit FileExistsCheckData(const RequestPath& path); + + const RequestPath& m_path; + bool m_found{ false }; + }; + + //! Searches for a file in the stack and retrieves the meta data. This may be slower than a file exists + //! check. + struct FileMetaDataRetrievalData + { + inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh; + inline constexpr static bool s_failWhenUnhandled = false; + + explicit FileMetaDataRetrievalData(const RequestPath& path); + + const RequestPath& m_path; + u64 m_fileSize{ 0 }; + bool m_found{ false }; + }; + + //! Cancels a request in the stream stack, if possible. + struct CancelData + { + inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHighest; + inline constexpr static bool s_failWhenUnhandled = false; + + explicit CancelData(FileRequestPtr target); + + FileRequestPtr m_target; //!< The request that will be canceled. + }; + + //! Updates the priority and deadline of a request that has not been queued yet. + struct RescheduleData + { + inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh; + inline constexpr static bool s_failWhenUnhandled = false; + + RescheduleData(FileRequestPtr target, AZStd::chrono::system_clock::time_point newDeadline, IStreamerTypes::Priority newPriority); + + FileRequestPtr m_target; //!< The request that will be rescheduled. + AZStd::chrono::system_clock::time_point m_newDeadline; //!< The new deadline for the request. + IStreamerTypes::Priority m_newPriority; //!< The new priority for the request. + }; + + //! Flushes all references to the provided file in the streaming stack. + struct FlushData + { + inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh; + inline constexpr static bool s_failWhenUnhandled = false; + + explicit FlushData(RequestPath path); + + RequestPath m_path; + }; + + //! Flushes all caches in the streaming stack. + struct FlushAllData + { + inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh; + inline constexpr static bool s_failWhenUnhandled = false; + }; + + //! Data for a custom command. This can be used by nodes added extensions that need data that can't be stored + //! in the already provided data. + struct CustomData + { + inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium; + + CustomData(AZStd::any data, bool failWhenUnhandled); + + AZStd::any m_data; //!< The data for the custom request. + bool m_failWhenUnhandled; //!< Whether or not the request is marked as failed or success when no node process it. + }; + using CommandVariant = AZStd::variant< + AZStd::monostate, + ExternalRequestData, + RequestPathStoreData, + ReadRequestData, + ReadData, + CompressedReadData, + WaitData, + FileExistsCheckData, + FileMetaDataRetrievalData, + CancelData, + RescheduleData, + FlushData, + FlushAllData, + CreateDedicatedCacheData, + DestroyDedicatedCacheData, + ReportData, + CustomData>; + +} // namespace AZ::IO::Requests + +namespace AZ::IO +{ class FileRequest final { public: @@ -36,218 +281,7 @@ namespace AZ::IO friend class StreamerContext; friend class ExternalFileRequest; - //! Stores a reference to the external request so it stays alive while the request is being processed. - //! This is needed because Streamer supports fire-and-forget requests since completion can be handled by - //! registering a callback. - struct ExternalRequestData - { - inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium; - inline constexpr static bool s_failWhenUnhandled = true; - - explicit ExternalRequestData(FileRequestPtr&& request); - - FileRequestPtr m_request; //!< The request that was send to Streamer. - }; - - //! Stores an instance of a RequestPath. To reduce copying instances of a RequestPath functions that - //! need a path take them by reference to the original request. In some cases a path originates from - //! within in the stack and temporary storage is needed. This struct allows for that temporary storage - //! so it can be safely referenced later. - struct RequestPathStoreData - { - inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium; - inline constexpr static bool s_failWhenUnhandled = true; - - explicit RequestPathStoreData(RequestPath path); - - RequestPath m_path; - }; - - //! Request to read data. This is an untranslated request and holds a relative path. The Scheduler - //! will translate this to the appropriate ReadData or CompressedReadData. - struct ReadRequestData - { - inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium; - inline constexpr static bool s_failWhenUnhandled = true; - - ReadRequestData(RequestPath path, void* output, u64 outputSize, u64 offset, u64 size, - AZStd::chrono::system_clock::time_point deadline, IStreamerTypes::Priority priority); - ReadRequestData(RequestPath path, IStreamerTypes::RequestMemoryAllocator* allocator, u64 offset, u64 size, - AZStd::chrono::system_clock::time_point deadline, IStreamerTypes::Priority priority); - ~ReadRequestData(); - - RequestPath m_path; //!< Relative path to the target file. - IStreamerTypes::RequestMemoryAllocator* m_allocator; //!< Allocator used to manage the memory for this request. - AZStd::chrono::system_clock::time_point m_deadline; //!< Time by which this request should have been completed. - void* m_output; //!< The memory address assigned (during processing) to store the read data to. - u64 m_outputSize; //!< The memory size of the addressed used to store the read data. - u64 m_offset; //!< The offset in bytes into the file. - u64 m_size; //!< The number of bytes to read from the file. - IStreamerTypes::Priority m_priority; //!< Priority used for ordering requests. This is used when requests have the same deadline. - IStreamerTypes::MemoryType m_memoryType; //!< The type of memory provided by the allocator if used. - }; - - //! Request to read data. This is a translated request and holds an absolute path and has been - //! resolved to the archive file if needed. - struct ReadData - { - inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium; - inline constexpr static bool s_failWhenUnhandled = true; - - ReadData(void* output, u64 outputSize, const RequestPath& path, u64 offset, u64 size, bool sharedRead); - - const RequestPath& m_path; //!< The path to the file that contains the requested data. - void* m_output; //!< Target output to write the read data to. - u64 m_outputSize; //!< Size of memory m_output points to. This needs to be at least as big as m_size, but can be bigger. - u64 m_offset; //!< The offset in bytes into the file. - u64 m_size; //!< The number of bytes to read from the file. - bool m_sharedRead; //!< True if other code will be reading from the file or the stack entry can exclusively lock. - }; - - //! Request to read and decompress data. - struct CompressedReadData - { - inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium; - inline constexpr static bool s_failWhenUnhandled = true; - - CompressedReadData(CompressionInfo&& compressionInfo, void* output, u64 readOffset, u64 readSize); - - CompressionInfo m_compressionInfo; - void* m_output; //!< Target output to write the read data to. - u64 m_readOffset; //!< The offset into the decompressed to start copying from. - u64 m_readSize; //!< Number of bytes to read from the decompressed file. - }; - - //! Holds the progress of an operation chain until this request is explicitly completed. - struct WaitData - { - inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium; - inline constexpr static bool s_failWhenUnhandled = true; - }; - - //! Checks to see if any node in the stack can find a file at the provided path. - struct FileExistsCheckData - { - inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh; - inline constexpr static bool s_failWhenUnhandled = false; - - explicit FileExistsCheckData(const RequestPath& path); - - const RequestPath& m_path; - bool m_found{ false }; - }; - - //! Searches for a file in the stack and retrieves the meta data. This may be slower than a file exists - //! check. - struct FileMetaDataRetrievalData - { - inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh; - inline constexpr static bool s_failWhenUnhandled = false; - - explicit FileMetaDataRetrievalData(const RequestPath& path); - - const RequestPath& m_path; - u64 m_fileSize{ 0 }; - bool m_found{ false }; - }; - - //! Cancels a request in the stream stack, if possible. - struct CancelData - { - inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHighest; - inline constexpr static bool s_failWhenUnhandled = false; - - explicit CancelData(FileRequestPtr target); - - FileRequestPtr m_target; //!< The request that will be canceled. - }; - - //! Updates the priority and deadline of a request that has not been queued yet. - struct RescheduleData - { - inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh; - inline constexpr static bool s_failWhenUnhandled = false; - - RescheduleData(FileRequestPtr target, AZStd::chrono::system_clock::time_point newDeadline, IStreamerTypes::Priority newPriority); - - FileRequestPtr m_target; //!< The request that will be rescheduled. - AZStd::chrono::system_clock::time_point m_newDeadline; //!< The new deadline for the request. - IStreamerTypes::Priority m_newPriority; //!< The new priority for the request. - }; - - //! Flushes all references to the provided file in the streaming stack. - struct FlushData - { - inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh; - inline constexpr static bool s_failWhenUnhandled = false; - - explicit FlushData(RequestPath path); - - RequestPath m_path; - }; - - //! Flushes all caches in the streaming stack. - struct FlushAllData - { - inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh; - inline constexpr static bool s_failWhenUnhandled = false; - }; - - //! Creates a cache dedicated to a single file. This is best used for files where blocks are read from - //! periodically such as audio banks of video files. - struct CreateDedicatedCacheData - { - inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh; - inline constexpr static bool s_failWhenUnhandled = false; - - CreateDedicatedCacheData(RequestPath path, const FileRange& range); - - RequestPath m_path; - FileRange m_range; - }; - - //! Destroys a cache dedicated to a single file that was previously created by CreateDedicatedCache - struct DestroyDedicatedCacheData - { - inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh; - inline constexpr static bool s_failWhenUnhandled = false; - - DestroyDedicatedCacheData(RequestPath path, const FileRange& range); - - RequestPath m_path; - FileRange m_range; - }; - - struct ReportData - { - inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityLow; - inline constexpr static bool s_failWhenUnhandled = false; - - enum class ReportType - { - FileLocks - }; - - explicit ReportData(ReportType reportType); - - ReportType m_reportType; - }; - - //! Data for a custom command. This can be used by nodes added extensions that need data that can't be stored - //! in the already provided data. - struct CustomData - { - inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium; - - CustomData(AZStd::any data, bool failWhenUnhandled); - - AZStd::any m_data; //!< The data for the custom request. - bool m_failWhenUnhandled; //!< Whether or not the request is marked as failed or success when no node process it. - }; - - using CommandVariant = AZStd::variant; + using CommandVariant = Requests::CommandVariant; using OnCompletionCallback = AZStd::function; AZ_CLASS_ALLOCATOR(FileRequest, SystemAllocator, 0); @@ -278,7 +312,7 @@ namespace AZ::IO void CreateFlushAll(); void CreateDedicatedCacheCreation(RequestPath path, const FileRange& range = {}, FileRequest* parent = nullptr); void CreateDedicatedCacheDestruction(RequestPath path, const FileRange& range = {}, FileRequest* parent = nullptr); - void CreateReport(ReportData::ReportType reportType); + void CreateReport(Requests::ReportType reportType); void CreateCustom(AZStd::any data, bool failWhenUnhandled = true, FileRequest* parent = nullptr); void SetCompletionCallback(OnCompletionCallback callback); @@ -325,8 +359,17 @@ namespace AZ::IO //! Command and parameters for the request. CommandVariant m_command; - //! Status of the request. - AZStd::atomic m_status{ IStreamerTypes::RequestStatus::Pending }; + //! Estimated time this request will complete. This is an estimation and depends on many + //! factors which can cause it to change drastically from moment to moment. + AZStd::chrono::system_clock::time_point m_estimatedCompletion; + + //! The file request that has a dependency on this one. This can be null if there are no + //! other request depending on this one to complete. + FileRequest* m_parent{ nullptr }; + + + //! Id assigned when the request is added to the pending queue. + size_t m_pendingId{ 0 }; //! Called once the request has completed. This will always be called from the Streamer thread //! and thread safety is the responsibility of called function. When assigning a lambda avoid @@ -336,16 +379,8 @@ namespace AZ::IO //! a longer running task is needed consider using a job to do the work. OnCompletionCallback m_onCompletion; - //! Estimated time this request will complete. This is an estimation and depends on many - //! factors which can cause it to change drastically from moment to moment. - AZStd::chrono::system_clock::time_point m_estimatedCompletion; - - //! The file request that has a dependency on this one. This can be null if there are no - //! other request depending on this one to complete. - FileRequest* m_parent{ nullptr }; - - //! Id assigned when the request is added to the pending queue. - size_t m_pendingId{ 0 }; + //! Status of the request. + AZStd::atomic m_status{ IStreamerTypes::RequestStatus::Pending }; //! The number of dependent file request that need to complete before this one is done. u16 m_dependencies{ 0 }; diff --git a/Code/Framework/AzCore/AzCore/IO/Streamer/FullFileDecompressor.cpp b/Code/Framework/AzCore/AzCore/IO/Streamer/FullFileDecompressor.cpp index 723a5d62c8..5087702c47 100644 --- a/Code/Framework/AzCore/AzCore/IO/Streamer/FullFileDecompressor.cpp +++ b/Code/Framework/AzCore/AzCore/IO/Streamer/FullFileDecompressor.cpp @@ -91,12 +91,12 @@ namespace AZ::IO AZStd::visit([this, request](auto&& args) { using Command = AZStd::decay_t; - if constexpr (AZStd::is_same_v) + if constexpr (AZStd::is_same_v) { PrepareReadRequest(request, args); } - else if constexpr (AZStd::is_same_v || - AZStd::is_same_v) + else if constexpr (AZStd::is_same_v || + AZStd::is_same_v) { PrepareDedicatedCache(request, args.m_path); } @@ -114,11 +114,11 @@ namespace AZ::IO AZStd::visit([this, request](auto&& args) { using Command = AZStd::decay_t; - if constexpr (AZStd::is_same_v) + if constexpr (AZStd::is_same_v) { m_pendingReads.push_back(request); } - else if constexpr (AZStd::is_same_v) + else if constexpr (AZStd::is_same_v) { m_pendingFileExistChecks.push_back(request); } @@ -203,7 +203,7 @@ namespace AZ::IO { FileRequest* compressedRequest = m_processingJobs[i].m_waitRequest->GetParent(); AZ_Assert(compressedRequest, "A wait request attached to FullFileDecompressor was completed but didn't have a parent compressed request."); - auto data = AZStd::get_if(&compressedRequest->GetCommand()); + auto data = AZStd::get_if(&compressedRequest->GetCommand()); AZ_Assert(data, "Compressed request in the decompression queue in FullFileDecompressor didn't contain compression read data."); size_t bytesToDecompress = data->m_compressionInfo.m_compressedSize; @@ -255,7 +255,7 @@ namespace AZ::IO // Calculate the amount of time it will take to decompress the data. FileRequest* compressedRequest = m_readRequests[i]->GetParent(); - auto data = AZStd::get_if(&compressedRequest->GetCommand()); + auto data = AZStd::get_if(&compressedRequest->GetCommand()); size_t bytesToDecompress = data->m_compressionInfo.m_compressedSize; auto decompressionDuration = AZStd::chrono::microseconds( @@ -290,7 +290,7 @@ namespace AZ::IO void FullFileDecompressor::EstimateCompressedReadRequest(FileRequest* request, AZStd::chrono::microseconds& cumulativeDelay, AZStd::chrono::microseconds decompressionDelay, double totalDecompressionDurationUs, double totalBytesDecompressed) const { - auto data = AZStd::get_if(&request->GetCommand()); + auto data = AZStd::get_if(&request->GetCommand()); if (data) { AZStd::chrono::microseconds processingTime = decompressionDelay; @@ -343,7 +343,7 @@ namespace AZ::IO m_numRunningJobs == 0; } - void FullFileDecompressor::PrepareReadRequest(FileRequest* request, FileRequest::ReadRequestData& data) + void FullFileDecompressor::PrepareReadRequest(FileRequest* request, Requests::ReadRequestData& data) { CompressionInfo info; if (CompressionUtils::FindCompressionInfo(info, data.m_path.GetRelativePath())) @@ -359,7 +359,7 @@ namespace AZ::IO { FileRequest* pathStorageRequest = m_context->GetNewInternalRequest(); pathStorageRequest->CreateRequestPathStore(request, AZStd::move(info.m_archiveFilename)); - auto& pathStorage = AZStd::get(pathStorageRequest->GetCommand()); + auto& pathStorage = AZStd::get(pathStorageRequest->GetCommand()); nextRequest->CreateRead(pathStorageRequest, data.m_output, data.m_outputSize, pathStorage.m_path, info.m_offset + data.m_offset, data.m_size, info.m_isSharedPak); @@ -370,13 +370,13 @@ namespace AZ::IO auto callback = [this, nextRequest](const FileRequest& checkRequest) { AZ_PROFILE_FUNCTION(AzCore); - auto check = AZStd::get_if(&checkRequest.GetCommand()); + auto check = AZStd::get_if(&checkRequest.GetCommand()); AZ_Assert(check, "Callback in FullFileDecompressor::PrepareReadRequest expected FileExistsCheck but got another command."); if (check->m_found) { FileRequest* originalRequest = m_context->RejectRequest(nextRequest); - if (AZStd::holds_alternative(originalRequest->GetCommand())) + if (AZStd::holds_alternative(originalRequest->GetCommand())) { originalRequest = m_context->RejectRequest(originalRequest); } @@ -412,12 +412,12 @@ namespace AZ::IO AZStd::visit([request, &info, nextRequest](auto&& args) { using Command = AZStd::decay_t; - if constexpr (AZStd::is_same_v) + if constexpr (AZStd::is_same_v) { nextRequest->CreateDedicatedCacheCreation(AZStd::move(info.m_archiveFilename), FileRange::CreateRange(info.m_offset, info.m_compressedSize), request); } - else if constexpr (AZStd::is_same_v) + else if constexpr (AZStd::is_same_v) { nextRequest->CreateDedicatedCacheDestruction(AZStd::move(info.m_archiveFilename), FileRange::CreateRange(info.m_offset, info.m_compressedSize), request); @@ -429,7 +429,7 @@ namespace AZ::IO auto callback = [this, nextRequest](const FileRequest& checkRequest) { AZ_PROFILE_FUNCTION(AzCore); - auto check = AZStd::get_if(&checkRequest.GetCommand()); + auto check = AZStd::get_if(&checkRequest.GetCommand()); AZ_Assert(check, "Callback in FullFileDecompressor::PrepareDedicatedCache expected FileExistsCheck but got another command."); if (check->m_found) @@ -461,7 +461,7 @@ namespace AZ::IO void FullFileDecompressor::FileExistsCheck(FileRequest* checkRequest) { - auto& fileCheckRequest = AZStd::get(checkRequest->GetCommand()); + auto& fileCheckRequest = AZStd::get(checkRequest->GetCommand()); CompressionInfo info; if (CompressionUtils::FindCompressionInfo(info, fileCheckRequest.m_path.GetRelativePath())) { @@ -487,7 +487,7 @@ namespace AZ::IO { if (m_readBufferStatus[i] == ReadBufferStatus::Unused) { - auto data = AZStd::get_if(&compressedReadRequest->GetCommand()); + auto data = AZStd::get_if(&compressedReadRequest->GetCommand()); AZ_Assert(data, "Compressed request that's starting a read in FullFileDecompressor didn't contain compression read data."); AZ_Assert(data->m_compressionInfo.m_decompressor, "FileRequest for FullFileDecompressor is missing a decompression callback."); @@ -549,7 +549,7 @@ namespace AZ::IO } else { - auto data = AZStd::get_if(&compressedRequest->GetCommand()); + auto data = AZStd::get_if(&compressedRequest->GetCommand()); AZ_Assert(data, "Compressed request in FullFileDecompressor that finished unsuccessfully didn't contain compression read data."); CompressionInfo& info = data->m_compressionInfo; size_t offsetAdjustment = info.m_offset - AZ_SIZE_ALIGN_DOWN(info.m_offset, aznumeric_cast(m_alignment)); @@ -591,7 +591,7 @@ namespace AZ::IO } FileRequest* waitRequest = m_readRequests[readSlot]; - AZ_Assert(AZStd::holds_alternative(waitRequest->GetCommand()), + AZ_Assert(AZStd::holds_alternative(waitRequest->GetCommand()), "File request waiting for decompression wasn't marked as being a wait operation."); FileRequest* compressedRequest = waitRequest->GetParent(); AZ_Assert(compressedRequest, "Read requests started by FullFileDecompressor is missing a parent request."); @@ -610,7 +610,7 @@ namespace AZ::IO m_readBuffers[readSlot] = nullptr; AZ::Job* decompressionJob; - auto data = AZStd::get_if(&compressedRequest->GetCommand()); + auto data = AZStd::get_if(&compressedRequest->GetCommand()); AZ_Assert(data, "Compressed request in FullFileDecompressor that's starting decompression didn't contain compression read data."); AZ_Assert(data->m_compressionInfo.m_decompressor, "FullFileDecompressor is queuing a decompression job but couldn't find a decompressor."); @@ -664,7 +664,7 @@ namespace AZ::IO FileRequest* compressedRequest = jobInfo.m_waitRequest->GetParent(); AZ_Assert(compressedRequest, "A wait request attached to FullFileDecompressor was completed but didn't have a parent compressed request."); - auto data = AZStd::get_if(&compressedRequest->GetCommand()); + auto data = AZStd::get_if(&compressedRequest->GetCommand()); AZ_Assert(data, "Compressed request in FullFileDecompressor that completed decompression didn't contain compression read data."); CompressionInfo& info = data->m_compressionInfo; size_t offsetAdjustment = info.m_offset - AZ_SIZE_ALIGN_DOWN(info.m_offset, aznumeric_cast(m_alignment)); @@ -694,7 +694,7 @@ namespace AZ::IO FileRequest* compressedRequest = info.m_waitRequest->GetParent(); AZ_Assert(compressedRequest, "A wait request attached to FullFileDecompressor was completed but didn't have a parent compressed request."); - auto request = AZStd::get_if(&compressedRequest->GetCommand()); + auto request = AZStd::get_if(&compressedRequest->GetCommand()); AZ_Assert(request, "Compressed request in FullFileDecompressor that's running full decompression didn't contain compression read data."); CompressionInfo& compressionInfo = request->m_compressionInfo; AZ_Assert(compressionInfo.m_decompressor, "Full decompressor job started, but there's no decompressor callback assigned."); @@ -719,7 +719,7 @@ namespace AZ::IO FileRequest* compressedRequest = info.m_waitRequest->GetParent(); AZ_Assert(compressedRequest, "A wait request attached to FullFileDecompressor was completed but didn't have a parent compressed request."); - auto request = AZStd::get_if(&compressedRequest->GetCommand()); + auto request = AZStd::get_if(&compressedRequest->GetCommand()); AZ_Assert(request, "Compressed request in FullFileDecompressor that's running partial decompression didn't contain compression read data."); CompressionInfo& compressionInfo = request->m_compressionInfo; AZ_Assert(compressionInfo.m_decompressor, "Partial decompressor job started, but there's no decompressor callback assigned."); diff --git a/Code/Framework/AzCore/AzCore/IO/Streamer/FullFileDecompressor.h b/Code/Framework/AzCore/AzCore/IO/Streamer/FullFileDecompressor.h index d9bd68f1a1..cb4226fd7c 100644 --- a/Code/Framework/AzCore/AzCore/IO/Streamer/FullFileDecompressor.h +++ b/Code/Framework/AzCore/AzCore/IO/Streamer/FullFileDecompressor.h @@ -21,6 +21,11 @@ namespace AZ::IO { + namespace Requests + { + struct ReadRequestData; + } + struct FullFileDecompressorConfig final : public IStreamerStackConfig { @@ -87,7 +92,7 @@ namespace AZ::IO bool IsIdle() const; - void PrepareReadRequest(FileRequest* request, FileRequest::ReadRequestData& data); + void PrepareReadRequest(FileRequest* request, Requests::ReadRequestData& data); void PrepareDedicatedCache(FileRequest* request, const RequestPath& path); void FileExistsCheck(FileRequest* checkRequest); diff --git a/Code/Framework/AzCore/AzCore/IO/Streamer/ReadSplitter.cpp b/Code/Framework/AzCore/AzCore/IO/Streamer/ReadSplitter.cpp index a952e31a93..282a1e15c9 100644 --- a/Code/Framework/AzCore/AzCore/IO/Streamer/ReadSplitter.cpp +++ b/Code/Framework/AzCore/AzCore/IO/Streamer/ReadSplitter.cpp @@ -118,7 +118,7 @@ namespace AZ::IO return; } - auto data = AZStd::get_if(&request->GetCommand()); + auto data = AZStd::get_if(&request->GetCommand()); if (data == nullptr) { StreamStackEntry::QueueRequest(request); @@ -156,7 +156,7 @@ namespace AZ::IO void ReadSplitter::QueueAlignedRead(FileRequest* request) { - auto data = AZStd::get_if(&request->GetCommand()); + auto data = AZStd::get_if(&request->GetCommand()); AZ_Assert(data != nullptr, "Provided request to queue by the Read Splitter did not contain a read command."); if (data->m_size <= m_maxReadSize) @@ -187,7 +187,7 @@ namespace AZ::IO bool ReadSplitter::QueueAlignedRead(PendingRead& pending) { - auto data = AZStd::get_if(&pending.m_request->GetCommand()); + auto data = AZStd::get_if(&pending.m_request->GetCommand()); AZ_Assert(data != nullptr, "Provided request to queue by the Read Splitter did not contain a read command."); while (pending.m_readSize > 0) @@ -237,7 +237,7 @@ namespace AZ::IO void ReadSplitter::QueueBufferedRead(FileRequest* request) { - auto data = AZStd::get_if(&request->GetCommand()); + auto data = AZStd::get_if(&request->GetCommand()); AZ_Assert(data != nullptr, "Provided request to queue by the Read Splitter did not contain a read command."); PendingRead pendingRead; @@ -262,7 +262,7 @@ namespace AZ::IO bool ReadSplitter::QueueBufferedRead(PendingRead& pending) { - auto data = AZStd::get_if(&pending.m_request->GetCommand()); + auto data = AZStd::get_if(&pending.m_request->GetCommand()); AZ_Assert(data != nullptr, "Provided request to queue by the Read Splitter did not contain a read command."); while (pending.m_readSize > 0) diff --git a/Code/Framework/AzCore/AzCore/IO/Streamer/Scheduler.cpp b/Code/Framework/AzCore/AzCore/IO/Streamer/Scheduler.cpp index fe1d5a5eda..fba9c3c98a 100644 --- a/Code/Framework/AzCore/AzCore/IO/Streamer/Scheduler.cpp +++ b/Code/Framework/AzCore/AzCore/IO/Streamer/Scheduler.cpp @@ -6,9 +6,11 @@ * */ +#include + #include #include -#include +#include #include #include @@ -35,6 +37,8 @@ namespace AZ::IO m_threadData.m_streamStack = AZStd::move(streamStack); } + Scheduler::~Scheduler() = default; + void Scheduler::Start(const AZStd::thread_desc& threadDesc) { if (!m_isRunning) @@ -222,10 +226,10 @@ namespace AZ::IO { using Command = AZStd::decay_t; if constexpr ( - AZStd::is_same_v || - AZStd::is_same_v) + AZStd::is_same_v || + AZStd::is_same_v) { - auto parentReadRequest = next->GetCommandFromChain(); + auto parentReadRequest = next->GetCommandFromChain(); AZ_Assert(parentReadRequest != nullptr, "The issued read request can't be found for the (compressed) read command."); size_t size = parentReadRequest->m_size; @@ -234,7 +238,7 @@ namespace AZ::IO AZ_Assert(parentReadRequest->m_allocator, "The read request was issued without a memory allocator or valid output address."); u64 recommendedSize = size; - if constexpr (AZStd::is_same_v) + if constexpr (AZStd::is_same_v) { recommendedSize = m_recommendations.CalculateRecommendedMemorySize(size, parentReadRequest->m_offset); } @@ -249,12 +253,12 @@ namespace AZ::IO parentReadRequest->m_output = allocation.m_address; parentReadRequest->m_outputSize = allocation.m_size; parentReadRequest->m_memoryType = allocation.m_type; - if constexpr (AZStd::is_same_v) + if constexpr (AZStd::is_same_v) { args.m_output = parentReadRequest->m_output; args.m_outputSize = allocation.m_size; } - else if constexpr (AZStd::is_same_v) + else if constexpr (AZStd::is_same_v) { args.m_output = parentReadRequest->m_output; } @@ -267,7 +271,7 @@ namespace AZ::IO } #endif - if constexpr (AZStd::is_same_v) + if constexpr (AZStd::is_same_v) { m_threadData.m_lastFilePath = args.m_path; m_threadData.m_lastFileOffset = args.m_offset + args.m_size; @@ -275,7 +279,7 @@ namespace AZ::IO m_processingSize += args.m_size; #endif } - else if constexpr (AZStd::is_same_v) + else if constexpr (AZStd::is_same_v) { const CompressionInfo& info = args.m_compressionInfo; m_threadData.m_lastFilePath = info.m_archiveFilename; @@ -288,15 +292,15 @@ namespace AZ::IO "Streamer queued %zu: %s", next->GetCommand().index(), parentReadRequest->m_path.GetRelativePath()); m_threadData.m_streamStack->QueueRequest(next); } - else if constexpr (AZStd::is_same_v) + else if constexpr (AZStd::is_same_v) { return Thread_ProcessCancelRequest(next, args); } - else if constexpr (AZStd::is_same_v) + else if constexpr (AZStd::is_same_v) { return Thread_ProcessRescheduleRequest(next, args); } - else if constexpr (AZStd::is_same_v || AZStd::is_same_v) + else if constexpr (AZStd::is_same_v || AZStd::is_same_v) { AZ_PROFILE_INTERVAL_START_COLORED(AzCore, next, ProfilerColor, "Streamer queued %zu", next->GetCommand().index()); @@ -345,7 +349,7 @@ namespace AZ::IO #endif { using Command = AZStd::decay_t; - if constexpr (AZStd::is_same_v) + if constexpr (AZStd::is_same_v) { if (args.m_output == nullptr && args.m_allocator != nullptr) { @@ -393,7 +397,7 @@ namespace AZ::IO } } - void Scheduler::Thread_ProcessCancelRequest(FileRequest* request, FileRequest::CancelData& data) + void Scheduler::Thread_ProcessCancelRequest(FileRequest* request, Requests::CancelData& data) { AZ_PROFILE_INTERVAL_START_COLORED(AzCore, request, ProfilerColor, "Streamer queued cancel"); auto& pending = m_context.GetPreparedRequests(); @@ -415,7 +419,7 @@ namespace AZ::IO m_threadData.m_streamStack->QueueRequest(request); } - void Scheduler::Thread_ProcessRescheduleRequest(FileRequest* request, FileRequest::RescheduleData& data) + void Scheduler::Thread_ProcessRescheduleRequest(FileRequest* request, Requests::RescheduleData& data) { AZ_PROFILE_INTERVAL_START_COLORED(AzCore, request, ProfilerColor, "Streamer queued reschedule"); auto& pendingRequests = m_context.GetPreparedRequests(); @@ -424,7 +428,7 @@ namespace AZ::IO if (pending->WorksOn(data.m_target)) { // Read requests are the only requests that use deadlines and dynamic priorities. - auto readRequest = pending->GetCommandFromChain(); + auto readRequest = pending->GetCommandFromChain(); if (readRequest) { readRequest->m_deadline = data.m_newDeadline; @@ -463,8 +467,8 @@ namespace AZ::IO // Order is the same for both requests, so prioritize the request that are at risk of missing // it's deadline. - const FileRequest::ReadRequestData* firstRead = first->GetCommandFromChain(); - const FileRequest::ReadRequestData* secondRead = second->GetCommandFromChain(); + const Requests::ReadRequestData* firstRead = first->GetCommandFromChain(); + const Requests::ReadRequestData* secondRead = second->GetCommandFromChain(); if (firstRead == nullptr || secondRead == nullptr) { @@ -496,11 +500,11 @@ namespace AZ::IO auto sameFile = [this](auto&& args) { using Command = AZStd::decay_t; - if constexpr (AZStd::is_same_v) + if constexpr (AZStd::is_same_v) { return m_threadData.m_lastFilePath == args.m_path; } - else if constexpr (AZStd::is_same_v) + else if constexpr (AZStd::is_same_v) { return m_threadData.m_lastFilePath == args.m_compressionInfo.m_archiveFilename; } @@ -517,11 +521,11 @@ namespace AZ::IO auto offset = [](auto&& args) -> s64 { using Command = AZStd::decay_t; - if constexpr (AZStd::is_same_v) + if constexpr (AZStd::is_same_v) { return aznumeric_caster(args.m_offset); } - else if constexpr (AZStd::is_same_v) + else if constexpr (AZStd::is_same_v) { return aznumeric_caster(args.m_compressionInfo.m_offset); } diff --git a/Code/Framework/AzCore/AzCore/IO/Streamer/Scheduler.h b/Code/Framework/AzCore/AzCore/IO/Streamer/Scheduler.h index 053a57d332..502002fd27 100644 --- a/Code/Framework/AzCore/AzCore/IO/Streamer/Scheduler.h +++ b/Code/Framework/AzCore/AzCore/IO/Streamer/Scheduler.h @@ -8,6 +8,7 @@ #pragma once +#include #include #include #include @@ -24,11 +25,19 @@ namespace AZ::IO { class FileRequest; + namespace Requests + { + struct CancelData; + struct RescheduleData; + } // namespace Requests + class Scheduler final { public: explicit Scheduler(AZStd::shared_ptr streamStack, u64 memoryAlignment = AZCORE_GLOBAL_NEW_ALIGNMENT, u64 sizeAlignment = 1, u64 granularity = 1_mib); + ~Scheduler(); + void Start(const AZStd::thread_desc& threadDesc); void Stop(); @@ -61,14 +70,14 @@ namespace AZ::IO bool Thread_ExecuteRequests(); bool Thread_PrepareRequests(AZStd::vector& outstandingRequests); void Thread_ProcessTillIdle(); - void Thread_ProcessCancelRequest(FileRequest* request, FileRequest::CancelData& data); - void Thread_ProcessRescheduleRequest(FileRequest* request, FileRequest::RescheduleData& data); + void Thread_ProcessCancelRequest(FileRequest* request, Requests::CancelData& data); + void Thread_ProcessRescheduleRequest(FileRequest* request, Requests::RescheduleData& data); enum class Order { - FirstRequest, //< The first request is the most important to process next. - SecondRequest, //< The second request is the most important to process next. - Equal //< Both requests are equally important. + FirstRequest, //!< The first request is the most important to process next. + SecondRequest, //!< The second request is the most important to process next. + Equal //!< Both requests are equally important. }; //! Determine which of the two provided requests is more important to process next. Order Thread_PrioritizeRequests(const FileRequest* first, const FileRequest* second) const; diff --git a/Code/Framework/AzCore/AzCore/IO/Streamer/StorageDrive.cpp b/Code/Framework/AzCore/AzCore/IO/Streamer/StorageDrive.cpp index cfd191b68f..20e08873da 100644 --- a/Code/Framework/AzCore/AzCore/IO/Streamer/StorageDrive.cpp +++ b/Code/Framework/AzCore/AzCore/IO/Streamer/StorageDrive.cpp @@ -60,13 +60,13 @@ namespace AZ::IO AZ_PROFILE_FUNCTION(AzCore); AZ_Assert(request, "PrepareRequest was provided a null request."); - if (AZStd::holds_alternative(request->GetCommand())) + if (AZStd::holds_alternative(request->GetCommand())) { - auto& readRequest = AZStd::get(request->GetCommand()); + auto& readRequest = AZStd::get(request->GetCommand()); FileRequest* read = m_context->GetNewInternalRequest(); - read->CreateRead(request, readRequest.m_output, readRequest.m_outputSize, readRequest.m_path, - readRequest.m_offset, readRequest.m_size); + read->CreateRead( + request, readRequest.m_output, readRequest.m_outputSize, readRequest.m_path, readRequest.m_offset, readRequest.m_size); m_context->PushPreparedRequest(read); return; } @@ -79,29 +79,29 @@ namespace AZ::IO AZStd::visit([this, request](auto&& args) { using Command = AZStd::decay_t; - if constexpr (AZStd::is_same_v || - AZStd::is_same_v || - AZStd::is_same_v) + if constexpr (AZStd::is_same_v || + AZStd::is_same_v || + AZStd::is_same_v) { m_pendingRequests.push_back(request); return; } - else if constexpr (AZStd::is_same_v) + else if constexpr (AZStd::is_same_v) { CancelRequest(request, args.m_target); return; } else { - if constexpr (AZStd::is_same_v) + if constexpr (AZStd::is_same_v) { FlushCache(args.m_path); } - else if constexpr (AZStd::is_same_v) + else if constexpr (AZStd::is_same_v) { FlushEntireCache(); } - else if constexpr (AZStd::is_same_v) + else if constexpr (AZStd::is_same_v) { Report(args); } @@ -118,15 +118,15 @@ namespace AZ::IO AZStd::visit([this, request](auto&& args) { using Command = AZStd::decay_t; - if constexpr (AZStd::is_same_v) + if constexpr (AZStd::is_same_v) { ReadFile(request); } - else if constexpr (AZStd::is_same_v) + else if constexpr (AZStd::is_same_v) { FileExistsRequest(request); } - else if constexpr (AZStd::is_same_v) + else if constexpr (AZStd::is_same_v) { FileMetaDataRetrievalRequest(request); } @@ -199,25 +199,25 @@ namespace AZ::IO AZStd::visit([&](auto&& args) { using Command = AZStd::decay_t; - if constexpr (AZStd::is_same_v) + if constexpr (AZStd::is_same_v) { targetFile = &args.m_path; readSize = args.m_size; offset = args.m_offset; } - else if constexpr (AZStd::is_same_v) + else if constexpr (AZStd::is_same_v) { targetFile = &args.m_compressionInfo.m_archiveFilename; readSize = args.m_compressionInfo.m_compressedSize; offset = args.m_compressionInfo.m_offset; } - else if constexpr (AZStd::is_same_v) + else if constexpr (AZStd::is_same_v) { readSize = 0; AZStd::chrono::microseconds averageTime = m_getFileExistsTimeAverage.CalculateAverage(); startTime += averageTime; } - else if constexpr (AZStd::is_same_v) + else if constexpr (AZStd::is_same_v) { readSize = 0; AZStd::chrono::microseconds averageTime = m_getFileMetaDataTimeAverage.CalculateAverage(); @@ -254,7 +254,7 @@ namespace AZ::IO { AZ_PROFILE_FUNCTION(AzCore); - auto data = AZStd::get_if(&request->GetCommand()); + auto data = AZStd::get_if(&request->GetCommand()); AZ_Assert(data, "FileRequest queued on StorageDrive to be read didn't contain read data."); SystemFile* file = nullptr; @@ -342,7 +342,7 @@ namespace AZ::IO AZ_PROFILE_FUNCTION(AzCore); TIMED_AVERAGE_WINDOW_SCOPE(m_getFileExistsTimeAverage); - auto& fileExists = AZStd::get(request->GetCommand()); + auto& fileExists = AZStd::get(request->GetCommand()); size_t cacheIndex = FindFileInCache(fileExists.m_path); if (cacheIndex != s_fileNotFound) { @@ -360,7 +360,7 @@ namespace AZ::IO AZ_PROFILE_FUNCTION(AzCore); TIMED_AVERAGE_WINDOW_SCOPE(m_getFileMetaDataTimeAverage); - auto& command = AZStd::get(request->GetCommand()); + auto& command = AZStd::get(request->GetCommand()); // If the file is already open, use the file handle which usually is cheaper than asking for the file by name. size_t cacheIndex = FindFileInCache(command.m_path); if (cacheIndex != s_fileNotFound) @@ -446,11 +446,11 @@ namespace AZ::IO } } - void StorageDrive::Report(const FileRequest::ReportData& data) const + void StorageDrive::Report(const Requests::ReportData& data) const { switch (data.m_reportType) { - case FileRequest::ReportData::ReportType::FileLocks: + case Requests::ReportType::FileLocks: for (u32 i = 0; i < m_fileHandles.size(); ++i) { if (m_fileHandles[i] != nullptr) diff --git a/Code/Framework/AzCore/AzCore/IO/Streamer/StorageDrive.h b/Code/Framework/AzCore/AzCore/IO/Streamer/StorageDrive.h index d90b31eeec..25f3d7b353 100644 --- a/Code/Framework/AzCore/AzCore/IO/Streamer/StorageDrive.h +++ b/Code/Framework/AzCore/AzCore/IO/Streamer/StorageDrive.h @@ -8,6 +8,7 @@ #pragma once +#include #include #include #include @@ -16,6 +17,11 @@ #include #include +namespace AZ::IO::Requests +{ + struct ReportData; +} + namespace AZ::IO { struct StorageDriveConfig final : @@ -72,7 +78,7 @@ namespace AZ::IO void EstimateCompletionTimeForRequest(FileRequest* request, AZStd::chrono::system_clock::time_point& startTime, const RequestPath*& activeFile, u64& activeOffset) const; - void Report(const FileRequest::ReportData& data) const; + void Report(const Requests::ReportData& data) const; TimedAverageWindow m_fileOpenCloseTimeAverage; TimedAverageWindow m_getFileExistsTimeAverage; diff --git a/Code/Framework/AzCore/AzCore/IO/Streamer/Streamer.cpp b/Code/Framework/AzCore/AzCore/IO/Streamer/Streamer.cpp index e4976f7d1c..dfc156bbee 100644 --- a/Code/Framework/AzCore/AzCore/IO/Streamer/Streamer.cpp +++ b/Code/Framework/AzCore/AzCore/IO/Streamer/Streamer.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -210,7 +211,7 @@ namespace AZ::IO IStreamerTypes::ClaimMemory claimMemory) const { AZ_Assert(request.m_request, "The request handle provided to Streamer::GetReadRequestResult is invalid."); - auto readRequest = AZStd::get_if(&request.m_request->GetCommand()); + auto readRequest = AZStd::get_if(&request.m_request->GetCommand()); if (readRequest != nullptr) { buffer = readRequest->m_output; @@ -281,14 +282,14 @@ namespace AZ::IO } } - FileRequestPtr Streamer::Report(FileRequest::ReportData::ReportType reportType) + FileRequestPtr Streamer::Report(Requests::ReportType reportType) { FileRequestPtr result = CreateRequest(); Report(result, reportType); return result; } - FileRequestPtr& Streamer::Report(FileRequestPtr& request, FileRequest::ReportData::ReportType reportType) + FileRequestPtr& Streamer::Report(FileRequestPtr& request, Requests::ReportType reportType) { request->m_request.CreateReport(reportType); return request; diff --git a/Code/Framework/AzCore/AzCore/IO/Streamer/Streamer.h b/Code/Framework/AzCore/AzCore/IO/Streamer/Streamer.h index bb363a0c64..7e3dd1a742 100644 --- a/Code/Framework/AzCore/AzCore/IO/Streamer/Streamer.h +++ b/Code/Framework/AzCore/AzCore/IO/Streamer/Streamer.h @@ -20,6 +20,10 @@ namespace AZStd struct thread_desc; } +namespace AZ::IO::Requests +{ + enum class ReportType : int8_t; +} namespace AZ::IO { @@ -185,9 +189,9 @@ namespace AZ::IO void RecordStatistics(); //! Tells AZ::IO::Streamer the report the information for the report to the output. - FileRequestPtr Report(FileRequest::ReportData::ReportType reportType); + FileRequestPtr Report(Requests::ReportType reportType); //! Tells AZ::IO::Streamer the report the information for the report to the output. - FileRequestPtr& Report(FileRequestPtr& request, FileRequest::ReportData::ReportType reportType); + FileRequestPtr& Report(FileRequestPtr& request, Requests::ReportType reportType); Streamer(const AZStd::thread_desc& threadDesc, AZStd::unique_ptr streamStack); diff --git a/Code/Framework/AzCore/AzCore/IO/Streamer/StreamerComponent.cpp b/Code/Framework/AzCore/AzCore/IO/Streamer/StreamerComponent.cpp index 9a465021c2..25fdb9bdfb 100644 --- a/Code/Framework/AzCore/AzCore/IO/Streamer/StreamerComponent.cpp +++ b/Code/Framework/AzCore/AzCore/IO/Streamer/StreamerComponent.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -207,7 +208,7 @@ namespace AZ { if (m_streamer) { - m_streamer->QueueRequest(m_streamer->Report(AZ::IO::FileRequest::ReportData::ReportType::FileLocks)); + m_streamer->QueueRequest(m_streamer->Report(AZ::IO::Requests::ReportType::FileLocks)); } } diff --git a/Code/Framework/AzCore/AzCore/IO/Streamer/StreamerContext.cpp b/Code/Framework/AzCore/AzCore/IO/Streamer/StreamerContext.cpp index 5cd483bc55..a4979320a7 100644 --- a/Code/Framework/AzCore/AzCore/IO/Streamer/StreamerContext.cpp +++ b/Code/Framework/AzCore/AzCore/IO/Streamer/StreamerContext.cpp @@ -22,6 +22,9 @@ namespace AZ static constexpr char LatePredictionName[] = "Early completions"; static constexpr char MissedDeadlinesName[] = "Missed deadlines"; #endif // AZ_STREAMER_ADD_EXTRA_PROFILING_INFO + + StreamerContext::StreamerContext() = default; + StreamerContext::~StreamerContext() { for (FileRequest* entry : m_internalRecycleBin) @@ -204,7 +207,7 @@ namespace AZ m_latePredictionsPercentageStat.GetMostRecentSample()); } } - auto readRequest = AZStd::get_if(&top->GetCommand()); + auto readRequest = AZStd::get_if(&top->GetCommand()); if (readRequest != nullptr) { m_missedDeadlinePercentageStat.PushSample(now < readRequest->m_deadline ? 0.0 : 1.0); @@ -224,7 +227,7 @@ namespace AZ top->m_onCompletion(*top); AZ_PROFILE_INTERVAL_END(AzCore, top); } - + if (parent) { AZ_Assert(parent->m_dependencies > 0, diff --git a/Code/Framework/AzCore/AzCore/IO/Streamer/StreamerContext.h b/Code/Framework/AzCore/AzCore/IO/Streamer/StreamerContext.h index 356eb7ddac..fee8d7b56b 100644 --- a/Code/Framework/AzCore/AzCore/IO/Streamer/StreamerContext.h +++ b/Code/Framework/AzCore/AzCore/IO/Streamer/StreamerContext.h @@ -8,22 +8,27 @@ #pragma once #include -#include #include #include #include -#include -#include -#include #include +#include +#include +#include namespace AZ::IO { + class FileRequest; + class ExternalFileRequest; + + using FileRequestPtr = AZStd::intrusive_ptr; + class StreamerContext { public: using PreparedQueue = AZStd::deque; + StreamerContext(); ~StreamerContext(); //! Gets a new file request, either by creating a new instance or diff --git a/Code/Framework/AzCore/AzCore/Math/MathIntrinsics.h b/Code/Framework/AzCore/AzCore/Math/MathIntrinsics.h index 7b731a12b2..32441aaa32 100644 --- a/Code/Framework/AzCore/AzCore/Math/MathIntrinsics.h +++ b/Code/Framework/AzCore/AzCore/Math/MathIntrinsics.h @@ -14,7 +14,7 @@ #define az_clz_u64(x) _lzcnt_u64(x) #define az_popcnt_u32(x) __popcnt(x) #define az_popcnt_u64(x) __popcnt64(x) -#elif defined(AZ_COMPILER_CLANG) +#elif defined(AZ_COMPILER_CLANG) || defined(AZ_COMPILER_GCC) #define az_ctz_u32(x) __builtin_ctz(x) #define az_ctz_u64(x) __builtin_ctzll(x) #define az_clz_u32(x) __builtin_clz(x) @@ -22,5 +22,5 @@ #define az_popcnt_u32(x) __builtin_popcount(x) #define az_popcnt_u64(x) __builtin_popcountll(x) #else - #error Count Leading Zeros, Count Trailing Zeros and Pop Count intrinsics isn't supported for this compiler + #error Count Leading Zeros, Count Trailing Zeros and Pop Count intrinsics isnt supported for this compiler #endif diff --git a/Code/Framework/AzCore/AzCore/Math/Matrix3x4.cpp b/Code/Framework/AzCore/AzCore/Math/Matrix3x4.cpp index 78da9e76d2..23d0eea618 100644 --- a/Code/Framework/AzCore/AzCore/Math/Matrix3x4.cpp +++ b/Code/Framework/AzCore/AzCore/Math/Matrix3x4.cpp @@ -25,7 +25,7 @@ namespace AZ void Matrix3x4SetRowGeneric(Matrix3x4* thisPtr, ScriptDataContext& dc) { - bool rowIsSet = false; + [[maybe_unused]] bool rowIsSet = false; if (dc.GetNumArguments() >= 5) { if (dc.IsNumber(0)) @@ -88,7 +88,7 @@ namespace AZ void Matrix3x4SetColumnGeneric(Matrix3x4* thisPtr, ScriptDataContext& dc) { - bool columnIsSet = false; + [[maybe_unused]] bool columnIsSet = false; if (dc.GetNumArguments() >= 4) { if (dc.IsNumber(0)) @@ -133,7 +133,7 @@ namespace AZ void Matrix3x4SetTranslationGeneric(Matrix3x4* thisPtr, ScriptDataContext& dc) { - bool translationIsSet = false; + [[maybe_unused]] bool translationIsSet = false; if (dc.GetNumArguments() == 3 && dc.IsNumber(0) && diff --git a/Code/Framework/AzCore/AzCore/Math/Uuid.cpp b/Code/Framework/AzCore/AzCore/Math/Uuid.cpp index 410d235a37..b27f1a0943 100644 --- a/Code/Framework/AzCore/AzCore/Math/Uuid.cpp +++ b/Code/Framework/AzCore/AzCore/Math/Uuid.cpp @@ -77,7 +77,7 @@ namespace AZ // check open brace char c = *current++; - bool has_open_brace = false; + [[maybe_unused]] bool has_open_brace = false; if (c == '{') { c = *current++; diff --git a/Code/Framework/AzCore/AzCore/Memory/AllocatorManager.h b/Code/Framework/AzCore/AzCore/Memory/AllocatorManager.h index 14dec68ad1..50afce929a 100644 --- a/Code/Framework/AzCore/AzCore/Memory/AllocatorManager.h +++ b/Code/Framework/AzCore/AzCore/Memory/AllocatorManager.h @@ -39,6 +39,9 @@ namespace AZ template constexpr friend void AZStd::destroy_at(T*); public: + + AllocatorManager(); + typedef AZStd::function OutOfMemoryCBType; static void PreRegisterAllocator(IAllocator* allocator); // Only call if the environment is not yet attached @@ -185,7 +188,6 @@ namespace AZ AZ::Debug::AllocationRecords::Mode m_defaultTrackingRecordMode; AZStd::unique_ptr m_mallocSchema; - AllocatorManager(); ~AllocatorManager(); static AllocatorManager g_allocMgr; ///< The single instance of the allocator manager diff --git a/Code/Framework/AzCore/AzCore/Name/NameDictionary.cpp b/Code/Framework/AzCore/AzCore/Name/NameDictionary.cpp index 1b39eb81bd..2bb4faf1d5 100644 --- a/Code/Framework/AzCore/AzCore/Name/NameDictionary.cpp +++ b/Code/Framework/AzCore/AzCore/Name/NameDictionary.cpp @@ -85,7 +85,7 @@ namespace AZ NameDictionary::~NameDictionary() { - bool leaksDetected = false; + [[maybe_unused]] bool leaksDetected = false; for (const auto& keyValue : m_dictionary) { diff --git a/Code/Framework/AzCore/AzCore/Name/NameDictionary.h b/Code/Framework/AzCore/AzCore/Name/NameDictionary.h index 8f9af4be3a..3df05f04b5 100644 --- a/Code/Framework/AzCore/AzCore/Name/NameDictionary.h +++ b/Code/Framework/AzCore/AzCore/Name/NameDictionary.h @@ -45,7 +45,9 @@ namespace AZ //! that already exist. class NameDictionary final { + public: AZ_CLASS_ALLOCATOR(NameDictionary, AZ::OSAllocator, 0); + private: friend Module; friend Name; @@ -75,8 +77,8 @@ namespace AZ //! @return A Name instance. If the hash was not found, the Name will be empty. Name FindName(Name::Hash hash) const; - private: NameDictionary(); + private: ~NameDictionary(); void ReportStats() const; diff --git a/Code/Framework/AzCore/AzCore/PlatformDef.h b/Code/Framework/AzCore/AzCore/PlatformDef.h index 7f00f7e90e..8609ad5756 100644 --- a/Code/Framework/AzCore/AzCore/PlatformDef.h +++ b/Code/Framework/AzCore/AzCore/PlatformDef.h @@ -10,10 +10,17 @@ ////////////////////////////////////////////////////////////////////////// // Platforms +#include + #include "PlatformRestrictedFileDef.h" #if defined(__clang__) #define AZ_COMPILER_CLANG __clang_major__ +#elif defined(__GNUC__) + // Assign AZ_COMPILER_GCC to a number that represents the major+minor (2 digits) + path level (2 digits) i.e. 3.2.0 == 30200 + #define AZ_COMPILER_GCC (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) #elif defined(_MSC_VER) #define AZ_COMPILER_MSVC _MSC_VER #else @@ -29,7 +36,7 @@ #define AZ_DYNAMIC_LIBRARY_PREFIX AZ_TRAIT_OS_DYNAMIC_LIBRARY_PREFIX #define AZ_DYNAMIC_LIBRARY_EXTENSION AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION -#if defined(AZ_COMPILER_CLANG) +#if defined(AZ_COMPILER_CLANG) || defined(AZ_COMPILER_GCC) #define AZ_DLL_EXPORT AZ_TRAIT_OS_DLL_EXPORT_CLANG #define AZ_DLL_IMPORT AZ_TRAIT_OS_DLL_IMPORT_CLANG #elif defined(AZ_COMPILER_MSVC) @@ -67,12 +74,36 @@ #if defined(AZ_COMPILER_MSVC) /// Disables a warning using push style. For use matched with an AZ_POP_WARNING -#define AZ_PUSH_DISABLE_WARNING(_msvcOption, __) \ - __pragma(warning(push)) \ + +// Compiler specific AZ_PUSH_DISABLE_WARNING +#define AZ_PUSH_DISABLE_WARNING_MSVC(_msvcOption) \ + __pragma(warning(push)) \ + __pragma(warning(disable : _msvcOption)) +#define AZ_PUSH_DISABLE_WARNING_CLANG(_clangOption) +#define AZ_PUSH_DISABLE_WARNING_GCC(_gccOption) + +/// Compiler specific AZ_POP_DISABLE_WARNING. This needs to be matched with the compiler specific AZ_PUSH_DISABLE_WARNINGs +#define AZ_POP_DISABLE_WARNING_CLANG +#define AZ_POP_DISABLE_WARNING_MSVC \ + __pragma(warning(pop)) +#define AZ_POP_DISABLE_WARNING_GCC + + +// Variadic definitions for AZ_PUSH_DISABLE_WARNING for the current compiler +#define AZ_PUSH_DISABLE_WARNING_1(_msvcOption) \ + __pragma(warning(push)) \ + __pragma(warning(disable : _msvcOption)) + +#define AZ_PUSH_DISABLE_WARNING_2(_msvcOption, _2) \ + __pragma(warning(push)) \ + __pragma(warning(disable : _msvcOption)) + +#define AZ_PUSH_DISABLE_WARNING_3(_msvcOption, _2, _3) \ + __pragma(warning(push)) \ __pragma(warning(disable : _msvcOption)) /// Pops the warning stack. For use matched with an AZ_PUSH_DISABLE_WARNING -#define AZ_POP_DISABLE_WARNING \ +#define AZ_POP_DISABLE_WARNING \ __pragma(warning(pop)) @@ -94,17 +125,62 @@ # define AZ_FUNCTION_SIGNATURE __FUNCSIG__ ////////////////////////////////////////////////////////////////////////// -#elif defined(AZ_COMPILER_CLANG) +#elif defined(AZ_COMPILER_CLANG) || defined(AZ_COMPILER_GCC) + +#if defined(AZ_COMPILER_CLANG) /// Disables a single warning using push style. For use matched with an AZ_POP_WARNING -#define AZ_PUSH_DISABLE_WARNING(__, _clangOption) \ - _Pragma("clang diagnostic push") \ + +// Compiler specific AZ_PUSH_DISABLE_WARNING +#define AZ_PUSH_DISABLE_WARNING_CLANG(_clangOption) \ + _Pragma("clang diagnostic push") \ _Pragma(AZ_STRINGIZE(clang diagnostic ignored _clangOption)) +#define AZ_PUSH_DISABLE_WARNING_MSVC(_msvcOption) +#define AZ_PUSH_DISABLE_WARNING_GCC(_gccOption) + +/// Compiler specific AZ_POP_DISABLE_WARNING. This needs to be matched with the compiler specific AZ_PUSH_DISABLE_WARNINGs +#define AZ_POP_DISABLE_WARNING_CLANG \ + _Pragma("clang diagnostic pop") +#define AZ_POP_DISABLE_WARNING_MSVC +#define AZ_POP_DISABLE_WARNING_GCC + +// Variadic definitions for AZ_PUSH_DISABLE_WARNING for the current compiler +#define AZ_PUSH_DISABLE_WARNING_1(_1) +#define AZ_PUSH_DISABLE_WARNING_2(_1, _clangOption) AZ_PUSH_DISABLE_WARNING_CLANG(_clangOption) +#define AZ_PUSH_DISABLE_WARNING_3(_1, _clangOption, _2) AZ_PUSH_DISABLE_WARNING_CLANG(_clangOption) /// Pops the warning stack. For use matched with an AZ_PUSH_DISABLE_WARNING #define AZ_POP_DISABLE_WARNING \ _Pragma("clang diagnostic pop") +#else + +/// Disables a single warning using push style. For use matched with an AZ_POP_WARNING + +// Compiler specific AZ_PUSH_DISABLE_WARNING +#define AZ_PUSH_DISABLE_WARNING_GCC(_gccOption) \ + _Pragma("GCC diagnostic push") \ + _Pragma(AZ_STRINGIZE(GCC diagnostic ignored _gccOption)) +#define AZ_PUSH_DISABLE_WARNING_CLANG(_clangOption) +#define AZ_PUSH_DISABLE_WARNING_MSVC(_msvcOption) + +/// Compiler specific AZ_POP_DISABLE_WARNING. This needs to be matched with the compiler specific AZ_PUSH_DISABLE_WARNINGs +#define AZ_POP_DISABLE_WARNING_CLANG +#define AZ_POP_DISABLE_WARNING_MSVC +#define AZ_POP_DISABLE_WARNING_GCC \ + _Pragma("GCC diagnostic pop") + +// Variadic definitions for AZ_PUSH_DISABLE_WARNING for the current compiler +#define AZ_PUSH_DISABLE_WARNING_1(_1) +#define AZ_PUSH_DISABLE_WARNING_2(_1, _2) +#define AZ_PUSH_DISABLE_WARNING_3(_1, _2, _gccOption) AZ_PUSH_DISABLE_WARNING_GCC(_gccOption) + +/// Pops the warning stack. For use matched with an AZ_PUSH_DISABLE_WARNING +#define AZ_POP_DISABLE_WARNING + _Pragma("GCC diagnostic pop") + +#endif // defined(AZ_COMPILER_CLANG) + #define AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING #define AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING #define AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING @@ -121,6 +197,8 @@ #error Compiler not supported #endif +#define AZ_PUSH_DISABLE_WARNING(...) AZ_MACRO_SPECIALIZE(AZ_PUSH_DISABLE_WARNING_, AZ_VA_NUM_ARGS(__VA_ARGS__), (__VA_ARGS__)) + // We need to define AZ_DEBUG_BUILD in debug mode. We can also define it in debug optimized mode (left up to the user). // note that _DEBUG is not in fact always defined on all platforms, and only AZ_DEBUG_BUILD should be relied on. #if !defined(AZ_DEBUG_BUILD) && defined(_DEBUG) diff --git a/Code/Framework/AzCore/AzCore/RTTI/BehaviorContext.h b/Code/Framework/AzCore/AzCore/RTTI/BehaviorContext.h index 7f48f301aa..0f7470eb39 100644 --- a/Code/Framework/AzCore/AzCore/RTTI/BehaviorContext.h +++ b/Code/Framework/AzCore/AzCore/RTTI/BehaviorContext.h @@ -1541,7 +1541,7 @@ namespace AZ } template - static bool SetClassEqualityComparer(BehaviorClass* behaviorClass, const T*) + static void SetClassEqualityComparer(BehaviorClass* behaviorClass, const T*) { behaviorClass->m_equalityComparer = &DefaultEqualityComparer; } @@ -2341,8 +2341,6 @@ namespace AZ // For some reason the Script.cpp test validates that an incomplete type can be used with the SetResult struct template static constexpr bool IsCopyAssignable = false; - template - static constexpr bool IsCopyAssignable() = AZStd::declval())>> = true; template static bool Set(BehaviorValueParameter& param, T&& result, bool IsValueCopy) @@ -2402,6 +2400,9 @@ namespace AZ } }; + template + constexpr bool SetResult::IsCopyAssignable() = AZStd::declval())>> = true; + AZ_FORCE_INLINE BehaviorValueParameter& BehaviorValueParameter::operator=(BehaviorValueParameter&& other) { *static_cast(this) = AZStd::move(static_cast(other)); diff --git a/Code/Framework/AzCore/AzCore/RTTI/RTTI.h b/Code/Framework/AzCore/AzCore/RTTI/RTTI.h index acf6f64f77..e8ccaa79cf 100644 --- a/Code/Framework/AzCore/AzCore/RTTI/RTTI.h +++ b/Code/Framework/AzCore/AzCore/RTTI/RTTI.h @@ -977,26 +977,32 @@ namespace AZ { return AzGenericTypeInfo::Uuid(); } - + + #if defined(AZ_COMPILER_MSVC) + // There is a bug with the MSVC compiler when using the 'auto' keyword here. It appears that MSVC is unable to distinguish between a template + // template argument with a type variadic pack vs a template template argument with a non-type auto variadic pack. template class U, typename = void> + #else + template class U, typename = void> + #endif // defined(AZ_COMPILER_MSVC) inline const AZ::TypeId& RttiTypeId() { return AzGenericTypeInfo::Uuid(); } - template class U, typename = void> + template class U, typename = void> inline const AZ::TypeId& RttiTypeId() { return AzGenericTypeInfo::Uuid(); } - template class U, typename = void> + template class U, typename = void> inline const AZ::TypeId& RttiTypeId() { return AzGenericTypeInfo::Uuid(); } - template class U, typename = void> + template class U, typename = void> inline const AZ::TypeId& RttiTypeId() { return AzGenericTypeInfo::Uuid(); @@ -1027,15 +1033,22 @@ namespace AZ } // Returns true if the type is contained, otherwise false. Safe to call for type not supporting AZRtti (returns false unless type fully match). + +#if defined(AZ_COMPILER_MSVC) + // There is a bug with the MSVC compiler when using the 'auto' keyword here. It appears that MSVC is unable to distinguish between a template + // template argument with a type variadic pack vs a template template argument with a non-type auto variadic pack. template class T, class U> - inline bool RttiIsTypeOf(const U&) +#else + template class T, class U> +#endif // defined(AZ_COMPILER_MSVC) + inline bool RttiIsTypeOf(const U&) { using CheckType = typename AZ::Internal::RttiRemoveQualifiers::type; return AzGenericTypeInfo::Uuid() == RttiTypeId(); } // Returns true if the type is contained, otherwise false. Safe to call for type not supporting AZRtti (returns false unless type fully match). - template class T, class U> + template class T, class U> inline bool RttiIsTypeOf(const U&) { using CheckType = typename AZ::Internal::RttiRemoveQualifiers::type; @@ -1043,7 +1056,7 @@ namespace AZ } // Returns true if the type is contained, otherwise false.Safe to call for type not supporting AZRtti(returns false unless type fully match). - template class T, class U> + template class T, class U> inline bool RttiIsTypeOf(const U&) { using CheckType = typename AZ::Internal::RttiRemoveQualifiers::type; @@ -1051,7 +1064,7 @@ namespace AZ } // Returns true if the type is contained, otherwise false.Safe to call for type not supporting AZRtti(returns false unless type fully match). - template class T, class U> + template class T, class U> inline bool RttiIsTypeOf(const U&) { using CheckType = typename AZ::Internal::RttiRemoveQualifiers::type; diff --git a/Code/Framework/AzCore/AzCore/RTTI/TypeInfo.h b/Code/Framework/AzCore/AzCore/RTTI/TypeInfo.h index 022025a3df..2cff17a638 100644 --- a/Code/Framework/AzCore/AzCore/RTTI/TypeInfo.h +++ b/Code/Framework/AzCore/AzCore/RTTI/TypeInfo.h @@ -148,11 +148,18 @@ namespace AZ { /// Needs to match declared parameter type. template