diff --git a/Assets/Editor/Icons/Components/Disabled/HttpClientComponent_white.png b/Assets/Editor/Icons/Components/Disabled/HttpClientComponent_white.png deleted file mode 100644 index 12b5be2ccc..0000000000 --- a/Assets/Editor/Icons/Components/Disabled/HttpClientComponent_white.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bfc2ef8c6dbf2fba078e27e4e94384099e090468e679327dd826a5cbf22b04ed -size 1019 diff --git a/Assets/Editor/Icons/Components/HttpClientComponent.png b/Assets/Editor/Icons/Components/HttpClientComponent.png deleted file mode 100644 index 7a619a5a59..0000000000 --- a/Assets/Editor/Icons/Components/HttpClientComponent.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:708b12d41229afab78e0f7d59097ae3de855fea8525a920c5c214fc0ce79f1bd -size 1209 diff --git a/Assets/Editor/Icons/Components/Viewport/HttpClientComponent.png b/Assets/Editor/Icons/Components/Viewport/HttpClientComponent.png deleted file mode 100644 index 16e4917180..0000000000 --- a/Assets/Editor/Icons/Components/Viewport/HttpClientComponent.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fab63af9b50790dca25330058e70517987ea8bf11c00f9353dd951ebdbd1dbe5 -size 5008 diff --git a/Assets/Editor/Translation/scriptcanvas_en_us.ts b/Assets/Editor/Translation/scriptcanvas_en_us.ts index 6d436b7caf..5af338426c 100644 --- a/Assets/Editor/Translation/scriptcanvas_en_us.ts +++ b/Assets/Editor/Translation/scriptcanvas_en_us.ts @@ -49513,106 +49513,6 @@ An Entity can be selected by using the pick button, or by dragging an Entity fro - - Handler: HttpClientComponentNotificationBus - - HANDLER_HTTPCLIENTCOMPONENTNOTIFICATIONBUS_NAME - HttpClientComponentNotificationBus - - - HANDLER_HTTPCLIENTCOMPONENTNOTIFICATIONBUS_TOOLTIP - - - - HANDLER_HTTPCLIENTCOMPONENTNOTIFICATIONBUS_CATEGORY - Networking - - - HANDLER_HTTPCLIENTCOMPONENTNOTIFICATIONBUS_ONHTTPREQUESTSUCCESS_NAME - Class/Bus: HttpClientComponentNotificationBus Event/Method: OnHttpRequestSuccess - OnHttpRequestSuccess - - - HANDLER_HTTPCLIENTCOMPONENTNOTIFICATIONBUS_ONHTTPREQUESTSUCCESS_TOOLTIP - - - - HANDLER_HTTPCLIENTCOMPONENTNOTIFICATIONBUS_ONHTTPREQUESTSUCCESS_CATEGORY - - - - HANDLER_HTTPCLIENTCOMPONENTNOTIFICATIONBUS_ONHTTPREQUESTSUCCESS_OUT_NAME - - - - HANDLER_HTTPCLIENTCOMPONENTNOTIFICATIONBUS_ONHTTPREQUESTSUCCESS_OUT_TOOLTIP - - - - HANDLER_HTTPCLIENTCOMPONENTNOTIFICATIONBUS_ONHTTPREQUESTSUCCESS_IN_NAME - - - - HANDLER_HTTPCLIENTCOMPONENTNOTIFICATIONBUS_ONHTTPREQUESTSUCCESS_IN_TOOLTIP - - - - HANDLER_HTTPCLIENTCOMPONENTNOTIFICATIONBUS_ONHTTPREQUESTSUCCESS_OUTPUT0_NAME - Simple Type: Number C++ Type: int - - - - HANDLER_HTTPCLIENTCOMPONENTNOTIFICATIONBUS_ONHTTPREQUESTSUCCESS_OUTPUT0_TOOLTIP - - - - HANDLER_HTTPCLIENTCOMPONENTNOTIFICATIONBUS_ONHTTPREQUESTSUCCESS_OUTPUT1_NAME - Simple Type: String C++ Type: AZStd::basic_string<char, AZStd::char_traits<char>, allocator> - - - - HANDLER_HTTPCLIENTCOMPONENTNOTIFICATIONBUS_ONHTTPREQUESTSUCCESS_OUTPUT1_TOOLTIP - - - - HANDLER_HTTPCLIENTCOMPONENTNOTIFICATIONBUS_ONHTTPREQUESTFAILURE_NAME - Class/Bus: HttpClientComponentNotificationBus Event/Method: OnHttpRequestFailure - OnHttpRequestFailure - - - HANDLER_HTTPCLIENTCOMPONENTNOTIFICATIONBUS_ONHTTPREQUESTFAILURE_TOOLTIP - - - - HANDLER_HTTPCLIENTCOMPONENTNOTIFICATIONBUS_ONHTTPREQUESTFAILURE_CATEGORY - - - - HANDLER_HTTPCLIENTCOMPONENTNOTIFICATIONBUS_ONHTTPREQUESTFAILURE_OUT_NAME - - - - HANDLER_HTTPCLIENTCOMPONENTNOTIFICATIONBUS_ONHTTPREQUESTFAILURE_OUT_TOOLTIP - - - - HANDLER_HTTPCLIENTCOMPONENTNOTIFICATIONBUS_ONHTTPREQUESTFAILURE_IN_NAME - - - - HANDLER_HTTPCLIENTCOMPONENTNOTIFICATIONBUS_ONHTTPREQUESTFAILURE_IN_TOOLTIP - - - - HANDLER_HTTPCLIENTCOMPONENTNOTIFICATIONBUS_ONHTTPREQUESTFAILURE_OUTPUT0_NAME - Simple Type: Number C++ Type: int - - - - HANDLER_HTTPCLIENTCOMPONENTNOTIFICATIONBUS_ONHTTPREQUESTFAILURE_OUTPUT0_TOOLTIP - - - Handler: InputEventNotificationBus @@ -69850,477 +69750,6 @@ The element is removed from its current parent and added as a child of the new p The name of the action triggered when the interactive element is released - - EBus: ForceVolumeRequestBus - - FORCEVOLUMEREQUESTBUS_NAME - ForceVolumeRequestBus - - - FORCEVOLUMEREQUESTBUS_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_CATEGORY - Physics - - - FORCEVOLUMEREQUESTBUS_SETAIRDENSITY_NAME - Class/Bus: ForceVolumeRequestBus Event/Method: SetAirDensity - SetAirDensity - - - FORCEVOLUMEREQUESTBUS_SETAIRDENSITY_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_SETAIRDENSITY_CATEGORY - - - - FORCEVOLUMEREQUESTBUS_SETAIRDENSITY_OUT_NAME - - - - FORCEVOLUMEREQUESTBUS_SETAIRDENSITY_OUT_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_SETAIRDENSITY_IN_NAME - - - - FORCEVOLUMEREQUESTBUS_SETAIRDENSITY_IN_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_SETAIRDENSITY_PARAM0_NAME - Simple Type: Number C++ Type: float - - - - FORCEVOLUMEREQUESTBUS_SETAIRDENSITY_PARAM0_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_GETAIRRESISTANCE_NAME - Class/Bus: ForceVolumeRequestBus Event/Method: GetAirResistance - GetAirResistance - - - FORCEVOLUMEREQUESTBUS_GETAIRRESISTANCE_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_GETAIRRESISTANCE_CATEGORY - - - - FORCEVOLUMEREQUESTBUS_GETAIRRESISTANCE_OUT_NAME - - - - FORCEVOLUMEREQUESTBUS_GETAIRRESISTANCE_OUT_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_GETAIRRESISTANCE_IN_NAME - - - - FORCEVOLUMEREQUESTBUS_GETAIRRESISTANCE_IN_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_GETAIRRESISTANCE_OUTPUT0_NAME - C++ Type: float - Number - - - FORCEVOLUMEREQUESTBUS_GETAIRRESISTANCE_OUTPUT0_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_GETFORCEMASSDEPENDENT_NAME - Class/Bus: ForceVolumeRequestBus Event/Method: GetForceMassDependent - GetForceMassDependent - - - FORCEVOLUMEREQUESTBUS_GETFORCEMASSDEPENDENT_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_GETFORCEMASSDEPENDENT_CATEGORY - - - - FORCEVOLUMEREQUESTBUS_GETFORCEMASSDEPENDENT_OUT_NAME - - - - FORCEVOLUMEREQUESTBUS_GETFORCEMASSDEPENDENT_OUT_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_GETFORCEMASSDEPENDENT_IN_NAME - - - - FORCEVOLUMEREQUESTBUS_GETFORCEMASSDEPENDENT_IN_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_GETFORCEMASSDEPENDENT_OUTPUT0_NAME - C++ Type: bool - Boolean - - - FORCEVOLUMEREQUESTBUS_GETFORCEMASSDEPENDENT_OUTPUT0_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_SETAIRRESISTANCE_NAME - Class/Bus: ForceVolumeRequestBus Event/Method: SetAirResistance - SetAirResistance - - - FORCEVOLUMEREQUESTBUS_SETAIRRESISTANCE_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_SETAIRRESISTANCE_CATEGORY - - - - FORCEVOLUMEREQUESTBUS_SETAIRRESISTANCE_OUT_NAME - - - - FORCEVOLUMEREQUESTBUS_SETAIRRESISTANCE_OUT_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_SETAIRRESISTANCE_IN_NAME - - - - FORCEVOLUMEREQUESTBUS_SETAIRRESISTANCE_IN_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_SETAIRRESISTANCE_PARAM0_NAME - Simple Type: Number C++ Type: float - - - - FORCEVOLUMEREQUESTBUS_SETAIRRESISTANCE_PARAM0_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_GETAIRDENSITY_NAME - Class/Bus: ForceVolumeRequestBus Event/Method: GetAirDensity - GetAirDensity - - - FORCEVOLUMEREQUESTBUS_GETAIRDENSITY_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_GETAIRDENSITY_CATEGORY - - - - FORCEVOLUMEREQUESTBUS_GETAIRDENSITY_OUT_NAME - - - - FORCEVOLUMEREQUESTBUS_GETAIRDENSITY_OUT_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_GETAIRDENSITY_IN_NAME - - - - FORCEVOLUMEREQUESTBUS_GETAIRDENSITY_IN_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_GETAIRDENSITY_OUTPUT0_NAME - C++ Type: float - Number - - - FORCEVOLUMEREQUESTBUS_GETAIRDENSITY_OUTPUT0_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_GETFORCEMODE_NAME - Class/Bus: ForceVolumeRequestBus Event/Method: GetForceMode - GetForceMode - - - FORCEVOLUMEREQUESTBUS_GETFORCEMODE_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_GETFORCEMODE_CATEGORY - - - - FORCEVOLUMEREQUESTBUS_GETFORCEMODE_OUT_NAME - - - - FORCEVOLUMEREQUESTBUS_GETFORCEMODE_OUT_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_GETFORCEMODE_IN_NAME - - - - FORCEVOLUMEREQUESTBUS_GETFORCEMODE_IN_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_GETFORCEMODE_OUTPUT0_NAME - C++ Type: int - Number - - - FORCEVOLUMEREQUESTBUS_GETFORCEMODE_OUTPUT0_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_GETFORCEMAGNITUDE_NAME - Class/Bus: ForceVolumeRequestBus Event/Method: GetForceMagnitude - GetForceMagnitude - - - FORCEVOLUMEREQUESTBUS_GETFORCEMAGNITUDE_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_GETFORCEMAGNITUDE_CATEGORY - - - - FORCEVOLUMEREQUESTBUS_GETFORCEMAGNITUDE_OUT_NAME - - - - FORCEVOLUMEREQUESTBUS_GETFORCEMAGNITUDE_OUT_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_GETFORCEMAGNITUDE_IN_NAME - - - - FORCEVOLUMEREQUESTBUS_GETFORCEMAGNITUDE_IN_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_GETFORCEMAGNITUDE_OUTPUT0_NAME - C++ Type: float - Number - - - FORCEVOLUMEREQUESTBUS_GETFORCEMAGNITUDE_OUTPUT0_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_SETFORCEMODE_NAME - Class/Bus: ForceVolumeRequestBus Event/Method: SetForceMode - SetForceMode - - - FORCEVOLUMEREQUESTBUS_SETFORCEMODE_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_SETFORCEMODE_CATEGORY - - - - FORCEVOLUMEREQUESTBUS_SETFORCEMODE_OUT_NAME - - - - FORCEVOLUMEREQUESTBUS_SETFORCEMODE_OUT_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_SETFORCEMODE_IN_NAME - - - - FORCEVOLUMEREQUESTBUS_SETFORCEMODE_IN_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_SETFORCEMODE_PARAM0_NAME - Simple Type: Number C++ Type: int - - - - FORCEVOLUMEREQUESTBUS_SETFORCEMODE_PARAM0_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_SETFORCEMAGNITUDE_NAME - Class/Bus: ForceVolumeRequestBus Event/Method: SetForceMagnitude - SetForceMagnitude - - - FORCEVOLUMEREQUESTBUS_SETFORCEMAGNITUDE_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_SETFORCEMAGNITUDE_CATEGORY - - - - FORCEVOLUMEREQUESTBUS_SETFORCEMAGNITUDE_OUT_NAME - - - - FORCEVOLUMEREQUESTBUS_SETFORCEMAGNITUDE_OUT_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_SETFORCEMAGNITUDE_IN_NAME - - - - FORCEVOLUMEREQUESTBUS_SETFORCEMAGNITUDE_IN_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_SETFORCEMAGNITUDE_PARAM0_NAME - Simple Type: Number C++ Type: float - - - - FORCEVOLUMEREQUESTBUS_SETFORCEMAGNITUDE_PARAM0_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_SETFORCEMASSDEPENDENT_NAME - Class/Bus: ForceVolumeRequestBus Event/Method: SetForceMassDependent - SetForceMassDependent - - - FORCEVOLUMEREQUESTBUS_SETFORCEMASSDEPENDENT_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_SETFORCEMASSDEPENDENT_CATEGORY - - - - FORCEVOLUMEREQUESTBUS_SETFORCEMASSDEPENDENT_OUT_NAME - - - - FORCEVOLUMEREQUESTBUS_SETFORCEMASSDEPENDENT_OUT_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_SETFORCEMASSDEPENDENT_IN_NAME - - - - FORCEVOLUMEREQUESTBUS_SETFORCEMASSDEPENDENT_IN_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_SETFORCEMASSDEPENDENT_PARAM0_NAME - Simple Type: Boolean C++ Type: bool - - - - FORCEVOLUMEREQUESTBUS_SETFORCEMASSDEPENDENT_PARAM0_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_SETFORCEDIRECTION_NAME - Class/Bus: ForceVolumeRequestBus Event/Method: SetForceDirection - SetForceDirection - - - FORCEVOLUMEREQUESTBUS_SETFORCEDIRECTION_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_SETFORCEDIRECTION_CATEGORY - - - - FORCEVOLUMEREQUESTBUS_SETFORCEDIRECTION_OUT_NAME - - - - FORCEVOLUMEREQUESTBUS_SETFORCEDIRECTION_OUT_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_SETFORCEDIRECTION_IN_NAME - - - - FORCEVOLUMEREQUESTBUS_SETFORCEDIRECTION_IN_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_SETFORCEDIRECTION_PARAM0_NAME - Simple Type: Vector3 C++ Type: const Vector3& - - - - FORCEVOLUMEREQUESTBUS_SETFORCEDIRECTION_PARAM0_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_GETFORCEDIRECTION_NAME - Class/Bus: ForceVolumeRequestBus Event/Method: GetForceDirection - GetForceDirection - - - FORCEVOLUMEREQUESTBUS_GETFORCEDIRECTION_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_GETFORCEDIRECTION_CATEGORY - - - - FORCEVOLUMEREQUESTBUS_GETFORCEDIRECTION_OUT_NAME - - - - FORCEVOLUMEREQUESTBUS_GETFORCEDIRECTION_OUT_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_GETFORCEDIRECTION_IN_NAME - - - - FORCEVOLUMEREQUESTBUS_GETFORCEDIRECTION_IN_TOOLTIP - - - - FORCEVOLUMEREQUESTBUS_GETFORCEDIRECTION_OUTPUT0_NAME - C++ Type: const Vector3& - Vector3 - - - FORCEVOLUMEREQUESTBUS_GETFORCEDIRECTION_OUTPUT0_TOOLTIP - - - Handler: UiDraggableNotificationBus @@ -73360,553 +72789,6 @@ The element is removed from its current parent and added as a child of the new p The absolute position where the entity should spawn - - EBus: WindVolumeRequestBus - - WINDVOLUMEREQUESTBUS_NAME - Wind Volume - - - WINDVOLUMEREQUESTBUS_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_CATEGORY - Physics (Legacy) - - - WINDVOLUMEREQUESTBUS_GETVOLUMESIZE_NAME - Class/Bus: WindVolumeRequestBus Event/Method: GetVolumeSize - Get Volume Size - - - WINDVOLUMEREQUESTBUS_GETVOLUMESIZE_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETVOLUMESIZE_CATEGORY - - - - WINDVOLUMEREQUESTBUS_GETVOLUMESIZE_OUT_NAME - - - - WINDVOLUMEREQUESTBUS_GETVOLUMESIZE_OUT_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETVOLUMESIZE_IN_NAME - - - - WINDVOLUMEREQUESTBUS_GETVOLUMESIZE_IN_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETVOLUMESIZE_OUTPUT0_NAME - C++ Type: const Vector3& - Vector3 - - - WINDVOLUMEREQUESTBUS_GETVOLUMESIZE_OUTPUT0_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETAIRRESISTANCE_NAME - Class/Bus: WindVolumeRequestBus Event/Method: GetAirResistance - Get Air Resistance - - - WINDVOLUMEREQUESTBUS_GETAIRRESISTANCE_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETAIRRESISTANCE_CATEGORY - - - - WINDVOLUMEREQUESTBUS_GETAIRRESISTANCE_OUT_NAME - - - - WINDVOLUMEREQUESTBUS_GETAIRRESISTANCE_OUT_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETAIRRESISTANCE_IN_NAME - - - - WINDVOLUMEREQUESTBUS_GETAIRRESISTANCE_IN_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETAIRRESISTANCE_OUTPUT0_NAME - C++ Type: float - Number - - - WINDVOLUMEREQUESTBUS_GETAIRRESISTANCE_OUTPUT0_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETAIRRESISTANCE_NAME - Class/Bus: WindVolumeRequestBus Event/Method: SetAirResistance - Set Air Resistance - - - WINDVOLUMEREQUESTBUS_SETAIRRESISTANCE_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETAIRRESISTANCE_CATEGORY - - - - WINDVOLUMEREQUESTBUS_SETAIRRESISTANCE_OUT_NAME - - - - WINDVOLUMEREQUESTBUS_SETAIRRESISTANCE_OUT_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETAIRRESISTANCE_IN_NAME - - - - WINDVOLUMEREQUESTBUS_SETAIRRESISTANCE_IN_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETAIRRESISTANCE_PARAM0_NAME - Simple Type: Number C++ Type: float - - - - WINDVOLUMEREQUESTBUS_SETAIRRESISTANCE_PARAM0_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETAIRDENSITY_NAME - Class/Bus: WindVolumeRequestBus Event/Method: GetAirDensity - Get Air Density - - - WINDVOLUMEREQUESTBUS_GETAIRDENSITY_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETAIRDENSITY_CATEGORY - - - - WINDVOLUMEREQUESTBUS_GETAIRDENSITY_OUT_NAME - - - - WINDVOLUMEREQUESTBUS_GETAIRDENSITY_OUT_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETAIRDENSITY_IN_NAME - - - - WINDVOLUMEREQUESTBUS_GETAIRDENSITY_IN_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETAIRDENSITY_OUTPUT0_NAME - C++ Type: float - Number - - - WINDVOLUMEREQUESTBUS_GETAIRDENSITY_OUTPUT0_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETSPEED_NAME - Class/Bus: WindVolumeRequestBus Event/Method: GetSpeed - Get Speed - - - WINDVOLUMEREQUESTBUS_GETSPEED_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETSPEED_CATEGORY - - - - WINDVOLUMEREQUESTBUS_GETSPEED_OUT_NAME - - - - WINDVOLUMEREQUESTBUS_GETSPEED_OUT_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETSPEED_IN_NAME - - - - WINDVOLUMEREQUESTBUS_GETSPEED_IN_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETSPEED_OUTPUT0_NAME - C++ Type: float - Number - - - WINDVOLUMEREQUESTBUS_GETSPEED_OUTPUT0_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETWINDDIRECTION_NAME - Class/Bus: WindVolumeRequestBus Event/Method: SetWindDirection - Set Wind Direction - - - WINDVOLUMEREQUESTBUS_SETWINDDIRECTION_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETWINDDIRECTION_CATEGORY - - - - WINDVOLUMEREQUESTBUS_SETWINDDIRECTION_OUT_NAME - - - - WINDVOLUMEREQUESTBUS_SETWINDDIRECTION_OUT_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETWINDDIRECTION_IN_NAME - - - - WINDVOLUMEREQUESTBUS_SETWINDDIRECTION_IN_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETWINDDIRECTION_PARAM0_NAME - Simple Type: Vector3 C++ Type: const Vector3& - - - - WINDVOLUMEREQUESTBUS_SETWINDDIRECTION_PARAM0_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETWINDDIRECTION_NAME - Class/Bus: WindVolumeRequestBus Event/Method: GetWindDirection - Get Wind Direction - - - WINDVOLUMEREQUESTBUS_GETWINDDIRECTION_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETWINDDIRECTION_CATEGORY - - - - WINDVOLUMEREQUESTBUS_GETWINDDIRECTION_OUT_NAME - - - - WINDVOLUMEREQUESTBUS_GETWINDDIRECTION_OUT_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETWINDDIRECTION_IN_NAME - - - - WINDVOLUMEREQUESTBUS_GETWINDDIRECTION_IN_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETWINDDIRECTION_OUTPUT0_NAME - C++ Type: const Vector3& - Vector3 - - - WINDVOLUMEREQUESTBUS_GETWINDDIRECTION_OUTPUT0_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETSPEED_NAME - Class/Bus: WindVolumeRequestBus Event/Method: SetSpeed - Set Speed - - - WINDVOLUMEREQUESTBUS_SETSPEED_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETSPEED_CATEGORY - - - - WINDVOLUMEREQUESTBUS_SETSPEED_OUT_NAME - - - - WINDVOLUMEREQUESTBUS_SETSPEED_OUT_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETSPEED_IN_NAME - - - - WINDVOLUMEREQUESTBUS_SETSPEED_IN_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETSPEED_PARAM0_NAME - Simple Type: Number C++ Type: float - - - - WINDVOLUMEREQUESTBUS_SETSPEED_PARAM0_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETVOLUMESIZE_NAME - Class/Bus: WindVolumeRequestBus Event/Method: SetVolumeSize - Set Volume Size - - - WINDVOLUMEREQUESTBUS_SETVOLUMESIZE_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETVOLUMESIZE_CATEGORY - - - - WINDVOLUMEREQUESTBUS_SETVOLUMESIZE_OUT_NAME - - - - WINDVOLUMEREQUESTBUS_SETVOLUMESIZE_OUT_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETVOLUMESIZE_IN_NAME - - - - WINDVOLUMEREQUESTBUS_SETVOLUMESIZE_IN_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETVOLUMESIZE_PARAM0_NAME - Simple Type: Vector3 C++ Type: const Vector3& - - - - WINDVOLUMEREQUESTBUS_SETVOLUMESIZE_PARAM0_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETELLIPSOIDAL_NAME - Class/Bus: WindVolumeRequestBus Event/Method: GetEllipsoidal - Get Ellipsoidal - - - WINDVOLUMEREQUESTBUS_GETELLIPSOIDAL_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETELLIPSOIDAL_CATEGORY - - - - WINDVOLUMEREQUESTBUS_GETELLIPSOIDAL_OUT_NAME - - - - WINDVOLUMEREQUESTBUS_GETELLIPSOIDAL_OUT_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETELLIPSOIDAL_IN_NAME - - - - WINDVOLUMEREQUESTBUS_GETELLIPSOIDAL_IN_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETELLIPSOIDAL_OUTPUT0_NAME - C++ Type: bool - Boolean - - - WINDVOLUMEREQUESTBUS_GETELLIPSOIDAL_OUTPUT0_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETFALLOFFINNER_NAME - Class/Bus: WindVolumeRequestBus Event/Method: GetFalloffInner - Get Falloff Inner - - - WINDVOLUMEREQUESTBUS_GETFALLOFFINNER_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETFALLOFFINNER_CATEGORY - - - - WINDVOLUMEREQUESTBUS_GETFALLOFFINNER_OUT_NAME - - - - WINDVOLUMEREQUESTBUS_GETFALLOFFINNER_OUT_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETFALLOFFINNER_IN_NAME - - - - WINDVOLUMEREQUESTBUS_GETFALLOFFINNER_IN_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_GETFALLOFFINNER_OUTPUT0_NAME - C++ Type: float - Number - - - WINDVOLUMEREQUESTBUS_GETFALLOFFINNER_OUTPUT0_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETELLIPSOIDAL_NAME - Class/Bus: WindVolumeRequestBus Event/Method: SetEllipsoidal - Set Ellipsoidal - - - WINDVOLUMEREQUESTBUS_SETELLIPSOIDAL_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETELLIPSOIDAL_CATEGORY - - - - WINDVOLUMEREQUESTBUS_SETELLIPSOIDAL_OUT_NAME - - - - WINDVOLUMEREQUESTBUS_SETELLIPSOIDAL_OUT_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETELLIPSOIDAL_IN_NAME - - - - WINDVOLUMEREQUESTBUS_SETELLIPSOIDAL_IN_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETELLIPSOIDAL_PARAM0_NAME - Simple Type: Boolean C++ Type: bool - - - - WINDVOLUMEREQUESTBUS_SETELLIPSOIDAL_PARAM0_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETFALLOFFINNER_NAME - Class/Bus: WindVolumeRequestBus Event/Method: SetFalloffInner - Set Falloff Inner - - - WINDVOLUMEREQUESTBUS_SETFALLOFFINNER_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETFALLOFFINNER_CATEGORY - - - - WINDVOLUMEREQUESTBUS_SETFALLOFFINNER_OUT_NAME - - - - WINDVOLUMEREQUESTBUS_SETFALLOFFINNER_OUT_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETFALLOFFINNER_IN_NAME - - - - WINDVOLUMEREQUESTBUS_SETFALLOFFINNER_IN_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETFALLOFFINNER_PARAM0_NAME - Simple Type: Number C++ Type: float - - - - WINDVOLUMEREQUESTBUS_SETFALLOFFINNER_PARAM0_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETAIRDENSITY_NAME - Class/Bus: WindVolumeRequestBus Event/Method: SetAirDensity - Set Air Density - - - WINDVOLUMEREQUESTBUS_SETAIRDENSITY_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETAIRDENSITY_CATEGORY - - - - WINDVOLUMEREQUESTBUS_SETAIRDENSITY_OUT_NAME - - - - WINDVOLUMEREQUESTBUS_SETAIRDENSITY_OUT_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETAIRDENSITY_IN_NAME - - - - WINDVOLUMEREQUESTBUS_SETAIRDENSITY_IN_TOOLTIP - - - - WINDVOLUMEREQUESTBUS_SETAIRDENSITY_PARAM0_NAME - Simple Type: Number C++ Type: float - - - - WINDVOLUMEREQUESTBUS_SETAIRDENSITY_PARAM0_TOOLTIP - - - EBus: ActorComponentNotificationBus @@ -79046,77 +77928,6 @@ The element is removed from its current parent and added as a child of the new p - - EBus: HttpClientComponentRequestBus - - HTTPCLIENTCOMPONENTREQUESTBUS_NAME - HttpClientComponentRequestBus - - - HTTPCLIENTCOMPONENTREQUESTBUS_TOOLTIP - - - - HTTPCLIENTCOMPONENTREQUESTBUS_CATEGORY - Networking - - - HTTPCLIENTCOMPONENTREQUESTBUS_MAKEHTTPREQUEST_NAME - Class/Bus: HttpClientComponentRequestBus Event/Method: MakeHttpRequest - MakeHttpRequest - - - HTTPCLIENTCOMPONENTREQUESTBUS_MAKEHTTPREQUEST_TOOLTIP - - - - HTTPCLIENTCOMPONENTREQUESTBUS_MAKEHTTPREQUEST_CATEGORY - - - - HTTPCLIENTCOMPONENTREQUESTBUS_MAKEHTTPREQUEST_OUT_NAME - - - - HTTPCLIENTCOMPONENTREQUESTBUS_MAKEHTTPREQUEST_OUT_TOOLTIP - - - - HTTPCLIENTCOMPONENTREQUESTBUS_MAKEHTTPREQUEST_IN_NAME - - - - HTTPCLIENTCOMPONENTREQUESTBUS_MAKEHTTPREQUEST_IN_TOOLTIP - - - - HTTPCLIENTCOMPONENTREQUESTBUS_MAKEHTTPREQUEST_PARAM0_NAME - Simple Type: String C++ Type: AZStd::basic_string<char, AZStd::char_traits<char>, allocator> - - - - HTTPCLIENTCOMPONENTREQUESTBUS_MAKEHTTPREQUEST_PARAM0_TOOLTIP - - - - HTTPCLIENTCOMPONENTREQUESTBUS_MAKEHTTPREQUEST_PARAM1_NAME - Simple Type: String C++ Type: AZStd::basic_string<char, AZStd::char_traits<char>, allocator> - - - - HTTPCLIENTCOMPONENTREQUESTBUS_MAKEHTTPREQUEST_PARAM1_TOOLTIP - - - - HTTPCLIENTCOMPONENTREQUESTBUS_MAKEHTTPREQUEST_PARAM2_NAME - Simple Type: String C++ Type: AZStd::basic_string<char, AZStd::char_traits<char>, allocator> - - - - HTTPCLIENTCOMPONENTREQUESTBUS_MAKEHTTPREQUEST_PARAM2_TOOLTIP - - - Handler: AWSBehaviorURLNotificationsBus 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/TestAnim/parent_tops.fbx b/AutomatedTesting/Assets/TestAnim/parent_tops.fbx new file mode 100644 index 0000000000..f13323ae8b --- /dev/null +++ b/AutomatedTesting/Assets/TestAnim/parent_tops.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3789abdf439a6d70438fd4bb1e06881ae6686a4699209c6bc371d22d161e5347 +size 26476 diff --git a/AutomatedTesting/Assets/TestAnim/parenting_test_default.fbx b/AutomatedTesting/Assets/TestAnim/parenting_test_default.fbx new file mode 100644 index 0000000000..d3e189bdc5 --- /dev/null +++ b/AutomatedTesting/Assets/TestAnim/parenting_test_default.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c987d7d79685fda83efcffb7e1afbcd356c37fc68ec5c663a89b02d4df10caea +size 46412 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/Code/Source/AutoGen/NetworkTestLevelEntityComponent.AutoComponent.xml b/AutomatedTesting/Gem/Code/Source/AutoGen/NetworkTestLevelEntityComponent.AutoComponent.xml new file mode 100644 index 0000000000..2fd196a2f6 --- /dev/null +++ b/AutomatedTesting/Gem/Code/Source/AutoGen/NetworkTestLevelEntityComponent.AutoComponent.xml @@ -0,0 +1,15 @@ + + + + + + + + + diff --git a/AutomatedTesting/Gem/Code/Source/AutoGen/NetworkTestPlayerComponent.AutoComponent.xml b/AutomatedTesting/Gem/Code/Source/AutoGen/NetworkTestPlayerComponent.AutoComponent.xml index 251d2b25af..b4dd35d741 100644 --- a/AutomatedTesting/Gem/Code/Source/AutoGen/NetworkTestPlayerComponent.AutoComponent.xml +++ b/AutomatedTesting/Gem/Code/Source/AutoGen/NetworkTestPlayerComponent.AutoComponent.xml @@ -29,8 +29,6 @@ - - diff --git a/AutomatedTesting/Gem/Code/automatedtesting_files.cmake b/AutomatedTesting/Gem/Code/automatedtesting_files.cmake index eb619104a4..1f6dbbd772 100644 --- a/AutomatedTesting/Gem/Code/automatedtesting_files.cmake +++ b/AutomatedTesting/Gem/Code/automatedtesting_files.cmake @@ -12,4 +12,5 @@ set(FILES Source/AutomatedTestingSystemComponent.cpp Source/AutomatedTestingSystemComponent.h Source/AutoGen/NetworkTestPlayerComponent.AutoComponent.xml + Source/AutoGen/NetworkTestLevelEntityComponent.AutoComponent.xml ) 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 f1e66ac492..8fc9838b52 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py @@ -21,7 +21,11 @@ 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("C36529679") + class AtomLevelLoadTest_Editor(EditorSharedTest): + from Atom.tests import hydra_Atom_LevelLoadTest as test_module @pytest.mark.test_case_id("C36525657") class AtomEditorComponents_BloomAdded(EditorSharedTest): @@ -120,6 +124,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 diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py index bd0477a1db..5299e55a2b 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py @@ -26,13 +26,3 @@ class TestAutomation(EditorTestSuite): @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/atom_constants.py b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py index e6d6ac7fb1..339108090f 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py @@ -32,6 +32,8 @@ GLOBAL_ILLUMINATION_QUALITY = { 'High': 2, } +# Level list used in Editor Level Load Test +LEVEL_LIST = ["hermanubis", "hermanubis_high", "macbeth_shaderballs", "PbrMaterialChart", "ShadowTest", "Sponza"] class AtomComponentProperties: """ @@ -195,11 +197,13 @@ class AtomComponentProperties: def entity_reference(property: str = 'name') -> str: """ Entity Reference component properties. + - 'EntityIdReferences' component container of entityId references. Initially empty. :param property: From the last element of the property tree path. Default 'name' for component name string. :return: Full property path OR component name if no property specified. """ properties = { 'name': 'Entity Reference', + 'EntityIdReferences': 'Controller|Configuration|EntityIdReferences', } return properties[property] 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..984774cd37 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_EntityReferenceAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_EntityReferenceAdded.py @@ -9,37 +9,58 @@ SPDX-License-Identifier: Apache-2.0 OR MIT class Tests: creation_undo = ( "UNDO Entity creation success", - "UNDO Entity creation failed") + "P0: UNDO Entity creation failed") creation_redo = ( "REDO Entity creation success", - "REDO Entity creation failed") + "P0: REDO Entity creation failed") entity_reference_creation = ( "Entity Reference Entity successfully created", - "Entity Reference Entity failed to be created") + "P0: Entity Reference Entity failed to be created") entity_reference_component = ( "Entity has an Entity Reference component", - "Entity failed to find Entity Reference component") + "P0: Entity failed to find Entity Reference component") enter_game_mode = ( "Entered game mode", - "Failed to enter game mode") + "P0: Failed to enter game mode") exit_game_mode = ( "Exited game mode", - "Couldn't exit game mode") + "P0: Couldn't exit game mode") is_visible = ( "Entity is visible", - "Entity was not visible") + "P0: Entity was not visible") is_hidden = ( "Entity is hidden", - "Entity was not hidden") + "P0: Entity was not hidden") entity_deleted = ( "Entity deleted", - "Entity was not deleted") + "P0: Entity was not deleted") deletion_undo = ( "UNDO deletion success", - "UNDO deletion failed") + "P0: UNDO deletion failed") deletion_redo = ( "REDO deletion success", - "REDO deletion failed") + "P0: REDO deletion failed") + entity_id_references_is_container = ( + "EntityIdReferences is a container property", + "P1: EntityIdReferences is NOT a container property") + container_append = ( + "EntityIdReferences append succeeded", + "P1: EntityIdReferences append did not succeed") + container_add = ( + "EntityIdReferences add succeeded", + "P1: EntityIdReferences add did not succeed") + container_update = ( + "EntityIdReferences update succeeded", + "P1: EntityIdReferences update did not succeed") + container_remove = ( + "EntityIdReferences remove succeeded", + "P1: EntityIdReferences remove did not succeed") + container_reset = ( + "EntityIdReferences reset succeeded", + "P1: EntityIdReferences reset did not succeed") + entity_reference_component_removed = ( + "Entity Reference component removed from entity", + "P1: Entity Reference component NOT removed from entity") def AtomEditorComponents_EntityReference_AddedToEntity(): @@ -60,13 +81,21 @@ def AtomEditorComponents_EntityReference_AddedToEntity(): 2) Add Entity Reference component to Entity Reference entity. 3) UNDO the entity creation and component addition. 4) REDO the entity creation and component addition. - 5) Enter/Exit game mode. - 6) Test IsHidden. - 7) Test IsVisible. - 8) Delete Entity Reference entity. - 9) UNDO deletion. - 10) REDO deletion. - 11) Look for errors. + 5) 'EntityIdReferences' is a container property + 6) Append item to 'EntityIdReferences' + 7) Add item to 'EntityIdReferences' + 8) Update item in 'EntityIdReferences' + 9) Remove item from 'EntityIdReferences' + 10) Reset the container property then put one entity reference back for further tests + 11) Remove component + 12) UNDO component remove + 13) Enter/Exit game mode. + 14) Test IsHidden. + 15) Test IsVisible. + 16) Delete Entity Reference entity. + 17) UNDO deletion. + 18) REDO deletion. + 19) Look for errors. :return: None """ @@ -81,7 +110,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. @@ -119,33 +148,107 @@ def AtomEditorComponents_EntityReference_AddedToEntity(): general.idle_wait_frames(1) Report.result(Tests.creation_redo, entity_reference_entity.exists()) - # 5. Enter/Exit game mode. + # Entities for EntityIdReferences tests + test_1 = EditorEntity.create_editor_entity('test_1') + test_2 = EditorEntity.create_editor_entity('test_2') + test_3 = EditorEntity.create_editor_entity('test_3') + + # 5. 'EntityIdReferences' is a container property + Report.result( + Tests.entity_id_references_is_container, + entity_reference_component.is_property_container( + AtomComponentProperties.entity_reference('EntityIdReferences'))) + + # 6. Append item to 'EntityIdReferences' + entity_reference_component.append_container_item( + AtomComponentProperties.entity_reference('EntityIdReferences'), test_1.id) + Report.result( + Tests.container_append, + entity_reference_component.get_container_item( + AtomComponentProperties.entity_reference('EntityIdReferences'), 0) == test_1.id) + + # 7. Add item to 'EntityIdReferences' + entity_reference_component.add_container_item( + AtomComponentProperties.entity_reference('EntityIdReferences'), 1, test_1.id) + Report.result( + Tests.container_add, + entity_reference_component.get_container_count( + AtomComponentProperties.entity_reference('EntityIdReferences')) == 2) + + # 8. Update item in 'EntityIdReferences' + entity_reference_component.update_container_item( + AtomComponentProperties.entity_reference('EntityIdReferences'), 1, test_2.id) + Report.result( + Tests.container_update, + entity_reference_component.get_container_item( + AtomComponentProperties.entity_reference('EntityIdReferences'), 1) == test_2.id) + + # 9. Remove item from 'EntityIdReferences' + entity_reference_component.append_container_item( + AtomComponentProperties.entity_reference('EntityIdReferences'), test_3.id) + count_before = entity_reference_component.get_container_count( + AtomComponentProperties.entity_reference('EntityIdReferences')) + entity_reference_component.remove_container_item( + AtomComponentProperties.entity_reference('EntityIdReferences'), 1) + count_after = entity_reference_component.get_container_count( + AtomComponentProperties.entity_reference('EntityIdReferences')) + Report.result( + Tests.container_remove, + ((count_before == 3) and (count_after == 2) and + (entity_reference_component.get_container_item( + AtomComponentProperties.entity_reference('EntityIdReferences'), 1) == test_3.id))) + + # 10. Reset the container property then put one entity reference back for further tests + entity_reference_component.reset_container(AtomComponentProperties.entity_reference('EntityIdReferences')) + general.idle_wait_frames(1) + Report.result( + Tests.container_reset, + entity_reference_component.get_container_count( + AtomComponentProperties.entity_reference('EntityIdReferences')) == 0) + entity_reference_component.append_container_item( + AtomComponentProperties.entity_reference('EntityIdReferences'), test_1.id) + + # 11. Remove component + entity_reference_entity.remove_component(AtomComponentProperties.entity_reference()) + general.idle_wait_frames(1) + Report.result(Tests.entity_reference_component_removed, not entity_reference_entity.has_component( + AtomComponentProperties.entity_reference())) + + # 12. UNDO component remove + general.undo() + general.idle_wait_frames(1) + Report.result(Tests.entity_reference_component, entity_reference_entity.has_component( + AtomComponentProperties.entity_reference())) + + # 13. Enter/Exit game mode. TestHelper.enter_game_mode(Tests.enter_game_mode) general.idle_wait_frames(1) TestHelper.exit_game_mode(Tests.exit_game_mode) - # 6. Test IsHidden. + # 14. Test IsHidden. entity_reference_entity.set_visibility_state(False) Report.result(Tests.is_hidden, entity_reference_entity.is_hidden() is True) - # 7. Test IsVisible. + # 15. Test IsVisible. entity_reference_entity.set_visibility_state(True) general.idle_wait_frames(1) Report.result(Tests.is_visible, entity_reference_entity.is_visible() is True) - # 8. Delete Entity Reference entity. + # 16. Delete Entity Reference entity. entity_reference_entity.delete() Report.result(Tests.entity_deleted, not entity_reference_entity.exists()) - # 9. UNDO deletion. + # 17. UNDO deletion. general.undo() + general.idle_wait_frames(1) Report.result(Tests.deletion_undo, entity_reference_entity.exists()) - # 10. REDO deletion. + # 18. 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. + # 19. Look for errors and asserts. TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0) for error_info in error_tracer.errors: Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}") 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_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_Atom_LevelLoadTest.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_Atom_LevelLoadTest.py new file mode 100644 index 0000000000..1efcbe4d01 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_Atom_LevelLoadTest.py @@ -0,0 +1,72 @@ +""" +Copyright (c) Contributors to the Open 3D Engine Project. +For complete copyright and license terms please see the LICENSE at the root of this distribution. + +SPDX-License-Identifier: Apache-2.0 OR MIT +""" + + +def Atom_LevelLoadTest(): + """ + Summary: + Loads all graphics levels within the AutomatedTesting project in editor. For each level this script will verify that + the level loads, and can enter/exit gameplay without crashing the editor. + + Test setup: + - Store all available levels in a list. + - Set up a for loop to run all checks for each level. + + Expected Behavior: + Test verifies that each level loads, enters/exits game mode, and reports success for all test actions. + + Test Steps for each level: + 1) Create tuple with level load success and failure messages + 2) Open the level using the python test tools command + 3) Verify level is loaded using a separate command, and report success/failure + 4) Enter gameplay and report result using a tuple + 5) Exit Gameplay and report result using a tuple + 6) Look for errors or asserts. + + :return: None + """ + + import azlmbr.legacy.general as general + + from editor_python_test_tools.utils import Report, Tracer, TestHelper + from Atom.atom_utils.atom_constants import LEVEL_LIST + + with Tracer() as error_tracer: + + for level in LEVEL_LIST: + + # 1. Create tuple with level load success and failure messages + level_check_tuple = (f"loaded {level}", f"failed to load {level}") + + # 2. Open the level using the python test tools command + TestHelper.init_idle() + TestHelper.open_level("Graphics", level) + + # 3. Verify level is loaded using a separate command, and report success/failure + Report.result(level_check_tuple, level == general.get_current_level_name()) + + # 4. Enter gameplay and report result using a tuple + enter_game_mode_tuple = (f"{level} entered gameplay successfully ", f"{level} failed to enter gameplay") + TestHelper.enter_game_mode(enter_game_mode_tuple) + general.idle_wait_frames(1) + + # 5. Exit gameplay and report result using a tuple + exit_game_mode_tuple = (f"{level} exited gameplay successfully ", f"{level} failed to exit gameplay") + TestHelper.exit_game_mode(exit_game_mode_tuple) + + + # 6. Look for errors or asserts. + TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0) + for error_info in error_tracer.errors: + Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}") + for assert_info in error_tracer.asserts: + Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}") + + +if __name__ == "__main__": + from editor_python_test_tools.utils import Report + Report.start_test(Atom_LevelLoadTest) diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py index c3398406ab..d8d4a77a65 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py @@ -473,12 +473,11 @@ class EditorEntity: :param component_names: List of component names to remove :return: None """ - type_ids = EditorComponent.get_type_ids(component_names, EditorEntityType.GAME) - for type_id in type_ids: - remove_outcome = editor.EditorComponentAPIBus(bus.Broadcast, "RemoveComponents", self.id, [type_id]) - assert ( - remove_outcome.IsSuccess() - ), f"Failure: could not remove component from '{self.get_name()}'" + component_ids = [component.id for component in self.get_components_of_type(component_names)] + remove_success = editor.EditorComponentAPIBus(bus.Broadcast, "RemoveComponents", component_ids) + assert ( + remove_success + ), f"Failure: could not remove component from entity '{self.get_name()}'" def get_components_of_type(self, component_names: list) -> List[EditorComponent]: """ 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/EditorPythonTestTools/editor_python_test_tools/prefab_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/prefab_utils.py index 016e01bc95..d0e51c4413 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/prefab_utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/prefab_utils.py @@ -48,8 +48,8 @@ def wait_for_propagation(): # This is a helper class which contains some of the useful information about a prefab instance. class PrefabInstance: - def __init__(self, prefab_file_name: str = None, container_entity: EditorEntity = None): - self.prefab_file_name: str = prefab_file_name + def __init__(self, prefab_file_path: str = None, container_entity: EditorEntity = None): + self.prefab_file_path: str = prefab_file_path self.container_entity: EditorEntity = container_entity def __eq__(self, other): @@ -66,7 +66,7 @@ class PrefabInstance: See if this instance is valid to be used with other prefab operations. :return: Whether the target instance is valid or not. """ - return self.container_entity.id.IsValid() and self.prefab_file_name in Prefab.existing_prefabs + return self.container_entity.id.IsValid() and self.prefab_file_path in Prefab.existing_prefabs def has_editor_prefab_component(self) -> bool: """ @@ -131,7 +131,7 @@ class PrefabInstance: has_correct_parent = reparented_container_entity_parent_id.ToString() == parent_entity_id.ToString() assert has_correct_parent, "Prefab Instance reparented is *not* under the expected parent entity" - current_instance_prefab = Prefab.get_prefab(self.prefab_file_name) + current_instance_prefab = Prefab.get_prefab(self.prefab_file_path) current_instance_prefab.instances.remove(self) self.container_entity = reparented_container_entity @@ -161,46 +161,48 @@ class Prefab: :param file_path: A unique file path of the target prefab. :return: Whether the target prefab is loaded or not. """ - return file_path in Prefab.existing_prefabs - + for entry in Prefab.existing_prefabs: + Report.info(f"PrefabPath: '{entry}'") + + return get_prefab_file_path(file_path) in Prefab.existing_prefabs @classmethod def prefab_exists(cls, file_path: str) -> bool: """ Check if a prefab exists in the directory for files of prefab tests. - :param file_name: A unique file name of the target prefab. + :param file_path: A unique file path of the target prefab. :return: Whether the target prefab exists or not. """ return path.exists(get_prefab_file_path(file_path)) @classmethod - def get_prefab(cls, file_name: str) -> Prefab: + def get_prefab(cls, file_path: str) -> Prefab: """ Return a prefab which can be used immediately. - :param file_name: A unique file name of the target prefab. + :param file_path: A unique file path of the target prefab. :return: The prefab with given file name. """ - assert file_name, "Received an empty file_name" - if Prefab.is_prefab_loaded(file_name): - return Prefab.existing_prefabs[file_name] + assert file_path, "Received an empty file_path" + if Prefab.is_prefab_loaded(file_path): + return Prefab.existing_prefabs[get_prefab_file_path(file_path)] else: - assert Prefab.prefab_exists(file_name), f"Attempted to get a prefab \"{file_name}\" that doesn't exist" - new_prefab = Prefab(file_name) - Prefab.existing_prefabs[file_name] = Prefab(file_name) + assert Prefab.prefab_exists(file_path), f"Attempted to get a prefab \"{file_path}\" that doesn't exist" + new_prefab = Prefab(file_path) + Prefab.existing_prefabs[new_prefab.file_path] = new_prefab return new_prefab @classmethod - def create_prefab(cls, entities: list[EditorEntity], file_name: str, prefab_instance_name: str=None) -> tuple(Prefab, PrefabInstance): + def create_prefab(cls, entities: list[EditorEntity], file_path: str, prefab_instance_name: str=None) -> tuple(Prefab, PrefabInstance): """ Create a prefab in memory and return it. The very first instance of this prefab will also be created. :param entities: The entities that should form the new prefab (along with their descendants). - :param file_name: A unique file name of new prefab. - :param prefab_instance_name: A name for the very first instance generated while prefab creation. The default instance name is the same as file_name. + :param file_path: A unique file path for new prefab. + :param prefab_instance_name: A name for the very first instance generated while prefab creation. The default instance name is the same as the file name in file_path. :return: Created Prefab object and the very first PrefabInstance object owned by the prefab. """ - assert not Prefab.is_prefab_loaded(file_name), f"Can't create Prefab '{file_name}' since the prefab already exists" + assert not Prefab.is_prefab_loaded(file_path), f"Can't create Prefab '{file_path}' since the prefab already exists" - new_prefab = Prefab(file_name) + new_prefab = Prefab(file_path) entity_ids = [entity.id for entity in entities] create_prefab_result = prefab.PrefabPublicRequestBus(bus.Broadcast, 'CreatePrefabInMemory', entity_ids, new_prefab.file_path) assert create_prefab_result.IsSuccess(), f"Prefab operation 'CreatePrefab' failed. Error: {create_prefab_result.GetError()}" @@ -210,15 +212,14 @@ class Prefab: children_entity_ids = container_entity.get_children_ids() assert len(children_entity_ids) == len(entities), f"Entity count of created prefab instance does *not* match the count of given entities." - - if prefab_instance_name: - container_entity.set_name(prefab_instance_name) - + wait_for_propagation() - new_prefab_instance = PrefabInstance(file_name, EditorEntity(container_entity_id)) + new_prefab_instance = PrefabInstance(new_prefab.file_path, EditorEntity(container_entity_id)) + if prefab_instance_name: + new_prefab_instance.container_entity.set_name(prefab_instance_name) new_prefab.instances.add(new_prefab_instance) - Prefab.existing_prefabs[file_name] = new_prefab + Prefab.existing_prefabs[new_prefab.file_path] = new_prefab return new_prefab, new_prefab_instance @classmethod @@ -250,7 +251,7 @@ class Prefab: assert False, "Not all entities and descendants in target prefabs are deleted." for instance in prefab_instances: - instance_deleted_prefab = Prefab.get_prefab(instance.prefab_file_name) + instance_deleted_prefab = Prefab.get_prefab(instance.prefab_file_path) instance_deleted_prefab.instances.remove(instance) instance = PrefabInstance() @@ -290,8 +291,7 @@ class Prefab: prefab_file_path = prefab.PrefabPublicRequestBus(bus.Broadcast, 'GetOwningInstancePrefabPath', duplicate_container_entity_id) assert prefab_file_path, "Returned file path should *not* be empty." - prefab_file_name = Path(prefab_file_path).stem - duplicate_instance_prefab = Prefab.get_prefab(prefab_file_name) + duplicate_instance_prefab = Prefab.get_prefab(prefab_file_path) duplicate_instance = PrefabInstance(prefab_file_path, EditorEntity(duplicate_container_entity_id)) duplicate_instance_prefab.instances.add(duplicate_instance) duplicate_instances.append(duplicate_instance) @@ -324,7 +324,7 @@ class Prefab: wait_for_propagation() - instance_owner_prefab = Prefab.get_prefab(prefab_instance.prefab_file_name) + instance_owner_prefab = Prefab.get_prefab(prefab_instance.prefab_file_path) instance_owner_prefab.instances.remove(prefab_instance) prefab_instance = PrefabInstance() @@ -346,13 +346,13 @@ class Prefab: container_entity_id = instantiate_prefab_result.GetValue() container_entity = EditorEntity(container_entity_id) - if name: - container_entity.set_name(name) - wait_for_propagation() new_prefab_instance = PrefabInstance(self.file_path, EditorEntity(container_entity_id)) - assert not new_prefab_instance in self.instances, "This prefab instance is already existed before this instantiation." + assert not new_prefab_instance in self.instances, "This prefab instance already existed before this instantiation." + if name: + new_prefab_instance.container_entity.set_name(name) + self.instances.add(new_prefab_instance) assert new_prefab_instance.is_at_position(prefab_position), "This prefab instance is *not* at expected position." diff --git a/AutomatedTesting/Gem/PythonTests/Multiplayer/TestSuite_Sandbox.py b/AutomatedTesting/Gem/PythonTests/Multiplayer/TestSuite_Sandbox.py index 20198be597..2b43b8c931 100644 --- a/AutomatedTesting/Gem/PythonTests/Multiplayer/TestSuite_Sandbox.py +++ b/AutomatedTesting/Gem/PythonTests/Multiplayer/TestSuite_Sandbox.py @@ -38,4 +38,8 @@ class TestAutomation(TestAutomationBase): def test_Multiplayer_BasicConnectivity_Connects(self, request, workspace, editor, launcher_platform): from .tests import Multiplayer_BasicConnectivity_Connects as test_module - self._run_prefab_test(request, workspace, editor, test_module) \ No newline at end of file + self._run_prefab_test(request, workspace, editor, test_module) + + def test_Multiplayer_SimpleNetworkLevelEntity(self, request, workspace, editor, launcher_platform): + from .tests import Multiplayer_SimpleNetworkLevelEntity as test_module + self._run_prefab_test(request, workspace, editor, test_module) diff --git a/AutomatedTesting/Gem/PythonTests/Multiplayer/tests/Multiplayer_SimpleNetworkLevelEntity.py b/AutomatedTesting/Gem/PythonTests/Multiplayer/tests/Multiplayer_SimpleNetworkLevelEntity.py new file mode 100644 index 0000000000..0d1067269c --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Multiplayer/tests/Multiplayer_SimpleNetworkLevelEntity.py @@ -0,0 +1,76 @@ +""" +Copyright (c) Contributors to the Open 3D Engine Project. +For complete copyright and license terms please see the LICENSE at the root of this distribution. + +SPDX-License-Identifier: Apache-2.0 OR MIT +""" + + +# Test Case Title : Check that level entities with network bindings are properly replicated. +# Note: This test should be ran on a fresh editor run; some bugs with spawnables occur only on the first editor play-mode. + + +# fmt: off +class TestSuccessFailTuples(): + enter_game_mode = ("Entered game mode", "Failed to enter game mode") + exit_game_mode = ("Exited game mode", "Couldn't exit game mode") + find_network_player = ("Found network player", "Couldn't find network player") +# fmt: on + + +def Multiplayer_SimpleNetworkLevelEntity(): + r""" + Summary: + Test to make sure that network entities in a level function and are replicated to clients as expected + + Level Description: + - Static + 1. NetLevelEntity. This is a networked entity which has a script attached which prints logs to ensure it's replicated. + + + Expected Outcome: + We should see logs stating that the net-sync'd level entity exists on both server and client. + + :return: + """ + import azlmbr.legacy.general as general + from editor_python_test_tools.utils import Report + from editor_python_test_tools.utils import Tracer + + from editor_python_test_tools.utils import TestHelper as helper + from ly_remote_console.remote_console_commands import RemoteConsole as RemoteConsole + + level_name = "SimpleNetworkLevelEntity" + player_prefab_name = "Player" + player_prefab_path = f"levels/multiplayer/{level_name}/{player_prefab_name}.network.spawnable" + + helper.init_idle() + + # 1) Open Level + helper.open_level("Multiplayer", level_name) + + with Tracer() as section_tracer: + # 2) Enter game mode + helper.multiplayer_enter_game_mode(TestSuccessFailTuples.enter_game_mode, player_prefab_path.lower()) + + # 3) Make sure the network player was spawned + player_id = general.find_game_entity(player_prefab_name) + Report.critical_result(TestSuccessFailTuples.find_network_player, player_id.IsValid()) + + # 4) Check the editor logs for network spawnable errors + ATTEMPTING_INVALID_NETSPAWN_WAIT_TIME_SECONDS = 0.0 # The editor will try to net-spawn its networked level entity before it's even a client. Make sure this didn't happen. + helper.fail_if_log_line_found('NetworkEntityManager', "RequestNetSpawnableInstantiation: Requested spawnable Root.network.spawnable doesn't exist in the NetworkSpawnableLibrary. Please make sure it is a network spawnable", section_tracer.errors, ATTEMPTING_INVALID_NETSPAWN_WAIT_TIME_SECONDS) + + # 5) Ensure the script graph attached to the level entity is running on the server + SCRIPTGRAPH_ENABLED_WAIT_TIME_SECONDS = 0.25 + helper.succeed_if_log_line_found('EditorServer', "Script: SimpleNetworkLevelEntity: On Graph Start", section_tracer.prints, SCRIPTGRAPH_ENABLED_WAIT_TIME_SECONDS) + + + # Exit game mode + helper.exit_game_mode(TestSuccessFailTuples.exit_game_mode) + + + +if __name__ == "__main__": + from editor_python_test_tools.utils import Report + Report.start_test(Multiplayer_SimpleNetworkLevelEntity) diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/Prefab/TestSuite_Main.py index 6e1f94d358..1fd48ee3c9 100644 --- a/AutomatedTesting/Gem/PythonTests/Prefab/TestSuite_Main.py +++ b/AutomatedTesting/Gem/PythonTests/Prefab/TestSuite_Main.py @@ -38,6 +38,10 @@ class TestAutomation(TestAutomationBase): from Prefab.tests.instantiate_prefab import InstantiatePrefab_ContainingASingleEntity as test_module self._run_prefab_test(request, workspace, editor, test_module) + def test_InstantiatePrefab_FromCreatedPrefabWithSingleEntity(self, request, workspace, editor, launcher_platform): + from Prefab.tests.instantiate_prefab import InstantiatePrefab_FromCreatedPrefabWithSingleEntity as test_module + self._run_prefab_test(request, workspace, editor, test_module) + def test_DeletePrefab_ContainingASingleEntity(self, request, workspace, editor, launcher_platform): from Prefab.tests.delete_prefab import DeletePrefab_ContainingASingleEntity as test_module self._run_prefab_test(request, workspace, editor, test_module) diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/Prefab/TestSuite_Main_Optimized.py index bf67b2c661..816b3b8e75 100644 --- a/AutomatedTesting/Gem/PythonTests/Prefab/TestSuite_Main_Optimized.py +++ b/AutomatedTesting/Gem/PythonTests/Prefab/TestSuite_Main_Optimized.py @@ -45,8 +45,12 @@ class TestAutomationNoAutoTestMode(EditorTestSuite): class test_InstantiatePrefab_ContainingASingleEntity(EditorSharedTest): from .tests.instantiate_prefab import InstantiatePrefab_ContainingASingleEntity as test_module + class test_InstantiatePrefab_FromCreatedPrefabWithSingleEntity(EditorSharedTest): + from .tests.instantiate_prefab import InstantiatePrefab_FromCreatedPrefabWithSingleEntity as test_module + class test_DeletePrefab_ContainingASingleEntity(EditorSharedTest): from .tests.delete_prefab import DeletePrefab_ContainingASingleEntity as test_module class test_DuplicatePrefab_ContainingASingleEntity(EditorSharedTest): - from .tests.duplicate_prefab import DuplicatePrefab_ContainingASingleEntity as test_module \ No newline at end of file + from .tests.duplicate_prefab import DuplicatePrefab_ContainingASingleEntity as test_module + \ No newline at end of file diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/tests/create_prefab/CreatePrefab_UnderAnEntity.py b/AutomatedTesting/Gem/PythonTests/Prefab/tests/create_prefab/CreatePrefab_UnderAnEntity.py index 5033c1da9c..4fdd5e4c4d 100644 --- a/AutomatedTesting/Gem/PythonTests/Prefab/tests/create_prefab/CreatePrefab_UnderAnEntity.py +++ b/AutomatedTesting/Gem/PythonTests/Prefab/tests/create_prefab/CreatePrefab_UnderAnEntity.py @@ -13,7 +13,8 @@ def CreatePrefab_UnderAnEntity(): Test is successful if the new instanced prefab of the child has the parent entity id """ - CAR_PREFAB_FILE_NAME = 'car_prefab' + from pathlib import Path + CAR_PREFAB_FILE_NAME = Path(__file__).stem + 'car_prefab' from editor_python_test_tools.editor_entity_utils import EditorEntity from editor_python_test_tools.prefab_utils import Prefab diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/tests/create_prefab/CreatePrefab_WithSingleEntity.py b/AutomatedTesting/Gem/PythonTests/Prefab/tests/create_prefab/CreatePrefab_WithSingleEntity.py index eb8a262a69..cd6d87a630 100644 --- a/AutomatedTesting/Gem/PythonTests/Prefab/tests/create_prefab/CreatePrefab_WithSingleEntity.py +++ b/AutomatedTesting/Gem/PythonTests/Prefab/tests/create_prefab/CreatePrefab_WithSingleEntity.py @@ -7,7 +7,8 @@ SPDX-License-Identifier: Apache-2.0 OR MIT def CreatePrefab_WithSingleEntity(): - CAR_PREFAB_FILE_NAME = 'car_prefab' + from pathlib import Path + CAR_PREFAB_FILE_NAME = Path(__file__).stem + 'car_prefab' from editor_python_test_tools.editor_entity_utils import EditorEntity from editor_python_test_tools.utils import Report diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_prefab/DeletePrefab_ContainingASingleEntity.py b/AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_prefab/DeletePrefab_ContainingASingleEntity.py index 919168019e..e2c4ead034 100644 --- a/AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_prefab/DeletePrefab_ContainingASingleEntity.py +++ b/AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_prefab/DeletePrefab_ContainingASingleEntity.py @@ -7,7 +7,8 @@ SPDX-License-Identifier: Apache-2.0 OR MIT def DeletePrefab_ContainingASingleEntity(): - CAR_PREFAB_FILE_NAME = 'car_prefab' + from pathlib import Path + CAR_PREFAB_FILE_NAME = Path(__file__).stem + 'car_prefab' from editor_python_test_tools.editor_entity_utils import EditorEntity from editor_python_test_tools.prefab_utils import Prefab diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/tests/detach_prefab/DetachPrefab_UnderAnotherPrefab.py b/AutomatedTesting/Gem/PythonTests/Prefab/tests/detach_prefab/DetachPrefab_UnderAnotherPrefab.py index 69dbcfc89c..326d58023f 100644 --- a/AutomatedTesting/Gem/PythonTests/Prefab/tests/detach_prefab/DetachPrefab_UnderAnotherPrefab.py +++ b/AutomatedTesting/Gem/PythonTests/Prefab/tests/detach_prefab/DetachPrefab_UnderAnotherPrefab.py @@ -7,8 +7,9 @@ SPDX-License-Identifier: Apache-2.0 OR MIT def DetachPrefab_UnderAnotherPrefab(): - CAR_PREFAB_FILE_NAME = 'car_prefab2' - WHEEL_PREFAB_FILE_NAME = 'wheel_prefab2' + from pathlib import Path + CAR_PREFAB_FILE_NAME = Path(__file__).stem + 'car_prefab' + WHEEL_PREFAB_FILE_NAME = Path(__file__).stem + 'wheel_prefab' import editor_python_test_tools.pyside_utils as pyside_utils diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/tests/duplicate_prefab/DuplicatePrefab_ContainingASingleEntity.py b/AutomatedTesting/Gem/PythonTests/Prefab/tests/duplicate_prefab/DuplicatePrefab_ContainingASingleEntity.py index e611303fbb..6acd303e2b 100644 --- a/AutomatedTesting/Gem/PythonTests/Prefab/tests/duplicate_prefab/DuplicatePrefab_ContainingASingleEntity.py +++ b/AutomatedTesting/Gem/PythonTests/Prefab/tests/duplicate_prefab/DuplicatePrefab_ContainingASingleEntity.py @@ -7,7 +7,8 @@ SPDX-License-Identifier: Apache-2.0 OR MIT def DuplicatePrefab_ContainingASingleEntity(): - CAR_PREFAB_FILE_NAME = 'car_prefab' + from pathlib import Path + CAR_PREFAB_FILE_NAME = Path(__file__).stem + 'car_prefab' from editor_python_test_tools.editor_entity_utils import EditorEntity from editor_python_test_tools.prefab_utils import Prefab diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/tests/instantiate_prefab/InstantiatePrefab_FromCreatedPrefabWithSingleEntity.py b/AutomatedTesting/Gem/PythonTests/Prefab/tests/instantiate_prefab/InstantiatePrefab_FromCreatedPrefabWithSingleEntity.py new file mode 100644 index 0000000000..ddd1528533 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Prefab/tests/instantiate_prefab/InstantiatePrefab_FromCreatedPrefabWithSingleEntity.py @@ -0,0 +1,34 @@ +""" +Copyright (c) Contributors to the Open 3D Engine Project. +For complete copyright and license terms please see the LICENSE at the root of this distribution. + +SPDX-License-Identifier: Apache-2.0 OR MIT +""" + +def InstantiatePrefab_FromCreatedPrefabWithSingleEntity(): + + from pathlib import Path + CAR_PREFAB_FILE_NAME = Path(__file__).stem + 'car_prefab' + + from editor_python_test_tools.editor_entity_utils import EditorEntity + from editor_python_test_tools.utils import Report + from editor_python_test_tools.prefab_utils import Prefab + + import Prefab.tests.PrefabTestUtils as prefab_test_utils + + prefab_test_utils.open_base_tests_level() + + # Creates a new entity at the root level + car_entity = EditorEntity.create_editor_entity() + car_prefab_entities = [car_entity] + + # Creates a prefab from the new entity + car_prefab, car_prefab_instance = Prefab.create_prefab(car_prefab_entities, CAR_PREFAB_FILE_NAME) + + # Instantiate another instance and verify + car_prefab_instance_2 = car_prefab.instantiate() + assert car_prefab_instance_2.is_valid(), "Failed to instantiate prefab" + +if __name__ == "__main__": + from editor_python_test_tools.utils import Report + Report.start_test(InstantiatePrefab_FromCreatedPrefabWithSingleEntity) diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/tests/reparent_prefab/ReparentPrefab_UnderAnotherPrefab.py b/AutomatedTesting/Gem/PythonTests/Prefab/tests/reparent_prefab/ReparentPrefab_UnderAnotherPrefab.py index 2c460a3298..49aeb97f63 100644 --- a/AutomatedTesting/Gem/PythonTests/Prefab/tests/reparent_prefab/ReparentPrefab_UnderAnotherPrefab.py +++ b/AutomatedTesting/Gem/PythonTests/Prefab/tests/reparent_prefab/ReparentPrefab_UnderAnotherPrefab.py @@ -7,8 +7,9 @@ SPDX-License-Identifier: Apache-2.0 OR MIT def ReparentPrefab_UnderAnotherPrefab(): - CAR_PREFAB_FILE_NAME = 'car_prefab' - WHEEL_PREFAB_FILE_NAME = 'wheel_prefab' + from pathlib import Path + CAR_PREFAB_FILE_NAME = Path(__file__).stem + 'car_prefab' + WHEEL_PREFAB_FILE_NAME = Path(__file__).stem + 'wheel_prefab' import editor_python_test_tools.pyside_utils as pyside_utils diff --git a/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/landscape_canvas_utils.py b/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/landscape_canvas_utils.py index d54e32089a..333422815f 100755 --- a/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/landscape_canvas_utils.py +++ b/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/landscape_canvas_utils.py @@ -19,12 +19,16 @@ def find_nodes_matching_entity_component(component_name, entity_id): :param entity_id: The entity ID to search for the given component node on :return List of matching nodes """ + component_type_id = hydra.get_component_type_id(component_name) component = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', entity_id, - hydra.get_component_type_id(component_name)) + component_type_id) + if component.IsSuccess(): component_id = component.GetValue() component_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'GetAllNodesMatchingEntityComponent', component_id) if component_node: print(f"{component_name} node found on entity {entity_id.ToString()}") + else: + print(f"Failed to find {component_name} node on entity {entity_id.ToString()}") return component_node diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py index 4fcdc371e7..0060a3b29a 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py @@ -32,10 +32,10 @@ def Menus_FileMenuOptions_Work(): file_menu_options = [ ("New Level",), - #("Open Level",), Temporarily disabled due to https://github.com/o3de/o3de/issues/6605 - #("Import",), Temporarily disabled due to https://github.com/o3de/o3de/issues/6746 + ("Open Level",), + #("Import",), #Temporarily disabled due to https://github.com/o3de/o3de/issues/6746 ("Save",), - #("Save As",), Temporarily disabled due to https://github.com/o3de/o3de/issues/6605 + ("Save As",), ("Save Level Statistics",), ("Edit Project Settings",), #("Edit Platform Settings",), Temporarily disabled due to https://github.com/o3de/o3de/issues/6604 diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt index ba607ede32..f016094b26 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 @@ -43,7 +43,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ NAME AutomatedTesting::LandscapeCanvasTests_Main_Optimized TEST_SERIAL TEST_SUITE main - PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas/TestSuite_Main_Optimized.py + PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas/TestSuite_Main.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 b5c00a53b7..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) 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..09dc6d7d0b 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_DependentComponentsAdded.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_DependentComponentsAdded.py @@ -68,8 +68,7 @@ def AreaNodes_DependentComponentsAdded(): newEntityId = parameters[0] # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Open Landscape Canvas tool and verify general.open_pane('Landscape Canvas') diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_EntityCreatedOnNodeAdd.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_EntityCreatedOnNodeAdd.py index f3f4a1862d..95294de2d2 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_EntityCreatedOnNodeAdd.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_EntityCreatedOnNodeAdd.py @@ -58,7 +58,6 @@ def AreaNodes_EntityCreatedOnNodeAdd(): 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 editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID @@ -67,8 +66,7 @@ def AreaNodes_EntityCreatedOnNodeAdd(): newEntityId = parameters[0] # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Open Landscape Canvas tool and verify general.open_pane('Landscape Canvas') diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_EntityRemovedOnNodeDelete.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_EntityRemovedOnNodeDelete.py index f8b0539759..4e5e75b3e1 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_EntityRemovedOnNodeDelete.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_EntityRemovedOnNodeDelete.py @@ -59,8 +59,8 @@ def AreaNodes_EntityRemovedOnNodeDelete(): import azlmbr.math as math import azlmbr.paths + 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 editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID @@ -73,8 +73,7 @@ def AreaNodes_EntityRemovedOnNodeDelete(): deletedEntityId = parameters[0] # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Open Landscape Canvas tool and verify general.open_pane('Landscape Canvas') diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/ComponentUpdates_UpdateGraph.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/ComponentUpdates_UpdateGraph.py index cc40d8b861..1635365a08 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/ComponentUpdates_UpdateGraph.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/ComponentUpdates_UpdateGraph.py @@ -1,15 +1,14 @@ """ Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - SPDX-License-Identifier: Apache-2.0 OR MIT """ class Tests: - slice_instantiated = ( - "Slice instantiated successfully", - "Failed to instantiate slice" + prefab_instantiated = ( + "Prefab instantiated successfully", + "Failed to instantiate prefab" ) lc_entity_found = ( "LandscapeCanvas entity found", @@ -24,7 +23,7 @@ class Tests: "Failed to find Distribution Filter component on BushSpawner entity" ) existing_graph_opened = ( - "Opened existing graph from slice", + "Opened existing graph from prefab", "Failed to open existing graph" ) dist_filter_node_found = ( @@ -66,10 +65,8 @@ def ComponentUpdates_UpdateGraph(): Summary: This test verifies that the Landscape Canvas graphs update properly when components are added/removed outside of Landscape Canvas. - Expected Behavior: Graphs properly reflect component changes made to entities outside of Landscape Canvas. - Test Steps: 1. Open Level 2. Find LandscapeCanvas named entity @@ -83,41 +80,36 @@ def ComponentUpdates_UpdateGraph(): 9. Add a new entity with unique name as a child of the Landscape Canvas entity 10. Add a Box Shape component to the new child entity 11. Ensure Box Shape node is present on the open graph - Note: - This test file must be called from the Open 3D Engine Editor command terminal - Any passed and failed tests are written to the Editor.log file. Parsing the file or running a log_monitor are required to observe the test results. - :return: None """ import os - import azlmbr.asset as asset import azlmbr.bus as bus import azlmbr.editor as editor import azlmbr.entity as entity import azlmbr.legacy.general as general import azlmbr.landscapecanvas as landscapecanvas import azlmbr.math as math - import azlmbr.slice as slice + import azlmbr.prefab as prefab 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 a simple level and instantiate LC_BushFlowerBlender.slice - helper.init_idle() - helper.open_level("Physics", "Base") + # Open a simple level and instantiate BushFlowerBlender.prefab + hydra.open_base_level() transform = math.Transform_CreateIdentity() position = math.Vector3(64.0, 64.0, 32.0) transform.invoke('SetPosition', position) - test_slice_path = os.path.join("Slices", "LC_BushFlowerBlender.slice") - test_slice_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", test_slice_path, math.Uuid(), - False) - test_slice = slice.SliceRequestBus(bus.Broadcast, 'InstantiateSliceFromAssetId', test_slice_id, transform) - Report.critical_result(Tests.slice_instantiated, test_slice.IsValid()) + test_prefab_path = os.path.join("Assets", "Prefabs", "BushFlowerBlender.prefab") + prefab_result = prefab.PrefabPublicRequestBus(bus.Broadcast, 'InstantiatePrefab', test_prefab_path, + entity.EntityId(), position) + Report.critical_result(Tests.prefab_instantiated, prefab_result.IsSuccess()) # Find root entity in the loaded level search_filter = entity.SearchFilter() @@ -126,8 +118,8 @@ def ComponentUpdates_UpdateGraph(): # Allow a few seconds for matching entity to be found helper.wait_for_condition(lambda: len(entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)) > 0, 5.0) lc_matching_entities = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter) - slice_root_id = lc_matching_entities[0] #Entity with Landscape Canvas component - Report.critical_result(Tests.lc_entity_found, slice_root_id.IsValid()) + prefab_root_id = lc_matching_entities[0] #Entity with Landscape Canvas component + Report.critical_result(Tests.lc_entity_found, prefab_root_id.IsValid()) # Find the BushSpawner entity search_filter.names = ["BushSpawner"] @@ -147,7 +139,7 @@ def ComponentUpdates_UpdateGraph(): # Open Landscape Canvas and the existing graph general.open_pane('Landscape Canvas') - open_graph = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', slice_root_id) + open_graph = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', prefab_root_id) Report.critical_result(Tests.existing_graph_opened, open_graph.IsValid()) # Verify that Distribution Filter node is present on the graph diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Component_AddedRemoved.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Component_AddedRemoved.py index 7f21a26595..465cf14481 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Component_AddedRemoved.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Component_AddedRemoved.py @@ -45,11 +45,9 @@ def Component_AddedRemoved(): 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() # Create an Entity at the root of the level newEntityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId()) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Edit_DisabledNodeDuplication.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Edit_DisabledNodeDuplication.py index 4dfc227c53..e5b66399cb 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Edit_DisabledNodeDuplication.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Edit_DisabledNodeDuplication.py @@ -59,8 +59,7 @@ def Edit_DisabledNodeDuplication(): newEntityId = parameters[0] # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Open Landscape Canvas tool and verify general.open_pane('Landscape Canvas') diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Edit_UndoNodeDelete_SliceEntity.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Edit_UndoNodeDelete_PrefabEntity.py old mode 100755 new mode 100644 similarity index 85% rename from AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Edit_UndoNodeDelete_SliceEntity.py rename to AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Edit_UndoNodeDelete_PrefabEntity.py index a26e16755f..d7735f59c2 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Edit_UndoNodeDelete_SliceEntity.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Edit_UndoNodeDelete_PrefabEntity.py @@ -1,15 +1,14 @@ """ Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - SPDX-License-Identifier: Apache-2.0 OR MIT """ class Tests: - slice_spawned = ( - "Slice instantiated successfully", - "Failed to instantiate slice" + prefab_instantiated = ( + "Prefab instantiated successfully", + "Failed to instantiate prefab" ) lc_entity_found = ( "Landscape Canvas entity found", @@ -31,31 +30,28 @@ class Tests: "Vegetation Layer Spawner node was successfully removed", "Failed to remove Vegetation Layer Spawner node" ) -def Edit_UndoNodeDelete_SliceEntity(): + + +def Edit_UndoNodeDelete_PrefabEntity(): """ Summary: - This test verifies Editor stability after undoing the deletion of nodes on a slice entity. - + This test verifies Editor stability after undoing the deletion of nodes on a prefab entity. Expected Behavior: Editor remains stable and free of crashes. - Test Steps: 1) Open a simple level - 2) Instantiate a slice with a Landscape Canvas setup + 2) Instantiate a prefab with a Landscape Canvas setup 3) Find a specific node on the graph, and delete it 4) Restore the node with Undo - Note: - This test file must be called from the Open 3D Engine Editor command terminal - Any passed and failed tests are written to the Editor.log file. Parsing the file or running a log_monitor are required to observe the test results. - :return: None """ import os - import azlmbr.asset as asset import azlmbr.bus as bus import azlmbr.editor as editor import azlmbr.entity as entity @@ -63,25 +59,23 @@ def Edit_UndoNodeDelete_SliceEntity(): import azlmbr.editor.graph as graph import azlmbr.landscapecanvas as landscapecanvas import azlmbr.math as math - import azlmbr.slice as slice + import azlmbr.prefab as prefab 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() # Instantiate slice transform = math.Transform_CreateIdentity() position = math.Vector3(64.0, 64.0, 32.0) transform.invoke('SetPosition', position) - test_slice_path = os.path.join("Slices", "LC_BushFlowerBlender.slice") - test_slice_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", test_slice_path, math.Uuid(), - False) - test_slice = slice.SliceRequestBus(bus.Broadcast, 'InstantiateSliceFromAssetId', test_slice_id, transform) - Report.result(Tests.slice_spawned, test_slice.IsValid()) + test_prefab_path = os.path.join("Assets", "Prefabs", "BushFlowerBlender.prefab") + prefab_result = prefab.PrefabPublicRequestBus(bus.Broadcast, 'InstantiatePrefab', test_prefab_path, + entity.EntityId(), position) + Report.critical_result(Tests.prefab_instantiated, prefab_result.IsSuccess()) # Find root entity in the loaded level search_filter = entity.SearchFilter() @@ -134,5 +128,4 @@ def Edit_UndoNodeDelete_SliceEntity(): if __name__ == "__main__": from editor_python_test_tools.utils import Report - Report.start_test(Edit_UndoNodeDelete_SliceEntity) - + Report.start_test(Edit_UndoNodeDelete_PrefabEntity) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientMixer_NodeConstruction.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientMixer_NodeConstruction.py index c390df7c61..95a9b08fe5 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientMixer_NodeConstruction.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientMixer_NodeConstruction.py @@ -76,7 +76,6 @@ def GradientMixer_NodeConstruction(): 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 editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID @@ -85,8 +84,7 @@ def GradientMixer_NodeConstruction(): newEntityId = parameters[0] # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Open Landscape Canvas tool and verify general.open_pane('Landscape Canvas') diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientModifierNodes_EntityCreatedOnNodeAdd.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientModifierNodes_EntityCreatedOnNodeAdd.py index c3952fe34b..3b6e28ca3d 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientModifierNodes_EntityCreatedOnNodeAdd.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientModifierNodes_EntityCreatedOnNodeAdd.py @@ -58,7 +58,6 @@ def GradientModifierNodes_EntityCreatedOnNodeAdd(): 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 editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID @@ -67,8 +66,7 @@ def GradientModifierNodes_EntityCreatedOnNodeAdd(): newEntityId = parameters[0] # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Open Landscape Canvas tool and verify general.open_pane('Landscape Canvas') diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientModifierNodes_EntityRemovedOnNodeDelete.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientModifierNodes_EntityRemovedOnNodeDelete.py index d7789a21fb..e6fb61e10a 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientModifierNodes_EntityRemovedOnNodeDelete.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientModifierNodes_EntityRemovedOnNodeDelete.py @@ -58,8 +58,8 @@ def GradientModifierNodes_EntityRemovedOnNodeDelete(): import azlmbr.legacy.general as general import azlmbr.math as math + 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 editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID @@ -72,8 +72,7 @@ def GradientModifierNodes_EntityRemovedOnNodeDelete(): deletedEntityId = parameters[0] # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Open Landscape Canvas tool and verify general.open_pane('Landscape Canvas') diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_DependentComponentsAdded.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_DependentComponentsAdded.py index 63df9a6fcb..c2007e49e2 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_DependentComponentsAdded.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_DependentComponentsAdded.py @@ -60,7 +60,6 @@ def GradientNodes_DependentComponentsAdded(): 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 editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID @@ -69,8 +68,7 @@ def GradientNodes_DependentComponentsAdded(): newEntityId = parameters[0] # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Open Landscape Canvas tool and verify general.open_pane('Landscape Canvas') diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_EntityCreatedOnNodeAdd.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_EntityCreatedOnNodeAdd.py index d5595e342c..5111f45f22 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_EntityCreatedOnNodeAdd.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_EntityCreatedOnNodeAdd.py @@ -58,7 +58,6 @@ def GradientNodes_EntityCreatedOnNodeAdd(): 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 editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID @@ -67,8 +66,7 @@ def GradientNodes_EntityCreatedOnNodeAdd(): newEntityId = parameters[0] # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Open Landscape Canvas tool and verify general.open_pane('Landscape Canvas') diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_EntityRemovedOnNodeDelete.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_EntityRemovedOnNodeDelete.py index e5bfbfc7f1..1840fd3f1a 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_EntityRemovedOnNodeDelete.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_EntityRemovedOnNodeDelete.py @@ -58,8 +58,8 @@ def GradientNodes_EntityRemovedOnNodeDelete(): import azlmbr.legacy.general as general import azlmbr.math as math + 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 editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID @@ -72,8 +72,7 @@ def GradientNodes_EntityRemovedOnNodeDelete(): deletedEntityId = parameters[0] # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Open Landscape Canvas tool and verify general.open_pane('Landscape Canvas') diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphClosed_OnEntityDelete.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphClosed_OnEntityDelete.py index 0f83688206..1902516fb3 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphClosed_OnEntityDelete.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphClosed_OnEntityDelete.py @@ -51,8 +51,8 @@ def GraphClosed_OnEntityDelete(): import azlmbr.editor.graph as graph import azlmbr.legacy.general as general + import editor_python_test_tools.hydra_editor_utils as hydra from editor_python_test_tools.utils import Report - from editor_python_test_tools.utils import TestHelper as helper editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID @@ -61,8 +61,7 @@ def GraphClosed_OnEntityDelete(): newRootEntityId = parameters[0] # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Open Landscape Canvas tool and verify general.open_pane('Landscape Canvas') diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphClosed_OnLevelChange.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphClosed_OnLevelChange.py index 67c2ec6908..d5d46c042d 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphClosed_OnLevelChange.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphClosed_OnLevelChange.py @@ -51,14 +51,13 @@ def GraphClosed_OnLevelChange(): import azlmbr.editor.graph as graph import azlmbr.legacy.general as general + import editor_python_test_tools.hydra_editor_utils as hydra from editor_python_test_tools.utils import Report - from editor_python_test_tools.utils import TestHelper as helper editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Open Landscape Canvas tool and verify general.open_pane('Landscape Canvas') @@ -73,7 +72,7 @@ def GraphClosed_OnLevelChange(): Report.result(Tests.graph_registered, graph_registered) # Open a different level, which should close any open Landscape Canvas graphs - general.open_level_no_prompt('WhiteBox/EmptyLevel') + general.open_level_no_prompt('Base') # Make sure the graph we created is now closed graphIsOpen = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphClosed_TabbedGraph.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphClosed_TabbedGraph.py index 83762e0afb..d33ee7746f 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphClosed_TabbedGraph.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphClosed_TabbedGraph.py @@ -51,8 +51,8 @@ def GraphClosed_TabbedGraphClosesIndependently(): import azlmbr.editor.graph as graph import azlmbr.legacy.general as general + import editor_python_test_tools.hydra_editor_utils as hydra from editor_python_test_tools.utils import Report - from editor_python_test_tools.utils import TestHelper as helper editor_id = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID @@ -65,8 +65,7 @@ def GraphClosed_TabbedGraphClosesIndependently(): return graph_open # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Open Landscape Canvas tool and verify general.open_pane('Landscape Canvas') diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphUpdates_UpdateComponents.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphUpdates_UpdateComponents.py index c489c738d5..6a007a9014 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphUpdates_UpdateComponents.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphUpdates_UpdateComponents.py @@ -1,18 +1,17 @@ """ Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - SPDX-License-Identifier: Apache-2.0 OR MIT """ class Tests: - slice_instantiated = ( - "Slice instantiated successfully", - "Failed to instantiate slice" + prefab_instantiated = ( + "Prefab instantiated successfully", + "Failed to instantiate prefab" ) existing_graph_opened = ( - "Opened existing graph from slice", + "Opened existing graph from prefab", "Failed to open existing graph" ) node_removed = ( @@ -37,13 +36,11 @@ def GraphUpdates_UpdateComponent(): """ Summary: This test verifies that components are properly updated as nodes are added/removed/updated. - Expected Behavior: Landscape Canvas node CRUD properly updates component entities. - Test Steps: 1. Open Level. - 2. Open the graph on LC_BushFlowerBlender.slice + 2. Open the graph on BushFlowerBlender.prefab 3. Find the Rotation Modifier node on the BushSpawner entity 4. Delete the Rotation Modifier node 5. Ensure the Vegetation Rotation Modifier component is removed from the BushSpawner entity @@ -51,18 +48,15 @@ def GraphUpdates_UpdateComponent(): 7. Ensure BushSpawner entity is deleted 8. Change connection from second Rotation Modifier node to a different Gradient 9. Ensure Gradient reference on component is updated - Note: - This test file must be called from the Open 3D Engine Editor command terminal - Any passed and failed tests are written to the Editor.log file. Parsing the file or running a log_monitor are required to observe the test results. - :return: None """ import os - import azlmbr.asset as asset import azlmbr.bus as bus import azlmbr.editor as editor import azlmbr.entity as entity @@ -70,39 +64,37 @@ def GraphUpdates_UpdateComponent(): import azlmbr.editor.graph as graph import azlmbr.landscapecanvas as landscapecanvas import azlmbr.math as math - import azlmbr.slice as slice + import azlmbr.prefab as prefab import automatedtesting_shared.landscape_canvas_utils as lc 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 a simple level and instantiate LC_BushFlowerBlender.slice - helper.init_idle() - helper.open_level("Physics", "Base") + # Open a simple level and instantiate BushFlowerBlender.prefab + hydra.open_base_level() transform = math.Transform_CreateIdentity() position = math.Vector3(64.0, 64.0, 32.0) transform.invoke('SetPosition', position) - test_slice_path = os.path.join("Slices", "LC_BushFlowerBlender.slice") - test_slice_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", test_slice_path, math.Uuid(), - False) - test_slice = slice.SliceRequestBus(bus.Broadcast, 'InstantiateSliceFromAssetId', test_slice_id, transform) - Report.critical_result(Tests.slice_instantiated, test_slice.IsValid()) + test_prefab_path = os.path.join("Assets", "Prefabs", "BushFlowerBlender.prefab") + prefab_result = prefab.PrefabPublicRequestBus(bus.Broadcast, 'InstantiatePrefab', test_prefab_path, + entity.EntityId(), position) + Report.critical_result(Tests.prefab_instantiated, prefab_result.IsSuccess()) - # Search for root entity to ensure slice is loaded + # Search for root entity to ensure prefab is loaded search_filter = entity.SearchFilter() search_filter.names = ["LandscapeCanvas"] helper.wait_for_condition(lambda: len(entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)) > 0, 5.0) + prefab_lc_root = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)[0] # Find needed entities in the loaded level - slice_root_id = hydra.find_entity_by_name('LandscapeCanvas') bush_spawner_id = hydra.find_entity_by_name('BushSpawner') flower_spawner_id = hydra.find_entity_by_name('FlowerSpawner') inverted_perlin_noise_id = hydra.find_entity_by_name('Invert') # Open Landscape Canvas and the existing graph general.open_pane('Landscape Canvas') - open_graph_id = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', slice_root_id) + open_graph_id = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', prefab_lc_root) Report.critical_result(Tests.existing_graph_opened, open_graph_id.IsValid()) # Find the Rotation Modifier node on the BushSpawner entity @@ -110,6 +102,7 @@ def GraphUpdates_UpdateComponent(): # Remove the Rotation Modifier node graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', open_graph_id, rotation_modifier_node[0]) + general.idle_wait_frames(2) # Verify node was removed rotation_modifier_node = lc.find_nodes_matching_entity_component('Vegetation Rotation Modifier', bush_spawner_id) @@ -121,14 +114,18 @@ def GraphUpdates_UpdateComponent(): Report.result(Tests.component_removed, not has_rotation_modifier) # Find the Vegetation Layer Spawner node on the BushSpawner entity + open_graph_id = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', prefab_lc_root) layer_spawner_node = lc.find_nodes_matching_entity_component('Vegetation Layer Spawner', bush_spawner_id) # Remove the Vegetation Layer Spawner node and verify the corresponding entity is deleted graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', open_graph_id, layer_spawner_node[0]) + general.idle_wait_frames(2) + layer_spawner_node = lc.find_nodes_matching_entity_component('Vegetation Layer Spawner', bush_spawner_id) bush_spawner_id = hydra.find_entity_by_name('BushSpawner') - Report.result(Tests.entity_deleted, not bush_spawner_id) + Report.result(Tests.entity_deleted, not layer_spawner_node and not bush_spawner_id) # Connect the FlowerSpawner's Rotation Modifier node to the Invert Gradient Modifier node + open_graph_id = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', prefab_lc_root) rotation_modifier_node = lc.find_nodes_matching_entity_component('Vegetation Rotation Modifier', flower_spawner_id) invert_node = lc.find_nodes_matching_entity_component('Invert Gradient Modifier', inverted_perlin_noise_id) @@ -137,7 +134,7 @@ def GraphUpdates_UpdateComponent(): graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', open_graph_id, invert_node[0], outbound_gradient_slot, rotation_modifier_node[0], inbound_gradient_z_slot) - general.idle_wait(1.0) # Add a small wait to ensure component property has time to update + general.idle_wait_frames(2) # Add a small wait to ensure component property has time to update # Verify the Gradient Entity Id reference on the Rotation Modifier component was properly set rotation_type_id = hydra.get_component_type_id('Vegetation Rotation Modifier') diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/LayerBlender_NodeConstruction.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/LayerBlender_NodeConstruction.py index b2bf20411b..da9a21aee6 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/LayerBlender_NodeConstruction.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/LayerBlender_NodeConstruction.py @@ -64,7 +64,6 @@ def LayerBlender_NodeConstruction(): 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 editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID @@ -73,8 +72,7 @@ def LayerBlender_NodeConstruction(): newEntityId = parameters[0] # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Open Landscape Canvas tool and verify general.open_pane('Landscape Canvas') diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/LayerExtenderNodes_ComponentEntitySync.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/LayerExtenderNodes_ComponentEntitySync.py index 510c404614..cd54a741ec 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/LayerExtenderNodes_ComponentEntitySync.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/LayerExtenderNodes_ComponentEntitySync.py @@ -63,7 +63,6 @@ def LayerExtenderNodes_ComponentEntitySync(): 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 editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID @@ -72,8 +71,7 @@ def LayerExtenderNodes_ComponentEntitySync(): newEntityId = parameters[0] # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Open Landscape Canvas tool and verify general.open_pane('Landscape Canvas') diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/NewGraph_CreatedSuccessfully.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/NewGraph_CreatedSuccessfully.py index d13c5dfa2f..f7564a643d 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/NewGraph_CreatedSuccessfully.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/NewGraph_CreatedSuccessfully.py @@ -60,7 +60,6 @@ def NewGraph_CreatedSuccessfully(): 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 editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID @@ -69,8 +68,7 @@ def NewGraph_CreatedSuccessfully(): new_root_entity_id = parameters[0] # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Listen for entity creation notifications so we can check if the entity created # with the new graph has our Landscape Canvas component automatically added diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Prefab_CreateInstantiate.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Prefab_CreateInstantiate.py new file mode 100644 index 0000000000..894a69a40e --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Prefab_CreateInstantiate.py @@ -0,0 +1,69 @@ +""" +Copyright (c) Contributors to the Open 3D Engine Project. +For complete copyright and license terms please see the LICENSE at the root of this distribution. +SPDX-License-Identifier: Apache-2.0 OR MIT +""" + + +class Tests: + prefab_created = ( + "Prefab created successfully", + "Failed to create prefab" + ) + prefab_instantiated = ( + "Prefab instantiated successfully", + "Failed to instantiate prefab" + ) + + +def Prefab_CreateInstantiate(): + """ + Summary: + A prefab containing the LandscapeCanvas component can be created/instantiated. + Expected Result: + Prefab is created/processed/instantiated successfully and free of errors/warnings. + Test Steps: + 1) Open a simple level + 2) Create a new entity with a Landscape Canvas component + 3) Create a prefab of the new entity + 4) Instantiate a new copy of the prefab + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + :return: None + """ + + import azlmbr.math as math + + 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 + from editor_python_test_tools.prefab_utils import Prefab + + # Open an existing simple level + hydra.open_base_level() + + # Create entity with Landscape Canvas component + position = math.Vector3(512.0, 512.0, 32.0) + landscape_canvas = hydra.Entity("landscape_canvas_entity") + landscape_canvas.create_entity(position, ["Landscape Canvas"]) + + # Create in-memory prefab from the created entity + lc_prefab_filename = "LC_PrefabTest" + lc_prefab, lc_prefab_instance = Prefab.create_prefab([landscape_canvas], lc_prefab_filename) + + # Verify if prefab is created + helper.wait_for_condition(lambda: lc_prefab.is_prefab_loaded(lc_prefab_filename), 5.0) + Report.result(Tests.prefab_created, lc_prefab.is_prefab_loaded(lc_prefab_filename)) + + # Instantiate prefab + lc_prefab_instance2 = lc_prefab.instantiate() + helper.wait_for_condition(lambda: lc_prefab_instance2.has_editor_prefab_component(), 5.0) + Report.result(Tests.prefab_instantiated, lc_prefab_instance2.has_editor_prefab_component()) + + +if __name__ == "__main__": + + from editor_python_test_tools.utils import Report + Report.start_test(Prefab_CreateInstantiate) \ No newline at end of file diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/ShapeNodes_EntityCreatedOnNodeAdd.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/ShapeNodes_EntityCreatedOnNodeAdd.py index 93464c7ad3..c93b377945 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/ShapeNodes_EntityCreatedOnNodeAdd.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/ShapeNodes_EntityCreatedOnNodeAdd.py @@ -58,7 +58,6 @@ def ShapeNodes_EntityCreatedOnNodeAdd(): 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 editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID @@ -66,10 +65,8 @@ def ShapeNodes_EntityCreatedOnNodeAdd(): global newEntityId newEntityId = parameters[0] - # Open an existing simple level - - helper.init_idle() - helper.open_level("Physics", "Base") + # Open an existing simple level + hydra.open_base_level() # Open Landscape Canvas tool and verify general.open_pane('Landscape Canvas') diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/ShapeNodes_EntityRemovedOnNodeDelete.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/ShapeNodes_EntityRemovedOnNodeDelete.py index d2708f643d..4057e7f6e9 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/ShapeNodes_EntityRemovedOnNodeDelete.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/ShapeNodes_EntityRemovedOnNodeDelete.py @@ -58,8 +58,8 @@ def ShapeNodes_EntityRemovedOnNodeDelete(): import azlmbr.legacy.general as general import azlmbr.math as math + 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 editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID @@ -72,8 +72,7 @@ def ShapeNodes_EntityRemovedOnNodeDelete(): deletedEntityId = parameters[0] # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Open Landscape Canvas tool and verify general.open_pane('Landscape Canvas') diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Slice_CreateInstantiate.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Slice_CreateInstantiate.py deleted file mode 100644 index c5ab08f99a..0000000000 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Slice_CreateInstantiate.py +++ /dev/null @@ -1,84 +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 -""" - - -class Tests: - slice_created = ( - "Slice created successfully", - "Failed to create slice" - ) - slice_instantiated = ( - "Slice instantiated successfully", - "Failed to instantiate slice" - ) - - -def Slice_CreateInstantiate(): - """ - Summary: - A slice containing the LandscapeCanvas component can be created/instantiated. - - Expected Result: - Slice is created/processed/instantiated successfully and free of errors/warnings. - - Test Steps: - 1) Open a simple level - 2) Create a new entity with a Landscape Canvas component - 3) Create a slice of the new entity - 4) Instantiate a new copy of the slice - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - :return: None - """ - - import os - - import azlmbr.math as math - import azlmbr.bus as bus - import azlmbr.asset as asset - import azlmbr.slice as slice - - import editor_python_test_tools.hydra_editor_utils as hydra - from editor_python_test_tools.utils import Report - from editor_python_test_tools.utils import TestHelper as helper - - def path_is_valid_asset(asset_path): - asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", asset_path, math.Uuid(), False) - return asset_id.invoke("IsValid") - - # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") - - # Create entity with Landscape Canvas component - position = math.Vector3(512.0, 512.0, 32.0) - landscape_canvas = hydra.Entity("landscape_canvas_entity") - landscape_canvas.create_entity(position, ["Landscape Canvas"]) - - # Create slice from the created entity - slice_path = os.path.join("slices", "TestSlice.slice") - slice.SliceRequestBus(bus.Broadcast, "CreateNewSlice", landscape_canvas.id, slice_path) - - # Verify if slice is created - helper.wait_for_condition(lambda: path_is_valid_asset(slice_path), 5.0) - Report.result(Tests.slice_created, path_is_valid_asset(slice_path)) - - # Instantiate slice - transform = math.Transform_CreateIdentity() - asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", slice_path, math.Uuid(), False) - test_slice = slice.SliceRequestBus(bus.Broadcast, "InstantiateSliceFromAssetId", asset_id, transform) - helper.wait_for_condition(lambda: test_slice.IsValid(), 5.0) - Report.result(Tests.slice_instantiated, test_slice.IsValid()) - - -if __name__ == "__main__": - - from editor_python_test_tools.utils import Report - Report.start_test(Slice_CreateInstantiate) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/SlotConnections_UpdateComponentReferences.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/SlotConnections_UpdateComponentReferences.py index 3169908621..208849ea61 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/SlotConnections_UpdateComponentReferences.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/SlotConnections_UpdateComponentReferences.py @@ -67,7 +67,6 @@ def SlotConnections_UpdateComponentReferences(): 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 editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID @@ -101,8 +100,7 @@ def SlotConnections_UpdateComponentReferences(): newEntityId = parameters[0] # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Open Landscape Canvas tool and verify general.open_pane('Landscape Canvas') diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Main.py index dedc9c70c0..12e426e400 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Main.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Main.py @@ -1,29 +1,88 @@ """ Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - SPDX-License-Identifier: Apache-2.0 OR MIT """ -import os import pytest -import sys -import ly_test_tools.environment.file_system as file_system - -sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../automatedtesting_shared') -from base import TestAutomationBase +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_LandscapeCanvas_SlotConnections_UpdateComponentReferences(self, request, workspace, editor, launcher_platform): - from .EditorScripts import SlotConnections_UpdateComponentReferences as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) + class test_LandscapeCanvas_AreaNodes_DependentComponentsAdded(EditorSharedTest): + from .EditorScripts import AreaNodes_DependentComponentsAdded as test_module - def test_LandscapeCanvas_GradientMixer_NodeConstruction(self, request, workspace, editor, launcher_platform): + class test_LandscapeCanvas_AreaNodes_EntityCreatedOnNodeAdd(EditorSharedTest): + from .EditorScripts import AreaNodes_EntityCreatedOnNodeAdd as test_module + + class test_LandscapeCanvas_AreaNodes_EntityRemovedOnNodeDelete(EditorSharedTest): + from .EditorScripts import AreaNodes_EntityRemovedOnNodeDelete as test_module + + class test_LandscapeCanvas_Component_AddedRemoved(EditorSharedTest): + from .EditorScripts import Component_AddedRemoved as test_module + + class test_LandscapeCanvas_ComponentUpdates_UpdateGraph(EditorSharedTest): + from .EditorScripts import ComponentUpdates_UpdateGraph as test_module + + class test_LandscapeCanvas_Edit_DisabledNodeDuplication(EditorSharedTest): + from .EditorScripts import Edit_DisabledNodeDuplication as test_module + + class test_LandscapeCanvas_Edit_UndoNodeDelete_PrefabEntity(EditorSharedTest): + from .EditorScripts import Edit_UndoNodeDelete_PrefabEntity as test_module + + class test_LandscapeCanvas_GradientMixer_NodeConstruction(EditorSharedTest): from .EditorScripts import GradientMixer_NodeConstruction as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) + + class test_LandscapeCanvas_GradientModifierNodes_EntityCreatedOnNodeAdd(EditorSharedTest): + from .EditorScripts import GradientModifierNodes_EntityCreatedOnNodeAdd as test_module + + class test_LandscapeCanvas_GradientModifierNodes_EntityRemovedOnNodeDelete(EditorSharedTest): + from .EditorScripts import GradientModifierNodes_EntityRemovedOnNodeDelete as test_module + + class test_LandscapeCanvas_GradientNodes_DependentComponentsAdded(EditorSharedTest): + from .EditorScripts import GradientNodes_DependentComponentsAdded as test_module + + class test_LandscapeCanvas_GradientNodes_EntityCreatedOnNodeAdd(EditorSharedTest): + from .EditorScripts import GradientNodes_EntityCreatedOnNodeAdd as test_module + + class test_LandscapeCanvas_GradientNodes_EntityRemovedOnNodeDelete(EditorSharedTest): + from .EditorScripts import GradientNodes_EntityRemovedOnNodeDelete as test_module + + @pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/2201") + class test_LandscapeCanvas_GraphClosed_OnEntityDelete(EditorSharedTest): + from .EditorScripts import GraphClosed_OnEntityDelete as test_module + + class test_LandscapeCanvas_GraphClosed_OnLevelChange(EditorSharedTest): + from .EditorScripts import GraphClosed_OnLevelChange as test_module + + class test_LandscapeCanvas_GraphClosed_TabbedGraphClosesIndependently(EditorSharedTest): + from .EditorScripts import GraphClosed_TabbedGraph as test_module + + @pytest.mark.skip(reason="https://github.com/o3de/o3de/issues/7141" "https://github.com/o3de/o3de/issues/4872") + class test_LandscapeCanvas_GraphUpdates_UpdateComponents(EditorSharedTest): + from .EditorScripts import GraphUpdates_UpdateComponents as test_module + + class test_LandscapeCanvas_LayerBlender_NodeConstruction(EditorSharedTest): + from .EditorScripts import LayerBlender_NodeConstruction as test_module + + class test_LandscapeCanvas_LayerExtenderNodes_ComponentEntitySync(EditorSharedTest): + from .EditorScripts import LayerExtenderNodes_ComponentEntitySync as test_module + + class test_LandscapeCanvas_NewGraph_CreatedSuccessfully(EditorSharedTest): + from .EditorScripts import NewGraph_CreatedSuccessfully as test_module + + class test_LandscapeCanvas_Prefab_CreateInstantiate(EditorSharedTest): + from .EditorScripts import Prefab_CreateInstantiate as test_module + + class test_LandscapeCanvas_ShapeNodes_EntityCreatedOnNodeAdd(EditorSharedTest): + from .EditorScripts import ShapeNodes_EntityCreatedOnNodeAdd as test_module + + class test_LandscapeCanvas_ShapeNodes_EntityRemovedOnNodeDelete(EditorSharedTest): + from .EditorScripts import ShapeNodes_EntityRemovedOnNodeDelete as test_module + + class test_LandscapeCanvas_SlotConnections_UpdateComponentReferences(EditorSharedTest): + from .EditorScripts import SlotConnections_UpdateComponentReferences as test_module diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Main_Optimized.py deleted file mode 100644 index 402df133cb..0000000000 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Main_Optimized.py +++ /dev/null @@ -1,100 +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 -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 TestAutomation(EditorTestSuite): - - enable_prefab_system = False - - class test_LandscapeCanvas_SlotConnections_UpdateComponentReferences(EditorSharedTest): - from .EditorScripts import SlotConnections_UpdateComponentReferences as test_module - - 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 - - class test_LandscapeCanvas_AreaNodes_EntityRemovedOnNodeDelete(EditorSharedTest): - from .EditorScripts import AreaNodes_EntityRemovedOnNodeDelete as test_module - - class test_LandscapeCanvas_LayerExtenderNodes_ComponentEntitySync(EditorSharedTest): - from .EditorScripts import LayerExtenderNodes_ComponentEntitySync as test_module - - class test_LandscapeCanvas_Edit_DisabledNodeDuplication(EditorSharedTest): - from .EditorScripts import Edit_DisabledNodeDuplication as test_module - - class test_LandscapeCanvas_Edit_UndoNodeDelete_SliceEntity(EditorSharedTest): - from .EditorScripts import Edit_UndoNodeDelete_SliceEntity as test_module - - class test_LandscapeCanvas_NewGraph_CreatedSuccessfully(EditorSharedTest): - from .EditorScripts import NewGraph_CreatedSuccessfully as test_module - - class test_LandscapeCanvas_Component_AddedRemoved(EditorSharedTest): - from .EditorScripts import Component_AddedRemoved as test_module - - class test_LandscapeCanvas_GraphClosed_OnLevelChange(EditorSharedTest): - from .EditorScripts import GraphClosed_OnLevelChange as test_module - - @pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/2201") - class test_LandscapeCanvas_GraphClosed_OnEntityDelete(EditorSharedTest): - from .EditorScripts import GraphClosed_OnEntityDelete as test_module - - class test_LandscapeCanvas_GraphClosed_TabbedGraphClosesIndependently(EditorSharedTest): - from .EditorScripts import GraphClosed_TabbedGraph as test_module - - class test_LandscapeCanvas_Slice_CreateInstantiate(EditorSingleTest): - from .EditorScripts import Slice_CreateInstantiate as test_module - # Custom teardown to remove slice asset created during test - def teardown(self, request, workspace, editor, editor_test_results, launcher_platform): - file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "slices", - "TestSlice.slice")], True, True) - - class test_LandscapeCanvas_GradientModifierNodes_EntityCreatedOnNodeAdd(EditorSharedTest): - from .EditorScripts import GradientModifierNodes_EntityCreatedOnNodeAdd as test_module - - class test_LandscapeCanvas_GradientModifierNodes_EntityRemovedOnNodeDelete(EditorSharedTest): - from .EditorScripts import GradientModifierNodes_EntityRemovedOnNodeDelete as test_module - - class test_LandscapeCanvas_GradientNodes_DependentComponentsAdded(EditorSharedTest): - from .EditorScripts import GradientNodes_DependentComponentsAdded as test_module - - class test_LandscapeCanvas_GradientNodes_EntityCreatedOnNodeAdd(EditorSharedTest): - from .EditorScripts import GradientNodes_EntityCreatedOnNodeAdd as test_module - - class test_LandscapeCanvas_GradientNodes_EntityRemovedOnNodeDelete(EditorSharedTest): - from .EditorScripts import GradientNodes_EntityRemovedOnNodeDelete as test_module - - @pytest.mark.skipif("debug" == os.path.basename(internal_plugin.build_directory), - reason="https://github.com/o3de/o3de/issues/4872") - class test_LandscapeCanvas_GraphUpdates_UpdateComponents(EditorSharedTest): - from .EditorScripts import GraphUpdates_UpdateComponents as test_module - - class test_LandscapeCanvas_ComponentUpdates_UpdateGraph(EditorSharedTest): - from .EditorScripts import ComponentUpdates_UpdateGraph as test_module - - class test_LandscapeCanvas_LayerBlender_NodeConstruction(EditorSharedTest): - from .EditorScripts import LayerBlender_NodeConstruction as test_module - - class test_LandscapeCanvas_ShapeNodes_EntityCreatedOnNodeAdd(EditorSharedTest): - from .EditorScripts import ShapeNodes_EntityCreatedOnNodeAdd as test_module - - class test_LandscapeCanvas_ShapeNodes_EntityRemovedOnNodeDelete(EditorSharedTest): - from .EditorScripts import ShapeNodes_EntityRemovedOnNodeDelete as test_module \ No newline at end of file diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Periodic.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Periodic.py deleted file mode 100644 index a719b1a7c0..0000000000 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Periodic.py +++ /dev/null @@ -1,121 +0,0 @@ -""" -Copyright (c) Contributors to the Open 3D Engine Project. -For complete copyright and license terms please see the LICENSE at the root of this distribution. - -SPDX-License-Identifier: Apache-2.0 OR MIT -""" - -import os -import pytest -import sys - -import ly_test_tools.environment.file_system as file_system - -sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../automatedtesting_shared') -from base import TestAutomationBase - - -@pytest.fixture -def remove_test_slice(request, workspace, project): - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice.slice")], True, True) - - def teardown(): - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice.slice")], True, - True) - - request.addfinalizer(teardown) - - -@pytest.mark.SUITE_periodic -@pytest.mark.parametrize("launcher_platform", ['windows_editor']) -@pytest.mark.parametrize("project", ["AutomatedTesting"]) -class TestAutomation(TestAutomationBase): - - def test_LandscapeCanvas_AreaNodes_DependentComponentsAdded(self, request, workspace, editor, launcher_platform): - from .EditorScripts import AreaNodes_DependentComponentsAdded as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_LandscapeCanvas_AreaNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform): - from .EditorScripts import AreaNodes_EntityCreatedOnNodeAdd as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_LandscapeCanvas_AreaNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform): - from .EditorScripts import AreaNodes_EntityRemovedOnNodeDelete as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_LandscapeCanvas_LayerExtenderNodes_ComponentEntitySync(self, request, workspace, editor, launcher_platform): - from .EditorScripts import LayerExtenderNodes_ComponentEntitySync as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_LandscapeCanvas_Edit_DisabledNodeDuplication(self, request, workspace, editor, launcher_platform): - from .EditorScripts import Edit_DisabledNodeDuplication as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_LandscapeCanvas_Edit_UndoNodeDelete_SliceEntity(self, request, workspace, editor, launcher_platform): - from .EditorScripts import Edit_UndoNodeDelete_SliceEntity as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_LandscapeCanvas_NewGraph_CreatedSuccessfully(self, request, workspace, editor, launcher_platform): - from .EditorScripts import NewGraph_CreatedSuccessfully as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_LandscapeCanvas_Component_AddedRemoved(self, request, workspace, editor, launcher_platform): - from .EditorScripts import Component_AddedRemoved as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_LandscapeCanvas_GraphClosed_OnLevelChange(self, request, workspace, editor, launcher_platform): - from .EditorScripts import GraphClosed_OnLevelChange 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/2201") - def test_LandscapeCanvas_GraphClosed_OnEntityDelete(self, request, workspace, editor, launcher_platform): - from .EditorScripts import GraphClosed_OnEntityDelete as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_LandscapeCanvas_GraphClosed_TabbedGraphClosesIndependently(self, request, workspace, editor, launcher_platform): - from .EditorScripts import GraphClosed_TabbedGraph as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_LandscapeCanvas_Slice_CreateInstantiate(self, request, workspace, editor, remove_test_slice, launcher_platform): - from .EditorScripts import Slice_CreateInstantiate as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_LandscapeCanvas_GradientModifierNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform): - from .EditorScripts import GradientModifierNodes_EntityCreatedOnNodeAdd as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_LandscapeCanvas_GradientModifierNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform): - from .EditorScripts import GradientModifierNodes_EntityRemovedOnNodeDelete as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_LandscapeCanvas_GradientNodes_DependentComponentsAdded(self, request, workspace, editor, launcher_platform): - from .EditorScripts import GradientNodes_DependentComponentsAdded as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_LandscapeCanvas_GradientNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform): - from .EditorScripts import GradientNodes_EntityCreatedOnNodeAdd as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_LandscapeCanvas_GradientNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform): - from .EditorScripts import GradientNodes_EntityRemovedOnNodeDelete as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_LandscapeCanvas_GraphUpdates_UpdateComponents(self, request, workspace, editor, launcher_platform): - from .EditorScripts import GraphUpdates_UpdateComponents as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_LandscapeCanvas_ComponentUpdates_UpdateGraph(self, request, workspace, editor, launcher_platform): - from .EditorScripts import ComponentUpdates_UpdateGraph as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_LandscapeCanvas_LayerBlender_NodeConstruction(self, request, workspace, editor, launcher_platform): - from .EditorScripts import LayerBlender_NodeConstruction as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_LandscapeCanvas_ShapeNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform): - from .EditorScripts import ShapeNodes_EntityCreatedOnNodeAdd as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) - - def test_LandscapeCanvas_ShapeNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform): - from .EditorScripts import ShapeNodes_EntityRemovedOnNodeDelete as test_module - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) 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/Levels/Multiplayer/SimpleNetworkLevelEntity/Player.prefab b/AutomatedTesting/Levels/Multiplayer/SimpleNetworkLevelEntity/Player.prefab new file mode 100644 index 0000000000..975319a516 --- /dev/null +++ b/AutomatedTesting/Levels/Multiplayer/SimpleNetworkLevelEntity/Player.prefab @@ -0,0 +1,151 @@ +{ + "ContainerEntity": { + "Id": "ContainerEntity", + "Name": "Player", + "Components": { + "Component_[10626669441604518614]": { + "$type": "EditorPrefabComponent", + "Id": 10626669441604518614 + }, + "Component_[15284109105474306026]": { + "$type": "EditorVisibilityComponent", + "Id": 15284109105474306026 + }, + "Component_[1884250773831675865]": { + "$type": "SelectionComponent", + "Id": 1884250773831675865 + }, + "Component_[3027124663594865592]": { + "$type": "EditorInspectorComponent", + "Id": 3027124663594865592 + }, + "Component_[3314300526416851038]": { + "$type": "EditorEntitySortComponent", + "Id": 3314300526416851038, + "Child Entity Order": [ + "Entity_[1340484004600]" + ] + }, + "Component_[5583377204116393478]": { + "$type": "EditorEntityIconComponent", + "Id": 5583377204116393478 + }, + "Component_[5897955848881060165]": { + "$type": "EditorLockComponent", + "Id": 5897955848881060165 + }, + "Component_[6405389103180201977]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 6405389103180201977, + "Parent Entity": "" + }, + "Component_[7695912346724202125]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 7695912346724202125 + }, + "Component_[775363990560391238]": { + "$type": "EditorOnlyEntityComponent", + "Id": 775363990560391238 + }, + "Component_[904355854135646057]": { + "$type": "EditorPendingCompositionComponent", + "Id": 904355854135646057 + } + } + }, + "Entities": { + "Entity_[1340484004600]": { + "Id": "Entity_[1340484004600]", + "Name": "Player", + "Components": { + "Component_[12294726333564087591]": { + "$type": "SelectionComponent", + "Id": 12294726333564087591 + }, + "Component_[13587084088242540786]": { + "$type": "EditorInspectorComponent", + "Id": 13587084088242540786, + "ComponentOrderEntryArray": [ + { + "ComponentId": 6819443882832501114 + }, + { + "ComponentId": 4337571454344109612, + "SortIndex": 1 + }, + { + "ComponentId": 16457408099527309065, + "SortIndex": 2 + }, + { + "ComponentId": 5577505593558922067, + "SortIndex": 3 + } + ] + }, + "Component_[14335168881008289852]": { + "$type": "EditorEntitySortComponent", + "Id": 14335168881008289852 + }, + "Component_[16308902899170829847]": { + "$type": "EditorVisibilityComponent", + "Id": 16308902899170829847 + }, + "Component_[16457408099527309065]": { + "$type": "GenericComponentWrapper", + "Id": 16457408099527309065, + "m_template": { + "$type": "Multiplayer::NetworkTransformComponent" + } + }, + "Component_[16541569566865026527]": { + "$type": "EditorOnlyEntityComponent", + "Id": 16541569566865026527 + }, + "Component_[2002761223483048905]": { + "$type": "EditorPendingCompositionComponent", + "Id": 2002761223483048905 + }, + "Component_[4337571454344109612]": { + "$type": "GenericComponentWrapper", + "Id": 4337571454344109612, + "m_template": { + "$type": "NetBindComponent" + } + }, + "Component_[477591477979440744]": { + "$type": "EditorLockComponent", + "Id": 477591477979440744 + }, + "Component_[5577505593558922067]": { + "$type": "AZ::Render::EditorMeshComponent", + "Id": 5577505593558922067, + "Controller": { + "Configuration": { + "ModelAsset": { + "assetId": { + "guid": "{6DE0E9A8-A1C7-5D0F-9407-4E627C1F223C}", + "subId": 284780167 + }, + "assetHint": "models/sphere.azmodel" + } + } + } + }, + "Component_[5828214869455694702]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 5828214869455694702 + }, + "Component_[6819443882832501114]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 6819443882832501114, + "Parent Entity": "ContainerEntity" + }, + "Component_[8838623765985560328]": { + "$type": "EditorEntityIconComponent", + "Id": 8838623765985560328 + } + } + } + } +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Multiplayer/SimpleNetworkLevelEntity/SimpleNetworkLevelEntity.prefab b/AutomatedTesting/Levels/Multiplayer/SimpleNetworkLevelEntity/SimpleNetworkLevelEntity.prefab new file mode 100644 index 0000000000..abe458246a --- /dev/null +++ b/AutomatedTesting/Levels/Multiplayer/SimpleNetworkLevelEntity/SimpleNetworkLevelEntity.prefab @@ -0,0 +1,580 @@ +{ + "ContainerEntity": { + "Id": "Entity_[1146574390643]", + "Name": "Level", + "Components": { + "Component_[10641544592923449938]": { + "$type": "EditorInspectorComponent", + "Id": 10641544592923449938 + }, + "Component_[12039882709170782873]": { + "$type": "EditorOnlyEntityComponent", + "Id": 12039882709170782873 + }, + "Component_[12265484671603697631]": { + "$type": "EditorPendingCompositionComponent", + "Id": 12265484671603697631 + }, + "Component_[14126657869720434043]": { + "$type": "EditorEntitySortComponent", + "Id": 14126657869720434043, + "Child Entity Order": [ + "Entity_[1176639161715]", + "Entity_[806656324666]" + ] + }, + "Component_[15230859088967841193]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 15230859088967841193, + "Parent Entity": "" + }, + "Component_[16239496886950819870]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 16239496886950819870 + }, + "Component_[5688118765544765547]": { + "$type": "EditorEntityIconComponent", + "Id": 5688118765544765547 + }, + "Component_[6545738857812235305]": { + "$type": "SelectionComponent", + "Id": 6545738857812235305 + }, + "Component_[7247035804068349658]": { + "$type": "EditorPrefabComponent", + "Id": 7247035804068349658 + }, + "Component_[9307224322037797205]": { + "$type": "EditorLockComponent", + "Id": 9307224322037797205 + }, + "Component_[9562516168917670048]": { + "$type": "EditorVisibilityComponent", + "Id": 9562516168917670048 + } + } + }, + "Entities": { + "Entity_[1155164325235]": { + "Id": "Entity_[1155164325235]", + "Name": "Sun", + "Components": { + "Component_[10440557478882592717]": { + "$type": "SelectionComponent", + "Id": 10440557478882592717 + }, + "Component_[13620450453324765907]": { + "$type": "EditorLockComponent", + "Id": 13620450453324765907 + }, + "Component_[2134313378593666258]": { + "$type": "EditorInspectorComponent", + "Id": 2134313378593666258 + }, + "Component_[234010807770404186]": { + "$type": "EditorVisibilityComponent", + "Id": 234010807770404186 + }, + "Component_[2970359110423865725]": { + "$type": "EditorEntityIconComponent", + "Id": 2970359110423865725 + }, + "Component_[3722854130373041803]": { + "$type": "EditorOnlyEntityComponent", + "Id": 3722854130373041803 + }, + "Component_[5992533738676323195]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 5992533738676323195 + }, + "Component_[7378860763541895402]": { + "$type": "AZ::Render::EditorDirectionalLightComponent", + "Id": 7378860763541895402, + "Controller": { + "Configuration": { + "Intensity": 1.0, + "CameraEntityId": "", + "ShadowFilterMethod": 1 + } + } + }, + "Component_[7892834440890947578]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 7892834440890947578, + "Parent Entity": "Entity_[1176639161715]", + "Transform Data": { + "Translate": [ + 0.0, + 0.0, + 13.487043380737305 + ], + "Rotate": [ + -76.13099670410156, + -0.847000002861023, + -15.8100004196167 + ] + } + }, + "Component_[8599729549570828259]": { + "$type": "EditorEntitySortComponent", + "Id": 8599729549570828259 + }, + "Component_[952797371922080273]": { + "$type": "EditorPendingCompositionComponent", + "Id": 952797371922080273 + } + } + }, + "Entity_[1159459292531]": { + "Id": "Entity_[1159459292531]", + "Name": "Ground", + "Components": { + "Component_[11701138785793981042]": { + "$type": "SelectionComponent", + "Id": 11701138785793981042 + }, + "Component_[12260880513256986252]": { + "$type": "EditorEntityIconComponent", + "Id": 12260880513256986252 + }, + "Component_[13711420870643673468]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 13711420870643673468 + }, + "Component_[138002849734991713]": { + "$type": "EditorOnlyEntityComponent", + "Id": 138002849734991713 + }, + "Component_[16578565737331764849]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 16578565737331764849, + "Parent Entity": "Entity_[1176639161715]" + }, + "Component_[16919232076966545697]": { + "$type": "EditorInspectorComponent", + "Id": 16919232076966545697 + }, + "Component_[5182430712893438093]": { + "$type": "EditorMaterialComponent", + "Id": 5182430712893438093 + }, + "Component_[5675108321710651991]": { + "$type": "AZ::Render::EditorMeshComponent", + "Id": 5675108321710651991, + "Controller": { + "Configuration": { + "ModelAsset": { + "assetId": { + "guid": "{0CD745C0-6AA8-569A-A68A-73A3270986C4}", + "subId": 277889906 + }, + "assetHint": "objects/groudplane/groundplane_512x512m.azmodel" + } + } + } + }, + "Component_[5681893399601237518]": { + "$type": "EditorEntitySortComponent", + "Id": 5681893399601237518 + }, + "Component_[592692962543397545]": { + "$type": "EditorPendingCompositionComponent", + "Id": 592692962543397545 + }, + "Component_[7090012899106946164]": { + "$type": "EditorLockComponent", + "Id": 7090012899106946164 + }, + "Component_[9410832619875640998]": { + "$type": "EditorVisibilityComponent", + "Id": 9410832619875640998 + } + } + }, + "Entity_[1163754259827]": { + "Id": "Entity_[1163754259827]", + "Name": "Camera", + "Components": { + "Component_[11895140916889160460]": { + "$type": "EditorEntityIconComponent", + "Id": 11895140916889160460 + }, + "Component_[16880285896855930892]": { + "$type": "{CA11DA46-29FF-4083-B5F6-E02C3A8C3A3D} EditorCameraComponent", + "Id": 16880285896855930892, + "Controller": { + "Configuration": { + "Field of View": 55.0, + "EditorEntityId": 9021008456353177945 + } + } + }, + "Component_[17187464423780271193]": { + "$type": "EditorLockComponent", + "Id": 17187464423780271193 + }, + "Component_[17495696818315413311]": { + "$type": "EditorEntitySortComponent", + "Id": 17495696818315413311 + }, + "Component_[18086214374043522055]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 18086214374043522055, + "Parent Entity": "Entity_[1176639161715]", + "Transform Data": { + "Translate": [ + -2.3000001907348633, + -3.9368600845336914, + 1.0 + ], + "Rotate": [ + -2.050307512283325, + 1.9552897214889526, + -43.623355865478516 + ] + } + }, + "Component_[18387556550380114975]": { + "$type": "SelectionComponent", + "Id": 18387556550380114975 + }, + "Component_[2654521436129313160]": { + "$type": "EditorVisibilityComponent", + "Id": 2654521436129313160 + }, + "Component_[5265045084611556958]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 5265045084611556958 + }, + "Component_[7169798125182238623]": { + "$type": "EditorPendingCompositionComponent", + "Id": 7169798125182238623 + }, + "Component_[7255796294953281766]": { + "$type": "GenericComponentWrapper", + "Id": 7255796294953281766, + "m_template": { + "$type": "FlyCameraInputComponent" + } + }, + "Component_[8866210352157164042]": { + "$type": "EditorInspectorComponent", + "Id": 8866210352157164042 + }, + "Component_[9129253381063760879]": { + "$type": "EditorOnlyEntityComponent", + "Id": 9129253381063760879 + } + } + }, + "Entity_[1168049227123]": { + "Id": "Entity_[1168049227123]", + "Name": "Grid", + "Components": { + "Component_[11443347433215807130]": { + "$type": "EditorEntityIconComponent", + "Id": 11443347433215807130 + }, + "Component_[11779275529534764488]": { + "$type": "SelectionComponent", + "Id": 11779275529534764488 + }, + "Component_[14249419413039427459]": { + "$type": "EditorInspectorComponent", + "Id": 14249419413039427459 + }, + "Component_[15448581635946161318]": { + "$type": "AZ::Render::EditorGridComponent", + "Id": 15448581635946161318, + "Controller": { + "Configuration": { + "primarySpacing": 4.0, + "primaryColor": [ + 0.501960813999176, + 0.501960813999176, + 0.501960813999176 + ], + "secondarySpacing": 0.5, + "secondaryColor": [ + 0.250980406999588, + 0.250980406999588, + 0.250980406999588 + ] + } + } + }, + "Component_[1843303322527297409]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 1843303322527297409 + }, + "Component_[380249072065273654]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 380249072065273654, + "Parent Entity": "Entity_[1176639161715]" + }, + "Component_[7476660583684339787]": { + "$type": "EditorPendingCompositionComponent", + "Id": 7476660583684339787 + }, + "Component_[7557626501215118375]": { + "$type": "EditorEntitySortComponent", + "Id": 7557626501215118375 + }, + "Component_[7984048488947365511]": { + "$type": "EditorVisibilityComponent", + "Id": 7984048488947365511 + }, + "Component_[8118181039276487398]": { + "$type": "EditorOnlyEntityComponent", + "Id": 8118181039276487398 + }, + "Component_[9189909764215270515]": { + "$type": "EditorLockComponent", + "Id": 9189909764215270515 + } + } + }, + "Entity_[1176639161715]": { + "Id": "Entity_[1176639161715]", + "Name": "Atom Default Environment", + "Components": { + "Component_[10757302973393310045]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 10757302973393310045, + "Parent Entity": "Entity_[1146574390643]" + }, + "Component_[14505817420424255464]": { + "$type": "EditorInspectorComponent", + "Id": 14505817420424255464, + "ComponentOrderEntryArray": [ + { + "ComponentId": 10757302973393310045 + } + ] + }, + "Component_[14988041764659020032]": { + "$type": "EditorLockComponent", + "Id": 14988041764659020032 + }, + "Component_[15808690248755038124]": { + "$type": "SelectionComponent", + "Id": 15808690248755038124 + }, + "Component_[15900837685796817138]": { + "$type": "EditorVisibilityComponent", + "Id": 15900837685796817138 + }, + "Component_[3298767348226484884]": { + "$type": "EditorOnlyEntityComponent", + "Id": 3298767348226484884 + }, + "Component_[4076975109609220594]": { + "$type": "EditorPendingCompositionComponent", + "Id": 4076975109609220594 + }, + "Component_[5679760548946028854]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 5679760548946028854 + }, + "Component_[5855590796136709437]": { + "$type": "EditorEntitySortComponent", + "Id": 5855590796136709437, + "Child Entity Order": [ + "Entity_[1155164325235]", + "Entity_[1180934129011]", + "Entity_[1168049227123]", + "Entity_[1163754259827]", + "Entity_[1159459292531]" + ] + }, + "Component_[9277695270015777859]": { + "$type": "EditorEntityIconComponent", + "Id": 9277695270015777859 + } + } + }, + "Entity_[1180934129011]": { + "Id": "Entity_[1180934129011]", + "Name": "Global Sky", + "Components": { + "Component_[11231930600558681245]": { + "$type": "AZ::Render::EditorHDRiSkyboxComponent", + "Id": 11231930600558681245, + "Controller": { + "Configuration": { + "CubemapAsset": { + "assetId": { + "guid": "{215E47FD-D181-5832-B1AB-91673ABF6399}", + "subId": 1000 + }, + "assetHint": "lightingpresets/highcontrast/goegap_4k_skyboxcm.exr.streamingimage" + } + } + } + }, + "Component_[11980494120202836095]": { + "$type": "SelectionComponent", + "Id": 11980494120202836095 + }, + "Component_[1428633914413949476]": { + "$type": "EditorLockComponent", + "Id": 1428633914413949476 + }, + "Component_[14936200426671614999]": { + "$type": "AZ::Render::EditorImageBasedLightComponent", + "Id": 14936200426671614999, + "Controller": { + "Configuration": { + "diffuseImageAsset": { + "assetId": { + "guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}", + "subId": 3000 + }, + "assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_ibldiffuse.exr.streamingimage" + }, + "specularImageAsset": { + "assetId": { + "guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}", + "subId": 2000 + }, + "assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_iblspecular.exr.streamingimage" + } + } + } + }, + "Component_[14994774102579326069]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 14994774102579326069 + }, + "Component_[15417479889044493340]": { + "$type": "EditorPendingCompositionComponent", + "Id": 15417479889044493340 + }, + "Component_[15826613364991382688]": { + "$type": "EditorEntitySortComponent", + "Id": 15826613364991382688 + }, + "Component_[1665003113283562343]": { + "$type": "EditorOnlyEntityComponent", + "Id": 1665003113283562343 + }, + "Component_[3704934735944502280]": { + "$type": "EditorEntityIconComponent", + "Id": 3704934735944502280 + }, + "Component_[5698542331457326479]": { + "$type": "EditorVisibilityComponent", + "Id": 5698542331457326479 + }, + "Component_[6644513399057217122]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 6644513399057217122, + "Parent Entity": "Entity_[1176639161715]" + }, + "Component_[931091830724002070]": { + "$type": "EditorInspectorComponent", + "Id": 931091830724002070 + } + } + }, + "Entity_[806656324666]": { + "Id": "Entity_[806656324666]", + "Name": "NetEntity", + "Components": { + "Component_[10272449525230713408]": { + "$type": "EditorScriptCanvasComponent", + "Id": 10272449525230713408, + "m_name": "SimpleNetworkLevelEntity.scriptcanvas", + "runtimeDataIsValid": true, + "runtimeDataOverrides": { + "source": { + "id": "{C8F17F94-1225-5FFB-A89F-7C5546FF9DD2}", + "path": "C:/prj/o3de/AutomatedTesting/Levels/Multiplayer/SimpleNetworkLevelEntity/SimpleNetworkLevelEntity.scriptcanvas" + } + }, + "sourceHandle": { + "id": "{C8F17F94-1225-5FFB-A89F-7C5546FF9DD2}", + "path": "C:/prj/o3de/AutomatedTesting/Levels/Multiplayer/SimpleNetworkLevelEntity/SimpleNetworkLevelEntity.scriptcanvas" + } + }, + "Component_[12604265186664827718]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 12604265186664827718 + }, + "Component_[12971088454284742740]": { + "$type": "EditorInspectorComponent", + "Id": 12971088454284742740 + }, + "Component_[13637345797899267673]": { + "$type": "EditorPendingCompositionComponent", + "Id": 13637345797899267673 + }, + "Component_[14691827217729577086]": { + "$type": "EditorVisibilityComponent", + "Id": 14691827217729577086 + }, + "Component_[17587769654029626028]": { + "$type": "AZ::Render::EditorMeshComponent", + "Id": 17587769654029626028, + "Controller": { + "Configuration": { + "ModelAsset": { + "assetId": { + "guid": "{6DE0E9A8-A1C7-5D0F-9407-4E627C1F223C}", + "subId": 284780167 + }, + "assetHint": "models/sphere.azmodel" + } + } + } + }, + "Component_[3583806849894952953]": { + "$type": "EditorOnlyEntityComponent", + "Id": 3583806849894952953 + }, + "Component_[3992057042487734240]": { + "$type": "EditorLockComponent", + "Id": 3992057042487734240 + }, + "Component_[4205899043279271481]": { + "$type": "GenericComponentWrapper", + "Id": 4205899043279271481, + "m_template": { + "$type": "Multiplayer::NetworkTransformComponent" + } + }, + "Component_[4416976521140638764]": { + "$type": "EditorEntityIconComponent", + "Id": 4416976521140638764 + }, + "Component_[4951162661196722987]": { + "$type": "EditorEntitySortComponent", + "Id": 4951162661196722987 + }, + "Component_[57491843687005111]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 57491843687005111, + "Parent Entity": "Entity_[1146574390643]", + "Transform Data": { + "Translate": [ + -0.010266244411468506, + 0.09999752044677734, + 0.4922151565551758 + ] + } + }, + "Component_[7427201282284088219]": { + "$type": "SelectionComponent", + "Id": 7427201282284088219 + }, + "Component_[9767802049284917261]": { + "$type": "GenericComponentWrapper", + "Id": 9767802049284917261, + "m_template": { + "$type": "NetBindComponent" + } + } + } + } + } +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Multiplayer/SimpleNetworkLevelEntity/SimpleNetworkLevelEntity.scriptcanvas b/AutomatedTesting/Levels/Multiplayer/SimpleNetworkLevelEntity/SimpleNetworkLevelEntity.scriptcanvas new file mode 100644 index 0000000000..7f41ed9af2 --- /dev/null +++ b/AutomatedTesting/Levels/Multiplayer/SimpleNetworkLevelEntity/SimpleNetworkLevelEntity.scriptcanvas @@ -0,0 +1,228 @@ +{ + "Type": "JsonSerialization", + "Version": 1, + "ClassName": "ScriptCanvasData", + "ClassData": { + "m_scriptCanvas": { + "Id": { + "id": 5227099818161821361 + }, + "Name": "Script Canvas Graph", + "Components": { + "Component_[14745706451564425001]": { + "$type": "EditorGraphVariableManagerComponent", + "Id": 14745706451564425001 + }, + "Component_[6188351434280490877]": { + "$type": "EditorGraph", + "Id": 6188351434280490877, + "m_graphData": { + "m_nodes": [ + { + "Id": { + "id": 1181151842701 + }, + "Name": "SC-Node(Print)", + "Components": { + "Component_[11204048151736284490]": { + "$type": "Print", + "Id": 11204048151736284490, + "Slots": [ + { + "id": { + "m_id": "{A417FF98-493E-4DE6-AD3A-E7A1848661E4}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "toolTip": "Input signal", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{38BC2AB1-7654-407E-9903-4B5D77EDB6F3}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + } + ], + "m_format": "SimpleNetworkLevelEntity: On Graph Start\n", + "m_unresolvedString": [ + "SimpleNetworkLevelEntity: On Graph Start\n" + ] + } + } + }, + { + "Id": { + "id": 811784655245 + }, + "Name": "SC-Node(Start)", + "Components": { + "Component_[2986280341871382503]": { + "$type": "Start", + "Id": 2986280341871382503, + "Slots": [ + { + "id": { + "m_id": "{61FBEFC6-23BA-4A53-89BF-D0D0E834608C}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "toolTip": "Signaled when the entity that owns this graph is fully activated.", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + } + ] + } + } + } + ], + "m_connections": [ + { + "Id": { + "id": 2521181639053 + }, + "Name": "srcEndpoint=(On Graph Start: Out), destEndpoint=(Print: In)", + "Components": { + "Component_[16295428600276205051]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 16295428600276205051, + "sourceEndpoint": { + "nodeId": { + "id": 811784655245 + }, + "slotId": { + "m_id": "{61FBEFC6-23BA-4A53-89BF-D0D0E834608C}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 1181151842701 + }, + "slotId": { + "m_id": "{A417FF98-493E-4DE6-AD3A-E7A1848661E4}" + } + } + } + } + } + ] + }, + "m_assetType": "{00000000-0000-0000-D033-B2489A010000}", + "versionData": { + "_grammarVersion": 1, + "_runtimeVersion": 1, + "_fileVersion": 1 + }, + "GraphCanvasData": [ + { + "Key": { + "id": 811784655245 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "TimeNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 340.0, + 180.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{6045F7F7-02B0-442A-96C7-A0CBCEFF7275}" + } + } + } + }, + { + "Key": { + "id": 1181151842701 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "StringNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 580.0, + 180.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{589F773E-D82A-4EDD-AEBD-3ADC07FC67CE}" + } + } + } + }, + { + "Key": { + "id": 5227099818161821361 + }, + "Value": { + "ComponentData": { + "{5F84B500-8C45-40D1-8EFC-A5306B241444}": { + "$type": "SceneComponentSaveData" + } + } + } + } + ], + "StatisticsHelper": { + "InstanceCounter": [ + { + "Key": 4199610336680704683, + "Value": 1 + }, + { + "Key": 10684225535275896474, + "Value": 1 + } + ] + } + } + } + } + } +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Multiplayer/SimpleNetworkLevelEntity/tags.txt b/AutomatedTesting/Levels/Multiplayer/SimpleNetworkLevelEntity/tags.txt new file mode 100644 index 0000000000..0d6c1880e7 --- /dev/null +++ b/AutomatedTesting/Levels/Multiplayer/SimpleNetworkLevelEntity/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/AutomatedTesting/project.json b/AutomatedTesting/project.json index 5a4b303570..a928547f20 100644 --- a/AutomatedTesting/project.json +++ b/AutomatedTesting/project.json @@ -16,4 +16,4 @@ "external_subdirectories": [ "Gem" ] -} \ No newline at end of file +} diff --git a/CMakeLists.txt b/CMakeLists.txt index c81581fe0f..3f9f56a606 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,60 +44,26 @@ include(cmake/SettingsRegistry.cmake) include(cmake/TestImpactFramework/LYTestImpactFramework.cmake) include(cmake/CMakeFiles.cmake) include(cmake/O3DEJson.cmake) +include(cmake/Subdirectories.cmake) -################################################################################ -# Subdirectory processing -################################################################################ - -# this function is building up the LY_EXTERNAL_SUBDIRS global property -function(add_engine_gem_json_external_subdirectories gem_path) - set(gem_json_path ${gem_path}/gem.json) - if(EXISTS ${gem_json_path}) - read_json_external_subdirs(gem_external_subdirs ${gem_path}/gem.json) - foreach(gem_external_subdir ${gem_external_subdirs}) - file(REAL_PATH ${gem_external_subdir} real_external_subdir BASE_DIRECTORY ${gem_path}) - set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS ${real_external_subdir}) - add_engine_gem_json_external_subdirectories(${real_external_subdir}) - endforeach() - endif() -endfunction() - -function(add_engine_json_external_subdirectories) - read_json_external_subdirs(engine_external_subdirs ${LY_ROOT_FOLDER}/engine.json) - foreach(engine_external_subdir ${engine_external_subdirs}) - file(REAL_PATH ${engine_external_subdir} real_external_subdir BASE_DIRECTORY ${LY_ROOT_FOLDER}) - set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS ${real_external_subdir}) - add_engine_gem_json_external_subdirectories(${real_external_subdir}) - endforeach() -endfunction() - -function(add_subdirectory_on_externalsubdirs) - get_property(external_subdirs GLOBAL PROPERTY LY_EXTERNAL_SUBDIRS) - list(APPEND LY_EXTERNAL_SUBDIRS ${external_subdirs}) - # Loop over the additional external subdirectories and invoke add_subdirectory on them - foreach(external_directory ${LY_EXTERNAL_SUBDIRS}) - # Hash the external_directory name and append it to the Binary Directory section of add_subdirectory - # This is to deal with potential situations where multiple external directories has the same last directory name - # For example if D:/Company1/RayTracingGem and F:/Company2/Path/RayTracingGem were both added as a subdirectory - file(REAL_PATH ${external_directory} full_directory_path) - string(SHA256 full_directory_hash ${full_directory_path}) - # Truncate the full_directory_hash down to 8 characters to avoid hitting the Windows 260 character path limit - # when the external subdirectory contains relative paths of significant length - string(SUBSTRING ${full_directory_hash} 0 8 full_directory_hash) - # Use the last directory as the suffix path to use for the Binary Directory - get_filename_component(directory_name ${external_directory} NAME) - add_subdirectory(${external_directory} ${CMAKE_BINARY_DIR}/External/${directory_name}-${full_directory_hash}) - endforeach() -endfunction() +# Gather the list of o3de_manifest external Subdirectories +# into the LY_EXTERNAL_SUBDIRS_O3DE_MANIFEST_PROPERTY +add_o3de_manifest_json_external_subdirectories() # 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. + # external subdirectories. This should go before adding the rest of the targets so the targets are available to the launcher. add_engine_json_external_subdirectories() - add_subdirectory_on_externalsubdirs() + + # Invoke add_subdirectory on external subdirectories that should be used a this point + add_subdirectory_on_external_subdirs() # Add the rest of the targets add_subdirectory(Assets) @@ -110,7 +76,7 @@ if(NOT INSTALLED_ENGINE) else() ly_find_o3de_packages() - add_subdirectory_on_externalsubdirs() + add_subdirectory_on_external_subdirs() endif() ################################################################################ diff --git a/Code/Editor/AzAssetBrowser/AssetBrowserWindow.cpp b/Code/Editor/AzAssetBrowser/AssetBrowserWindow.cpp deleted file mode 100644 index 1a45d1e391..0000000000 --- a/Code/Editor/AzAssetBrowser/AssetBrowserWindow.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ -#include "AzAssetBrowserWindow.h" -#include "AzAssetBrowser/ui_AssetBrowserWindow.h" - -#include -#include -#include -#include -#include - -const char* ASSET_BROWSER_PREVIEW_NAME = "Asset Browser (PREVIEW)"; - -AzAssetBrowserWindow::AzAssetBrowserWindow(const QString& name, QWidget* parent) - : QDialog(parent) - , m_ui(new Ui::AssetBrowserWindowClass()) - , m_assetDatabaseSortFilterProxyModel(new AssetBrowser::UI::SortFilterProxyModel(parent)) - , m_name(name) - , m_assetBrowser(new AssetBrowser::UI::AssetTreeView(name, this)) - { - EBUS_EVENT_RESULT(m_assetBrowserModel, AssetBrowser::AssetCache::AssetCacheRequestsBus, GetAssetBrowserModel); - AZ_Assert(m_assetBrowserModel, "Failed to get filebrowser model"); - m_assetDatabaseSortFilterProxyModel->setSourceModel(m_assetBrowserModel); - - m_ui->setupUi(this); - - connect(m_ui->searchCriteriaWidget, - &AzToolsFramework::SearchCriteriaWidget::SearchCriteriaChanged, - m_assetDatabaseSortFilterProxyModel.data(), - &AssetBrowser::UI::SortFilterProxyModel::OnSearchCriteriaChanged); - - connect(m_assetBrowser, &QTreeView::customContextMenuRequested, this, &AzAssetBrowserWindow::OnContextMenu); - } - - AzAssetBrowserWindow::~AzAssetBrowserWindow() - { - m_assetBrowser->SaveState(); - } - - ////////////////////////////////////////////////////////////////////////// - const AZ::Uuid& AzAssetBrowserWindow::GetClassID() - { - return AZ::AzTypeInfo::Uuid(); - } - - void AzAssetBrowserWindow::OnContextMenu(const QPoint& point) - { - (void)point; - //get the selected entries - QModelIndexList sourceIndexes; - for (const auto& index : m_assetBrowser->selectedIndexes()) - { - sourceIndexes.push_back(m_assetDatabaseSortFilterProxyModel->mapToSource(index)); - } - AZStd::vector entries; - m_assetBrowserModel->SourceIndexesToAssetDatabaseEntries(sourceIndexes, entries); - - if (entries.empty() || entries.size() > 1) - { - return; - } - auto entry = entries.front(); - - EBUS_EVENT(AssetBrowser::AssetBrowserRequestBus::Bus, OnItemContextMenu, this, entry); - } - -#include - diff --git a/Code/Editor/AzAssetBrowser/AssetBrowserWindow.h b/Code/Editor/AzAssetBrowser/AssetBrowserWindow.h deleted file mode 100644 index a16cc4b494..0000000000 --- a/Code/Editor/AzAssetBrowser/AssetBrowserWindow.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include - -#include -#endif - -namespace Ui -{ - class AssetBrowserWindowClass; -} - -namespace AssetBrowser -{ - namespace UI - { - class AssetTreeView; - class SortFilterProxyModel; - class AssetBrowserModel; - } -} - -class AzAssetBrowserWindow - : public QDialog -{ - Q_OBJECT -public: - AZ_CLASS_ALLOCATOR(AzAssetBrowserWindow, AZ::SystemAllocator, 0); - AZ_TYPE_INFO(AzAssetBrowserWindow, "{20238D23-2670-44BC-9110-A51374C18B5A}"); - - explicit AzAssetBrowserWindow(const QString& name = "default", QWidget* parent = nullptr); - virtual ~AzAssetBrowserWindow(); - - static const AZ::Uuid& GetClassID(); - -protected Q_SLOTS: - void OnContextMenu(const QPoint& point); - -private: - QScopedPointer m_ui; - QScopedPointer m_assetDatabaseModel; - QScopedPointer m_assetDatabaseSortFilterProxyModel; - QString m_name; - AssetBrowser::UI::AssetTreeView* m_assetBrowser; - AssetBrowser::UI::AssetBrowserModel* m_assetBrowserModel; -}; - -extern const char* ASSET_BROWSER_PREVIEW_NAME; 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/CVarMenu.cpp b/Code/Editor/CVarMenu.cpp deleted file mode 100644 index 6449be9b3c..0000000000 --- a/Code/Editor/CVarMenu.cpp +++ /dev/null @@ -1,186 +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 "CVarMenu.h" - -CVarMenu::CVarMenu(QWidget* parent) - : QMenu(parent) -{ -} - -void CVarMenu::AddCVarToggleItem(CVarToggle cVarToggle) -{ - // Add CVar toggle action - QAction* action = addAction(cVarToggle.m_displayName); - connect(action, &QAction::triggered, [this, cVarToggle](bool checked) - { - // Update the CVar's value based on the action's new checked state - ICVar* cVar = gEnv->pConsole->GetCVar(cVarToggle.m_cVarName.toUtf8().data()); - if (cVar) - { - SetCVar(cVar, checked ? cVarToggle.m_onValue : cVarToggle.m_offValue); - } - }); - action->setCheckable(true); - - // Initialize the action's checked state based on the associated CVar's value - ICVar* cVar = gEnv->pConsole->GetCVar(cVarToggle.m_cVarName.toUtf8().data()); - bool checked = (cVar && cVar->GetFVal() == cVarToggle.m_onValue); - action->setChecked(checked); -} - -void CVarMenu::AddCVarValuesItem(QString cVarName, - QString displayName, - CVarDisplayNameValuePairs availableCVarValues, - float offValue) -{ - // Add a submenu offering multiple values for one CVar - QMenu* menu = addMenu(displayName); - QActionGroup* group = new QActionGroup(menu); - group->setExclusive(true); - - ICVar* cVar = gEnv->pConsole->GetCVar(cVarName.toUtf8().data()); - float cVarValue = cVar ? cVar->GetFVal() : 0.0f; - for (const auto& availableCVarValue : availableCVarValues) - { - QAction* action = menu->addAction(availableCVarValue.first); - action->setCheckable(true); - group->addAction(action); - - float availableOnValue = availableCVarValue.second; - connect(action, &QAction::triggered, [this, action, cVarName, availableOnValue, offValue](bool checked) - { - ICVar* cVar = gEnv->pConsole->GetCVar(cVarName.toUtf8().data()); - if (cVar) - { - if (!checked) - { - SetCVar(cVar, offValue); - } - else - { - // Toggle the CVar and update the action's checked state to - // allow none of the items to be checked in the exclusive group. - // Otherwise we could have just used the action's currently checked - // state and updated the CVar's value only - bool cVarOn = (cVar->GetFVal() == availableOnValue); - checked = !cVarOn; - SetCVar(cVar, checked ? availableOnValue : offValue); - action->setChecked(checked); - } - } - }); - - // Initialize the action's checked state based on the CVar's current value - bool checked = (cVarValue == availableOnValue); - action->setChecked(checked); - } -} - -void CVarMenu::AddUniqueCVarsItem(QString displayName, - AZStd::vector availableCVars) -{ - // Add a submenu of actions offering values for unique CVars - QMenu* menu = addMenu(displayName); - QActionGroup* group = new QActionGroup(menu); - group->setExclusive(true); - - for (const CVarToggle& availableCVar : availableCVars) - { - QAction* action = menu->addAction(availableCVar.m_displayName); - action->setCheckable(true); - group->addAction(action); - - connect(action, &QAction::triggered, [this, action, availableCVar, availableCVars](bool checked) - { - ICVar* cVar = gEnv->pConsole->GetCVar(availableCVar.m_cVarName.toUtf8().data()); - if (cVar) - { - if (!checked) - { - SetCVar(cVar, availableCVar.m_offValue); - } - else - { - // Toggle the CVar and update the action's checked state to - // allow none of the items to be checked in the exclusive group. - // Otherwise we could have just used the action's currently checked - // state and updated the CVar's value only - bool cVarOn = (cVar->GetFVal() == availableCVar.m_onValue); - bool cVarChecked = !cVarOn; - SetCVar(cVar, cVarChecked ? availableCVar.m_onValue : availableCVar.m_offValue); - action->setChecked(cVarChecked); - if (cVarChecked) - { - // Set the rest of the CVars in the group to their off values - SetCVarsToOffValue(availableCVars, availableCVar); - } - } - } - }); - - // Initialize the action's checked state based on its associated CVar's current value - ICVar* cVar = gEnv->pConsole->GetCVar(availableCVar.m_cVarName.toUtf8().data()); - bool cVarChecked = (cVar && cVar->GetFVal() == availableCVar.m_onValue); - action->setChecked(cVarChecked); - if (cVarChecked) - { - // Set the rest of the CVars in the group to their off values - SetCVarsToOffValue(availableCVars, availableCVar); - } - } -} - -void CVarMenu::AddResetCVarsItem() -{ - QAction* action = addAction(tr("Reset to Default")); - connect(action, &QAction::triggered, this, [this]() - { - for (auto it : m_originalCVarValues) - { - ICVar* cVar = gEnv->pConsole->GetCVar(it.first.c_str()); - if (cVar) - { - cVar->Set(it.second); - } - } - }); -} - -void CVarMenu::SetCVarsToOffValue(const AZStd::vector& cVarToggles, const CVarToggle& excludeCVarToggle) -{ - // Set all but the specified CVars to their off values - for (const CVarToggle& cVarToggle : cVarToggles) - { - if (cVarToggle.m_cVarName != excludeCVarToggle.m_cVarName - || cVarToggle.m_onValue != excludeCVarToggle.m_onValue) - { - ICVar* cVar = gEnv->pConsole->GetCVar(cVarToggle.m_cVarName.toUtf8().data()); - if (cVar) - { - SetCVar(cVar, cVarToggle.m_offValue); - } - } - } -} - -void CVarMenu::SetCVar(ICVar* cVar, float newValue) -{ - float oldValue = cVar->GetFVal(); - cVar->Set(newValue); - - // Store original value for CVar if not already in the list - m_originalCVarValues.emplace(AZStd::string(cVar->GetName()), oldValue); -} - -void CVarMenu::AddSeparator() -{ - addSeparator(); -} diff --git a/Code/Editor/CVarMenu.h b/Code/Editor/CVarMenu.h deleted file mode 100644 index 5195bd99d7..0000000000 --- a/Code/Editor/CVarMenu.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include -#include - -#include -#include -#include -#include - -struct ICVar; - -class CVarMenu - : public QMenu -{ - Q_OBJECT -public: - // CVar that can be toggled on and off - struct CVarToggle - { - QString m_cVarName; - QString m_displayName; - float m_onValue; - float m_offValue; - }; - - // List of a CVar's available values and their descriptions - using CVarDisplayNameValuePairs = AZStd::vector>; - - CVarMenu(QWidget* parent = nullptr); - - // Add an action that turns a CVar on/off - void AddCVarToggleItem(CVarToggle cVarToggle); - - // Add a submenu of actions for a CVar that offers multiple values for exclusive selection - void AddCVarValuesItem(QString cVarName, - QString displayName, - CVarDisplayNameValuePairs availableCVarValues, - float offValue); - - // Add a submenu of actions for exclusively turning unique CVars on/off - void AddUniqueCVarsItem(QString displayName, - AZStd::vector availableCVars); - - // Add an action to reset all CVars to their original values before they - // were modified by this menu - void AddResetCVarsItem(); - - void AddSeparator(); - -private: - void SetCVarsToOffValue(const AZStd::vector& cVarToggles, const CVarToggle& excludeCVarToggle); - void SetCVar(ICVar* cVar, float newValue); - - // Original CVar values before they were modified by this menu - AZStd::unordered_map m_originalCVarValues; -}; diff --git a/Code/Editor/Commands/CommandManagerBus.h b/Code/Editor/Commands/CommandManagerBus.h deleted file mode 100644 index a5edceaee8..0000000000 --- a/Code/Editor/Commands/CommandManagerBus.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include - -class CommandManagerRequests : public AZ::EBusTraits -{ -public: - - struct CommandDetails - { - AZStd::string m_name; - AZStd::vector m_arguments; - }; - - virtual AZStd::vector GetCommands() const = 0; - virtual void ExecuteCommand(const AZStd::string& commandLine) {} - - virtual void GetCommandDetails(AZStd::string commandName, CommandDetails& outArguments) const = 0; - -}; - -using CommandManagerRequestBus = AZ::EBus; diff --git a/Code/Editor/ConfigGroup.cpp b/Code/Editor/ConfigGroup.cpp deleted file mode 100644 index 42236e43dd..0000000000 --- a/Code/Editor/ConfigGroup.cpp +++ /dev/null @@ -1,195 +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 "ConfigGroup.h" - -namespace Config -{ - CConfigGroup::CConfigGroup() - { - } - - CConfigGroup::~CConfigGroup() - { - for (IConfigVar* var : m_vars) - { - delete var; - } - } - - void CConfigGroup::AddVar(IConfigVar* var) - { - m_vars.push_back(var); - } - - AZ::u32 CConfigGroup::GetVarCount() - { - return aznumeric_cast(m_vars.size()); - } - - IConfigVar* CConfigGroup::GetVar(const char* szName) - { - for (IConfigVar* var : m_vars) - { - if (0 == _stricmp(szName, var->GetName().c_str())) - { - return var; - } - } - - return nullptr; - } - - const IConfigVar* CConfigGroup::GetVar(const char* szName) const - { - for (const IConfigVar* var : m_vars) - { - if (0 == _stricmp(szName, var->GetName().c_str())) - { - return var; - } - - } - - return nullptr; - } - - IConfigVar* CConfigGroup::GetVar(AZ::u32 index) - { - if (index < m_vars.size()) - { - return m_vars[index]; - } - - return nullptr; - } - - const IConfigVar* CConfigGroup::GetVar(AZ::u32 index) const - { - if (index < m_vars.size()) - { - return m_vars[index]; - } - - return nullptr; - } - - void CConfigGroup::SaveToXML(XmlNodeRef node) - { - // save only values that don't have default values - for (const IConfigVar* var : m_vars) - { - if (var->IsFlagSet(IConfigVar::eFlag_DoNotSave) || var->IsDefault()) - { - continue; - } - - const char* szName = var->GetName().c_str(); - - switch (var->GetType()) - { - case IConfigVar::eType_BOOL: - { - bool currentValue = false; - var->Get(¤tValue); - node->setAttr(szName, currentValue); - break; - } - - case IConfigVar::eType_INT: - { - int currentValue = 0; - var->Get(¤tValue); - node->setAttr(szName, currentValue); - break; - } - - case IConfigVar::eType_FLOAT: - { - float currentValue = 0; - var->Get(¤tValue); - node->setAttr(szName, currentValue); - break; - } - - case IConfigVar::eType_STRING: - { - AZStd::string currentValue; - var->Get(¤tValue); - node->setAttr(szName, currentValue.c_str()); - break; - } - } - } - } - - void CConfigGroup::LoadFromXML(XmlNodeRef node) - { - // load values that are save-able - for (IConfigVar* var : m_vars) - { - if (var->IsFlagSet(IConfigVar::eFlag_DoNotSave)) - { - continue; - } - const char* szName = var->GetName().c_str(); - - switch (var->GetType()) - { - case IConfigVar::eType_BOOL: - { - bool currentValue = false; - var->GetDefault(¤tValue); - if (node->getAttr(szName, currentValue)) - { - var->Set(¤tValue); - } - break; - } - - case IConfigVar::eType_INT: - { - int currentValue = 0; - var->GetDefault(¤tValue); - if (node->getAttr(szName, currentValue)) - { - var->Set(¤tValue); - } - break; - } - - case IConfigVar::eType_FLOAT: - { - float currentValue = 0; - var->GetDefault(¤tValue); - if (node->getAttr(szName, currentValue)) - { - var->Set(¤tValue); - } - break; - } - - case IConfigVar::eType_STRING: - { - AZStd::string currentValue; - var->GetDefault(¤tValue); - QString readValue(currentValue.c_str()); - if (node->getAttr(szName, readValue)) - { - currentValue = readValue.toUtf8().data(); - var->Set(¤tValue); - } - break; - } - } - } - } -} diff --git a/Code/Editor/ConfigGroup.h b/Code/Editor/ConfigGroup.h deleted file mode 100644 index 004725e32c..0000000000 --- a/Code/Editor/ConfigGroup.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#pragma once -#include -#include -#include - -struct ICVar; -class XmlNodeRef; - -namespace Config -{ - // Abstract configurable variable - struct IConfigVar - { - public: - enum EType - { - eType_BOOL, - eType_INT, - eType_FLOAT, - eType_STRING, - }; - - enum EFlags - { - eFlag_NoUI = 1 << 0, - eFlag_NoCVar = 1 << 1, - eFlag_DoNotSave = 1 << 2, - }; - - IConfigVar(const char* szName, const char* szDescription, EType varType, AZ::u8 flags) - : m_name(szName) - , m_description(szDescription) - , m_type(varType) - , m_flags(flags) - , m_ptr(nullptr) - {}; - - virtual ~IConfigVar() = default; - - AZ_FORCE_INLINE EType GetType() const - { - return m_type; - } - - AZ_FORCE_INLINE const AZStd::string& GetName() const - { - return m_name; - } - - AZ_FORCE_INLINE const AZStd::string& GetDescription() const - { - return m_description; - } - - AZ_FORCE_INLINE bool IsFlagSet(EFlags flag) const - { - return 0 != (m_flags & flag); - } - - virtual void Get(void* outPtr) const = 0; - virtual void Set(const void* ptr) = 0; - virtual bool IsDefault() const = 0; - virtual void GetDefault(void* outPtr) const = 0; - virtual void Reset() = 0; - - static constexpr EType TranslateType(const bool&) { return eType_BOOL; } - static constexpr EType TranslateType(const int&) { return eType_INT; } - static constexpr EType TranslateType(const float&) { return eType_FLOAT; } - static constexpr EType TranslateType(const AZStd::string&) { return eType_STRING; } - - protected: - EType m_type; - AZ::u8 m_flags; - AZStd::string m_name; - AZStd::string m_description; - void* m_ptr; - ICVar* m_pCVar; - }; - - // Group of configuration variables with optional mapping to CVars - class CConfigGroup - { - private: - using TConfigVariables = AZStd::vector ; - TConfigVariables m_vars; - - using TConsoleVariables = AZStd::vector; - TConsoleVariables m_consoleVars; - - public: - CConfigGroup(); - virtual ~CConfigGroup(); - - void AddVar(IConfigVar* var); - AZ::u32 GetVarCount(); - IConfigVar* GetVar(const char* szName); - IConfigVar* GetVar(AZ::u32 index); - const IConfigVar* GetVar(const char* szName) const; - const IConfigVar* GetVar(AZ::u32 index) const; - - void SaveToXML(XmlNodeRef node); - void LoadFromXML(XmlNodeRef node); - }; -}; diff --git a/Code/Editor/Controls/ReflectedPropertyControl/PropertyAnimationCtrl.cpp b/Code/Editor/Controls/ReflectedPropertyControl/PropertyAnimationCtrl.cpp deleted file mode 100644 index 4fb18e438c..0000000000 --- a/Code/Editor/Controls/ReflectedPropertyControl/PropertyAnimationCtrl.cpp +++ /dev/null @@ -1,131 +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 "PropertyAnimationCtrl.h" - -// Qt -#include -#include -#include - -// Editor -#include "Util/UIEnumerations.h" -#include "IResourceSelectorHost.h" - -AnimationPropertyCtrl::AnimationPropertyCtrl(QWidget *pParent) - : QWidget(pParent) -{ - m_animationLabel = new QLabel; - - m_pApplyButton = new QToolButton; - m_pApplyButton->setIcon(QIcon(":/reflectedPropertyCtrl/img/apply.png")); - - m_pApplyButton->setFocusPolicy(Qt::StrongFocus); - - QHBoxLayout *pLayout = new QHBoxLayout(this); - pLayout->setContentsMargins(0, 0, 0, 0); - pLayout->addWidget(m_animationLabel, 1); - pLayout->addWidget(m_pApplyButton); - - connect(m_pApplyButton, &QAbstractButton::clicked, this, &AnimationPropertyCtrl::OnApplyClicked); -}; - -AnimationPropertyCtrl::~AnimationPropertyCtrl() -{ -} - - -void AnimationPropertyCtrl::SetValue(const CReflectedVarAnimation &animation) -{ - m_animation = animation; - m_animationLabel->setText(animation.m_animation.c_str()); -} - -CReflectedVarAnimation AnimationPropertyCtrl::value() const -{ - return m_animation; -} - -void AnimationPropertyCtrl::OnApplyClicked() -{ - QStringList cSelectedAnimations; - int nTotalAnimations(0); - int nCurrentAnimation(0); - - QString combinedString = GetIEditor()->GetResourceSelectorHost()->GetGlobalSelection("animation"); - SplitString(combinedString, cSelectedAnimations, ','); - - nTotalAnimations = cSelectedAnimations.size(); - for (nCurrentAnimation = 0; nCurrentAnimation < nTotalAnimations; ++nCurrentAnimation) - { - QString& rstrCurrentAnimAction = cSelectedAnimations[nCurrentAnimation]; - if (!rstrCurrentAnimAction.isEmpty()) - { - m_animation.m_animation = rstrCurrentAnimAction.toUtf8().data(); - m_animationLabel->setText(m_animation.m_animation.c_str()); - emit ValueChanged(m_animation); - } - } -} - -QWidget* AnimationPropertyCtrl::GetFirstInTabOrder() -{ - return m_pApplyButton; -} -QWidget* AnimationPropertyCtrl::GetLastInTabOrder() -{ - return m_pApplyButton; -} - -void AnimationPropertyCtrl::UpdateTabOrder() -{ - setTabOrder(m_pApplyButton, m_pApplyButton); -} - - -QWidget* AnimationPropertyWidgetHandler::CreateGUI(QWidget *pParent) -{ - AnimationPropertyCtrl* newCtrl = aznew AnimationPropertyCtrl(pParent); - connect(newCtrl, &AnimationPropertyCtrl::ValueChanged, newCtrl, [newCtrl]() - { - EBUS_EVENT(AzToolsFramework::PropertyEditorGUIMessages::Bus, RequestWrite, newCtrl); - }); - return newCtrl; -} - - -void AnimationPropertyWidgetHandler::ConsumeAttribute(AnimationPropertyCtrl* GUI, AZ::u32 attrib, AzToolsFramework::PropertyAttributeReader* attrValue, const char* debugName) -{ - Q_UNUSED(GUI); - Q_UNUSED(attrib); - Q_UNUSED(attrValue); - Q_UNUSED(debugName); -} - -void AnimationPropertyWidgetHandler::WriteGUIValuesIntoProperty(size_t index, AnimationPropertyCtrl* GUI, property_t& instance, AzToolsFramework::InstanceDataNode* node) -{ - Q_UNUSED(index); - Q_UNUSED(node); - CReflectedVarAnimation val = GUI->value(); - instance = static_cast(val); -} - -bool AnimationPropertyWidgetHandler::ReadValuesIntoGUI(size_t index, AnimationPropertyCtrl* GUI, const property_t& instance, AzToolsFramework::InstanceDataNode* node) -{ - Q_UNUSED(index); - Q_UNUSED(node); - CReflectedVarAnimation val = instance; - GUI->SetValue(val); - return false; -} - - -#include - diff --git a/Code/Editor/Controls/ReflectedPropertyControl/PropertyAnimationCtrl.h b/Code/Editor/Controls/ReflectedPropertyControl/PropertyAnimationCtrl.h deleted file mode 100644 index 6f3e5b44f3..0000000000 --- a/Code/Editor/Controls/ReflectedPropertyControl/PropertyAnimationCtrl.h +++ /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 - * - */ - -#ifndef CRYINCLUDE_EDITOR_UTILS_PROPERTYANIMATIONCTRL_H -#define CRYINCLUDE_EDITOR_UTILS_PROPERTYANIMATIONCTRL_H -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#include -#include "ReflectedVar.h" -#include -#include -#endif - -class QToolButton; -class QLabel; -class QHBoxLayout; - -class AnimationPropertyCtrl - : public QWidget -{ - Q_OBJECT -public: - AZ_CLASS_ALLOCATOR(AnimationPropertyCtrl, AZ::SystemAllocator, 0); - - AnimationPropertyCtrl(QWidget* pParent = nullptr); - virtual ~AnimationPropertyCtrl(); - - CReflectedVarAnimation value() const; - - QWidget* GetFirstInTabOrder(); - QWidget* GetLastInTabOrder(); - void UpdateTabOrder(); - -signals: - void ValueChanged(CReflectedVarAnimation value); - -public slots: - void SetValue(const CReflectedVarAnimation& animation); - -protected slots: - void OnApplyClicked(); - -private: - QToolButton* m_pApplyButton; - QLabel* m_animationLabel; - - CReflectedVarAnimation m_animation; -}; - -class AnimationPropertyWidgetHandler - : QObject - , public AzToolsFramework::PropertyHandler < CReflectedVarAnimation, AnimationPropertyCtrl > -{ -public: - AZ_CLASS_ALLOCATOR(AnimationPropertyWidgetHandler, AZ::SystemAllocator, 0); - - virtual AZ::u32 GetHandlerName(void) const override { return AZ_CRC("Animation", 0x8d5284dc); } - virtual bool IsDefaultHandler() const override { return true; } - virtual QWidget* GetFirstInTabOrder(AnimationPropertyCtrl* widget) override { return widget->GetFirstInTabOrder(); } - virtual QWidget* GetLastInTabOrder(AnimationPropertyCtrl* widget) override { return widget->GetLastInTabOrder(); } - virtual void UpdateWidgetInternalTabbing(AnimationPropertyCtrl* widget) override { widget->UpdateTabOrder(); } - - virtual QWidget* CreateGUI(QWidget* pParent) override; - virtual void ConsumeAttribute(AnimationPropertyCtrl* GUI, AZ::u32 attrib, AzToolsFramework::PropertyAttributeReader* attrValue, const char* debugName) override; - virtual void WriteGUIValuesIntoProperty(size_t index, AnimationPropertyCtrl* GUI, property_t& instance, AzToolsFramework::InstanceDataNode* node) override; - virtual bool ReadValuesIntoGUI(size_t index, AnimationPropertyCtrl* GUI, const property_t& instance, AzToolsFramework::InstanceDataNode* node) override; -}; - - -#endif // CRYINCLUDE_EDITOR_UTILS_PROPERTYANIMATIONCTRL_H diff --git a/Code/Editor/CryEdit.cpp b/Code/Editor/CryEdit.cpp index 3beaf4d438..b9081c3f90 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 @@ -144,9 +136,7 @@ AZ_POP_DISABLE_WARNING #include "Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.h" -// AWSNativeSDK #include -#include #if defined(AZ_PLATFORM_WINDOWS) @@ -1830,10 +1820,7 @@ bool CCryEditApp::InitInstance() if (GetIEditor()->GetCommandManager()->IsRegistered("editor.open_lnm_editor")) { CCommand0::SUIInfo uiInfo; -#if !defined(NDEBUG) - bool ok = -#endif - GetIEditor()->GetCommandManager()->GetUIInfo("editor.open_lnm_editor", uiInfo); + [[maybe_unused]] bool ok = GetIEditor()->GetCommandManager()->GetUIInfo("editor.open_lnm_editor", uiInfo); assert(ok); } @@ -2125,8 +2112,6 @@ 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(); @@ -3363,6 +3348,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()) { @@ -3370,6 +3359,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/CryEditDoc.cpp b/Code/Editor/CryEditDoc.cpp index 9d93fd5f5b..c7d719184d 100644 --- a/Code/Editor/CryEditDoc.cpp +++ b/Code/Editor/CryEditDoc.cpp @@ -57,7 +57,6 @@ // LmbrCentral #include -#include // for LmbrCentral::EditorLightComponentRequestBus static const char* kAutoBackupFolder = "_autobackup"; static const char* kHoldFolder = "$tmp_hold"; // conform to the ignored file types $tmp[0-9]*_ regex @@ -2130,52 +2129,13 @@ void CCryEditDoc::ReleaseXmlArchiveArray(TDocMultiArchive& arrXmlAr) ////////////////////////////////////////////////////////////////////////// // AzToolsFramework::EditorEntityContextNotificationBus interface implementation -void CCryEditDoc::OnSliceInstantiated(const AZ::Data::AssetId& sliceAssetId, AZ::SliceComponent::SliceInstanceAddress& sliceAddress, const AzFramework::SliceInstantiationTicket& /*ticket*/) +void CCryEditDoc::OnSliceInstantiated([[maybe_unused]] const AZ::Data::AssetId& sliceAssetId, [[maybe_unused]] AZ::SliceComponent::SliceInstanceAddress& sliceAddress, [[maybe_unused]] const AzFramework::SliceInstantiationTicket& ticket) { - if (m_envProbeSliceAssetId == sliceAssetId) - { - const AZ::SliceComponent::EntityList& entities = sliceAddress.GetInstance()->GetInstantiated()->m_entities; - const AZ::Uuid editorEnvProbeComponentId("{8DBD6035-583E-409F-AFD9-F36829A0655D}"); - AzToolsFramework::EntityIdList entityIds; - entityIds.reserve(entities.size()); - for (const AZ::Entity* entity : entities) - { - if (entity->FindComponent(editorEnvProbeComponentId)) - { - // Update Probe Area size to cover the whole terrain - LmbrCentral::EditorLightComponentRequestBus::Event(entity->GetId(), &LmbrCentral::EditorLightComponentRequests::SetProbeAreaDimensions, AZ::Vector3(m_terrainSize, m_terrainSize, m_envProbeHeight)); - - // Force update the light to apply cubemap - LmbrCentral::EditorLightComponentRequestBus::Event(entity->GetId(), &LmbrCentral::EditorLightComponentRequests::RefreshLight); - } - entityIds.push_back(entity->GetId()); - } - - //Detach instantiated env probe entities from engine slice - AzToolsFramework::SliceEditorEntityOwnershipServiceRequestBus::Broadcast( - &AzToolsFramework::SliceEditorEntityOwnershipServiceRequests::DetachSliceEntities, entityIds); - - sliceAddress.SetInstance(nullptr); - sliceAddress.SetReference(nullptr); - SetModifiedFlag(true); - SetModifiedModules(eModifiedEntities); - - AzToolsFramework::SliceEditorEntityOwnershipServiceNotificationBus::Handler::BusDisconnect(); - - //save after level default slice fully instantiated - Save(); - } GetIEditor()->ResumeUndo(); } - -void CCryEditDoc::OnSliceInstantiationFailed(const AZ::Data::AssetId& sliceAssetId, const AzFramework::SliceInstantiationTicket& /*ticket*/) +void CCryEditDoc::OnSliceInstantiationFailed([[maybe_unused]] const AZ::Data::AssetId& sliceAssetId, [[maybe_unused]] const AzFramework::SliceInstantiationTicket& ticket) { - if (m_envProbeSliceAssetId == sliceAssetId) - { - AzToolsFramework::SliceEditorEntityOwnershipServiceNotificationBus::Handler::BusDisconnect(); - AZ_Warning("Editor", false, "Failed to instantiate default environment probe slice."); - } GetIEditor()->ResumeUndo(); } ////////////////////////////////////////////////////////////////////////// diff --git a/Code/Editor/CryEditDoc.h b/Code/Editor/CryEditDoc.h index 5d20bddf45..3874914396 100644 --- a/Code/Editor/CryEditDoc.h +++ b/Code/Editor/CryEditDoc.h @@ -200,7 +200,6 @@ protected: QString m_pathName; QString m_slicePathName; QString m_title; - AZ::Data::AssetId m_envProbeSliceAssetId; float m_terrainSize; const char* m_envProbeSliceRelativePath = "EngineAssets/Slices/DefaultLevelSetup.slice"; const float m_envProbeHeight = 200.0f; diff --git a/Code/Editor/EditorDefs.h b/Code/Editor/EditorDefs.h index 97c03b2b45..e86f007604 100644 --- a/Code/Editor/EditorDefs.h +++ b/Code/Editor/EditorDefs.h @@ -123,9 +123,7 @@ #include "Util/XmlTemplate.h" // Utility classes. -#include "Util/bitarray.h" #include "Util/RefCountBase.h" -#include "Util/TRefCountBase.h" #include "Util/MemoryBlock.h" #include "Util/PathUtil.h" @@ -168,18 +166,3 @@ #ifdef LoadCursor #undef LoadCursor #endif - - -#ifdef _DEBUG -#if !defined(AZ_PLATFORM_LINUX) -#ifdef assert -#undef assert -#if defined(USE_AZ_ASSERT) -#define assert(condition) AZ_Assert(condition, "") -#else -#define assert CRY_ASSERT -#endif -#endif // !defined(AZ_PLATFORM_LINUX) -#endif -#endif - diff --git a/Code/Editor/EditorPreferencesBus.h b/Code/Editor/EditorPreferencesBus.h deleted file mode 100644 index d6c9e3ed55..0000000000 --- a/Code/Editor/EditorPreferencesBus.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include - -//! Allows handlers to be notified when settings are changed to refresh accordingly -class EditorPreferencesNotifications - : public AZ::EBusTraits -{ -public: - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - - //! Notifies about changes in the Editor Preferences - virtual void OnEditorPreferencesChanged() {} -}; -using EditorPreferencesNotificationBus = AZ::EBus; 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 a8180bcace..9a9e9f5ad3 100644 --- a/Code/Editor/EditorViewportWidget.cpp +++ b/Code/Editor/EditorViewportWidget.cpp @@ -89,6 +89,7 @@ #include // Atom +#include #include #include #include @@ -584,7 +585,7 @@ void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event) m_renderViewport->SetScene(nullptr); break; - case eNotify_OnEndSceneOpen: + case eNotify_OnEndLoad: UpdateScene(); SetDefaultCamera(); break; @@ -2324,7 +2325,26 @@ void EditorViewportWidget::UpdateScene() { AZ::RPI::SceneNotificationBus::Handler::BusDisconnect(); m_renderViewport->SetScene(mainScene); - AZ::RPI::SceneNotificationBus::Handler::BusConnect(m_renderViewport->GetViewportContext()->GetRenderScene()->GetId()); + auto viewportContext = m_renderViewport->GetViewportContext(); + AZ::RPI::SceneNotificationBus::Handler::BusConnect(viewportContext->GetRenderScene()->GetId()); + + // Don't enable the render pipeline until a level has been loaded + // Also show/hide the RenderViewportWidget accordingly so that we get the + // expected gradient background when no level is loaded + auto renderPipeline = viewportContext->GetCurrentPipeline(); + if (renderPipeline) + { + if (GetIEditor()->IsLevelLoaded()) + { + m_renderViewport->show(); + renderPipeline->AddToRenderTick(); + } + else + { + m_renderViewport->hide(); + renderPipeline->RemoveFromRenderTick(); + } + } } } } diff --git a/Code/Editor/ErrorRecorder.h b/Code/Editor/ErrorRecorder.h index beacc3f0e5..9a0bad7d91 100644 --- a/Code/Editor/ErrorRecorder.h +++ b/Code/Editor/ErrorRecorder.h @@ -14,7 +14,7 @@ #define CRYINCLUDE_EDITOR_CORE_ERRORRECORDER_H #pragma once -#include "Include/EditorCoreAPI.h" +#include ////////////////////////////////////////////////////////////////////////// //! Automatic class to record and display error. diff --git a/Code/Editor/ErrorReport.h b/Code/Editor/ErrorReport.h index 98d230e383..a80bb36404 100644 --- a/Code/Editor/ErrorReport.h +++ b/Code/Editor/ErrorReport.h @@ -17,9 +17,6 @@ // forward declarations. class CParticleItem; -#include -#include - #include "Objects/BaseObject.h" #include "Include/EditorCoreAPI.h" #include "Include/IErrorReport.h" diff --git a/Code/Editor/GameEngine.cpp b/Code/Editor/GameEngine.cpp index 9786dcf1b8..8aab168b6d 100644 --- a/Code/Editor/GameEngine.cpp +++ b/Code/Editor/GameEngine.cpp @@ -18,6 +18,7 @@ // AzCore #include #include +#include #include #include diff --git a/Code/Editor/IEditor.h b/Code/Editor/IEditor.h index 90f1b63f55..52f8c1ac6f 100644 --- a/Code/Editor/IEditor.h +++ b/Code/Editor/IEditor.h @@ -19,8 +19,6 @@ #include "Util/UndoUtil.h" #include -#include - #include #include @@ -66,11 +64,6 @@ struct SEditorSettings; class CGameExporter; class IAWSResourceManager; -namespace WinWidget -{ - class WinWidgetManager; -} - struct ISystem; struct IRenderer; struct AABB; @@ -323,17 +316,6 @@ enum MouseCallbackFlags MK_CALLBACK_FLAGS = 0x100 }; -//! Types of database items -enum EDataBaseItemType -{ - EDB_TYPE_MATERIAL, - EDB_TYPE_PARTICLE, - EDB_TYPE_MUSIC, - EDB_TYPE_EAXPRESET, - EDB_TYPE_SOUNDMOOD, - EDB_TYPE_FLARE -}; - enum EEditorPathName { EDITOR_PATH_OBJECTS, @@ -597,10 +579,6 @@ struct IEditor virtual bool SetViewFocus(const char* sViewClassName) = 0; virtual void CloseView(const GUID& classId) = 0; // close ALL panels related to classId, used when unloading plugins. - // We want to open a view object but not wrap it in a view pane) - virtual QWidget* OpenWinWidget(WinWidgetId openId) = 0; - virtual WinWidget::WinWidgetManager* GetWinWidgetManager() const = 0; - //! Opens standard color selection dialog. //! Initialized with the color specified in color parameter. //! Returns true if selection is made and false if selection is canceled. diff --git a/Code/Editor/IEditorImpl.cpp b/Code/Editor/IEditorImpl.cpp index 38006c6fca..d3f881a252 100644 --- a/Code/Editor/IEditorImpl.cpp +++ b/Code/Editor/IEditorImpl.cpp @@ -12,16 +12,11 @@ #include "EditorDefs.h" #include "IEditorImpl.h" +#include // Qt #include -// AWS Native SDK -AZ_PUSH_DISABLE_WARNING(4251 4355 4996, "-Wunknown-warning-option") -#include -#include -AZ_POP_DISABLE_WARNING - // AzCore #include #include @@ -75,12 +70,6 @@ AZ_POP_DISABLE_WARNING #include "Editor/AzAssetBrowser/AzAssetBrowserRequestHandler.h" #include "Editor/AssetEditor/AssetEditorRequestsHandler.h" -// EditorCommon -#include - -// AWSNativeSDK -#include - #include "Core/QtEditorApplication.h" // for Editor::EditorQtApplication static CCryEditDoc * theDocument; @@ -132,7 +121,6 @@ CEditorImpl::CEditorImpl() , m_pSettingsManager(nullptr) , m_pLevelIndependentFileMan(nullptr) , m_pExportManager(nullptr) - , m_awsResourceManager(nullptr) , m_bMatEditMode(false) , m_bShowStatusText(true) , m_bInitialized(false) @@ -177,8 +165,6 @@ CEditorImpl::CEditorImpl() DetectVersion(); RegisterTools(); - m_winWidgetManager.reset(new WinWidget::WinWidgetManager); - m_pAssetDatabaseLocationListener = nullptr; m_pAssetBrowserRequestHandler = nullptr; m_assetEditorRequestsHandler = nullptr; @@ -847,20 +833,6 @@ const QtViewPane* CEditorImpl::OpenView(QString sViewClassName, bool reuseOpened return QtViewPaneManager::instance()->OpenPane(sViewClassName, openMode); } -QWidget* CEditorImpl::OpenWinWidget(WinWidgetId openId) -{ - if (m_winWidgetManager) - { - return m_winWidgetManager->OpenWinWidget(openId); - } - return nullptr; -} - -WinWidget::WinWidgetManager* CEditorImpl::GetWinWidgetManager() const -{ - return m_winWidgetManager.get(); -} - QWidget* CEditorImpl::FindView(QString viewClassName) { return QtViewPaneManager::instance()->GetView(viewClassName); diff --git a/Code/Editor/IEditorImpl.h b/Code/Editor/IEditorImpl.h index 7867912941..08629e434b 100644 --- a/Code/Editor/IEditorImpl.h +++ b/Code/Editor/IEditorImpl.h @@ -53,11 +53,6 @@ namespace Editor class EditorQtApplication; } -namespace WinWidget -{ - class WinWidgetManager; -} - namespace AssetDatabase { class AssetDatabaseLocationListener; @@ -221,9 +216,6 @@ public: bool CloseView(const char* sViewClassName) override; bool SetViewFocus(const char* sViewClassName) override; - QWidget* OpenWinWidget(WinWidgetId openId) override; - WinWidget::WinWidgetManager* GetWinWidgetManager() const override; - // close ALL panels related to classId, used when unloading plugins. void CloseView(const GUID& classId) override; bool SelectColor(QColor &color, QWidget *parent = 0) override; @@ -369,8 +361,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. //! In this mode only very limited functionality is available. diff --git a/Code/Editor/IObservable.h b/Code/Editor/IObservable.h deleted file mode 100644 index 9de78a7bc1..0000000000 --- a/Code/Editor/IObservable.h +++ /dev/null @@ -1,20 +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_IOBSERVABLE_H -#define CRYINCLUDE_EDITOR_IOBSERVABLE_H -#pragma once - -//! Observable macro to be used in pure interfaces -#define DEFINE_OBSERVABLE_PURE_METHODS(observerClassName) \ - virtual bool RegisterObserver(observerClassName * pObserver) = 0; \ - virtual bool UnregisterObserver(observerClassName * pObserver) = 0; \ - virtual void UnregisterAllObservers() = 0; - -#endif // CRYINCLUDE_EDITOR_IOBSERVABLE_H 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/Launcher/editor_launcher.rc b/Code/Editor/Launcher/editor_launcher.rc deleted file mode 100644 index 26dad7a3da..0000000000 --- a/Code/Editor/Launcher/editor_launcher.rc +++ /dev/null @@ -1,2 +0,0 @@ -IDI_ICON1 ICON DISCARDABLE "..\\res\\lyeditor.ico" - diff --git a/Code/Editor/Lib/Tests/IEditorMock.h b/Code/Editor/Lib/Tests/IEditorMock.h index aaee34c2c6..b2f7e2627f 100644 --- a/Code/Editor/Lib/Tests/IEditorMock.h +++ b/Code/Editor/Lib/Tests/IEditorMock.h @@ -128,8 +128,6 @@ public: MOCK_METHOD1(CloseView, bool(const char* )); MOCK_METHOD1(SetViewFocus, bool(const char* )); MOCK_METHOD1(CloseView, void(const GUID& )); - MOCK_METHOD1(OpenWinWidget, QWidget* (WinWidgetId )); - MOCK_CONST_METHOD0(GetWinWidgetManager, WinWidget::WinWidgetManager* ()); MOCK_METHOD2(SelectColor, bool(QColor &, QWidget *)); MOCK_METHOD0(GetUndoManager, class CUndoManager* ()); MOCK_METHOD0(BeginUndo, void()); diff --git a/Code/Editor/Lib/Tests/test_EditorPythonBindings.cpp b/Code/Editor/Lib/Tests/test_EditorPythonBindings.cpp index 49b65f7ffc..0c5e221d21 100644 --- a/Code/Editor/Lib/Tests/test_EditorPythonBindings.cpp +++ b/Code/Editor/Lib/Tests/test_EditorPythonBindings.cpp @@ -25,7 +25,6 @@ #include #include #include -#include #include #include "IEditorMock.h" 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..3a52bb85a1 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 @@ -77,7 +72,6 @@ AZ_POP_DISABLE_WARNING #include "ToolbarManager.h" #include "Core/QtEditorApplication.h" #include "UndoDropDown.h" -#include "CVarMenu.h" #include "EditorViewportSettings.h" #include "KeyboardCustomizationSettings.h" diff --git a/Code/Editor/MainWindow.h b/Code/Editor/MainWindow.h index 1e375b08f2..9759dadade 100644 --- a/Code/Editor/MainWindow.h +++ b/Code/Editor/MainWindow.h @@ -49,7 +49,6 @@ class ToolbarCustomizationDialog; class QWidgetAction; class ActionManager; class ShortcutDispatcher; -class CVarMenu; namespace AzQtComponents { @@ -64,11 +63,11 @@ namespace AzToolsFramework //! @name Reverse URLs. //! Used to identify common actions and override them when necessary. //@{ - constexpr inline AZ::Crc32 EditModeMove = AZ_CRC_CE("com.o3de.action.editor.editmode.move"); - constexpr inline AZ::Crc32 EditModeRotate = AZ_CRC_CE("com.o3de.action.editor.editmode.rotate"); - constexpr inline AZ::Crc32 EditModeScale = AZ_CRC_CE("com.o3de.action.editor.editmode.scale"); - constexpr inline AZ::Crc32 SnapToGrid = AZ_CRC_CE("com.o3de.action.editor.snaptogrid"); - constexpr inline AZ::Crc32 SnapAngle = AZ_CRC_CE("com.o3de.action.editor.snapangle"); + constexpr inline AZ::Crc32 EditModeMove = AZ_CRC_CE("org.o3de.action.editor.editmode.move"); + constexpr inline AZ::Crc32 EditModeRotate = AZ_CRC_CE("org.o3de.action.editor.editmode.rotate"); + constexpr inline AZ::Crc32 EditModeScale = AZ_CRC_CE("org.o3de.action.editor.editmode.scale"); + constexpr inline AZ::Crc32 SnapToGrid = AZ_CRC_CE("org.o3de.action.editor.snaptogrid"); + constexpr inline AZ::Crc32 SnapAngle = AZ_CRC_CE("org.o3de.action.editor.snapangle"); //@} } diff --git a/Code/Editor/Objects/BaseObject.h b/Code/Editor/Objects/BaseObject.h index fea248c7f7..666d9f3e1d 100644 --- a/Code/Editor/Objects/BaseObject.h +++ b/Code/Editor/Objects/BaseObject.h @@ -31,7 +31,6 @@ class CUndoBaseObject; class CObjectManager; class CGizmo; class CObjectArchive; -struct SSubObjSelectionModifyContext; struct SRayHitInfo; class CPopupMenuItem; class QMenu; diff --git a/Code/Editor/Objects/SubObjSelection.cpp b/Code/Editor/Objects/SubObjSelection.cpp deleted file mode 100644 index 3a67b8dfb7..0000000000 --- a/Code/Editor/Objects/SubObjSelection.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#include "EditorDefs.h" - -#include "SubObjSelection.h" - -SSubObjSelOptions g_SubObjSelOptions; - -/* - -////////////////////////////////////////////////////////////////////////// -bool CSubObjSelContext::IsEmpty() const -{ - if (GetCount() == 0) - return false; - for (int i = 0; i < GetCount(); i++) - { - CSubObjectSelection *pSel = GetSelection(i); - if (!pSel->IsEmpty()) - return true; - } - return false; -} - -////////////////////////////////////////////////////////////////////////// -void CSubObjSelContext::ModifySelection( SSubObjSelectionModifyContext &modCtx ) -{ - for (int n = 0; n < GetCount(); n++) - { - CSubObjectSelection *pSel = GetSelection(n); - if (pSel->IsEmpty()) - continue; - modCtx.pSubObjSelection = pSel; - pSel->pGeometry->SubObjSelectionModify( modCtx ); - } - if (modCtx.type == SO_MODIFY_MOVE) - { - OnSelectionChange(); - } -} - -////////////////////////////////////////////////////////////////////////// -void CSubObjSelContext::AcceptModifySelection() -{ - for (int n = 0; n < GetCount(); n++) - { - CSubObjectSelection *pSel = GetSelection(n); - if (pSel->IsEmpty()) - continue; - if (pSel->pGeometry) - pSel->pGeometry->Update(); - } -} - -*/ diff --git a/Code/Editor/Objects/SubObjSelection.h b/Code/Editor/Objects/SubObjSelection.h deleted file mode 100644 index 9e07bdc203..0000000000 --- a/Code/Editor/Objects/SubObjSelection.h +++ /dev/null @@ -1,91 +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_OBJECTS_SUBOBJSELECTION_H -#define CRYINCLUDE_EDITOR_OBJECTS_SUBOBJSELECTION_H -#pragma once - -////////////////////////////////////////////////////////////////////////// -// Sub Object element type. -////////////////////////////////////////////////////////////////////////// -enum ESubObjElementType -{ - SO_ELEM_NONE = 0, - SO_ELEM_VERTEX, - SO_ELEM_EDGE, - SO_ELEM_FACE, - SO_ELEM_POLYGON, - SO_ELEM_UV, -}; - -////////////////////////////////////////////////////////////////////////// -enum ESubObjDisplayType -{ - SO_DISPLAY_WIREFRAME, - SO_DISPLAY_FLAT, - SO_DISPLAY_GEOMETRY, -}; - -////////////////////////////////////////////////////////////////////////// -// Options for sub-object selection. -////////////////////////////////////////////////////////////////////////// -struct SSubObjSelOptions -{ - bool bSelectByVertex; - bool bIgnoreBackfacing; - int nMatID; - - bool bSoftSelection; - float fSoftSelFalloff; - - // Display options. - bool bDisplayBackfacing; - bool bDisplayNormals; - float fNormalsLength; - ESubObjDisplayType displayType; - - SSubObjSelOptions() - { - bSelectByVertex = false; - bIgnoreBackfacing = false; - bSoftSelection = false; - nMatID = 0; - fSoftSelFalloff = 1; - - bDisplayBackfacing = true; - bDisplayNormals = false; - displayType = SO_DISPLAY_FLAT; - fNormalsLength = 0.4f; - } -}; - -extern SSubObjSelOptions g_SubObjSelOptions; - - -////////////////////////////////////////////////////////////////////////// -enum ESubObjSelectionModifyType -{ - SO_MODIFY_UNSELECT, - SO_MODIFY_MOVE, - SO_MODIFY_ROTATE, - SO_MODIFY_SCALE, -}; - -////////////////////////////////////////////////////////////////////////// -// This structure is passed when user is dragging sub object selection. -////////////////////////////////////////////////////////////////////////// -struct SSubObjSelectionModifyContext -{ - CViewport* view; - ESubObjSelectionModifyType type; - Vec3 vValue; - Matrix34 worldRefFrame; -}; - -#endif // CRYINCLUDE_EDITOR_OBJECTS_SUBOBJSELECTION_H 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/Plugin.h b/Code/Editor/Plugin.h index 5fa45ac140..dd2637f0e9 100644 --- a/Code/Editor/Plugin.h +++ b/Code/Editor/Plugin.h @@ -15,45 +15,6 @@ #include "Util/GuidUtil.h" #include -//! Derive from this class to decrease the amount of work for creating a new class description -//! Provides standard reference counter implementation for IUnknown -class CRefCountClassDesc - : public IClassDesc -{ -public: - virtual ~CRefCountClassDesc() { } - HRESULT STDMETHODCALLTYPE QueryInterface([[maybe_unused]] const IID& riid, [[maybe_unused]] void** ppvObj) - { - return E_NOINTERFACE; - } - - ULONG STDMETHODCALLTYPE AddRef() - { - ++m_nRefCount; - return m_nRefCount; - } - - ULONG STDMETHODCALLTYPE Release() - { - int refs = m_nRefCount; - - if (--m_nRefCount <= 0) - { - delete this; - } - - return refs; - } - -private: - int m_nRefCount; -}; - - -// Use this for debugging unregistration problems. -//#define DEBUG_CLASS_NAME_REGISTRATION - - //! Class factory is a common repository of all registered plugin classes, //! Classes here can found by their class ID or all classes of given system class retrieved class CRYEDIT_API CClassFactory diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/ComponentEntityEditorPlugin.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/ComponentEntityEditorPlugin.cpp index 50b315b9c3..9022341309 100644 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/ComponentEntityEditorPlugin.cpp +++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/ComponentEntityEditorPlugin.cpp @@ -14,7 +14,6 @@ #include "UI/QComponentEntityEditorOutlinerWindow.h" #include "UI/QComponentLevelEntityEditorMainWindow.h" #include "UI/ComponentPalette/ComponentPaletteSettings.h" -#include "UI/ComponentPalette/ComponentPaletteWindow.h" #include #include diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/ComponentEntityEditorPlugin.mf b/Code/Editor/Plugins/ComponentEntityEditorPlugin/ComponentEntityEditorPlugin.mf deleted file mode 100644 index 997209477a..0000000000 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/ComponentEntityEditorPlugin.mf +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp index 69b195d243..b88c7f8d60 100644 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp +++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp @@ -69,7 +69,6 @@ #include "ISourceControl.h" #include "UI/QComponentEntityEditorMainWindow.h" -#include #include #include diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/AssetCatalogModel.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/AssetCatalogModel.cpp index 60fda239dc..b1233b8387 100644 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/AssetCatalogModel.cpp +++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/AssetCatalogModel.cpp @@ -16,7 +16,6 @@ #include #include -#include #include #include diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/CategoriesList.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/CategoriesList.cpp deleted file mode 100644 index cd157fe838..0000000000 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/CategoriesList.cpp +++ /dev/null @@ -1,97 +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 "CategoriesList.h" - -ComponentCategoryList::ComponentCategoryList(QWidget* parent /*= nullptr*/) - : QTreeWidget(parent) -{ -} - -void ComponentCategoryList::Init() -{ - setColumnCount(1); - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - setDragDropMode(QAbstractItemView::DragDropMode::DragOnly); - setDragEnabled(true); - setSelectionMode(QAbstractItemView::ExtendedSelection); - setAllColumnsShowFocus(true); - setStyleSheet("QTreeWidget { selection-background-color: rgba(255,255,255,0.2); }"); - - QStringList headers; - headers << tr("Categories"); - setHeaderLabels(headers); - - const QString parentCategoryIconPath = QString("Icons/PropertyEditor/Browse_on.png"); - const QString categoryIconPath = QString("Icons/PropertyEditor/Browse.png"); - - QTreeWidgetItem* allCategory = new QTreeWidgetItem(this); - allCategory->setText(0, "All"); - allCategory->setIcon(0, QIcon(categoryIconPath)); - - // Need this briefly to collect the list of available categories. - ComponentDataModel dataModel(this); - for (const auto& cat : dataModel.GetCategories()) - { - QString categoryString = QString(cat.c_str()); - QStringList categories = categoryString.split('/', Qt::SkipEmptyParts); - - QTreeWidgetItem* parent = nullptr; - QTreeWidgetItem* categoryWidget = nullptr; - - for (const auto& categoryName : categories) - { - if (parent) - { - categoryWidget = new QTreeWidgetItem(parent); - categoryWidget->setIcon(0, QIcon(categoryIconPath)); - - // Store the full category path in a user role because we'll need it to locate the actual category - categoryWidget->setData(0, Qt::UserRole, QVariant::fromValue(categoryString)); - } - else - { - auto existingCategory = findItems(categoryName, Qt::MatchExactly); - if (existingCategory.empty()) - { - categoryWidget = new QTreeWidgetItem(this); - categoryWidget->setIcon(0, QIcon(parentCategoryIconPath)); - } - else - { - categoryWidget = static_cast(existingCategory.first()); - categoryWidget->setIcon(0, QIcon(parentCategoryIconPath)); - } - } - - parent = categoryWidget; - - categoryWidget->setText(0, categoryName); - } - } - - expandAll(); - - connect(this, &QTreeWidget::itemClicked, this, &ComponentCategoryList::OnItemClicked); -} - -void ComponentCategoryList::OnItemClicked(QTreeWidgetItem* item, int /*column*/) -{ - QVariant userData = item->data(0, Qt::UserRole); - if (userData.isValid()) - { - // Send in the full category path, not just the child category name - emit OnCategoryChange(userData.value().toStdString().c_str()); - } - else - { - emit OnCategoryChange(item->text(0).toStdString().c_str()); - } -} - -#include diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/CategoriesList.h b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/CategoriesList.h deleted file mode 100644 index 76a955ea76..0000000000 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/CategoriesList.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 - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include "ComponentDataModel.h" -#include -#endif - -//! ComponentCategoryList -//! Provides a list of all reflected categories that users can select for quick -//! filtering the filtered component list. -class ComponentCategoryList : public QTreeWidget -{ - Q_OBJECT - -public: - - AZ_CLASS_ALLOCATOR(ComponentCategoryList, AZ::SystemAllocator, 0); - - explicit ComponentCategoryList(QWidget* parent = nullptr); - - void Init(); - -Q_SIGNALS: - void OnCategoryChange(const char* category); - -protected: - - // Will emit OnCategoryChange signal - void OnItemClicked(QTreeWidgetItem* item, int column); - -}; diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/ComponentDataModel.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/ComponentDataModel.cpp deleted file mode 100644 index dcae6abfeb..0000000000 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/ComponentDataModel.cpp +++ /dev/null @@ -1,547 +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 "ComponentDataModel.h" - -#include "Include/IObjectManager.h" -#include "Objects/SelectionGroup.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include - -namespace -{ - // This is a helper function that given an object that derives from QAbstractItemModel, - // it will request the model's "ClassDataRole" class data for an entry and use that - // information to create a new entity with the selected components. - AZ::EntityId CreateEntityFromSelection(const QModelIndexList& selection, QAbstractItemModel* model) - { - AZ::Vector3 position = AZ::Vector3::CreateZero(); - CViewport *view = GetIEditor()->GetViewManager()->GetGameViewport(); - int width, height; - view->GetDimensions(&width, &height); - position = LYVec3ToAZVec3(view->ViewToWorld(QPoint(width / 2, height / 2))); - - AZ::EntityId newEntityId; - EBUS_EVENT_RESULT(newEntityId, AzToolsFramework::EditorRequests::Bus, CreateNewEntityAtPosition, position, AZ::EntityId()); - if (newEntityId.IsValid()) - { - // Add all the selected components. - AZ::ComponentTypeList componentsToAdd; - for (auto index : selection) - { - // We only need to consider the first column, it's important that the data() function that - // returns ComponentDataModel::ClassDataRole also does so for the first column. - if (index.column() != 0) - { - continue; - } - - QVariant classDataVariant = model->data(index, ComponentDataModel::ClassDataRole); - if (classDataVariant.isValid()) - { - const AZ::SerializeContext::ClassData* classData = reinterpret_cast(classDataVariant.value()); - componentsToAdd.push_back(classData->m_typeId); - } - } - - AzToolsFramework::EntityCompositionRequestBus::Broadcast(&AzToolsFramework::EntityCompositionRequests::AddComponentsToEntities, AzToolsFramework::EntityIdList{ newEntityId }, componentsToAdd); - - return newEntityId; - } - - return AZ::EntityId(); - } -} - -namespace ComponentDataUtilities -{ - // This is a helper function to add the specified components to the selected entities, it relies on the provided - // QAbstractItemModel to determine the appropriate ClassData to use to create the components (given that some widgets - // may provide proxy models that alter the order). - void AddComponentsToSelectedEntities(const QModelIndexList& selectedComponents, QAbstractItemModel* model) - { - AzToolsFramework::EntityIdList selectedEntities; - AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(selectedEntities, &AzToolsFramework::ToolsApplicationRequests::GetSelectedEntities); - if (selectedEntities.empty()) - { - return; - } - - // Add all the selected components. - AZ::ComponentTypeList componentsToAdd; - for (auto index : selectedComponents) - { - // We only need to consider the first column, it's important that the data() function that - // returns ComponentDataModel::ClassDataRole also does so for the first column. - if (index.column() != 0) - { - continue; - } - - QVariant classDataVariant = model->data(index, ComponentDataModel::ClassDataRole); - if (classDataVariant.isValid()) - { - const AZ::SerializeContext::ClassData* classData = reinterpret_cast(classDataVariant.value()); - componentsToAdd.push_back(classData->m_typeId); - } - } - - AzToolsFramework::EntityCompositionRequestBus::Broadcast(&AzToolsFramework::EntityCompositionRequests::AddComponentsToEntities, selectedEntities, componentsToAdd); - } -} - - -// ComponentDataModel -////////////////////////////////////////////////////////////////////////// - -ComponentDataModel::ComponentDataModel(QObject* parent) - : QAbstractTableModel(parent) -{ - AZ::SerializeContext* serializeContext = nullptr; - EBUS_EVENT_RESULT(serializeContext, AZ::ComponentApplicationBus, GetSerializeContext); - AZ_Assert(serializeContext, "Failed to acquire application serialize context."); - - serializeContext->EnumerateDerived([this](const AZ::SerializeContext::ClassData* classData, const AZ::Uuid&) -> bool - { - bool allowed = false; - bool hidden = false; - AZStd::string category = "Miscellaneous"; - - if (classData->m_editData) - { - for (const AZ::Edit::ElementData& element : classData->m_editData->m_elements) - { - if (element.m_elementId == AZ::Edit::ClassElements::EditorData) - { - AZStd::string iconPath; - AzToolsFramework::EditorRequestBus::BroadcastResult(iconPath, &AzToolsFramework::EditorRequests::GetComponentTypeEditorIcon, classData->m_typeId); - if (!iconPath.empty()) - { - m_componentIcons[classData->m_typeId] = QIcon(iconPath.c_str()); - } - - for (const AZ::Edit::AttributePair& attribPair : element.m_attributes) - { - if (attribPair.first == AZ::Edit::Attributes::AppearsInAddComponentMenu) - { - if (auto data = azdynamic_cast*>(attribPair.second)) - { - if (data->Get(nullptr) == AZ_CRC("Game")) - { - allowed = true; - } - } - } - else if (attribPair.first == AZ::Edit::Attributes::AddableByUser) - { - // skip this component if user is not allowed to add it directly - if (auto data = azdynamic_cast*>(attribPair.second)) - { - if (!data->Get(nullptr)) - { - hidden = true; - } - } - } - else if (attribPair.first == AZ::Edit::Attributes::Category) - { - if (auto data = azdynamic_cast*>(attribPair.second)) - { - category = data->Get(nullptr); - } - } - } - - break; - } - } - } - - if (allowed && !hidden) - { - m_componentList.push_back(classData); - m_componentMap[category].push_back(classData); - m_categories.insert(category); - } - - return true; - }); - - // we'd like viewport events - AzQtComponents::DragAndDropEventsBus::Handler::BusConnect(AzQtComponents::DragAndDropContexts::EditorViewport); -} - -ComponentDataModel::~ComponentDataModel() -{ - AzQtComponents::DragAndDropEventsBus::Handler::BusDisconnect(); -} - -Qt::ItemFlags ComponentDataModel::flags([[maybe_unused]] const QModelIndex &index) const -{ - return Qt::ItemFlags( - Qt::ItemIsEnabled | - Qt::ItemIsDragEnabled | - Qt::ItemIsDropEnabled | - Qt::ItemIsSelectable); -} - -const AZ::SerializeContext::ClassData* ComponentDataModel::GetClassData(const QModelIndex& index) const -{ - int row = index.row(); - if (row < 0 || row >= m_componentList.size()) - { - return nullptr; - } - - return m_componentList[row]; -} - -const char* ComponentDataModel::GetCategory(const AZ::SerializeContext::ClassData* classData) -{ - if (classData) - { - if (auto editorDataElement = classData->m_editData->FindElementData(AZ::Edit::ClassElements::EditorData)) - { - if (auto categoryAttribute = editorDataElement->FindAttribute(AZ::Edit::Attributes::Category)) - { - if (auto categoryData = azdynamic_cast*>(categoryAttribute)) - { - const char* result = categoryData->Get(nullptr); - if (result) - { - return result; - } - } - } - } - } - - return ""; -} - - -QModelIndex ComponentDataModel::index(int row, int column, const QModelIndex &parent /*= QModelIndex()*/) const -{ - if (row >= rowCount(parent) || column >= columnCount(parent)) - { - return QModelIndex(); - } - - return createIndex(row, column, (void*)(m_componentList[row])); -} - -QModelIndex ComponentDataModel::parent([[maybe_unused]] const QModelIndex &child) const -{ - return QModelIndex(); -} - -int ComponentDataModel::rowCount([[maybe_unused]] const QModelIndex &parent /*= QModelIndex()*/) const -{ - return static_cast(m_componentList.size()); -} - -int ComponentDataModel::columnCount([[maybe_unused]] const QModelIndex &parent /*= QModelIndex()*/) const -{ - return ColumnIndex::Count; -} - -QVariant ComponentDataModel::data(const QModelIndex &index, int role /*= Qt::DisplayRole*/) const -{ - if (index.isValid()) - { - const AZ::SerializeContext::ClassData* classData = m_componentList[index.row()]; - if (!classData) - { - return QVariant(); - } - - switch (role) - { - case ClassDataRole: - if (index.column() == 0) // Only get data for one column - { - return QVariant::fromValue(reinterpret_cast(const_cast(classData))); - } - break; - - case Qt::DisplayRole: - { - if (index.column() == ColumnIndex::Name) - { - return QVariant(classData->m_editData->m_name); - } - else - if (index.column() == ColumnIndex::Category) - { - if (auto editorDataElement = classData->m_editData->FindElementData(AZ::Edit::ClassElements::EditorData)) - { - if (auto categoryAttribute = editorDataElement->FindAttribute(AZ::Edit::Attributes::Category)) - { - if (auto categoryData = azdynamic_cast*>(categoryAttribute)) - { - return QVariant(categoryData->Get(nullptr)); - } - } - } - } - - } - break; - - case Qt::ToolTipRole: - { - return QVariant(classData->m_editData->m_description); - } - - case Qt::DecorationRole: - { - if (index.column() == ColumnIndex::Icon) - { - auto iconIterator = m_componentIcons.find(classData->m_typeId); - if (iconIterator != m_componentIcons.end()) - { - return iconIterator->second; - } - } - } - break; - - default: - break; - } - } - - return QVariant(); -} - -QMimeData* ComponentDataModel::mimeData(const QModelIndexList& indices) const -{ - QModelIndexList list; - - // Filter out columns we are not interested in. - for (const QModelIndex& index : indices) - { - if (index.column() == 0) - { - list.push_back(index); - } - } - - AZStd::vector sortedList; - for (QModelIndex index : list) - { - QVariant classDataVariant = index.data(ComponentDataModel::ClassDataRole); - if (classDataVariant.isValid()) - { - const AZ::SerializeContext::ClassData* classData = reinterpret_cast(classDataVariant.value()); - sortedList.push_back(classData); - } - } - - QMimeData* mimeData = nullptr; - if (!sortedList.empty()) - { - mimeData = AzToolsFramework::ComponentTypeMimeData::Create(sortedList).release(); - } - - return mimeData; -} - -bool ComponentDataModel::CanAcceptDragAndDropEvent(QDropEvent* event, AzQtComponents::DragAndDropContextBase& context) const -{ - using namespace AzToolsFramework; - using namespace AzQtComponents; - - // if a listener with a higher priority already claimed this event, do not touch it. - if ((!event) || (event->isAccepted()) || (!event->mimeData())) - { - return false; - } - - ViewportDragContext* contextVP = azrtti_cast(&context); - if (!contextVP) - { - // not a viewport event. This is for some other GUI such as the main window itself. - return false; - } - - AZStd::vector componentClassDataList; - return AzToolsFramework::ComponentTypeMimeData::Get(event->mimeData(), componentClassDataList); -} - -void ComponentDataModel::DragEnter(QDragEnterEvent* event, AzQtComponents::DragAndDropContextBase& context) -{ - if (CanAcceptDragAndDropEvent(event, context)) - { - event->setDropAction(Qt::CopyAction); - event->setAccepted(true); - // opportunities to show special highlights, or ghosted entities or previews here. - } -} - -void ComponentDataModel::DragMove(QDragMoveEvent* event, AzQtComponents::DragAndDropContextBase& context) -{ - if (CanAcceptDragAndDropEvent(event, context)) - { - event->setDropAction(Qt::CopyAction); - event->setAccepted(true); - // opportunities to update special highlights, or ghosted entities or previews here. - } -} - -void ComponentDataModel::DragLeave(QDragLeaveEvent* /*event*/) -{ - // opportunities to remove ghosted entities or previews here. -} - -void ComponentDataModel::Drop(QDropEvent* event, AzQtComponents::DragAndDropContextBase& context) -{ - using namespace AzToolsFramework; - using namespace AzQtComponents; - - // ALWAYS CHECK - you are not the only one connected to this bus, and someone else may have already - // handled the event or accepted the drop - it might not contain types relevant to you. - // you still get informed about the drop event in case you did some stuff in your gui and need to clean it up. - if (!CanAcceptDragAndDropEvent(event, context)) - { - return; - } - - // note that the above call already checks all the pointers such as event, or whether context is a VP context, mimetype, etc - ViewportDragContext* contextVP = azrtti_cast(&context); - - // we don't get given this action by Qt unless we already returned accepted from one of the other ones (such as drag move of drag enter) - event->setDropAction(Qt::CopyAction); - event->setAccepted(true); - - AzToolsFramework::ScopedUndoBatch undo("Create entity from components"); - const AZStd::string name = AZStd::string::format("Entity%d", GetIEditor()->GetObjectManager()->GetObjectCount()); - - AZ::Entity* newEntity = aznew AZ::Entity(name.c_str()); - if (newEntity) - { - AzToolsFramework::EditorEntityContextRequestBus::Broadcast(&AzToolsFramework::EditorEntityContextRequests::AddRequiredComponents, *newEntity); - auto* transformComponent = newEntity->FindComponent(); - if (transformComponent) - { - transformComponent->SetWorldTM(AZ::Transform::CreateTranslation(contextVP->m_hitLocation)); - } - - // Add the entity to the editor context, which activates it and creates the sandbox object. - AzToolsFramework::EditorEntityContextRequestBus::Broadcast(&AzToolsFramework::EditorEntityContextRequests::AddEditorEntity, newEntity); - - // Prepare undo command last so it captures the final state of the entity. - AzToolsFramework::EntityCreateCommand* command = aznew AzToolsFramework::EntityCreateCommand(static_cast(newEntity->GetId())); - command->Capture(newEntity); - command->SetParent(undo.GetUndoBatch()); - - // Only need to add components to the new entity - AzToolsFramework::EntityIdList entities = { newEntity->GetId() }; - - AZStd::vector componentClassDataList; - AzToolsFramework::ComponentTypeMimeData::Get(event->mimeData(), componentClassDataList); - - AZ::ComponentTypeList componentsToAdd; - for (auto classData : componentClassDataList) - { - if (!classData) - { - continue; - } - - componentsToAdd.push_back(classData->m_typeId); - } - - AzToolsFramework::EntityCompositionRequests::AddComponentsOutcome addedComponentsResult = AZ::Failure(AZStd::string("Failed to call AddComponentsToEntities on EntityCompositionRequestBus")); - AzToolsFramework::EntityCompositionRequestBus::BroadcastResult(addedComponentsResult, &AzToolsFramework::EntityCompositionRequests::AddComponentsToEntities, entities, componentsToAdd); - - ToolsApplicationRequests::Bus::Broadcast(&ToolsApplicationRequests::AddDirtyEntity, newEntity->GetId()); - AzToolsFramework::ToolsApplicationRequestBus::Broadcast(&AzToolsFramework::ToolsApplicationRequests::SetSelectedEntities, entities); - } -} - -AZ::EntityId ComponentDataProxyModel::NewEntityFromSelection(const QModelIndexList& selection) -{ - return CreateEntityFromSelection(selection, this); -} - -AZ::EntityId ComponentDataModel::NewEntityFromSelection(const QModelIndexList& selection) -{ - return CreateEntityFromSelection(selection, this); -} - -bool ComponentDataProxyModel::filterAcceptsRow(int sourceRow, [[maybe_unused]] const QModelIndex &sourceParent) const -{ - if (m_selectedCategory.empty() && !filterRegExp().isValid()) - return true; - - ComponentDataModel* dataModel = static_cast(sourceModel()); - if (sourceRow < 0 || sourceRow >= dataModel->GetComponents().size()) - { - return false; - } - - const AZ::SerializeContext::ClassData* classData = dataModel->GetComponents()[sourceRow]; - if (!classData) - { - return false; - } - - // Get Category - if (!m_selectedCategory.empty()) - { - AZStd::string currentCateogry = ComponentDataModel::GetCategory(classData); - - if (AzFramework::StringFunc::Find(currentCateogry.c_str(), m_selectedCategory.c_str())) - { - return false; - } - } - - if (filterRegExp().isValid()) - { - QString componentName = QString::fromUtf8(classData->m_editData->m_name); - return componentName.contains(filterRegExp()); - } - - return true; -} - -void ComponentDataProxyModel::SetSelectedCategory(const AZStd::string& category) -{ - m_selectedCategory = category; - invalidate(); -} - -void ComponentDataProxyModel::ClearSelectedCategory() -{ - m_selectedCategory.clear(); - invalidate(); -} - -#include "UI/ComponentPalette/moc_ComponentDataModel.cpp" diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/ComponentDataModel.h b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/ComponentDataModel.h deleted file mode 100644 index 2c9cd27a5f..0000000000 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/ComponentDataModel.h +++ /dev/null @@ -1,128 +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 - -#if !defined(Q_MOC_RUN) -#include -#include - -#include -#include - -#include -#include -#include - -#include -#endif - -namespace ComponentDataUtilities -{ - // Given a list of selected components, use the provided model to get the components to add to any selected entities. - void AddComponentsToSelectedEntities(const QModelIndexList& selectedComponents, QAbstractItemModel* model); -} - -class CViewport; - -//! ComponentDataModel -//! Holds the data required to display components in a table, this includes component name, categories, icons. -class ComponentDataModel - : public QAbstractTableModel - , protected AzQtComponents::DragAndDropEventsBus::Handler // its okay if more than one of these is installed, the first one gets it. -{ - Q_OBJECT - -public: - AZ_CLASS_ALLOCATOR(ComponentDataModel, AZ::SystemAllocator, 0); - - using ComponentClassList = AZStd::vector; - using ComponentCategorySet = AZStd::set; - using ComponentClassMap = AZStd::unordered_map>; - using ComponentIconMap = AZStd::unordered_map; - - enum ColumnIndex - { - Icon, - Category, - Name, - Count - }; - - enum CustomRoles - { - ClassDataRole = Qt::UserRole + 1 - }; - - ComponentDataModel(QObject* parent = nullptr); - ~ComponentDataModel() override; - - QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; - QModelIndex parent(const QModelIndex &child) const override; - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - - Qt::ItemFlags flags(const QModelIndex &index) const override; - - QMimeData* mimeData(const QModelIndexList& indexes) const override; - - const AZ::SerializeContext::ClassData* GetClassData(const QModelIndex&) const; - - AZ::EntityId NewEntityFromSelection(const QModelIndexList& selection); - - static const char* GetCategory(const AZ::SerializeContext::ClassData* classData); - - ComponentClassList& GetComponents() { return m_componentList; } - ComponentCategorySet& GetCategories() { return m_categories; } - -protected: - ////////////////////////////////////////////////////////////////////////// - // AzQtComponents::DragAndDropEventsBus::Handler - ////////////////////////////////////////////////////////////////////////// - void DragEnter(QDragEnterEvent* event, AzQtComponents::DragAndDropContextBase& context) override; - void DragMove(QDragMoveEvent* event, AzQtComponents::DragAndDropContextBase& context) override; - void DragLeave(QDragLeaveEvent* event) override; - void Drop(QDropEvent* event, AzQtComponents::DragAndDropContextBase& context) override; - bool CanAcceptDragAndDropEvent(QDropEvent* event, AzQtComponents::DragAndDropContextBase& context) const; - - ComponentClassList m_componentList; - ComponentClassMap m_componentMap; - ComponentIconMap m_componentIcons; - ComponentCategorySet m_categories; -}; - -//! ComponentDataProxyModel -//! FilterProxy for the ComponentDataModel is used along with the search criteria to filter the -//! list of components based on tags and/or selected category. -class ComponentDataProxyModel : public QSortFilterProxyModel -{ - Q_OBJECT - -public: - AZ_CLASS_ALLOCATOR(ComponentDataProxyModel, AZ::SystemAllocator, 0); - - ComponentDataProxyModel(QObject* parent = nullptr) - : QSortFilterProxyModel(parent) - {} - - // Creates a new entity and adds the selected components to it. - // It is specialized here to ensure it uses the correct indices according to the sorted data. - AZ::EntityId NewEntityFromSelection(const QModelIndexList& selection); - - // Filters rows according to the specifed tags and/or selected category - bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; - - // Set the category to filter by. - void SetSelectedCategory(const AZStd::string& category); - void ClearSelectedCategory(); - -protected: - - AZStd::string m_selectedCategory; -}; diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/ComponentPaletteWindow.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/ComponentPaletteWindow.cpp deleted file mode 100644 index 1791301654..0000000000 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/ComponentPaletteWindow.cpp +++ /dev/null @@ -1,116 +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 "ComponentPaletteWindow.h" -#include "ComponentDataModel.h" -#include "FavoriteComponentList.h" -#include "FilteredComponentList.h" -#include "CategoriesList.h" - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -ComponentPaletteWindow::ComponentPaletteWindow(QWidget* parent) - : QMainWindow(parent) -{ - Init(); -} - -void ComponentPaletteWindow::Init() -{ - layout()->setSizeConstraint(QLayout::SetMinimumSize); - - QVBoxLayout* layout = new QVBoxLayout(); - layout->setSizeConstraint(QLayout::SetMinimumSize); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(0); - - QHBoxLayout* gridLayout = new QHBoxLayout(nullptr); - gridLayout->setSizeConstraint(QLayout::SetMaximumSize); - gridLayout->setContentsMargins(0, 0, 0, 0); - gridLayout->setSpacing(0); - - m_filterWidget = new AzToolsFramework::SearchCriteriaWidget(this); - - QStringList tags; - tags << tr("name"); - m_filterWidget->SetAcceptedTags(tags, tags[0]); - layout->addLayout(gridLayout, 1); - - // Left Panel - QVBoxLayout* leftPaneLayout = new QVBoxLayout(this); - - // Favorites - leftPaneLayout->addWidget(new QLabel(tr("Favorites"))); - leftPaneLayout->addWidget(new QLabel(tr("Drag components here to add favorites."))); - FavoritesList* favorites = new FavoritesList(); - favorites->Init(); - leftPaneLayout->addWidget(favorites); - - // Categories - m_categoryListWidget = new ComponentCategoryList(); - m_categoryListWidget->Init(); - leftPaneLayout->addWidget(m_categoryListWidget); - gridLayout->addLayout(leftPaneLayout); - - // Right Panel - QVBoxLayout* rightPanelLayout = new QVBoxLayout(this); - gridLayout->addLayout(rightPanelLayout); - - // Component list - m_componentListWidget = new FilteredComponentList(this); - m_componentListWidget->Init(); - - rightPanelLayout->addWidget(new QLabel(tr("Components"))); - rightPanelLayout->addWidget(m_filterWidget, 0, Qt::AlignTop); - rightPanelLayout->addWidget(m_componentListWidget); - - // The main window - QWidget* window = new QWidget(); - window->setLayout(layout); - setCentralWidget(window); - - connect(m_categoryListWidget, &ComponentCategoryList::OnCategoryChange, m_componentListWidget, &FilteredComponentList::SetCategory); - connect(m_filterWidget, &AzToolsFramework::SearchCriteriaWidget::SearchCriteriaChanged, m_componentListWidget, &FilteredComponentList::SearchCriteriaChanged); - -} - -void ComponentPaletteWindow::keyPressEvent(QKeyEvent* event) -{ - if (event->modifiers().testFlag(Qt::ControlModifier) && event->key() == Qt::Key_F) - { - m_filterWidget->SelectTextEntryBox(); - } - else - { - QMainWindow::keyPressEvent(event); - } -} - -void ComponentPaletteWindow::RegisterViewClass() -{ - using namespace AzToolsFramework; - - ViewPaneOptions options; - options.canHaveMultipleInstances = true; - RegisterViewPane("Component Palette", LyViewPane::CategoryOther, options); -} - -#include diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/ComponentPaletteWindow.h b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/ComponentPaletteWindow.h deleted file mode 100644 index f662f69342..0000000000 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/ComponentPaletteWindow.h +++ /dev/null @@ -1,59 +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 - -#if !defined(Q_MOC_RUN) -#include -#include -#include -#endif - -namespace AzToolsFramework -{ - class SearchCriteriaWidget; -} - -class ComponentCategoryList; -class FilteredComponentList; -class ComponentDataModel; - -//! ComponentPaletteWindow -//! Provides a window with controls related to the Component Entity system. It provides an intuitive and organized -//! set of controls to display, sort, filter components. It provides mechanisms for creating entities by dragging -//! and dropping components into the viewport as well as from context menus. -class ComponentPaletteWindow - : public QMainWindow -{ - Q_OBJECT - -public: - - explicit ComponentPaletteWindow(QWidget* parent = 0); - - void Init(); - - static const GUID& GetClassID() - { - // {4236998F-1138-466D-9DF5-6533BFA1DFCA} - static const GUID guid = - { - 0x4236998F, 0x1138, 0x466D, { 0x9D, 0xF5, 0x65, 0x33, 0xBF, 0xA1, 0xDF, 0xCA } - }; - return guid; - } - - static void RegisterViewClass(); - -protected: - ComponentCategoryList* m_categoryListWidget; - FilteredComponentList* m_componentListWidget; - AzToolsFramework::SearchCriteriaWidget* m_filterWidget; - - void keyPressEvent(QKeyEvent* event) override; -}; diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/FavoriteComponentList.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/FavoriteComponentList.cpp deleted file mode 100644 index 41eed6f93f..0000000000 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/FavoriteComponentList.cpp +++ /dev/null @@ -1,392 +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 "FavoriteComponentList.h" -#include -#include -#include - -#include -#include - -#include -#include - -// FavoritesList -////////////////////////////////////////////////////////////////////////// - -FavoritesList::FavoritesList(QWidget* parent /*= nullptr*/) - : FilteredComponentList(parent) -{ -} - -FavoritesList::~FavoritesList() -{ - FavoriteComponentListRequestBus::Handler::BusDisconnect(); -} - -void FavoritesList::Init() -{ - FavoriteComponentListRequestBus::Handler::BusConnect(); - - FavoritesDataModel* favoritesDataModel = new FavoritesDataModel(this); - - setModel(favoritesDataModel); - - horizontalHeader()->setSectionResizeMode(ComponentDataModel::ColumnIndex::Name, QHeaderView::Stretch); - - setShowGrid(false); - - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - setSelectionMode(QAbstractItemView::SelectionMode::ExtendedSelection); - setStyleSheet("QTableView { selection-background-color: rgba(255,255,255,0.2); }"); - setGridStyle(Qt::PenStyle::NoPen); - verticalHeader()->hide(); - horizontalHeader()->hide(); - setSelectionBehavior(QAbstractItemView::SelectionBehavior::SelectRows); - setShowGrid(false); - setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); - setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); - - setColumnWidth(ComponentDataModel::ColumnIndex::Icon, 32); - hideColumn(ComponentDataModel::ColumnIndex::Category); - - setDragDropMode(QAbstractItemView::DragDrop); - setAcceptDrops(true); - - horizontalHeader()->setSectionResizeMode(ComponentDataModel::ColumnIndex::Icon, QHeaderView::ResizeToContents); - setColumnWidth(ComponentDataModel::ColumnIndex::Icon, 32); - - horizontalHeader()->setSectionResizeMode(ComponentDataModel::ColumnIndex::Category, QHeaderView::Stretch); - setColumnWidth(ComponentDataModel::ColumnIndex::Category, 90); - - // Context menu - setContextMenuPolicy(Qt::CustomContextMenu); - connect(this, &QWidget::customContextMenuRequested, this, &FavoritesList::ShowContextMenu); -} - -void FavoritesList::ShowContextMenu(const QPoint& pos) -{ - // Only show if a level is loaded - if (!GetIEditor() || GetIEditor()->IsInGameMode()) - { - return; - } - - if ( model()->rowCount() == 0) - { - return; - } - - QMenu contextMenu(tr("Context menu"), this); - - QAction actionNewEntity(tr("Make entity with selected favorites"), this); - QAction actionAddToSelection(this); - if (GetIEditor()->GetDocument()->IsDocumentReady()) - { - QObject::connect(&actionNewEntity, &QAction::triggered, this, [&] { ContextMenu_NewEntity(); }); - contextMenu.addAction(&actionNewEntity); - - AzToolsFramework::EntityIdList selectedEntities; - EBUS_EVENT_RESULT(selectedEntities, AzToolsFramework::ToolsApplicationRequests::Bus, GetSelectedEntities); - - if (!selectedEntities.empty()) - { - QString addToSelection = selectedEntities.size() > 1 ? tr("Add to selected entities") : tr("Add to selected entity"); - actionAddToSelection.setText(addToSelection); - - QObject::connect(&actionAddToSelection, &QAction::triggered, this, [&] { ContextMenu_AddToSelectedEntities(); }); - contextMenu.addAction(&actionAddToSelection); - } - - contextMenu.addSeparator(); - } - - QAction action(tr("Remove"), this); - QObject::connect(&action, &QAction::triggered, this, [&] { ContextMenu_RemoveSelectedFavorites(); }); - contextMenu.addAction(&action); - - contextMenu.exec(mapToGlobal(pos)); -} - -void FavoritesList::ContextMenu_RemoveSelectedFavorites() -{ - FavoritesDataModel* dataModel = qobject_cast(model()); - if (!selectedIndexes().empty()) - { - dataModel->Remove(selectedIndexes()); - } -} - -void FavoritesList::rowsInserted([[maybe_unused]] const QModelIndex& parent, [[maybe_unused]] int start, [[maybe_unused]] int end) -{ - resizeRowToContents(0); -} - -void FavoritesList::AddFavorites(const AZStd::vector& classDataContainer) -{ - for (const AZ::SerializeContext::ClassData* classData : classDataContainer) - { - if (classData) - { - FavoritesDataModel* dataModel = qobject_cast(model()); - dataModel->AddFavorite(classData); - } - } -} - -void FavoritesList::dragEnterEvent(QDragEnterEvent* event) -{ - if (event->mimeData()->hasFormat(AzToolsFramework::ComponentTypeMimeData::GetMimeType())) - { - event->acceptProposedAction(); - } -} - -void FavoritesList::dragMoveEvent(QDragMoveEvent* event) -{ - if (event->source() == this) - { - event->ignore(); - } - else - { - event->accept(); - } -} - -// FavoritesDataModel -////////////////////////////////////////////////////////////////////////// - -int FavoritesDataModel::rowCount([[maybe_unused]] const QModelIndex &parent /*= QModelIndex()*/) const -{ - return m_favorites.size(); -} - -int FavoritesDataModel::columnCount([[maybe_unused]] const QModelIndex &parent /*= QModelIndex()*/) const -{ - return ColumnIndex::Count; -} - -void FavoritesDataModel::SaveState() -{ - AZStd::vector favorites; - for (const AZ::SerializeContext::ClassData* classData : m_favorites) - { - favorites.push_back(classData->m_typeId); - } - m_settings->SetFavorites(AZStd::move(favorites)); - - - // Write the settings to file... - AZ::SerializeContext* serializeContext = nullptr; - EBUS_EVENT_RESULT(serializeContext, AZ::ComponentApplicationBus, GetSerializeContext); - AZ_Assert(serializeContext, "Serialize Context is null!"); - - char settingsPath[AZ_MAX_PATH_LEN] = { 0 }; - AZ::IO::FileIOBase::GetInstance()->ResolvePath(ComponentPaletteSettings::GetSettingsFile(), settingsPath, AZ_MAX_PATH_LEN); - - bool result = m_provider.Save(settingsPath, serializeContext); - (void)result; - AZ_Warning("ComponentPaletteSettings", result, "Failed to Save the Component Palette Settings!"); -} - -void FavoritesDataModel::LoadState() -{ - // It is necessary to Load the settings file *before* you call UserSettings::CreateFind! - AZ::SerializeContext* serializeContext = nullptr; - EBUS_EVENT_RESULT(serializeContext, AZ::ComponentApplicationBus, GetSerializeContext); - AZ_Assert(serializeContext, "Serialize Context is null!"); - - char settingsPath[AZ_MAX_PATH_LEN] = { 0 }; - AZ::IO::FileIOBase::GetInstance()->ResolvePath(ComponentPaletteSettings::GetSettingsFile(), settingsPath, AZ_MAX_PATH_LEN); - - bool result = m_provider.Load(settingsPath, serializeContext); - (void)result; - - - // Create (if no file was found) or find the settings, this will populate the m_settings->m_favorites list. - m_settings = AZ::UserSettings::CreateFind(AZ_CRC("ComponentPaletteSettings", 0x481d355b), m_providerId); - - // Add favorites to the data model from loaded settings - for (const AZ::Uuid& favorite : m_settings->m_favorites) - { - const AZ::SerializeContext::ClassData* classData = serializeContext->FindClassData(favorite); - if (classData) - { - AddFavorite(classData, false); - } - } -} - -void FavoritesDataModel::Remove(const QModelIndexList& indices) -{ - beginResetModel(); - - auto newFavorites = m_favorites; - - // swap here - for (auto index : indices) - { - // we're only dealing with columns and they're the only thing with class data anyways - if (index.column() == 0) - { - QVariant classDataVariant = index.data(ComponentDataModel::ClassDataRole); - if (classDataVariant.isValid()) - { - const AZ::SerializeContext::ClassData* classData = reinterpret_cast(classDataVariant.value()); - newFavorites.removeAll(classData); - - AZ_TracePrintf("Debug", "Removing: %s\n", classData->m_editData->m_name); - } - } - } - - m_favorites.swap(newFavorites); - - endResetModel(); - - SaveState(); -} - -QModelIndex FavoritesDataModel::index(int row, int column, const QModelIndex &parent) const -{ - if (!hasIndex(row, column, parent)) - { - return QModelIndex(); - } - - if (row >= rowCount(parent) || column >= columnCount(parent)) - { - return QModelIndex(); - } - - return createIndex(row, column, (void*)(m_favorites[row])); -} - -QVariant FavoritesDataModel::data(const QModelIndex &index, int role /*= Qt::DisplayRole*/) const -{ - if (!index.isValid()) - { - return QVariant(); - } - - const AZ::SerializeContext::ClassData* classData = m_favorites[index.row()]; - if (!classData) - { - return QVariant(); - } - - switch (role) - { - case Qt::DisplayRole: - { - if (index.column() == ComponentDataModel::ColumnIndex::Name) - { - if (m_favorites.empty()) - { - return QVariant(tr("You have 0 favorites.\nDrag some components here.")); - } - - return QVariant(classData->m_editData->m_name); - } - } - break; - - case Qt::DecorationRole: - { - if (index.column() == ColumnIndex::Icon) - { - const AZ::SerializeContext::ClassData* iconClassData = m_favorites[index.row()]; - auto iconIterator = m_componentIcons.find(iconClassData->m_typeId); - if (iconIterator != m_componentIcons.end()) - { - return iconIterator->second; - } - - return QVariant(); - } - } - break; - - case ClassDataRole: - if (index.column() == 0) // Only get data for one column - { - return QVariant::fromValue(reinterpret_cast(const_cast(classData))); - } - break; - - default: - break; - } - - return ComponentDataModel::data(index, role); - -} - -void FavoritesDataModel::SetSavedStateKey([[maybe_unused]] AZ::u32 key) -{ -} - -FavoritesDataModel::FavoritesDataModel(QWidget* parent /*= nullptr*/) - : ComponentDataModel(parent) - , m_providerId(AZ_CRC("ComponentPaletteSettingsProviderId")) -{ - m_provider.Activate(m_providerId); - LoadState(); -} - -FavoritesDataModel::~FavoritesDataModel() -{ - m_provider.Deactivate(); -} - -void FavoritesDataModel::AddFavorite(const AZ::SerializeContext::ClassData* classData, bool updateSettings) -{ - beginResetModel(); - - if (m_favorites.indexOf(classData) < 0) - { - m_favorites.push_back(classData); - } - - endResetModel(); - - if (updateSettings) - { - SaveState(); - } -} - -bool FavoritesDataModel::dropMimeData(const QMimeData *data, Qt::DropAction action, [[maybe_unused]] int row, [[maybe_unused]] int column, [[maybe_unused]] const QModelIndex &parent) -{ - if (action == Qt::IgnoreAction) - { - return true; - } - - if (data && data->hasFormat(AzToolsFramework::ComponentTypeMimeData::GetMimeType())) - { - AzToolsFramework::ComponentTypeMimeData::ClassDataContainer classDataContainer; - AzToolsFramework::ComponentTypeMimeData::Get(data, classDataContainer); - - for (const AZ::SerializeContext::ClassData* classData : classDataContainer) - { - if (classData) - { - AddFavorite(classData); - } - } - - return true; - } - - return false; -} - -#include diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/FavoriteComponentList.h b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/FavoriteComponentList.h deleted file mode 100644 index 2bd2d83e04..0000000000 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/FavoriteComponentList.h +++ /dev/null @@ -1,117 +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 - -#if !defined(Q_MOC_RUN) -#include "ComponentDataModel.h" -#include "FilteredComponentList.h" -#include "ComponentPaletteSettings.h" - -#include -#include -#include -#include -#endif - -//! FavoriteComponentListRequest -//! Bus that provides a way for external features to record favorites -class FavoriteComponentListRequest : public AZ::EBusTraits -{ -public: - virtual void AddFavorites(const AZStd::vector&) = 0; -}; - -using FavoriteComponentListRequestBus = AZ::EBus; - - -//! FavoritesDataModel -//! Stores the list of component class data to display in the favorites control, offers persistence through user settings. -class FavoritesDataModel - : public ComponentDataModel -{ - Q_OBJECT - -public: - - AZ_CLASS_ALLOCATOR(FavoritesDataModel, AZ::SystemAllocator, 0); - - FavoritesDataModel(QWidget* parent = nullptr); - ~FavoritesDataModel() override; - - //! Add a favorite component - //! \param classData The ClassData information for the component to store as favorite - //! \param updateSettings Optional parameter used to determine if the persistent settings need to be updated. - void AddFavorite(const AZ::SerializeContext::ClassData* classData, bool updateSettings = true); - - //! Remove all the specified items from the table - //! \param indices List of indices to remove from favorites - void Remove(const QModelIndexList& indices); - - //! Save the list of favorite components to user settings - void SaveState(); - - //! Load the list of favorite components from user settings - void LoadState(); - -protected: - - void SetSavedStateKey(AZ::u32 key); - - // Qt handlers - QModelIndex index(int row, int column, const QModelIndex &parent) const override; - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; - - // List of component class data - QList m_favorites; - - // The Palette settings and provider information for saving out the Favorites list - AZStd::intrusive_ptr m_settings; - AZ::UserSettingsProvider m_provider; - AZ::u32 m_providerId; -}; - - -//! FavoritesList -//! User customized list of favorite components, provides persistence. -class FavoritesList - : public FilteredComponentList - , FavoriteComponentListRequestBus::Handler -{ - Q_OBJECT - -public: - - explicit FavoritesList(QWidget* parent = nullptr); - ~FavoritesList() override; - - void Init() override; - -protected: - - ////////////////////////////////////////////////////////////////////////// - // FavoriteComponentListRequestBus - void AddFavorites(const AZStd::vector& classDataContainer) override; - ////////////////////////////////////////////////////////////////////////// - - void rowsInserted(const QModelIndex& parent, int start, int end) override; - - // Context menu handlers - void ShowContextMenu(const QPoint&); - void ContextMenu_RemoveSelectedFavorites(); - - // Validate data being dragged in - void dragEnterEvent(QDragEnterEvent * event) override; - void dragMoveEvent(QDragMoveEvent* event) override; - - //! Handler used when dropping PaletteItems into the Viewport. - static void DragDropHandler(CViewport* viewport, int ptx, int pty, void* custom); -}; diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/FilteredComponentList.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/FilteredComponentList.cpp deleted file mode 100644 index 2431653e36..0000000000 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/FilteredComponentList.cpp +++ /dev/null @@ -1,264 +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 "ComponentDataModel.h" -#include "FavoriteComponentList.h" -#include "FilteredComponentList.h" - -#include "CryCommon/MathConversion.h" -#include "Editor/IEditor.h" -#include "Editor/ViewManager.h" -#include - -#include - -#include - -void FilteredComponentList::Init() -{ - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - setDragDropMode(QAbstractItemView::DragDropMode::DragOnly); - setDragEnabled(true); - - setSelectionMode(QAbstractItemView::SelectionMode::ExtendedSelection); - setStyleSheet("QTreeWidget { selection-background-color: rgba(255,255,255,0.2); }"); - setGridStyle(Qt::PenStyle::NoPen); - verticalHeader()->hide(); - horizontalHeader()->hide(); - setSelectionBehavior(QAbstractItemView::SelectionBehavior::SelectRows); - setAcceptDrops(false); - - m_componentDataModel = new ComponentDataModel(this); - ComponentDataProxyModel* componentDataProxyModel = new ComponentDataProxyModel(this); - componentDataProxyModel->setSourceModel(m_componentDataModel); - setModel(componentDataProxyModel); - - QHeaderView* horizontalHeaderView = horizontalHeader(); - horizontalHeaderView->setSectionResizeMode(ComponentDataModel::ColumnIndex::Icon, QHeaderView::ResizeToContents); - horizontalHeaderView->setSectionResizeMode(ComponentDataModel::ColumnIndex::Name, QHeaderView::Stretch); - - setColumnWidth(ComponentDataModel::ColumnIndex::Icon, 32); - setShowGrid(false); - - setColumnWidth(ComponentDataModel::ColumnIndex::Name, 90); - setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); - - sortByColumn(ComponentDataModel::ColumnIndex::Name, Qt::AscendingOrder); - hideColumn(ComponentDataModel::ColumnIndex::Category); - - connect(model(), &QAbstractItemModel::rowsInserted, this, &FilteredComponentList::rowsInserted); - connect(model(), &QAbstractItemModel::rowsRemoved, this, &FilteredComponentList::rowsAboutToBeRemoved); - - connect(model(), SIGNAL(modelReset()), SLOT(modelReset())); - - - // Context menu - setContextMenuPolicy(Qt::CustomContextMenu); - connect(this, &QWidget::customContextMenuRequested, this, &FilteredComponentList::ShowContextMenu); -} - -void FilteredComponentList::ContextMenu_NewEntity() -{ - AZ::EntityId entityId; - - auto proxyDataModel = qobject_cast(model()); - if (proxyDataModel) - { - entityId = proxyDataModel->NewEntityFromSelection(selectedIndexes()); - } - else - { - auto dataModel = qobject_cast(model()); - if (dataModel) - { - entityId = dataModel->NewEntityFromSelection(selectedIndexes()); - } - } -} - - -void FilteredComponentList::ContextMenu_AddToFavorites() -{ - AZStd::vector componentsToAdd; - for (auto index : selectedIndexes()) - { - QVariant classDataVariant = index.data(ComponentDataModel::ClassDataRole); - if (classDataVariant.isValid()) - { - auto classData = reinterpret_cast(classDataVariant.value()); - componentsToAdd.push_back(classData); - } - } - - if (!componentsToAdd.empty()) - { - EBUS_EVENT(FavoriteComponentListRequestBus, AddFavorites, componentsToAdd); - } -} - -void FilteredComponentList::ContextMenu_AddToSelectedEntities() -{ - ComponentDataUtilities::AddComponentsToSelectedEntities(selectedIndexes(), model()); -} - -void FilteredComponentList::ShowContextMenu(const QPoint& pos) -{ - QMenu contextMenu(tr("Context menu"), this); - - QAction actionNewEntity(tr("Create new entity with selected components"), this); - if (GetIEditor()->GetDocument()->IsDocumentReady()) - { - QObject::connect(&actionNewEntity, &QAction::triggered, this, [this] { ContextMenu_NewEntity(); }); - contextMenu.addAction(&actionNewEntity); - } - - QAction actionAddFavorite(tr("Add to favorites"), this); - QObject::connect(&actionAddFavorite, &QAction::triggered, this, [this] { ContextMenu_AddToFavorites(); }); - contextMenu.addAction(&actionAddFavorite); - - QAction actionAddToSelection(this); - if (GetIEditor()->GetDocument()->IsDocumentReady()) - { - AzToolsFramework::EntityIdList selectedEntities; - EBUS_EVENT_RESULT(selectedEntities, AzToolsFramework::ToolsApplicationRequests::Bus, GetSelectedEntities); - - if (!selectedEntities.empty()) - { - QString addToSelection = selectedEntities.size() > 1 ? tr("Add to selected entities") : tr("Add to selected entity"); - - actionAddToSelection.setText(addToSelection); - QObject::connect(&actionAddToSelection, &QAction::triggered, this, [this] { ContextMenu_AddToSelectedEntities(); }); - contextMenu.addAction(&actionAddToSelection); - } - } - // TODO: Requires information panel implementation LMBR-28174 - //QAction actionHelp(tr("Help"), this); - //QObject::connect(&actionHelp, &QAction::triggered, this, [&] {}); - //contextMenu.addAction(&actionHelp); - - contextMenu.exec(mapToGlobal(pos)); -} - -void FilteredComponentList::modelReset() -{ - // Ensure that the category column is hidden - hideColumn(ComponentDataModel::ColumnIndex::Category); -} - -FilteredComponentList::FilteredComponentList(QWidget* parent /*= nullptr*/) - : QTableView(parent) -{ -} - -FilteredComponentList::~FilteredComponentList() -{ -} - -void FilteredComponentList::SearchCriteriaChanged(QStringList& criteriaList, AzToolsFramework::FilterOperatorType filterOperator) -{ - setUpdatesEnabled(false); - - auto dataModel = qobject_cast(model()); - if (dataModel) - { - // Go through the list of items and show/hide as needed due to filter. - QString filter; - for (const auto& criteria : criteriaList) - { - QString tag, text; - AzToolsFramework::SearchCriteriaButton::SplitTagAndText(criteria, tag, text); - AppendFilter(filter, text, filterOperator); - } - - dataModel->setFilterRegExp(QRegExp(filter, Qt::CaseSensitivity::CaseInsensitive)); - } - - setUpdatesEnabled(true); -} - -void FilteredComponentList::SetCategory(const char* category) -{ - auto dataModel = qobject_cast(model()); - if (dataModel) - { - if (!category || category[0] == 0 || azstricmp(category, "All") == 0) - { - dataModel->ClearSelectedCategory(); - } - else - { - dataModel->SetSelectedCategory(category); - } - } - - // Note: this ensures the category column remains hidden - hideColumn(ComponentDataModel::ColumnIndex::Category); -} - -void FilteredComponentList::BuildFilter(QStringList& criteriaList, AzToolsFramework::FilterOperatorType filterOperator) -{ - ClearFilterRegExp(); - - for (const auto& criteria : criteriaList) - { - QString tag, text; - AzToolsFramework::SearchCriteriaButton::SplitTagAndText(criteria, tag, text); - if (tag.isEmpty()) - { - tag = "null"; - } - - QString filter = m_filtersRegExp[tag.toStdString().c_str()].pattern(); - - AppendFilter(filter, text, filterOperator); - - SetFilterRegExp(tag.toStdString().c_str(), QRegExp(filter, Qt::CaseInsensitive)); - } -} - -void FilteredComponentList::AppendFilter(QString& filter, const QString& text, AzToolsFramework::FilterOperatorType filterOperator) -{ - if (filterOperator == AzToolsFramework::FilterOperatorType::Or) - { - if (filter.isEmpty()) - { - filter = text; - } - else - { - filter += "|" + text; - } - } - else if (filterOperator == AzToolsFramework::FilterOperatorType::And) - { - //using lookaheads to produce an "and" effect. - filter += "(?=.*" + text + ")"; - } -} - -void FilteredComponentList::SetFilterRegExp(const AZStd::string& filterType, const QRegExp& regExp) -{ - m_filtersRegExp[filterType] = regExp; -} - -void FilteredComponentList::ClearFilterRegExp(const AZStd::string& filterType /*= AZStd::string()*/) -{ - if (filterType.empty()) - { - for (auto& it : m_filtersRegExp) - { - it.second = QRegExp(); - } - } - else - { - m_filtersRegExp[filterType] = QRegExp(); - } -} - -#include diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/FilteredComponentList.h b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/FilteredComponentList.h deleted file mode 100644 index 113128fbcc..0000000000 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/ComponentPalette/FilteredComponentList.h +++ /dev/null @@ -1,68 +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 - -#if !defined(Q_MOC_RUN) -#include -#include - -#include -#include -#include -#include "ComponentDataModel.h" -#endif - -namespace AZ -{ - class SerializeContext; - class ClassData; -} - -class ComponentDataModel; - -//! FilteredComponentList -//! Provides a list of components that can be filtered according to search criteria provided and/or from -//! a category selection control. -class FilteredComponentList - : public QTableView -{ - Q_OBJECT - -public: - - explicit FilteredComponentList(QWidget* parent = nullptr); - - ~FilteredComponentList() override; - - virtual void Init(); - - void SearchCriteriaChanged(QStringList& criteriaList, AzToolsFramework::FilterOperatorType filterOperator); - - void SetCategory(const char* category); - -protected: - - // Filtering support - void BuildFilter(QStringList& criteriaList, AzToolsFramework::FilterOperatorType filterOperator); - void AppendFilter(QString& filter, const QString& text, AzToolsFramework::FilterOperatorType filterOperator); - void SetFilterRegExp(const AZStd::string& filterType, const QRegExp& regExp); - void ClearFilterRegExp(const AZStd::string& filterType = AZStd::string()); - - // Context menu handlers - void ShowContextMenu(const QPoint&); - void ContextMenu_NewEntity(); - void ContextMenu_AddToFavorites(); - void ContextMenu_AddToSelectedEntities(); - - void modelReset(); - - AzToolsFramework::FilterByCategoryMap m_filtersRegExp; - ComponentDataModel* m_componentDataModel; - -}; diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/componententityeditorplugin_files.cmake b/Code/Editor/Plugins/ComponentEntityEditorPlugin/componententityeditorplugin_files.cmake index c663926618..28f96de862 100644 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/componententityeditorplugin_files.cmake +++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/componententityeditorplugin_files.cmake @@ -20,19 +20,7 @@ set(FILES UI/QComponentEntityEditorOutlinerWindow.cpp UI/AssetCatalogModel.h UI/AssetCatalogModel.cpp - UI/ComponentPalette/CategoriesList.h - UI/ComponentPalette/CategoriesList.cpp - UI/ComponentPalette/ComponentDataModel.h - UI/ComponentPalette/ComponentDataModel.cpp UI/ComponentPalette/ComponentPaletteSettings.h - UI/ComponentPalette/ComponentPaletteWindow.h - UI/ComponentPalette/ComponentPaletteWindow.cpp - UI/ComponentPalette/FavoriteComponentList.h - UI/ComponentPalette/FavoriteComponentList.cpp - UI/ComponentPalette/FilteredComponentList.h - UI/ComponentPalette/FilteredComponentList.cpp - UI/ComponentPalette/InformationPanel.h - UI/ComponentPalette/InformationPanel.cpp UI/Outliner/OutlinerDisplayOptionsMenu.h UI/Outliner/OutlinerDisplayOptionsMenu.cpp UI/Outliner/OutlinerTreeView.hxx diff --git a/Code/Editor/Plugins/EditorAssetImporter/AssetImporterDocument.cpp b/Code/Editor/Plugins/EditorAssetImporter/AssetImporterDocument.cpp index 105a5b4954..4c65affd83 100644 --- a/Code/Editor/Plugins/EditorAssetImporter/AssetImporterDocument.cpp +++ b/Code/Editor/Plugins/EditorAssetImporter/AssetImporterDocument.cpp @@ -7,7 +7,6 @@ */ #include -#include #include #include #include diff --git a/Code/Editor/Plugins/EditorCommon/Cry_LegacyPhysUtils.h b/Code/Editor/Plugins/EditorCommon/Cry_LegacyPhysUtils.h deleted file mode 100644 index b3735fa4b6..0000000000 --- a/Code/Editor/Plugins/EditorCommon/Cry_LegacyPhysUtils.h +++ /dev/null @@ -1,700 +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 - * - */ - -// Copied utils functions from CryPhysics that are used by non-physics systems -// This functions will be eventually removed, DO *NOT* use these functions -// TO-DO: Re-implement users using new code -// LY-109806 - -#pragma once - -#include "Cry_Math.h" - -namespace LegacyCryPhysicsUtils -{ - namespace polynomial_tpl_IMPL - { - template - class polynomial_tpl - { - public: - explicit polynomial_tpl() { denom = (ftype)1; }; - explicit polynomial_tpl(ftype op) { zero(); data[degree] = op; } - AZ_FORCE_INLINE polynomial_tpl& zero() - { - for (int i = 0; i <= degree; i++) - { - data[i] = 0; - } - denom = (ftype)1; - return *this; - } - polynomial_tpl(const polynomial_tpl& src) { *this = src; } - polynomial_tpl& operator=(const polynomial_tpl& src) - { - denom = src.denom; - for (int i = 0; i <= degree; i++) - { - data[i] = src.data[i]; - } - return *this; - } - template - AZ_FORCE_INLINE polynomial_tpl& operator=(const polynomial_tpl& src) - { - int i; - denom = src.denom; - for (i = 0; i <= min(degree, degree1); i++) - { - data[i] = src.data[i]; - } - for (; i < degree; i++) - { - data[i] = 0; - } - return *this; - } - AZ_FORCE_INLINE polynomial_tpl& set(ftype* pdata) - { - for (int i = 0; i <= degree; i++) - { - data[degree - i] = pdata[i]; - } - return *this; - } - - AZ_FORCE_INLINE ftype& operator[](int idx) { return data[idx]; } - - void calc_deriviative(polynomial_tpl& deriv, int curdegree = degree) const; - - AZ_FORCE_INLINE polynomial_tpl& fixsign() - { - ftype sg = sgnnz(denom); - denom *= sg; - for (int i = 0; i <= degree; i++) - { - data[i] *= sg; - } - return *this; - } - - int findroots(ftype start, ftype end, ftype* proots, int nIters = 20, int curdegree = degree, bool noDegreeCheck = false) const; - int nroots(ftype start, ftype end) const; - - AZ_FORCE_INLINE ftype eval(ftype x) const - { - ftype res = 0; - for (int i = degree; i >= 0; i--) - { - res = res * x + data[i]; - } - return res; - } - AZ_FORCE_INLINE ftype eval(ftype x, int subdegree) const - { - ftype res = data[subdegree]; - for (int i = subdegree - 1; i >= 0; i--) - { - res = res * x + data[i]; - } - return res; - } - - AZ_FORCE_INLINE polynomial_tpl& operator+=(ftype op) { data[0] += op * denom; return *this; } - AZ_FORCE_INLINE polynomial_tpl& operator-=(ftype op) { data[0] -= op * denom; return *this; } - AZ_FORCE_INLINE polynomial_tpl operator*(ftype op) const - { - polynomial_tpl res; - res.denom = denom; - for (int i = 0; i <= degree; i++) - { - res.data[i] = data[i] * op; - } - return res; - } - AZ_FORCE_INLINE polynomial_tpl& operator*=(ftype op) - { - for (int i = 0; i <= degree; i++) - { - data[i] *= op; - } - return *this; - } - AZ_FORCE_INLINE polynomial_tpl operator/(ftype op) const - { - polynomial_tpl res = *this; - res.denom = denom * op; - return res; - } - AZ_FORCE_INLINE polynomial_tpl& operator/=(ftype op) { denom *= op; return *this; } - - AZ_FORCE_INLINE polynomial_tpl sqr() const { return *this * *this; } - - ftype denom; - ftype data[degree + 1]; - }; - - template - struct tagPolyE - { - inline static ftype polye() { return (ftype)1E-10; } - }; - - template<> - inline float tagPolyE::polye() { return 1e-6f; } - - template - inline ftype polye() { return tagPolyE::polye(); } - - // Don't use this macro; use AZStd::max instead. This is only here to make the template const arguments below readable - // and because Visual Studio 2013 doesn't have a const_expr version of std::max - #define deprecated_degmax(degree1, degree2) (((degree1) > (degree2)) ? (degree1) : (degree2)) - - template - AZ_FORCE_INLINE polynomial_tpl operator+(const polynomial_tpl& pn, ftype op) - { - polynomial_tpl res = pn; - res.data[0] += op * res.denom; - return res; - } - template - AZ_FORCE_INLINE polynomial_tpl operator-(const polynomial_tpl& pn, ftype op) - { - polynomial_tpl res = pn; - res.data[0] -= op * res.denom; - return res; - } - - template - AZ_FORCE_INLINE polynomial_tpl operator+(ftype op, const polynomial_tpl& pn) - { - polynomial_tpl res = pn; - res.data[0] += op * res.denom; - return res; - } - template - AZ_FORCE_INLINE polynomial_tpl operator-(ftype op, const polynomial_tpl& pn) - { - polynomial_tpl res = pn; - res.data[0] -= op * res.denom; - for (int i = 0; i <= degree; i++) - { - res.data[i] = -res.data[i]; - } - return res; - } - template - polynomial_tpl AZ_FORCE_INLINE psqr(const polynomial_tpl& op) { return op * op; } - - template - AZ_FORCE_INLINE polynomial_tpl operator+(const polynomial_tpl& op1, const polynomial_tpl& op2) - { - polynomial_tpl res; - int i; - for (i = 0; i <= min(degree1, degree2); i++) - { - res.data[i] = op1.data[i] * op2.denom + op2.data[i] * op1.denom; - } - for (; i <= degree1; i++) - { - res.data[i] = op1.data[i] * op2.denom; - } - for (; i <= degree2; i++) - { - res.data[i] = op2.data[i] * op1.denom; - } - res.denom = op1.denom * op2.denom; - return res; - } - template - AZ_FORCE_INLINE polynomial_tpl operator-(const polynomial_tpl& op1, const polynomial_tpl& op2) - { - polynomial_tpl res; - int i; - for (i = 0; i <= min(degree1, degree2); i++) - { - res.data[i] = op1.data[i] * op2.denom - op2.data[i] * op1.denom; - } - for (; i <= degree1; i++) - { - res.data[i] = op1.data[i] * op2.denom; - } - for (; i <= degree2; i++) - { - res.data[i] = op2.data[i] * op1.denom; - } - res.denom = op1.denom * op2.denom; - return res; - } - - template - AZ_FORCE_INLINE polynomial_tpl& operator+=(polynomial_tpl& op1, const polynomial_tpl& op2) - { - for (int i = 0; i < min(degree1, degree2); i++) - { - op1.data[i] = op1.data[i] * op2.denom + op2.data[i] * op1.denom; - } - op1.denom *= op2.denom; - return op1; - } - template - AZ_FORCE_INLINE polynomial_tpl& operator-=(polynomial_tpl& op1, const polynomial_tpl& op2) - { - for (int i = 0; i < min(degree1, degree2); i++) - { - op1.data[i] = op1.data[i] * op2.denom - op2.data[i] * op1.denom; - } - op1.denom *= op2.denom; - return op1; - } - - template - AZ_FORCE_INLINE polynomial_tpl operator*(const polynomial_tpl& op1, const polynomial_tpl& op2) - { - polynomial_tpl res; - res.zero(); - int j; - switch (degree1) - { - case 8: - for (j = 0; j <= degree2; j++) - { - res.data[8 + j] += op1.data[8] * op2.data[j]; - } - case 7: - for (j = 0; j <= degree2; j++) - { - res.data[7 + j] += op1.data[7] * op2.data[j]; - } - case 6: - for (j = 0; j <= degree2; j++) - { - res.data[6 + j] += op1.data[6] * op2.data[j]; - } - case 5: - for (j = 0; j <= degree2; j++) - { - res.data[5 + j] += op1.data[5] * op2.data[j]; - } - case 4: - for (j = 0; j <= degree2; j++) - { - res.data[4 + j] += op1.data[4] * op2.data[j]; - } - case 3: - for (j = 0; j <= degree2; j++) - { - res.data[3 + j] += op1.data[3] * op2.data[j]; - } - case 2: - for (j = 0; j <= degree2; j++) - { - res.data[2 + j] += op1.data[2] * op2.data[j]; - } - case 1: - for (j = 0; j <= degree2; j++) - { - res.data[1 + j] += op1.data[1] * op2.data[j]; - } - case 0: - for (j = 0; j <= degree2; j++) - { - res.data[0 + j] += op1.data[0] * op2.data[j]; - } - } - res.denom = op1.denom * op2.denom; - return res; - } - - - template - AZ_FORCE_INLINE void polynomial_divide(const polynomial_tpl& num, const polynomial_tpl& den, polynomial_tpl& quot, - polynomial_tpl& rem, int degree1, int degree2) - { - int i, j, k, l; - ftype maxel; - for (i = 0; i <= degree1; i++) - { - rem.data[i] = num.data[i]; - } - for (i = 0; i <= degree1 - degree2; i++) - { - quot.data[i] = 0; - } - for (i = 1, maxel = fabs_tpl(num.data[0]); i <= degree1; i++) - { - maxel = max(maxel, num.data[i]); - } - for (maxel *= polye(); degree1 >= 0 && fabs_tpl(num.data[degree1]) < maxel; degree1--) - { - ; - } - for (i = 1, maxel = fabs_tpl(den.data[0]); i <= degree2; i++) - { - maxel = max(maxel, den.data[i]); - } - for (maxel *= polye(); degree2 >= 0 && fabs_tpl(den.data[degree2]) < maxel; degree2--) - { - ; - } - rem.denom = num.denom; - quot.denom = (ftype)1; - if (degree1 < 0 || degree2 < 0) - { - return; - } - - for (k = degree1 - degree2, l = degree1; l >= degree2; l--, k--) - { - quot.data[k] = rem.data[l] * den.denom; - quot.denom *= den.data[degree2]; - for (i = degree1 - degree2; i > k; i--) - { - quot.data[i] *= den.data[degree2]; - } - for (i = degree2 - 1, j = l - 1; i >= 0; i--, j--) - { - rem.data[j] = rem.data[j] * den.data[degree2] - den.data[i] * rem.data[l]; - } - for (; j >= 0; j--) - { - rem.data[j] *= den.data[degree2]; - } - rem.denom *= den.data[degree2]; - } - } - - template - AZ_FORCE_INLINE polynomial_tpl operator/(const polynomial_tpl& num, const polynomial_tpl& den) - { - polynomial_tpl quot; - polynomial_tpl rem; - polynomial_divide((polynomial_tpl&)num, (polynomial_tpl&)den, (polynomial_tpl&)quot, - (polynomial_tpl&)rem, degree1, degree2); - return quot; - } - template - AZ_FORCE_INLINE polynomial_tpl operator%(const polynomial_tpl& num, const polynomial_tpl& den) - { - polynomial_tpl quot; - polynomial_tpl rem; - polynomial_divide((polynomial_tpl&)num, (polynomial_tpl&)den, (polynomial_tpl&)quot, - (polynomial_tpl&)rem, degree1, degree2); - return (polynomial_tpl&)rem; - } - - template - AZ_FORCE_INLINE void polynomial_tpl::calc_deriviative(polynomial_tpl& deriv, int curdegree) const - { - for (int i = 0; i < curdegree; i++) - { - deriv.data[i] = data[i + 1] * (i + 1); - } - deriv.denom = denom; - } - - template - to_t* convert_type(from_t* input) - { - typedef union - { - to_t* to; - from_t* from; - } convert_union; - convert_union u; - u.from = input; - return u.to; - } - - template - AZ_FORCE_INLINE int polynomial_tpl::nroots(ftype start, ftype end) const - { - polynomial_tpl f[degree + 1]; - int i, j, sg_a, sg_b; - ftype val, prevval; - - calc_deriviative(f[0]); - polynomial_divide(*convert_type >(this), *convert_type< polynomial_tpl >(&f[0]), *convert_type >(&f[degree]), - *convert_type >(&f[1]), degree, degree - 1); - f[1].denom = -f[1].denom; - for (i = 2; i < degree; i++) - { - polynomial_divide(*convert_type >(&f[i - 2]), *convert_type >(&f[i - 1]), *convert_type >(&f[degree]), - *convert_type >(&f[i]), degree + 1 - i, degree - i); - f[i].denom = -f[i].denom; - if (fabs_tpl(f[i].denom) > (ftype)1E10) - { - for (j = 0; j <= degree - 1 - i; j++) - { - f[i].data[j] *= (ftype)1E-10; - } - f[i].denom *= (ftype)1E-10; - } - } - - prevval = eval(start) * denom; - for (i = sg_a = 0; i < degree; i++, prevval = val) - { - val = f[i].eval(start, degree - 1 - i) * f[i].denom; - sg_a += isneg(val * prevval); - } - - prevval = eval(end) * denom; - for (i = sg_b = 0; i < degree; i++, prevval = val) - { - val = f[i].eval(end, degree - 1 - i) * f[i].denom; - sg_b += isneg(val * prevval); - } - - return fabs_tpl(sg_a - sg_b); - } - - template - AZ_FORCE_INLINE ftype cubert_tpl(ftype x) { return fabs_tpl(x) > (ftype)1E-20 ? exp_tpl(log_tpl(fabs_tpl(x)) * (ftype)(1.0 / 3)) * sgnnz(x) : x; } - template - AZ_FORCE_INLINE ftype pow_tpl(ftype x, ftype pow) { return fabs_tpl(x) > (ftype)1E-20 ? exp_tpl(log_tpl(fabs_tpl(x)) * pow) * sgnnz(x) : x; } - template - AZ_FORCE_INLINE void swap(ftype* ptr, int i, int j) { ftype t = ptr[i]; ptr[i] = ptr[j]; ptr[j] = t; } - - template - int polynomial_tpl::findroots(ftype start, ftype end, ftype* proots, [[maybe_unused]] int nIters, int degree, bool noDegreeCheck) const - { - AZ_UNUSED(nIters); - int i, j, nRoots = 0; - ftype maxel; - if (!noDegreeCheck) - { - for (i = 1, maxel = fabs_tpl(data[0]); i <= degree; i++) - { - maxel = max(maxel, data[i]); - } - for (maxel *= polye(); degree > 0 && fabs_tpl(data[degree]) <= maxel; degree--) - { - ; - } - } - - if constexpr (maxdegree >= 1) - { - if (degree == 1) - { - proots[0] = data[0] / data[1]; - nRoots = 1; - } - } - - if constexpr (maxdegree >= 2) - { - if (degree == 2) - { - ftype a, b, c, d, bound[2], sg; - - a = data[2]; - b = data[1]; - c = data[0]; - d = aznumeric_cast(sgnnz(a)); - a *= d; - b *= d; - c *= d; - d = b * b - a * c * 4; - bound[0] = start * a * 2 + b; - bound[1] = end * a * 2 + b; - sg = aznumeric_cast((sgnnz(bound[0] * bound[1]) + 1) >> 1); - bound[0] *= bound[0]; - bound[1] *= bound[1]; - bound[isneg(fabs_tpl(bound[1]) - fabs_tpl(bound[0]))] *= sg; - - if (isnonneg(d) & inrange(d, bound[0], bound[1])) - { - d = sqrt_tpl(d); - a = (ftype)0.5 / a; - proots[nRoots] = (-b - d) * a; - nRoots += inrange(proots[nRoots], start, end); - proots[nRoots] = (-b + d) * a; - nRoots += inrange(proots[nRoots], start, end); - } - } - } - - if constexpr (maxdegree >= 3) - { - if (degree == 3) - { - ftype t, a, b, c, a3, p, q, Q, Qr, Ar, Ai, phi; - - t = (ftype)1.0 / data[3]; - a = data[2] * t; - b = data[1] * t; - c = data[0] * t; - a3 = a * (ftype)(1.0 / 3); - p = b - a * a3; - q = (a3 * b - c) * (ftype)0.5 - cube(a3); - Q = cube(p * (ftype)(1.0 / 3)) + q * q; - Qr = sqrt_tpl(fabs_tpl(Q)); - - if (Q > 0) - { - proots[0] = cubert_tpl(q + Qr) + cubert_tpl(q - Qr) - a3; - nRoots = 1; - } - else - { - phi = atan2_tpl(Qr, q) * (ftype)(1.0 / 3); - t = pow_tpl(Qr * Qr + q * q, (ftype)(1.0 / 6)); - Ar = t * cos_tpl(phi); - Ai = t * sin_tpl(phi); - proots[0] = 2 * Ar - a3; - proots[1] = aznumeric_cast(-Ar + Ai * sqrt3 - a3); - proots[2] = aznumeric_cast(-Ar - Ai * sqrt3 - a3); - i = idxmax3(proots); - swap(proots, i, 2); - i = isneg(proots[0] - proots[1]); - swap(proots, i, 1); - nRoots = 3; - } - } - } - - if constexpr (maxdegree >= 4) - { - if (degree == 4) - { - ftype t, a3, a2, a1, a0, y, R, D, E, subroots[3]; - const ftype e = (ftype)1E-9; - - t = (ftype)1.0 / data[4]; - a3 = data[3] * t; - a2 = data[2] * t; - a1 = data[1] * t; - a0 = data[0] * t; - polynomial_tpl p3aux; - ftype kp3aux[] = { 1, -a2, a1 * a3 - 4 * a0, 4 * a2 * a0 - a1 * a1 - a3 * a3 * a0 }; - p3aux.set(kp3aux); - if (!p3aux.findroots((ftype)-1E20, (ftype)1E20, subroots)) - { - return 0; - } - R = a3 * a3 * (ftype)0.25 - a2 + (y = subroots[0]); - - if (R > -e) - { - if (R < e) - { - D = E = a3 * a3 * (ftype)(3.0 / 4) - 2 * a2; - t = y * y - 4 * a0; - if (t < -e) - { - return 0; - } - t = 2 * sqrt_tpl(max((ftype)0, t)); - } - else - { - R = sqrt_tpl(max((ftype)0, R)); - D = E = a3 * a3 * (ftype)(3.0 / 4) - R * R - 2 * a2; - t = (4 * a3 * a2 - 8 * a1 - a3 * a3 * a3) / R * (ftype)0.25; - } - if (D + t > -e) - { - D = sqrt_tpl(max((ftype)0, D + t)); - proots[nRoots++] = a3 * (ftype)-0.25 + (R - D) * (ftype)0.5; - proots[nRoots++] = a3 * (ftype)-0.25 + (R + D) * (ftype)0.5; - } - if (E - t > -e) - { - E = sqrt_tpl(max((ftype)0, E - t)); - proots[nRoots++] = a3 * (ftype)-0.25 - (R + E) * (ftype)0.5; - proots[nRoots++] = a3 * (ftype)-0.25 - (R - E) * (ftype)0.5; - } - if (nRoots == 4) - { - i = idxmax3(proots); - if (proots[3] < proots[i]) - { - swap(proots, i, 3); - } - i = idxmax3(proots); - swap(proots, i, 2); - i = isneg(proots[0] - proots[1]); - swap(proots, i, 1); - } - } - } - } - - if constexpr (maxdegree > 4) - { - if (degree > 4) - { - ftype roots[maxdegree + 1], prevroot, val, prevval[2], curval, bound[2], middle; - polynomial_tpl deriv; - int nExtremes, iter, iBound; - calc_deriviative(deriv); - - // find a subset of deriviative extremes between start and end - for (nExtremes = deriv.findroots(start, end, roots + 1, nIters, degree - 1) + 1; nExtremes > 1 && roots[nExtremes - 1] > end; nExtremes--) - { - ; - } - for (i = 1; i < nExtremes && roots[i] < start; i++) - { - ; - } - roots[i - 1] = start; - PREFAST_ASSUME(nExtremes < maxdegree + 1); - roots[nExtremes++] = end; - - for (prevroot = start, prevval[0] = eval(start, degree), nRoots = 0; i < nExtremes; prevval[0] = val, prevroot = roots[i++]) - { - val = eval(roots[i], degree); - if (val * prevval[0] < 0) - { - // we have exactly one root between prevroot and roots[i] - bound[0] = prevroot; - bound[1] = roots[i]; - iter = 0; - do - { - middle = (bound[0] + bound[1]) * (ftype)0.5; - curval = eval(middle, degree); - iBound = isneg(prevval[0] * curval); - bound[iBound] = middle; - prevval[iBound] = curval; - } while (++iter < nIters); - proots[nRoots++] = middle; - } - } - } - } - - for (i = 0; i < nRoots && proots[i] < start; i++) - { - ; - } - for (; nRoots > i&& proots[nRoots - 1] > end; nRoots--) - { - ; - } - for (j = i; j < nRoots; j++) - { - proots[j - i] = proots[j]; - } - - return nRoots - i; - } - } // namespace polynomial_tpl_IMPL - template - using polynomial_tpl = polynomial_tpl_IMPL::polynomial_tpl; - - typedef polynomial_tpl P3; - typedef polynomial_tpl P2; - typedef polynomial_tpl P1; - typedef polynomial_tpl P3f; - typedef polynomial_tpl P2f; - typedef polynomial_tpl P1f; -} // namespace LegacyCryPhysicsUtils diff --git a/Code/Editor/Plugins/EditorCommon/DeepFilterProxyModel.cpp b/Code/Editor/Plugins/EditorCommon/DeepFilterProxyModel.cpp deleted file mode 100644 index d4bcabdfbe..0000000000 --- a/Code/Editor/Plugins/EditorCommon/DeepFilterProxyModel.cpp +++ /dev/null @@ -1,172 +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 "DeepFilterProxyModel.h" -#include - -DeepFilterProxyModel::DeepFilterProxyModel(QObject* parent) - : QSortFilterProxyModel(parent) -{ -} - -void DeepFilterProxyModel::setFilterString(const QString& filter) -{ - m_filter = filter; - m_filterParts = m_filter.split(' ', Qt::SkipEmptyParts); - m_acceptCache.clear(); -} - -void DeepFilterProxyModel::invalidate() -{ - QSortFilterProxyModel::invalidate(); - m_acceptCache.clear(); -} - -QVariant DeepFilterProxyModel::data(const QModelIndex& index, int role) const -{ - if (role == Qt::ForegroundRole) - { - QModelIndex sourceIndex = mapToSource(index); - if (matchFilter(sourceIndex.row(), sourceIndex.parent())) - { - return QSortFilterProxyModel::data(index, role); - } - else - { - return QPalette().color(QPalette::Disabled, QPalette::Text); - } - } - else - { - return QSortFilterProxyModel::data(index, role); - } -} - - -void DeepFilterProxyModel::setFilterWildcard(const QString& pattern) -{ - m_acceptCache.clear(); - QSortFilterProxyModel::setFilterWildcard(pattern); -} - -bool DeepFilterProxyModel::matchFilter(int sourceRow, const QModelIndex& sourceParent) const -{ - int columnCount = sourceModel()->columnCount(sourceParent); - for (int i = 0; i < m_filterParts.size(); ++i) - { - bool atLeastOneContains = false; - for (int j = 0; j < columnCount; ++j) - { - QModelIndex index = sourceModel()->index(sourceRow, j, sourceParent); - QVariant data = sourceModel()->data(index, Qt::DisplayRole); - QString str(data.toString()); - if (str.isEmpty()) - { - if (m_filterParts.empty()) - { - atLeastOneContains = true; - } - } - else if (str.contains(m_filterParts[i], Qt::CaseInsensitive)) - { - atLeastOneContains = true; - } - } - if (!atLeastOneContains) - { - return false; - } - } - return true; -} - -bool DeepFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const -{ - if (matchFilter(sourceRow, sourceParent)) - { - return true; - } - - if (hasAcceptedChildrenCached(sourceRow, sourceParent)) - { - return true; - } - - return false; -} - -bool DeepFilterProxyModel::hasAcceptedChildrenCached(int sourceRow, const QModelIndex& sourceParent) const -{ - std::pair indexId = std::make_pair(sourceParent, sourceRow); - TAcceptCache::iterator it = m_acceptCache.find(indexId); - if (it == m_acceptCache.end()) - { - bool result = hasAcceptedChildren(sourceRow, sourceParent); - m_acceptCache[indexId] = result; - return result; - } - else - { - return it->second; - } -} - -bool DeepFilterProxyModel::hasAcceptedChildren(int sourceRow, const QModelIndex& sourceParent) const -{ - QModelIndex item = sourceModel()->index(sourceRow, 0, sourceParent); - if (!item.isValid()) - { - return false; - } - - int childCount = item.model()->rowCount(item); - if (childCount == 0) - { - return false; - } - - for (int i = 0; i < childCount; ++i) - { - if (filterAcceptsRow(i, item)) - { - return true; - } - } - - return false; -} - -QModelIndex DeepFilterProxyModel::findFirstMatchingIndex(const QModelIndex& root) -{ - int rowCount = this->rowCount(root); - for (int i = 0; i < rowCount; ++i) - { - QModelIndex index = this->index(i, 0, root); - if (!index.isValid()) - { - continue; - } - QModelIndex sourceIndex = mapToSource(index); - if (!sourceIndex.isValid()) - { - continue; - } - if (matchFilter(sourceIndex.row(), sourceIndex.parent())) - { - return index; - } - - QModelIndex child = findFirstMatchingIndex(index); - if (child.isValid()) - { - return child; - } - } - return QModelIndex(); -} diff --git a/Code/Editor/Plugins/EditorCommon/DeepFilterProxyModel.h b/Code/Editor/Plugins/EditorCommon/DeepFilterProxyModel.h deleted file mode 100644 index c7373ef18c..0000000000 --- a/Code/Editor/Plugins/EditorCommon/DeepFilterProxyModel.h +++ /dev/null @@ -1,48 +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_EDITORCOMMON_DEEPFILTERPROXYMODEL_H -#define CRYINCLUDE_EDITORCOMMON_DEEPFILTERPROXYMODEL_H -#pragma once - -#include -#include -#include -#include "EditorCommonAPI.h" - -class EDITOR_COMMON_API DeepFilterProxyModel - : public QSortFilterProxyModel -{ -public: - DeepFilterProxyModel(QObject* parent); - - void setFilterString(const QString& filter); - void invalidate(); - - QVariant data(const QModelIndex& index, int role) const override; - - void setFilterWildcard(const QString& pattern); - - bool matchFilter(int source_row, const QModelIndex& source_parent) const; - bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override; - bool hasAcceptedChildrenCached(int source_row, const QModelIndex& source_parent) const; - bool hasAcceptedChildren(int source_row, const QModelIndex& source_parent) const; - - QModelIndex findFirstMatchingIndex(const QModelIndex& root); - -private: - QString m_filter; - AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING - QStringList m_filterParts; - typedef std::map, bool> TAcceptCache; - mutable TAcceptCache m_acceptCache; - AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING -}; - -#endif // CRYINCLUDE_EDITORCOMMON_DEEPFILTERPROXYMODEL_H diff --git a/Code/Editor/Plugins/EditorCommon/DisplayContext.cpp b/Code/Editor/Plugins/EditorCommon/DisplayContext.cpp deleted file mode 100644 index f0a82ba13c..0000000000 --- a/Code/Editor/Plugins/EditorCommon/DisplayContext.cpp +++ /dev/null @@ -1,9 +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 "../../Editor/Objects/DisplayContextShared.inl" diff --git a/Code/Editor/Plugins/EditorCommon/DrawingPrimitives/Ruler.cpp b/Code/Editor/Plugins/EditorCommon/DrawingPrimitives/Ruler.cpp deleted file mode 100644 index 1f0bd9ad88..0000000000 --- a/Code/Editor/Plugins/EditorCommon/DrawingPrimitives/Ruler.cpp +++ /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 - * - */ - - -#include "Ruler.h" - -#include -#include -#include -#include - -namespace DrawingPrimitives -{ - enum - { - RULER_MIN_PIXELS_PER_TICK = 3, - }; - - std::vector CalculateTicks(uint size, Range visibleRange, Range rulerRange, int* pRulerPrecision, Range* pScreenRulerRange) - { - std::vector ticks; - - if (size == 0) - { - if (pRulerPrecision) - { - *pRulerPrecision = 0; - } - - return ticks; - } - - const float pixelsPerUnit = visibleRange.Length() > 0.0f ? (float)size / visibleRange.Length() : 1.0f; - - const float startTime = rulerRange.start; - const float endTime = rulerRange.end; - const float totalDuration = endTime - startTime; - - const float ticksMinPower = log10f(RULER_MIN_PIXELS_PER_TICK); - const float ticksPowerDelta = ticksMinPower - log10f(pixelsPerUnit); - - const int digitsAfterPoint = AZStd::max(-int(ceil(ticksPowerDelta)) - 1, 0); - if (pRulerPrecision) - { - *pRulerPrecision = digitsAfterPoint; - } - - const float scaleStep = powf(10.0f, ceil(ticksPowerDelta)); - const float scaleStepPixels = scaleStep * pixelsPerUnit; - const int numMarkers = int(totalDuration / scaleStep) + 1; - - const float startTimeRound = int(startTime / scaleStep) * scaleStep; - const int startOffsetMod = int(startTime / scaleStep) % 10; - const int scaleOffsetPixels = aznumeric_cast((startTime - startTimeRound) * pixelsPerUnit); - - const int startX = aznumeric_cast((rulerRange.start - visibleRange.start) * pixelsPerUnit); - const int endX = aznumeric_cast(startX + (numMarkers - 1) * scaleStepPixels - scaleOffsetPixels); - - if (pScreenRulerRange) - { - *pScreenRulerRange = Range(aznumeric_cast(startX), aznumeric_cast(endX)); - } - - const int startLoop = std::max((int)((scaleOffsetPixels - startX) / scaleStepPixels) - 1, 0); - const int endLoop = std::min((int)((size + scaleOffsetPixels - startX) / scaleStepPixels) + 1, numMarkers); - - for (int i = startLoop; i < endLoop; ++i) - { - STick tick; - - const int x = aznumeric_cast(startX + i * scaleStepPixels - scaleOffsetPixels); - const float value = startTimeRound + i * scaleStep; - - tick.m_bTenth = (startOffsetMod + i) % 10 != 0; - tick.m_position = x; - tick.m_value = value; - - ticks.push_back(tick); - } - - return ticks; - } - - QColor Interpolate(const QColor& a, const QColor& b, float k) - { - float mk = 1.0f - k; - return QColor(aznumeric_cast(a.red() * mk + b.red() * k), - aznumeric_cast(a.green() * mk + b.green() * k), - aznumeric_cast(a.blue() * mk + b.blue() * k), - aznumeric_cast(a.alpha() * mk + b.alpha() * k)); - } - - void DrawTicks(const std::vector& ticks, QPainter& painter, const QPalette& palette, const STickOptions& options) - { - QColor midDark = DrawingPrimitives::Interpolate(palette.color(QPalette::Dark), palette.color(QPalette::Button), 0.5f); - painter.setPen(QPen(midDark)); - - const int height = options.m_rect.height(); - const int top = options.m_rect.top(); - - for (const STick& tick : ticks) - { - const int x = tick.m_position + options.m_rect.left(); - - if (tick.m_bTenth) - { - painter.drawLine(QPoint(x, top + height - options.m_markHeight / 2), QPoint(x, top + height)); - } - else - { - painter.drawLine(QPoint(x, top + height - options.m_markHeight), QPoint(x, top + height)); - } - } - } - - void DrawTicks(QPainter& painter, const QPalette& palette, const SRulerOptions& options) - { - const std::vector ticks = CalculateTicks(options.m_rect.width(), options.m_visibleRange, options.m_rulerRange, nullptr, nullptr); - DrawTicks(ticks, painter, palette, options); - } - - void DrawRuler(QPainter& painter, const QPalette& palette, const SRulerOptions& options, int* pRulerPrecision) - { - int rulerPrecision; - Range screenRulerRange; - const std::vector ticks = CalculateTicks(options.m_rect.width(), options.m_visibleRange, options.m_rulerRange, &rulerPrecision, &screenRulerRange); - - if (pRulerPrecision) - { - *pRulerPrecision = rulerPrecision; - } - - if (options.m_shadowSize > 0) - { - QRect shadowRect = QRect(options.m_rect.left(), options.m_rect.height(), options.m_rect.width(), options.m_shadowSize); - QLinearGradient upperGradient(shadowRect.left(), shadowRect.top(), shadowRect.left(), shadowRect.bottom()); - upperGradient.setColorAt(0.0f, QColor(0, 0, 0, 128)); - upperGradient.setColorAt(1.0f, QColor(0, 0, 0, 0)); - QBrush upperBrush(upperGradient); - painter.fillRect(shadowRect, upperBrush); - } - - painter.fillRect(options.m_rect, DrawingPrimitives::Interpolate(palette.color(QPalette::Button), palette.color(QPalette::Midlight), 0.25f)); - if (options.m_drawBackgroundCallback) - { - options.m_drawBackgroundCallback(); - } - - QColor midDark = DrawingPrimitives::Interpolate(palette.color(QPalette::Dark), palette.color(QPalette::Button), 0.5f); - painter.setPen(QPen(midDark)); - - QFont font; - font.setPixelSize(10); - painter.setFont(font); - - - char format[16] = ""; - azsprintf(format, "%%.%df", rulerPrecision); - - const int height = options.m_rect.height(); - const int top = options.m_rect.top(); - - QString str; - for (const STick& tick : ticks) - { - const int x = tick.m_position + options.m_rect.left(); - const float value = tick.m_value; - - if (tick.m_bTenth) - { - painter.drawLine(QPoint(x, top + height - options.m_markHeight / 2), QPoint(x, top + height)); - } - else - { - painter.drawLine(QPoint(x, top + height - options.m_markHeight), QPoint(x, top + height)); - painter.setPen(palette.color(QPalette::Disabled, QPalette::Text)); - str.asprintf(format, value); - painter.drawText(QPoint(x + 2, top + height - options.m_markHeight + 1), str); - painter.setPen(midDark); - } - } - - painter.setPen(QPen(palette.color(QPalette::Dark))); - painter.drawLine(QPoint(aznumeric_cast(options.m_rect.left() + screenRulerRange.start), 0), QPoint(aznumeric_cast(options.m_rect.left() + screenRulerRange.start), options.m_rect.top() + height)); - painter.drawLine(QPoint(aznumeric_cast(options.m_rect.left() + screenRulerRange.end), 0), QPoint(aznumeric_cast(options.m_rect.left() + screenRulerRange.end), options.m_rect.top() + height)); - } -} diff --git a/Code/Editor/Plugins/EditorCommon/DrawingPrimitives/Ruler.h b/Code/Editor/Plugins/EditorCommon/DrawingPrimitives/Ruler.h deleted file mode 100644 index fd8bc62ff7..0000000000 --- a/Code/Editor/Plugins/EditorCommon/DrawingPrimitives/Ruler.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#pragma once - -#include "Range.h" - -#include -#include -#include - -class QPainter; -class QPalette; - -namespace DrawingPrimitives -{ - struct SRulerOptions; - typedef std::function TDrawCallback; - - struct SRulerOptions - { - QRect m_rect; - Range m_visibleRange; - Range m_rulerRange; - int m_textXOffset; - int m_textYOffset; - int m_markHeight; - int m_shadowSize; - - TDrawCallback m_drawBackgroundCallback; - }; - - struct STick - { - bool m_bTenth; - int m_position; - float m_value; - }; - - typedef SRulerOptions STickOptions; - - std::vector CalculateTicks(uint size, Range visibleRange, Range rulerRange, int* pRulerPrecision, Range* pScreenRulerRange); - void DrawTicks(const std::vector& ticks, QPainter& painter, const QPalette& palette, const STickOptions& options); - void DrawTicks(QPainter& painter, const QPalette& palette, const STickOptions& options); - void DrawRuler(QPainter& painter, const QPalette& palette, const SRulerOptions& options, int* pRulerPrecision); -} diff --git a/Code/Editor/Plugins/EditorCommon/DrawingPrimitives/TimeSlider.cpp b/Code/Editor/Plugins/EditorCommon/DrawingPrimitives/TimeSlider.cpp deleted file mode 100644 index 291723ff6b..0000000000 --- a/Code/Editor/Plugins/EditorCommon/DrawingPrimitives/TimeSlider.cpp +++ /dev/null @@ -1,48 +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 "TimeSlider.h" - -#include -#include - -#include - -namespace DrawingPrimitives -{ - void DrawTimeSlider(QPainter& painter, const QPalette& palette, const STimeSliderOptions& options) - { - QString text = QString::number(options.m_time, 'f', options.m_precision + 1); - - QFontMetrics fm(painter.font()); - const int textWidth = fm.horizontalAdvance(text) + fm.height(); - const int markerHeight = fm.height(); - - const int thumbX = options.m_position; - const bool fits = thumbX + textWidth < options.m_rect.right(); - - const QRect timeRect(fits ? thumbX : thumbX - textWidth, 3, textWidth, fm.height()); - painter.fillRect(timeRect.adjusted(fits ? 0 : -1, 0, fits ? 1 : 0, 0), options.m_bHasFocus ? palette.highlight() : palette.shadow()); - painter.setPen(palette.color(QPalette::HighlightedText)); - painter.drawText(timeRect.adjusted(fits ? 0 : aznumeric_cast(markerHeight * 0.2f), -1, fits ? aznumeric_cast(-markerHeight * 0.2f) : 0, 0), text, QTextOption(fits ? Qt::AlignRight : Qt::AlignLeft)); - - painter.setPen(palette.color(QPalette::Text)); - painter.drawLine(QPointF(thumbX, 0), QPointF(thumbX, options.m_rect.height())); - QPointF points[3] = - { - QPointF(thumbX, markerHeight), - QPointF(thumbX - markerHeight * 0.66f, 0), - QPointF(thumbX + markerHeight * 0.66f, 0) - }; - - painter.setBrush(palette.base()); - painter.setPen(palette.color(QPalette::Text)); - painter.drawPolygon(points, 3); - } -} diff --git a/Code/Editor/Plugins/EditorCommon/DrawingPrimitives/TimeSlider.h b/Code/Editor/Plugins/EditorCommon/DrawingPrimitives/TimeSlider.h deleted file mode 100644 index 4553b106e2..0000000000 --- a/Code/Editor/Plugins/EditorCommon/DrawingPrimitives/TimeSlider.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#pragma once - -#include "Range.h" - -#include - -class QPainter; -class QPalette; - -namespace DrawingPrimitives -{ - struct STimeSliderOptions - { - QRect m_rect; - int m_precision; - int m_position; - float m_time; - bool m_bHasFocus; - }; - - void DrawTimeSlider(QPainter& painter, const QPalette& palette, const STimeSliderOptions& options); -} diff --git a/Code/Editor/Plugins/EditorCommon/EditorCommon.rc b/Code/Editor/Plugins/EditorCommon/EditorCommon.rc deleted file mode 100644 index 77deebb598..0000000000 Binary files a/Code/Editor/Plugins/EditorCommon/EditorCommon.rc and /dev/null differ diff --git a/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/auto.png b/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/auto.png deleted file mode 100644 index 4009c4110c..0000000000 --- a/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/auto.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3e60156229cc8677e0294d297486f04bd78867ef4e0922b35444c8b45f78584d -size 1090 diff --git a/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/break.png b/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/break.png deleted file mode 100644 index 75399a536a..0000000000 --- a/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/break.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fd29a16a1d1d9a363e4b154d51910c2cba2787fbbe1360cfd107b393053d2e49 -size 1226 diff --git a/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/fit_horizontal.png b/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/fit_horizontal.png deleted file mode 100644 index fee50a459c..0000000000 --- a/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/fit_horizontal.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:244005cde119238bbfc2815f36a343c6135c3233d0b72a5c97a6080604568e8f -size 1160 diff --git a/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/fit_vertical.png b/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/fit_vertical.png deleted file mode 100644 index 9a067e6980..0000000000 --- a/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/fit_vertical.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:33176a8ea6b0798adf1114fdbea4b0f5c708f40c3d48a047b1cb0fa6ebcbbded -size 1181 diff --git a/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/linear_in.png b/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/linear_in.png deleted file mode 100644 index 1ba6d72859..0000000000 --- a/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/linear_in.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c122557745cc377768491ce59c5b5b17e54671aa59f7f87101766aa61758959e -size 939 diff --git a/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/linear_out.png b/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/linear_out.png deleted file mode 100644 index 58694e0c4f..0000000000 --- a/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/linear_out.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3c2a360a56a37bfae2bea16b495f5b6ee482caa28d0949e8eadea48fdaae654f -size 845 diff --git a/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/step_in.png b/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/step_in.png deleted file mode 100644 index d1a2238790..0000000000 --- a/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/step_in.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:eb0f43228bdb5246ea3bfde0726f07e0df0468279610ba4c801b21e264b33123 -size 765 diff --git a/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/step_out.png b/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/step_out.png deleted file mode 100644 index 910db1aeb3..0000000000 --- a/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/step_out.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:97a2e879222323bc70787efbe2cbc1c47bbabb7b10df8465857e600a9084abb2 -size 795 diff --git a/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/unify.png b/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/unify.png deleted file mode 100644 index 5a8a5105d7..0000000000 --- a/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/unify.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:58e8476b7bec1ed8eddfde3d5228f58fcfba11329318f5dfef3d98eb99f3a897 -size 1113 diff --git a/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/zero_in.png b/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/zero_in.png deleted file mode 100644 index d43d881d45..0000000000 --- a/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/zero_in.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a7847e8b7f3dd76395d893888916e4bd97ddf3f678d37d19836da04c2923791e -size 871 diff --git a/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/zero_out.png b/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/zero_out.png deleted file mode 100644 index f287d1c7af..0000000000 --- a/Code/Editor/Plugins/EditorCommon/Icons/CurveEditor/zero_out.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:470266956c6911690299f29539c400122ae707f88d9b6ba3516faf196a8fd571 -size 877 diff --git a/Code/Editor/Plugins/EditorCommon/QtViewPane.cpp b/Code/Editor/Plugins/EditorCommon/QtViewPane.cpp deleted file mode 100644 index 3deef7e503..0000000000 --- a/Code/Editor/Plugins/EditorCommon/QtViewPane.cpp +++ /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 - * - */ - - -#include "platform.h" - -#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS -#include -#include - -#include "QtViewPane.h" - -#include "Include/IViewPane.h" -#include "Util/RefCountBase.h" -#include "QtWinMigrate/qwinwidget.h" - -#include -#include -#include -#include -#include - -#include "QtUtil.h" - -// ugly dependencies: -#include "Functor.h" -class CXmlArchive; -#include -#include "Util/PathUtil.h" -// ^^^ - -// --------------------------------------------------------------------------- -// --------------------------------------------------------------------------- - diff --git a/Code/Editor/Plugins/EditorCommon/Resource.h b/Code/Editor/Plugins/EditorCommon/Resource.h deleted file mode 100644 index d1acef6314..0000000000 --- a/Code/Editor/Plugins/EditorCommon/Resource.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - - -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by EditorCommon.rc -// - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS - -#define _APS_NEXT_RESOURCE_VALUE 1000 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 1000 -#define _APS_NEXT_COMMAND_VALUE 32771 -#endif -#endif diff --git a/Code/Editor/Plugins/EditorCommon/WinWidget/WinWidget.h b/Code/Editor/Plugins/EditorCommon/WinWidget/WinWidget.h deleted file mode 100644 index 06e84c1405..0000000000 --- a/Code/Editor/Plugins/EditorCommon/WinWidget/WinWidget.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#pragma once - -#include "EditorCommonAPI.h" -#include "IEditor.h" - - -#include -#include -#include - -namespace WinWidget -{ - template - bool RegisterWinWidget() - { - static QWidget* winWidget {nullptr}; // Must declare outside of lambda - - WinWidget::WinWidgetManager::WinWidgetCreateCall createCall = []() -> QWidget* - { - if (!winWidget) - { - winWidget = new QWidget(GetIEditor()->GetEditorMainWindow()); - } - - // Ensure only one instance of each window type exists - QList existingWidgets = winWidget->findChildren(); - if (existingWidgets.size() > 0) // Note that the list should contain 0 or 1 entries - { - if (existingWidgets.first()->isVisible()) - { - return nullptr; // TWidget type already in use - continue using it and don't create another - } - delete existingWidgets.first(); // Closed TWidget - remove - } - - TWidget* createWidget = new TWidget(winWidget); - - createWidget->Display(); - return winWidget; - }; - - return GetIEditor()->GetWinWidgetManager()->RegisterWinWidget(TWidget::GetWWId(), createCall); - } - - template - void UnregisterWinWidget() - { - GetIEditor()->GetWinWidgetManager()->UnregisterWinWidget(TWidget::GetWWId()); - } -} diff --git a/Code/Editor/Plugins/EditorCommon/WinWidget/WinWidgetManager.cpp b/Code/Editor/Plugins/EditorCommon/WinWidget/WinWidgetManager.cpp deleted file mode 100644 index 3ffa1b1b99..0000000000 --- a/Code/Editor/Plugins/EditorCommon/WinWidget/WinWidgetManager.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include - -namespace WinWidget -{ - WinWidgetManager::WinWidgetManager() - : m_createCalls(size_t(WinWidgetId::NUM_WIN_WIDGET_IDS) + 1) - { - } - - size_t WinWidgetManager::GetIndexForId(WinWidgetId thisId) const - { - size_t thisIndex = static_cast(thisId); - if (thisIndex >= m_createCalls.size()) - { - return 0; - } - return thisIndex; - } - - WinWidgetManager::WinWidgetCreateCall WinWidgetManager::GetCreateCall(WinWidgetId thisId) const - { - size_t thisIndex = GetIndexForId(thisId); - if (!thisIndex) - { - return nullptr; - } - return m_createCalls[thisIndex]; - } - - bool WinWidgetManager::RegisterWinWidget(WinWidgetId thisId, WinWidgetCreateCall createCall) - { - size_t thisIndex = GetIndexForId(thisId); - if (m_createCalls[thisIndex] != nullptr) - { - return false; - } - m_createCalls[thisIndex] = createCall; - return true; - } - - bool WinWidgetManager::UnregisterWinWidget(WinWidgetId thisId) - { - size_t thisIndex = GetIndexForId(thisId); - if (m_createCalls[thisIndex] == nullptr) - { - return false; - } - m_createCalls[thisIndex] = nullptr; - return true; - } - - - QWidget* WinWidgetManager::OpenWinWidget(WinWidgetId createId) const - { - WinWidgetManager::WinWidgetCreateCall createCall = GetCreateCall(createId); - if (!createCall) - { - return nullptr; - } - return createCall(); - } -} diff --git a/Code/Editor/Plugins/EditorCommon/WinWidget/WinWidgetManager.h b/Code/Editor/Plugins/EditorCommon/WinWidget/WinWidgetManager.h deleted file mode 100644 index 968f3ea6d2..0000000000 --- a/Code/Editor/Plugins/EditorCommon/WinWidget/WinWidgetManager.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include -#include "EditorCommonAPI.h" - -#include -#include - -class QWidget; - -namespace WinWidget -{ - class EDITOR_COMMON_API WinWidgetManager - { - public: - using WinWidgetCreateCall = std::function; - - WinWidgetManager(); - ~WinWidgetManager() {} - - bool RegisterWinWidget(WinWidgetId thisId, WinWidgetCreateCall createCall); - bool UnregisterWinWidget(WinWidgetId thisId); - - QWidget* OpenWinWidget(WinWidgetId) const; - private: - WinWidgetCreateCall GetCreateCall(WinWidgetId thisId) const; - size_t GetIndexForId(WinWidgetId thisId) const; - - AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING - std::vector m_createCalls; - AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING - }; -} diff --git a/Code/Editor/Plugins/EditorCommon/editorcommon_files.cmake b/Code/Editor/Plugins/EditorCommon/editorcommon_files.cmake index 1c6efbdf2c..1ae1f51632 100644 --- a/Code/Editor/Plugins/EditorCommon/editorcommon_files.cmake +++ b/Code/Editor/Plugins/EditorCommon/editorcommon_files.cmake @@ -9,7 +9,6 @@ set(FILES EditorCommon.h EditorCommon.cpp - EditorCommon.rc EditorCommonAPI.h ActionOutput.h ActionOutput.cpp @@ -17,16 +16,4 @@ set(FILES DockTitleBarWidget.h SaveUtilities/AsyncSaveRunner.h SaveUtilities/AsyncSaveRunner.cpp - AxisHelper.cpp - DisplayContext.cpp - DeepFilterProxyModel.cpp - DeepFilterProxyModel.h - Resource.h - DrawingPrimitives/Ruler.cpp - DrawingPrimitives/Ruler.h - DrawingPrimitives/TimeSlider.cpp - DrawingPrimitives/TimeSlider.h - WinWidget/WinWidget.h - WinWidget/WinWidgetManager.h - WinWidget/WinWidgetManager.cpp ) diff --git a/Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin.rc b/Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin.rc deleted file mode 100644 index 404387a244..0000000000 --- a/Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin.rc +++ /dev/null @@ -1,61 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE 9, 1 -#pragma code_page(1252) - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/Code/Editor/Plugins/FFMPEGPlugin/ffmpegplugin_files.cmake b/Code/Editor/Plugins/FFMPEGPlugin/ffmpegplugin_files.cmake index 779fc816f4..6d63e3a8f8 100644 --- a/Code/Editor/Plugins/FFMPEGPlugin/ffmpegplugin_files.cmake +++ b/Code/Editor/Plugins/FFMPEGPlugin/ffmpegplugin_files.cmake @@ -7,7 +7,6 @@ # set(FILES - FFMPEGPlugin.rc main.cpp FFMPEGPlugin.cpp FFMPEGPlugin.h diff --git a/Code/Editor/Plugins/FFMPEGPlugin/resource.h b/Code/Editor/Plugins/FFMPEGPlugin/resource.h deleted file mode 100644 index dcf269a2b4..0000000000 --- a/Code/Editor/Plugins/FFMPEGPlugin/resource.h +++ /dev/null @@ -1,22 +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 - * - */ - -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by FFMPEGPlugin.rc - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/Code/Editor/Plugins/PerforcePlugin/PerforcePlugin.qrc b/Code/Editor/Plugins/PerforcePlugin/PerforcePlugin.qrc deleted file mode 100644 index d378e6b5e4..0000000000 --- a/Code/Editor/Plugins/PerforcePlugin/PerforcePlugin.qrc +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/Code/Editor/Plugins/PerforcePlugin/PerforcePlugin.rc b/Code/Editor/Plugins/PerforcePlugin/PerforcePlugin.rc deleted file mode 100644 index 26e4bbda6b..0000000000 --- a/Code/Editor/Plugins/PerforcePlugin/PerforcePlugin.rc +++ /dev/null @@ -1,71 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_P4 ICON "res\\p4.ico" -IDI_P4_ERROR ICON "res\\p4_error.ico" -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/Code/Editor/Plugins/PerforcePlugin/perforceplugin_files.cmake b/Code/Editor/Plugins/PerforcePlugin/perforceplugin_files.cmake index 7932c01015..5302a9f718 100644 --- a/Code/Editor/Plugins/PerforcePlugin/perforceplugin_files.cmake +++ b/Code/Editor/Plugins/PerforcePlugin/perforceplugin_files.cmake @@ -13,8 +13,6 @@ set(FILES PasswordDlg.h PerforcePlugin.cpp PerforcePlugin.h - PerforcePlugin.qrc PerforceSourceControl.cpp PerforceSourceControl.h - resource.h ) diff --git a/Code/Editor/Plugins/PerforcePlugin/resource.h b/Code/Editor/Plugins/PerforcePlugin/resource.h deleted file mode 100644 index bb41c2b1bd..0000000000 --- a/Code/Editor/Plugins/PerforcePlugin/resource.h +++ /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 - * - */ - - -#define IDI_P4 104 -#define IDI_P4_ERROR 106 -#define IDC_ERROR 1004 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 107 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1010 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/Code/Editor/Report.h b/Code/Editor/Report.h deleted file mode 100644 index 1dbf3788cd..0000000000 --- a/Code/Editor/Report.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -// Description : Generic report class, which contains arbitrary report entries. - -#ifndef CRYINCLUDE_EDITOR_REPORT_H -#define CRYINCLUDE_EDITOR_REPORT_H -#pragma once - - -class IReportField -{ -public: - virtual ~IReportField() {} - - virtual const char* GetDescription() const = 0; - virtual const char* GetText() const = 0; -}; - -template -class CReportField - : public IReportField -{ -public: - typedef T Object; - typedef G TextGetter; - - CReportField(Object& object, const char* description, TextGetter& getter); - virtual const char* GetDescription() const; - virtual const char* GetText() const; - -private: - TextGetter m_getter; - string m_text; - string m_description; -}; - -class IReportRecord -{ -public: - virtual ~IReportRecord() {} - virtual int GetFieldCount() const = 0; - virtual const char* GetFieldDescription(int fieldIndex) const = 0; - virtual const char* GetFieldText(int fieldIndex) const = 0; -}; - -template -class CReportRecord - : public IReportRecord -{ -public: - typedef T Object; - - CReportRecord(Object& object); - virtual ~CReportRecord(); - virtual int GetFieldCount() const; - virtual const char* GetFieldDescription(int fieldIndex) const; - virtual const char* GetFieldText(int fieldIndex) const; - template - CReportField* AddField(const char* description, G& getter); - -private: - Object m_object; - typedef std::vector FieldContainer; - FieldContainer m_fields; -}; - -class CReport -{ -public: - ~CReport(); - template - CReportRecord* AddRecord(T& object); - int GetRecordCount() const; - IReportRecord* GetRecord(int recordIndex); - void Clear(); - -private: - typedef std::vector RecordContainer; - RecordContainer m_records; -}; - -template -inline CReportField::CReportField(Object& object, const char* description, TextGetter& getter) - : m_getter(getter) - , m_description(description) -{ - m_text = m_getter(object); -} - -template -inline const char* CReportField::GetDescription() const -{ - return m_description.c_str(); -} - -template -inline const char* CReportField::GetText() const -{ - return m_text.c_str(); -} - -template -inline CReportRecord::CReportRecord(Object& object) - : m_object(object) -{ -} - -template -inline CReportRecord::~CReportRecord() -{ - for (FieldContainer::iterator it = m_fields.begin(); it != m_fields.end(); ++it) - { - delete (*it); - } -} - -template -inline int CReportRecord::GetFieldCount() const -{ - return m_fields.size(); -} - -template -inline const char* CReportRecord::GetFieldDescription(int fieldIndex) const -{ - return m_fields[fieldIndex]->GetDescription(); -} - -template -inline const char* CReportRecord::GetFieldText(int fieldIndex) const -{ - return m_fields[fieldIndex]->GetText(); -} - -template -template -inline CReportField* CReportRecord::AddField(const char* description, G& getter) -{ - CReportField* field = new CReportField(m_object, description, getter); - m_fields.push_back(field); - return field; -} - -inline CReport::~CReport() -{ - Clear(); -} - -template -inline CReportRecord* CReport::AddRecord(T& object) -{ - CReportRecord* record = new CReportRecord(object); - m_records.push_back(record); - return record; -} - -inline int CReport::GetRecordCount() const -{ - return m_records.size(); -} - -inline IReportRecord* CReport::GetRecord(int recordIndex) -{ - return m_records[recordIndex]; -} - -inline void CReport::Clear() -{ - for (RecordContainer::iterator it = m_records.begin(); it != m_records.end(); ++it) - { - delete (*it); - } - m_records.clear(); -} - -#endif // CRYINCLUDE_EDITOR_REPORT_H diff --git a/Code/Editor/ResizeResolutionDialog.cpp b/Code/Editor/ResizeResolutionDialog.cpp deleted file mode 100644 index f2a03fb1b2..0000000000 --- a/Code/Editor/ResizeResolutionDialog.cpp +++ /dev/null @@ -1,119 +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 "ResizeResolutionDialog.h" - -AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING -#include -AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING - -class ResizeResolutionModel - : public QAbstractListModel -{ -public: - ResizeResolutionModel(QObject* parent = nullptr); - - int rowCount(const QModelIndex& parent = {}) const override; - int columnCount(const QModelIndex& parent = {}) const override; - QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; - - int SizeRow(uint32 dwSize) const; - -private: - static const int kNumSizes = 6; -}; - -ResizeResolutionModel::ResizeResolutionModel(QObject* parent) - : QAbstractListModel(parent) -{ -} - -int ResizeResolutionModel::rowCount(const QModelIndex& parent) const -{ - return parent.isValid() ? 0 : kNumSizes; -} - -int ResizeResolutionModel::columnCount(const QModelIndex& parent) const -{ - return parent.isValid() ? 0 : 1; -} - -QVariant ResizeResolutionModel::data(const QModelIndex& index, int role) const -{ - if (!index.isValid() || index.column() > 0 || index.row() >= kNumSizes) - { - return {}; - } - - const int size = 64 * (1 << index.row()); - - switch (role) - { - case Qt::DisplayRole: - return QStringLiteral("%1x%2").arg(size).arg(size); - - case Qt::UserRole: - return size; - } - - return {}; -} - -int ResizeResolutionModel::SizeRow(uint32 dwSize) const -{ - // not a power of 2? - if (dwSize & (dwSize - 1)) - { - return 0; - } - - int row = 0; - - for (auto i = dwSize / 64; i > 1; i >>= 1) - { - ++row; - } - - return row; -} - -///////////////////////////////////////////////////////////////////////////// -// CResizeResolutionDialog dialog - - -CResizeResolutionDialog::CResizeResolutionDialog(QWidget* pParent /*=nullptr*/) - : QDialog(pParent) - , m_model(new ResizeResolutionModel(this)) - , ui(new Ui::CResizeResolutionDialog) -{ - ui->setupUi(this); - - ui->m_resolution->setModel(m_model); - - connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); -} - -CResizeResolutionDialog::~CResizeResolutionDialog() -{ -} - -///////////////////////////////////////////////////////////////////////////// -void CResizeResolutionDialog::SetSize(uint32 dwSize) -{ - ui->m_resolution->setCurrentIndex(m_model->SizeRow(dwSize)); -} - -///////////////////////////////////////////////////////////////////////////// -uint32 CResizeResolutionDialog::GetSize() -{ - return ui->m_resolution->itemData(ui->m_resolution->currentIndex()).toInt(); -} diff --git a/Code/Editor/ResizeResolutionDialog.h b/Code/Editor/ResizeResolutionDialog.h deleted file mode 100644 index 123075688f..0000000000 --- a/Code/Editor/ResizeResolutionDialog.h +++ /dev/null @@ -1,46 +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_RESIZERESOLUTIONDIALOG_H -#define CRYINCLUDE_EDITOR_RESIZERESOLUTIONDIALOG_H - -#pragma once -// ResizeResolutionDialog.h : header file -// - -#if !defined(Q_MOC_RUN) -#include -#endif - -namespace Ui { - class CResizeResolutionDialog; -} - -class ResizeResolutionModel; - -///////////////////////////////////////////////////////////////////////////// -// CResizeResolutionDialog dialog - -class CResizeResolutionDialog - : public QDialog -{ - // Construction -public: - CResizeResolutionDialog(QWidget* pParent = nullptr); // standard constructor - ~CResizeResolutionDialog(); - - void SetSize(uint32 dwSize); - uint32 GetSize(); - -private: - ResizeResolutionModel* m_model; - QScopedPointer ui; -}; - -#endif // CRYINCLUDE_EDITOR_RESIZERESOLUTIONDIALOG_H diff --git a/Code/Editor/ResizeResolutionDialog.ui b/Code/Editor/ResizeResolutionDialog.ui deleted file mode 100644 index c958e6acaf..0000000000 --- a/Code/Editor/ResizeResolutionDialog.ui +++ /dev/null @@ -1,58 +0,0 @@ - - - CResizeResolutionDialog - - - - 0 - 0 - 250 - 96 - - - - - - - - - - 0 - 0 - - - - Select resolution: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - - QFrame::HLine - - - QFrame::Sunken - - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - 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/StartupTraceHandler.cpp b/Code/Editor/StartupTraceHandler.cpp index 498bf10e31..407b030e9a 100644 --- a/Code/Editor/StartupTraceHandler.cpp +++ b/Code/Editor/StartupTraceHandler.cpp @@ -37,26 +37,10 @@ namespace SandboxEditor bool StartupTraceHandler::OnPreAssert(const char* fileName, int line, const char* func, const char* message) { - // Asserts are more fatal than errors, and need to be displayed right away. - // After the assert occurs, nothing else may be functional enough to collect and display messages. - - // Only use Cry message boxes if we aren't using native dialog boxes -#ifndef USE_AZ_ASSERT - if (message == nullptr || message[0] == 0) - { - AZStd::string emptyText = AZStd::string::format("Assertion failed in %s %s:%i", func, fileName, line); - OnMessage(emptyText.c_str(), nullptr, MessageDisplayBehavior::AlwaysShow); - } - else - { - OnMessage(message, nullptr, MessageDisplayBehavior::AlwaysShow); - } -#else AZ_UNUSED(fileName); AZ_UNUSED(line); AZ_UNUSED(func); AZ_UNUSED(message); -#endif // !USE_AZ_ASSERT // Return false so other listeners can handle this. The StartupTraceHandler won't report messages // will probably crash before that occurs, because this is an assert. 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/TrackView/TrackViewDialog.cpp b/Code/Editor/TrackView/TrackViewDialog.cpp index d70cbad29e..034e12c098 100644 --- a/Code/Editor/TrackView/TrackViewDialog.cpp +++ b/Code/Editor/TrackView/TrackViewDialog.cpp @@ -1046,7 +1046,12 @@ void CTrackViewDialog::OnAddSequence() AzToolsFramework::ScopedUndoBatch undoBatch("Create TrackView Director Node"); sequenceManager->CreateSequence(sequenceName, sequenceType); CTrackViewSequence* newSequence = sequenceManager->GetSequenceByName(sequenceName); - AZ_Assert(newSequence, "Creating new sequence failed."); + + if (!newSequence) + { + return; + } + undoBatch.MarkEntityDirty(newSequence->GetSequenceComponentEntityId()); // make it the currently selected sequence diff --git a/Code/Editor/Util/ColorUtils.cpp b/Code/Editor/Util/ColorUtils.cpp index 02e3c9b615..eaaea8a2ef 100644 --- a/Code/Editor/Util/ColorUtils.cpp +++ b/Code/Editor/Util/ColorUtils.cpp @@ -6,11 +6,9 @@ * */ - -#include "ColorUtils.h" - // Qt #include +#include ////////////////////////////////////////////////////////////////////////// QColor ColorLinearToGamma(ColorF col) diff --git a/Code/Editor/Util/ColorUtils.h b/Code/Editor/Util/ColorUtils.h deleted file mode 100644 index 9993238e10..0000000000 --- a/Code/Editor/Util/ColorUtils.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -// Description : Utility classes used by Editor. - - -#pragma once - -#include - -class QColor; - -QColor ColorLinearToGamma(ColorF col); -ColorF ColorGammaToLinear(const QColor& col); -QColor ColorToQColor(uint32 color); - diff --git a/Code/Editor/Util/Contrib/NvFloatMath.inl b/Code/Editor/Util/Contrib/NvFloatMath.inl deleted file mode 100644 index 6bd3b9f7c5..0000000000 --- a/Code/Editor/Util/Contrib/NvFloatMath.inl +++ /dev/null @@ -1,455 +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 - * - */ -/* BEGIN CONTENTS OF README.TXT ------------------------------------- -The ConvexDecomposition library was written by John W. Ratcliff mailto:jratcliffscarab@gmail.com - -What is Convex Decomposition? - -Convex Decomposition is when you take an arbitrarily complex triangle mesh and sub-divide it into -a collection of discrete compound pieces (each represented as a convex hull) to approximate -the original shape of the objet. - -This is required since few physics engines can treat aribtrary triangle mesh objects as dynamic -objects. Even those engines which can handle this use case incurr a huge performance and memory -penalty to do so. - -By breaking a complex triangle mesh up into a discrete number of convex components you can greatly -improve performance for dynamic simulations. - --------------------------------------------------------------------------------- - -This code is released under the MIT license. - -The code is functional but could use the following improvements: - -(1) The convex hull generator, originally written by Stan Melax, could use some major code cleanup. - -(2) The code to remove T-junctions appears to have a bug in it. This code was working fine before, -but I haven't had time to debug why it stopped working. - -(3) Island generation once the mesh has been split is currently disabled due to the fact that the -Remove Tjunctions functionality has a bug in it. - -(4) The code to perform a raycast against a triangle mesh does not currently use any acceleration -data structures. - -(5) When a split is performed, the surface that got split is not 'capped'. This causes a problem -if you use a high recursion depth on your convex decomposition. It will cause the object to -be modelled as if it had a hollow interior. A lot of work was done to solve this problem, but -it hasn't been integrated into this code drop yet. - - -*/// ---------- END CONTENTS OF README.TXT ---------------------------- - - -// a set of routines that let you do common 3d math -// operations without any vector, matrix, or quaternion -// classes or templates. -// -// a vector (or point) is a 'NxF32 *' to 3 floating point numbers. -// a matrix is a 'NxF32 *' to an array of 16 floating point numbers representing a 4x4 transformation matrix compatible with D3D or OGL -// a quaternion is a 'NxF32 *' to 4 floats representing a quaternion x,y,z,w -// -// -/*! -** -** Copyright (c) 2009 by John W. Ratcliff mailto:jratcliffscarab@gmail.com -** -** Portions of this source has been released with the PhysXViewer application, as well as -** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. -** -** If you find this code useful or you are feeling particularily generous I would -** ask that you please go to http://www.amillionpixels.us and make a donation -** to Troy DeMolay. -** -** DeMolay is a youth group for young men between the ages of 12 and 21. -** It teaches strong moral principles, as well as leadership skills and -** public speaking. The donations page uses the 'pay for pixels' paradigm -** where, in this case, a pixel is only a single penny. Donations can be -** made for as small as $4 or as high as a $100 block. Each person who donates -** will get a link to their own site as well as acknowledgement on the -** donations blog located here http://www.amillionpixels.blogspot.com/ -** -** If you wish to contact me you can use the following methods: -** -** Skype ID: jratcliff63367 -** Yahoo: jratcliff63367 -** AOL: jratcliff1961 -** email: jratcliffscarab@gmail.com -** -** -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -class TVec -{ -public: - TVec(NxF64 _x, NxF64 _y, NxF64 _z) { x = _x; y = _y; z = _z; }; - TVec(void) { }; - - NxF64 x; - NxF64 y; - NxF64 z; -}; - - -class CTriangulator -{ -public: - /// Default constructor - CTriangulator(); - - /// Default destructor - virtual ~CTriangulator(); - - /// Returns the given point in the triangulator array - inline TVec get(const TU32 id) { return mPoints[id]; } - - virtual void reset(void) - { - mInputPoints.clear(); - mPoints.clear(); - mIndices.clear(); - } - - virtual void addPoint(NxF64 x, NxF64 y, NxF64 z) - { - TVec v(x, y, z); - // update bounding box... - if (mInputPoints.empty()) - { - mMin = v; - mMax = v; - } - else - { - if (x < mMin.x) - { - mMin.x = x; - } - if (y < mMin.y) - { - mMin.y = y; - } - if (z < mMin.z) - { - mMin.z = z; - } - - if (x > mMax.x) - { - mMax.x = x; - } - if (y > mMax.y) - { - mMax.y = y; - } - if (z > mMax.z) - { - mMax.z = z; - } - } - mInputPoints.push_back(v); - } - - // Triangulation happens in 2d. We could inverse transform the polygon around the normal direction, or we just use the two most signficant axes - // Here we find the two longest axes and use them to triangulate. Inverse transforming them would introduce more doubleing point error and isn't worth it. - virtual NxU32* triangulate(NxU32& tcount, NxF64 epsilon) - { - NxU32* ret = 0; - tcount = 0; - mEpsilon = epsilon; - - if (!mInputPoints.empty()) - { - mPoints.clear(); - - NxF64 dx = mMax.x - mMin.x; // locate the first, second and third longest edges and store them in i1, i2, i3 - NxF64 dy = mMax.y - mMin.y; - NxF64 dz = mMax.z - mMin.z; - - NxU32 i1, i2, i3; - - if (dx > dy && dx > dz) - { - i1 = 0; - if (dy > dz) - { - i2 = 1; - i3 = 2; - } - else - { - i2 = 2; - i3 = 1; - } - } - else if (dy > dx && dy > dz) - { - i1 = 1; - if (dx > dz) - { - i2 = 0; - i3 = 2; - } - else - { - i2 = 2; - i3 = 0; - } - } - else - { - i1 = 2; - if (dx > dy) - { - i2 = 0; - i3 = 1; - } - else - { - i2 = 1; - i3 = 0; - } - } - - NxU32 pcount = (NxU32)mInputPoints.size(); - const NxF64* points = &mInputPoints[0].x; - for (NxU32 i = 0; i < pcount; i++) - { - TVec v(points[i1], points[i2], points[i3]); - mPoints.push_back(v); - points += 3; - } - - mIndices.clear(); - triangulate(mIndices); - tcount = (NxU32)mIndices.size() / 3; - if (tcount) - { - ret = &mIndices[0]; - } - } - return ret; - } - - virtual const NxF64* getPoint(NxU32 index) - { - return &mInputPoints[index].x; - } - - -private: - NxF64 mEpsilon; - TVec mMin; - TVec mMax; - TVecVector mInputPoints; - TVecVector mPoints; - TU32Vector mIndices; - - /// Tests if a point is inside the given triangle - bool _insideTriangle(const TVec& A, const TVec& B, const TVec& C, const TVec& P); - - /// Returns the area of the contour - NxF64 _area(); - - bool _snip(NxI32 u, NxI32 v, NxI32 w, NxI32 n, NxI32* V); - - /// Processes the triangulation - void _process(TU32Vector& indices); - /// Triangulates the contour - void triangulate(TU32Vector& indices); -}; - -/// Default constructor -CTriangulator::CTriangulator(void) -{ -} - -/// Default destructor -CTriangulator::~CTriangulator() -{ -} - -/// Triangulates the contour -void CTriangulator::triangulate(TU32Vector& indices) -{ - _process(indices); -} - -/// Processes the triangulation -void CTriangulator::_process(TU32Vector& indices) -{ - const NxI32 n = (const NxI32)mPoints.size(); - if (n < 3) - { - return; - } - NxI32* V = (NxI32*)MEMALLOC_MALLOC(sizeof(NxI32) * n); - - bool flipped = false; - - if (0.0f < _area()) - { - for (NxI32 v = 0; v < n; v++) - { - V[v] = v; - } - } - else - { - flipped = true; - for (NxI32 v = 0; v < n; v++) - { - V[v] = (n - 1) - v; - } - } - - NxI32 nv = n; - NxI32 count = 2 * nv; - for (NxI32 m = 0, v = nv - 1; nv > 2; ) - { - if (0 >= (count--)) - { - return; - } - - NxI32 u = v; - if (nv <= u) - { - u = 0; - } - v = u + 1; - if (nv <= v) - { - v = 0; - } - NxI32 w = v + 1; - if (nv <= w) - { - w = 0; - } - - if (_snip(u, v, w, nv, V)) - { - NxI32 a, b, c, s, t; - a = V[u]; - b = V[v]; - c = V[w]; - if (flipped) - { - indices.push_back(a); - indices.push_back(b); - indices.push_back(c); - } - else - { - indices.push_back(c); - indices.push_back(b); - indices.push_back(a); - } - m++; - for (s = v, t = v + 1; t < nv; s++, t++) - { - V[s] = V[t]; - } - nv--; - count = 2 * nv; - } - } - - MEMALLOC_FREE(V); -} - -/// Returns the area of the contour -NxF64 CTriangulator::_area() -{ - NxI32 n = (NxU32)mPoints.size(); - NxF64 A = 0.0f; - for (NxI32 p = n - 1, q = 0; q < n; p = q++) - { - const TVec& pval = mPoints[p]; - const TVec& qval = mPoints[q]; - A += pval.x * qval.y - qval.x * pval.y; - } - A *= 0.5f; - return A; -} - -bool CTriangulator::_snip(NxI32 u, NxI32 v, NxI32 w, NxI32 n, NxI32* V) -{ - NxI32 p; - - const TVec& A = mPoints[V[u]]; - const TVec& B = mPoints[V[v]]; - const TVec& C = mPoints[V[w]]; - - if (mEpsilon > (((B.x - A.x) * (C.y - A.y)) - ((B.y - A.y) * (C.x - A.x)))) - { - return false; - } - - for (p = 0; p < n; p++) - { - if ((p == u) || (p == v) || (p == w)) - { - continue; - } - const TVec& P = mPoints[V[p]]; - if (_insideTriangle(A, B, C, P)) - { - return false; - } - } - return true; -} - -/// Tests if a point is inside the given triangle -bool CTriangulator::_insideTriangle(const TVec& A, const TVec& B, const TVec& C, const TVec& P) -{ - NxF64 ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy; - NxF64 cCROSSap, bCROSScp, aCROSSbp; - - ax = C.x - B.x; - ay = C.y - B.y; - bx = A.x - C.x; - by = A.y - C.y; - cx = B.x - A.x; - cy = B.y - A.y; - apx = P.x - A.x; - apy = P.y - A.y; - bpx = P.x - B.x; - bpy = P.y - B.y; - cpx = P.x - C.x; - cpy = P.y - C.y; - - aCROSSbp = ax * bpy - ay * bpx; - cCROSSap = cx * apy - cy * apx; - bCROSScp = bx * cpy - by * cpx; - - return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f)); -} - diff --git a/Code/Editor/Util/DynamicArray2D.cpp b/Code/Editor/Util/DynamicArray2D.cpp deleted file mode 100644 index 3f09c557de..0000000000 --- a/Code/Editor/Util/DynamicArray2D.cpp +++ /dev/null @@ -1,150 +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 "DynamicArray2D.h" - -// Editor -#include "Util/fastlib.h" - -////////////////////////////////////////////////////////////////////// -// Construction / destruction -////////////////////////////////////////////////////////////////////// - -CDynamicArray2D::CDynamicArray2D(unsigned int iDimension1, unsigned int iDimension2) -{ - //////////////////////////////////////////////////////////////////////// - // Declare a 2D array on the free store - //////////////////////////////////////////////////////////////////////// - - unsigned int i; - - // Save the position of the array dimensions - m_Dimension1 = iDimension1; - m_Dimension2 = iDimension2; - - // First dimension - m_Array = new float* [m_Dimension1]; - assert(m_Array); - - // Second dimension - for (i = 0; i < m_Dimension1; ++i) - { - m_Array[i] = new float[m_Dimension2]; - - // Init all fields with 0 - memset(&m_Array[i][0], 0, m_Dimension2 * sizeof(float)); - } -} - -CDynamicArray2D::~CDynamicArray2D() -{ - //////////////////////////////////////////////////////////////////////// - // Remove the 2D array and all its sub arrays from the free store - //////////////////////////////////////////////////////////////////////// - - unsigned int i; - - for (i = 0; i < m_Dimension1; ++i) - { - delete [] m_Array[i]; - } - - delete [] m_Array; - m_Array = nullptr; -} - - -void CDynamicArray2D::ScaleImage(CDynamicArray2D* pDestination) -{ - //////////////////////////////////////////////////////////////////////// - // Scale an image stored (in an array class) to a new size - //////////////////////////////////////////////////////////////////////// - - unsigned int i, j, iOldWidth; - int iXSrcFl, iXSrcCe, iYSrcFl, iYSrcCe; - float fXSrc, fYSrc; - float fHeight[4]; - float fHeightWeight[4]; - float fHeightBottom; - float fHeightTop; - - assert(pDestination); - assert(pDestination->m_Dimension1 > 1); - - // Width has to be zero based, not a count - iOldWidth = m_Dimension1 - 1; - - // Loop trough each field of the new image and interpolate the value - // from the source heightmap - for (i = 0; i < pDestination->m_Dimension1; i++) - { - // Calculate the average source array position - fXSrc = i / (float) pDestination->m_Dimension1 * iOldWidth; - assert(fXSrc >= 0.0f && fXSrc <= iOldWidth); - - // Precalculate floor and ceiling values. Use fast asm integer floor and - // fast asm float / integer conversion - iXSrcFl = ifloor(fXSrc); - iXSrcCe = FloatToIntRet((float) ceil(fXSrc)); - - // Distribution between left and right height values - fHeightWeight[0] = (float) iXSrcCe - fXSrc; - fHeightWeight[1] = fXSrc - (float) iXSrcFl; - - // Avoid error when floor() and ceil() return the same value - if (fHeightWeight[0] == 0.0f && fHeightWeight[1] == 0.0f) - { - fHeightWeight[0] = 0.5f; - fHeightWeight[1] = 0.5f; - } - - for (j = 0; j < pDestination->m_Dimension1; j++) - { - // Calculate the average source array position - fYSrc = j / (float) pDestination->m_Dimension1 * iOldWidth; - assert(fYSrc >= 0.0f && fYSrc <= iOldWidth); - - // Precalculate floor and ceiling values. Use fast asm integer floor and - // fast asm float / integer conversion - iYSrcFl = ifloor(fYSrc); - iYSrcCe = FloatToIntRet((float) ceil(fYSrc)); - - // Get the four nearest height values - fHeight[0] = m_Array[iXSrcFl][iYSrcFl]; - fHeight[1] = m_Array[iXSrcCe][iYSrcFl]; - fHeight[2] = m_Array[iXSrcFl][iYSrcCe]; - fHeight[3] = m_Array[iXSrcCe][iYSrcCe]; - - // Calculate how much weight each height value has - - // Distribution between top and bottom height values - fHeightWeight[2] = (float) iYSrcCe - fYSrc; - fHeightWeight[3] = fYSrc - (float) iYSrcFl; - - // Avoid error when floor() and ceil() return the same value - if (fHeightWeight[2] == 0.0f && fHeightWeight[3] == 0.0f) - { - fHeightWeight[2] = 0.5f; - fHeightWeight[3] = 0.5f; - } - - // Interpolate between the four nearest height values - - // Get the height for the given X position trough interpolation between - // the left and the right height - fHeightBottom = (fHeight[0] * fHeightWeight[0] + fHeight[1] * fHeightWeight[1]); - fHeightTop = (fHeight[2] * fHeightWeight[0] + fHeight[3] * fHeightWeight[1]); - - // Set the new value in the destination heightmap - pDestination->m_Array[i][j] = fHeightBottom * fHeightWeight[2] + fHeightTop * fHeightWeight[3]; - } - } -} diff --git a/Code/Editor/Util/DynamicArray2D.h b/Code/Editor/Util/DynamicArray2D.h deleted file mode 100644 index 20d26d2d87..0000000000 --- a/Code/Editor/Util/DynamicArray2D.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -// Description : Interface of the class CDynamicArray. - - -#ifndef CRYINCLUDE_EDITOR_UTIL_DYNAMICARRAY2D_H -#define CRYINCLUDE_EDITOR_UTIL_DYNAMICARRAY2D_H -#pragma once - - -class CDynamicArray2D -{ -public: - // constructor - CDynamicArray2D(unsigned int iDimension1, unsigned int iDimension2); - // destructor - virtual ~CDynamicArray2D(); - // - void ScaleImage(CDynamicArray2D* pDestination); - - - float** m_Array; // - -private: - - unsigned int m_Dimension1; // - unsigned int m_Dimension2; // -}; - -#endif // CRYINCLUDE_EDITOR_UTIL_DYNAMICARRAY2D_H diff --git a/Code/Editor/Util/GdiUtil.cpp b/Code/Editor/Util/GdiUtil.cpp deleted file mode 100644 index 72e5e28605..0000000000 --- a/Code/Editor/Util/GdiUtil.cpp +++ /dev/null @@ -1,179 +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 "GdiUtil.h" - -// Qt -#include -#include - -QColor ScaleColor(const QColor& c, float aScale) -{ - QColor aColor = c; - if (!aColor.isValid()) - { - // help out scaling, by starting at very low black - aColor = QColor(1, 1, 1); - } - - const float r = static_cast(aColor.red()) * aScale; - const float g = static_cast(aColor.green()) * aScale; - const float b = static_cast(aColor.blue()) * aScale; - - return QColor(AZStd::clamp(static_cast(r), 0, 255), AZStd::clamp(static_cast(g), 0, 255), AZStd::clamp(static_cast(b), 0, 255)); -} - -CAlphaBitmap::CAlphaBitmap() -{ - m_width = m_height = 0; -} - -CAlphaBitmap::~CAlphaBitmap() -{ - Free(); -} - -bool CAlphaBitmap::Create(void* pData, UINT aWidth, UINT aHeight, bool bVerticalFlip, bool bPremultiplyAlpha) -{ - if (!aWidth || !aHeight) - { - return false; - } - - m_bmp = QImage(aWidth, aHeight, QImage::Format_RGBA8888); - if (m_bmp.isNull()) - { - return false; - } - - std::vector vBuffer; - - if (pData) - { - // copy over the raw 32bpp data - bVerticalFlip = !bVerticalFlip; // in Qt, the flip is not required. Still, keep the API behaving the same - if (bVerticalFlip) - { - UINT nBufLen = aWidth * aHeight; - vBuffer.resize(nBufLen); - - if (IsBadReadPtr(pData, nBufLen * 4)) - { - //TODO: remove after testing alot the browser, it doesnt happen anymore - QMessageBox::critical(QApplication::activeWindow(), QString(), QObject::tr("Bad image data ptr!")); - Free(); - return false; - } - - assert(!vBuffer.empty()); - - if (vBuffer.empty()) - { - Free(); - return false; - } - - UINT scanlineSize = aWidth * 4; - - for (UINT i = 0, iCount = aHeight; i < iCount; ++i) - { - // top scanline position - UINT* pTopScanPos = (UINT*)&vBuffer[0] + i * aWidth; - // bottom scanline position - UINT* pBottomScanPos = (UINT*)pData + (aHeight - i - 1) * aWidth; - - // save a scanline from top - memcpy(pTopScanPos, pBottomScanPos, scanlineSize); - } - - pData = &vBuffer[0]; - } - - // premultiply alpha, AlphaBlend GDI expects it - if (bPremultiplyAlpha) - { - for (UINT y = 0; y < aHeight; ++y) - { - BYTE* pPixel = (BYTE*) pData + aWidth * 4 * y; - - for (UINT x = 0; x < aWidth; ++x) - { - pPixel[0] = ((int)pPixel[0] * pPixel[3] + 127) >> 8; - pPixel[1] = ((int)pPixel[1] * pPixel[3] + 127) >> 8; - pPixel[2] = ((int)pPixel[2] * pPixel[3] + 127) >> 8; - pPixel += 4; - } - } - } - - memcpy(m_bmp.bits(), pData, aWidth * aHeight * 4); - - if (m_bmp.isNull()) - { - return false; - } - } - else - { - m_bmp.fill(Qt::transparent); - } - - // we dont need this screen DC anymore - m_width = aWidth; - m_height = aHeight; - - return true; -} - -QImage& CAlphaBitmap::GetBitmap() -{ - return m_bmp; -} - -void CAlphaBitmap::Free() -{ - -} - -UINT CAlphaBitmap::GetWidth() -{ - return m_width; -} - -UINT CAlphaBitmap::GetHeight() -{ - return m_height; -} - -void CheckerboardFillRect(QPainter* pGraphics, const QRect& rRect, int checkDiameter, const QColor& aColor1, const QColor& aColor2) -{ - pGraphics->save(); - pGraphics->setClipRect(rRect); - // Create a checkerboard background for easier readability - pGraphics->fillRect(rRect, aColor1); - QBrush lightBrush(aColor2); - - // QRect bottom/right methods are short one unit for legacy reasons. Compute bottomr/right of the rectange ourselves to get the full size. - const int rectRight = rRect.x() + rRect.width(); - const int rectBottom = rRect.y() + rRect.height(); - - for (int i = rRect.left(); i < rectRight; i += checkDiameter) - { - for (int j = rRect.top(); j < rectBottom; j += checkDiameter) - { - if ((i / checkDiameter) % 2 ^ (j / checkDiameter) % 2) - { - pGraphics->fillRect(QRect(i, j, checkDiameter, checkDiameter), lightBrush); - } - } - } - pGraphics->restore(); -} diff --git a/Code/Editor/Util/GdiUtil.h b/Code/Editor/Util/GdiUtil.h deleted file mode 100644 index f38cbc0c0e..0000000000 --- a/Code/Editor/Util/GdiUtil.h +++ /dev/null @@ -1,54 +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 : Utilitarian classes for double buffer GDI rendering and 32bit bitmaps - - -#ifndef CRYINCLUDE_EDITOR_UTIL_GDIUTIL_H -#define CRYINCLUDE_EDITOR_UTIL_GDIUTIL_H -#pragma once - -QColor ScaleColor(const QColor& coor, float aScale); - -//! This class loads alpha-channel bitmaps and holds a DC for use with AlphaBlend function -class CRYEDIT_API CAlphaBitmap -{ -public: - - CAlphaBitmap(); - ~CAlphaBitmap(); - - //! creates the bitmap from raw 32bpp data - //! \param pData the 32bpp raw image data, RGBA, can be nullptr and it would create just an empty bitmap - //! \param aWidth the bitmap width - //! \param aHeight the bitmap height - bool Create(void* pData, UINT aWidth, UINT aHeight, bool bVerticalFlip = false, bool bPremultiplyAlpha = false); - //! \return the actual bitmap - QImage& GetBitmap(); - //! free the bitmap and DC - void Free(); - //! \return bitmap width - UINT GetWidth(); - //! \return bitmap height - UINT GetHeight(); - -protected: - - QImage m_bmp; - UINT m_width, m_height; -}; - -//! Fill a rectangle with a checkerboard pattern. -//! \param pGraphics The Graphics object used for drawing -//! \param rRect The rectangle to be filled -//! \param checkDiameter the diameter of the check squares -//! \param aColor1 the color that starts in the top left corner check square -//! \param aColor2 the second color used for check squares -void CheckerboardFillRect(QPainter* pGraphics, const QRect& rRect, int checkDiameter, const QColor& aColor1, const QColor& aColor2); -#endif // CRYINCLUDE_EDITOR_UTIL_GDIUTIL_H diff --git a/Code/Editor/Util/GuidUtil.cpp b/Code/Editor/Util/GuidUtil.cpp index 5f81eac88e..dbd7d4c371 100644 --- a/Code/Editor/Util/GuidUtil.cpp +++ b/Code/Editor/Util/GuidUtil.cpp @@ -6,12 +6,35 @@ * */ - -#include "EditorDefs.h" - #include "GuidUtil.h" +const char* GuidUtil::ToString(REFGUID guid) +{ + static char guidString[64]; + azsprintf(guidString, "{%.8" GUID_FORMAT_DATA1 "-%.4X-%.4X-%.2X%.2X-%.2X%.2X%.2X%.2X%.2X%.2X}", guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], + guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); + return guidString; +} + ////////////////////////////////////////////////////////////////////////// -const GUID GuidUtil::NullGuid = { - 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } -}; +GUID GuidUtil::FromString(const char* guidString) +{ + GUID guid; + unsigned int d[8]; + memset(&d, 0, sizeof(guid)); + guid.Data1 = 0; + guid.Data2 = 0; + guid.Data3 = 0; + azsscanf(guidString, "{%8" GUID_FORMAT_DATA1 "-%4hX-%4hX-%2X%2X-%2X%2X%2X%2X%2X%2X}", + &guid.Data1, &guid.Data2, &guid.Data3, &d[0], &d[1], &d[2], &d[3], &d[4], &d[5], &d[6], &d[7]); + guid.Data4[0] = static_cast(d[0]); + guid.Data4[1] = static_cast(d[1]); + guid.Data4[2] = static_cast(d[2]); + guid.Data4[3] = static_cast(d[3]); + guid.Data4[4] = static_cast(d[4]); + guid.Data4[5] = static_cast(d[5]); + guid.Data4[6] = static_cast(d[6]); + guid.Data4[7] = static_cast(d[7]); + + return guid; +} diff --git a/Code/Editor/Util/GuidUtil.h b/Code/Editor/Util/GuidUtil.h index de2bad8759..762b556f44 100644 --- a/Code/Editor/Util/GuidUtil.h +++ b/Code/Editor/Util/GuidUtil.h @@ -14,7 +14,12 @@ #define CRYINCLUDE_EDITOR_UTIL_GUIDUTIL_H #pragma once -#include "AzCore/Math/Uuid.h" +#include + +#ifndef _REFGUID_DEFINED +#define _REFGUID_DEFINED +typedef const GUID& REFGUID; +#endif struct GuidUtil { @@ -23,9 +28,6 @@ struct GuidUtil static const char* ToString(REFGUID guid); //! Convert from guid string in valid format to GUID class. static GUID FromString(const char* guidString); - static bool IsEmpty(REFGUID guid); - - static const GUID NullGuid; }; /** Used to compare GUID keys. @@ -38,42 +40,4 @@ struct guid_less_predicate } }; -////////////////////////////////////////////////////////////////////////// -inline bool GuidUtil::IsEmpty(REFGUID guid) -{ - return guid == NullGuid; -} - -////////////////////////////////////////////////////////////////////////// -inline const char* GuidUtil::ToString(REFGUID guid) -{ - static char guidString[64]; - sprintf_s(guidString, "{%.8" GUID_FORMAT_DATA1 "-%.4X-%.4X-%.2X%.2X-%.2X%.2X%.2X%.2X%.2X%.2X}", guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], - guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); - return guidString; -} - -////////////////////////////////////////////////////////////////////////// -inline GUID GuidUtil::FromString(const char* guidString) -{ - GUID guid; - unsigned int d[8]; - memset(&d, 0, sizeof(guid)); - guid.Data1 = 0; - guid.Data2 = 0; - guid.Data3 = 0; - azsscanf(guidString, "{%8" GUID_FORMAT_DATA1 "-%4hX-%4hX-%2X%2X-%2X%2X%2X%2X%2X%2X}", - &guid.Data1, &guid.Data2, &guid.Data3, &d[0], &d[1], &d[2], &d[3], &d[4], &d[5], &d[6], &d[7]); - guid.Data4[0] = static_cast(d[0]); - guid.Data4[1] = static_cast(d[1]); - guid.Data4[2] = static_cast(d[2]); - guid.Data4[3] = static_cast(d[3]); - guid.Data4[4] = static_cast(d[4]); - guid.Data4[5] = static_cast(d[5]); - guid.Data4[6] = static_cast(d[6]); - guid.Data4[7] = static_cast(d[7]); - - return guid; -} - #endif // CRYINCLUDE_EDITOR_UTIL_GUIDUTIL_H diff --git a/Code/Editor/Util/IObservable.h b/Code/Editor/Util/IObservable.h deleted file mode 100644 index 5fa7201c80..0000000000 --- a/Code/Editor/Util/IObservable.h +++ /dev/null @@ -1,20 +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 : Handy macro when working with observers in interfaces - - -#ifndef CRYINCLUDE_EDITOR_UTIL_IOBSERVABLE_H -#define CRYINCLUDE_EDITOR_UTIL_IOBSERVABLE_H -#pragma once -#define DEFINE_OBSERVABLE_PURE_METHODS(observerClassName) \ - virtual bool RegisterObserver(observerClassName * pObserver) = 0; \ - virtual bool UnregisterObserver(observerClassName * pObserver) = 0; \ - virtual void UnregisterAllObservers() = 0; -#endif // CRYINCLUDE_EDITOR_UTIL_IOBSERVABLE_H diff --git a/Code/Editor/Util/ImageASC.cpp b/Code/Editor/Util/ImageASC.cpp deleted file mode 100644 index 1c4a8acf73..0000000000 --- a/Code/Editor/Util/ImageASC.cpp +++ /dev/null @@ -1,190 +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 "ImageASC.h" - -// Editor -#include "Util/Image.h" - -//--------------------------------------------------------------------------- - -bool CImageASC::Save(const QString& fileName, const CFloatImage& image) -{ - // There are two types of ARCGrid file formats - binary (ADF) and ASCII (ASC). - // See here: https://en.wikipedia.org/wiki/Esri_grid - - uint32 width = image.GetWidth(); - uint32 height = image.GetHeight(); - float* pixels = image.GetData(); - - AZStd::string fileHeader = AZStd::string::format( - // Number of columns and rows in the data - "ncols %d\n" - "nrows %d\n" - - // The coordinates of the bottom-left corner. - // These numbers represent coordinates on a globe, so this choice of values is arbitrary. - "xllcorner 0.0\n" - "yllcorner 0.0\n" - - // The size of each grid square. - // The problem is that cellsize represents the size of a square on a grid being projected onto a globe. - // This number can be used to convert size to degrees, based on where on the globe it appears. - // We don't have a real-world location associated with our data, so this size choice is arbitrary. - "cellsize 0.0003\n" - - // The value used for missing data. Since we shouldn't have any missing data, we'll choose a value that can't appear below. - "nodata_value -1\n" - , width, height); - - FILE* file = nullptr; - azfopen(&file, fileName.toUtf8().data(), "wt"); - if (!file) - { - return false; - } - - // First print the file header - fprintf(file, "%s", fileHeader.c_str()); - - // Then print all the pixels. - for (uint32 y = 0; y < height; y++) - { - for (uint32 x = 0; x < width; x++) - { - fprintf(file, "%.7f ", pixels[x + y * width]); - } - fprintf(file, "\n"); - } - - fclose(file); - return true; -} - -//--------------------------------------------------------------------------- - -bool CImageASC::Load(const QString& fileName, CFloatImage& image) -{ - FILE* file = nullptr; - azfopen(&file, fileName.toUtf8().data(), "rt"); - if (!file) - { - return false; - } - - const char seps[] = " \r\n\t"; - char* token; - - int32 width = 0; - int32 height = 0; - float nodataValue = 0.0f; - - bool validData = true; - - // Read the file into memory - - fseek(file, 0, SEEK_END); - int fileSize = ftell(file); - fseek(file, 0, SEEK_SET); - - char* str = new char[fileSize]; - fread(str, fileSize, 1, file); - - // Break all of the values in the file apart into tokens. - - [[maybe_unused]] char* nextToken = nullptr; - token = azstrtok(str, 0, seps, &nextToken); - - // ncols = grid width - validData = validData && (azstricmp(token, "ncols") == 0); - token = azstrtok(nullptr, 0, seps, &nextToken); - width = atoi(token); - - // nrows = grid height - token = azstrtok(nullptr, 0, seps, &nextToken); - validData = validData && (azstricmp(token, "nrows") == 0); - token = azstrtok(nullptr, 0, seps, &nextToken); - height = atoi(token); - - // xllcorner = leftmost coordinate. (Skip, we don't care about it) - token = azstrtok(nullptr, 0, seps, &nextToken); - validData = validData && (azstricmp(token, "xllcorner") == 0); - token = azstrtok(nullptr, 0, seps, &nextToken); - - // yllcorner = bottommost coordinate. (Skip, we don't care about it) - token = azstrtok(nullptr, 0, seps, &nextToken); - validData = validData && (azstricmp(token, "yllcorner") == 0); - token = azstrtok(nullptr, 0, seps, &nextToken); - - // cellsize = size of each grid cell. (Skip, we don't care about it) - token = azstrtok(nullptr, 0, seps, &nextToken); - validData = validData && (azstricmp(token, "cellsize") == 0); - token = azstrtok(nullptr, 0, seps, &nextToken); - - // nodata_value = the value used for missing data. We'll replace these with 0 height. - token = azstrtok(nullptr, 0, seps, &nextToken); - validData = validData && (azstricmp(token, "nodata_value") == 0); - token = azstrtok(nullptr, 0, seps, &nextToken); - nodataValue = static_cast(atof(token)); - - if (!validData) - { - // Bad file. not supported asc. - delete[]str; - fclose(file); - return false; - } - - image.Allocate(width, height); - - // Read in the pixel data - - float* p = image.GetData(); - int size = width * height; - int i = 0; - float pixelValue; - float maxPixel = 0.0f; - while (token != nullptr && i < size) - { - token = azstrtok(nullptr, 0, seps, &nextToken); - if (token != nullptr) - { - // Negative heights aren't supported, clamp to 0. - pixelValue = max(0.0f, static_cast(atof(token))); - - // If this is a location we specifically don't have data for, set it to 0. - if (pixelValue == nodataValue) - { - pixelValue = 0.0f; - } - - *p++ = pixelValue; - maxPixel = max(maxPixel, pixelValue); - i++; - } - } - - if (maxPixel > 0.0f) - { - // Scale our range down to 0 - 1 - float* pp = image.GetData(); - for (i = 0; i < size; i++) - { - pp[i] = clamp_tpl(pp[i] / maxPixel, 0.0f, 1.0f); - } - } - - delete[]str; - - fclose(file); - - return true; -} - diff --git a/Code/Editor/Util/ImageASC.h b/Code/Editor/Util/ImageASC.h deleted file mode 100644 index 4570145dcf..0000000000 --- a/Code/Editor/Util/ImageASC.h +++ /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 - * - */ - -#ifndef CRYINCLUDE_EDITOR_UTIL_IMAGEASC_H -#define CRYINCLUDE_EDITOR_UTIL_IMAGEASC_H -#pragma once - -#include "Util/Image.h" - -class SANDBOX_API CImageASC -{ -public: - bool Load(const QString& fileName, CFloatImage& outImage); - bool Save(const QString& fileName, const CFloatImage& image); -}; - - -#endif // CRYINCLUDE_EDITOR_UTIL_IMAGEASC_H diff --git a/Code/Editor/Util/ImageBT.cpp b/Code/Editor/Util/ImageBT.cpp deleted file mode 100644 index eb54213cf1..0000000000 --- a/Code/Editor/Util/ImageBT.cpp +++ /dev/null @@ -1,207 +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 "ImageBT.h" - -//--------------------------------------------------------------------------- -// Load and save the VTP Binary Terrain (BT) format, documented here: -// http://vterrain.org/Implementation/Formats/BT.html - -// This structure represents a binary layout in the file. To direct load & save it, we need to remove all structure memory padding -#pragma pack(push,1) -struct BtHeader -{ - char headerTag[7]; // Should be "binterr" - char headerTagVersion[3]; // Should be "1.3" - int32 columns; // # of columns in the heightfield - int32 rows; // # of rows in the heightfield - int16 bytesPerPoint; // bytes per height value, either 2 for signed ints or 4 for floats - int16 isFloatingPointData; // 1 if height values are floats, 0 for 16-bit signed ints - int16 horizUnits; // 0 if degrees, 1 if meters, 2 if international feet, 3 if US survey feet - int16 utmZone; // UTM projection zone 1 to 60 or -1 to -60 (see https://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system ) - int16 datum; // Datum value (6001 to 6094), see http://www.epsg.org/ - double leftExtent; // left coordinate projection of the file - double rightExtent; // right coordinate projection of the file - double bottomExtent; // bottom coordinate projection of the file - double topExtent; // top coordinate projection of the file - int16 externalProjection; // 1 if projection is in an external .prj file, 0 if it's contained in the header - float scale; // vertical units in meters. 0.0 should be treated as 1.0 - char unused[190]; -}; -#pragma pack(pop) - -bool CImageBT::Save(const QString& fileName, const CFloatImage& image) -{ - int width = image.GetWidth(); - int height = image.GetHeight(); - - float *pixels = image.GetData(); - - // Create a header with reasonable default values. - BtHeader header = - { - {'b', 'i', 'n', 't', 'e', 'r', 'r'}, - {'1', '.', '3' }, - width, - height, - sizeof(float), // we'll use floats to make sure we can capture the full potential range of heightfield values - 1, // use floats - 1, // units are meters - 0, // no UTM projection zone - 6326, // WGS84 Datum value. Recommended by VTP as the default if you don't care about Datum values. - 0.0, // set the left extent to 0? - double(width), // set the right extent to the width? (assumes 1 m per pixel) - double(height), // set the bottom extent to the height? (assumes 1 m per pixel) - 0.0, // set the top extent to 0? - 0, // no external prj file - 1.0f - }; - - memset(header.unused, 0, sizeof(header.unused)); - - FILE* file = nullptr; - azfopen(&file, fileName.toUtf8().data(), "wb"); - if (!file) - { - return false; - } - - fwrite(&header, sizeof(header), 1, file); - for (int32 y = 0; y < height; y++) - { - for (int32 x = 0; x < width; x++) - { - float heightmapValue = pixels[(y * width) + x]; - fwrite(&heightmapValue, sizeof(float), 1, file); - } - } - - fclose(file); - return true; -} - -//--------------------------------------------------------------------------- - -bool CImageBT::Load(const QString& fileName, CFloatImage& image) -{ - FILE* file = nullptr; - azfopen(&file, fileName.toUtf8().data(), "rb"); - if (!file) - { - return false; - } - - // Get the file size - - fseek(file, 0, SEEK_END); - int fileSize = ftell(file); - fseek(file, 0, SEEK_SET); - - // Our file needs to be at least as big as the BT file header. - if (fileSize < sizeof(BtHeader)) - { - return false; - } - - // Get the BT header data - BtHeader header; - memset(&header, 0, sizeof(BtHeader)); // C4701 potentially uninitialized local variable 'header' used - bool validData = true; - validData = validData && (fread(&header, sizeof(BtHeader), 1, file) != 0); - - // Do some quick error-checking on the header to make sure it meets our expectations - - // Does the header have the right header tag? (binterr1.0 - binterr1.3) - validData = validData && (memcmp(header.headerTag, "binterr", sizeof(header.headerTag)) == 0); - validData = validData && (header.headerTagVersion[0] == '1') && (header.headerTagVersion[1] == '.') && (header.headerTagVersion[2] >= '0') && (header.headerTagVersion[2] <= '3'); - - // Will the grid fit into a reasonable image size? - validData = validData && (header.columns >= 0) && (header.columns < 65536); - validData = validData && (header.rows >= 0) && (header.rows < 65536); - - // Do we either have 32-bit floats or 16-bit ints? - validData = validData && (((header.isFloatingPointData == 1) && (header.bytesPerPoint == 4)) || ((header.isFloatingPointData == 0) && (header.bytesPerPoint == 2))); - - // Is the remaining data exactly the size needed to fill our image? - validData = validData && ((fileSize - sizeof(BtHeader)) == (header.columns * header.rows * header.bytesPerPoint)); - - if (!validData) - { - fclose(file); - return false; - } - - if (header.scale == 0.0f) - { - header.scale = 1.0f; - } - - // The BT format defines the data as stored in column-first order, from bottom to top. - // However, some BT files store the data in row-first order, from top to bottom. - // There isn't anything that clearly specifies which type of file it is. If you load it the wrong way, - // the data will look like a bunch of wavy stripes. - // The only difference I've found in test files is datum values above 8000, which appears to be an invalid value for datum - // (it should be 6001-6904 according to the BT definition) - const int invalidDatumValueDenotingColumnFirstData = 8000; - bool isColumnFirstData = (header.datum >= invalidDatumValueDenotingColumnFirstData) ? true : false; - float height = 0.0f; - int imageWidth, imageHeight; - - if (isColumnFirstData) - { - imageWidth = header.rows; - imageHeight = header.columns; - } - else - { - imageWidth = header.columns; - imageHeight = header.rows; - } - - - image.Allocate(imageWidth, imageHeight); - float* p = image.GetData(); - float maxPixel = 0.0f; - - // Read in the pixel data - for (int32 y = 0; y < imageHeight; y++) - { - for (int32 x = 0; x < imageWidth; x++) - { - if (header.isFloatingPointData) - { - fread(&height, sizeof(float), 1, file); - } - else - { - int16 intHeight = 0; - fread(&intHeight, sizeof(int16), 1, file); - height = static_cast(intHeight); - } - // Scale based on what our header defines, and clamp the values to positive range, negatives not supported - p[(y * imageWidth) + x] = max((height * header.scale), 0.0f); - maxPixel = max(maxPixel, p[(y * imageWidth) + x]); - } - } - - // Scale our range down to 0 - 1 - if (maxPixel > 0.0f) - { - p = image.GetData(); - for (int32 i = 0; i < (imageWidth * imageHeight); i++) - { - p[i] = clamp_tpl(p[i] / maxPixel, 0.0f, 1.0f); - } - } - - fclose(file); - return true; -} - diff --git a/Code/Editor/Util/ImageBT.h b/Code/Editor/Util/ImageBT.h deleted file mode 100644 index dc7061527a..0000000000 --- a/Code/Editor/Util/ImageBT.h +++ /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 - * - */ - -#ifndef CRYINCLUDE_EDITOR_UTIL_IMAGEBT_H -#define CRYINCLUDE_EDITOR_UTIL_IMAGEBT_H -#pragma once - -#include "Util/Image.h" - -class SANDBOX_API CImageBT -{ -public: - bool Load(const QString& fileName, CFloatImage& outImage); - bool Save(const QString& fileName, const CFloatImage& image); -}; - - -#endif // CRYINCLUDE_EDITOR_UTIL_IMAGEBT_H diff --git a/Code/Editor/Util/ImagePainter.cpp b/Code/Editor/Util/ImagePainter.cpp deleted file mode 100644 index 37cf5d000c..0000000000 --- a/Code/Editor/Util/ImagePainter.cpp +++ /dev/null @@ -1,350 +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 "ImagePainter.h" - -// Editor -#include "Terrain/Heightmap.h" -#include "Terrain/Layer.h" - -SEditorPaintBrush::SEditorPaintBrush(CHeightmap& rHeightmap, CLayer& rLayer, - const bool bMaskByLayerSettings, const uint32 dwLayerIdMask, const bool bFlood) - : bBlended(true) - , m_rHeightmap(rHeightmap) - , m_rLayer(rLayer) - , m_cFilterColor(1, 1, 1) - , m_dwLayerIdMask(dwLayerIdMask) - , m_bFlood(bFlood) -{ - if (bMaskByLayerSettings) - { - m_fMinAltitude = m_rLayer.GetLayerStart(); - m_fMaxAltitude = m_rLayer.GetLayerEnd(); - m_fMinSlope = tan(m_rLayer.GetLayerMinSlopeAngle() / 90.1f * g_PI / 2.0f); // 0..90 -> 0..~1/0 - m_fMaxSlope = tan(m_rLayer.GetLayerMaxSlopeAngle() / 90.1f * g_PI / 2.0f); // 0..90 -> 0..~1/0 - } - else - { - m_fMinAltitude = -FLT_MAX; - m_fMaxAltitude = FLT_MAX; - m_fMinSlope = 0; - m_fMaxSlope = FLT_MAX; - } -} - -float SEditorPaintBrush::GetMask(const float fX, const float fY) const -{ - // Our expectation is that fX and fY are values of [0, 1) (i.e. includes 0, excludes 1). - // We're mapping this back to an int range where the width & height are generally powers of 2. So for example, we're mapping to 0 - 1023. - // To preserve maximum precision in our floats, and for ease of understanding, we're going to expect that our floats actually represent - // the 0 - 1024 range (i.e. 1 is 1024, not 1023), so that way each increment of a float is 1/1024 instead of 1/1023. This means that a value - // of 1 that's passed in is off the right edge of our range and technically invalid, so we'll just clamp if that happens. - int iX = AZStd::clamp(static_cast(fX * m_rHeightmap.GetWidth()), static_cast(0), static_cast(m_rHeightmap.GetWidth() - 1)); - int iY = AZStd::clamp(static_cast(fY * m_rHeightmap.GetHeight()), static_cast(0), static_cast(m_rHeightmap.GetHeight() - 1)); - - float fAltitude = m_rHeightmap.GetZInterpolated(fX * m_rHeightmap.GetWidth(), fY * m_rHeightmap.GetHeight()); - - // Check if altitude is within brush min/max altitude - if (fAltitude < m_fMinAltitude || fAltitude > m_fMaxAltitude) - { - return 0; - } - - float fSlope = m_rHeightmap.GetAccurateSlope(fX * m_rHeightmap.GetWidth(), fY * m_rHeightmap.GetHeight()); - - // Check if slope is within brush min/max slope - if (fSlope < m_fMinSlope || fSlope > m_fMaxSlope) - { - return 0; - } - - // Soft slope test - // float fSlopeAplha = 1.f; - // fSlopeAplha *= CLAMP((m_fMaxSlope-fSlope)*4 + 0.25f,0,1); - // fSlopeAplha *= CLAMP((fSlope-m_fMinSlope)*4 + 0.25f,0,1); - - if (m_dwLayerIdMask != 0xffffffff) - { - LayerWeight weight = m_rHeightmap.GetLayerWeightAt(iX, iY); - - if ((weight.PrimaryId() & CLayer::e_undefined) != m_dwLayerIdMask) - { - return 0; - } - } - - return 1; -} - - -////////////////////////////////////////////////////////////////////////// -void CImagePainter::PaintBrush(const float fpx, const float fpy, TImage& image, const SEditorPaintBrush& brush) -{ - float fX = fpx * image.GetWidth(), fY = fpy * image.GetHeight(); - - // By using 1/width and 1/height as our scale, this means we're expecting to generate values of [0, 1). - // i.e. we're expecting to generate 0/width to (width-1)/width, and 0/height to (height-1)/height. - // This aligns with the expectations of how GetMask() will use these values. - const float fScaleX = 1.0f / image.GetWidth(); - const float fScaleY = 1.0f / image.GetHeight(); - - //////////////////////////////////////////////////////////////////////// - // Draw an attenuated spot on the map - //////////////////////////////////////////////////////////////////////// - float fMaxDist, fAttenuation, fYSquared; - float fHardness = brush.hardness; - - unsigned int pos; - - LayerWeight* sourceData = image.GetData(); - - // Calculate the maximum distance - fMaxDist = brush.fRadius * image.GetWidth(); - - assert(image.GetWidth() == image.GetHeight()); - - int width = image.GetWidth(); - int height = image.GetHeight(); - - int iMinX = (int)floor(fX - fMaxDist), iMinY = (int)floor(fY - fMaxDist); - int iMaxX = (int)ceil(fX + fMaxDist), iMaxY = (int)ceil(fY + fMaxDist); - - for (int iPosY = iMinY; iPosY <= iMaxY; iPosY++) - { - // Skip invalid locations - if (iPosY < 0 || iPosY > height - 1) - { - continue; - } - - float fy = (float)iPosY - fY; - - // Precalculate - fYSquared = (float)(fy * fy); - - for (int iPosX = iMinX; iPosX <= iMaxX; iPosX++) - { - float fx = (float)iPosX - fX; - - // Skip invalid locations - if (iPosX < 0 || iPosX > width - 1) - { - continue; - } - - // Only circle. - float dist = sqrtf(fYSquared + fx * fx); - if (!brush.m_bFlood && dist > fMaxDist) - { - continue; - } - - float fMask = brush.GetMask(iPosX * fScaleX, iPosY * fScaleY); - - if (fMask < 0.5f) - { - continue; - } - - - // Calculate the array index - pos = iPosX + iPosY * width; - - // Calculate attenuation factor - fAttenuation = brush.m_bFlood ? 1.0f : 1.0f - __min(1.0f, dist / fMaxDist); - - float h = static_cast(sourceData[pos].GetWeight(brush.color) / 255.0f); - float dh = 1.0f - h; - float fh = clamp_tpl((fAttenuation) * dh * fHardness + h, 0.0f, 1.0f); - - // A non-zero distance between our weight sample and the center point of the brush - // can cause fAttenuation to be ~0.999, so if h (the current weight) is 254, any - // value less than 1 * dh will give us a value between 254 and 255. - // As we convert from 0-1 back to 0-255 number ranges, it's important to round - // instead of truncating so that we don't have to have an exact distance of 0 - // to reach a value of 255. - uint8 weight = static_cast(clamp_tpl(round(fh * 255.0f), 0.0f, 255.0f)); - - sourceData[pos].SetWeight(brush.color, weight); - } - } -} - - -void CImagePainter::PaintBrushWithPattern(const float fpx, const float fpy, CImageEx& outImageBGR, - const uint32 dwOffsetX, const uint32 dwOffsetY, const float fScaleX, const float fScaleY, - const SEditorPaintBrush& brush, const CImageEx& imgPattern) -{ - float fX = fpx * fScaleX, fY = fpy * fScaleY; - - //////////////////////////////////////////////////////////////////////// - // Draw an attenuated spot on the map - //////////////////////////////////////////////////////////////////////// - float fMaxDist, fAttenuation, fYSquared; - float fHardness = brush.hardness; - - unsigned int pos; - - uint32* srcBGR = outImageBGR.GetData(); - uint32* pat = imgPattern.GetData(); - - int value = brush.color; - - // Calculate the maximum distance - fMaxDist = brush.fRadius; - - int width = outImageBGR.GetWidth(); - int height = outImageBGR.GetHeight(); - - int patwidth = imgPattern.GetWidth(); - int patheight = imgPattern.GetHeight(); - - int iMinX = (int)floor(fX - fMaxDist), iMinY = (int)floor(fY - fMaxDist); - int iMaxX = (int)ceil(fX + fMaxDist), iMaxY = (int)ceil(fY + fMaxDist); - - bool bSRGB = imgPattern.GetSRGB(); - - for (int iPosY = iMinY; iPosY < iMaxY; iPosY++) - { - // Skip invalid locations - if (iPosY - dwOffsetY < 0 || iPosY - dwOffsetY > height - 1) - { - continue; - } - - float fy = (float)iPosY - fY; - - // Precalculate - fYSquared = (float)(fy * fy); - - int32 iPatY = ((uint32)iPosY) % patheight; - assert(iPatY >= 0 && iPatY < patheight); - - for (int iPosX = iMinX; iPosX < iMaxX; iPosX++) - { - float fx = (float)iPosX - fX; - - // Skip invalid locations - if (iPosX - dwOffsetX < 0 || iPosX - dwOffsetX > width - 1) - { - continue; - } - - // Only circle. - float dist = sqrtf(fYSquared + fx * fx); - - if (!brush.m_bFlood && dist > fMaxDist) - { - continue; - } - - // Calculate the array index - pos = (iPosX - dwOffsetX) + (iPosY - dwOffsetY) * width; - - // Calculate attenuation factor - fAttenuation = brush.m_bFlood ? 1.0f : 1.0f - __min(1.0f, dist / fMaxDist); - assert(fAttenuation >= 0.0f && fAttenuation <= 1.0f); - - // Note that GetMask expects a range of [0, 1), so it's correct to divide by - // fScaleX and fScaleY instead of (fScaleX-1) and (fScaleY-1). - float fMask = brush.GetMask(iPosX / fScaleX, iPosY / fScaleY); - - uint32 cDstPixBGR = srcBGR[pos]; - - int32 iPatX = ((uint32)iPosX) % patwidth; - assert(iPatX >= 0 && iPatX < patwidth); - - uint32 cSrcPix = pat[iPatX + iPatY * patwidth]; - - float s = fAttenuation * fHardness * fMask; - assert(s >= 0.0f && s <= 1.0f); - if (fcmp(s, 0)) - { - // If the blend would be entirely biased to the pixel in outImage then don't modify anything - // (The logic below is susceptible to floating point inaccuracy and would change the pixel - // even though it is not supposed to) - continue; - } - - const float fRecip255 = 1.0f / 255.0f; - - // Convert Src to Linear Space (Src is pattern texture, can be in linear or gamma space) - ColorF cSrc = ColorF(GetRValue(cSrcPix), GetGValue(cSrcPix), GetBValue(cSrcPix)) * fRecip255; - if (bSRGB) - { - cSrc.srgb2rgb(); - } - - ColorF cMtl = brush.m_cFilterColor; - cMtl.srgb2rgb(); - - cSrc *= cMtl; - cSrc.clamp(0.0f, 1.0f); - - // Convert Dst to Linear Space ( Dst is always in gamma space ), and load from BGR -> RGB - ColorF cDst = ColorF(GetBValue(cDstPixBGR), GetGValue(cDstPixBGR), GetRValue(cDstPixBGR)) * fRecip255; - cDst.srgb2rgb(); - - // Linear space blend - ColorF cOut = cSrc * s + cDst * (1.0f - s); - - // Convert final result to gamma space and put back in [0..255] range - cOut.rgb2srgb(); - cOut *= 255.0f; - - // Save the blended result as BGR - // It's important to round as we go from float back to int. If we just truncate, - // we'll end up with consistently darker colors. - srcBGR[pos] = RGB(round(cOut.b), round(cOut.g), round(cOut.r)); - } - } -} - - -void CImagePainter::FillWithPattern(CImageEx& outImage, const uint32 dwOffsetX, const uint32 dwOffsetY, - const CImageEx& imgPattern) -{ - unsigned int pos; - - uint32* src = outImage.GetData(); - uint32* pat = imgPattern.GetData(); - - int width = outImage.GetWidth(); - int height = outImage.GetHeight(); - - int patwidth = imgPattern.GetWidth(); - int patheight = imgPattern.GetHeight(); - - if (patheight == 0 || patwidth == 0) - { - return; - } - - for (int iPosY = 0; iPosY < height; iPosY++) - { - int32 iPatY = ((uint32)iPosY + dwOffsetY) % patheight; - assert(iPatY >= 0 && iPatY < patheight); - - for (int iPosX = 0; iPosX < width; iPosX++) - { - // Calculate the array index - pos = iPosX + iPosY * width; - - int32 iPatX = ((uint32)iPosX + dwOffsetX) % patwidth; - assert(iPatX >= 0 && iPatX < patwidth); - - uint32 cSrc = pat[iPatX + iPatY * patwidth]; - - src[pos] = cSrc; - } - } -} - diff --git a/Code/Editor/Util/ImagePainter.h b/Code/Editor/Util/ImagePainter.h deleted file mode 100644 index 81d1450f06..0000000000 --- a/Code/Editor/Util/ImagePainter.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#ifndef CRYINCLUDE_EDITOR_UTIL_IMAGEPAINTER_H -#define CRYINCLUDE_EDITOR_UTIL_IMAGEPAINTER_H -#pragma once - -#include "Util/Image.h" - -struct LayerWeight; - -// Brush structure used for painting. -struct SANDBOX_API SEditorPaintBrush -{ - // constructor - SEditorPaintBrush(class CHeightmap& rHeightmap, class CLayer& rLayer, - const bool bMaskByLayerSettings, const uint32 dwLayerIdMask, const bool bFlood); - - CHeightmap& m_rHeightmap; // for mask support - unsigned char color; // Painting color - float fRadius; // outer radius (0..1 for the whole terrain size) - float hardness; // 0-1 hardness of brush - bool bBlended; // true=shades of the value are stores, false=the value is either stored or not - bool m_bFlood; // true=fills square area without attenuation, false=fills circle area with attenuation - uint32 m_dwLayerIdMask;// reference Value for the mask, 0xffffffff if not used - CLayer& m_rLayer; // layer we paint with - AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING - ColorF m_cFilterColor; // (1,1,1) if not used, multiplied with brightness - AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING - - // Arguments: - // fX - 0..1 in the whole terrain - // fY - 0..1 in the whole terrain - // Return: - // 0=paint there 0% .. 1=paint there 100% - float GetMask(const float fX, const float fY) const; - -protected: // -------------------------------------------------------------------------- - - float m_fMinSlope; // in m per m - float m_fMaxSlope; // in m per me - float m_fMinAltitude; // in m - float m_fMaxAltitude; // in m -}; - -// Contains image painting functions. -class CImagePainter -{ -public: - - // Paint spot on image at position px,py with specified paint brush parameters (to a layer) - // Arguments: - // fpx - 0..1 in the whole terrain (used for the mask) - // fpy - 0..1 in the whole terrain (used for the mask) - SANDBOX_API void PaintBrush(const float fpx, const float fpy, TImage& image, const SEditorPaintBrush& brush); - - // Paint spot with pattern (to an RGB image) - // real spot is drawn to (fpx-dwOffsetX,fpy-dwOffsetY) - to get the pattern working we need this info split up like this - // Arguments: - // fpx - 0..1 in the whole terrain (used for the mask) - // fpy - 0..1 in the whole terrain (used for the mask) - void PaintBrushWithPattern(const float fpx, const float fpy, CImageEx& outImage, const uint32 dwOffsetX, const uint32 dwOffsetY, - const float fScaleX, const float fScaleY, const SEditorPaintBrush& brush, const CImageEx& imgPattern); - - // - void FillWithPattern(CImageEx& outImage, const uint32 dwOffsetX, const uint32 dwOffsetY, const CImageEx& imgPattern); -}; - - -#endif // CRYINCLUDE_EDITOR_UTIL_IMAGEPAINTER_H diff --git a/Code/Editor/Util/MemoryBlock.cpp b/Code/Editor/Util/MemoryBlock.cpp index b7ae017113..eb4b53420b 100644 --- a/Code/Editor/Util/MemoryBlock.cpp +++ b/Code/Editor/Util/MemoryBlock.cpp @@ -170,10 +170,7 @@ void CMemoryBlock::Uncompress(CMemoryBlock& toBlock) const toBlock.Allocate(m_uncompressedSize); toBlock.m_uncompressedSize = 0; unsigned long destSize = m_uncompressedSize; -#if !defined(NDEBUG) - int result = -#endif - uncompress((unsigned char*)toBlock.GetBuffer(), &destSize, (unsigned char*)GetBuffer(), GetSize()); + [[maybe_unused]] int result = uncompress((unsigned char*)toBlock.GetBuffer(), &destSize, (unsigned char*)GetBuffer(), GetSize()); assert(result == Z_OK); assert(destSize == static_cast(m_uncompressedSize)); } diff --git a/Code/Editor/Util/ModalWindowDismisser.cpp b/Code/Editor/Util/ModalWindowDismisser.cpp index 7ae62e4a67..17bd1f8543 100644 --- a/Code/Editor/Util/ModalWindowDismisser.cpp +++ b/Code/Editor/Util/ModalWindowDismisser.cpp @@ -45,7 +45,8 @@ bool ModalWindowDismisser::eventFilter(QObject* object, QEvent* event) { if (dialog->isModal()) { - if (event->type() == QEvent::Show) + QEvent::Type test = event->type(); + if (test == QEvent::Show || test == QEvent::WindowActivate) { auto it = AZStd::find(m_windows.begin(), m_windows.end(), dialog); if (it == m_windows.end()) diff --git a/Code/Editor/Util/Observable.h b/Code/Editor/Util/Observable.h deleted file mode 100644 index e42fc2c94a..0000000000 --- a/Code/Editor/Util/Observable.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -// Description : This file declares templates to be used when a class can -// have a list of observers to feed - - -#ifndef CRYINCLUDE_EDITOR_UTIL_OBSERVABLE_H -#define CRYINCLUDE_EDITOR_UTIL_OBSERVABLE_H -#pragma once - -#include - -//! Observable template class, holds a list of observers which can be called at once using the helper defines -template -class CObservable -{ -public: - // Description: - // Register a new observer for the class, will check if not already added - // Return: - // true - if the observer was successfully added to the list - // false - if the observer is already in the list - bool RegisterObserver(T* pObserver) - { - if (m_observers.end() != std::find(m_observers.begin(), m_observers.end(), pObserver)) - { - return false; - } - - m_observers.push_back(pObserver); - - return true; - } - - // Description: - // Unregister an observer from the list - // Return: - // true - if the observer was successfuly removed - // false - if the observer is not in the list - bool UnregisterObserver(T* pObserver) - { - typename std::vector::iterator iter; - - if (m_observers.end() == (iter = std::find(m_observers.begin(), m_observers.end(), pObserver))) - { - return false; - } - - m_observers.erase(iter); - - return true; - } - - // Description: - // Uregister all the observers - void UnregisterAllObservers() - { - m_observers.clear(); - } - -protected: - std::vector m_observers; -}; - -// -// Helper defines to ease the process of calling the methods of all observers in the list -// - -// Description: -// Call the method of the observers, this must be used inside the subject class -// Example: CALL_OBSERVERS_METHOD(OnStuffHappened(120, "NO!")) -#define CALL_OBSERVERS_METHOD(methodCall) \ - { for (size_t iObs = 0, iObsCount = m_observers.size(); iObs < iObsCount; ++iObs) { m_observers[iObs]->methodCall; } \ - } - -// Description: -// Call the method of the observers, this can be used outside the subject class -// Example: CALL_OBSERVERS_METHOD_OF(pSomeObservableSubject, OnStuffHappened(120, "NO!")) -#define CALL_OBSERVERS_METHOD_OF(pObservable, methodCall) \ - { for (size_t iObs = 0, iObsCount = pObservable->m_observers.size(); iObs < iObsCount; ++iObs) { pObservable->m_observers[iObs]->methodCall; } \ - } - -// Description: -// Call the method of the observers, this can be called using a custom vector of observers -// Example: CALL_SPECIFIED_OBSERVERS_LIST_METHOD(vMyPreciousSpecialObservers, OnStuffHappened(120, "NO!")) -#define CALL_SPECIFIED_OBSERVERS_LIST_METHOD(vObservers, methodCall) \ - { for (size_t iObs = 0, iObsCount = vObservers.size(); iObs < iObsCount; ++iObs) { vObservers[iObs]->methodCall; } \ - } - -// Description: -// Implement the observable methods when the user class is inheriting from a virtual interface using the observable methods -#define IMPLEMENT_OBSERVABLE_METHODS(observerClassName) \ - virtual bool RegisterObserver(observerClassName * pObserver) { return CObservable::RegisterObserver(pObserver); }; \ - virtual bool UnregisterObserver(observerClassName * pObserver) { return CObservable::UnregisterObserver(pObserver); }; \ - virtual void UnregisterAllObservers() { CObservable::UnregisterAllObservers(); }; -#endif // CRYINCLUDE_EDITOR_UTIL_OBSERVABLE_H diff --git a/Code/Editor/Util/TRefCountBase.h b/Code/Editor/Util/TRefCountBase.h deleted file mode 100644 index aeedda9d16..0000000000 --- a/Code/Editor/Util/TRefCountBase.h +++ /dev/null @@ -1,56 +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 : Reference counted base object. - - -#ifndef CRYINCLUDE_EDITOR_UTIL_TREFCOUNTBASE_H -#define CRYINCLUDE_EDITOR_UTIL_TREFCOUNTBASE_H -#pragma once - -AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING -////////////////////////////////////////////////////////////////////////// -//! Derive from this class to get reference counting for your class. -////////////////////////////////////////////////////////////////////////// -template -class CRYEDIT_API TRefCountBase - : public ParentClass -{ -AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING -public: - TRefCountBase() { m_nRefCount = 0; }; - - //! Add new refrence to this object. - unsigned long AddRef() - { - m_nRefCount++; - return m_nRefCount; - }; - - //! Release refrence to this object. - //! when reference count reaches zero, object is deleted. - unsigned long Release() - { - int refs = --m_nRefCount; - if (m_nRefCount <= 0) - { - delete this; - } - return refs; - } - -protected: - virtual ~TRefCountBase() {}; - -private: - int m_nRefCount; -}; - - -#endif // CRYINCLUDE_EDITOR_UTIL_TREFCOUNTBASE_H diff --git a/Code/Editor/Util/Triangulate.cpp b/Code/Editor/Util/Triangulate.cpp deleted file mode 100644 index c8160a375a..0000000000 --- a/Code/Editor/Util/Triangulate.cpp +++ /dev/null @@ -1,69 +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 "Triangulate.h" - -// this file is essentially a wrapper for a portion of the MIT-licenced -// ConvexDecomposition library by John W. Ratcliff mailto:jratcliffscarab@gmail.com. -// it contains no code from that library, it just provides it with the required types, then includes the -// portion we need. - -static const float TRIANGULATION_EPSILON = 0.0000000001f; - -#define MEMALLOC_MALLOC malloc -#define MEMALLOC_FREE free - -namespace TriInternal -{ - class TVec; - typedef double NxF64; - typedef float NxF32; - typedef unsigned char NxU8; - typedef unsigned int NxU32; - typedef int NxI32; - typedef unsigned int TU32; - - typedef std::vector< TVec > TVecVector; - typedef std::vector< NxU32 > TU32Vector; - #include "Contrib/NvFloatMath.inl" -} - -#undef MEMALLOC_MALLOC -#undef MEMALLOC_FREE - -namespace Triangulator -{ - // given the contour of a triangle, triangulate it, and return the result - // as a set of triangles - // return false if you fail to triangulate it. - bool Triangulate(const VectorOfVectors& contour, VectorOfVectors& result) - { - TriInternal::CTriangulator tri; - for (auto pt : contour) - { - tri.addPoint(pt.x, pt.y, pt.z); - } - TriInternal::NxU32 tricount = 0; - TriInternal::NxU32* indices = tri.triangulate(tricount, TRIANGULATION_EPSILON); - if (!indices) - { - return false; - } - - for (TriInternal::NxU32 currentIdx = 0; currentIdx < tricount * 3; ++currentIdx) - { - TriInternal::NxU32 indexValue = *indices++; - result.push_back(contour[indexValue]); - } - - return result.size() > 2; - } -} diff --git a/Code/Editor/Util/Triangulate.h b/Code/Editor/Util/Triangulate.h deleted file mode 100644 index dad3a14de1..0000000000 --- a/Code/Editor/Util/Triangulate.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#ifndef CRYINCLUDE_EDITOR_UTIL_TRIANGULATE_H -#define CRYINCLUDE_EDITOR_UTIL_TRIANGULATE_H -#pragma once - -#include -#include "Cry_Vector3.h" - -// you pass in a vector of vec3 (the contour of a shape) and it outputs a vector of vec3 (being the triangles) - -namespace Triangulator -{ - typedef std::vector< Vec3 > VectorOfVectors; - bool Triangulate(const VectorOfVectors& contour, VectorOfVectors& result); -}; - - -#endif diff --git a/Code/Editor/Util/UIEnumerations.cpp b/Code/Editor/Util/UIEnumerations.cpp deleted file mode 100644 index 2666a49f8e..0000000000 --- a/Code/Editor/Util/UIEnumerations.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -// Description : This file implements the container for the assotiaon of -// enumeration name to enumeration values - - -#include "EditorDefs.h" - -#include "UIEnumerations.h" - -////////////////////////////////////////////////////////////////////////// -CUIEnumerations& CUIEnumerations::GetUIEnumerationsInstance() -{ - static CUIEnumerations oGeneralProxy; - return oGeneralProxy; -} - -////////////////////////////////////////////////////////////////////////// -CUIEnumerations::TDValuesContainer& CUIEnumerations::GetStandardNameContainer() -{ - static TDValuesContainer cValuesContainer; - static bool boInit(false); - - if (!boInit) - { - boInit = true; - - XmlNodeRef oRootNode; - XmlNodeRef oEnumaration; - XmlNodeRef oEnumerationItem; - - int nNumberOfEnumarations(0); - int nCurrentEnumaration(0); - - int nNumberOfEnumerationItems(0); - int nCurrentEnumarationItem(0); - - oRootNode = GetISystem()->GetXmlUtils()->LoadXmlFromFile("Editor\\PropertyEnumerations.xml"); - nNumberOfEnumarations = oRootNode ? oRootNode->getChildCount() : 0; - - for (nCurrentEnumaration = 0; nCurrentEnumaration < nNumberOfEnumarations; ++nCurrentEnumaration) - { - TDValues cValues; - oEnumaration = oRootNode->getChild(nCurrentEnumaration); - - nNumberOfEnumerationItems = oEnumaration->getChildCount(); - for (nCurrentEnumarationItem = 0; nCurrentEnumarationItem < nNumberOfEnumerationItems; ++nCurrentEnumarationItem) - { - oEnumerationItem = oEnumaration->getChild(nCurrentEnumarationItem); - - const char* szKey(nullptr); - const char* szValue(nullptr); - oEnumerationItem->getAttributeByIndex(0, &szKey, &szValue); - - cValues.push_back(szValue); - } - - const char* szKey(nullptr); - const char* szValue(nullptr); - oEnumaration->getAttributeByIndex(0, &szKey, &szValue); - - cValuesContainer.insert(TDValuesContainer::value_type(szValue, cValues)); - } - } - - return cValuesContainer; -} -////////////////////////////////////////////////////////////////////////// diff --git a/Code/Editor/Util/UIEnumerations.h b/Code/Editor/Util/UIEnumerations.h deleted file mode 100644 index f23ebf9604..0000000000 --- a/Code/Editor/Util/UIEnumerations.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -// Description : This file declares the container for the assotiaon of -// enumeration name to enumeration values - - -#ifndef CRYINCLUDE_EDITOR_UTIL_UIENUMERATIONS_H -#define CRYINCLUDE_EDITOR_UTIL_UIENUMERATIONS_H -#pragma once - - -class CUIEnumerations -{ -public: - // For XML standard values. - typedef QStringList TDValues; - typedef std::map TDValuesContainer; -protected: -private: - -public: - static CUIEnumerations& GetUIEnumerationsInstance(); - - TDValuesContainer& GetStandardNameContainer(); -protected: -private: -}; - - -#endif // CRYINCLUDE_EDITOR_UTIL_UIENUMERATIONS_H diff --git a/Code/Editor/Util/bitarray.h b/Code/Editor/Util/bitarray.h deleted file mode 100644 index 5a887b02d5..0000000000 --- a/Code/Editor/Util/bitarray.h +++ /dev/null @@ -1,335 +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 : Array of m_bits. - - -#ifndef CRYINCLUDE_EDITOR_UTIL_BITARRAY_H -#define CRYINCLUDE_EDITOR_UTIL_BITARRAY_H -#pragma once - - -////////////////////////////////////////////////////////////////////////// -// -// CBitArray is similar to std::vector but faster to clear. -// -////////////////////////////////////////////////////////////////////////// -class CBitArray -{ -public: - struct BitReference - { - uint32* p; - uint32 mask; - BitReference(uint32* __x, uint32 __y) - : p(__x) - , mask(__y) {} - - - public: - BitReference() - : p(0) - , mask(0) {} - - operator bool() const { - return !(!(*p & mask)); - } - BitReference& operator=(bool __x) - { - if (__x) - { - * p |= mask; - } - else - { - * p &= ~mask; - } - return *this; - } - BitReference& operator=(const BitReference& __x) { return *this = bool(__x); } - bool operator==(const BitReference& __x) const { return bool(*this) == bool(__x); } - bool operator<(const BitReference& __x) const { return !bool(*this) && bool(__x); } - BitReference& operator |= (bool __x) - { - if (__x) - { - * p |= mask; - } - return *this; - } - BitReference& operator &= (bool __x) - { - if (!__x) - { - * p &= ~mask; - } - return *this; - } - void flip() {* p ^= mask; } - }; - - CBitArray() { m_base = nullptr; m_bits = nullptr; m_size = 0; m_numBits = 0; }; - CBitArray(int numBits) { resize(numBits); }; - ~CBitArray() - { - if (m_base) - { - free(m_base); - } - }; - - void resize(int c) - { - m_numBits = c; - int newSize = ((c + 63) & (~63)) >> 5; - if (newSize > m_size) - { - Alloc(newSize); - } - } - int size() const { return m_numBits; }; - bool empty() const { return m_numBits == 0; }; - - ////////////////////////////////////////////////////////////////////////// - void set() - { - memset(m_bits, 0xFFFFFFFF, m_size * sizeof(uint32)); // Set all bits. - } - ////////////////////////////////////////////////////////////////////////// - void set(int numBits) - { - int num = (numBits >> 3) + 1; - if (num > (m_size * sizeof(uint32))) - { - num = m_size * sizeof(uint32); - } - memset(m_bits, 0xFFFFFFFF, num); // Reset num bits. - } - - ////////////////////////////////////////////////////////////////////////// - void clear() - { - memset(m_bits, 0, m_size * sizeof(uint32)); // Reset all bits. - } - - ////////////////////////////////////////////////////////////////////////// - void clear(int numBits) - { - int num = (numBits >> 3) + 1; - if (num > (m_size * sizeof(uint32))) - { - num = m_size * sizeof(uint32); - } - memset(m_bits, 0, num); // Reset num bits. - } - - ////////////////////////////////////////////////////////////////////////// - // Check if all bits are 0. - bool is_zero() const - { - for (int i = 0; i < m_size; i++) - { - if (m_bits[i] != 0) - { - return false; - } - } - return true; - } - - // Count number of set bits. - int count_bits() const - { - int c = 0; - for (int i = 0; i < m_size; i++) - { - uint32 v = m_bits[i]; - for (int j = 0; j < 32; j++) - { - if (v & (1 << (j & 0x1F))) - { - c++; // if bit set increase bit count. - } - } - } - return c; - } - - BitReference operator[](int pos) { return BitReference(&m_bits[index(pos)], shift(pos)); } - const BitReference operator[](int pos) const { return BitReference(&m_bits[index(pos)], shift(pos)); } - - ////////////////////////////////////////////////////////////////////////// - void swap(CBitArray& bitarr) - { - std::swap(m_base, bitarr.m_base); - std::swap(m_bits, bitarr.m_bits); - std::swap(m_size, bitarr.m_size); - } - - CBitArray& operator =(const CBitArray& b) - { - if (m_size != b.m_size) - { - Alloc(b.m_size); - } - memcpy(m_bits, b.m_bits, m_size * sizeof(uint32)); - return *this; - } - - bool checkByte(int pos) const { return reinterpret_cast(m_bits)[pos] != 0; }; - - ////////////////////////////////////////////////////////////////////////// - // Compresses this bit array into the specified one. - // Uses run length encoding compression. - void compress(CBitArray& b) const - { - int i, countz, compsize, bsize; - char* out; - char* in; - - bsize = m_size * 4; - compsize = 0; - in = (char*)m_bits; - for (i = 0; i < bsize; i++) - { - compsize++; - if (in[i] == 0) - { - countz = 1; - while (++i < bsize) - { - if (in[i] == 0 && countz != 255) - { - countz++; - } - else - { - break; - } - } - i--; - compsize++; - } - } - b.resize((compsize + 1) << 3); - out = (char*)b.m_bits; - in = (char*)m_bits; - *out++ = static_cast(bsize); - for (i = 0; i < bsize; i++) - { - *out++ = in[i]; - if (in[i] == 0) - { - countz = 1; - while (++i < bsize) - { - if (in[i] == 0 && countz != 255) - { - countz++; - } - else - { - break; - } - } - i--; - *out++ = static_cast(countz); - } - } - } - - ////////////////////////////////////////////////////////////////////////// - // Decompress specified bit array in to this one. - // Uses run length encoding compression. - void decompress(CBitArray& b) - { - int raw, decompressed, c; - char* out, * in; - - in = (char*)m_bits; - out = (char*)b.m_bits; - decompressed = 0; - raw = *in++; - while (decompressed < raw) - { - if (*in != 0) - { - *out++ = *in++; - decompressed++; - } - else - { - in++; - c = *in++; - decompressed += c; - while (c) - { - *out++ = 0; - c--; - } - ; - } - } - m_numBits = decompressed; - } - - void CopyFromMem(const char* src, int size) - { - Alloc(size); - memcpy(m_bits, src, size); - } - int CopyToMem(char* trg) - { - memcpy(trg, m_bits, m_size); - return m_size; - } - -private: - void* m_base; - uint32* m_bits; - int m_size; - int m_numBits; - - void Alloc(int s) - { - if (m_base) - { - free(m_base); - } - m_size = s; - m_base = (char*)malloc(m_size * sizeof(uint32) + 32); - m_bits = (uint32*)(((UINT_PTR)m_base + 31) & (~31)); // align by 32. - memset(m_bits, 0, m_size * sizeof(uint32)); // Reset all bits. - } - uint32 shift(int pos) const - { - return (1 << (pos & 0x1F)); - } - uint32 index(int pos) const - { - return pos >> 5; - } - - friend int concatBitarray(CBitArray& b1, CBitArray& b2, CBitArray& test, CBitArray& res); -}; - -inline int concatBitarray(CBitArray& b1, CBitArray& b2, CBitArray& test, CBitArray& res) -{ - unsigned int b, any; - any = 0; - for (int i = 0; i < b1.size(); i++) - { - b = b1.m_bits[i] & b2.m_bits[i]; - any |= (b & (~test.m_bits[i])); // test if any different from test(i) bit set. - res.m_bits[i] = b; - } - return any; -} - -#endif // CRYINCLUDE_EDITOR_UTIL_BITARRAY_H diff --git a/Code/Editor/Util/smartptr.h b/Code/Editor/Util/smartptr.h deleted file mode 100644 index d9e656ef24..0000000000 --- a/Code/Editor/Util/smartptr.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#ifndef CRYINCLUDE_EDITOR_UTIL_SMARTPTR_H -#define CRYINCLUDE_EDITOR_UTIL_SMARTPTR_H -#pragma once - -#include - -#define TSmartPtr _smart_ptr - -/** Use this to define smart pointers of classes. - For example: - class CNode : public CRefCountBase {}; - SMARTPTRTypeYPEDEF( CNode ); - { - CNodePtr node; // Smart pointer. - } -*/ - -#define SMARTPTR_TYPEDEF(Class) typedef TSmartPtr Class##Ptr - -#endif // CRYINCLUDE_EDITOR_UTIL_SMARTPTR_H diff --git a/Code/Editor/ViewPane.cpp b/Code/Editor/ViewPane.cpp index e3494a4049..99b4c5a1cc 100644 --- a/Code/Editor/ViewPane.cpp +++ b/Code/Editor/ViewPane.cpp @@ -87,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; } } @@ -179,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; } @@ -745,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/ViewportManipulatorController.cpp b/Code/Editor/ViewportManipulatorController.cpp index 9879a84b62..93c999f71f 100644 --- a/Code/Editor/ViewportManipulatorController.cpp +++ b/Code/Editor/ViewportManipulatorController.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -33,53 +34,6 @@ namespace SandboxEditor ViewportManipulatorControllerInstance::~ViewportManipulatorControllerInstance() = default; - AzToolsFramework::ViewportInteraction::MouseButton ViewportManipulatorControllerInstance::GetMouseButton( - const AzFramework::InputChannel& inputChannel) - { - using AzToolsFramework::ViewportInteraction::MouseButton; - using InputButton = AzFramework::InputDeviceMouse::Button; - const auto& id = inputChannel.GetInputChannelId(); - if (id == InputButton::Left) - { - return MouseButton::Left; - } - if (id == InputButton::Middle) - { - return MouseButton::Middle; - } - if (id == InputButton::Right) - { - return MouseButton::Right; - } - return MouseButton::None; - } - - bool ViewportManipulatorControllerInstance::IsMouseMove(const AzFramework::InputChannel& inputChannel) - { - return inputChannel.GetInputChannelId() == AzFramework::InputDeviceMouse::SystemCursorPosition; - } - - AzToolsFramework::ViewportInteraction::KeyboardModifier ViewportManipulatorControllerInstance::GetKeyboardModifier( - const AzFramework::InputChannel& inputChannel) - { - using AzToolsFramework::ViewportInteraction::KeyboardModifier; - using Key = AzFramework::InputDeviceKeyboard::Key; - const auto& id = inputChannel.GetInputChannelId(); - if (id == Key::ModifierAltL || id == Key::ModifierAltR) - { - return KeyboardModifier::Alt; - } - if (id == Key::ModifierCtrlL || id == Key::ModifierCtrlR) - { - return KeyboardModifier::Ctrl; - } - if (id == Key::ModifierShiftL || id == Key::ModifierShiftR) - { - return KeyboardModifier::Shift; - } - return KeyboardModifier::None; - } - bool ViewportManipulatorControllerInstance::HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event) { // We only care about manipulator and viewport interaction events @@ -97,6 +51,7 @@ namespace SandboxEditor using AzToolsFramework::ViewportInteraction::MouseInteractionEvent; using AzToolsFramework::ViewportInteraction::ProjectedViewportRay; using AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus; + using AzToolsFramework::ViewportInteraction::Helpers; bool interactionHandled = false; float wheelDelta = 0.0f; @@ -109,7 +64,7 @@ namespace SandboxEditor const bool finishedProcessingEvents = event.m_priority == InteractionPriority; const auto state = event.m_inputChannel.GetState(); - if (IsMouseMove(event.m_inputChannel)) + if (Helpers::IsMouseMove(event.m_inputChannel)) { // Cache the ray trace results when doing manipulator interaction checks, no need to recalculate after if (event.m_priority == ManipulatorPriority) @@ -136,7 +91,7 @@ namespace SandboxEditor eventType = MouseEvent::Move; } - else if (auto mouseButton = GetMouseButton(event.m_inputChannel); mouseButton != MouseButton::None) + else if (auto mouseButton = Helpers::GetMouseButton(event.m_inputChannel); mouseButton != MouseButton::None) { const AZ::u32 mouseButtonValue = static_cast(mouseButton); overrideButton = mouseButton; @@ -178,7 +133,7 @@ namespace SandboxEditor } } } - else if (auto keyboardModifier = GetKeyboardModifier(event.m_inputChannel); keyboardModifier != KeyboardModifier::None) + else if (auto keyboardModifier = Helpers::GetKeyboardModifier(event.m_inputChannel); keyboardModifier != KeyboardModifier::None) { if (state == InputChannel::State::Began || state == InputChannel::State::Updated) { diff --git a/Code/Editor/ViewportManipulatorController.h b/Code/Editor/ViewportManipulatorController.h index b9c359a544..4872d32fd6 100644 --- a/Code/Editor/ViewportManipulatorController.h +++ b/Code/Editor/ViewportManipulatorController.h @@ -35,10 +35,6 @@ namespace SandboxEditor private: bool IsDoubleClick(AzToolsFramework::ViewportInteraction::MouseButton) const; - static AzToolsFramework::ViewportInteraction::MouseButton GetMouseButton(const AzFramework::InputChannel& inputChannel); - static bool IsMouseMove(const AzFramework::InputChannel& inputChannel); - static AzToolsFramework::ViewportInteraction::KeyboardModifier GetKeyboardModifier(const AzFramework::InputChannel& inputChannel); - //! Represents the time and location of a click. struct ClickEvent { 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/WinWidgetId.h b/Code/Editor/WinWidgetId.h deleted file mode 100644 index dc8daa43c6..0000000000 --- a/Code/Editor/WinWidgetId.h +++ /dev/null @@ -1,20 +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 - -enum class WinWidgetId -{ - NONE = 0, - ACTIVE_DEPLOYMENT, - PROFILE_SELECTOR, - ADD_PROFILE, - INITIALIZE_PROJECT, - // ALL VALIDS ABOVE HERE - NUM_WIN_WIDGET_IDS -}; diff --git a/Code/Editor/editor_core_files.cmake b/Code/Editor/editor_core_files.cmake index 1f0a5a3618..7cb40927a4 100644 --- a/Code/Editor/editor_core_files.cmake +++ b/Code/Editor/editor_core_files.cmake @@ -58,13 +58,11 @@ set(FILES Util/ImageHistogram.h Util/Image.h Util/ColorUtils.cpp - Util/ColorUtils.h Undo/Undo.cpp Undo/IUndoManagerListener.h Undo/IUndoObject.h Undo/Undo.h Undo/UndoVariableChange.h - WinWidgetId.h QtUI/ColorButton.cpp QtUI/ColorButton.h QtUtil.h diff --git a/Code/Editor/editor_lib_files.cmake b/Code/Editor/editor_lib_files.cmake index 5d45bbd853..d1c903eb72 100644 --- a/Code/Editor/editor_lib_files.cmake +++ b/Code/Editor/editor_lib_files.cmake @@ -249,8 +249,6 @@ set(FILES CryEditPy.cpp CryEdit.cpp CryEdit.h - CVarMenu.cpp - CVarMenu.h EditorToolsApplication.cpp EditorToolsApplication.h EditorToolsApplicationAPI.h @@ -392,9 +390,6 @@ set(FILES QuickAccessBar.cpp QuickAccessBar.h QuickAccessBar.ui - ResizeResolutionDialog.cpp - ResizeResolutionDialog.h - ResizeResolutionDialog.ui SelectLightAnimationDialog.cpp SelectLightAnimationDialog.h SelectSequenceDialog.cpp @@ -443,7 +438,6 @@ set(FILES FBXExporterDialog.h FileTypeUtils.h GridUtils.h - IObservable.h IPostRenderer.h ToolBox.h TrackViewNewSequenceDialog.h @@ -458,8 +452,6 @@ set(FILES Objects/DisplayContextShared.inl Objects/SelectionGroup.cpp Objects/SelectionGroup.h - Objects/SubObjSelection.cpp - Objects/SubObjSelection.h Objects/ObjectLoader.cpp Objects/ObjectLoader.h Objects/ObjectManager.cpp @@ -552,7 +544,6 @@ set(FILES LevelInfo.h ProcessInfo.cpp ProcessInfo.h - Report.h TrackView/AtomOutputFrameCapture.cpp TrackView/AtomOutputFrameCapture.h TrackView/TrackViewDialog.qrc @@ -631,16 +622,12 @@ set(FILES TrackView/TrackViewSequence.h TrackView/TrackViewNodeFactories.h TrackView/TrackViewEventNode.h - ConfigGroup.cpp - ConfigGroup.h Util/AffineParts.h Util/AutoLogTime.cpp Util/AutoLogTime.h Util/AutoDirectoryRestoreFileDialog.h Util/AutoDirectoryRestoreFileDialog.cpp Util/CryMemFile.h - Util/DynamicArray2D.cpp - Util/DynamicArray2D.h Util/EditorAutoLevelLoadTest.cpp Util/EditorAutoLevelLoadTest.h Util/EditorUtils.cpp @@ -649,33 +636,24 @@ set(FILES Util/FileEnum.h Util/FileUtil.cpp Util/FileUtil.h - Util/GdiUtil.cpp - Util/GdiUtil.h Util/GeometryUtil.cpp Util/GuidUtil.cpp Util/GuidUtil.h - Util/IObservable.h Util/Mailer.h Util/NamedData.cpp Util/NamedData.h - Util/Observable.h Util/PakFile.cpp Util/PakFile.h Util/PredefinedAspectRatios.cpp Util/PredefinedAspectRatios.h Util/StringHelpers.cpp Util/StringHelpers.h - Util/TRefCountBase.h - Util/Triangulate.cpp - Util/Triangulate.h Util/Util.h Util/XmlArchive.cpp Util/XmlArchive.h Util/XmlTemplate.cpp Util/XmlTemplate.h - Util/bitarray.h Util/fastlib.h - Util/smartptr.h WaitProgress.cpp WaitProgress.h Util/FileUtil_impl.h @@ -704,17 +682,11 @@ set(FILES Util/FileChangeMonitor.h Util/ImageUtil.cpp Util/ImageUtil.h - Util/ImageASC.cpp - Util/ImageASC.h - Util/ImageBT.cpp - Util/ImageBT.h Util/ImageGif.cpp Util/ImageGif.h Util/ImageTIF.cpp Util/ImageTIF.h Util/Math.h - Util/UIEnumerations.cpp - Util/UIEnumerations.h WelcomeScreen/WelcomeScreenDialog.h WelcomeScreen/WelcomeScreenDialog.cpp WelcomeScreen/WelcomeScreenDialog.ui diff --git a/Code/Editor/editor_lib_terrain_files.cmake b/Code/Editor/editor_lib_terrain_files.cmake deleted file mode 100644 index 09b521ad39..0000000000 --- a/Code/Editor/editor_lib_terrain_files.cmake +++ /dev/null @@ -1,84 +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 -# -# - -set(FILES - TerrainPainterPanel.cpp - TerrainPainterPanel.h - TerrainPainterPanel.ui - NewTerrainDialog.cpp - NewTerrainDialog.h - NewTerrainDialog.ui - TerrainTextureExport.cpp - TerrainTextureExport.h - TerrainTextureExport.ui - Terrain/Clouds.cpp - Terrain/GenerationParam.cpp - Terrain/GenerationParam.ui - Terrain/Heightmap.cpp - Terrain/Layer.cpp - Terrain/Noise.cpp - Terrain/PythonTerrainFuncs.cpp - Terrain/PythonTerrainLayerFuncs.cpp - Terrain/RGBLayer.cpp - Terrain/SurfaceType.cpp - Terrain/TerrainConverter.cpp - Terrain/TerrainGrid.cpp - Terrain/TerrainLayerTexGen.cpp - Terrain/TerrainLightGen.cpp - Terrain/TerrainManager.cpp - Terrain/TerrainTexGen.cpp - Terrain/TextureCompression.cpp - Terrain/MacroTextureExporter.cpp - Terrain/Clouds.h - Terrain/GenerationParam.h - Terrain/Heightmap.h - Terrain/Layer.h - Terrain/LayerWeight.h - Terrain/Noise.h - Terrain/RGBLayer.h - Terrain/SurfaceType.h - Terrain/TerrainConverter.h - Terrain/TerrainGrid.h - Terrain/TerrainLayerTexGen.h - Terrain/TerrainLightGen.h - Terrain/TerrainManager.h - Terrain/TerrainTexGen.h - Terrain/LayerWeight.cpp - Terrain/TextureCompression.h - Terrain/MacroTextureExporter.h - TerrainDialog.cpp - TerrainDialog.h - TerrainDialog.ui - TerrainTexture.cpp - TerrainTexture.h - TerrainTexture.ui - Terrain/SkyAccessibility/HeightmapAccessibility.h - Terrain/SkyAccessibility/HorizonTracker.h - TerrainHolePanel.cpp - TerrainHoleTool.cpp - TerrainHolePanel.h - TerrainHolePanel.ui - TerrainHoleTool.h - TerrainMiniMapTool.cpp - TerrainMiniMapTool.h - TerrainMiniMapPanel.ui - TerrainModifyPanel.cpp - TerrainModifyPanel.h - TerrainModifyPanel.ui - TerrainModifyTool.cpp - TerrainModifyTool.h - TerrainMoveTool.cpp - TerrainMoveToolPanel.cpp - TerrainMoveTool.h - TerrainMoveToolPanel.h - TerrainMoveToolPanel.ui - TerrainTexturePainter.cpp - TerrainTexturePainter.h - Util/ImagePainter.cpp - Util/ImagePainter.h -) diff --git a/Code/Editor/editor_lib_test_terrain_files.cmake b/Code/Editor/editor_lib_test_terrain_files.cmake deleted file mode 100644 index e0f4c99cdb..0000000000 --- a/Code/Editor/editor_lib_test_terrain_files.cmake +++ /dev/null @@ -1,17 +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 -# -# - -set(FILES - Lib/Tests/test_TerrainModifyPythonBindings.cpp - Lib/Tests/test_TerrainPythonBindings.cpp - Lib/Tests/test_TerrainLayerPythonBindings.cpp - Lib/Tests/test_TerrainPainterPythonBindings.cpp - Lib/Tests/test_TerrainHoleToolPythonBindings.cpp - Lib/Tests/test_TerrainTexturePythonBindings.cpp - Terrain/Tests/test_Terrain.cpp -) 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/AtomCore/AtomCore/atomcore_files.cmake b/Code/Framework/AtomCore/AtomCore/atomcore_files.cmake index 9167c1e645..827d26ecf5 100644 --- a/Code/Framework/AtomCore/AtomCore/atomcore_files.cmake +++ b/Code/Framework/AtomCore/AtomCore/atomcore_files.cmake @@ -13,7 +13,6 @@ set(FILES Instance/InstanceData.h Instance/InstanceData.cpp Instance/InstanceDatabase.h - std/containers/array_view.h std/containers/fixed_vector_set.h std/containers/lru_cache.h std/containers/vector_set.h diff --git a/Code/Framework/AtomCore/AtomCore/std/containers/array_view.h b/Code/Framework/AtomCore/AtomCore/std/containers/array_view.h deleted file mode 100644 index 522b69bf9b..0000000000 --- a/Code/Framework/AtomCore/AtomCore/std/containers/array_view.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ -#pragma once - -#include -#include -#include - -namespace AZStd -{ - /** - * Immutable wrapper for an array of data. It does not maintain storage for the data, - * but just holds pointers to mark the beginning and end of the array. It can be - * conveniently constructed from a variety of other container types like array, - * vector, and fixed_vector. - * - * Example: - * Given "void Func(AZStd::array_view a) {...}" you can call... - * - Func({1,2,3}); - * - AZStd::array a = {1,2,3}; - * Func(a); - * - AZStd::vector v = {1,2,3}; - * Func(v); - * - AZStd::fixed_vector fv = {1,2,3}; - * Func(fv); - * - * Since the array_view does not copy and store any data, it is only valid as long as the data used to create it is valid. - */ - template - class array_view final - { - public: - using value_type = Element; - - using pointer = value_type*; - using const_pointer = const value_type*; - - using reference = value_type&; - using const_reference = const value_type&; - - using size_type = AZStd::size_t; - using difference_type = AZStd::ptrdiff_t; - - using iterator = const value_type*; - using const_iterator = const value_type*; - using reverse_iterator = AZStd::reverse_iterator; - using const_reverse_iterator = AZStd::reverse_iterator; - - array_view() - : m_begin(nullptr) - , m_end(nullptr) - { } - - ~array_view() = default; - - array_view(const_pointer s, size_type length) - : m_begin(s) - , m_end(m_begin + length) - { - if (length == 0) erase(); - } - - array_view(const_pointer first, const_pointer last) - : m_begin(first) - , m_end(last) - { } - - // We explicitly delete this constructor because it's too easy to accidentally - // create an array_view to just the first element instead of an entire array. - array_view(const_pointer s) = delete; - - template - array_view(const AZStd::array& data) - : m_begin(data.data()) - , m_end(m_begin + data.size()) - { } - - array_view(const AZStd::vector& data) - : m_begin(data.data()) - , m_end(m_begin + data.size()) - { } - - template - array_view(const AZStd::fixed_vector& data) - : m_begin(data.data()) - , m_end(m_begin + data.size()) - { } - - array_view(const array_view&) = default; - - array_view(array_view&& other) - : array_view(other.m_begin, other.m_end) - { -#if AZ_DEBUG_BUILD // Clearing the original pointers isn't necessary, but is good for debugging - other.m_begin = nullptr; - other.m_end = nullptr; -#endif - } - - array_view& operator=(const array_view& other) = default; - - array_view& operator=(array_view&& other) - { - m_begin = other.m_begin; - m_end = other.m_end; -#if AZ_DEBUG_BUILD // Clearing the original pointers isn't necessary, but is good for debugging - other.m_begin = nullptr; - other.m_end = nullptr; -#endif - return *this; - } - - size_type size() const { return m_end - m_begin; } - - bool empty() const { return m_end == m_begin; } - - const_pointer data() const { return m_begin; } - - const_reference operator[](size_type index) const - { - AZ_Assert(index < size(), "index value is out of range"); - return m_begin[index]; - } - - void erase() { m_begin = m_end = nullptr; } - - iterator begin() const { return m_begin; } - iterator end() const { return m_end; } - const_iterator cbegin() const { return m_begin; } - const_iterator cend() const { return m_end; } - reverse_iterator rbegin() const { return reverse_iterator(m_end); } - reverse_iterator rend() const { return reverse_iterator(m_begin); } - const_reverse_iterator crbegin() const { return const_reverse_iterator(cend()); } - const_reverse_iterator crend() const { return const_reverse_iterator(cbegin()); } - - friend bool operator==(array_view lhs, array_view rhs) - { - return lhs.m_begin == rhs.m_begin && lhs.m_end == rhs.m_end; - } - - friend bool operator!=(array_view lhs, array_view rhs) { return !(lhs == rhs); } - friend bool operator< (array_view lhs, array_view rhs) { return lhs.m_begin < rhs.m_begin || lhs.m_begin == rhs.m_begin && lhs.m_end < rhs.m_end; } - friend bool operator> (array_view lhs, array_view rhs) { return lhs.m_begin > rhs.m_begin || lhs.m_begin == rhs.m_begin && lhs.m_end > rhs.m_end; } - friend bool operator<=(array_view lhs, array_view rhs) { return lhs == rhs || lhs < rhs; } - friend bool operator>=(array_view lhs, array_view rhs) { return lhs == rhs || lhs > rhs; } - - private: - const_pointer m_begin; - const_pointer m_end; - }; -} // namespace AZStd diff --git a/Code/Framework/AtomCore/Tests/ArrayView.cpp b/Code/Framework/AtomCore/Tests/ArrayView.cpp deleted file mode 100644 index f0208ced3b..0000000000 --- a/Code/Framework/AtomCore/Tests/ArrayView.cpp +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include - -#include -#include - -namespace UnitTest -{ - using namespace AZStd; - - class ArrayView : public AllocatorsTestFixture - { - protected: - template - void ExpectEqual(initializer_list expectedValues, array_view arrayView) - { - EXPECT_EQ(false, arrayView.empty()); - EXPECT_EQ(expectedValues.size(), arrayView.size()); - - typename AZStd::vector::const_iterator iterator = arrayView.begin(); - - for (int i = 0; i < expectedValues.size(); ++i, ++iterator) - { - EXPECT_EQ(expectedValues.begin()[i], arrayView[i]); - EXPECT_EQ(expectedValues.begin()[i], *iterator); - } - - EXPECT_EQ(iterator, arrayView.end()); - } - }; - - TEST_F(ArrayView, DefaultConstructor) - { - array_view defaultView; - - EXPECT_EQ(nullptr, defaultView.begin()); - EXPECT_EQ(nullptr, defaultView.end()); - EXPECT_EQ(0, defaultView.size()); - EXPECT_EQ(true, defaultView.empty()); - } - - TEST_F(ArrayView, PointerConstructor1) - { - int originalValues[4] = { 2,3,4,5 }; - array_view view(originalValues, AZ_ARRAY_SIZE(originalValues)); - - ExpectEqual({ 2,3,4,5 }, view); - - EXPECT_EQ(originalValues, view.begin()); - EXPECT_EQ(&originalValues[4], view.end()); - } - - TEST_F(ArrayView, PointerConstructor2) - { - int originalValues[3] = { 6,7,8 }; - array_view view(originalValues, &originalValues[3]); - - ExpectEqual({ 6,7,8 }, view); - - EXPECT_EQ(originalValues, view.begin()); - EXPECT_EQ(&originalValues[3], view.end()); - } - - TEST_F(ArrayView, ArrayConstructor) - { - array originalValues = { 9,10,11,12 }; - array_view view(originalValues); - - ExpectEqual({ 9,10,11,12 }, view); - - EXPECT_EQ(originalValues.begin(), view.begin()); - EXPECT_EQ(originalValues.end(), view.end()); - } - - - TEST_F(ArrayView, VectorConstructor) - { - vector originalValues = { 13,14,15,16,17,18 }; - array_view view(originalValues); - - ExpectEqual({ 13,14,15,16,17,18 }, view); - - EXPECT_EQ(originalValues.begin(), view.begin()); - EXPECT_EQ(originalValues.end(), view.end()); - } - - TEST_F(ArrayView, FixedVectorConstructor) - { - fixed_vector originalValues = { 17,18,19 }; // Note that even though the fixed_vector capacity is 10, it's size is 3, so the view size will be 3 as well - array_view view(originalValues); - - ExpectEqual({ 17,18,19 }, view); - - EXPECT_EQ(originalValues.begin(), view.begin()); - EXPECT_EQ(originalValues.end(), view.end()); - } - - TEST_F(ArrayView, CopyConstructor) - { - fixed_vector originalValues = { 27,28 }; - - array_view view1(originalValues); - array_view view2(view1); - - ExpectEqual({ 27,28 }, view2); - - EXPECT_EQ(view1.begin(), view2.begin()); - EXPECT_EQ(view1.end(), view2.end()); - } - - TEST_F(ArrayView, MoveConstructor) - { - int originalValues[] = { 29,30,31 }; - array_view view1(originalValues, AZ_ARRAY_SIZE(originalValues)); - array_view view2(AZStd::move(view1)); - - ExpectEqual({ 29,30,31 }, view2); - - EXPECT_EQ(originalValues, view2.begin()); - EXPECT_EQ(&originalValues[3], view2.end()); - - // This isn't strictly necessary but is a good way to make sure the move - // constructor actually exists and it itn't just calling the copy constructor -#if AZ_DEBUG_BUILD // The pointers are only cleared in debug - EXPECT_EQ(nullptr, view1.begin()); - EXPECT_EQ(nullptr, view1.end()); -#endif - } - - TEST_F(ArrayView, AssignmentOperator) - { - fixed_vector originalValues = { 32,33,34,35 }; - - array_view view1(originalValues); - array_view view2; - - view2 = view1; - - ExpectEqual({ 32,33,34,35 }, view2); - - EXPECT_EQ(view1.begin(), view2.begin()); - EXPECT_EQ(view1.end(), view2.end()); - } - - TEST_F(ArrayView, MoveAssignmentOperator) - { - int originalValues[] = { 36,37,38,39,40 }; - array_view view1(originalValues, AZ_ARRAY_SIZE(originalValues)); - array_view view2; - view2 = AZStd::move(view1); - - ExpectEqual({ 36,37,38,39,40 }, view2); - - EXPECT_EQ(originalValues, view2.begin()); - EXPECT_EQ(&originalValues[5], view2.end()); - - // This isn't strictly necessary but is a good way to make sure the move - // assignment operator actually exists and it itn't just calling the norm - // assignment operator -#if AZ_DEBUG_BUILD // The pointers are only cleared in debug - EXPECT_EQ(nullptr, view1.begin()); - EXPECT_EQ(nullptr, view1.end()); -#endif - } - - TEST_F(ArrayView, Erase) - { - fixed_vector originalValues = { 1,2,3,4 }; - - array_view view(originalValues); - view.erase(); - - EXPECT_EQ(nullptr, view.begin()); - EXPECT_EQ(nullptr, view.end()); - EXPECT_EQ(0, view.size()); - EXPECT_EQ(true, view.empty()); - } - - TEST_F(ArrayView, BeginAndEnd) - { - fixed_vector originalValues = { 1,2,3,4 }; - - array_view view(originalValues); - - EXPECT_EQ(1, view.begin()[0]); - EXPECT_EQ(4, view.end()[-1]); - EXPECT_EQ(1, view.cbegin()[0]); - EXPECT_EQ(4, view.cend()[-1]); - EXPECT_EQ(4, view.rbegin()[0]); - EXPECT_EQ(1, view.rend()[-1]); - EXPECT_EQ(4, view.crbegin()[0]); - EXPECT_EQ(1, view.crend()[-1]); - } - - TEST_F(ArrayView, ImplicitConstruction) - { - // This test verifies that we can pass in various non-array_view types - // into functions that take an array_view - - // The compile cannot detect the correct template type so that has to be specified explicitly - - ExpectEqual({ 1,2,3 }, vector({ 1,2,3 })); - ExpectEqual({ 1,2,3 }, fixed_vector({ 1,2,3 })); - ExpectEqual({ 1,2,3 }, array({ 1,2,3 })); - } - - void CheckComparisonOperators(bool areEqual, array_view a, array_view b) - { - EXPECT_EQ(areEqual, a == b); - - // For less/greater operators, the exact order doesn't really matter; - // We just check for internal consistency - if (areEqual) - { - EXPECT_EQ(false, a != b); - EXPECT_EQ(false, a < b); - EXPECT_EQ(false, a > b); - EXPECT_EQ(true, a <= b); - EXPECT_EQ(true, a >= b); - } - else - { - EXPECT_EQ(true, a != b); - - EXPECT_EQ(a > b, a >= b); - EXPECT_EQ(a < b, a <= b); - - EXPECT_NE(a > b, a < b); - EXPECT_NE(a >= b, a <= b); - EXPECT_NE(a >= b, a < b); - EXPECT_NE(a > b, a <= b); - EXPECT_NE(a <= b, a > b); - EXPECT_NE(a < b, a >= b); - } - } - - TEST_F(ArrayView, ComparisonOperators) - { - int arrayA[] = { 1,2,3 }; - int arrayB[] = { 1,2,3 }; - - array_view arrayA_view(arrayA, 3); - array_view arrayB_view(arrayB, 3); - array_view arrayA_otherView(arrayA, 3); - // view of a sub-array aligned to the beginning of the array - array_view arrayA_headView(arrayA, 2); - array_view arrayB_headView(arrayB, 2); - // view of a sub-array aligned to the end of the array - array_view arrayA_tailView(&arrayA[1], 2); - array_view arrayB_tailView(&arrayB[1], 2); - // view of a sub-array in the middle of the array - array_view arrayA_centerView(&arrayA[1], 1); - array_view arrayB_centerView(&arrayB[1], 1); - - // Same view - CheckComparisonOperators(true, arrayA_view, arrayA_view); - - // Different view, same array - CheckComparisonOperators(true, arrayA_view, arrayA_otherView); - CheckComparisonOperators(true, arrayA_otherView, arrayA_view); - - // Different arrays - CheckComparisonOperators(false, arrayA_view, arrayB_view); - CheckComparisonOperators(false, arrayB_view, arrayA_view); - - // Same arrays, but one is a just a subset of the array - CheckComparisonOperators(false, arrayA_view, arrayA_headView); - CheckComparisonOperators(false, arrayA_view, arrayA_tailView); - CheckComparisonOperators(false, arrayA_view, arrayA_centerView); - CheckComparisonOperators(false, arrayA_headView, arrayA_view); - CheckComparisonOperators(false, arrayA_tailView, arrayA_view); - CheckComparisonOperators(false, arrayA_centerView, arrayA_view); - - // Different arrays, different lengths - CheckComparisonOperators(false, arrayA_view, arrayB_headView); - CheckComparisonOperators(false, arrayB_view, arrayA_headView); - CheckComparisonOperators(false, arrayB_headView, arrayA_view); - CheckComparisonOperators(false, arrayA_headView, arrayB_view); - } - - TEST_F(ArrayView, AssertOutOfBounds) - { - array_view view({ 1,2,3,4 }); - - AZ_TEST_START_TRACE_SUPPRESSION; - - view[4]; - view[5]; - - AZ_TEST_STOP_TRACE_SUPPRESSION(2); - } - -} diff --git a/Code/Framework/AtomCore/Tests/atomcore_tests_files.cmake b/Code/Framework/AtomCore/Tests/atomcore_tests_files.cmake index 4522a4b7b6..c518371e8d 100644 --- a/Code/Framework/AtomCore/Tests/atomcore_tests_files.cmake +++ b/Code/Framework/AtomCore/Tests/atomcore_tests_files.cmake @@ -7,7 +7,6 @@ # set(FILES - ArrayView.cpp ConcurrencyCheckerTests.cpp InstanceDatabase.cpp lru_cache.cpp diff --git a/Code/Framework/AzAndroid/java/com/amazon/lumberyard/LumberyardActivity.java b/Code/Framework/AzAndroid/java/com/amazon/lumberyard/LumberyardActivity.java index a234d323eb..846114110f 100644 --- a/Code/Framework/AzAndroid/java/com/amazon/lumberyard/LumberyardActivity.java +++ b/Code/Framework/AzAndroid/java/com/amazon/lumberyard/LumberyardActivity.java @@ -64,7 +64,7 @@ public class LumberyardActivity extends NativeActivity //////////////////////////////////////////////////////////////// // called from the native to get the application package name - // e.g. com.lumberyard.samples for SamplesProject + // e.g. org.o3de.samples for SamplesProject public String GetPackageName() { return getApplicationContext().getPackageName(); 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/BuildInfo.h b/Code/Framework/AzCore/AzCore/BuildInfo.h deleted file mode 100644 index 7032b4b190..0000000000 --- a/Code/Framework/AzCore/AzCore/BuildInfo.h +++ /dev/null @@ -1,11 +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 - * - */ -#define AZCORE_BUILD_NUMBER 368 -#define AZCORE_BUILD_DATE "Thu 10/10/2013" -#define AZCORE_BUILD_TIME "19:42:16.96" -#define AZCORE_SOURCE_CHANGELIST 2992189 diff --git a/Code/Framework/AzCore/AzCore/Component/Component.cpp b/Code/Framework/AzCore/AzCore/Component/Component.cpp index c9829c6dd8..c11e4ef69f 100644 --- a/Code/Framework/AzCore/AzCore/Component/Component.cpp +++ b/Code/Framework/AzCore/AzCore/Component/Component.cpp @@ -49,7 +49,7 @@ namespace AZ return m_entity->GetId(); } - AZ_Warning("System", false, "Can't get component %p entity ID as it is not attached to an entity yet!", this); + AZ_Warning("System", false, "Can't get component (type: %s, addr: %p) entity ID as it is not attached to an entity yet!", RTTI_GetTypeName(), this); return EntityId(); } @@ -60,7 +60,7 @@ namespace AZ return NamedEntityId(m_entity->GetId(), m_entity->GetName()); } - AZ_Warning("System", false, "Can't get component %p entity ID as it is not attached to an entity yet!", this); + AZ_Warning("System", false, "Can't get component (type: %s, addr: %p) entity ID as it is not attached to an entity yet!", RTTI_GetTypeName(), this); return NamedEntityId(); } diff --git a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp index 72b6e807d2..b0194febff 100644 --- a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp +++ b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp @@ -152,8 +152,6 @@ namespace AZ m_reservedDebug = 0; m_recordingMode = Debug::AllocationRecords::RECORD_STACK_IF_NO_FILE_LINE; m_stackRecordLevels = 5; - m_useOverrunDetection = false; - m_useMalloc = false; } bool AppDescriptorConverter(SerializeContext& serialize, SerializeContext::DataElementNode& node) @@ -323,9 +321,6 @@ namespace AZ ->Field("blockSize", &Descriptor::m_memoryBlocksByteSize) ->Field("reservedOS", &Descriptor::m_reservedOS) ->Field("reservedDebug", &Descriptor::m_reservedDebug) - ->Field("useOverrunDetection", &Descriptor::m_useOverrunDetection) - ->Field("useMalloc", &Descriptor::m_useMalloc) - ->Field("allocatorRemappings", &Descriptor::m_allocatorRemappings) ->Field("modules", &Descriptor::m_modules) ; @@ -361,8 +356,6 @@ namespace AZ ->Attribute(Edit::Attributes::Step, &Descriptor::m_pageSize) ->DataElement(Edit::UIHandlers::SpinBox, &Descriptor::m_reservedOS, "OS reserved memory", "System memory reserved for OS (used only when 'Allocate all memory at startup' is true)") ->DataElement(Edit::UIHandlers::SpinBox, &Descriptor::m_reservedDebug, "Memory reserved for debugger", "System memory reserved for Debug allocator, like memory tracking (used only when 'Allocate all memory at startup' is true)") - ->DataElement(Edit::UIHandlers::CheckBox, &Descriptor::m_useOverrunDetection, "Use Overrun Detection", "Use the overrun detection memory manager (only available on some platforms, ignored in Release builds)") - ->DataElement(Edit::UIHandlers::CheckBox, &Descriptor::m_useMalloc, "Use Malloc", "Use malloc for memory allocations (for memory debugging only, ignored in Release builds)") ; } } @@ -881,7 +874,7 @@ namespace AZ AZ::AllocatorInstance::Create(desc); AZ::Debug::Trace::Instance().Init(); - AZ::Debug::AllocationRecords* records = AllocatorInstance::GetAllocator().GetRecords(); + AZ::Debug::AllocationRecords* records = AllocatorInstance::Get().GetRecords(); if (records) { records->SetMode(m_descriptor.m_recordingMode); @@ -893,35 +886,6 @@ namespace AZ m_isSystemAllocatorOwner = true; } - -#ifndef RELEASE - if (m_descriptor.m_useOverrunDetection) - { - OverrunDetectionSchema::Descriptor overrunDesc(false); - s_overrunDetectionSchema = Environment::CreateVariable(AzTypeInfo::Name(), overrunDesc); - OverrunDetectionSchema* schemaPtr = &s_overrunDetectionSchema.Get(); - - AZ::AllocatorManager::Instance().SetOverrideAllocatorSource(schemaPtr); - } - - if (m_descriptor.m_useMalloc) - { - AZ_Printf("Malloc", "WARNING: Malloc override is enabled. Registered allocators will use malloc instead of their normal allocation schemas."); - s_mallocSchema = Environment::CreateVariable(AzTypeInfo::Name()); - MallocSchema* schemaPtr = &s_mallocSchema.Get(); - - AZ::AllocatorManager::Instance().SetOverrideAllocatorSource(schemaPtr); - } -#endif - - AllocatorManager& allocatorManager = AZ::AllocatorManager::Instance(); - - for (const auto& remapping : m_descriptor.m_allocatorRemappings) - { - allocatorManager.AddAllocatorRemapping(remapping.m_from.c_str(), remapping.m_to.c_str()); - } - - allocatorManager.FinalizeConfiguration(); } void ComponentApplication::MergeSettingsToRegistry(SettingsRegistryInterface& registry) diff --git a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.h b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.h index d53b8e1a4e..a28c58ac6b 100644 --- a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.h +++ b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.h @@ -142,10 +142,6 @@ namespace AZ AZ::u64 m_reservedDebug; //!< Reserved memory for Debugging (allocation,etc.). Used only when m_grabAllMemory is set to true. (default: 0) Debug::AllocationRecords::Mode m_recordingMode; //!< When to record stack traces (default: AZ::Debug::AllocationRecords::RECORD_STACK_IF_NO_FILE_LINE) AZ::u64 m_stackRecordLevels; //!< If stack recording is enabled, how many stack levels to record. (default: 5) - bool m_useOverrunDetection; //!< True to use the overrun detection memory management scheme. Only available on some platforms; greatly increases memory consumption. - bool m_useMalloc; //!< True to use malloc instead of the internal memory manager. Intended for debugging purposes only. - - AllocatorRemappings m_allocatorRemappings; //!< List of remappings of allocators to perform, so that they can alias each other. ModuleDescriptorList m_modules; //!< Dynamic modules used by the application. //!< These will be loaded on startup. @@ -159,7 +155,7 @@ namespace AZ //! If set, this allocator is used to allocate the temporary bootstrap memory, as well as the main \ref SystemAllocator heap. //! If it's left nullptr (default), the \ref OSAllocator will be used. - IAllocatorAllocate* m_allocator = nullptr; + IAllocator* m_allocator = nullptr; //! Callback to create AZ::Modules for the static libraries linked by this application. //! Leave null if the application uses no static AZ::Modules. @@ -372,7 +368,7 @@ namespace AZ bool m_isOSAllocatorOwner{ false }; bool m_ownsConsole{}; void* m_fixedMemoryBlock{ nullptr }; //!< Pointer to the memory block allocator, so we can free it OnDestroy. - IAllocatorAllocate* m_osAllocator{ nullptr }; + IAllocator* m_osAllocator{ nullptr }; EntitySetType m_entities; AZ::SettingsRegistryInterface::NotifyEventHandler m_projectPathChangedHandler; diff --git a/Code/Framework/AzCore/AzCore/Component/Entity.cpp b/Code/Framework/AzCore/AzCore/Component/Entity.cpp index c5cda98f2c..db9ead93ad 100644 --- a/Code/Framework/AzCore/AzCore/Component/Entity.cpp +++ b/Code/Framework/AzCore/AzCore/Component/Entity.cpp @@ -230,7 +230,7 @@ namespace AZ EBUS_EVENT_ID(m_id, EntityBus, OnEntityDeactivated, m_id); EBUS_EVENT(EntitySystemBus, OnEntityDeactivated, m_id); - AZ_Assert(m_state == State::Active, "Component should be in Active state to br Deactivated!"); + AZ_Assert(m_state == State::Active, "Component should be in Active state to be Deactivated!"); SetState(State::Deactivating); for (ComponentArrayType::reverse_iterator it = m_components.rbegin(); it != m_components.rend(); ++it) diff --git a/Code/Framework/AzCore/AzCore/Compression/Compression.h b/Code/Framework/AzCore/AzCore/Compression/Compression.h index 855dcf9a6a..105fb9dbe6 100644 --- a/Code/Framework/AzCore/AzCore/Compression/Compression.h +++ b/Code/Framework/AzCore/AzCore/Compression/Compression.h @@ -15,7 +15,7 @@ struct z_stream_s; namespace AZ { class IAllocator; - class IAllocatorAllocate; + class IAllocatorSchema; /** * The most well known and used compression algorithm. It gives the best compression ratios even on level 1, @@ -90,7 +90,7 @@ namespace AZ z_stream_s* m_strDeflate; z_stream_s* m_strInflate; - IAllocatorAllocate* m_workMemoryAllocator; + IAllocatorSchema* m_workMemoryAllocator; }; } diff --git a/Code/Framework/AzCore/AzCore/Compression/compression.cpp b/Code/Framework/AzCore/AzCore/Compression/compression.cpp index 8b6f270b00..b5b775ef5e 100644 --- a/Code/Framework/AzCore/AzCore/Compression/compression.cpp +++ b/Code/Framework/AzCore/AzCore/Compression/compression.cpp @@ -26,7 +26,7 @@ ZLib::ZLib(IAllocator* workMemAllocator) : m_strDeflate(nullptr) , m_strInflate(nullptr) { - m_workMemoryAllocator = workMemAllocator ? workMemAllocator->GetAllocationSource() : nullptr; + m_workMemoryAllocator = workMemAllocator->GetSchema(); if (!m_workMemoryAllocator) { m_workMemoryAllocator = &AllocatorInstance::Get(); @@ -55,7 +55,7 @@ ZLib::~ZLib() //========================================================================= void* ZLib::AllocateMem(void* userData, unsigned int items, unsigned int size) { - IAllocatorAllocate* allocator = reinterpret_cast(userData); + IAllocator* allocator = reinterpret_cast(userData); return allocator->Allocate(items * size, 4, 0, "ZLib", __FILE__, __LINE__); } @@ -65,7 +65,7 @@ void* ZLib::AllocateMem(void* userData, unsigned int items, unsigned int size) //========================================================================= void ZLib::FreeMem(void* userData, void* address) { - IAllocatorAllocate* allocator = reinterpret_cast(userData); + IAllocator* allocator = reinterpret_cast(userData); allocator->DeAllocate(address); } diff --git a/Code/Framework/AzCore/AzCore/Compression/zstd_compression.cpp b/Code/Framework/AzCore/AzCore/Compression/zstd_compression.cpp index ecab62d123..95576a275b 100644 --- a/Code/Framework/AzCore/AzCore/Compression/zstd_compression.cpp +++ b/Code/Framework/AzCore/AzCore/Compression/zstd_compression.cpp @@ -16,7 +16,7 @@ using namespace AZ; -ZStd::ZStd(IAllocatorAllocate* workMemAllocator) +ZStd::ZStd(IAllocator* workMemAllocator) { m_workMemoryAllocator = workMemAllocator; if (!m_workMemoryAllocator) @@ -41,13 +41,13 @@ ZStd::~ZStd() void* ZStd::AllocateMem(void* userData, size_t size) { - IAllocatorAllocate* allocator = reinterpret_cast(userData); + IAllocator* allocator = reinterpret_cast(userData); return allocator->Allocate(size, 4, 0, "ZStandard", __FILE__, __LINE__); } void ZStd::FreeMem(void* userData, void* address) { - IAllocatorAllocate* allocator = reinterpret_cast(userData); + IAllocator* allocator = reinterpret_cast(userData); allocator->DeAllocate(address); } diff --git a/Code/Framework/AzCore/AzCore/Compression/zstd_compression.h b/Code/Framework/AzCore/AzCore/Compression/zstd_compression.h index 3fe6677fff..70d8c37831 100644 --- a/Code/Framework/AzCore/AzCore/Compression/zstd_compression.h +++ b/Code/Framework/AzCore/AzCore/Compression/zstd_compression.h @@ -17,12 +17,11 @@ namespace AZ { class IAllocator; - class IAllocatorAllocate; class ZStd { public: - ZStd(IAllocatorAllocate* workMemAllocator = 0); + ZStd(IAllocator* workMemAllocator = 0); ~ZStd(); enum FlushType @@ -77,7 +76,7 @@ namespace AZ ZSTD_CStream* m_streamCompression; ZSTD_DStream* m_streamDecompression; - IAllocatorAllocate* m_workMemoryAllocator; + IAllocator* m_workMemoryAllocator; ZSTD_inBuffer m_inBuffer; ZSTD_outBuffer m_outBuffer; size_t m_nextBlockSize; 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/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index 10c8e33715..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 @@ -1177,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 d1d3c1745d..4620692b5a 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 @@ -51,7 +53,6 @@ namespace AZ::Dom ValueAllocator() : Base("DomValueAllocator", "Allocator for AZ::Dom::Value") { - DisableOverriding(); } }; @@ -380,6 +381,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/Debug/Profiler.h b/Code/Framework/AzCore/AzCore/Debug/Profiler.h index 6e86de2e93..6b27b35f53 100644 --- a/Code/Framework/AzCore/AzCore/Debug/Profiler.h +++ b/Code/Framework/AzCore/AzCore/Debug/Profiler.h @@ -10,11 +10,6 @@ #include #include -#ifdef USE_PIX -#include -#include -#endif - #if defined(AZ_PROFILER_MACRO_DISABLE) // by default we never disable the profiler registers as their overhead should be minimal, you can // still do that for your code though. #define AZ_PROFILE_SCOPE(...) diff --git a/Code/Framework/AzCore/AzCore/Debug/Profiler.inl b/Code/Framework/AzCore/AzCore/Debug/Profiler.inl index 74c0f553c4..c820639b09 100644 --- a/Code/Framework/AzCore/AzCore/Debug/Profiler.inl +++ b/Code/Framework/AzCore/AzCore/Debug/Profiler.inl @@ -10,44 +10,48 @@ namespace AZ::Debug { + namespace Platform + { + template + void BeginProfileRegion(Budget* budget, const char* eventName, T const&... args); + void BeginProfileRegion(Budget* budget, const char* eventName); + void EndProfileRegion(Budget* budget); + } // namespace Platform + template void ProfileScope::BeginRegion( [[maybe_unused]] Budget* budget, [[maybe_unused]] const char* eventName, [[maybe_unused]] T const&... args) { - if (!budget) + #if !defined(_RELEASE) + if (budget) { - return; - } -#if !defined(_RELEASE) - // TODO: Verification that the supplied system name corresponds to a known budget -#if defined(USE_PIX) - PIXBeginEvent(PIX_COLOR_INDEX(budget->Crc() & 0xff), eventName, args...); -#endif - budget->BeginProfileRegion(); + Platform::BeginProfileRegion(budget, eventName, args...); - if (auto profiler = AZ::Interface::Get(); profiler) - { - profiler->BeginRegion(budget, eventName); + budget->BeginProfileRegion(); + + if (auto profiler = AZ::Interface::Get(); profiler) + { + profiler->BeginRegion(budget, eventName); + } } -#endif + #endif // #if !defined(_RELEASE) } inline void ProfileScope::EndRegion([[maybe_unused]] Budget* budget) { - if (!budget) + #if !defined(_RELEASE) + if (budget) { - return; + budget->EndProfileRegion(); + + if (auto profiler = AZ::Interface::Get(); profiler) + { + profiler->EndRegion(budget); + } + + Platform::EndProfileRegion(budget); } -#if !defined(_RELEASE) - budget->EndProfileRegion(); -#if defined(USE_PIX) - PIXEndEvent(); -#endif - if (auto profiler = AZ::Interface::Get(); profiler) - { - profiler->EndRegion(budget); - } -#endif + #endif // !defined(_RELEASE) } template @@ -63,3 +67,5 @@ namespace AZ::Debug } } // namespace AZ::Debug + +#include 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/CompressorZStd.h b/Code/Framework/AzCore/AzCore/IO/CompressorZStd.h index ed6b94fffa..9503f22665 100644 --- a/Code/Framework/AzCore/AzCore/IO/CompressorZStd.h +++ b/Code/Framework/AzCore/AzCore/IO/CompressorZStd.h @@ -48,7 +48,7 @@ namespace AZ public: AZ_CLASS_ALLOCATOR(CompressorZStdData, AZ::SystemAllocator, 0); - CompressorZStdData(IAllocatorAllocate* zstdMemAllocator = 0) + CompressorZStdData(IAllocator* zstdMemAllocator = 0) { m_zstd = zstdMemAllocator; } 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/IStreamerTypes.cpp b/Code/Framework/AzCore/AzCore/IO/IStreamerTypes.cpp index 4c8272cfc8..4126d7457d 100644 --- a/Code/Framework/AzCore/AzCore/IO/IStreamerTypes.cpp +++ b/Code/Framework/AzCore/AzCore/IO/IStreamerTypes.cpp @@ -21,7 +21,7 @@ namespace AZ::IO::IStreamerTypes : m_allocator(AZ::AllocatorInstance::Get()) {} - DefaultRequestMemoryAllocator::DefaultRequestMemoryAllocator(AZ::IAllocatorAllocate& allocator) + DefaultRequestMemoryAllocator::DefaultRequestMemoryAllocator(AZ::IAllocator& allocator) : m_allocator(allocator) {} diff --git a/Code/Framework/AzCore/AzCore/IO/IStreamerTypes.h b/Code/Framework/AzCore/AzCore/IO/IStreamerTypes.h index 901fc5e594..2c4dc28518 100644 --- a/Code/Framework/AzCore/AzCore/IO/IStreamerTypes.h +++ b/Code/Framework/AzCore/AzCore/IO/IStreamerTypes.h @@ -137,7 +137,7 @@ namespace AZ::IO::IStreamerTypes public: //! DefaultRequestMemoryAllocator wraps around the AZ::SystemAllocator by default. DefaultRequestMemoryAllocator(); - explicit DefaultRequestMemoryAllocator(AZ::IAllocatorAllocate& allocator); + explicit DefaultRequestMemoryAllocator(AZ::IAllocator& allocator); ~DefaultRequestMemoryAllocator() override; void LockAllocator() override; @@ -151,7 +151,7 @@ namespace AZ::IO::IStreamerTypes private: AZStd::atomic_int m_lockCounter{ 0 }; AZStd::atomic_int m_allocationCounter{ 0 }; - AZ::IAllocatorAllocate& m_allocator; + AZ::IAllocator& m_allocator; }; // The following alignment functions are put here until they're available in AzCore's math library. diff --git a/Code/Framework/AzCore/AzCore/IO/Path/Path.cpp b/Code/Framework/AzCore/AzCore/IO/Path/Path.cpp index 6e4dfdaa63..028ffaf535 100644 --- a/Code/Framework/AzCore/AzCore/IO/Path/Path.cpp +++ b/Code/Framework/AzCore/AzCore/IO/Path/Path.cpp @@ -15,9 +15,9 @@ namespace AZ::IO // Class template instantations template class BasicPath; template class BasicPath; - template class PathIterator; - template class PathIterator; - template class PathIterator; + template class PathIterator; + template class PathIterator; + template class PathIterator; // Swap function instantiations template void swap(Path& lhs, Path& rhs) noexcept; @@ -38,16 +38,16 @@ namespace AZ::IO const typename BasicPath::value_type* rhs); // Iterator compare instantiations - template bool operator==(const PathIterator& lhs, - const PathIterator& rhs); - template bool operator==(const PathIterator& lhs, - const PathIterator& rhs); - template bool operator==(const PathIterator& lhs, - const PathIterator& rhs); - template bool operator!=(const PathIterator& lhs, - const PathIterator& rhs); - template bool operator!=(const PathIterator& lhs, - const PathIterator& rhs); - template bool operator!=(const PathIterator& lhs, - const PathIterator& rhs); + template bool operator==(const PathIterator& lhs, + const PathIterator& rhs); + template bool operator==(const PathIterator& lhs, + const PathIterator& rhs); + template bool operator==(const PathIterator& lhs, + const PathIterator& rhs); + template bool operator!=(const PathIterator& lhs, + const PathIterator& rhs); + template bool operator!=(const PathIterator& lhs, + const PathIterator& rhs); + template bool operator!=(const PathIterator& lhs, + const PathIterator& rhs); } diff --git a/Code/Framework/AzCore/AzCore/IO/Path/Path.h b/Code/Framework/AzCore/AzCore/IO/Path/Path.h index 7f89809294..235310a5da 100644 --- a/Code/Framework/AzCore/AzCore/IO/Path/Path.h +++ b/Code/Framework/AzCore/AzCore/IO/Path/Path.h @@ -43,9 +43,9 @@ namespace AZ::IO public: using string_view_type = AZStd::string_view; using value_type = char; - using const_iterator = const PathIterator; + using const_iterator = PathIterator; using iterator = const_iterator; - friend PathIterator; + friend const_iterator; // constructors and destructor constexpr PathView() = default; @@ -319,9 +319,9 @@ namespace AZ::IO using value_type = typename StringType::value_type; using traits_type = typename StringType::traits_type; using string_view_type = AZStd::string_view; - using const_iterator = const PathIterator; + using const_iterator = PathIterator; using iterator = const_iterator; - friend PathIterator; + friend const_iterator; // constructors and destructor constexpr BasicPath() = default; @@ -692,7 +692,7 @@ namespace AZ::IO friend PathType; using iterator_category = AZStd::bidirectional_iterator_tag; - using value_type = PathType; + using value_type = AZStd::remove_cv_t; using difference_type = ptrdiff_t; using pointer = const value_type*; using reference = const value_type&; @@ -703,8 +703,9 @@ namespace AZ::IO constexpr PathIterator() = default; constexpr PathIterator(const PathIterator&) = default; - + constexpr PathIterator(PathIterator&&) noexcept = default; constexpr PathIterator& operator=(const PathIterator&) = default; + constexpr PathIterator& operator=(PathIterator&&) noexcept = default; constexpr reference operator*() const; @@ -733,10 +734,10 @@ namespace AZ::IO ParserState m_state{ Singular }; }; - template - constexpr bool operator==(const PathIterator& lhs, const PathIterator& rhs); - template - constexpr bool operator!=(const PathIterator& lhs, const PathIterator& rhs); + template + constexpr bool operator==(const PathIterator& lhs, const PathIterator& rhs); + template + constexpr bool operator!=(const PathIterator& lhs, const PathIterator& rhs); } #include diff --git a/Code/Framework/AzCore/AzCore/IO/Path/Path.inl b/Code/Framework/AzCore/AzCore/IO/Path/Path.inl index 0dc1799528..bde2353112 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 { @@ -443,7 +399,7 @@ namespace AZ::IO constexpr auto PathView::begin() const -> const_iterator { auto pathParser = parser::PathParser::CreateBegin(m_path, m_preferred_separator); - PathIterator it; + const_iterator it; it.m_path_ref = this; it.m_state = static_cast(pathParser.m_parser_state); it.m_path_entry_view = pathParser.m_path_raw_entry; @@ -453,7 +409,7 @@ namespace AZ::IO constexpr auto PathView::end() const -> const_iterator { - PathIterator it; + const_iterator it; it.m_state = const_iterator::AtEnd; it.m_path_ref = this; return it; @@ -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); @@ -1306,7 +1262,7 @@ namespace AZ::IO constexpr auto BasicPath::begin() const -> const_iterator { auto pathParser = parser::PathParser::CreateBegin(m_path, m_preferred_separator); - PathIterator it; + const_iterator it; it.m_path_ref = this; it.m_state = static_cast(pathParser.m_parser_state); it.m_path_entry_view = pathParser.m_path_raw_entry; @@ -1317,7 +1273,7 @@ namespace AZ::IO template constexpr auto BasicPath::end() const -> const_iterator { - PathIterator it; + const_iterator it; it.m_state = const_iterator::AtEnd; it.m_path_ref = this; return it; @@ -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/Path/PathParser.inl b/Code/Framework/AzCore/AzCore/IO/Path/PathParser.inl index b19c518ff9..f8712551b0 100644 --- a/Code/Framework/AzCore/AzCore/IO/Path/PathParser.inl +++ b/Code/Framework/AzCore/AzCore/IO/Path/PathParser.inl @@ -10,6 +10,7 @@ #include #include +#include namespace AZ::IO::Internal { @@ -17,7 +18,7 @@ namespace AZ::IO::Internal { return elem == '/' || elem == '\\'; } - template >> + template >> static constexpr bool HasDrivePrefix(InputIt first, EndIt last) { size_t prefixSize = AZStd::distance(first, last); @@ -46,7 +47,7 @@ namespace AZ::IO::Internal //! Windows root names can have include drive letter within them template constexpr auto ConsumeRootName(InputIt entryBeginIter, InputIt entryEndIter, const char preferredSeparator) - -> AZStd::enable_if_t, InputIt> + -> AZStd::enable_if_t, InputIt> { if (preferredSeparator == PosixPathSeparator) { @@ -147,7 +148,7 @@ namespace AZ::IO::Internal //! If the preferred separator is '/' just checks if the path starts with a '/ //! Otherwise a check for a Windows absolute path occurs //! Windows absolute paths can include a RootName - template >> + template >> static constexpr bool IsAbsolute(InputIt first, EndIt last, const char preferredSeparator) { size_t pathSize = AZStd::distance(first, last); @@ -208,11 +209,11 @@ namespace AZ::IO::parser enum ParserState : uint8_t { // Zero is a special sentinel value used by default constructed iterators. - PS_BeforeBegin = PathIterator::BeforeBegin, - PS_InRootName = PathIterator::InRootName, - PS_InRootDir = PathIterator::InRootDir, - PS_InFilenames = PathIterator::InFilenames, - PS_AtEnd = PathIterator::AtEnd + PS_BeforeBegin = PathView::const_iterator::BeforeBegin, + PS_InRootName = PathView::const_iterator::InRootName, + PS_InRootDir = PathView::const_iterator::InRootDir, + PS_InFilenames = PathView::const_iterator::InFilenames, + PS_AtEnd = PathView::const_iterator::AtEnd }; struct PathParser 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/Jobs/LegacyJobExecutor.h b/Code/Framework/AzCore/AzCore/Jobs/LegacyJobExecutor.h deleted file mode 100644 index 8018cf409f..0000000000 --- a/Code/Framework/AzCore/AzCore/Jobs/LegacyJobExecutor.h +++ /dev/null @@ -1,197 +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 AZCORE_JOBS_JOBEXECUTOR_H -#define AZCORE_JOBS_JOBEXECUTOR_H - -#pragma once - -#include -#include -#include -#include - -namespace AZ -{ - /** - * Helper for porting legacy jobs that allows Starting and Waiting for multiple jobs asynchronously - */ - class LegacyJobExecutor final - { - public: - LegacyJobExecutor() = default; - - LegacyJobExecutor(const LegacyJobExecutor&) = delete; - - ~LegacyJobExecutor() - { - WaitForCompletion(); - } - - template - inline void StartJob(const Function& processFunction, JobContext* context = nullptr) - { - Job * job = aznew JobFunctionExecutorHelper(processFunction, *this, context); - StartJobInternal(job); - } - - // SetPostJob - This API exists to support backwards compatibility and is not a recommended pattern to be copied. - // Instead, create AZ::Jobs with appropriate dependencies on each other - template - inline void SetPostJob(LegacyJobExecutor& postJobExecutor, const Function& processFunction, JobContext* context = nullptr) - { - AZStd::unique_ptr postJob(aznew JobFunctionExecutorHelper(processFunction, postJobExecutor, context)); // Allocate outside the lock - { - LockGuard lockGuard(m_conditionLock); - - AZ_Assert(!m_postJob, "Post already set"); - AZ_Assert(!m_running, "LegacyJobExecutor::SetPostJob() must be called before starting any jobs"); - m_postJob = std::move(postJob); - // Note: m_jobCount is not incremented until we push the post job - } - } - - inline void ClearPostJob() - { - LockGuard lockGuard(m_conditionLock); - m_postJob.reset(); - } - - inline void Reset() - { - AZ_Assert(!IsRunning(), "LegacyJobExecutor::Reset() called while jobs in flight"); - } - - inline void WaitForCompletion() - { - AZStd::unique_lock uniqueLock(m_conditionLock); - - while (m_running) - { - AZ_PROFILE_FUNCTION(AzCore); - m_completionCondition.wait(uniqueLock, [this] { return !this->m_running; }); - } - } - - // Push a logical fence that will cause WaitForCompletion to wait until PopCompletionFence is called and all jobs are complete. Analogue to the legacy API SJobState::SetStarted() - // Note: this does NOT fence execution of jobs in relation to each other - inline void PushCompletionFence() - { - IncJobCount(); - } - - // Pop a logical completion fence. Analogue to the legacy API SJobState::SetStopped() - inline void PopCompletionFence() - { - JobCompleteUpdate(); - } - - // Are there presently jobs in-flight (queued or running)? - inline bool IsRunning() - { - return m_running; - } - - private: - void JobCompleteUpdate() - { - AZ_Assert(m_jobCount, "Invalid LegacyJobExecutor::m_jobCount."); - if (--m_jobCount == 0) // note: m_jobCount is atomic, so only the last completing job will take the count to zero - { - JobExecutorHelper* postJob = nullptr; - { - // All state transitions to and from running must be serialized through the condition lock - LockGuard lockGuard(m_conditionLock); - - // Test count again as another job may have started before we got the lock - if (!m_jobCount) - { - m_running = false; - postJob = m_postJob.release(); - m_completionCondition.notify_all(); - } - } - - // outside the lock (this pointer is no longer valid)... - if (postJob) - { - postJob->StartOnExecutor(); - } - } - } - - void StartJobInternal(Job * job) - { - IncJobCount(); - job->Start(); - } - - void IncJobCount() - { - if (m_jobCount++ == 0) - { - // All state transitions to and from running must be serialized through the condition lock (Even though m_running is atomic) - LockGuard lockGuard(m_conditionLock); - m_running = true; - } - } - - class JobExecutorHelper - { - public: - virtual ~JobExecutorHelper() = default; - virtual void StartOnExecutor() = 0; - }; - - /** - * Private Job type that notifies the owning LegacyJobExecutor of completion - */ - template - class JobFunctionExecutorHelper : public JobFunction, public JobExecutorHelper - { - using Base = JobFunction; - public: - AZ_CLASS_ALLOCATOR(JobFunctionExecutorHelper, ThreadPoolAllocator, 0) - - JobFunctionExecutorHelper(typename JobFunction::FunctionCRef processFunction, LegacyJobExecutor& executor, JobContext* context) - : JobFunction(processFunction, true /* isAutoDelete */, context) - , m_executor(executor) - { - } - - void StartOnExecutor() override - { - m_executor.StartJobInternal(this); - } - - void Process() override - { - Base::Process(); - - m_executor.JobCompleteUpdate(); - } - - private: - LegacyJobExecutor& m_executor; - }; - - template - friend class JobFunctionExecutorHelper; // For JobCompleteUpdate, StartJobInternal - - using Lock = AZStd::mutex; - using LockGuard = AZStd::lock_guard; - - AZStd::condition_variable m_completionCondition; - Lock m_conditionLock; - AZStd::unique_ptr m_postJob; - - AZStd::atomic_uint m_jobCount{0}; - AZStd::atomic_bool m_running{false}; - }; -} - -#endif 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/AllocatorBase.cpp b/Code/Framework/AzCore/AzCore/Memory/AllocatorBase.cpp index c2bf9fe45c..e877739e29 100644 --- a/Code/Framework/AzCore/AzCore/Memory/AllocatorBase.cpp +++ b/Code/Framework/AzCore/AzCore/Memory/AllocatorBase.cpp @@ -9,11 +9,12 @@ #include #include -#define RECORDING_ENABLED 0 +// Only used to create recordings of memory operations to use for memory benchmarks +#define O3DE_RECORDING_ENABLED 0 -#if RECORDING_ENABLED +#if O3DE_RECORDING_ENABLED -#include +#include #include #include #include @@ -62,23 +63,24 @@ namespace static constexpr size_t s_maxNumberOfAllocationsToRecord = 16384; static size_t s_numberOfAllocationsRecorded = 0; - static constexpr size_t s_allocationOperationCount = 5 * 1024; + static constexpr size_t s_allocationOperationCount = 8 * 1024; static AZStd::array s_operations = {}; static uint64_t s_operationCounter = 0; static unsigned int s_nextRecordId = 1; - using AllocatorOperationByAddress = AZStd::unordered_map, DebugAllocator>; + using AllocatorOperationByAddress = AZStd::map, DebugAllocator>; static AllocatorOperationByAddress s_allocatorOperationByAddress; using AvailableRecordIds = AZStd::vector; AvailableRecordIds s_availableRecordIds; void RecordAllocatorOperation(AllocatorOperation::OperationType type, void* ptr, size_t size = 0, size_t alignment = 0) { - AZStd::scoped_lock lock(s_operationsMutex); + AZStd::scoped_lock lock(s_operationsMutex); if (s_operationCounter == s_allocationOperationCount) { AZ::IO::SystemFile file; int mode = AZ::IO::SystemFile::OpenMode::SF_OPEN_APPEND | AZ::IO::SystemFile::OpenMode::SF_OPEN_WRITE_ONLY; + // memoryrecordings.bin is being output to the current working directory if (!file.Exists("memoryrecordings.bin")) { mode |= AZ::IO::SystemFile::OpenMode::SF_OPEN_CREATE; @@ -158,8 +160,8 @@ namespace namespace AZ { - AllocatorBase::AllocatorBase(IAllocatorAllocate* allocationSource, const char* name, const char* desc) - : IAllocator(allocationSource) + AllocatorBase::AllocatorBase(IAllocatorSchema* allocationSchema, const char* name, const char* desc) + : IAllocator(allocationSchema) , m_name(name) , m_desc(desc) { @@ -184,11 +186,6 @@ namespace AZ return m_desc; } - IAllocatorAllocate* AllocatorBase::GetSchema() - { - return nullptr; - } - Debug::AllocationRecords* AllocatorBase::GetRecords() { return m_records; @@ -205,11 +202,6 @@ namespace AZ return m_isReady; } - bool AllocatorBase::CanBeOverridden() const - { - return m_canBeOverridden; - } - void AllocatorBase::PostCreate() { if (m_registrationEnabled) @@ -272,11 +264,6 @@ namespace AZ return m_isProfilingActive; } - void AllocatorBase::DisableOverriding() - { - m_canBeOverridden = false; - } - void AllocatorBase::DisableRegistration() { m_registrationEnabled = false; @@ -285,10 +272,6 @@ namespace AZ void AllocatorBase::ProfileAllocation( void* ptr, size_t byteSize, size_t alignment, const char* name, const char* fileName, int lineNum, int suppressStackRecord) { -#if defined(AZ_HAS_VARIADIC_TEMPLATES) && defined(AZ_DEBUG_BUILD) - ++suppressStackRecord; // one more for the fact the ebus is a function -#endif // AZ_HAS_VARIADIC_TEMPLATES - if (m_isProfilingActive) { auto records = GetRecords(); @@ -298,7 +281,7 @@ namespace AZ } } -#if RECORDING_ENABLED +#if O3DE_RECORDING_ENABLED RecordAllocatorOperation(AllocatorOperation::ALLOCATE, ptr, byteSize, alignment); #endif } @@ -313,7 +296,7 @@ namespace AZ records->UnregisterAllocation(ptr, byteSize, alignment, info); } } -#if RECORDING_ENABLED +#if O3DE_RECORDING_ENABLED RecordAllocatorOperation(AllocatorOperation::DEALLOCATE, ptr, byteSize, alignment); #endif } @@ -330,7 +313,7 @@ namespace AZ ProfileDeallocation(ptr, 0, 0, &info); ProfileAllocation(newPtr, newSize, newAlignment, info.m_name, info.m_fileName, info.m_lineNum, 0); } -#if RECORDING_ENABLED +#if O3DE_RECORDING_ENABLED RecordAllocatorOperation(AllocatorOperation::DEALLOCATE, ptr); RecordAllocatorOperation(AllocatorOperation::ALLOCATE, newPtr, newSize, newAlignment); #endif @@ -351,7 +334,7 @@ namespace AZ records->ResizeAllocation(ptr, newSize); } } -#if RECORDING_ENABLED +#if O3DE_RECORDING_ENABLED RecordAllocatorOperation(AllocatorOperation::ALLOCATE, ptr, newSize); #endif } diff --git a/Code/Framework/AzCore/AzCore/Memory/AllocatorBase.h b/Code/Framework/AzCore/AzCore/Memory/AllocatorBase.h index 8f8a17e470..f2521087b3 100644 --- a/Code/Framework/AzCore/AzCore/Memory/AllocatorBase.h +++ b/Code/Framework/AzCore/AzCore/Memory/AllocatorBase.h @@ -22,7 +22,7 @@ namespace AZ class AllocatorBase : public IAllocator { protected: - AllocatorBase(IAllocatorAllocate* allocationSource, const char* name, const char* desc); + AllocatorBase(IAllocatorSchema* allocationSchema, const char* name, const char* desc); ~AllocatorBase(); public: @@ -32,11 +32,9 @@ namespace AZ //--------------------------------------------------------------------- const char* GetName() const override; const char* GetDescription() const override; - IAllocatorAllocate* GetSchema() override; Debug::AllocationRecords* GetRecords() final; void SetRecords(Debug::AllocationRecords* records) final; bool IsReady() const final; - bool CanBeOverridden() const final; void PostCreate() override; void PreDestroy() final; void SetLazilyCreated(bool lazy) final; @@ -68,10 +66,6 @@ namespace AZ return byteSize; } - /// Call to disallow this allocator from being overridden. - /// Only kernel-level allocators where it would be especially problematic for them to be overridden should do this. - void DisableOverriding(); - /// Call to disallow this allocator from being registered with the AllocatorManager. /// Only kernel-level allocators where it would be especially problematic for them to be registered with the AllocatorManager should do this. void DisableRegistration(); @@ -107,7 +101,6 @@ namespace AZ bool m_isLazilyCreated = false; bool m_isProfilingActive = false; bool m_isReady = false; - bool m_canBeOverridden = true; bool m_registrationEnabled = true; }; diff --git a/Code/Framework/AzCore/AzCore/Memory/AllocatorManager.cpp b/Code/Framework/AzCore/AzCore/Memory/AllocatorManager.cpp index 70ac813972..758fa222fe 100644 --- a/Code/Framework/AzCore/AzCore/Memory/AllocatorManager.cpp +++ b/Code/Framework/AzCore/AzCore/Memory/AllocatorManager.cpp @@ -12,17 +12,12 @@ #include #include -#include #include #include #include #include -#if !defined(RELEASE) && !defined(AZCORE_MEMORY_ENABLE_OVERRIDES) -# define AZCORE_MEMORY_ENABLE_OVERRIDES -#endif - namespace AZ::Internal { struct AMStringHasher @@ -54,18 +49,6 @@ namespace AZ::Internal namespace AZ { -struct AllocatorManager::InternalData -{ - explicit InternalData(const AZStdIAllocator& alloc) - : m_allocatorMap(alloc) - , m_remappings(alloc) - , m_remappingsReverse(alloc) - {} - Internal::AllocatorNameMap m_allocatorMap; - Internal::AllocatorRemappings m_remappings; - Internal::AllocatorRemappings m_remappingsReverse; -}; - static EnvironmentVariable s_allocManager = nullptr; static AllocatorManager* s_allocManagerDebug = nullptr; // For easier viewing in crash dumps @@ -81,16 +64,6 @@ static Internal::PreEnvironmentAttachData& GetPreEnvironmentAttachData() void AllocatorManager::PreRegisterAllocator(IAllocator* allocator) { auto& data = GetPreEnvironmentAttachData(); - -#ifdef AZCORE_MEMORY_ENABLE_OVERRIDES - // All allocators must switch to an OverrideEnabledAllocationSource proxy if they are to support allocator overriding. - if (allocator->CanBeOverridden()) - { - auto shim = Internal::AllocatorOverrideShim::Create(allocator, &data.m_mallocSchema); - allocator->SetAllocationSource(shim); - } -#endif - { AZStd::lock_guard lock(data.m_mutex); AZ_Assert(data.m_unregisteredAllocatorCount < Internal::PreEnvironmentAttachData::MAX_UNREGISTERED_ALLOCATORS, "Too many allocators trying to register before environment attached!"); @@ -175,12 +148,9 @@ AllocatorManager::AllocatorManager() } ) { - m_overrideSource = nullptr; m_numAllocators = 0; m_isAllocatorLeaking = false; - m_configurationFinalized = false; m_defaultTrackingRecordMode = Debug::AllocationRecords::RECORD_NO_RECORDS; - m_data = new (m_mallocSchema->Allocate(sizeof(InternalData), AZStd::alignment_of::value, 0)) InternalData(AZStdIAllocator(m_mallocSchema.get())); } //========================================================================= @@ -210,10 +180,6 @@ AllocatorManager::RegisterAllocator(class IAllocator* alloc) alloc->SetProfilingActive(m_profilingRefcount.load() > 0); m_allocators[m_numAllocators++] = alloc; - -#ifdef AZCORE_MEMORY_ENABLE_OVERRIDES - ConfigureAllocatorOverrides(alloc); -#endif } //========================================================================= @@ -232,81 +198,12 @@ AllocatorManager::InternalDestroy() // Do not actually destroy the lazy allocator as it may have work to do during non-deterministic shutdown } - if (m_data) - { - m_data->~InternalData(); - m_mallocSchema->DeAllocate(m_data); - m_data = nullptr; - } - if (!m_isAllocatorLeaking) { AZ_Assert(m_numAllocators == 0, "There are still %d registered allocators!", m_numAllocators); } } -//========================================================================= -// ConfigureAllocatorOverrides -// [10/14/2018] -//========================================================================= -void -AllocatorManager::ConfigureAllocatorOverrides(IAllocator* alloc) -{ - auto record = m_data->m_allocatorMap.emplace(AZStd::piecewise_construct, AZStd::forward_as_tuple(alloc->GetName(), AZStdIAllocator(m_mallocSchema.get())), AZStd::forward_as_tuple(alloc)); - - // We only need to keep going if the allocator supports overrides. - if (!alloc->CanBeOverridden()) - { - return; - } - - if (!alloc->IsAllocationSourceChanged()) - { - // All allocators must switch to an OverrideEnabledAllocationSource proxy if they are to support allocator overriding. - auto overrideEnabled = Internal::AllocatorOverrideShim::Create(alloc, m_mallocSchema.get()); - alloc->SetAllocationSource(overrideEnabled); - } - - auto itr = m_data->m_remappings.find(record.first->first); - - if (itr != m_data->m_remappings.end()) - { - auto remapTo = m_data->m_allocatorMap.find(itr->second); - - if (remapTo != m_data->m_allocatorMap.end()) - { - static_cast(alloc->GetAllocationSource())->SetOverride(remapTo->second->GetOriginalAllocationSource()); - } - } - - itr = m_data->m_remappingsReverse.find(record.first->first); - - if (itr != m_data->m_remappingsReverse.end()) - { - auto remapFrom = m_data->m_allocatorMap.find(itr->second); - - if (remapFrom != m_data->m_allocatorMap.end()) - { - AZ_Assert(!m_configurationFinalized, "Allocators may only remap to allocators that have been created before configuration finalization"); - static_cast(remapFrom->second->GetAllocationSource())->SetOverride(alloc->GetOriginalAllocationSource()); - } - } - - if (m_overrideSource) - { - static_cast(alloc->GetAllocationSource())->SetOverride(m_overrideSource); - } - - if (m_configurationFinalized) - { - // We can get rid of the intermediary if configuration won't be changing any further. - // (The creation of it at the top of this function was superflous, but it made it easier to set things up going through a single code path.) - auto shim = static_cast(alloc->GetAllocationSource()); - alloc->SetAllocationSource(shim->GetOverride()); - Internal::AllocatorOverrideShim::Destroy(shim); - } -} - //========================================================================= // UnRegisterAllocator // [9/17/2009] @@ -365,7 +262,7 @@ AllocatorManager::GarbageCollect() for (int i = 0; i < m_numAllocators; ++i) { - m_allocators[i]->GetAllocationSource()->GarbageCollect(); + m_allocators[i]->GetSchema()->GarbageCollect(); } } @@ -414,94 +311,6 @@ AllocatorManager::SetTrackingMode(Debug::AllocationRecords::Mode mode) } } -//========================================================================= -// SetOverrideSchema -// [8/17/2018] -//========================================================================= -void -AllocatorManager::SetOverrideAllocatorSource(IAllocatorAllocate* source, bool overrideExistingAllocators) -{ - (void)source; - (void)overrideExistingAllocators; - -#ifdef AZCORE_MEMORY_ENABLE_OVERRIDES - AZ_Assert(!m_configurationFinalized, "You cannot set an allocator source after FinalizeConfiguration() has been called."); - m_overrideSource = source; - - if (overrideExistingAllocators) - { - AZStd::lock_guard lock(m_allocatorListMutex); - for (int i = 0; i < m_numAllocators; ++i) - { - if (m_allocators[i]->CanBeOverridden()) - { - auto shim = static_cast(m_allocators[i]->GetAllocationSource()); - shim->SetOverride(source); - } - } - } -#endif -} - -//========================================================================= -// AddAllocatorRemapping -// [8/27/2018] -//========================================================================= -void -AllocatorManager::AddAllocatorRemapping(const char* fromName, const char* toName) -{ - (void)fromName; - (void)toName; - -#ifdef AZCORE_MEMORY_ENABLE_OVERRIDES - AZ_Assert(!m_configurationFinalized, "You cannot set an allocator remapping after FinalizeConfiguration() has been called."); - m_data->m_remappings.emplace(AZStd::piecewise_construct, AZStd::forward_as_tuple(fromName, m_mallocSchema.get()), AZStd::forward_as_tuple(toName, m_mallocSchema.get())); - m_data->m_remappingsReverse.emplace(AZStd::piecewise_construct, AZStd::forward_as_tuple(toName, m_mallocSchema.get()), AZStd::forward_as_tuple(fromName, m_mallocSchema.get())); -#endif -} - -void -AllocatorManager::FinalizeConfiguration() -{ - if (m_configurationFinalized) - { - return; - } - -#ifdef AZCORE_MEMORY_ENABLE_OVERRIDES - { - AZStd::lock_guard lock(m_allocatorListMutex); - - for (int i = 0; i < m_numAllocators; ++i) - { - if (!m_allocators[i]->CanBeOverridden()) - { - continue; - } - - auto shim = static_cast(m_allocators[i]->GetAllocationSource()); - - if (!shim->IsOverridden()) - { - m_allocators[i]->ResetAllocationSource(); - Internal::AllocatorOverrideShim::Destroy(shim); - } - else if (!shim->HasOrphanedAllocations()) - { - m_allocators[i]->SetAllocationSource(shim->GetOverride()); - Internal::AllocatorOverrideShim::Destroy(shim); - } - else - { - shim->SetFinalizedConfiguration(); - } - } - } -#endif - - m_configurationFinalized = true; -} - void AllocatorManager::EnterProfilingMode() { @@ -545,27 +354,18 @@ AllocatorManager::DumpAllocators() size_t totalConsumedBytes = 0; memset(m_dumpInfo, 0, sizeof(m_dumpInfo)); - void* sourceList[m_maxNumAllocators]; AZ_Printf(TAG, "%d allocators active\n", m_numAllocators); AZ_Printf(TAG, "Index,Name,Used kb,Reserved kb,Consumed kb\n"); for (int i = 0; i < m_numAllocators; i++) { - auto allocator = m_allocators[i]; - auto source = allocator->GetAllocationSource(); + IAllocator* allocator = GetAllocator(i); const char* name = allocator->GetName(); - size_t usedBytes = source->NumAllocatedBytes(); - size_t reservedBytes = source->Capacity(); + size_t usedBytes = allocator->NumAllocatedBytes(); + size_t reservedBytes = allocator->Capacity(); size_t consumedBytes = reservedBytes; - // Very hacky and inefficient check to see if this allocator obtains its memory from another allocator - sourceList[i] = source; - if (AZStd::find(sourceList, sourceList + i, allocator->GetSchema()) != sourceList + i) - { - consumedBytes = 0; - } - totalUsedBytes += usedBytes; totalReservedBytes += reservedBytes; totalConsumedBytes += consumedBytes; @@ -585,61 +385,21 @@ void AllocatorManager::GetAllocatorStats(size_t& allocatedBytes, size_t& capacit AZStd::lock_guard lock(m_allocatorListMutex); const int allocatorCount = GetNumAllocators(); - AZStd::unordered_map existingAllocators; - AZStd::unordered_map sourcesToAllocators; // Build a mapping of original allocator sources to their allocators for (int i = 0; i < allocatorCount; ++i) { IAllocator* allocator = GetAllocator(i); - sourcesToAllocators.emplace(allocator->GetOriginalAllocationSource(), allocator); - } - - for (int i = 0; i < allocatorCount; ++i) - { - IAllocator* allocator = GetAllocator(i); - IAllocatorAllocate* source = allocator->GetAllocationSource(); - IAllocatorAllocate* originalSource = allocator->GetOriginalAllocationSource(); - IAllocatorAllocate* schema = allocator->GetSchema(); - IAllocator* alias = (source != originalSource) ? sourcesToAllocators[source] : nullptr; - - if (schema && !alias) - { - // Check to see if this allocator's source maps to another allocator - // Need to check both the schema and the allocator itself, as either one might be used as the alias depending on how it's implemented - AZStd::array checkAllocators = { { schema, allocator->GetAllocationSource() } }; - - for (IAllocatorAllocate* check : checkAllocators) - { - auto existing = existingAllocators.emplace(check, allocator); - - if (!existing.second) - { - alias = existing.first->second; - // Do not break out of the loop as we need to add to the map for all entries - } - } - } - - static const IAllocator* OS_ALLOCATOR = &AllocatorInstance::GetAllocator(); - size_t sourceAllocatedBytes = source->NumAllocatedBytes(); - size_t sourceCapacityBytes = source->Capacity(); - - if (allocator == OS_ALLOCATOR) - { - // Need to special case the OS allocator because its capacity is a made-up number. Better to just use the allocated amount, it will hopefully be small anyway. - sourceCapacityBytes = sourceAllocatedBytes; - } - + allocatedBytes += allocator->NumAllocatedBytes(); + capacityBytes += allocator->Capacity(); + if (outStats) { - outStats->emplace(outStats->end(), allocator->GetName(), alias ? alias->GetName() : allocator->GetDescription(), sourceAllocatedBytes, sourceCapacityBytes, alias != nullptr); - } - - if (!alias) - { - allocatedBytes += sourceAllocatedBytes; - capacityBytes += sourceCapacityBytes; + outStats->emplace(outStats->end(), + allocator->GetName(), + allocator->GetDescription(), + allocator->NumAllocatedBytes(), + allocator->Capacity()); } } } diff --git a/Code/Framework/AzCore/AzCore/Memory/AllocatorManager.h b/Code/Framework/AzCore/AzCore/Memory/AllocatorManager.h index 14dec68ad1..f38fb23c47 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 @@ -84,17 +87,6 @@ namespace AZ /// Especially for great code and engines... void SetAllocatorLeaking(bool allowLeaking) { m_isAllocatorLeaking = allowLeaking; } - /// Set an override allocator - /// All allocators registered with the AllocatorManager will automatically redirect to this allocator - /// if set. - void SetOverrideAllocatorSource(IAllocatorAllocate* source, bool overrideExistingAllocators = true); - - /// Retrieve the override schema - IAllocatorAllocate* GetOverrideAllocatorSource() const { return m_overrideSource; } - - void AddAllocatorRemapping(const char* fromName, const char* toName); - void FinalizeConfiguration(); - /// Enter or exit profiling mode; calls to Enter must be matched with calls to Exit void EnterProfilingMode(); void ExitProfilingMode(); @@ -113,19 +105,17 @@ namespace AZ struct AllocatorStats { - AllocatorStats(const char* name, const char* aliasOrDescription, size_t allocatedBytes, size_t capacityBytes, bool isAlias) + AllocatorStats(const char* name, const char* aliasOrDescription, size_t allocatedBytes, size_t capacityBytes) : m_name(name) , m_aliasOrDescription(aliasOrDescription) , m_allocatedBytes(allocatedBytes) , m_capacityBytes(capacityBytes) - , m_isAlias(isAlias) {} AZStd::string m_name; AZStd::string m_aliasOrDescription; size_t m_allocatedBytes; size_t m_capacityBytes; - bool m_isAlias; }; void GetAllocatorStats(size_t& usedBytes, size_t& reservedBytes, AZStd::vector* outStats = nullptr); @@ -157,7 +147,6 @@ namespace AZ private: void InternalDestroy(); - void ConfigureAllocatorOverrides(IAllocator* alloc); void DebugBreak(void* address, const Debug::AllocationInfo& info); AZ::MallocSchema* CreateMallocSchema(); @@ -172,20 +161,14 @@ namespace AZ MemoryBreak m_memoryBreak[MaxNumMemoryBreaks]; char m_activeBreaks; AZStd::mutex m_allocatorListMutex; - IAllocatorAllocate* m_overrideSource; DumpInfo m_dumpInfo[m_maxNumAllocators]; - struct InternalData; - - InternalData* m_data; - bool m_configurationFinalized; AZStd::atomic m_profilingRefcount; 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/Memory/AllocatorOverrideShim.cpp b/Code/Framework/AzCore/AzCore/Memory/AllocatorOverrideShim.cpp deleted file mode 100644 index e4928e83c5..0000000000 --- a/Code/Framework/AzCore/AzCore/Memory/AllocatorOverrideShim.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include - -namespace AZ::Internal -{ - AllocatorOverrideShim* AllocatorOverrideShim::Create(IAllocator* owningAllocator, IAllocatorAllocate* shimAllocationSource) - { - void* memory = shimAllocationSource->Allocate(sizeof(AllocatorOverrideShim), AZStd::alignment_of::value, 0); - auto result = new (memory) AllocatorOverrideShim(owningAllocator, shimAllocationSource); - return result; - } - - void AllocatorOverrideShim::Destroy(AllocatorOverrideShim* source) - { - auto shimAllocationSource = source->m_shimAllocationSource; - source->~AllocatorOverrideShim(); - shimAllocationSource->DeAllocate(source); - } - - AllocatorOverrideShim::AllocatorOverrideShim(IAllocator* owningAllocator, IAllocatorAllocate* shimAllocationSource) - : m_owningAllocator(owningAllocator) - , m_source(owningAllocator->GetOriginalAllocationSource()) - , m_overridingSource(owningAllocator->GetOriginalAllocationSource()) - , m_shimAllocationSource(shimAllocationSource) - , m_records(typename AllocationSet::hasher(), typename AllocationSet::key_eq(), StdAllocationSrc(shimAllocationSource)) - { - } - - void AllocatorOverrideShim::SetOverride(IAllocatorAllocate* source) - { - m_overridingSource = source; - } - - IAllocatorAllocate* AllocatorOverrideShim::GetOverride() const - { - return m_overridingSource; - } - - bool AllocatorOverrideShim::IsOverridden() const - { - return m_source != m_overridingSource; - } - - bool AllocatorOverrideShim::HasOrphanedAllocations() const - { - return !m_records.empty(); - } - - void AllocatorOverrideShim::SetFinalizedConfiguration() - { - m_finalizedConfiguration = true; - } - - typename AllocatorOverrideShim::pointer_type AllocatorOverrideShim::Allocate(size_type byteSize, size_type alignment, int flags, const char* name, const char* fileName, int lineNum, unsigned int suppressStackRecord) - { - pointer_type ptr = m_overridingSource->Allocate(byteSize, alignment, flags, name, fileName, lineNum, suppressStackRecord); - - if (!IsOverridden()) - { - lock_type lock(m_mutex); - m_records.insert(ptr); // Record in case we need to orphan this allocation later - } - - return ptr; - } - - void AllocatorOverrideShim::DeAllocate(pointer_type ptr, size_type byteSize, size_type alignment) - { - IAllocatorAllocate* source = m_overridingSource; - bool destroy = false; - - { - lock_type lock(m_mutex); - - // Check to see if this came from a prior allocation source - if (m_records.erase(ptr) && IsOverridden()) - { - source = m_source; - - if (m_records.empty() && m_finalizedConfiguration) - { - // All orphaned records are gone; we are no longer needed - m_owningAllocator->SetAllocationSource(m_overridingSource); - destroy = true; // Must destroy outside the lock - } - } - } - - source->DeAllocate(ptr, byteSize, alignment); - - if (destroy) - { - Destroy(this); - } - } - - typename AllocatorOverrideShim::size_type AllocatorOverrideShim::Resize(pointer_type ptr, size_type newSize) - { - IAllocatorAllocate* source = m_overridingSource; - - if (IsOverridden()) - { - // Determine who owns the allocation - lock_type lock(m_mutex); - - if (m_records.count(ptr)) - { - source = m_source; - } - } - - size_t result = source->Resize(ptr, newSize); - - return result; - } - - typename AllocatorOverrideShim::pointer_type AllocatorOverrideShim::ReAllocate(pointer_type ptr, size_type newSize, size_type newAlignment) - { - pointer_type newPtr = nullptr; - bool useOverride = true; - bool destroy = false; - - if (IsOverridden()) - { - lock_type lock(m_mutex); - - if (m_records.erase(ptr)) - { - // An old allocation needs to be transferred to the new, overriding allocator. - useOverride = false; // We'll do the reallocation here - size_t oldSize = m_source->AllocationSize(ptr); - - if (newSize) - { - newPtr = m_overridingSource->Allocate(newSize, newAlignment, 0); - memcpy(newPtr, ptr, AZStd::min(newSize, oldSize)); - } - - m_source->DeAllocate(ptr, oldSize); - - if (m_records.empty() && m_finalizedConfiguration) - { - // All orphaned records are gone; we are no longer needed - m_owningAllocator->SetAllocationSource(m_overridingSource); - destroy = true; // Must destroy outside the lock - } - } - } - - if (useOverride) - { - // Default behavior, we weren't deleting an old allocation - newPtr = m_overridingSource->ReAllocate(ptr, newSize, newAlignment); - - if (!IsOverridden()) - { - // Still need to do bookkeeping if we haven't been overridden yet - lock_type lock(m_mutex); - m_records.erase(ptr); - m_records.insert(newPtr); - } - } - - if (destroy) - { - Destroy(this); - } - - return newPtr; - } - - typename AllocatorOverrideShim::size_type AllocatorOverrideShim::AllocationSize(pointer_type ptr) - { - IAllocatorAllocate* source = m_overridingSource; - - if (IsOverridden()) - { - // Determine who owns the allocation - lock_type lock(m_mutex); - - if (m_records.count(ptr)) - { - source = m_source; - } - } - - return source->AllocationSize(ptr); - } - - void AllocatorOverrideShim::GarbageCollect() - { - m_source->GarbageCollect(); - } - - typename AllocatorOverrideShim::size_type AllocatorOverrideShim::NumAllocatedBytes() const - { - return m_source->NumAllocatedBytes(); - } - - typename AllocatorOverrideShim::size_type AllocatorOverrideShim::Capacity() const - { - return m_source->Capacity(); - } - - typename AllocatorOverrideShim::size_type AllocatorOverrideShim::GetMaxAllocationSize() const - { - return m_source->GetMaxAllocationSize(); - } - - auto AllocatorOverrideShim::GetMaxContiguousAllocationSize() const -> size_type - { - return m_source->GetMaxContiguousAllocationSize(); - } - - IAllocatorAllocate* AllocatorOverrideShim::GetSubAllocator() - { - return m_source->GetSubAllocator(); - } - -} // namespace AZ::Internal diff --git a/Code/Framework/AzCore/AzCore/Memory/AllocatorOverrideShim.h b/Code/Framework/AzCore/AzCore/Memory/AllocatorOverrideShim.h deleted file mode 100644 index 3b45b9953e..0000000000 --- a/Code/Framework/AzCore/AzCore/Memory/AllocatorOverrideShim.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ -#pragma once - -#include -#include -#include - -namespace AZ -{ - class AllocatorManager; - - namespace Internal - { - /** - * A shim schema that solves the problem of overriding lazily-created allocators especially, that perform allocations before the override happens. - * - * Any allocator that *might* be overridden at some point must have this shim installed as its allocation source. This is done automatically by - * the AllocationManager; you generally do not have to interact with this shim directly at all. - * - * The shim will keep track of any allocations that occur, and if the allocator gets overridden it will ensure that prior allocations are - * deallocated with the old schema rather than the new one. - * - * There is some performance cost to this intrusion, however, in most cases it's only temporary: - * * Once the application calls FinalizeConfiguration(), any non-overridden allocators will have their shims destroyed. - * * Any overridden allocators that do not have prior allocations will have their shims destroyed. - * * Any overridden allocator will automatically destroy its shim once the last of the prior allocations has been deallocated. - * - * Note that an allocator that gets overridden but has prior allocations that it never intends to deallocate (such as file-level statics that never - * get changed) will keep its shim indefinitely. This is an unfortunate cost but only affects those allocators if they are being overridden. - */ - class AllocatorOverrideShim - : public IAllocatorAllocate - { - friend AllocatorManager; - - public: - //--------------------------------------------------------------------- - // IAllocator implementation - //--------------------------------------------------------------------- - pointer_type Allocate(size_type byteSize, size_type alignment, int flags = 0, const char* name = nullptr, const char* fileName = nullptr, int lineNum = 0, unsigned int suppressStackRecord = 0) override; - void DeAllocate(pointer_type ptr, size_type byteSize = 0, size_type alignment = 0) override; - size_type Resize(pointer_type ptr, size_type newSize) override; - pointer_type ReAllocate(pointer_type ptr, size_type newSize, size_type newAlignment) override; - size_type AllocationSize(pointer_type ptr) override; - void GarbageCollect() override; - size_type NumAllocatedBytes() const override; - size_type Capacity() const override; - size_type GetMaxAllocationSize() const override; - size_type GetMaxContiguousAllocationSize() const override; - IAllocatorAllocate* GetSubAllocator() override; - - private: - /// Creates a shim using a custom memory source - static AllocatorOverrideShim* Create(IAllocator* owningAllocator, IAllocatorAllocate* shimAllocationSource); - static void Destroy(AllocatorOverrideShim* source); - - AllocatorOverrideShim(IAllocator* owningAllocator, IAllocatorAllocate* shimAllocationSource); - - /// Overrides the shim's memory source with a different memory source. - void SetOverride(IAllocatorAllocate* source); - - /// Returns the override source. - IAllocatorAllocate* GetOverride() const; - - /// Returns true if the shim has an override source set on it. - bool IsOverridden() const; - - /// Returns true if there are orphaned allocations from before the shim had its override set. - bool HasOrphanedAllocations() const; - - /// Called by the AllocatorManager to signify that the configuration has been finalized by the application. - void SetFinalizedConfiguration(); - - private: - class StdAllocationSrc : public AZStdIAllocator - { - public: - StdAllocationSrc(IAllocatorAllocate* schema = nullptr) : AZStdIAllocator(schema) - { - } - }; - - typedef AZStd::mutex mutex_type; - typedef AZStd::lock_guard lock_type; - typedef AZStd::unordered_set, AZStd::equal_to, StdAllocationSrc> AllocationSet; - - IAllocator* m_owningAllocator; - IAllocatorAllocate* m_source; - IAllocatorAllocate* m_overridingSource; - IAllocatorAllocate* m_shimAllocationSource; - AllocationSet m_records; - mutex_type m_mutex; - bool m_finalizedConfiguration = false; - }; - } -} diff --git a/Code/Framework/AzCore/AzCore/Memory/BestFitExternalMapAllocator.cpp b/Code/Framework/AzCore/AzCore/Memory/BestFitExternalMapAllocator.cpp index d55ca8b695..eb938fc99a 100644 --- a/Code/Framework/AzCore/AzCore/Memory/BestFitExternalMapAllocator.cpp +++ b/Code/Framework/AzCore/AzCore/Memory/BestFitExternalMapAllocator.cpp @@ -20,8 +20,7 @@ namespace AZ // [1/28/2011] //========================================================================= BestFitExternalMapAllocator::BestFitExternalMapAllocator() - : AllocatorBase(this, "BestFitExternalMapAllocator", "Best fit allocator with external tracking storage!") - , m_schema(nullptr) + : AllocatorBase(nullptr, "BestFitExternalMapAllocator", "Best fit allocator with external tracking storage!") { } @@ -182,13 +181,4 @@ namespace AZ return m_schema->GetMaxContiguousAllocationSize(); } - //========================================================================= - // GetSubAllocator - // [1/28/2011] - //========================================================================= - IAllocatorAllocate* BestFitExternalMapAllocator::GetSubAllocator() - { - return m_schema->GetSubAllocator(); - } - } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Memory/BestFitExternalMapAllocator.h b/Code/Framework/AzCore/AzCore/Memory/BestFitExternalMapAllocator.h index 90e2056d65..952dd9d99e 100644 --- a/Code/Framework/AzCore/AzCore/Memory/BestFitExternalMapAllocator.h +++ b/Code/Framework/AzCore/AzCore/Memory/BestFitExternalMapAllocator.h @@ -19,7 +19,6 @@ namespace AZ */ class BestFitExternalMapAllocator : public AllocatorBase - , public IAllocatorAllocate { public: AZ_TYPE_INFO(BestFitExternalMapAllocator, "{36266C8B-9A2C-4E3E-9812-3DB260868A2B}") @@ -37,7 +36,7 @@ namespace AZ static const int m_memoryBlockAlignment = 16; void* m_memoryBlock; ///< Pointer to memory to allocate from. Can be uncached. unsigned int m_memoryBlockByteSize; ///< Sizes if the memory block. - IAllocatorAllocate* m_mapAllocator; ///< Allocator for the free chunks map. If null the SystemAllocator will be used. + IAllocator* m_mapAllocator; ///< Allocator for the free chunks map. If null the SystemAllocator will be used. bool m_allocationRecords; ///< True if we want to track memory allocations, otherwise false. unsigned char m_stackRecordLevels; ///< If stack recording is enabled, how many stack levels to record. @@ -52,7 +51,7 @@ namespace AZ AllocatorDebugConfig GetDebugConfig() override; ////////////////////////////////////////////////////////////////////////// - // IAllocatorAllocate + // IAllocatorSchema pointer_type Allocate(size_type byteSize, size_type alignment, int flags = 0, const char* name = 0, const char* fileName = 0, int lineNum = 0, unsigned int suppressStackRecord = 0) override; void DeAllocate(pointer_type ptr, size_type byteSize = 0, size_type alignment = 0) override; size_type Resize(pointer_type ptr, size_type newSize) override; @@ -63,7 +62,6 @@ namespace AZ size_type Capacity() const override; size_type GetMaxAllocationSize() const override; size_type GetMaxContiguousAllocationSize() const override; - IAllocatorAllocate* GetSubAllocator() override; ////////////////////////////////////////////////////////////////////////// protected: @@ -71,7 +69,6 @@ namespace AZ BestFitExternalMapAllocator& operator=(const BestFitExternalMapAllocator&); Descriptor m_desc; - BestFitExternalMapSchema* m_schema; }; } diff --git a/Code/Framework/AzCore/AzCore/Memory/BestFitExternalMapSchema.cpp b/Code/Framework/AzCore/AzCore/Memory/BestFitExternalMapSchema.cpp index 841f36f58a..5029e6349f 100644 --- a/Code/Framework/AzCore/AzCore/Memory/BestFitExternalMapSchema.cpp +++ b/Code/Framework/AzCore/AzCore/Memory/BestFitExternalMapSchema.cpp @@ -42,9 +42,15 @@ namespace AZ // Allocate // [1/28/2011] //========================================================================= - BestFitExternalMapSchema::pointer_type BestFitExternalMapSchema::Allocate(size_type byteSize, size_type alignment, int flags) + BestFitExternalMapSchema::pointer_type BestFitExternalMapSchema::Allocate( + size_type byteSize, + size_type alignment, + [[maybe_unused]] int flags, + [[maybe_unused]] const char* name, + [[maybe_unused]] const char* fileName, + [[maybe_unused]] int lineNum, + [[maybe_unused]] unsigned int suppressStackRecord) { - (void)flags; char* address = nullptr; AZ_Assert(alignment > 0 && (alignment & (alignment - 1)) == 0, "Alignment must be >0 and power of 2!"); for (int i = 0; i < 2; ++i) // max 2 attempts to allocate @@ -96,7 +102,7 @@ namespace AZ // DeAllocate // [1/28/2011] //========================================================================= - void BestFitExternalMapSchema::DeAllocate(pointer_type ptr) + void BestFitExternalMapSchema::DeAllocate(pointer_type ptr, [[maybe_unused]] size_type byteSize, [[maybe_unused]] size_type alignment) { if (ptr == nullptr) { @@ -125,6 +131,18 @@ namespace AZ return 0; } + BestFitExternalMapSchema::size_type BestFitExternalMapSchema::Resize(pointer_type, size_type) + { + AZ_Assert(false, "%s unsupported", AZ_FUNCTION_SIGNATURE); + return 0; + } + + BestFitExternalMapSchema::pointer_type BestFitExternalMapSchema::ReAllocate(pointer_type, size_type, size_type) + { + AZ_Assert(false, "%s unsupported", AZ_FUNCTION_SIGNATURE); + return nullptr; + } + //========================================================================= // GetMaxAllocationSize // [1/28/2011] diff --git a/Code/Framework/AzCore/AzCore/Memory/BestFitExternalMapSchema.h b/Code/Framework/AzCore/AzCore/Memory/BestFitExternalMapSchema.h index 0055a86ee2..0a157b716c 100644 --- a/Code/Framework/AzCore/AzCore/Memory/BestFitExternalMapSchema.h +++ b/Code/Framework/AzCore/AzCore/Memory/BestFitExternalMapSchema.h @@ -20,7 +20,7 @@ namespace AZ * External map allows us to use this allocator with uncached memory, * because the tracking node is stored outside the main chunk. */ - class BestFitExternalMapSchema + class BestFitExternalMapSchema : public IAllocatorSchema { public: typedef void* pointer_type; @@ -44,26 +44,27 @@ namespace AZ static const int m_memoryBlockAlignment = 16; void* m_memoryBlock; ///< Pointer to memory to allocate from. Can be uncached. unsigned int m_memoryBlockByteSize; ///< Sizes if the memory block. - IAllocatorAllocate* m_mapAllocator; ///< Allocator for the free chunks map. If null the SystemAllocator will be used. + IAllocator* m_mapAllocator; ///< Allocator for the free chunks map. If null the SystemAllocator will be used. }; BestFitExternalMapSchema(const Descriptor& desc); - pointer_type Allocate(size_type byteSize, size_type alignment, int flags); - void DeAllocate(pointer_type ptr); - size_type AllocationSize(pointer_type ptr); + pointer_type Allocate(size_type byteSize, size_type alignment, int flags = 0, const char* name = nullptr, const char* fileName = nullptr, int lineNum = 0, unsigned int suppressStackRecord = 0) override; + void DeAllocate(pointer_type ptr, size_type byteSize = 0, size_type alignment = 0) override; + size_type Resize(pointer_type ptr, size_type newSize) override; + pointer_type ReAllocate(pointer_type ptr, size_type newSize, size_type newAlignment) override; + size_type AllocationSize(pointer_type ptr) override; - AZ_FORCE_INLINE size_type NumAllocatedBytes() const { return m_used; } - AZ_FORCE_INLINE size_type Capacity() const { return m_desc.m_memoryBlockByteSize; } - size_type GetMaxAllocationSize() const; - size_type GetMaxContiguousAllocationSize() const; - AZ_FORCE_INLINE IAllocatorAllocate* GetSubAllocator() const { return m_desc.m_mapAllocator; } + AZ_FORCE_INLINE size_type NumAllocatedBytes() const override { return m_used; } + AZ_FORCE_INLINE size_type Capacity() const override { return m_desc.m_memoryBlockByteSize; } + size_type GetMaxAllocationSize() const override; + size_type GetMaxContiguousAllocationSize() const override; /** - * Since we don't consolidate chucnks at free time (too expensive) we will do it as we need or when we can't + * Since we don't consolidate chunks at free time (too expensive) we will do it as we need or when we can't * allocate memory. This function is at least O(nlogn) where 'n' are the free chunks. */ - void GarbageCollect(); + void GarbageCollect() override; private: AZ_FORCE_INLINE size_type ChunckSize(pointer_type ptr); diff --git a/Code/Framework/AzCore/AzCore/Memory/HeapSchema.cpp b/Code/Framework/AzCore/AzCore/Memory/HeapSchema.cpp index 1f0fc59a97..98ca1f87ed 100644 --- a/Code/Framework/AzCore/AzCore/Memory/HeapSchema.cpp +++ b/Code/Framework/AzCore/AzCore/Memory/HeapSchema.cpp @@ -107,7 +107,6 @@ namespace AZ m_used = 0; m_desc = desc; - m_subAllocator = nullptr; for (int i = 0; i < Descriptor::m_maxNumBlocks; ++i) { diff --git a/Code/Framework/AzCore/AzCore/Memory/HeapSchema.h b/Code/Framework/AzCore/AzCore/Memory/HeapSchema.h index 3a7716a127..ea4a4ebdc6 100644 --- a/Code/Framework/AzCore/AzCore/Memory/HeapSchema.h +++ b/Code/Framework/AzCore/AzCore/Memory/HeapSchema.h @@ -17,7 +17,7 @@ namespace AZ * Internally uses use dlmalloc or version of it (nedmalloc, ptmalloc3). */ class HeapSchema - : public IAllocatorAllocate + : public IAllocatorSchema { public: typedef void* pointer_type; @@ -52,7 +52,6 @@ namespace AZ size_type Capacity() const override { return m_capacity; } size_type GetMaxAllocationSize() const override; size_type GetMaxContiguousAllocationSize() const override; - IAllocatorAllocate* GetSubAllocator() override { return m_subAllocator; } void GarbageCollect() override {} private: @@ -62,7 +61,7 @@ namespace AZ Descriptor m_desc; size_type m_capacity; ///< Capacity in bytes. size_type m_used; ///< Number of bytes in use. - IAllocatorAllocate* m_subAllocator; + IAllocatorSchema* m_subAllocator; bool m_ownMemoryBlock[Descriptor::m_maxNumBlocks]; }; } diff --git a/Code/Framework/AzCore/AzCore/Memory/HphaSchema.cpp b/Code/Framework/AzCore/AzCore/Memory/HphaSchema.cpp index 6e40ccd8cd..6891eb4248 100644 --- a/Code/Framework/AzCore/AzCore/Memory/HphaSchema.cpp +++ b/Code/Framework/AzCore/AzCore/Memory/HphaSchema.cpp @@ -1081,7 +1081,7 @@ namespace AZ { const size_t m_treePageAlignment; const size_t m_poolPageSize; bool m_isPoolAllocations; - IAllocatorAllocate* m_subAllocator; + IAllocatorSchema* m_subAllocator; #if !defined (USE_MUTEX_PER_BUCKET) mutable AZStd::mutex m_mutex; diff --git a/Code/Framework/AzCore/AzCore/Memory/HphaSchema.h b/Code/Framework/AzCore/AzCore/Memory/HphaSchema.h index 5ee0205196..27dbd321d2 100644 --- a/Code/Framework/AzCore/AzCore/Memory/HphaSchema.h +++ b/Code/Framework/AzCore/AzCore/Memory/HphaSchema.h @@ -19,7 +19,7 @@ namespace AZ * Heap allocator schema, based on Dimitar Lazarov "High Performance Heap Allocator". */ class HphaSchema - : public IAllocatorAllocate + : public IAllocatorSchema { public: /** @@ -47,7 +47,7 @@ namespace AZ unsigned int m_isPoolAllocations : 1; ///< True to allow allocations from pools, otherwise false. size_t m_fixedMemoryBlockByteSize; ///< Memory block size, if 0 we use the OS memory allocation functions. void* m_fixedMemoryBlock; ///< Can be NULL if so the we will allocate memory from the subAllocator if m_memoryBlocksByteSize is != 0. - IAllocatorAllocate* m_subAllocator; ///< Allocator that m_memoryBlocks memory was allocated from or should be allocated (if NULL). + IAllocatorSchema* m_subAllocator; ///< Allocator that m_memoryBlocks memory was allocated from or should be allocated (if NULL). size_t m_systemChunkSize; ///< Size of chunk to request from the OS when more memory is needed (defaults to m_pageSize) size_t m_capacity; ///< Max size this allocator can grow to }; @@ -68,7 +68,6 @@ namespace AZ size_type GetMaxAllocationSize() const override; size_type GetMaxContiguousAllocationSize() const override; size_type GetUnAllocatedMemory(bool isPrint = false) const override; - IAllocatorAllocate* GetSubAllocator() override { return m_desc.m_subAllocator; } /// Return unused memory to the OS (if we don't use fixed block). Don't call this unless you really need free memory, it is slow. void GarbageCollect() override; diff --git a/Code/Framework/AzCore/AzCore/Memory/IAllocator.cpp b/Code/Framework/AzCore/AzCore/Memory/IAllocator.cpp index 08c567bf84..2d561b45ef 100644 --- a/Code/Framework/AzCore/AzCore/Memory/IAllocator.cpp +++ b/Code/Framework/AzCore/AzCore/Memory/IAllocator.cpp @@ -9,23 +9,12 @@ namespace AZ { - IAllocator::IAllocator(IAllocatorAllocate* allocationSource) - : m_allocationSource(allocationSource) - , m_originalAllocationSource(allocationSource) + IAllocator::IAllocator(IAllocatorSchema* schema) + : m_schema(schema) { } IAllocator::~IAllocator() { } - - void IAllocator::SetAllocationSource(IAllocatorAllocate* allocationSource) - { - m_allocationSource = allocationSource; - } - - void IAllocator::ResetAllocationSource() - { - m_allocationSource = m_originalAllocationSource; - } } diff --git a/Code/Framework/AzCore/AzCore/Memory/IAllocator.h b/Code/Framework/AzCore/AzCore/Memory/IAllocator.h index 532335e50b..4612b27249 100644 --- a/Code/Framework/AzCore/AzCore/Memory/IAllocator.h +++ b/Code/Framework/AzCore/AzCore/Memory/IAllocator.h @@ -28,19 +28,18 @@ namespace AZ class AllocatorManager; /** - * Allocator alloc/free basic interface. It is separate because it can be used - * for user provided allocators overrides + * Allocator schema interface */ - class IAllocatorAllocate + class IAllocatorSchema { public: typedef void* pointer_type; typedef size_t size_type; typedef ptrdiff_t difference_type; - virtual ~IAllocatorAllocate() {} + virtual ~IAllocatorSchema() = default; - virtual pointer_type Allocate(size_type byteSize, size_type alignment, int flags = 0, const char* name = 0, const char* fileName = 0, int lineNum = 0, unsigned int suppressStackRecord = 0) = 0; + virtual pointer_type Allocate(size_type byteSize, size_type alignment, int flags = 0, const char* name = nullptr, const char* fileName = nullptr, int lineNum = 0, unsigned int suppressStackRecord = 0) = 0; virtual void DeAllocate(pointer_type ptr, size_type byteSize = 0, size_type alignment = 0) = 0; /// Resize an allocated memory block. Returns the new adjusted size (as close as possible or equal to the requested one) or 0 (if you don't support resize at all). virtual size_type Resize(pointer_type ptr, size_type newSize) = 0; @@ -70,8 +69,6 @@ namespace AZ * that will be reported. */ virtual size_type GetUnAllocatedMemory(bool isPrint = false) const { (void)isPrint; return 0; } - /// Returns a pointer to a sub-allocator or NULL. - virtual IAllocatorAllocate* GetSubAllocator() = 0; }; /** @@ -100,56 +97,19 @@ namespace AZ /** * Interface class for all allocators. */ - class IAllocator + class IAllocator : public IAllocatorSchema { public: - IAllocator(IAllocatorAllocate* allocationSource); + IAllocator(IAllocatorSchema* schema = nullptr); virtual ~IAllocator(); - // @{ Every system allocator is required to provide name this is how + // Every system allocator is required to provide name this is how // it will be registered with the allocator manager. virtual const char* GetName() const = 0; virtual const char* GetDescription() const = 0; - // @} - //--------------------------------------------------------------------- - // Code releating to the allocation source is made concrete within this - // interface as a performance optimization. - //--------------------------------------------------------------------- - - /// Returns the current allocation source, which may be used to perform memory allocations. - AZ_FORCE_INLINE IAllocatorAllocate* GetAllocationSource() const - { - return m_allocationSource; - } - - /// Returns the original allocation source. Generally only used for debugging purposes. - AZ_FORCE_INLINE IAllocatorAllocate* GetOriginalAllocationSource() const - { - return m_originalAllocationSource; - } - - /// Returns true if the allocation source has changed from its original value. - AZ_FORCE_INLINE bool IsAllocationSourceChanged() const - { - return m_allocationSource != m_originalAllocationSource; - } - - /// Sets the allocation source, effectively overriding the allocator. - /// Be very careful doing this, as existing allocations will be deallocated through the new source, - /// typically leading to unwanted effects (such as crashes). - void SetAllocationSource(IAllocatorAllocate* allocationSource); - - /// Restores the allocation source to its original value. - /// Be very careful doing this, as allocations that came from the new source will now be deallocated - /// through the original source, typically leading to unwanted effects (such as crashes). - void ResetAllocationSource(); - - //--------------------------------------------------------------------- - - /// Returns the schema, if the allocator uses one. Returns nullptr if the allocator does not use a schema. - /// This is mainly used when debugging to determine if allocators alias each other under the hood. - virtual IAllocatorAllocate* GetSchema() = 0; + /// Returns the schema + AZ_FORCE_INLINE IAllocatorSchema* GetSchema() const { return m_schema; }; /// Returns the debug configuration for this allocator. virtual AllocatorDebugConfig GetDebugConfig() = 0; @@ -163,11 +123,6 @@ namespace AZ /// Returns true if this allocator is ready to use. virtual bool IsReady() const = 0; - /// Returns true if this allocator can be overridden with a different source. - /// Almost all allocators should return true. There are very few minor exceptions, such as the OS Allocator, that are required for direct - /// interfacing with the kernel and must never be overridden under any circumstances. - virtual bool CanBeOverridden() const = 0; - /// Returns true if the allocator was lazily created. Exposed primarily for testing systems that need to verify the state of allocators. virtual bool IsLazilyCreated() const = 0; @@ -195,9 +150,7 @@ namespace AZ virtual void Destroy() = 0; protected: - // The allocation source is made a direct member of the interface as a performance optimization. - IAllocatorAllocate * m_allocationSource; - IAllocatorAllocate* m_originalAllocationSource; + IAllocatorSchema* m_schema; template friend class AllocatorStorage::StoragePolicyBase; diff --git a/Code/Framework/AzCore/AzCore/Memory/MallocSchema.cpp b/Code/Framework/AzCore/AzCore/Memory/MallocSchema.cpp index 9aa31cd8b6..37fa277fab 100644 --- a/Code/Framework/AzCore/AzCore/Memory/MallocSchema.cpp +++ b/Code/Framework/AzCore/AzCore/Memory/MallocSchema.cpp @@ -22,31 +22,15 @@ namespace AZ::Internal namespace AZ { + static constexpr size_t DEFAULT_ALIGNMENT = sizeof(void*) * 2; // Default malloc alignment + //--------------------------------------------------------------------- // MallocSchema methods //--------------------------------------------------------------------- - MallocSchema::MallocSchema(const Descriptor& desc) + MallocSchema::MallocSchema(const Descriptor&) : m_bytesAllocated(0) { - if (desc.m_useAZMalloc) - { - static const int DEFAULT_ALIGNMENT = sizeof(void*) * 2; // Default malloc alignment - - m_mallocFn = [](size_t byteSize) - { - return AZ_OS_MALLOC(byteSize, DEFAULT_ALIGNMENT); - }; - m_freeFn = [](void* ptr) - { - AZ_OS_FREE(ptr); - }; - } - else - { - m_mallocFn = &malloc; - m_freeFn = &free; - } } MallocSchema::~MallocSchema() @@ -84,7 +68,7 @@ namespace AZ ((alignment > sizeof(double)) ? alignment : 0); // Malloc will align to a minimum boundary for native objects, so we only pad if aligning to a large value - void* data = (*m_mallocFn)(required); + void* data = AZ_OS_MALLOC(required, DEFAULT_ALIGNMENT); void* result = PointerAlignUp(reinterpret_cast(reinterpret_cast(data) + sizeof(Internal::Header)), alignment); Internal::Header* header = PointerAlignDown( (Internal::Header*)(reinterpret_cast(result) - sizeof(Internal::Header)), AZStd::alignment_of::value); @@ -112,7 +96,7 @@ namespace AZ void* freePtr = reinterpret_cast(reinterpret_cast(ptr) - static_cast(header->offset)); m_bytesAllocated -= header->size; - (*m_freeFn)(freePtr); + AZ_OS_FREE(freePtr); } MallocSchema::pointer_type MallocSchema::ReAllocate(pointer_type ptr, size_type newSize, size_type newAlignment) @@ -166,11 +150,6 @@ namespace AZ return AZ_CORE_MAX_ALLOCATOR_SIZE; } - IAllocatorAllocate* MallocSchema::GetSubAllocator() - { - return nullptr; - } - void MallocSchema::GarbageCollect() { } diff --git a/Code/Framework/AzCore/AzCore/Memory/MallocSchema.h b/Code/Framework/AzCore/AzCore/Memory/MallocSchema.h index 7a8c4a0366..02559fdb57 100644 --- a/Code/Framework/AzCore/AzCore/Memory/MallocSchema.h +++ b/Code/Framework/AzCore/AzCore/Memory/MallocSchema.h @@ -16,7 +16,7 @@ namespace AZ * Uses malloc internally. Mainly intended for debugging using host operating system features. */ class MallocSchema - : public IAllocatorAllocate + : public IAllocatorSchema { public: AZ_TYPE_INFO("MallocSchema", "{2A21D120-A42A-484C-997C-5735DCCA5FE9}"); @@ -25,21 +25,13 @@ namespace AZ typedef size_t size_type; typedef ptrdiff_t difference_type; - struct Descriptor - { - Descriptor(bool useAZMalloc = true) - : m_useAZMalloc(useAZMalloc) - { - } - - bool m_useAZMalloc; - }; + struct Descriptor {}; MallocSchema(const Descriptor& desc = Descriptor()); virtual ~MallocSchema(); //--------------------------------------------------------------------- - // IAllocatorAllocate + // IAllocatorSchema //--------------------------------------------------------------------- pointer_type Allocate(size_type byteSize, size_type alignment, int flags, const char* name = 0, const char* fileName = 0, int lineNum = 0, unsigned int suppressStackRecord = 0) override; void DeAllocate(pointer_type ptr, size_type byteSize = 0, size_type alignment = 0) override; @@ -51,15 +43,9 @@ namespace AZ size_type Capacity() const override; size_type GetMaxAllocationSize() const override; size_type GetMaxContiguousAllocationSize() const override; - IAllocatorAllocate* GetSubAllocator() override; void GarbageCollect() override; private: - typedef void* (*MallocFn)(size_t); - typedef void (*FreeFn)(void*); - AZStd::atomic m_bytesAllocated; - MallocFn m_mallocFn; - FreeFn m_freeFn; }; } diff --git a/Code/Framework/AzCore/AzCore/Memory/Memory.cpp b/Code/Framework/AzCore/AzCore/Memory/Memory.cpp index 6ec66f9e3d..6393e3138f 100644 --- a/Code/Framework/AzCore/AzCore/Memory/Memory.cpp +++ b/Code/Framework/AzCore/AzCore/Memory/Memory.cpp @@ -7,22 +7,8 @@ */ #include -#include #include -#include -#include - -AZ::AllocatorStorage::LazyAllocatorRef::~LazyAllocatorRef() -{ - m_destructor(*m_allocator); -} - -void AZ::AllocatorStorage::LazyAllocatorRef::Init(size_t size, size_t alignment, CreationFn creationFn, DestructionFn destructionFn) -{ - m_allocator = AZ::AllocatorManager::CreateLazyAllocator(size, alignment, creationFn); - m_destructor = destructionFn; -} ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // New overloads diff --git a/Code/Framework/AzCore/AzCore/Memory/Memory.h b/Code/Framework/AzCore/AzCore/Memory/Memory.h index 2e08ec1b15..f1f49924a1 100644 --- a/Code/Framework/AzCore/AzCore/Memory/Memory.h +++ b/Code/Framework/AzCore/AzCore/Memory/Memory.h @@ -141,9 +141,9 @@ void* operator new[](std::size_t, const AZ::Internal::AllocatorDummy*); */ #define azfree(...) AZ_MACRO_SPECIALIZE(azfree_, AZ_VA_NUM_ARGS(__VA_ARGS__), (__VA_ARGS__)) -/// Returns allocation size, based on it's pointer \ref AZ::IAllocatorAllocate::AllocationSize. +/// Returns allocation size, based on it's pointer \ref AZ::IAllocatorSchema::AllocationSize. #define azallocsize(_Ptr, _Allocator) AZ::AllocatorInstance< _Allocator >::Get().AllocationSize(_Ptr) -/// Returns the new expanded size or 0 if NOT supported by the allocator \ref AZ::IAllocatorAllocate::Resize. +/// Returns the new expanded size or 0 if NOT supported by the allocator \ref AZ::IAllocatorSchema::Resize. #define azallocresize(_Ptr, _NewSize, _Allocator) AZ::AllocatorInstance< _Allocator >::Get().Resize(_Ptr, _NewSize) namespace AZ { @@ -521,19 +521,6 @@ namespace AZ { namespace AllocatorStorage { - /// A private structure to create heap-storage for an allocator that won't expire until other static module members are destructed. - struct LazyAllocatorRef - { - using CreationFn = IAllocator*(*)(void*); - using DestructionFn = void(*)(IAllocator&); - - ~LazyAllocatorRef(); - void Init(size_t size, size_t alignment, CreationFn creationFn, DestructionFn destructionFn); - - IAllocator* m_allocator = nullptr; - DestructionFn m_destructor = nullptr; - }; - /** * A base class for all storage policies. This exists to provide access to private IAllocator methods via template friends. */ @@ -640,87 +627,6 @@ namespace AZ template EnvironmentVariable EnvironmentStoragePolicy::s_allocator; - - /** - * ModuleStoragePolicy stores the allocator in a static variable that is local to the module using it. - * This forces separate instances of the allocator to exist in each module, and permits lazy instantiation. - * We only tolerate this for some special allocators, primarily to maintain backwards compatibility with CryEngine, - * since it still allocates outside of code in the data section. - * - * It has two ways of storing its allocator: either on the heap, which is the preferred way, since it guarantees - * the memory for the allocator won't be deallocated (such as in a DLL) before anyone that's using it. If disabled - * the allocator is stored in a static variable, which should only be used where this isn't a problem a shut-down - * time, such as on a console. - */ - template - struct ModuleStoragePolicyBase; - - template - struct ModuleStoragePolicyBase: public StoragePolicyBase - { - protected: - // Use a static instance to store the allocator. This is not recommended when the order of shut-down with the module matters, as the allocator could have its memory destroyed - // before the users of it are destroyed. The primary use case for this is allocators that need to support the CRT, as they cannot allocate from the heap. - static Allocator& GetModuleAllocatorInstance() - { - static Allocator* s_allocator = nullptr; - static typename AZStd::aligned_storage::value>::type s_storage; - - if (!s_allocator) - { - s_allocator = new (&s_storage) Allocator; - StoragePolicyBase::Create(*s_allocator, typename Allocator::Descriptor(), true); - } - - return *s_allocator; - } - }; - - template - struct ModuleStoragePolicyBase : public StoragePolicyBase - { - protected: - // Store-on-heap implementation uses the LazyAllocatorRef to create and destroy an allocator using heap-space so there isn't a problem with destruction order within the module. - static Allocator& GetModuleAllocatorInstance() - { - static LazyAllocatorRef s_allocator; - - if (!s_allocator.m_allocator) - { - s_allocator.Init(sizeof(Allocator), AZStd::alignment_of::value, [](void* mem) -> IAllocator* { return new (mem) Allocator; }, &StoragePolicyBase::Destroy); - StoragePolicyBase::Create(*static_cast(s_allocator.m_allocator), typename Allocator::Descriptor(), true); - } - - return *static_cast(s_allocator.m_allocator); - } - }; - - template - class ModuleStoragePolicy : public ModuleStoragePolicyBase - { - public: - using Base = ModuleStoragePolicyBase; - - static IAllocator& GetAllocator() - { - return Base::GetModuleAllocatorInstance(); - } - - static void Create(const typename Allocator::Descriptor& desc = typename Allocator::Descriptor()) - { - StoragePolicyBase::Create(Base::GetModuleAllocatorInstance(), desc, true); - } - - static void Destroy() - { - StoragePolicyBase::Destroy(Base::GetModuleAllocatorInstance()); - } - - static bool IsReady() - { - return Base::GetModuleAllocatorInstance().IsReady(); - } - }; } namespace Internal @@ -734,12 +640,15 @@ namespace AZ public: typedef typename Allocator::Descriptor Descriptor; - AZ_FORCE_INLINE static IAllocatorAllocate& Get() + // Maintained for backwards compatibility, prefer to use Get() instead. + // Get was previously used to get the the schema, however, that bypasses what the allocators are doing. + // If the schema is needed, call Get().GetSchema() + AZ_FORCE_INLINE static IAllocator& GetAllocator() { - return *GetAllocator().GetAllocationSource(); + return StoragePolicy::GetAllocator(); } - AZ_FORCE_INLINE static IAllocator& GetAllocator() + AZ_FORCE_INLINE static IAllocator& Get() { return StoragePolicy::GetAllocator(); } @@ -781,7 +690,7 @@ namespace AZ // structure of another allocator template class ChildAllocatorSchema - : public IAllocatorAllocate + : public IAllocatorSchema { public: // No descriptor is necessary, as the parent allocator is expected to already @@ -792,7 +701,7 @@ namespace AZ ChildAllocatorSchema(const Descriptor&) {} //--------------------------------------------------------------------- - // IAllocatorAllocate + // IAllocatorSchema //--------------------------------------------------------------------- pointer_type Allocate(size_type byteSize, size_type alignment, int flags = 0, const char* name = 0, const char* fileName = 0, int lineNum = 0, unsigned int suppressStackRecord = 0) override { @@ -848,11 +757,6 @@ namespace AZ { return AZ::AllocatorInstance::Get().GetUnAllocatedMemory(isPrint); } - - IAllocatorAllocate* GetSubAllocator() override - { - return AZ::AllocatorInstance::Get().GetSubAllocator(); - } }; /** @@ -873,7 +777,7 @@ namespace AZ { if (AllocatorInstance::IsReady()) { - m_name = AllocatorInstance::GetAllocator().GetName(); + m_name = AllocatorInstance::Get().GetName(); } else { @@ -932,7 +836,7 @@ namespace AZ typedef AZStd::ptrdiff_t difference_type; typedef AZStd::false_type allow_memory_leaks; ///< Regular allocators should not leak. - AZ_FORCE_INLINE AZStdIAllocator(IAllocatorAllocate* allocator, const char* name = "AZ::AZStdIAllocator") + AZ_FORCE_INLINE AZStdIAllocator(IAllocator* allocator, const char* name = "AZ::AZStdIAllocator") : m_allocator(allocator) , m_name(name) { @@ -965,7 +869,7 @@ namespace AZ AZ_FORCE_INLINE bool operator==(const AZStdIAllocator& rhs) const { return m_allocator == rhs.m_allocator; } AZ_FORCE_INLINE bool operator!=(const AZStdIAllocator& rhs) const { return m_allocator != rhs.m_allocator; } private: - IAllocatorAllocate* m_allocator; + IAllocator* m_allocator; const char* m_name; }; @@ -982,8 +886,8 @@ namespace AZ using size_type = AZStd::size_t; using difference_type = AZStd::ptrdiff_t; using allow_memory_leaks = AZStd::false_type; ///< Regular allocators should not leak. - using functor_type = IAllocatorAllocate&(*)(); ///< Function Pointer must return IAllocatorAllocate&. - ///< function pointers do not support covariant return types + using functor_type = IAllocator&(*)(); ///< Function Pointer must return IAllocator&. + ///< function pointers do not support covariant return types constexpr AZStdFunctorAllocator(functor_type allocatorFunctor, const char* name = "AZ::AZStdFunctorAllocator") : m_allocatorFunctor(allocatorFunctor) diff --git a/Code/Framework/AzCore/AzCore/Memory/OSAllocator.cpp b/Code/Framework/AzCore/AzCore/Memory/OSAllocator.cpp index 317df214d6..293cd92354 100644 --- a/Code/Framework/AzCore/AzCore/Memory/OSAllocator.cpp +++ b/Code/Framework/AzCore/AzCore/Memory/OSAllocator.cpp @@ -19,7 +19,6 @@ namespace AZ , m_custom(nullptr) , m_numAllocatedBytes(0) { - DisableOverriding(); } //========================================================================= diff --git a/Code/Framework/AzCore/AzCore/Memory/OSAllocator.h b/Code/Framework/AzCore/AzCore/Memory/OSAllocator.h index 3a8080483b..0bdf7d9fed 100644 --- a/Code/Framework/AzCore/AzCore/Memory/OSAllocator.h +++ b/Code/Framework/AzCore/AzCore/Memory/OSAllocator.h @@ -24,7 +24,6 @@ namespace AZ */ class OSAllocator : public AllocatorBase - , public IAllocatorAllocate { public: AZ_TYPE_INFO(OSAllocator, "{9F835EE3-F23C-454E-B4E3-011E2F3C8118}") @@ -39,7 +38,7 @@ namespace AZ { Descriptor() : m_custom(0) {} - IAllocatorAllocate* m_custom; ///< You can provide our own allocation scheme. If NULL a HeapScheme will be used with the provided Descriptor. + IAllocatorSchema* m_custom; ///< You can provide our own allocation scheme. If NULL a HeapScheme will be used with the provided Descriptor. }; bool Create(const Descriptor& desc); @@ -51,7 +50,7 @@ namespace AZ AllocatorDebugConfig GetDebugConfig() override; ////////////////////////////////////////////////////////////////////////// - // IAllocatorAllocate + // IAllocatorSchema pointer_type Allocate(size_type byteSize, size_type alignment, int flags = 0, const char* name = 0, const char* fileName = 0, int lineNum = 0, unsigned int suppressStackRecord = 0) override; void DeAllocate(pointer_type ptr, size_type byteSize = 0, size_type alignment = 0) override; size_type Resize(pointer_type ptr, size_type newSize) override { return m_custom ? m_custom->Resize(ptr, newSize) : 0; } @@ -62,13 +61,12 @@ namespace AZ size_type Capacity() const override { return m_custom ? m_custom->Capacity() : AZ_CORE_MAX_ALLOCATOR_SIZE; } // custom size or unlimited size_type GetMaxAllocationSize() const override { return m_custom ? m_custom->GetMaxAllocationSize() : AZ_CORE_MAX_ALLOCATOR_SIZE; } // custom size or unlimited size_type GetMaxContiguousAllocationSize() const override { return m_custom ? m_custom->GetMaxContiguousAllocationSize() : AZ_CORE_MAX_ALLOCATOR_SIZE; } // custom size or unlimited - IAllocatorAllocate* GetSubAllocator() override { return m_custom ? m_custom : NULL; } protected: OSAllocator(const OSAllocator&); OSAllocator& operator=(const OSAllocator&); - IAllocatorAllocate* m_custom; + IAllocatorSchema* m_custom; size_type m_numAllocatedBytes; }; diff --git a/Code/Framework/AzCore/AzCore/Memory/OverrunDetectionAllocator.cpp b/Code/Framework/AzCore/AzCore/Memory/OverrunDetectionAllocator.cpp index ed5e0febc2..096fbbac95 100644 --- a/Code/Framework/AzCore/AzCore/Memory/OverrunDetectionAllocator.cpp +++ b/Code/Framework/AzCore/AzCore/Memory/OverrunDetectionAllocator.cpp @@ -233,7 +233,6 @@ namespace AZ size_type Capacity() const; size_type GetMaxAllocationSize() const; size_type GetMaxContiguousAllocationSize() const; - IAllocatorAllocate* GetSubAllocator(); void GarbageCollect(); private: @@ -680,11 +679,6 @@ auto AZ::OverrunDetectionSchemaImpl::GetMaxContiguousAllocationSize() const -> s return 0; } -AZ::IAllocatorAllocate* AZ::OverrunDetectionSchemaImpl::GetSubAllocator() -{ - return nullptr; -} - void AZ::OverrunDetectionSchemaImpl::GarbageCollect() { } @@ -810,11 +804,6 @@ auto AZ::OverrunDetectionSchema::GetMaxContiguousAllocationSize() const -> size_ return m_impl->GetMaxContiguousAllocationSize(); } -AZ::IAllocatorAllocate* AZ::OverrunDetectionSchema::GetSubAllocator() -{ - return m_impl->GetSubAllocator(); -} - void AZ::OverrunDetectionSchema::GarbageCollect() { m_impl->GarbageCollect(); diff --git a/Code/Framework/AzCore/AzCore/Memory/OverrunDetectionAllocator.h b/Code/Framework/AzCore/AzCore/Memory/OverrunDetectionAllocator.h index 9895a5f84f..073b54160b 100644 --- a/Code/Framework/AzCore/AzCore/Memory/OverrunDetectionAllocator.h +++ b/Code/Framework/AzCore/AzCore/Memory/OverrunDetectionAllocator.h @@ -27,7 +27,7 @@ namespace AZ * the requested memory, plus the trap page). On most platforms this is 8kb (4kb * 2 pages). */ class OverrunDetectionSchema - : public IAllocatorAllocate + : public IAllocatorSchema { public: AZ_TYPE_INFO("OverrunDetectionSchema", "{0DF781AC-1615-40AE-81F7-6CA5841E2914}"); @@ -75,7 +75,7 @@ namespace AZ virtual ~OverrunDetectionSchema(); //--------------------------------------------------------------------- - // IAllocatorAllocate + // IAllocatorSchema //--------------------------------------------------------------------- pointer_type Allocate(size_type byteSize, size_type alignment, int flags, const char* name = 0, const char* fileName = 0, int lineNum = 0, unsigned int suppressStackRecord = 0) override; void DeAllocate(pointer_type ptr, size_type byteSize = 0, size_type alignment = 0) override; @@ -87,7 +87,6 @@ namespace AZ size_type Capacity() const override; size_type GetMaxAllocationSize() const override; size_type GetMaxContiguousAllocationSize() const override; - IAllocatorAllocate* GetSubAllocator() override; void GarbageCollect() override; private: diff --git a/Code/Framework/AzCore/AzCore/Memory/PoolAllocator.h b/Code/Framework/AzCore/AzCore/Memory/PoolAllocator.h index a03f7b5b92..f55c6251bf 100644 --- a/Code/Framework/AzCore/AzCore/Memory/PoolAllocator.h +++ b/Code/Framework/AzCore/AzCore/Memory/PoolAllocator.h @@ -102,7 +102,7 @@ namespace AZ } ////////////////////////////////////////////////////////////////////////// - // IAllocatorAllocate + // IAllocatorSchema pointer_type ReAllocate(pointer_type ptr, size_type newSize, size_type newAlignment) override { (void)ptr; diff --git a/Code/Framework/AzCore/AzCore/Memory/PoolSchema.cpp b/Code/Framework/AzCore/AzCore/Memory/PoolSchema.cpp index c57cfea222..07cc14a0f6 100644 --- a/Code/Framework/AzCore/AzCore/Memory/PoolSchema.cpp +++ b/Code/Framework/AzCore/AzCore/Memory/PoolSchema.cpp @@ -163,7 +163,7 @@ namespace AZ } using AllocatorType = PoolAllocation; - IAllocatorAllocate* m_pageAllocator; + IAllocatorSchema* m_pageAllocator; AllocatorType m_allocator; void* m_staticDataBlock; unsigned int m_numStaticPages; @@ -301,7 +301,7 @@ namespace AZ FreePagesType m_freePages; AZStd::vector m_threads; ///< Array with all separate thread data. Used to traverse end free elements. - IAllocatorAllocate* m_pageAllocator; + IAllocatorSchema* m_pageAllocator; void* m_staticDataBlock; size_t m_numStaticPages; size_t m_pageSize; @@ -744,15 +744,6 @@ namespace AZ return m_impl->m_numStaticPages * m_impl->m_pageSize; } - //========================================================================= - // GetPageAllocator - // [11/17/2010] - //========================================================================= - IAllocatorAllocate* PoolSchema::GetSubAllocator() - { - return m_impl->m_pageAllocator; - } - ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // PollAllocator Implementation @@ -1095,15 +1086,6 @@ namespace AZ return m_impl->m_numStaticPages * m_impl->m_pageSize; } - //========================================================================= - // GetPageAllocator - // [11/17/2010] - //========================================================================= - IAllocatorAllocate* ThreadPoolSchema::GetSubAllocator() - { - return m_impl->m_pageAllocator; - } - //========================================================================= // ThreadPoolSchemaImpl // [9/15/2009] diff --git a/Code/Framework/AzCore/AzCore/Memory/PoolSchema.h b/Code/Framework/AzCore/AzCore/Memory/PoolSchema.h index ef38dcf24f..9d605cd515 100644 --- a/Code/Framework/AzCore/AzCore/Memory/PoolSchema.h +++ b/Code/Framework/AzCore/AzCore/Memory/PoolSchema.h @@ -21,7 +21,7 @@ namespace AZ * use ThreadPool Schema or do the sync yourself. */ class PoolSchema - : public IAllocatorAllocate + : public IAllocatorSchema { public: /** @@ -51,7 +51,7 @@ namespace AZ * this is the minimum number of pages we will have allocated at all times, otherwise the total number of pages supported. */ unsigned int m_numStaticPages; - IAllocatorAllocate* m_pageAllocator; ///< If you provide this interface we will use it for page allocations, otherwise SystemAllocator will be used. + IAllocatorSchema* m_pageAllocator; ///< If you provide this interface we will use it for page allocations, otherwise SystemAllocator will be used. }; PoolSchema(const Descriptor& desc = Descriptor()); @@ -72,7 +72,6 @@ namespace AZ size_type GetMaxContiguousAllocationSize() const override; size_type NumAllocatedBytes() const override; size_type Capacity() const override; - IAllocatorAllocate* GetSubAllocator() override; protected: PoolSchema(const PoolSchema&); @@ -89,7 +88,7 @@ namespace AZ * for each thread. So there will be some memory overhead, especially if you use fixed pool sizes. */ class ThreadPoolSchema - : public IAllocatorAllocate + : public IAllocatorSchema { public: // Functions for getting an instance of a ThreadPoolData when using thread local storage @@ -118,7 +117,6 @@ namespace AZ size_type GetMaxContiguousAllocationSize() const override; size_type NumAllocatedBytes() const override; size_type Capacity() const override; - IAllocatorAllocate* GetSubAllocator() override; protected: ThreadPoolSchema(const ThreadPoolSchema&); diff --git a/Code/Framework/AzCore/AzCore/Memory/SimpleSchemaAllocator.h b/Code/Framework/AzCore/AzCore/Memory/SimpleSchemaAllocator.h index 5fbc890203..76be66786e 100644 --- a/Code/Framework/AzCore/AzCore/Memory/SimpleSchemaAllocator.h +++ b/Code/Framework/AzCore/AzCore/Memory/SimpleSchemaAllocator.h @@ -22,17 +22,15 @@ namespace AZ template class SimpleSchemaAllocator : public AllocatorBase - , public IAllocatorAllocate { public: using Descriptor = DescriptorType; - using pointer_type = typename IAllocatorAllocate::pointer_type; - using size_type = typename IAllocatorAllocate::size_type; - using difference_type = typename IAllocatorAllocate::difference_type; + using pointer_type = typename Schema::pointer_type; + using size_type = typename Schema::size_type; + using difference_type = typename Schema::difference_type; SimpleSchemaAllocator(const char* name, const char* desc) - : AllocatorBase(this, name, desc) - , m_schema(nullptr) + : AllocatorBase(nullptr, name, desc) { } @@ -65,13 +63,8 @@ namespace AZ return AllocatorDebugConfig(); } - IAllocatorAllocate* GetSchema() override - { - return m_schema; - } - //--------------------------------------------------------------------- - // IAllocatorAllocate + // IAllocatorSchema //--------------------------------------------------------------------- pointer_type Allocate(size_type byteSize, size_type alignment, int flags = 0, const char* name = nullptr, const char* fileName = nullptr, int lineNum = 0, unsigned int suppressStackRecord = 0) override { @@ -188,14 +181,6 @@ namespace AZ { return m_schema->GetUnAllocatedMemory(isPrint); } - - IAllocatorAllocate* GetSubAllocator() override - { - return m_schema->GetSubAllocator(); - } - - protected: - IAllocatorAllocate* m_schema; private: typename AZStd::aligned_storage::value>::type m_schemaStorage; diff --git a/Code/Framework/AzCore/AzCore/Memory/SystemAllocator.cpp b/Code/Framework/AzCore/AzCore/Memory/SystemAllocator.cpp index 41099f7a38..7238a18672 100644 --- a/Code/Framework/AzCore/AzCore/Memory/SystemAllocator.cpp +++ b/Code/Framework/AzCore/AzCore/Memory/SystemAllocator.cpp @@ -50,9 +50,8 @@ namespace AZ // [9/2/2009] //========================================================================= SystemAllocator::SystemAllocator() - : AllocatorBase(this, "SystemAllocator", "Fundamental generic memory allocator") + : AllocatorBase(nullptr, "SystemAllocator", "Fundamental generic memory allocator") , m_isCustom(false) - , m_allocator(nullptr) , m_ownsOSAllocator(false) { } @@ -91,7 +90,7 @@ namespace AZ if (desc.m_custom) { m_isCustom = true; - m_allocator = desc.m_custom; + m_schema = desc.m_custom; isReady = true; } else @@ -119,9 +118,9 @@ namespace AZ AZ_Assert(!g_isSystemSchemaUsed, "AZ::SystemAllocator MUST be created first! It's the source of all allocations!"); #if AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_HPHA - m_allocator = new (&g_systemSchema) HphaSchema(heapDesc); + m_schema = new (&g_systemSchema) HphaSchema(heapDesc); #elif AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_MALLOC - m_allocator = new (&g_systemSchema) MallocSchema(heapDesc); + m_schema = new (&g_systemSchema) MallocSchema(heapDesc); #endif g_isSystemSchemaUsed = true; isReady = true; @@ -134,11 +133,11 @@ namespace AZ "System allocator must be created before any other allocator! They allocate from it."); #if AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_HPHA - m_allocator = azcreate(HphaSchema, (heapDesc), SystemAllocator); + m_schema = azcreate(HphaSchema, (heapDesc), SystemAllocator); #elif AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_MALLOC - m_allocator = azcreate(MallocSchema, (heapDesc), SystemAllocator); + m_schema = azcreate(MallocSchema, (heapDesc), SystemAllocator); #endif - if (m_allocator == nullptr) + if (m_schema == nullptr) { isReady = false; } @@ -166,18 +165,18 @@ namespace AZ if (!m_isCustom) { - if ((void*)m_allocator == (void*)&g_systemSchema) + if ((void*)m_schema == (void*)&g_systemSchema) { #if AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_HPHA - static_cast(m_allocator)->~HphaSchema(); + static_cast(m_schema)->~HphaSchema(); #elif AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_MALLOC - static_cast(m_allocator)->~MallocSchema(); + static_cast(m_schema)->~MallocSchema(); #endif g_isSystemSchemaUsed = false; } else { - azdestroy(m_allocator); + azdestroy(m_schema); } } @@ -197,11 +196,6 @@ namespace AZ .ExcludeFromDebugging(!m_desc.m_allocationRecords); } - IAllocatorAllocate* SystemAllocator::GetSchema() - { - return m_allocator; - } - //========================================================================= // Allocate // [9/2/2009] @@ -224,14 +218,14 @@ namespace AZ byteSize = MemorySizeAdjustedUp(byteSize); SystemAllocator::pointer_type address = - m_allocator->Allocate(byteSize, alignment, flags, name, fileName, lineNum, suppressStackRecord + 1); + m_schema->Allocate(byteSize, alignment, flags, name, fileName, lineNum, suppressStackRecord + 1); if (address == nullptr) { // Free all memory we can and try again! AllocatorManager::Instance().GarbageCollect(); - address = m_allocator->Allocate(byteSize, alignment, flags, name, fileName, lineNum, suppressStackRecord + 1); + address = m_schema->Allocate(byteSize, alignment, flags, name, fileName, lineNum, suppressStackRecord + 1); } if (address == nullptr) @@ -258,7 +252,7 @@ namespace AZ byteSize = MemorySizeAdjustedUp(byteSize); AZ_PROFILE_MEMORY_FREE(MemoryReserved, ptr); AZ_MEMORY_PROFILE(ProfileDeallocation(ptr, byteSize, alignment, nullptr)); - m_allocator->DeAllocate(ptr, byteSize, alignment); + m_schema->DeAllocate(ptr, byteSize, alignment); } //========================================================================= @@ -271,7 +265,7 @@ namespace AZ AZ_MEMORY_PROFILE(ProfileReallocationBegin(ptr, newSize)); AZ_PROFILE_MEMORY_FREE(MemoryReserved, ptr); - pointer_type newAddress = m_allocator->ReAllocate(ptr, newSize, newAlignment); + pointer_type newAddress = m_schema->ReAllocate(ptr, newSize, newAlignment); AZ_PROFILE_MEMORY_ALLOC(MemoryReserved, newAddress, newSize, "SystemAllocator realloc"); AZ_MEMORY_PROFILE(ProfileReallocationEnd(ptr, newAddress, newSize, newAlignment)); @@ -285,7 +279,7 @@ namespace AZ SystemAllocator::size_type SystemAllocator::Resize(pointer_type ptr, size_type newSize) { newSize = MemorySizeAdjustedUp(newSize); - size_type resizedSize = m_allocator->Resize(ptr, newSize); + size_type resizedSize = m_schema->Resize(ptr, newSize); AZ_MEMORY_PROFILE(ProfileResize(ptr, resizedSize)); @@ -298,7 +292,7 @@ namespace AZ //========================================================================= SystemAllocator::size_type SystemAllocator::AllocationSize(pointer_type ptr) { - size_type allocSize = MemorySizeAdjustedDown(m_allocator->AllocationSize(ptr)); + size_type allocSize = MemorySizeAdjustedDown(m_schema->AllocationSize(ptr)); return allocSize; } diff --git a/Code/Framework/AzCore/AzCore/Memory/SystemAllocator.h b/Code/Framework/AzCore/AzCore/Memory/SystemAllocator.h index c730b8dde6..3ccdbd7f28 100644 --- a/Code/Framework/AzCore/AzCore/Memory/SystemAllocator.h +++ b/Code/Framework/AzCore/AzCore/Memory/SystemAllocator.h @@ -25,7 +25,6 @@ namespace AZ */ class SystemAllocator : public AllocatorBase - , public IAllocatorAllocate { public: AZ_TYPE_INFO(SystemAllocator, "{424C94D8-85CF-4E89-8CD6-AB5EC173E875}") @@ -38,7 +37,7 @@ namespace AZ * we will allocate system memory using system calls. You can * provide arenas (spaces) with pre-allocated memory, and use the * flag to specify which arena you want to allocate from. - * You are also allowed to supply IAllocatorAllocate, but if you do + * You are also allowed to supply IAllocatorSchema, but if you do * so you will need to take care of all allocations, we will not use * the default HeapSchema. * \ref HeapSchema::Descriptor @@ -50,7 +49,7 @@ namespace AZ , m_allocationRecords(true) , m_stackRecordLevels(5) {} - IAllocatorAllocate* m_custom; ///< You can provide our own allocation scheme. If NULL a HeapScheme will be used with the provided Descriptor. + IAllocatorSchema* m_custom; ///< You can provide our own allocation scheme. If NULL a HeapScheme will be used with the provided Descriptor. struct Heap { @@ -72,7 +71,7 @@ namespace AZ int m_numFixedMemoryBlocks; ///< Number of memory blocks to use. void* m_fixedMemoryBlocks[m_maxNumFixedBlocks]; ///< Pointers to provided memory blocks or NULL if you want the system to allocate them for you with the System Allocator. size_t m_fixedMemoryBlocksByteSize[m_maxNumFixedBlocks]; ///< Sizes of different memory blocks (MUST be multiple of m_pageSize), if m_memoryBlock is 0 the block will be allocated for you with the System Allocator. - IAllocatorAllocate* m_subAllocator; ///< Allocator that m_memoryBlocks memory was allocated from or should be allocated (if NULL). + IAllocatorSchema* m_subAllocator; ///< Allocator that m_memoryBlocks memory was allocated from or should be allocated (if NULL). size_t m_systemChunkSize; ///< Size of chunk to request from the OS when more memory is needed (defaults to m_pageSize) } m_heap; bool m_allocationRecords; ///< True if we want to track memory allocations, otherwise false. @@ -86,25 +85,23 @@ namespace AZ ////////////////////////////////////////////////////////////////////////// // IAllocator AllocatorDebugConfig GetDebugConfig() override; - IAllocatorAllocate* GetSchema() override; ////////////////////////////////////////////////////////////////////////// - // IAllocatorAllocate + // IAllocatorSchema pointer_type Allocate(size_type byteSize, size_type alignment, int flags = 0, const char* name = 0, const char* fileName = 0, int lineNum = 0, unsigned int suppressStackRecord = 0) override; void DeAllocate(pointer_type ptr, size_type byteSize = 0, size_type alignment = 0) override; pointer_type ReAllocate(pointer_type ptr, size_type newSize, size_type newAlignment) override; size_type Resize(pointer_type ptr, size_type newSize) override; size_type AllocationSize(pointer_type ptr) override; - void GarbageCollect() override { m_allocator->GarbageCollect(); } + void GarbageCollect() override { GetSchema()->GarbageCollect(); } - size_type NumAllocatedBytes() const override { return m_allocator->NumAllocatedBytes(); } - size_type Capacity() const override { return m_allocator->Capacity(); } + size_type NumAllocatedBytes() const override { return GetSchema()->NumAllocatedBytes(); } + size_type Capacity() const override { return GetSchema()->Capacity(); } /// Keep in mind this operation will execute GarbageCollect to make sure it returns, max allocation. This function WILL be slow. - size_type GetMaxAllocationSize() const override { return m_allocator->GetMaxAllocationSize(); } - size_type GetMaxContiguousAllocationSize() const override { return m_allocator->GetMaxContiguousAllocationSize(); } - size_type GetUnAllocatedMemory(bool isPrint = false) const override { return m_allocator->GetUnAllocatedMemory(isPrint); } - IAllocatorAllocate* GetSubAllocator() override { return m_isCustom ? m_allocator : m_allocator->GetSubAllocator(); } + size_type GetMaxAllocationSize() const override { return GetSchema()->GetMaxAllocationSize(); } + size_type GetMaxContiguousAllocationSize() const override { return GetSchema()->GetMaxContiguousAllocationSize(); } + size_type GetUnAllocatedMemory(bool isPrint = false) const override { return GetSchema()->GetUnAllocatedMemory(isPrint); } ////////////////////////////////////////////////////////////////////////// @@ -114,7 +111,6 @@ namespace AZ Descriptor m_desc; bool m_isCustom; - IAllocatorAllocate* m_allocator; bool m_ownsOSAllocator; }; } 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..8416099f15 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) @@ -170,14 +248,14 @@ #if defined(__has_builtin) #if __has_builtin(__builtin_is_constant_evaluated) #define az_builtin_is_constant_evaluated() __builtin_is_constant_evaluated() - #define az_has_builtin_is_constant_evaluated() true + #define az_has_builtin_is_constant_evaluated true #endif #elif AZ_COMPILER_MSVC >= 1928 #define az_builtin_is_constant_evaluated() __builtin_is_constant_evaluated() - #define az_has_builtin_is_constant_evaluated() true + #define az_has_builtin_is_constant_evaluated true #elif AZ_COMPILER_GCC #define az_builtin_is_constant_evaluated() __builtin_is_constant_evaluated() - #define az_has_builtin_is_constant_evaluated() true + #define az_has_builtin_is_constant_evaluated true #endif #endif @@ -193,7 +271,7 @@ } } #define az_builtin_is_constant_evaluated() AZ::Internal::builtin_is_constant_evaluated() - #define az_has_builtin_is_constant_evaluated() false + #define az_has_builtin_is_constant_evaluated false #endif // define builtin functions used by char_traits class for efficient compile time and runtime 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