From 45b83e49da99ed40a322d78a627296f09eb8a68c Mon Sep 17 00:00:00 2001 From: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> Date: Mon, 5 Jul 2021 13:08:05 +0100 Subject: [PATCH 01/11] Move camera properties from CVars to the Settings Registry (#1766) * updates to camera inputs Signed-off-by: hultonha * update test names to include types Signed-off-by: hultonha * move all camera input controls to the settings registry Signed-off-by: hultonha * small fixes before PR Signed-off-by: hultonha --- Code/Editor/EditorViewportSettings.cpp | 149 +++++++++++++++++- Code/Editor/EditorViewportSettings.h | 42 ++++- Code/Editor/EditorViewportWidget.cpp | 38 ++--- .../AzFramework/Viewport/CameraInput.cpp | 119 +++----------- .../AzFramework/Viewport/CameraInput.h | 31 +++- Code/Framework/Tests/CameraInputTests.cpp | 54 ++++--- 6 files changed, 287 insertions(+), 146 deletions(-) diff --git a/Code/Editor/EditorViewportSettings.cpp b/Code/Editor/EditorViewportSettings.cpp index 5a852c0ae5..ce7a6f9888 100644 --- a/Code/Editor/EditorViewportSettings.cpp +++ b/Code/Editor/EditorViewportSettings.cpp @@ -1,6 +1,6 @@ /* * 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 * */ @@ -30,6 +30,19 @@ namespace SandboxEditor constexpr AZStd::string_view CameraPanSpeedSetting = "/Amazon/Preferences/Editor/Camera/PanSpeed"; constexpr AZStd::string_view CameraRotateSmoothnessSetting = "/Amazon/Preferences/Editor/Camera/RotateSmoothness"; constexpr AZStd::string_view CameraTranslateSmoothnessSetting = "/Amazon/Preferences/Editor/Camera/TranslateSmoothness"; + constexpr AZStd::string_view CameraTranslateForwardIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateForwardId"; + constexpr AZStd::string_view CameraTranslateBackwardIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateBackwardId"; + constexpr AZStd::string_view CameraTranslateLeftIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateLeftId"; + constexpr AZStd::string_view CameraTranslateRightIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateRightId"; + constexpr AZStd::string_view CameraTranslateUpIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateUpId"; + constexpr AZStd::string_view CameraTranslateDownIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateUpDownId"; + constexpr AZStd::string_view CameraTranslateBoostIdSetting = "/Amazon/Preferences/Editor/Camera/TranslateBoostId"; + constexpr AZStd::string_view CameraOrbitIdSetting = "/Amazon/Preferences/Editor/Camera/OrbitId"; + constexpr AZStd::string_view CameraFreeLookIdSetting = "/Amazon/Preferences/Editor/Camera/FreeLookId"; + constexpr AZStd::string_view CameraFreePanIdSetting = "/Amazon/Preferences/Editor/Camera/FreePanId"; + constexpr AZStd::string_view CameraOrbitLookIdSetting = "/Amazon/Preferences/Editor/Camera/OrbitLookId"; + constexpr AZStd::string_view CameraOrbitDollyIdSetting = "/Amazon/Preferences/Editor/Camera/OrbitDollyId"; + constexpr AZStd::string_view CameraOrbitPanIdSetting = "/Amazon/Preferences/Editor/Camera/OrbitPanId"; template void SetRegistry(const AZStd::string_view setting, T&& value) @@ -244,4 +257,138 @@ namespace SandboxEditor { SetRegistry(CameraTranslateSmoothnessSetting, smoothness); } + + AzFramework::InputChannelId CameraTranslateForwardChannelId() + { + return AzFramework::InputChannelId( + GetRegistry(CameraTranslateForwardIdSetting, AZStd::string("keyboard_key_alphanumeric_W")).c_str()); + } + + void SetCameraTranslateForwardChannelId(AZStd::string_view cameraTranslateForwardId) + { + SetRegistry(CameraTranslateForwardIdSetting, cameraTranslateForwardId); + } + + AzFramework::InputChannelId CameraTranslateBackwardChannelId() + { + return AzFramework::InputChannelId( + GetRegistry(CameraTranslateBackwardIdSetting, AZStd::string("keyboard_key_alphanumeric_S")).c_str()); + } + + void SetCameraTranslateBackwardChannelId(AZStd::string_view cameraTranslateBackwardId) + { + SetRegistry(CameraTranslateBackwardIdSetting, cameraTranslateBackwardId); + } + + AzFramework::InputChannelId CameraTranslateLeftChannelId() + { + return AzFramework::InputChannelId(GetRegistry(CameraTranslateLeftIdSetting, AZStd::string("keyboard_key_alphanumeric_A")).c_str()); + } + + void SetCameraTranslateLeftChannelId(AZStd::string_view cameraTranslateLeftId) + { + SetRegistry(CameraTranslateLeftIdSetting, cameraTranslateLeftId); + } + + AzFramework::InputChannelId CameraTranslateRightChannelId() + { + return AzFramework::InputChannelId( + GetRegistry(CameraTranslateRightIdSetting, AZStd::string("keyboard_key_alphanumeric_D")).c_str()); + } + + void SetCameraTranslateRightChannelId(AZStd::string_view cameraTranslateRightId) + { + SetRegistry(CameraTranslateRightIdSetting, cameraTranslateRightId); + } + + AzFramework::InputChannelId CameraTranslateUpChannelId() + { + return AzFramework::InputChannelId(GetRegistry(CameraTranslateUpIdSetting, AZStd::string("keyboard_key_alphanumeric_E")).c_str()); + } + + void SetCameraTranslateUpChannelId(AZStd::string_view cameraTranslateUpId) + { + SetRegistry(CameraTranslateUpIdSetting, cameraTranslateUpId); + } + + AzFramework::InputChannelId CameraTranslateDownChannelId() + { + return AzFramework::InputChannelId(GetRegistry(CameraTranslateDownIdSetting, AZStd::string("keyboard_key_alphanumeric_Q")).c_str()); + } + + void SetCameraTranslateDownChannelId(AZStd::string_view cameraTranslateDownId) + { + SetRegistry(CameraTranslateDownIdSetting, cameraTranslateDownId); + } + + AzFramework::InputChannelId CameraTranslateBoostChannelId() + { + return AzFramework::InputChannelId( + GetRegistry(CameraTranslateBoostIdSetting, AZStd::string("keyboard_key_modifier_shift_l")).c_str()); + } + + void SetCameraTranslateBoostChannelId(AZStd::string_view cameraTranslateBoostId) + { + SetRegistry(CameraTranslateDownIdSetting, cameraTranslateBoostId); + } + + AzFramework::InputChannelId CameraOrbitChannelId() + { + return AzFramework::InputChannelId(GetRegistry(CameraOrbitIdSetting, AZStd::string("keyboard_key_modifier_alt_l")).c_str()); + } + + void SetCameraOrbitChannelChannelId(AZStd::string_view cameraOrbitId) + { + SetRegistry(CameraOrbitIdSetting, cameraOrbitId); + } + + AzFramework::InputChannelId CameraFreeLookChannelId() + { + return AzFramework::InputChannelId(GetRegistry(CameraFreeLookIdSetting, AZStd::string("mouse_button_right")).c_str()); + } + + void SetCameraFreeLookChannelId(AZStd::string_view cameraFreeLookId) + { + SetRegistry(CameraFreeLookIdSetting, cameraFreeLookId); + } + + AzFramework::InputChannelId CameraFreePanChannelId() + { + return AzFramework::InputChannelId(GetRegistry(CameraFreePanIdSetting, AZStd::string("mouse_button_middle")).c_str()); + } + + void SetCameraFreePanChannelId(AZStd::string_view cameraFreePanId) + { + SetRegistry(CameraFreePanIdSetting, cameraFreePanId); + } + + AzFramework::InputChannelId CameraOrbitLookChannelId() + { + return AzFramework::InputChannelId(GetRegistry(CameraOrbitLookIdSetting, AZStd::string("mouse_button_left")).c_str()); + } + + void SetCameraOrbitLookChannelId(AZStd::string_view cameraOrbitLookId) + { + SetRegistry(CameraOrbitLookIdSetting, cameraOrbitLookId); + } + + AzFramework::InputChannelId CameraOrbitDollyChannelId() + { + return AzFramework::InputChannelId(GetRegistry(CameraOrbitDollyIdSetting, AZStd::string("mouse_button_right")).c_str()); + } + + void SetCameraOrbitDollyChannelId(AZStd::string_view cameraOrbitDollyId) + { + SetRegistry(CameraOrbitDollyIdSetting, cameraOrbitDollyId); + } + + AzFramework::InputChannelId CameraOrbitPanChannelId() + { + return AzFramework::InputChannelId(GetRegistry(CameraOrbitPanIdSetting, AZStd::string("mouse_button_middle")).c_str()); + } + + void SetCameraOrbitPanChannelId(AZStd::string_view cameraOrbitPanId) + { + SetRegistry(CameraOrbitPanIdSetting, cameraOrbitPanId); + } } // namespace SandboxEditor diff --git a/Code/Editor/EditorViewportSettings.h b/Code/Editor/EditorViewportSettings.h index 718782ccd5..5744111ff3 100644 --- a/Code/Editor/EditorViewportSettings.h +++ b/Code/Editor/EditorViewportSettings.h @@ -1,6 +1,6 @@ /* * 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 * */ @@ -11,6 +11,7 @@ #include #include +#include namespace SandboxEditor { @@ -78,6 +79,45 @@ namespace SandboxEditor SANDBOX_API float CameraTranslateSmoothness(); SANDBOX_API void SetCameraTranslateSmoothness(float smoothness); + SANDBOX_API AzFramework::InputChannelId CameraTranslateForwardChannelId(); + SANDBOX_API void SetCameraTranslateForwardChannelId(AZStd::string_view cameraTranslateForwardId); + + SANDBOX_API AzFramework::InputChannelId CameraTranslateBackwardChannelId(); + SANDBOX_API void SetCameraTranslateBackwardChannelId(AZStd::string_view cameraTranslateBackwardId); + + SANDBOX_API AzFramework::InputChannelId CameraTranslateLeftChannelId(); + SANDBOX_API void SetCameraTranslateLeftChannelId(AZStd::string_view cameraTranslateLeftId); + + SANDBOX_API AzFramework::InputChannelId CameraTranslateRightChannelId(); + SANDBOX_API void SetCameraTranslateRightChannelId(AZStd::string_view cameraTranslateRightId); + + SANDBOX_API AzFramework::InputChannelId CameraTranslateUpChannelId(); + SANDBOX_API void SetCameraTranslateUpChannelId(AZStd::string_view cameraTranslateUpId); + + SANDBOX_API AzFramework::InputChannelId CameraTranslateDownChannelId(); + SANDBOX_API void SetCameraTranslateDownChannelId(AZStd::string_view cameraTranslateDownId); + + SANDBOX_API AzFramework::InputChannelId CameraTranslateBoostChannelId(); + SANDBOX_API void SetCameraTranslateBoostChannelId(AZStd::string_view cameraTranslateBoostId); + + SANDBOX_API AzFramework::InputChannelId CameraOrbitChannelId(); + SANDBOX_API void SetCameraOrbitChannelChannelId(AZStd::string_view cameraOrbitId); + + SANDBOX_API AzFramework::InputChannelId CameraFreeLookChannelId(); + SANDBOX_API void SetCameraFreeLookChannelId(AZStd::string_view cameraFreeLookId); + + SANDBOX_API AzFramework::InputChannelId CameraFreePanChannelId(); + SANDBOX_API void SetCameraFreePanChannelId(AZStd::string_view cameraFreePanId); + + SANDBOX_API AzFramework::InputChannelId CameraOrbitLookChannelId(); + SANDBOX_API void SetCameraOrbitLookChannelId(AZStd::string_view cameraOrbitLookId); + + SANDBOX_API AzFramework::InputChannelId CameraOrbitDollyChannelId(); + SANDBOX_API void SetCameraOrbitDollyChannelId(AZStd::string_view cameraOrbitDollyId); + + SANDBOX_API AzFramework::InputChannelId CameraOrbitPanChannelId(); + SANDBOX_API void SetCameraOrbitPanChannelId(AZStd::string_view cameraOrbitPanId); + //! Return if the new editor camera system is enabled or not. //! @note This is implemented in EditorViewportWidget.cpp SANDBOX_API bool UsingNewCameraSystem(); diff --git a/Code/Editor/EditorViewportWidget.cpp b/Code/Editor/EditorViewportWidget.cpp index 0e03cf67cb..cc9a5e5355 100644 --- a/Code/Editor/EditorViewportWidget.cpp +++ b/Code/Editor/EditorViewportWidget.cpp @@ -113,15 +113,6 @@ namespace SandboxEditor EditorViewportWidget* EditorViewportWidget::m_pPrimaryViewport = nullptr; -namespace AzFramework -{ - extern InputChannelId CameraFreeLookButton; - extern InputChannelId CameraFreePanButton; - extern InputChannelId CameraOrbitLookButton; - extern InputChannelId CameraOrbitDollyButton; - extern InputChannelId CameraOrbitPanButton; -} // namespace AzFramework - #if AZ_TRAIT_OS_PLATFORM_APPLE void StopFixedCursorMode(); void StartFixedCursorMode(QObject *viewport); @@ -1236,8 +1227,6 @@ bool EditorViewportWidget::ShowingWorldSpace() AZStd::shared_ptr CreateModularViewportCameraController( AzFramework::ViewportId viewportId) { - AzFramework::ReloadCameraKeyBindings(); - auto controller = AZStd::make_shared(); controller->SetCameraPropsBuilderCallback( [](AzFramework::CameraProps& cameraProps) @@ -1267,7 +1256,7 @@ AZStd::shared_ptr CreateMod viewportId, &AzToolsFramework::ViewportInteraction::ViewportMouseCursorRequestBus::Events::EndCursorCapture); }; - auto firstPersonRotateCamera = AZStd::make_shared(AzFramework::CameraFreeLookButton); + auto firstPersonRotateCamera = AZStd::make_shared(SandboxEditor::CameraFreeLookChannelId()); firstPersonRotateCamera->m_rotateSpeedFn = [] { return SandboxEditor::CameraRotateSpeed(); @@ -1276,7 +1265,7 @@ AZStd::shared_ptr CreateMod firstPersonRotateCamera->SetActivationEndedFn(showCursor); auto firstPersonPanCamera = - AZStd::make_shared(AzFramework::CameraFreePanButton, AzFramework::LookPan); + AZStd::make_shared(SandboxEditor::CameraFreePanChannelId(), AzFramework::LookPan); firstPersonPanCamera->m_panSpeedFn = [] { return SandboxEditor::CameraPanSpeed(); @@ -1290,7 +1279,17 @@ AZStd::shared_ptr CreateMod return SandboxEditor::CameraPanInvertedY(); }; - auto firstPersonTranslateCamera = AZStd::make_shared(AzFramework::LookTranslation); + AzFramework::TranslateCameraInputChannels translateCameraInputChannels; + translateCameraInputChannels.m_leftChannelId = SandboxEditor::CameraTranslateLeftChannelId(); + translateCameraInputChannels.m_rightChannelId = SandboxEditor::CameraTranslateRightChannelId(); + translateCameraInputChannels.m_forwardChannelId = SandboxEditor::CameraTranslateForwardChannelId(); + translateCameraInputChannels.m_backwardChannelId = SandboxEditor::CameraTranslateBackwardChannelId(); + translateCameraInputChannels.m_upChannelId = SandboxEditor::CameraTranslateUpChannelId(); + translateCameraInputChannels.m_downChannelId = SandboxEditor::CameraTranslateDownChannelId(); + translateCameraInputChannels.m_boostChannelId = SandboxEditor::CameraTranslateBoostChannelId(); + + auto firstPersonTranslateCamera = + AZStd::make_shared(AzFramework::LookTranslation, translateCameraInputChannels); firstPersonTranslateCamera->m_translateSpeedFn = [] { return SandboxEditor::CameraTranslateSpeed(); @@ -1306,7 +1305,7 @@ AZStd::shared_ptr CreateMod return SandboxEditor::CameraScrollSpeed(); }; - auto orbitCamera = AZStd::make_shared(); + auto orbitCamera = AZStd::make_shared(SandboxEditor::CameraOrbitChannelId()); orbitCamera->SetLookAtFn( [viewportId](const AZ::Vector3& position, const AZ::Vector3& direction) -> AZStd::optional { @@ -1343,7 +1342,7 @@ AZStd::shared_ptr CreateMod return {}; }); - auto orbitRotateCamera = AZStd::make_shared(AzFramework::CameraOrbitLookButton); + auto orbitRotateCamera = AZStd::make_shared(SandboxEditor::CameraOrbitLookChannelId()); orbitRotateCamera->m_rotateSpeedFn = [] { return SandboxEditor::CameraRotateSpeed(); @@ -1353,7 +1352,8 @@ AZStd::shared_ptr CreateMod return SandboxEditor::CameraOrbitYawRotationInverted(); }; - auto orbitTranslateCamera = AZStd::make_shared(AzFramework::OrbitTranslation); + auto orbitTranslateCamera = + AZStd::make_shared(AzFramework::OrbitTranslation, translateCameraInputChannels); orbitTranslateCamera->m_translateSpeedFn = [] { return SandboxEditor::CameraTranslateSpeed(); @@ -1370,13 +1370,13 @@ AZStd::shared_ptr CreateMod }; auto orbitDollyMoveCamera = - AZStd::make_shared(AzFramework::CameraOrbitDollyButton); + AZStd::make_shared(SandboxEditor::CameraOrbitDollyChannelId()); orbitDollyMoveCamera->m_cursorSpeedFn = [] { return SandboxEditor::CameraDollyMotionSpeed(); }; - auto orbitPanCamera = AZStd::make_shared(AzFramework::CameraOrbitPanButton, AzFramework::OrbitPan); + auto orbitPanCamera = AZStd::make_shared(SandboxEditor::CameraOrbitPanChannelId(), AzFramework::OrbitPan); orbitPanCamera->m_panSpeedFn = [] { return SandboxEditor::CameraPanSpeed(); diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp index a12069c712..e42f65d682 100644 --- a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp +++ b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp @@ -26,85 +26,6 @@ namespace AzFramework AZ_CVAR(float, ed_cameraSystemMinOrbitDistance, 10.0f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); AZ_CVAR(float, ed_cameraSystemMaxOrbitDistance, 50.0f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); - AZ_CVAR( - AZ::CVarFixedString, ed_cameraSystemTranslateForwardKey, "keyboard_key_alphanumeric_W", nullptr, AZ::ConsoleFunctorFlags::Null, ""); - AZ_CVAR( - AZ::CVarFixedString, - ed_cameraSystemTranslateBackwardKey, - "keyboard_key_alphanumeric_S", - nullptr, - AZ::ConsoleFunctorFlags::Null, - ""); - AZ_CVAR( - AZ::CVarFixedString, ed_cameraSystemTranslateLeftKey, "keyboard_key_alphanumeric_A", nullptr, AZ::ConsoleFunctorFlags::Null, ""); - AZ_CVAR( - AZ::CVarFixedString, ed_cameraSystemTranslateRightKey, "keyboard_key_alphanumeric_D", nullptr, AZ::ConsoleFunctorFlags::Null, ""); - AZ_CVAR(AZ::CVarFixedString, ed_cameraSystemTranslateUpKey, "keyboard_key_alphanumeric_E", nullptr, AZ::ConsoleFunctorFlags::Null, ""); - AZ_CVAR( - AZ::CVarFixedString, ed_cameraSystemTranslateDownKey, "keyboard_key_alphanumeric_Q", nullptr, AZ::ConsoleFunctorFlags::Null, ""); - AZ_CVAR( - AZ::CVarFixedString, ed_cameraSystemTranslateBoostKey, "keyboard_key_modifier_shift_l", nullptr, AZ::ConsoleFunctorFlags::Null, ""); - AZ_CVAR(AZ::CVarFixedString, ed_cameraSystemOrbitKey, "keyboard_key_modifier_alt_l", nullptr, AZ::ConsoleFunctorFlags::Null, ""); - - AZ_CVAR(AZ::CVarFixedString, ed_cameraSystemFreeLookButton, "mouse_button_right", nullptr, AZ::ConsoleFunctorFlags::Null, ""); - AZ_CVAR(AZ::CVarFixedString, ed_cameraSystemFreePanButton, "mouse_button_middle", nullptr, AZ::ConsoleFunctorFlags::Null, ""); - AZ_CVAR(AZ::CVarFixedString, ed_cameraSystemOrbitLookButton, "mouse_button_left", nullptr, AZ::ConsoleFunctorFlags::Null, ""); - AZ_CVAR(AZ::CVarFixedString, ed_cameraSystemOrbitDollyButton, "mouse_button_right", nullptr, AZ::ConsoleFunctorFlags::Null, ""); - AZ_CVAR(AZ::CVarFixedString, ed_cameraSystemOrbitPanButton, "mouse_button_middle", nullptr, AZ::ConsoleFunctorFlags::Null, ""); - - static InputChannelId CameraTranslateForwardId; - static InputChannelId CameraTranslateBackwardId; - static InputChannelId CameraTranslateLeftId; - static InputChannelId CameraTranslateRightId; - static InputChannelId CameraTranslateDownId; - static InputChannelId CameraTranslateUpId; - static InputChannelId CameraTranslateBoostId; - static InputChannelId CameraOrbitId; - - // externed elsewhere - InputChannelId CameraFreeLookButton; - InputChannelId CameraFreePanButton; - InputChannelId CameraOrbitLookButton; - InputChannelId CameraOrbitDollyButton; - InputChannelId CameraOrbitPanButton; - - void ReloadCameraKeyBindings() - { - const AZ::CVarFixedString& forward = ed_cameraSystemTranslateForwardKey; - CameraTranslateForwardId = InputChannelId(forward.c_str()); - const AZ::CVarFixedString& backward = ed_cameraSystemTranslateBackwardKey; - CameraTranslateBackwardId = InputChannelId(backward.c_str()); - const AZ::CVarFixedString& left = ed_cameraSystemTranslateLeftKey; - CameraTranslateLeftId = InputChannelId(left.c_str()); - const AZ::CVarFixedString& right = ed_cameraSystemTranslateRightKey; - CameraTranslateRightId = InputChannelId(right.c_str()); - const AZ::CVarFixedString& down = ed_cameraSystemTranslateDownKey; - CameraTranslateDownId = InputChannelId(down.c_str()); - const AZ::CVarFixedString& up = ed_cameraSystemTranslateUpKey; - CameraTranslateUpId = InputChannelId(up.c_str()); - const AZ::CVarFixedString& boost = ed_cameraSystemTranslateBoostKey; - CameraTranslateBoostId = InputChannelId(boost.c_str()); - const AZ::CVarFixedString& orbit = ed_cameraSystemOrbitKey; - CameraOrbitId = InputChannelId(orbit.c_str()); - const AZ::CVarFixedString& freeLook = ed_cameraSystemFreeLookButton; - CameraFreeLookButton = InputChannelId(freeLook.c_str()); - const AZ::CVarFixedString& freePan = ed_cameraSystemFreePanButton; - CameraFreePanButton = InputChannelId(freePan.c_str()); - const AZ::CVarFixedString& orbitLook = ed_cameraSystemOrbitLookButton; - CameraOrbitLookButton = InputChannelId(orbitLook.c_str()); - const AZ::CVarFixedString& orbitDolly = ed_cameraSystemOrbitDollyButton; - CameraOrbitDollyButton = InputChannelId(orbitDolly.c_str()); - const AZ::CVarFixedString& orbitPan = ed_cameraSystemOrbitPanButton; - CameraOrbitPanButton = InputChannelId(orbitPan.c_str()); - } - - static void ReloadCameraKeyBindingsConsole(const AZ::ConsoleCommandContainer&) - { - ReloadCameraKeyBindings(); - } - - AZ_CONSOLEFREEFUNC(ReloadCameraKeyBindingsConsole, AZ::ConsoleFunctorFlags::Null, "Reload keybindings for the modern camera system"); - //! return -1.0f if inverted, 1.0f otherwise constexpr static float Invert(const bool invert) { @@ -289,7 +210,7 @@ namespace AzFramework }); } - RotateCameraInput::RotateCameraInput(const InputChannelId rotateChannelId) + RotateCameraInput::RotateCameraInput(const InputChannelId& rotateChannelId) : m_rotateChannelId(rotateChannelId) { m_rotateSpeedFn = []() constexpr @@ -372,7 +293,7 @@ namespace AzFramework return nextCamera; } - PanCameraInput::PanCameraInput(const InputChannelId panChannelId, PanAxesFn panAxesFn) + PanCameraInput::PanCameraInput(const InputChannelId& panChannelId, PanAxesFn panAxesFn) : m_panAxesFn(AZStd::move(panAxesFn)) , m_panChannelId(panChannelId) { @@ -433,34 +354,35 @@ namespace AzFramework return nextCamera; } - TranslateCameraInput::TranslationType TranslateCameraInput::TranslationFromKey(InputChannelId channelId) + TranslateCameraInput::TranslationType TranslateCameraInput::TranslationFromKey( + const InputChannelId& channelId, const TranslateCameraInputChannels& translateCameraInputChannels) { - if (channelId == CameraTranslateForwardId) + if (channelId == translateCameraInputChannels.m_forwardChannelId) { return TranslationType::Forward; } - if (channelId == CameraTranslateBackwardId) + if (channelId == translateCameraInputChannels.m_backwardChannelId) { return TranslationType::Backward; } - if (channelId == CameraTranslateLeftId) + if (channelId == translateCameraInputChannels.m_leftChannelId) { return TranslationType::Left; } - if (channelId == CameraTranslateRightId) + if (channelId == translateCameraInputChannels.m_rightChannelId) { return TranslationType::Right; } - if (channelId == CameraTranslateDownId) + if (channelId == translateCameraInputChannels.m_downChannelId) { return TranslationType::Down; } - if (channelId == CameraTranslateUpId) + if (channelId == translateCameraInputChannels.m_upChannelId) { return TranslationType::Up; } @@ -468,8 +390,10 @@ namespace AzFramework return TranslationType::Nil; } - TranslateCameraInput::TranslateCameraInput(TranslationAxesFn translationAxesFn) + TranslateCameraInput::TranslateCameraInput( + TranslationAxesFn translationAxesFn, const TranslateCameraInputChannels& translateCameraInputChannels) : m_translationAxesFn(AZStd::move(translationAxesFn)) + , m_translateCameraInputChannels(translateCameraInputChannels) { m_translateSpeedFn = []() constexpr { @@ -489,13 +413,13 @@ namespace AzFramework { if (input->m_state == InputChannel::State::Began) { - m_translation |= TranslationFromKey(input->m_channelId); + m_translation |= TranslationFromKey(input->m_channelId, m_translateCameraInputChannels); if (m_translation != TranslationType::Nil) { BeginActivation(); } - if (input->m_channelId == CameraTranslateBoostId) + if (input->m_channelId == m_translateCameraInputChannels.m_boostChannelId) { m_boost = true; } @@ -503,12 +427,12 @@ namespace AzFramework // ensure we don't process end events in the idle state else if (input->m_state == InputChannel::State::Ended && !Idle()) { - m_translation &= ~(TranslationFromKey(input->m_channelId)); + m_translation &= ~(TranslationFromKey(input->m_channelId, m_translateCameraInputChannels)); if (m_translation == TranslationType::Nil) { EndActivation(); } - if (input->m_channelId == CameraTranslateBoostId) + if (input->m_channelId == m_translateCameraInputChannels.m_boostChannelId) { m_boost = false; } @@ -580,11 +504,16 @@ namespace AzFramework m_boost = false; } + OrbitCameraInput::OrbitCameraInput(const InputChannelId& orbitChannelId) + : m_orbitChannelId(orbitChannelId) + { + } + bool OrbitCameraInput::HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, const float scrollDelta) { if (const auto* input = AZStd::get_if(&event)) { - if (input->m_channelId == CameraOrbitId) + if (input->m_channelId == m_orbitChannelId) { if (input->m_state == InputChannel::State::Began) { @@ -697,7 +626,7 @@ namespace AzFramework return nextCamera; } - OrbitDollyCursorMoveCameraInput::OrbitDollyCursorMoveCameraInput(const InputChannelId dollyChannelId) + OrbitDollyCursorMoveCameraInput::OrbitDollyCursorMoveCameraInput(const InputChannelId& dollyChannelId) : m_dollyChannelId(dollyChannelId) { m_cursorSpeedFn = []() constexpr diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h index 1ec84475b5..da4a78f479 100644 --- a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h +++ b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h @@ -18,9 +18,6 @@ namespace AzFramework { - //! Updates camera key bindings that can be overridden with AZ console vars (invoke from console to update). - void ReloadCameraKeyBindings(); - //! Returns Euler angles (pitch, roll, yaw) for the incoming orientation. //! @note Order of rotation is Z, Y, X. AZ::Vector3 EulerAngles(const AZ::Matrix3x3& orientation); @@ -276,7 +273,7 @@ namespace AzFramework class RotateCameraInput : public CameraInput { public: - explicit RotateCameraInput(InputChannelId rotateChannelId); + explicit RotateCameraInput(const InputChannelId& rotateChannelId); // CameraInput overrides ... bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; @@ -327,7 +324,7 @@ namespace AzFramework class PanCameraInput : public CameraInput { public: - PanCameraInput(InputChannelId panChannelId, PanAxesFn panAxesFn); + PanCameraInput(const InputChannelId& panChannelId, PanAxesFn panAxesFn); // CameraInput overrides ... bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; @@ -373,11 +370,24 @@ namespace AzFramework return AZ::Matrix3x3::CreateFromColumns(basisX, basisY, basisZ); } + //! Groups all camera translation inputs. + struct TranslateCameraInputChannels + { + InputChannelId m_forwardChannelId; + InputChannelId m_backwardChannelId; + InputChannelId m_leftChannelId; + InputChannelId m_rightChannelId; + InputChannelId m_downChannelId; + InputChannelId m_upChannelId; + InputChannelId m_boostChannelId; + }; + //! A camera input to handle discrete events that can translate the camera (translate in three axes). class TranslateCameraInput : public CameraInput { public: - explicit TranslateCameraInput(TranslationAxesFn translationAxesFn); + explicit TranslateCameraInput( + TranslationAxesFn translationAxesFn, const TranslateCameraInputChannels& translateCameraInputChannels); // CameraInput overrides ... bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; @@ -444,10 +454,12 @@ namespace AzFramework } //! Converts from a generic input channel id to a concrete translation type (based on the user's key mappings). - static TranslationType TranslationFromKey(InputChannelId channelId); + TranslationType TranslationFromKey( + const InputChannelId& channelId, const TranslateCameraInputChannels& translateCameraInputChannels); TranslationType m_translation = TranslationType::Nil; //!< Types of translation the camera input is under. TranslationAxesFn m_translationAxesFn; //!< Builder for translation axes. + TranslateCameraInputChannels m_translateCameraInputChannels; //!< Input channel ids that map to internal translation types. bool m_boost = false; //!< Is the translation speed currently being multiplied/scaled upwards. }; @@ -468,7 +480,7 @@ namespace AzFramework class OrbitDollyCursorMoveCameraInput : public CameraInput { public: - explicit OrbitDollyCursorMoveCameraInput(InputChannelId dollyChannelId); + explicit OrbitDollyCursorMoveCameraInput(const InputChannelId& dollyChannelId); // CameraInput overrides ... bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; @@ -500,6 +512,8 @@ namespace AzFramework public: using LookAtFn = AZStd::function(const AZ::Vector3& position, const AZ::Vector3& direction)>; + explicit OrbitCameraInput(const InputChannelId& orbitChannelId); + // CameraInput overrides ... bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; @@ -511,6 +525,7 @@ namespace AzFramework void SetLookAtFn(const LookAtFn& lookAtFn); private: + InputChannelId m_orbitChannelId; //!< Input channel to begin the orbit camera input. LookAtFn m_lookAtFn; //!< The look-at behavior to use for this orbit camera (how is the look-at point calculated/retrieved). }; diff --git a/Code/Framework/Tests/CameraInputTests.cpp b/Code/Framework/Tests/CameraInputTests.cpp index 0639c2582a..77ae6fe9be 100644 --- a/Code/Framework/Tests/CameraInputTests.cpp +++ b/Code/Framework/Tests/CameraInputTests.cpp @@ -32,16 +32,25 @@ namespace UnitTest { AllocatorsTestFixture::SetUp(); - AzFramework::ReloadCameraKeyBindings(); - m_cameraSystem = AZStd::make_shared(); - m_firstPersonRotateCamera = AZStd::make_shared(AzFramework::InputDeviceMouse::Button::Right); - m_firstPersonTranslateCamera = AZStd::make_shared(AzFramework::LookTranslation); + m_translateCameraInputChannels.m_leftChannelId = AzFramework::InputChannelId("keyboard_key_alphanumeric_A"); + m_translateCameraInputChannels.m_rightChannelId = AzFramework::InputChannelId("keyboard_key_alphanumeric_D"); + m_translateCameraInputChannels.m_forwardChannelId = AzFramework::InputChannelId("keyboard_key_alphanumeric_W"); + m_translateCameraInputChannels.m_backwardChannelId = AzFramework::InputChannelId("keyboard_key_alphanumeric_S"); + m_translateCameraInputChannels.m_upChannelId = AzFramework::InputChannelId("keyboard_key_alphanumeric_E"); + m_translateCameraInputChannels.m_downChannelId = AzFramework::InputChannelId("keyboard_key_alphanumeric_Q"); + m_translateCameraInputChannels.m_boostChannelId = AzFramework::InputChannelId("keyboard_key_modifier_shift_l"); - auto orbitCamera = AZStd::make_shared(); + m_firstPersonRotateCamera = AZStd::make_shared(AzFramework::InputDeviceMouse::Button::Right); + m_firstPersonTranslateCamera = + AZStd::make_shared(AzFramework::LookTranslation, m_translateCameraInputChannels); + + auto orbitCamera = + AZStd::make_shared(AzFramework::InputChannelId("keyboard_key_modifier_alt_l")); auto orbitRotateCamera = AZStd::make_shared(AzFramework::InputDeviceMouse::Button::Left); - auto orbitTranslateCamera = AZStd::make_shared(AzFramework::OrbitTranslation); + auto orbitTranslateCamera = + AZStd::make_shared(AzFramework::OrbitTranslation, m_translateCameraInputChannels); orbitCamera->m_orbitCameras.AddCamera(orbitRotateCamera); orbitCamera->m_orbitCameras.AddCamera(orbitTranslateCamera); @@ -62,11 +71,12 @@ namespace UnitTest AllocatorsTestFixture::TearDown(); } + AzFramework::TranslateCameraInputChannels m_translateCameraInputChannels; AZStd::shared_ptr m_firstPersonRotateCamera; AZStd::shared_ptr m_firstPersonTranslateCamera; }; - TEST_F(CameraInputFixture, Begin_and_end_orbit_camera_consumes_correct_events) + TEST_F(CameraInputFixture, Begin_and_end_OrbitCameraInput_consumes_correct_events) { // begin orbit camera const bool consumed1 = HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ AzFramework::InputDeviceKeyboard::Key::ModifierAltL, @@ -86,7 +96,7 @@ namespace UnitTest EXPECT_THAT(allConsumed, ElementsAre(true, false, true, false)); } - TEST_F(CameraInputFixture, Begin_camera_input_notifies_activation_began_callback_for_translate_camera) + TEST_F(CameraInputFixture, Begin_CameraInput_notifies_ActivationBeganFn_for_TranslateCameraInput) { bool activationBegan = false; m_firstPersonTranslateCamera->SetActivationBeganFn( @@ -95,13 +105,13 @@ namespace UnitTest activationBegan = true; }); - HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ AzFramework::InputDeviceKeyboard::Key::AlphanumericW, - AzFramework::InputChannel::State::Began }); + HandleEventAndUpdate( + AzFramework::DiscreteInputEvent{ m_translateCameraInputChannels.m_forwardChannelId, AzFramework::InputChannel::State::Began }); EXPECT_TRUE(activationBegan); } - TEST_F(CameraInputFixture, Begin_camera_input_notifies_activation_began_callback_after_delta_for_rotate_camera) + TEST_F(CameraInputFixture, Begin_CameraInput_notifies_ActivationBeganFn_after_delta_for_RotateCameraInput) { bool activationBegan = false; m_firstPersonRotateCamera->SetActivationBeganFn( @@ -117,7 +127,7 @@ namespace UnitTest EXPECT_TRUE(activationBegan); } - TEST_F(CameraInputFixture, Begin_camera_input_does_not_notify_activation_began_callback_with_no_delta_for_rotate_camera) + TEST_F(CameraInputFixture, Begin_CameraInput_does_not_notify_ActivationBeganFn_with_no_delta_for_RotateCameraInput) { bool activationBegan = false; m_firstPersonRotateCamera->SetActivationBeganFn( @@ -132,7 +142,7 @@ namespace UnitTest EXPECT_FALSE(activationBegan); } - TEST_F(CameraInputFixture, End_camera_input_notifies_activation_end_callback_after_delta_for_rotate_camera) + TEST_F(CameraInputFixture, End_CameraInput_notifies_ActivationEndFn_after_delta_for_RotateCameraInput) { bool activationEnded = false; m_firstPersonRotateCamera->SetActivationEndedFn( @@ -150,7 +160,7 @@ namespace UnitTest EXPECT_TRUE(activationEnded); } - TEST_F(CameraInputFixture, End_camera_input_does_not_notify_activation_began_or_end_callback_with_no_delta_for_rotate_camera) + TEST_F(CameraInputFixture, End_CameraInput_does_not_notify_ActivationBeganFn_or_ActivationBeganFn_with_no_delta_for_RotateCameraInput) { bool activationBegan = false; m_firstPersonRotateCamera->SetActivationBeganFn( @@ -175,7 +185,7 @@ namespace UnitTest EXPECT_FALSE(activationEnded); } - TEST_F(CameraInputFixture, End_camera_input_notifies_activation_began_or_end_callback_with_translate_camera) + TEST_F(CameraInputFixture, End_CameraInput_notifies_ActivationBeganFn_or_ActivationEndFn_with_TranslateCamera) { bool activationBegan = false; m_firstPersonTranslateCamera->SetActivationBeganFn( @@ -191,16 +201,16 @@ namespace UnitTest activationEnded = true; }); - HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ AzFramework::InputDeviceKeyboard::Key::AlphanumericW, - AzFramework::InputChannel::State::Began }); - HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ AzFramework::InputDeviceKeyboard::Key::AlphanumericW, - AzFramework::InputChannel::State::Ended }); + HandleEventAndUpdate( + AzFramework::DiscreteInputEvent{ m_translateCameraInputChannels.m_forwardChannelId, AzFramework::InputChannel::State::Began }); + HandleEventAndUpdate( + AzFramework::DiscreteInputEvent{ m_translateCameraInputChannels.m_forwardChannelId, AzFramework::InputChannel::State::Ended }); EXPECT_TRUE(activationBegan); EXPECT_TRUE(activationEnded); } - TEST_F(CameraInputFixture, End_activation_called_for_camera_input_if_active_when_cameras_are_cleared) + TEST_F(CameraInputFixture, End_activation_called_for_CameraInput_if_active_when_cameras_are_cleared) { bool activationEnded = false; m_firstPersonTranslateCamera->SetActivationEndedFn( @@ -209,8 +219,8 @@ namespace UnitTest activationEnded = true; }); - HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ AzFramework::InputDeviceKeyboard::Key::AlphanumericW, - AzFramework::InputChannel::State::Began }); + HandleEventAndUpdate( + AzFramework::DiscreteInputEvent{ m_translateCameraInputChannels.m_forwardChannelId, AzFramework::InputChannel::State::Began }); m_cameraSystem->m_cameras.Clear(); From 17fde4e228120041908d79ccd317bb30253359f1 Mon Sep 17 00:00:00 2001 From: John Date: Mon, 5 Jul 2021 14:56:48 +0100 Subject: [PATCH 02/11] Move source of truth logic from TIAF to job --- .../ConsoleFrontendConfig.in | 4 -- scripts/build/Jenkins/Jenkinsfile | 15 ++++- .../build/Platform/Windows/build_config.json | 7 +- scripts/build/TestImpactAnalysis/tiaf.py | 66 ++++++++++++------- .../build/TestImpactAnalysis/tiaf_driver.py | 6 +- 5 files changed, 61 insertions(+), 37 deletions(-) diff --git a/cmake/TestImpactFramework/ConsoleFrontendConfig.in b/cmake/TestImpactFramework/ConsoleFrontendConfig.in index ffd24ffb72..e4111fb9cd 100644 --- a/cmake/TestImpactFramework/ConsoleFrontendConfig.in +++ b/cmake/TestImpactFramework/ConsoleFrontendConfig.in @@ -4,10 +4,6 @@ "timestamp": "${timestamp}" }, "jenkins": { - "pipeline_of_truth" : [ - "nightly-incremental", - "nightly-clean" - ], "use_test_impact_analysis": ${use_tiaf} }, "repo": { diff --git a/scripts/build/Jenkins/Jenkinsfile b/scripts/build/Jenkins/Jenkinsfile index 8ac9353aea..3567267eab 100644 --- a/scripts/build/Jenkins/Jenkinsfile +++ b/scripts/build/Jenkins/Jenkinsfile @@ -13,8 +13,17 @@ EMPTY_JSON = readJSON text: '{}' ENGINE_REPOSITORY_NAME = 'o3de' -BUILD_SNAPSHOTS = ['development', 'stabilization/2106', ''] -DEFAULT_BUILD_SNAPSHOT = BUILD_SNAPSHOTS.get(0) +// Branches with build snapshots +BUILD_SNAPSHOTS = ['development', 'stabilization/2106'] + +// Build snapshots with empty snapshot (for use with 'SNAPSHOT' pipeline paramater) +BUILD_SNAPSHOTS_WITH_EMPTY = BUILD_SNAPSHOTS + '' + +// The default build snapshot to be selected in the 'SNAPSHOT' pipeline paramater +DEFAULT_BUILD_SNAPSHOT = BUILD_SNAPSHOTS_WITH_EMPTY.get(0) + +// Branches with build snapshots as comma separated value string +env.BUILD_SNAPSHOTS = BUILD_SNAPSHOTS.join(",") def pipelineProperties = [] @@ -476,7 +485,7 @@ try { } } else { // Non-PR builds - pipelineParameters.add(choice(defaultValue: DEFAULT_BUILD_SNAPSHOT, name: 'SNAPSHOT', choices: BUILD_SNAPSHOTS, description: 'Selects the build snapshot to use. A more diverted snapshot will cause longer build times, but will not cause build failures.')) + pipelineParameters.add(choice(defaultValue: DEFAULT_BUILD_SNAPSHOT, name: 'SNAPSHOT', choices: BUILD_SNAPSHOTS_WITH_EMPTY, description: 'Selects the build snapshot to use. A more diverted snapshot will cause longer build times, but will not cause build failures.')) snapshot = env.SNAPSHOT echo "Snapshot \"${snapshot}\" selected." } diff --git a/scripts/build/Platform/Windows/build_config.json b/scripts/build/Platform/Windows/build_config.json index 07e0e54bf5..b210d0bfb8 100644 --- a/scripts/build/Platform/Windows/build_config.json +++ b/scripts/build/Platform/Windows/build_config.json @@ -27,9 +27,7 @@ }, "profile_vs2019_pipe": { "TAGS": [ - "default", - "nightly-incremental", - "nightly-clean" + "default" ], "steps": [ "profile_vs2019", @@ -90,7 +88,8 @@ "OUTPUT_DIRECTORY": "build/windows_vs2019", "CONFIGURATION": "profile", "SCRIPT_PATH": "scripts/build/TestImpactAnalysis/tiaf_driver.py", - "SCRIPT_PARAMETERS": "--testFailurePolicy=continue --suite main --pipeline !PIPELINE_NAME! --destCommit !CHANGE_ID! --config \"!OUTPUT_DIRECTORY!/bin/TestImpactFramework/persistent/tiaf.profile.json\"" + "SCRIPT_PARAMETERS": + "--config=\"!OUTPUT_DIRECTORY!/bin/TestImpactFramework/persistent/tiaf.profile.json\" --suite=main --testFailurePolicy=continue --destBranch=!CHANGE_TARGET! --pipeline=!PIPELINE_NAME! --destCommit=!CHANGE_ID! --branchesOfTruth=!BUILD_SNAPSHOTS! --pipelinesOfTruth=default" } }, "debug_vs2019": { diff --git a/scripts/build/TestImpactAnalysis/tiaf.py b/scripts/build/TestImpactAnalysis/tiaf.py index 40158f8432..7d071138aa 100644 --- a/scripts/build/TestImpactAnalysis/tiaf.py +++ b/scripts/build/TestImpactAnalysis/tiaf.py @@ -20,33 +20,51 @@ def is_child_path(parent_path, child_path): return os.path.commonpath([os.path.abspath(parent_path)]) == os.path.commonpath([os.path.abspath(parent_path), os.path.abspath(child_path)]) class TestImpact: - def __init__(self, config_file, pipeline, dst_commit): - self.__pipeline = pipeline + def __init__(self, config_file, dst_commit, dst_branch, pipeline, branches_of_truth, pipelines_of_truth): + # Commit self.__dst_commit = dst_commit + print(f"Commit: '{self.__dst_commit}'.") self.__src_commit = None self.__has_src_commit = False + # Branch + self.__dst_branch = dst_branch + print(f"Destination branch: '{self.__dst_branch}'.") + self.__branches_of_truth = branches_of_truth + print(f"Branches of truth: '{self.__branches_of_truth}'.") + if self.__dst_branch in self.__branches_of_truth: + self.__is_branch_of_truth = True + else: + self.__is_branch_of_truth = False + print(f"Is branch of truth: '{self.__is_branch_of_truth}'.") + # Pipeline + self.__pipeline = pipeline + print(f"Pipeline: '{self.__pipeline}'.") + self.__pipelines_of_truth = pipelines_of_truth + print(f"Pipelines of truth: '{self.__pipelines_of_truth}'.") + if self.__pipeline in self.__pipelines_of_truth: + self.__is_pipeline_of_truth = True + else: + self.__is_pipeline_of_truth = False + print(f"Is pipeline of truth: '{self.__is_pipeline_of_truth}'.") + # Config self.__parse_config_file(config_file) - if self.__use_test_impact_analysis and not self.__is_pipeline_of_truth: - self.__generate_change_list() + # Sequence + if self.__use_test_impact_analysis: + if self.__is_pipeline_of_truth and self.__is_branch_of_truth: + self.__is_seeding = True + else: + self.__is_seeding = False + self.__generate_change_list() # Parse the configuration file and retrieve the data needed for launching the test impact analysis runtime def __parse_config_file(self, config_file): print(f"Attempting to parse configuration file '{config_file}'...") with open(config_file, "r") as config_data: config = json.load(config_data) - # Repository self.__repo_dir = config["repo"]["root"] - # Jenkins + self.__repo = Repo(self.__repo_dir) + # TIAF self.__use_test_impact_analysis = config["jenkins"]["use_test_impact_analysis"] - self.__pipeline_of_truth = config["jenkins"]["pipeline_of_truth"] - print(f"Pipeline of truth: '{self.__pipeline_of_truth}'.") - print(f"This pipeline: '{self.__pipeline}'.") - if self.__pipeline in self.__pipeline_of_truth: - self.__is_pipeline_of_truth = True - else: - self.__is_pipeline_of_truth = False - print(f"Is pipeline of truth: '{self.__is_pipeline_of_truth}'.") - # TIAF binary self.__tiaf_bin = config["repo"]["tiaf_bin"] if self.__use_test_impact_analysis and not os.path.isfile(self.__tiaf_bin): raise FileNotFoundError("Could not find tiaf binary") @@ -143,7 +161,7 @@ class TestImpact: # Runs the specified test sequence def run(self, suite, test_failure_policy, safe_mode, test_timeout, global_timeout): args = [] - pipeline_of_truth_test_failure_policy = "continue" + seed_sequence_test_failure_policy = "continue" # Suite args.append(f"--suite={suite}") print(f"Test suite is set to '{suite}'.") @@ -156,15 +174,15 @@ class TestImpact: print(f"Global sequence timeout is set to {test_timeout} seconds.") if self.__use_test_impact_analysis: print("Test impact analysis is enabled.") - # Pipeline of truth sequence - if self.__is_pipeline_of_truth: + # Seed sequences + if self.__is_seeding: # Sequence type args.append("--sequence=seed") print("Sequence type is set to 'seed'.") # Test failure policy - args.append(f"--fpolicy={pipeline_of_truth_test_failure_policy}") - print(f"Test failure policy is set to '{pipeline_of_truth_test_failure_policy}'.") - # Non pipeline of truth sequence + args.append(f"--fpolicy={seed_sequence_test_failure_policy}") + print(f"Test failure policy is set to '{seed_sequence_test_failure_policy}'.") + # Impact analysis sequences else: if self.__has_change_list: # Change list @@ -194,8 +212,8 @@ class TestImpact: # Pipeline of truth sequence if self.__is_pipeline_of_truth: # Test failure policy - args.append(f"--fpolicy={pipeline_of_truth_test_failure_policy}") - print(f"Test failure policy is set to '{pipeline_of_truth_test_failure_policy}'.") + args.append(f"--fpolicy={seed_sequence_test_failure_policy}") + print(f"Test failure policy is set to '{seed_sequence_test_failure_policy}'.") # Non pipeline of truth sequence else: # Test failure policy @@ -205,7 +223,7 @@ class TestImpact: print("Args: ", end='') print(*args) result = subprocess.run([self.__tiaf_bin] + args) - # If the sequence completed 9with or without failures) we will update the historical meta-data + # If the sequence completed (with or without failures) we will update the historical meta-data if result.returncode == 0 or result.returncode == 7: print("Test impact analysis runtime returned successfully.") if self.__is_pipeline_of_truth: diff --git a/scripts/build/TestImpactAnalysis/tiaf_driver.py b/scripts/build/TestImpactAnalysis/tiaf_driver.py index e346feaadd..3c8ec4b32a 100644 --- a/scripts/build/TestImpactAnalysis/tiaf_driver.py +++ b/scripts/build/TestImpactAnalysis/tiaf_driver.py @@ -35,14 +35,16 @@ def parse_args(): parser = argparse.ArgumentParser() parser.add_argument('--config', dest="config", type=file_path, help="Path to the test impact analysis framework configuration file", required=True) + parser.add_argument('--destBranch', dest="dst_branch", help="For PR builds, the destination branch to be merged to, otherwise empty") + parser.add_argument('--branchesOfTruth', dest="branches_of_truth", type=lambda arg: arg.split(','), help="Comma separated branches that seeding will occur on", required=True) parser.add_argument('--pipeline', dest="pipeline", help="Pipeline the test impact analysis framework is running on", required=True) + parser.add_argument('--pipelinesOfTruth', dest="pipelines_of_truth", type=lambda arg: arg.split(','), help="Comma separated pipeline that seeding will occur on", required=True) parser.add_argument('--destCommit', dest="dst_commit", help="Commit to run test impact analysis on (ignored when seeding)", required=True) parser.add_argument('--suite', dest="suite", help="Test suite to run", required=True) parser.add_argument('--testFailurePolicy', dest="test_failure_policy", type=test_failure_policy, help="Test failure policy for regular and test impact sequences (ignored when seeding)", required=True) parser.add_argument('--safeMode', dest="safe_mode", action='store_true', help="Run impact analysis tests in safe mode (ignored when seeding)") parser.add_argument('--testTimeout', dest="test_timeout", type=timout_type, help="Maximum run time (in seconds) of any test target before being terminated", required=False) parser.add_argument('--globalTimeout', dest="global_timeout", type=timout_type, help="Maximum run time of the sequence before being terminated", required=False) - parser.set_defaults(test_failure_policy="abort") parser.set_defaults(test_timeout=None) parser.set_defaults(global_timeout=None) args = parser.parse_args() @@ -52,7 +54,7 @@ def parse_args(): if __name__ == "__main__": try: args = parse_args() - tiaf = TestImpact(args.config, args.pipeline, args.dst_commit) + tiaf = TestImpact(args.config, args.dst_commit, args.dst_branch, args.pipeline, args.branches_of_truth, args.pipelines_of_truth) return_code = tiaf.run(args.suite, args.test_failure_policy, args.safe_mode, args.test_timeout, args.global_timeout) # Non-gating will be removed from this script and handled at the job level in SPEC-7413 #sys.exit(return_code) From 0d7d507889ab41a2017e2250c4ed49dc315df308 Mon Sep 17 00:00:00 2001 From: John Date: Mon, 5 Jul 2021 14:58:25 +0100 Subject: [PATCH 03/11] Fix instrumented non-gtests treated as failures --- .../Run/TestImpactInstrumentedTestRunner.cpp | 38 +++++++++------- .../Run/TestImpactInstrumentedTestRunner.h | 4 +- .../TestImpactTestEngineInstrumentedRun.cpp | 10 +++-- .../TestImpactTestEngineInstrumentedRun.h | 2 +- .../Runtime/Code/Source/TestImpactRuntime.cpp | 43 +++++++++++++------ 5 files changed, 62 insertions(+), 35 deletions(-) diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/Run/TestImpactInstrumentedTestRunner.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/Run/TestImpactInstrumentedTestRunner.cpp index 72f77cae96..4553219e37 100644 --- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/Run/TestImpactInstrumentedTestRunner.cpp +++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/Run/TestImpactInstrumentedTestRunner.cpp @@ -28,17 +28,6 @@ namespace TestImpact return m_coverageArtifact; } - InstrumentedTestRunner::JobPayload ParseTestRunAndCoverageFiles( - const RepoPath& runFile, - const RepoPath& coverageFile, - AZStd::chrono::milliseconds duration) - { - TestRun run(GTest::TestRunSuitesFactory(ReadFileContents(runFile)), duration); - AZStd::vector moduleCoverages = Cobertura::ModuleCoveragesFactory(ReadFileContents(coverageFile)); - TestCoverage coverage(AZStd::move(moduleCoverages)); - return {AZStd::move(run), AZStd::move(coverage)}; - } - InstrumentedTestRunner::InstrumentedTestRunner(size_t maxConcurrentRuns) : JobRunner(maxConcurrentRuns) { @@ -58,16 +47,35 @@ namespace TestImpact const auto& [meta, jobInfo] = jobData; if (meta.m_result == JobResult::ExecutedWithSuccess || meta.m_result == JobResult::ExecutedWithFailure) { + const auto printException = [](const Exception& e) + { + AZ_Printf("RunInstrumentedTests", AZStd::string::format("%s\n.", e.what()).c_str()); + }; + + AZStd::optional run; try { - runs[jobId] = ParseTestRunAndCoverageFiles( - jobInfo->GetRunArtifactPath(), - jobInfo->GetCoverageArtifactPath(), + run = TestRun( + GTest::TestRunSuitesFactory(ReadFileContents(jobInfo->GetRunArtifactPath())), meta.m_duration.value()); } catch (const Exception& e) { - AZ_Printf("RunInstrumentedTests", AZStd::string::format("%s\n", e.what()).c_str()); + // No run result is not necessarily a failure (e.g. test targets not using gtest) + printException(e); + } + + try + { + AZStd::vector moduleCoverages = + Cobertura::ModuleCoveragesFactory(ReadFileContents(jobInfo->GetCoverageArtifactPath())); + TestCoverage coverage(AZStd::move(moduleCoverages)); + runs[jobId] = { run, AZStd::move(coverage) }; + } + catch (const Exception& e) + { + printException(e); + // No coverage, however, is a failure runs[jobId] = AZStd::nullopt; } } diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/Run/TestImpactInstrumentedTestRunner.h b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/Run/TestImpactInstrumentedTestRunner.h index fb931024d6..caea4591a4 100644 --- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/Run/TestImpactInstrumentedTestRunner.h +++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/Run/TestImpactInstrumentedTestRunner.h @@ -30,9 +30,9 @@ namespace TestImpact //! Runs a batch of test targets to determine the test coverage and passes/failures. class InstrumentedTestRunner - : public TestJobRunner> + : public TestJobRunner, TestCoverage>> { - using JobRunner = TestJobRunner>; + using JobRunner = TestJobRunner, TestCoverage>>; public: //! Constructs an instrumented test runner with the specified parameters common to all job runs of this runner. diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngineInstrumentedRun.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngineInstrumentedRun.cpp index 63f0e60dcc..e1e230b3a7 100644 --- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngineInstrumentedRun.cpp +++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngineInstrumentedRun.cpp @@ -13,9 +13,9 @@ namespace TestImpact { namespace { - AZStd::optional ReleaseTestRun(AZStd::optional>& testRunAndCoverage) + AZStd::optional ReleaseTestRun(AZStd::optional, TestCoverage>>& testRunAndCoverage) { - if (testRunAndCoverage.has_value()) + if (testRunAndCoverage.has_value() && testRunAndCoverage.has_value()) { return AZStd::move(testRunAndCoverage.value().first); } @@ -23,7 +23,8 @@ namespace TestImpact return AZStd::nullopt; } - AZStd::optional ReleaseTestCoverage(AZStd::optional>& testRunAndCoverage) + AZStd::optional ReleaseTestCoverage( + AZStd::optional, TestCoverage>>& testRunAndCoverage) { if (testRunAndCoverage.has_value()) { @@ -34,7 +35,8 @@ namespace TestImpact } } - TestEngineInstrumentedRun::TestEngineInstrumentedRun(TestEngineJob&& testJob, AZStd::optional>&& testRunAndCoverage) + TestEngineInstrumentedRun::TestEngineInstrumentedRun( + TestEngineJob&& testJob, AZStd::optional, TestCoverage>>&& testRunAndCoverage) : TestEngineRegularRun(AZStd::move(testJob), ReleaseTestRun(testRunAndCoverage)) , m_testCoverage(ReleaseTestCoverage(testRunAndCoverage)) { diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngineInstrumentedRun.h b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngineInstrumentedRun.h index 801cfc0072..23ea356e40 100644 --- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngineInstrumentedRun.h +++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngineInstrumentedRun.h @@ -17,7 +17,7 @@ namespace TestImpact : public TestEngineRegularRun { public: - TestEngineInstrumentedRun(TestEngineJob&& testJob, AZStd::optional>&& testRunAndCoverage); + TestEngineInstrumentedRun(TestEngineJob&& testJob, AZStd::optional, TestCoverage>>&& testRunAndCoverage); //! Returns the test coverage payload for this job (if any). const AZStd::optional& GetTestCoverge() const; diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntime.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntime.cpp index ca3ade957e..7ec8fb549d 100644 --- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntime.cpp +++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntime.cpp @@ -22,6 +22,8 @@ namespace TestImpact { namespace { + static const char* const LogCallSite = "TestImpact"; + //! Simple helper class for tracking basic timing information. class Timer { @@ -149,7 +151,8 @@ namespace TestImpact } catch ([[maybe_unused]]const Exception& e) { - AZ_Printf("TestImpactRuntime", + AZ_Printf( + LogCallSite, AZStd::string::format( "No test impact analysis data found for suite '%s' at %s\n", GetSuiteTypeName(m_suiteFilter).c_str(), m_sparTIAFile.c_str()).c_str()); } @@ -283,8 +286,8 @@ namespace TestImpact job.GetTestCoverge().has_value(), RuntimeException, AZStd::string::format( - "Test target '%s' completed its test run successfully but produced no coverage data", - job.GetTestTarget()->GetName().c_str())); + "Test target '%s' completed its test run successfully but produced no coverage data. Command string: '%s'", + job.GetTestTarget()->GetName().c_str(), job.GetCommandString().c_str())); } if (!job.GetTestCoverge().has_value()) @@ -313,7 +316,7 @@ namespace TestImpact } else { - AZ_Warning("TestImpact", false, "Ignoring source, source it outside of repo: '%s'", sourcePath.c_str()); + AZ_Warning(LogCallSite, false, "Ignoring source, source it outside of repo: '%s'", sourcePath.c_str()); } } @@ -322,17 +325,31 @@ namespace TestImpact void Runtime::UpdateAndSerializeDynamicDependencyMap(const AZStd::vector& jobs) { - const auto sourceCoverageTestsList = CreateSourceCoveringTestFromTestCoverages(jobs); - if (!sourceCoverageTestsList.GetNumSources()) + try { - return; - } + const auto sourceCoverageTestsList = CreateSourceCoveringTestFromTestCoverages(jobs); + if (!sourceCoverageTestsList.GetNumSources()) + { + return; + } - m_dynamicDependencyMap->ReplaceSourceCoverage(sourceCoverageTestsList); - const auto sparTIA = m_dynamicDependencyMap->ExportSourceCoverage(); - const auto sparTIAData = SerializeSourceCoveringTestsList(sparTIA); - WriteFileContents(sparTIAData, m_sparTIAFile); - m_hasImpactAnalysisData = true; + m_dynamicDependencyMap->ReplaceSourceCoverage(sourceCoverageTestsList); + const auto sparTIA = m_dynamicDependencyMap->ExportSourceCoverage(); + const auto sparTIAData = SerializeSourceCoveringTestsList(sparTIA); + WriteFileContents(sparTIAData, m_sparTIAFile); + m_hasImpactAnalysisData = true; + } + catch(const RuntimeException& e) + { + if (m_integrationFailurePolicy == Policy::IntegrityFailure::Abort) + { + throw e; + } + else + { + AZ_Error("TestImpact", false, e.what()); + } + } } TestSequenceResult Runtime::RegularTestSequence( From b63468d95e2edc20d13f6a8fc1560fc69b1ee518 Mon Sep 17 00:00:00 2001 From: John Date: Mon, 5 Jul 2021 14:58:42 +0100 Subject: [PATCH 04/11] Fix API comments --- .../Runtime/Code/Source/Dependency/TestImpactSourceDependency.h | 2 +- .../Runtime/Code/Source/Target/TestImpactBuildTargetList.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactSourceDependency.h b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactSourceDependency.h index 0d56c0ac33..d32988bf44 100644 --- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactSourceDependency.h +++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactSourceDependency.h @@ -43,7 +43,7 @@ namespace TestImpact namespace AZStd { - //! Hash function for ParentTarget types for use in maps and sets + //! Hash function for ParentTarget types for use in maps and sets. template<> struct hash { size_t operator()(const TestImpact::ParentTarget& parentTarget) const noexcept diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Target/TestImpactBuildTargetList.h b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Target/TestImpactBuildTargetList.h index 4407cb6fa4..cec7bda2e6 100644 --- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Target/TestImpactBuildTargetList.h +++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Target/TestImpactBuildTargetList.h @@ -40,7 +40,7 @@ namespace TestImpact //! Returns true if the specified target is in the list, otherwise false. bool HasTarget(const AZStd::string& name) const; - // Returns the number of targets in the list. + //! Returns the number of targets in the list. size_t GetNumTargets() const; private: From 2003d81aba655c1f1ddb29c527cb5350f8c1599d Mon Sep 17 00:00:00 2001 From: John Date: Mon, 5 Jul 2021 15:05:17 +0100 Subject: [PATCH 05/11] Fix missing log call site --- .../Runtime/Code/Source/TestImpactRuntime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntime.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntime.cpp index 7ec8fb549d..b222f12d5a 100644 --- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntime.cpp +++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntime.cpp @@ -347,7 +347,7 @@ namespace TestImpact } else { - AZ_Error("TestImpact", false, e.what()); + AZ_Error(LogCallSite, false, e.what()); } } } From f86708a812e78a4fc9ff4f10322b416e9fcf6924 Mon Sep 17 00:00:00 2001 From: John Date: Mon, 5 Jul 2021 15:28:20 +0100 Subject: [PATCH 06/11] Fix run payload checking logic --- .../Source/TestEngine/TestImpactTestEngineInstrumentedRun.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngineInstrumentedRun.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngineInstrumentedRun.cpp index e1e230b3a7..bade8fef81 100644 --- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngineInstrumentedRun.cpp +++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngineInstrumentedRun.cpp @@ -15,7 +15,7 @@ namespace TestImpact { AZStd::optional ReleaseTestRun(AZStd::optional, TestCoverage>>& testRunAndCoverage) { - if (testRunAndCoverage.has_value() && testRunAndCoverage.has_value()) + if (testRunAndCoverage.has_value() && testRunAndCoverage->first.has_value()) { return AZStd::move(testRunAndCoverage.value().first); } From c5a4fd382d82ed72764e2c34d466887a8d8fcc68 Mon Sep 17 00:00:00 2001 From: John Date: Mon, 5 Jul 2021 16:25:29 +0100 Subject: [PATCH 07/11] Address PR comments --- .../Runtime/Code/Source/TestImpactRuntime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntime.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntime.cpp index b222f12d5a..af6f02fa20 100644 --- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntime.cpp +++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntime.cpp @@ -328,7 +328,7 @@ namespace TestImpact try { const auto sourceCoverageTestsList = CreateSourceCoveringTestFromTestCoverages(jobs); - if (!sourceCoverageTestsList.GetNumSources()) + if (sourceCoverageTestsList.GetNumSources() == 0) { return; } From eb0b7346c4beaf98f01885d669b59a513aa22f51 Mon Sep 17 00:00:00 2001 From: Nicholas Lawson <70027408+lawsonamzn@users.noreply.github.com> Date: Tue, 6 Jul 2021 08:04:43 -0700 Subject: [PATCH 08/11] o3de development - update licenses (#1665) Not to be committed before 7/6/2021 Signed-off-by: lawsonamzn <70027408+lawsonamzn@users.noreply.github.com> --- LICENSE.txt | 51 +++++------ LICENSE_APACHE2.TXT | 201 ++++++++++++++++++++++++++++++++++++++++++++ LICENSE_MIT.TXT | 7 ++ README.md | 15 +--- 4 files changed, 238 insertions(+), 36 deletions(-) create mode 100644 LICENSE_APACHE2.TXT create mode 100644 LICENSE_MIT.TXT diff --git a/LICENSE.txt b/LICENSE.txt index 7748e6705a..c4315a87fe 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,26 +1,27 @@ -Amazon Project Spectra Private Preview -Copyright (c) 2016-2021 Amazon Technologies, Inc., its affiliates or licensors. All Rights Reserved. - -************************************* -CONFIDENTIAL - LIMITED RELEASE SOFTWARE - SUBJECT TO NONDISCLOSURE TERMS - -Project Spectra is a confidential, pre-release project. Without the prior written consent of Amazon, you may not disclose it or its existence to any third party that is not part of the Open 3D Engine project (each, a "Project Participant"). Please see the terms of your/your organization's nondisclosure agreement with Amazon for detailed terms. By accessing this software, you agree to these terms. - -Each Project Participant acknowledges that other Project Participants may now have, or in the future may develop or receive, information that is the same as, or similar to, Project Spectra without having breached an obligation of confidentiality to the other. Nothing in these terms (a) prevents a Project Participant from using, for any purpose and without compensating other Project Participants (or Amazon), information retained in the unaided memory of a Project Participant's personnel who have had access to Project Spectra or (b) obligates Project Participants to restrict the scope of employment of the Project Participant's Personnel; provided, however, that this section does not create a license under any copyright or patent of Amazon or any Project Participant. - -If you provide any suggestions, ideas, or other feedback in connection with Project Spectra ("Feedback"), all Project Participants will be entitled to use the Feedback without restriction. You agree to license any pull requests or other submissions of copyrighted material related to Project Spectra under the Apache 2.0 and MIT licenses. - -All materials are made available on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied. Do not remove or modify any license notices. - -************************************* +OPEN 3D ENGINE LICENSING +The default license for Open 3D Engine is the Apache License, Version 2.0 +(see LICENSE_APACHE2.TXT); you may elect at your option to use the Open 3D +Engine under the MIT License (see LICENSE_MIT.TXT). Contributions must be +made under both licenses. + THIRD PARTY COMPONENTS - -Project Spectra requires the use of and makes available to you software and assets that have been developed by third parties and are subject to separate license terms (such as code licensed under an open source license), including the materials provided in \3rdParty. It is your responsibility to obtain and comply with the applicable licenses, along with any platform policies that may apply to you. Information on third party materials, and the applicable license terms, are referenced in or included with the materials, such as in separate LICENSE.txt files accompanying the materials. - -Please note that certain materials are subject to "copyleft" licenses, which require distribution of source code, including: -- Qt Toolkit https://github.com/qtproject/, which is subject to the GNU Lesser General Public License version 3 (with certain exceptions, see \3rdParty\Qt\). A copy of the source code for Qt Toolkit may be found at https://s3-us-west-2.amazonaws.com/ly-legal/LicenseConformance/Qt/Src.zip -- Chardet https://chardet.github.io/, which is subject to the GNU Lesser General Public License version 2.1. A copy of the source code may be found in \3rdParty\AWS\AWSPythonSDK\1.2.1\botocore\vendored\requests\packages\. - -This software contains Autodesk(R) FBX(R) code developed by Autodesk, Inc. Copyright 2013 Autodesk, Inc. All rights, reserved. Such code is provided "as is" and Autodesk, Inc. disclaims any and all warranties, whether express or implied, including without limitation the implied warranties of merchantability, fitness for a particular purpose or non-infringement of third party rights. In no event shall Autodesk, Inc. be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of such code. - -This product includes components of the PowerVR Tools Software from Imagination Technologies Limited. +Open 3D Engine requires the use of (and in some cases makes available to you) +software and assets that have been developed by third parties and are subject +to separate license terms (such as code licensed under other open source +licenses). It is your responsibility to comply with the applicable licenses. +Information on third party materials, and the applicable license terms, are +referenced in or included with the materials, such as in separate LICENSE.txt +files accompanying the materials. + +Please note that certain materials are subject to "copyleft" licenses, which +require distribution of source code, including: + +- Qt Toolkit https://github.com/qtproject/, which is subject to the GNU +Lesser General Public License version 3 (with certain exceptions). A copy of +the source code for Qt Toolkit may be found at +https://s3-us-west-2.amazonaws.com/ly-legal/LicenseConformance/Qt/Src.zip + +- The AWS Python SDK uses Chardet https://chardet.github.io/, which is +subject to the GNU Lesser General Public License version 2.1. A copy of the +source code may be found at https://github.com/chardet/chardet. + \ No newline at end of file diff --git a/LICENSE_APACHE2.TXT b/LICENSE_APACHE2.TXT new file mode 100644 index 0000000000..b7a7d6c0e5 --- /dev/null +++ b/LICENSE_APACHE2.TXT @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/LICENSE_MIT.TXT b/LICENSE_MIT.TXT new file mode 100644 index 0000000000..1b16d6d320 --- /dev/null +++ b/LICENSE_MIT.TXT @@ -0,0 +1,7 @@ +Copyright Contributors to the Open 3D Engine + +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. \ No newline at end of file diff --git a/README.md b/README.md index 7a9751529f..9cc816efe9 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,7 @@ -# Project Spectra Private Preview - -## Confidentiality; Pre-Release Access - -Welcome to the Project Spectra Private Preview. This is a confidential pre-release project; your use is subject to the nondisclosure agreement between you (or your organization) and Amazon. Do not disclose the existence of this project, your participation in it, or any of the materials provided, to any unauthorized third party. To request access for a third party, please contact [Royal O'Brien, obriroya@amazon.com](mailto:obriroya@amazon.com). - -## Full instructions can be found here: -### https://docs.o3de.org/docs/welcome-guide/setup/setup-from-github/ -(Note: Contact Royal or [Doug Erickson, dougeric@amazon.com](mailto:dougeric@amazon.com) for access) - ## Updates to this readme +July 06, 2021 +- Switch licenses to APACHE-2.0 OR MIT + May 14, 2021 - Removed instructions for the 3rdParty zip file and downloader URL. This is no longer a requirement. - Updated instructions for dependencies @@ -59,7 +52,7 @@ git config --global credential.helper osxkeychain ### Clone the repository ```shell -> git clone https://github.com/aws-lumberyard/o3de.git +> git clone https://github.com/o3de/o3de.git Cloning into 'o3de'... # initial prompt for credentials to download the repository code From f8753a609e4359549bac099465357504ef6fd9b7 Mon Sep 17 00:00:00 2001 From: brianherrera Date: Tue, 6 Jul 2021 15:08:39 -0700 Subject: [PATCH 09/11] Add bug issue template Signed-off-by: brianherrera --- .github/ISSUE_TEMPLATE/bug_template.md | 34 ++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_template.md diff --git a/.github/ISSUE_TEMPLATE/bug_template.md b/.github/ISSUE_TEMPLATE/bug_template.md new file mode 100644 index 0000000000..d197ca1312 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_template.md @@ -0,0 +1,34 @@ +--- +name: Bug report +about: Create a report to help us improve +title: 'Bug Report' +labels: 'needs-triage,needs-sig,kind/bug' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop/Device (please complete the following information):** + - Device: [e.g. PC, Mac, iPhone, Samsung] + - OS: [e.g. Windows, macOS, iOS, Android] + - Version [e.g. 10, Bug Sur, Oreo] + - CPU [e.g. Intel I9-9900k , Ryzen 5900x, ] + - GPU [AMD 6800 XT, NVidia RTX 3090] + - Memory [e.g. 16GB] + +**Additional context** +Add any other context about the problem here. \ No newline at end of file From a014aed03d849c170eb82c62c1cadcdd1403d2ae Mon Sep 17 00:00:00 2001 From: brianherrera Date: Tue, 6 Jul 2021 15:09:14 -0700 Subject: [PATCH 10/11] Add feature request template Signed-off-by: brianherrera --- .github/ISSUE_TEMPLATE/feature_request.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000000..6e070ad985 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- + +name: Feature request +about: Suggest an idea for this project +title: 'Feature Request' +labels: 'needs-triage,needs-sig' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. \ No newline at end of file From 64697350bc09e619d42bf32758525745f5a350f6 Mon Sep 17 00:00:00 2001 From: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> Date: Wed, 7 Jul 2021 10:53:21 +0100 Subject: [PATCH 11/11] LYN-4806: Switch Asset Browser Mode Button (Fix) (#1852) * Adding dropdown for view Signed-off-by: igarri * Adding Asset Browser Mode selector button Signed-off-by: igarri * Added display State Enum Signed-off-by: igarri * changed over to AZStd::unique_ptr Signed-off-by: igarri * added pointers Signed-off-by: igarri * Fixing pointers Signed-off-by: igarri * Fixing parenting Signed-off-by: igarri * Changes from Code Review Feedback Signed-off-by: igarri * Fixed wrong condition Signed-off-by: igarri * Added Button Icon Signed-off-by: igarri * Fixing Copyright Header Signed-off-by: igarri --- .../AzAssetBrowser/AzAssetBrowserWindow.cpp | 195 ++++++++++++--- .../AzAssetBrowser/AzAssetBrowserWindow.h | 30 ++- .../AzAssetBrowser/AzAssetBrowserWindow.ui | 10 +- .../Components/FilteredSearchWidget.ui | 236 +++++++++--------- .../Views/AssetBrowserTableView.cpp | 5 + 5 files changed, 311 insertions(+), 165 deletions(-) diff --git a/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp b/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp index a75780bda7..e0cb83d2cd 100644 --- a/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp +++ b/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp @@ -69,36 +69,38 @@ AzAssetBrowserWindow::AzAssetBrowserWindow(QWidget* parent) m_ui->setupUi(this); m_ui->m_searchWidget->Setup(true, true); + OnInitViewToggleButton(); + namespace AzAssetBrowser = AzToolsFramework::AssetBrowser; - AzAssetBrowser::AssetBrowserComponentRequestBus::BroadcastResult(m_assetBrowserModel, &AzAssetBrowser::AssetBrowserComponentRequests::GetAssetBrowserModel); + AzAssetBrowser::AssetBrowserComponentRequestBus::BroadcastResult( + m_assetBrowserModel, &AzAssetBrowser::AssetBrowserComponentRequests::GetAssetBrowserModel); AZ_Assert(m_assetBrowserModel, "Failed to get filebrowser model"); m_filterModel->setSourceModel(m_assetBrowserModel); m_filterModel->SetFilter(m_ui->m_searchWidget->GetFilter()); - m_ui->m_viewSwitcherCheckBox->setVisible(false); m_ui->m_assetBrowserTableViewWidget->setVisible(false); + m_ui->m_toggleDisplayViewBtn->setVisible(false); if (ed_useNewAssetBrowserTableView) { - m_ui->m_viewSwitcherCheckBox->setVisible(true); + m_ui->m_toggleDisplayViewBtn->setVisible(true); + m_ui->m_toggleDisplayViewBtn->setIcon(QIcon(":/Menu/menu.svg")); + m_tableModel->setFilterRole(Qt::DisplayRole); m_tableModel->setSourceModel(m_filterModel.data()); m_ui->m_assetBrowserTableViewWidget->setModel(m_tableModel.data()); + connect( m_filterModel.data(), &AzAssetBrowser::AssetBrowserFilterModel::filterChanged, this, - [this]() - { - if (!m_ui->m_searchWidget->GetFilterString().isEmpty()) - { - m_tableModel->UpdateTableModelMaps(); - } - }); + &AzAssetBrowserWindow::SetTableViewVisibleAfterFilter); + + connect( + m_filterModel.data(), &AzAssetBrowser::AssetBrowserFilterModel::filterChanged, this, + &AzAssetBrowserWindow::UpdateTableModelAfterFilter); connect( m_ui->m_assetBrowserTableViewWidget, &AzAssetBrowser::AssetBrowserTableView::selectionChangedSignal, this, &AzAssetBrowserWindow::SelectionChangedSlot); - connect( - m_ui->m_assetBrowserTableViewWidget, &QAbstractItemView::doubleClicked, this, - &AzAssetBrowserWindow::DoubleClickedItem); + connect(m_ui->m_assetBrowserTableViewWidget, &QAbstractItemView::doubleClicked, this, &AzAssetBrowserWindow::DoubleClickedItem); connect( m_ui->m_assetBrowserTableViewWidget, &AzAssetBrowser::AssetBrowserTableView::ClearStringFilter, m_ui->m_searchWidget, &AzAssetBrowser::SearchWidget::ClearStringFilter); @@ -107,22 +109,6 @@ AzAssetBrowserWindow::AzAssetBrowserWindow(QWidget* parent) &AzAssetBrowser::SearchWidget::ClearTypeFilter); m_ui->m_assetBrowserTableViewWidget->SetName("AssetBrowserTableView_main"); - - connect( - m_filterModel.data(), &AzAssetBrowser::AssetBrowserFilterModel::filterChanged, this, - [this]() - { - const bool hasFilter = !m_ui->m_searchWidget->GetFilterString().isEmpty(); - m_ui->m_assetBrowserTableViewWidget->setVisible(hasFilter); - m_ui->m_assetBrowserTreeViewWidget->setVisible(!hasFilter); - }); - connect( - m_ui->m_viewSwitcherCheckBox, &QCheckBox::stateChanged, this, - [this](bool visible) - { - m_ui->m_assetBrowserTableViewWidget->setVisible(visible); - m_ui->m_assetBrowserTreeViewWidget->setVisible(!visible); - }); } m_ui->m_assetBrowserTreeViewWidget->setModel(m_filterModel.data()); @@ -175,11 +161,143 @@ QObject* AzAssetBrowserWindow::createListenerForShowAssetEditorEvent(QObject* pa return listener; } +void AzAssetBrowserWindow::OnInitViewToggleButton() +{ + CreateSwitchViewMenu(); + m_ui->m_toggleDisplayViewBtn->setMenu(m_viewSwitchMenu); + m_ui->m_toggleDisplayViewBtn->setPopupMode(QToolButton::InstantPopup); + + connect(m_viewSwitchMenu, &QMenu::aboutToShow, this, &AzAssetBrowserWindow::UpdateDisplayInfo); +} + +void AzAssetBrowserWindow::CreateSwitchViewMenu() +{ + if (m_viewSwitchMenu != nullptr) + { + return; + } + + m_viewSwitchMenu = new QMenu("Asset Browser Mode Selection", this); + + m_expandedAssetBrowserMode = new QAction(tr("Expanded"), this); + m_expandedAssetBrowserMode->setCheckable(true); + connect(m_expandedAssetBrowserMode, &QAction::triggered, this, &AzAssetBrowserWindow::SetExpandedAssetBrowserMode); + m_viewSwitchMenu->addAction(m_expandedAssetBrowserMode); + + m_defaultAssetBrowserMode = new QAction(tr("Default"), this); + m_defaultAssetBrowserMode->setCheckable(true); + connect(m_defaultAssetBrowserMode, &QAction::triggered, this, &AzAssetBrowserWindow::SetDefaultAssetBrowserMode); + m_viewSwitchMenu->addAction(m_defaultAssetBrowserMode); + + UpdateDisplayInfo(); +} + +void AzAssetBrowserWindow::UpdateDisplayInfo() +{ + namespace AzAssetBrowser = AzToolsFramework::AssetBrowser; + + if (m_viewSwitchMenu == nullptr) + { + return; + } + + m_expandedAssetBrowserMode->setChecked(false); + m_defaultAssetBrowserMode->setChecked(false); + + switch (m_assetBrowserDisplayState) + { + case AzAssetBrowser::AssetBrowserDisplayState::ExpandedMode: + { + m_expandedAssetBrowserMode->setChecked(true); + break; + } + case AzAssetBrowser::AssetBrowserDisplayState::DefaultMode: + { + m_defaultAssetBrowserMode->setChecked(true); + break; + } + } +} + +void AzAssetBrowserWindow::SetExpandedAssetBrowserMode() +{ + namespace AzAssetBrowser = AzToolsFramework::AssetBrowser; + + m_assetBrowserDisplayState = AzAssetBrowser::AssetBrowserDisplayState::ExpandedMode; + + disconnect( + m_filterModel.data(), &AzAssetBrowser::AssetBrowserFilterModel::filterChanged, this, + &AzAssetBrowserWindow::UpdateTableModelAfterFilter); + disconnect( + m_filterModel.data(), &AzAssetBrowser::AssetBrowserFilterModel::filterChanged, this, + &AzAssetBrowserWindow::SetTableViewVisibleAfterFilter); + + disconnect( + m_ui->m_assetBrowserTableViewWidget, &AzAssetBrowser::AssetBrowserTableView::selectionChangedSignal, this, + &AzAssetBrowserWindow::SelectionChangedSlot); + disconnect(m_ui->m_assetBrowserTableViewWidget, &QAbstractItemView::doubleClicked, this, &AzAssetBrowserWindow::DoubleClickedItem); + disconnect( + m_ui->m_assetBrowserTableViewWidget, &AzAssetBrowser::AssetBrowserTableView::ClearStringFilter, m_ui->m_searchWidget, + &AzAssetBrowser::SearchWidget::ClearStringFilter); + disconnect( + m_ui->m_assetBrowserTableViewWidget, &AzAssetBrowser::AssetBrowserTableView::ClearTypeFilter, m_ui->m_searchWidget, + &AzAssetBrowser::SearchWidget::ClearTypeFilter); + + if (m_ui->m_assetBrowserTableViewWidget->isVisible()) + { + m_ui->m_assetBrowserTableViewWidget->setVisible(false); + m_ui->m_assetBrowserTreeViewWidget->setVisible(true); + } +} + +void AzAssetBrowserWindow::SetDefaultAssetBrowserMode() +{ + namespace AzAssetBrowser = AzToolsFramework::AssetBrowser; + + m_assetBrowserDisplayState = AzAssetBrowser::AssetBrowserDisplayState::DefaultMode; + + connect( + m_filterModel.data(), &AzAssetBrowser::AssetBrowserFilterModel::filterChanged, this, + &AzAssetBrowserWindow::SetTableViewVisibleAfterFilter); + + connect( + m_filterModel.data(), &AzAssetBrowser::AssetBrowserFilterModel::filterChanged, this, + &AzAssetBrowserWindow::UpdateTableModelAfterFilter); + connect( + m_ui->m_assetBrowserTableViewWidget, &AzAssetBrowser::AssetBrowserTableView::selectionChangedSignal, this, + &AzAssetBrowserWindow::SelectionChangedSlot); + connect(m_ui->m_assetBrowserTableViewWidget, &QAbstractItemView::doubleClicked, this, &AzAssetBrowserWindow::DoubleClickedItem); + connect( + m_ui->m_assetBrowserTableViewWidget, &AzAssetBrowser::AssetBrowserTableView::ClearStringFilter, m_ui->m_searchWidget, + &AzAssetBrowser::SearchWidget::ClearStringFilter); + connect( + m_ui->m_assetBrowserTableViewWidget, &AzAssetBrowser::AssetBrowserTableView::ClearTypeFilter, m_ui->m_searchWidget, + &AzAssetBrowser::SearchWidget::ClearTypeFilter); + + //If the filter is not empty we want to switch views and Update the model + UpdateTableModelAfterFilter(); + SetTableViewVisibleAfterFilter(); +} + +void AzAssetBrowserWindow::UpdateTableModelAfterFilter() +{ + if (!m_ui->m_searchWidget->GetFilterString().isEmpty()) + { + m_tableModel->UpdateTableModelMaps(); + } +} + +void AzAssetBrowserWindow::SetTableViewVisibleAfterFilter() +{ + const bool hasFilter = !m_ui->m_searchWidget->GetFilterString().isEmpty(); + m_ui->m_assetBrowserTableViewWidget->setVisible(hasFilter); + m_ui->m_assetBrowserTreeViewWidget->setVisible(!hasFilter); +} + void AzAssetBrowserWindow::UpdatePreview() const { - const auto& selectedAssets = m_ui->m_assetBrowserTreeViewWidget->isVisible() - ? m_ui->m_assetBrowserTreeViewWidget->GetSelectedAssets() - : m_ui->m_assetBrowserTableViewWidget->GetSelectedAssets(); + const auto& selectedAssets = m_ui->m_assetBrowserTreeViewWidget->isVisible() ? m_ui->m_assetBrowserTreeViewWidget->GetSelectedAssets() + : m_ui->m_assetBrowserTableViewWidget->GetSelectedAssets(); if (selectedAssets.size() != 1) { @@ -250,22 +368,23 @@ void AzAssetBrowserWindow::SelectionChangedSlot(const QItemSelection& /*selected void AzAssetBrowserWindow::DoubleClickedItem([[maybe_unused]] const QModelIndex& element) { namespace AzAssetBrowser = AzToolsFramework::AssetBrowser; - - const auto& selectedAssets = m_ui->m_assetBrowserTreeViewWidget->isVisible() - ? m_ui->m_assetBrowserTreeViewWidget->GetSelectedAssets() - : m_ui->m_assetBrowserTableViewWidget->GetSelectedAssets(); + + const auto& selectedAssets = m_ui->m_assetBrowserTreeViewWidget->isVisible() ? m_ui->m_assetBrowserTreeViewWidget->GetSelectedAssets() + : m_ui->m_assetBrowserTableViewWidget->GetSelectedAssets(); for (const AzAssetBrowser::AssetBrowserEntry* entry : selectedAssets) { AZ::Data::AssetId assetIdToOpen; AZStd::string fullFilePath; - if (const AzAssetBrowser::ProductAssetBrowserEntry* productEntry = azrtti_cast(entry)) + if (const AzAssetBrowser::ProductAssetBrowserEntry* productEntry = + azrtti_cast(entry)) { assetIdToOpen = productEntry->GetAssetId(); fullFilePath = entry->GetFullPath(); } - else if (const AzAssetBrowser::SourceAssetBrowserEntry* sourceEntry = azrtti_cast(entry)) + else if ( + const AzAssetBrowser::SourceAssetBrowserEntry* sourceEntry = azrtti_cast(entry)) { // manufacture an empty AssetID with the source's UUID assetIdToOpen = AZ::Data::AssetId(sourceEntry->GetSourceUuid(), 0); diff --git a/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.h b/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.h index 84691bc30e..b3b52a8ecb 100644 --- a/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.h +++ b/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.h @@ -27,11 +27,17 @@ namespace AzToolsFramework class AssetBrowserTableModel; class AssetBrowserModel; class AssetBrowserTableFilterModel; - } -} -class AzAssetBrowserWindow - : public QWidget + enum class AssetBrowserDisplayState : int + { + ExpandedMode, + DefaultMode, + Invalid + }; + } // namespace AssetBrowser +} // namespace AzToolsFramework + +class AzAssetBrowserWindow : public QWidget { Q_OBJECT public: @@ -47,12 +53,26 @@ public: static QObject* createListenerForShowAssetEditorEvent(QObject* parent); private: + void OnInitViewToggleButton(); + void UpdateDisplayInfo(); +protected slots: + void CreateSwitchViewMenu(); + void SetExpandedAssetBrowserMode(); + void SetDefaultAssetBrowserMode(); + void UpdateTableModelAfterFilter(); + void SetTableViewVisibleAfterFilter(); +private: QScopedPointer m_ui; QScopedPointer m_filterModel; QScopedPointer m_tableModel; AzToolsFramework::AssetBrowser::AssetBrowserModel* m_assetBrowserModel; - + QMenu* m_viewSwitchMenu = nullptr; + QAction* m_expandedAssetBrowserMode = nullptr; + QAction* m_defaultAssetBrowserMode = nullptr; + AzToolsFramework::AssetBrowser::AssetBrowserDisplayState m_assetBrowserDisplayState = + AzToolsFramework::AssetBrowser::AssetBrowserDisplayState::DefaultMode; + void UpdatePreview() const; private Q_SLOTS: diff --git a/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.ui b/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.ui index 37eb1521f3..df7474d9d4 100644 --- a/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.ui +++ b/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.ui @@ -54,7 +54,7 @@ 0 - + @@ -66,9 +66,9 @@ - + - Switch View + ... @@ -218,6 +218,8 @@
AzToolsFramework/AssetBrowser/Views/AssetBrowserTableView.h
- + + + diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/FilteredSearchWidget.ui b/Code/Framework/AzQtComponents/AzQtComponents/Components/FilteredSearchWidget.ui index 84fbdb711c..01373730be 100644 --- a/Code/Framework/AzQtComponents/AzQtComponents/Components/FilteredSearchWidget.ui +++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/FilteredSearchWidget.ui @@ -1,124 +1,124 @@ - FilteredSearchWidget - - - - 0 - 0 - 295 - 53 - - - - Form - - - - - - - 0 - - - - - - 1 - 0 - + FilteredSearchWidget + + + + 0 + 0 + 295 + 53 + - - + + Form - - - - - false - - - Search... - - - true - - - false - - - - - - - QToolButton::InstantPopup - - - true - - - - - - - Qt::Horizontal - - - QSizePolicy::MinimumExpanding - - - - 1 - 1 - - - - - + + + + + + 0 + + + + + + 1 + 0 + + + + + + + + + + false + + + Search... + + + true + + + false + + + + + + + QToolButton::InstantPopup + + + true + + + + + + + Qt::Horizontal + + + QSizePolicy::MinimumExpanding + + + + 1 + 1 + + + + + + + + + + + + + + + 10 + 75 + true + + + + <b>Filtered by:</b> + + + + + + + + 0 + 0 + + + + + + + + - - - - - - - - - 10 - 75 - true - - - - <b>Filtered by:</b> - - - - - - - - 0 - 0 - - - - - - - - - - - - AzQtComponents::ExtendedLabel - QLabel -
AzQtComponents/Components/ExtendedLabel.h
-
-
- - - - - + + + AzQtComponents::ExtendedLabel + QLabel +
AzQtComponents/Components/ExtendedLabel.h
+
+
+ + + + +
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTableView.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTableView.cpp index 73098f3702..c59f55315c 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTableView.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTableView.cpp @@ -43,6 +43,11 @@ namespace AzToolsFramework setSortingEnabled(true); setItemDelegate(m_delegate); verticalHeader()->hide(); + + //Styling the header aligning text to the left and using a bold font. + horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); + horizontalHeader()->setStyleSheet("QHeaderView { font-weight: bold; }"); + setContextMenuPolicy(Qt::CustomContextMenu); setMouseTracking(true);