From 5d5087e0d34b327521c346395996ceb778bb5633 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Tue, 9 Nov 2021 11:11:15 -0800 Subject: [PATCH 01/47] Moving CommunicatorTracePrinter to a place that AP and Multiplayer gem can use it. MultiplayerEditorSystemComponent now watching the server process and pumping the trace printer. Wip; for some reason not all the server logs are reaching the editor Signed-off-by: Gene Walters --- .../ProcessCommunicatorTracePrinter.cpp} | 12 ++++----- .../ProcessCommunicatorTracePrinter.h} | 13 +++++----- .../AzFramework/azframework_files.cmake | 2 ++ .../assetprocessor_static_files.cmake | 2 -- .../native/resourcecompiler/RCBuilder.cpp | 2 -- .../utilities/ApplicationManagerBase.cpp | 2 +- .../native/utilities/BuilderManager.cpp | 2 +- .../native/utilities/BuilderManager.h | 4 +-- .../MultiplayerEditorSystemComponent.cpp | 26 ++++++++++++++++--- .../Editor/MultiplayerEditorSystemComponent.h | 13 +++++++--- .../Source/MultiplayerSystemComponent.cpp | 1 + 11 files changed, 51 insertions(+), 28 deletions(-) rename Code/{Tools/AssetProcessor/native/utilities/CommunicatorTracePrinter.cpp => Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.cpp} (82%) rename Code/{Tools/AssetProcessor/native/utilities/CommunicatorTracePrinter.h => Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.h} (54%) diff --git a/Code/Tools/AssetProcessor/native/utilities/CommunicatorTracePrinter.cpp b/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.cpp similarity index 82% rename from Code/Tools/AssetProcessor/native/utilities/CommunicatorTracePrinter.cpp rename to Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.cpp index c6008deb34..8f3e45bec5 100644 --- a/Code/Tools/AssetProcessor/native/utilities/CommunicatorTracePrinter.cpp +++ b/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.cpp @@ -6,16 +6,16 @@ * */ -#include "CommunicatorTracePrinter.h" +#include "ProcessCommunicatorTracePrinter.h" -CommunicatorTracePrinter::CommunicatorTracePrinter(AzFramework::ProcessCommunicator* communicator, const char* window) : +ProcessCommunicatorTracePrinter::ProcessCommunicatorTracePrinter(AzFramework::ProcessCommunicator* communicator, const char* window) : m_communicator(communicator), m_window(window) { m_stringBeingConcatenated.reserve(1024); } -CommunicatorTracePrinter::~CommunicatorTracePrinter() +ProcessCommunicatorTracePrinter::~ProcessCommunicatorTracePrinter() { // flush stdout WriteCurrentString(false); @@ -24,7 +24,7 @@ CommunicatorTracePrinter::~CommunicatorTracePrinter() WriteCurrentString(true); } -void CommunicatorTracePrinter::Pump() +void ProcessCommunicatorTracePrinter::Pump() { if (m_communicator->IsValid()) { @@ -42,7 +42,7 @@ void CommunicatorTracePrinter::Pump() } } -void CommunicatorTracePrinter::ParseDataBuffer(AZ::u32 readSize, bool isFromStdErr) +void ProcessCommunicatorTracePrinter::ParseDataBuffer(AZ::u32 readSize, bool isFromStdErr) { if (readSize > AZ_ARRAY_SIZE(m_streamBuffer)) { @@ -67,7 +67,7 @@ void CommunicatorTracePrinter::ParseDataBuffer(AZ::u32 readSize, bool isFromStdE } } -void CommunicatorTracePrinter::WriteCurrentString(bool isFromStdErr) +void ProcessCommunicatorTracePrinter::WriteCurrentString(bool isFromStdErr) { AZStd::string& bufferToUse = isFromStdErr ? m_errorStringBeingConcatenated : m_stringBeingConcatenated; diff --git a/Code/Tools/AssetProcessor/native/utilities/CommunicatorTracePrinter.h b/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.h similarity index 54% rename from Code/Tools/AssetProcessor/native/utilities/CommunicatorTracePrinter.h rename to Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.h index c2e4da32af..8b84c4c28d 100644 --- a/Code/Tools/AssetProcessor/native/utilities/CommunicatorTracePrinter.h +++ b/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.h @@ -10,20 +10,21 @@ #include -//! CommunicatorTracePrinter listens to stderr and stdout of a running process and writes its output to the AZ_Trace system +//! ProcessCommunicatorTracePrinter listens to stderr and stdout of a running process and writes its output to the AZ_Trace system //! Importantly, it does not do any blocking operations. -class CommunicatorTracePrinter +class ProcessCommunicatorTracePrinter { public: - CommunicatorTracePrinter(AzFramework::ProcessCommunicator* communicator, const char* window); - ~CommunicatorTracePrinter(); + ProcessCommunicatorTracePrinter(AzFramework::ProcessCommunicator* communicator, const char* window); + ~ProcessCommunicatorTracePrinter(); - // call this periodically to drain the buffers and write them. + // Call this periodically to drain the buffers and write them. void Pump(); - // drains the buffer into the string thats being built, then traces the string when it hits a newline. + // Drains the buffer into the string that's being built, then traces the string when it hits a newline. void ParseDataBuffer(AZ::u32 readSize, bool isFromStdErr); + // Prints the current buffer to AZ_Error or AZ_TracePrintf so that it can be picked up by AZ::Debug::Trace void WriteCurrentString(bool isFromStdError); private: diff --git a/Code/Framework/AzFramework/AzFramework/azframework_files.cmake b/Code/Framework/AzFramework/AzFramework/azframework_files.cmake index e03d166cfc..232975d7c8 100644 --- a/Code/Framework/AzFramework/AzFramework/azframework_files.cmake +++ b/Code/Framework/AzFramework/AzFramework/azframework_files.cmake @@ -274,6 +274,8 @@ set(FILES Process/ProcessWatcher.cpp Process/ProcessWatcher.h Process/ProcessCommon_fwd.h + Process/ProcessCommunicatorTracePrinter.cpp + Process/ProcessCommunicatorTracePrinter.h ProjectManager/ProjectManager.h ProjectManager/ProjectManager.cpp Render/GameIntersectorComponent.h diff --git a/Code/Tools/AssetProcessor/assetprocessor_static_files.cmake b/Code/Tools/AssetProcessor/assetprocessor_static_files.cmake index 0c1347517f..056b88beb2 100644 --- a/Code/Tools/AssetProcessor/assetprocessor_static_files.cmake +++ b/Code/Tools/AssetProcessor/assetprocessor_static_files.cmake @@ -89,8 +89,6 @@ set(FILES native/utilities/BuilderManager.inl native/utilities/ByteArrayStream.cpp native/utilities/ByteArrayStream.h - native/utilities/CommunicatorTracePrinter.cpp - native/utilities/CommunicatorTracePrinter.h native/utilities/IniConfiguration.cpp native/utilities/IniConfiguration.h native/utilities/JobDiagnosticTracker.cpp diff --git a/Code/Tools/AssetProcessor/native/resourcecompiler/RCBuilder.cpp b/Code/Tools/AssetProcessor/native/resourcecompiler/RCBuilder.cpp index 27210685fc..c463f2320e 100644 --- a/Code/Tools/AssetProcessor/native/resourcecompiler/RCBuilder.cpp +++ b/Code/Tools/AssetProcessor/native/resourcecompiler/RCBuilder.cpp @@ -20,7 +20,6 @@ #include #include -#include #include #include @@ -31,7 +30,6 @@ #include "native/utilities/assetUtils.h" #include "native/utilities/AssetBuilderInfo.h" -#include "native/utilities/CommunicatorTracePrinter.h" #include diff --git a/Code/Tools/AssetProcessor/native/utilities/ApplicationManagerBase.cpp b/Code/Tools/AssetProcessor/native/utilities/ApplicationManagerBase.cpp index 4e0bc7e434..2c322da2f7 100644 --- a/Code/Tools/AssetProcessor/native/utilities/ApplicationManagerBase.cpp +++ b/Code/Tools/AssetProcessor/native/utilities/ApplicationManagerBase.cpp @@ -1479,7 +1479,7 @@ bool ApplicationManagerBase::WaitForBuilderExit(AzFramework::ProcessWatcher* pro AZ::u32 exitCode = 0; bool finishedOK = false; QElapsedTimer ticker; - CommunicatorTracePrinter tracer(processWatcher->GetCommunicator(), "AssetBuilder"); + ProcessCommunicatorTracePrinter tracer(processWatcher->GetCommunicator(), "AssetBuilder"); ticker.start(); diff --git a/Code/Tools/AssetProcessor/native/utilities/BuilderManager.cpp b/Code/Tools/AssetProcessor/native/utilities/BuilderManager.cpp index 751afc1a5d..aa462f7590 100644 --- a/Code/Tools/AssetProcessor/native/utilities/BuilderManager.cpp +++ b/Code/Tools/AssetProcessor/native/utilities/BuilderManager.cpp @@ -164,7 +164,7 @@ namespace AssetProcessor return false; } - m_tracePrinter = AZStd::make_unique(m_processWatcher->GetCommunicator(), "AssetBuilder"); + m_tracePrinter = AZStd::make_unique(m_processWatcher->GetCommunicator(), "AssetBuilder"); return WaitForConnection(); } diff --git a/Code/Tools/AssetProcessor/native/utilities/BuilderManager.h b/Code/Tools/AssetProcessor/native/utilities/BuilderManager.h index 657e4c7788..440f0b3709 100644 --- a/Code/Tools/AssetProcessor/native/utilities/BuilderManager.h +++ b/Code/Tools/AssetProcessor/native/utilities/BuilderManager.h @@ -10,11 +10,11 @@ #include #include #include +#include #include #include #include #include -#include #include #include // used in the inl file. @@ -127,7 +127,7 @@ namespace AssetProcessor AZStd::unique_ptr m_processWatcher = nullptr; //! Optional communicator, only available if we have a process watcher - AZStd::unique_ptr m_tracePrinter = nullptr; + AZStd::unique_ptr m_tracePrinter = nullptr; const AssetUtilities::QuitListener& m_quitListener; }; diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp index 11aca101b3..7d6a684b6b 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp @@ -6,6 +6,8 @@ * */ +#include "AzFramework/Process/ProcessCommunicator.h" + #include #include #include @@ -133,6 +135,7 @@ namespace Multiplayer AzToolsFramework::EditorEvents::Bus::Handler::BusDisconnect(); AzFramework::GameEntityContextEventBus::Handler::BusDisconnect(); MultiplayerEditorServerRequestBus::Handler::BusDisconnect(); + AZ::TickBus::Handler::BusDisconnect(); } void MultiplayerEditorSystemComponent::NotifyRegisterViews() @@ -157,12 +160,21 @@ namespace Multiplayer [[fallthrough]]; case eNotify_OnEndGameMode: // Kill the configured server if it's active - if (m_serverProcess) + if (m_serverProcessWatcher) { - m_serverProcess->TerminateProcess(0); - m_serverProcess = nullptr; + m_serverProcessWatcher->TerminateProcess(0); + if (m_serverProcessTracePrinter) + { + m_serverProcessTracePrinter->Pump(); + m_serverProcessTracePrinter->WriteCurrentString(true); + m_serverProcessTracePrinter->WriteCurrentString(false); + } + m_serverProcessWatcher = nullptr; + m_serverProcessTracePrinter = nullptr; } + AZ::TickBus::Handler::BusDisconnect(); + if (INetworkInterface* editorNetworkInterface = AZ::Interface::Get()->RetrieveNetworkInterface(AZ::Name(MpEditorInterfaceName))) { editorNetworkInterface->Disconnect(m_editorConnId, AzNetworking::DisconnectReason::TerminatedByClient); @@ -220,7 +232,7 @@ namespace Multiplayer // Launch the Server AzFramework::ProcessWatcher* outProcess = AzFramework::ProcessWatcher::LaunchProcess( - processLaunchInfo, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_NONE); + processLaunchInfo, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_STDINOUT); AZ_Error( "MultiplayerEditor", processLaunchInfo.m_launchResult != AzFramework::ProcessLauncher::ProcessLaunchResult::PLR_MissingFile, @@ -389,4 +401,10 @@ namespace Multiplayer { return PyIsInGameMode(); } + + void MultiplayerEditorSystemComponent::OnTick(float, AZ::ScriptTimePoint) + { + m_serverProcessTracePrinter->Pump(); + } + } diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.h b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.h index 77b41a5dc4..330a2c9d81 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.h +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.h @@ -13,14 +13,12 @@ #include #include -#include - #include #include #include -#include #include #include +#include #include namespace AzNetworking @@ -52,6 +50,7 @@ namespace Multiplayer , private AzToolsFramework::EditorEvents::Bus::Handler , private IEditorNotifyListener , private MultiplayerEditorServerRequestBus::Handler + , private AZ::TickBus::Handler { public: AZ_COMPONENT(MultiplayerEditorSystemComponent, "{9F335CC0-5574-4AD3-A2D8-2FAEF356946C}"); @@ -101,8 +100,14 @@ namespace Multiplayer void SendEditorServerLevelDataPacket(AzNetworking::IConnection* connection) override; //! @} + //! AZ::TickBus::Handler + //! @{ + void OnTick(float, AZ::ScriptTimePoint) override; + //! @} + IEditor* m_editor = nullptr; - AzFramework::ProcessWatcher* m_serverProcess = nullptr; + AzFramework::ProcessWatcher* m_serverProcessWatcher = nullptr; + AZStd::unique_ptr m_serverProcessTracePrinter = nullptr; AzNetworking::ConnectionId m_editorConnId; ServerAcceptanceReceivedEvent::Handler m_serverAcceptanceReceivedHandler; diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp index 6df5e4611f..54f5534864 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp @@ -1134,6 +1134,7 @@ namespace Multiplayer AZStd::to_lower(sv_defaultPlayerSpawnAssetLowerCase.begin(), sv_defaultPlayerSpawnAssetLowerCase.end()); PrefabEntityId playerPrefabEntityId(AZ::Name(static_cast(sv_defaultPlayerSpawnAssetLowerCase).c_str())); INetworkEntityManager::EntityList entityList = m_networkEntityManager.CreateEntitiesImmediate(playerPrefabEntityId, NetEntityRole::Authority, AZ::Transform::CreateIdentity(), Multiplayer::AutoActivate::DoNotActivate); + AZ_TracePrintf("MultiplayerSystemComponent", "Server spawned the default player: %s", sv_defaultPlayerSpawnAssetLowerCase.c_str()) for (NetworkEntityHandle subEntity : entityList) { From d6803d800b1521456cfbdbcaacf0c9883dbd4083 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Wed, 10 Nov 2021 19:37:11 -0800 Subject: [PATCH 02/47] Externed cvars dont get registered with setreg (not sure why). Updating sv_defaultPlayer to grab the variable via console string lookup instead so the proper value is gathered Signed-off-by: Gene Walters --- .../Editor/MultiplayerEditorSystemComponent.cpp | 16 ++++++++++++++-- .../Code/Source/MultiplayerSystemComponent.h | 2 -- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp index 7d6a684b6b..c5f3d0e226 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp @@ -219,12 +219,22 @@ namespace Multiplayer { server_rhi = static_cast(editorsv_rhi_override); } + + const auto console = AZ::Interface::Get(); + AZ::CVarFixedString sv_defaultPlayerSpawnAsset; + + if (console->GetCvarValue("sv_defaultPlayerSpawnAsset", sv_defaultPlayerSpawnAsset) != AZ::GetValueResult::Success) + { + AZ_Assert( false, + "MultiplayerEditorSystemComponent::LaunchEditorServer failed! Could not find the sv_defaultPlayerSpawnAsset cvar; the editor-server " + "will fall back to using some other default player! Please update this code to use a valid cvar!") + } processLaunchInfo.m_commandlineParameters = AZStd::string::format( R"("%s" --project-path "%s" --editorsv_isDedicated true --sv_defaultPlayerSpawnAsset "%s" --rhi "%s")", serverPath.c_str(), AZ::Utils::GetProjectPath().c_str(), - static_cast(sv_defaultPlayerSpawnAsset).c_str(), + sv_defaultPlayerSpawnAsset.c_str(), server_rhi.GetCStr() ); processLaunchInfo.m_showWindow = true; @@ -292,7 +302,9 @@ namespace Multiplayer editorNetworkInterface->Listen(editorsv_port); // Launch the editor-server - m_serverProcess = LaunchEditorServer(); + m_serverProcessWatcher = LaunchEditorServer(); + m_serverProcessTracePrinter = AZStd::make_unique(m_serverProcessWatcher->GetCommunicator(), "EditorServer"); + AZ::TickBus::Handler::BusConnect(); } else { diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h index 87d084d5bc..0281916de2 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h @@ -37,8 +37,6 @@ namespace AzNetworking namespace Multiplayer { - AZ_CVAR_EXTERNED(AZ::CVarFixedString, sv_defaultPlayerSpawnAsset); - //! Multiplayer system component wraps the bridging logic between the game and transport layer. class MultiplayerSystemComponent final : public AZ::Component From 4d161f42dfe65d483c50ee16a3713186dd8c8cf8 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Mon, 15 Nov 2021 12:37:21 -0800 Subject: [PATCH 03/47] WiP. fwrites are being stopped by AZCoreLogSink; need a long term solution to work around this... Signed-off-by: Gene Walters --- Code/Framework/AzCore/AzCore/Debug/Trace.cpp | 7 +++++-- .../AzFramework/Process/ProcessCommunicator_Win.cpp | 2 ++ .../Source/Editor/MultiplayerEditorSystemComponent.cpp | 2 ++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Debug/Trace.cpp b/Code/Framework/AzCore/AzCore/Debug/Trace.cpp index b9e4003500..d393018a92 100644 --- a/Code/Framework/AzCore/AzCore/Debug/Trace.cpp +++ b/Code/Framework/AzCore/AzCore/Debug/Trace.cpp @@ -26,6 +26,7 @@ #include #include #include +#pragma optimize("", off) //< remember to place this after the #includes so that you only optimize the code you want namespace AZ::Debug { @@ -523,10 +524,10 @@ namespace AZ::Debug EBUS_EVENT(TraceMessageDrillerBus, OnOutput, window, message); TraceMessageResult result; EBUS_EVENT_RESULT(result, TraceMessageBus, OnOutput, window, message); - if (result.m_value) + /* if (result.m_value) { return; - } + }*/ } // printf on Windows platforms seem to have a buffer length limit of 4096 characters @@ -537,6 +538,7 @@ namespace AZ::Debug fwrite(windowView.data(), 1, windowView.size(), stdout); fwrite(windowMessageSeparator.data(), 1, windowMessageSeparator.size(), stdout); fwrite(messageView.data(), 1, messageView.size(), stdout); + fwrite("\n\r", 1, 2, stdout); } //========================================================================= @@ -612,3 +614,4 @@ namespace AZ::Debug } } } // namspace AZ::Debug +#pragma optimize("", on) diff --git a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Process/ProcessCommunicator_Win.cpp b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Process/ProcessCommunicator_Win.cpp index c4629ccf2c..9c7bbfac15 100644 --- a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Process/ProcessCommunicator_Win.cpp +++ b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Process/ProcessCommunicator_Win.cpp @@ -8,6 +8,7 @@ #include +#pragma optimize("", off) //< remember to place this after the #includes so that you only optimize the code you want namespace AzFramework { @@ -274,3 +275,4 @@ namespace AzFramework } } // namespace AzToolsFramework +#pragma optimize("", on) diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp index 669393e31e..d75fbcbc70 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp @@ -420,6 +420,8 @@ namespace Multiplayer void MultiplayerEditorSystemComponent::OnTick(float, AZ::ScriptTimePoint) { + AZ_TracePrintf("MultiplayerEditorSystemComponent", "OnTick Pump"); + m_serverProcessTracePrinter->Pump(); } From e1ace4a8f63244f16a03b82a9ffd56586ec6e859 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Mon, 15 Nov 2021 12:37:52 -0800 Subject: [PATCH 04/47] WiP. fwrites are being stopped by AZCoreLogSink; need a long term solution to work around this... Signed-off-by: Gene Walters --- .../AzFramework/Process/ProcessCommunicatorTracePrinter.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.cpp b/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.cpp index 8f3e45bec5..ab9f7c8103 100644 --- a/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.cpp +++ b/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.cpp @@ -8,6 +8,8 @@ #include "ProcessCommunicatorTracePrinter.h" +#pragma optimize("", off) //< remember to place this after the #includes so that you only optimize the code you want + ProcessCommunicatorTracePrinter::ProcessCommunicatorTracePrinter(AzFramework::ProcessCommunicator* communicator, const char* window) : m_communicator(communicator), m_window(window) @@ -84,3 +86,4 @@ void ProcessCommunicatorTracePrinter::WriteCurrentString(bool isFromStdErr) bufferToUse.clear(); } } +#pragma optimize("", on) From 02590a1766d0613a12ec3be95f10fd8f7057c402 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Sat, 20 Nov 2021 14:48:48 -0800 Subject: [PATCH 05/47] AzCoreLogSink will check if it's running in an editor-server and will allow stdouts Signed-off-by: Gene Walters --- Code/Framework/AzCore/AzCore/Debug/Trace.cpp | 4 ++-- Code/Legacy/CrySystem/AZCoreLogSink.h | 11 +++++++++++ .../Editor/MultiplayerEditorSystemComponent.cpp | 2 -- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Debug/Trace.cpp b/Code/Framework/AzCore/AzCore/Debug/Trace.cpp index 78dbf3c979..d8a39deebb 100644 --- a/Code/Framework/AzCore/AzCore/Debug/Trace.cpp +++ b/Code/Framework/AzCore/AzCore/Debug/Trace.cpp @@ -535,10 +535,10 @@ namespace AZ::Debug EBUS_EVENT(TraceMessageDrillerBus, OnOutput, window, message); TraceMessageResult result; EBUS_EVENT_RESULT(result, TraceMessageBus, OnOutput, window, message); - /* if (result.m_value) + if (result.m_value) { return; - }*/ + } } RawOutput(window, message); diff --git a/Code/Legacy/CrySystem/AZCoreLogSink.h b/Code/Legacy/CrySystem/AZCoreLogSink.h index 1b09c3198d..605367f418 100644 --- a/Code/Legacy/CrySystem/AZCoreLogSink.h +++ b/Code/Legacy/CrySystem/AZCoreLogSink.h @@ -180,6 +180,17 @@ public: CryLog("(%s) - %s", window, message); } + // If this is an editor-server, then allow the default trace behavior (fwrites to stdout) to occur + // The editor will being listening to the stdout of this server + if (const auto console = AZ::Interface::Get()) + { + bool editorsv_isDedicated = false; + if (console->GetCvarValue("editorsv_isDedicated", editorsv_isDedicated) == AZ::GetValueResult::Success) + { + return !editorsv_isDedicated; + } + } + return true; // suppress default AzCore behavior. } diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp index d75fbcbc70..669393e31e 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp @@ -420,8 +420,6 @@ namespace Multiplayer void MultiplayerEditorSystemComponent::OnTick(float, AZ::ScriptTimePoint) { - AZ_TracePrintf("MultiplayerEditorSystemComponent", "OnTick Pump"); - m_serverProcessTracePrinter->Pump(); } From 0bd86cf0a4f7bf3a2f5a2bec63f420872a71d558 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Sat, 20 Nov 2021 14:58:09 -0800 Subject: [PATCH 06/47] small edit: removing pragma optimize offs Signed-off-by: Gene Walters --- Code/Framework/AzCore/AzCore/Debug/Trace.cpp | 2 -- .../AzFramework/Process/ProcessCommunicatorTracePrinter.cpp | 2 -- .../Windows/AzFramework/Process/ProcessCommunicator_Win.cpp | 2 -- Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp | 1 - 4 files changed, 7 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Debug/Trace.cpp b/Code/Framework/AzCore/AzCore/Debug/Trace.cpp index d8a39deebb..e2f0c6b29c 100644 --- a/Code/Framework/AzCore/AzCore/Debug/Trace.cpp +++ b/Code/Framework/AzCore/AzCore/Debug/Trace.cpp @@ -26,7 +26,6 @@ #include #include #include -#pragma optimize("", off) //< remember to place this after the #includes so that you only optimize the code you want namespace AZ::Debug { @@ -645,4 +644,3 @@ namespace AZ::Debug } } } // namspace AZ::Debug -#pragma optimize("", on) diff --git a/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.cpp b/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.cpp index ab9f7c8103..51674bb32c 100644 --- a/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.cpp +++ b/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.cpp @@ -8,7 +8,6 @@ #include "ProcessCommunicatorTracePrinter.h" -#pragma optimize("", off) //< remember to place this after the #includes so that you only optimize the code you want ProcessCommunicatorTracePrinter::ProcessCommunicatorTracePrinter(AzFramework::ProcessCommunicator* communicator, const char* window) : m_communicator(communicator), @@ -86,4 +85,3 @@ void ProcessCommunicatorTracePrinter::WriteCurrentString(bool isFromStdErr) bufferToUse.clear(); } } -#pragma optimize("", on) diff --git a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Process/ProcessCommunicator_Win.cpp b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Process/ProcessCommunicator_Win.cpp index 9c7bbfac15..c4629ccf2c 100644 --- a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Process/ProcessCommunicator_Win.cpp +++ b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Process/ProcessCommunicator_Win.cpp @@ -8,7 +8,6 @@ #include -#pragma optimize("", off) //< remember to place this after the #includes so that you only optimize the code you want namespace AzFramework { @@ -275,4 +274,3 @@ namespace AzFramework } } // namespace AzToolsFramework -#pragma optimize("", on) diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp index 8eb6d2d777..503a8128b0 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp @@ -1137,7 +1137,6 @@ namespace Multiplayer AZStd::to_lower(sv_defaultPlayerSpawnAssetLowerCase.begin(), sv_defaultPlayerSpawnAssetLowerCase.end()); PrefabEntityId playerPrefabEntityId(AZ::Name(static_cast(sv_defaultPlayerSpawnAssetLowerCase).c_str())); INetworkEntityManager::EntityList entityList = m_networkEntityManager.CreateEntitiesImmediate(playerPrefabEntityId, NetEntityRole::Authority, AZ::Transform::CreateIdentity(), Multiplayer::AutoActivate::DoNotActivate); - AZ_TracePrintf("MultiplayerSystemComponent", "Server spawned the default player: %s", sv_defaultPlayerSpawnAssetLowerCase.c_str()) for (NetworkEntityHandle subEntity : entityList) { From ff862a2f206aa2449e4c7ee77d2914b091103086 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Mon, 22 Nov 2021 18:56:48 -0800 Subject: [PATCH 07/47] Fix memory leak of ProcessWatcher Signed-off-by: Gene Walters --- .../Editor/MultiplayerEditorSystemComponent.cpp | 13 +++++++++---- .../Editor/MultiplayerEditorSystemComponent.h | 6 ++++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp index 669393e31e..7cc6fbc1b5 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp @@ -193,7 +193,7 @@ namespace Multiplayer } } - AzFramework::ProcessWatcher* LaunchEditorServer() + void MultiplayerEditorSystemComponent::LaunchEditorServer() { // Assemble the server's path AZ::CVarFixedString serverProcess = editorsv_process; @@ -248,7 +248,13 @@ namespace Multiplayer "MultiplayerEditor", processLaunchInfo.m_launchResult != AzFramework::ProcessLauncher::ProcessLaunchResult::PLR_MissingFile, "LaunchEditorServer failed! The ServerLauncher binary is missing! (%s) Please build server launcher.", serverPath.c_str()) - return outProcess; + // Stop the previous server if one exists + if (m_serverProcessWatcher) + { + m_serverProcessWatcher->TerminateProcess(0); + } + m_serverProcessWatcher.reset(outProcess); + m_serverProcessTracePrinter = AZStd::make_unique(m_serverProcessWatcher->GetCommunicator(), "EditorServer"); } void MultiplayerEditorSystemComponent::OnGameEntitiesStarted() @@ -308,8 +314,7 @@ namespace Multiplayer editorNetworkInterface->Listen(editorsv_port); // Launch the editor-server - m_serverProcessWatcher = LaunchEditorServer(); - m_serverProcessTracePrinter = AZStd::make_unique(m_serverProcessWatcher->GetCommunicator(), "EditorServer"); + LaunchEditorServer(); AZ::TickBus::Handler::BusConnect(); } else diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.h b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.h index 330a2c9d81..5e49f8f08d 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.h +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.h @@ -83,7 +83,9 @@ namespace Multiplayer bool IsInGameMode() override; //! @} - private: + private: + void LaunchEditorServer(); + //! EditorEvents::Handler overrides //! @{ void OnEditorNotifyEvent(EEditorNotifyEvent event) override; @@ -106,7 +108,7 @@ namespace Multiplayer //! @} IEditor* m_editor = nullptr; - AzFramework::ProcessWatcher* m_serverProcessWatcher = nullptr; + AZStd::unique_ptr m_serverProcessWatcher = nullptr; AZStd::unique_ptr m_serverProcessTracePrinter = nullptr; AzNetworking::ConnectionId m_editorConnId; From 33e44a4813b5beb109225085ed05e0d35e5dfa11 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Tue, 23 Nov 2021 09:27:50 -0800 Subject: [PATCH 08/47] revert rawoutput function. we'll update any of the logs we care about to include newlines Signed-off-by: Gene Walters --- Code/Framework/AzCore/AzCore/Debug/Trace.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Code/Framework/AzCore/AzCore/Debug/Trace.cpp b/Code/Framework/AzCore/AzCore/Debug/Trace.cpp index e2f0c6b29c..2c2b8215c0 100644 --- a/Code/Framework/AzCore/AzCore/Debug/Trace.cpp +++ b/Code/Framework/AzCore/AzCore/Debug/Trace.cpp @@ -558,7 +558,6 @@ namespace AZ::Debug fwrite(windowView.data(), 1, windowView.size(), stdout); fwrite(windowMessageSeparator.data(), 1, windowMessageSeparator.size(), stdout); fwrite(messageView.data(), 1, messageView.size(), stdout); - fwrite("\n\r", 1, 2, stdout); } //========================================================================= From 77e3dd786d30d14e45ccc847c999f87d75c815ec Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Wed, 24 Nov 2021 16:05:53 -0800 Subject: [PATCH 09/47] Instead of AZCoreLogSink pulling a cvar, we'll check if we're running an editor-server on SystemInit Signed-off-by: Gene Walters --- Code/Legacy/CrySystem/AZCoreLogSink.h | 19 +++++-------------- Code/Legacy/CrySystem/SystemInit.cpp | 13 ++++++++++++- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/Code/Legacy/CrySystem/AZCoreLogSink.h b/Code/Legacy/CrySystem/AZCoreLogSink.h index 605367f418..39a6131262 100644 --- a/Code/Legacy/CrySystem/AZCoreLogSink.h +++ b/Code/Legacy/CrySystem/AZCoreLogSink.h @@ -36,9 +36,10 @@ public: Disconnect(); } - inline static void Connect() + inline static void Connect(bool suppressSystemOutput) { GetInstance().m_ignoredAsserts = new IgnoredAssertMap(); + GetInstance().m_suppressSystemOutput = suppressSystemOutput; GetInstance().BusConnect(); } @@ -179,23 +180,13 @@ public: { CryLog("(%s) - %s", window, message); } - - // If this is an editor-server, then allow the default trace behavior (fwrites to stdout) to occur - // The editor will being listening to the stdout of this server - if (const auto console = AZ::Interface::Get()) - { - bool editorsv_isDedicated = false; - if (console->GetCvarValue("editorsv_isDedicated", editorsv_isDedicated) == AZ::GetValueResult::Success) - { - return !editorsv_isDedicated; - } - } - - return true; // suppress default AzCore behavior. + + return m_suppressSystemOutput; } private: using IgnoredAssertMap = AZStd::unordered_map, AZStd::equal_to, AZ::OSStdAllocator>; IgnoredAssertMap* m_ignoredAsserts; + bool m_suppressSystemOutput = true; }; diff --git a/Code/Legacy/CrySystem/SystemInit.cpp b/Code/Legacy/CrySystem/SystemInit.cpp index c5039f57e9..6f550fcac6 100644 --- a/Code/Legacy/CrySystem/SystemInit.cpp +++ b/Code/Legacy/CrySystem/SystemInit.cpp @@ -737,7 +737,18 @@ bool CSystem::Init(const SSystemInitParams& startupParams) m_pCmdLine = new CCmdLine(startupParams.szSystemCmdLine); - AZCoreLogSink::Connect(); + // Init AZCoreLogSink. Don't suppress system output if we're running as an editor-server + bool suppressSystemOutput = true; + if (const ICmdLineArg* isEditorServerArg = m_pCmdLine->FindArg(eCLAT_Pre, "editorsv_isDedicated")) + { + AZ::CVarFixedString lowercaseValue(isEditorServerArg->GetValue()); + AZStd::to_lower(lowercaseValue.begin(), lowercaseValue.end()); + if (lowercaseValue == "true") + { + suppressSystemOutput = false; + } + } + AZCoreLogSink::Connect(suppressSystemOutput); // Registers all AZ Console Variables functors specified within CrySystem if (auto azConsole = AZ::Interface::Get(); azConsole) From 34542337b9345786ef79afd61756ad42f143ca49 Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Wed, 24 Nov 2021 22:34:04 -0800 Subject: [PATCH 10/47] Remove dependency of ScriptCanvasPhysics on ScriptCanvas gem to fix runtime dependency conflict Signed-off-by: amzn-sj --- Gems/ScriptCanvas/Code/CMakeLists.txt | 16 + .../Code/scriptcanvasgem_headers.cmake | 378 ++++++++++++++++++ Gems/ScriptCanvasPhysics/Code/CMakeLists.txt | 2 +- 3 files changed, 395 insertions(+), 1 deletion(-) create mode 100644 Gems/ScriptCanvas/Code/scriptcanvasgem_headers.cmake diff --git a/Gems/ScriptCanvas/Code/CMakeLists.txt b/Gems/ScriptCanvas/Code/CMakeLists.txt index c126d343ed..25b0099e88 100644 --- a/Gems/ScriptCanvas/Code/CMakeLists.txt +++ b/Gems/ScriptCanvas/Code/CMakeLists.txt @@ -89,6 +89,22 @@ ly_add_target( Gem::ScriptCanvasDebugger ) +ly_add_target( + NAME ScriptCanvasAPI HEADERONLY + NAMESPACE Gem + FILES_CMAKE + scriptcanvasgem_headers.cmake + COMPILE_DEFINITIONS + INTERFACE + SCRIPTCANVAS_ERRORS_ENABLED + ${SCRIPT_CANVAS_COMMON_DEFINES} + INCLUDE_DIRECTORIES + INTERFACE + . + Include + Include/ScriptCanvas +) + ly_add_target( NAME ScriptCanvas ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE} NAMESPACE Gem diff --git a/Gems/ScriptCanvas/Code/scriptcanvasgem_headers.cmake b/Gems/ScriptCanvas/Code/scriptcanvasgem_headers.cmake new file mode 100644 index 0000000000..7dfe9653b6 --- /dev/null +++ b/Gems/ScriptCanvas/Code/scriptcanvasgem_headers.cmake @@ -0,0 +1,378 @@ +# +# Copyright (c) Contributors to the Open 3D Engine Project. +# For complete copyright and license terms please see the LICENSE at the root of this distribution. +# +# SPDX-License-Identifier: Apache-2.0 OR MIT +# +# + +set(FILES + Include/ScriptCanvas/SystemComponent.h + Include/ScriptCanvas/ScriptCanvasGem.h + Include/ScriptCanvas/Asset/AssetDescription.h + Include/ScriptCanvas/Asset/AssetRegistry.h + Include/ScriptCanvas/Asset/AssetRegistryBus.h + Include/ScriptCanvas/Asset/ExecutionLogAsset.h + Include/ScriptCanvas/Asset/ExecutionLogAssetBus.h + Include/ScriptCanvas/Asset/RuntimeAsset.h + Include/ScriptCanvas/Asset/RuntimeAssetHandler.h + Include/ScriptCanvas/Asset/ScriptCanvasAssetBase.h + Include/ScriptCanvas/Asset/ScriptCanvasAssetData.h + Include/ScriptCanvas/Asset/SubgraphInterfaceAssetHandler.h + Include/ScriptCanvas/Core/ScriptCanvasBus.h + Include/ScriptCanvas/Core/ExecutionNotificationsBus.h + Include/ScriptCanvas/Core/GraphBus.h + Include/ScriptCanvas/Core/NodeBus.h + Include/ScriptCanvas/Core/EBusNodeBus.h + Include/ScriptCanvas/Core/NodelingBus.h + Include/ScriptCanvas/Core/ContractBus.h + Include/ScriptCanvas/Core/Attributes.h + Include/ScriptCanvas/Core/Connection.h + Include/ScriptCanvas/Core/ConnectionBus.h + Include/ScriptCanvas/Core/Contract.h + Include/ScriptCanvas/Core/Contracts.h + Include/ScriptCanvas/Core/Contracts/MethodOverloadContract.h + Include/ScriptCanvas/Core/Contracts/RestrictedNodeContract.h + Include/ScriptCanvas/Core/Core.h + Include/ScriptCanvas/Core/Datum.h + Include/ScriptCanvas/Core/DatumBus.h + Include/ScriptCanvas/Core/EBusHandler.h + Include/ScriptCanvas/Core/Endpoint.h + Include/ScriptCanvas/Core/Graph.h + Include/ScriptCanvas/Core/GraphData.h + Include/ScriptCanvas/Core/GraphScopedTypes.h + Include/ScriptCanvas/Core/MethodConfiguration.h + Include/ScriptCanvas/Core/ModifiableDatumView.h + Include/ScriptCanvas/Core/Node.h + Include/ScriptCanvas/Core/Nodeable.h + Include/ScriptCanvas/Core/NodeableNode.h + Include/ScriptCanvas/Core/NodeableNodeOverloaded.h + Include/ScriptCanvas/Core/NodeFunctionGeneric.h + Include/ScriptCanvas/Core/SerializationListener.h + Include/ScriptCanvas/Core/Slot.h + Include/ScriptCanvas/Core/SlotConfigurationDefaults.h + Include/ScriptCanvas/Core/SlotConfigurations.h + Include/ScriptCanvas/Core/SlotExecutionMap.h + Include/ScriptCanvas/Core/SlotMetadata.h + Include/ScriptCanvas/Core/SlotNames.h + Include/ScriptCanvas/Core/SubgraphInterface.h + Include/ScriptCanvas/Core/SubgraphInterfaceUtility.h + Include/ScriptCanvas/Translation/AbstractModelTranslator.h + Include/ScriptCanvas/Translation/Configuration.h + Include/ScriptCanvas/Translation/GraphToCPlusPlus.h + Include/ScriptCanvas/Translation/GraphToLua.h + Include/ScriptCanvas/Translation/GraphToLuaUtility.h + Include/ScriptCanvas/Translation/GraphToX.h + Include/ScriptCanvas/Translation/Translation.h + Include/ScriptCanvas/Translation/TranslationContext.h + Include/ScriptCanvas/Translation/TranslationResult.h + Include/ScriptCanvas/Translation/TranslationUtilities.h + Include/ScriptCanvas/PerformanceStatistician.h + Include/ScriptCanvas/PerformanceStatisticsBus.h + Include/ScriptCanvas/PerformanceTracker.h + Include/ScriptCanvas/AutoGen/ScriptCanvas_Macros.jinja + Include/ScriptCanvas/AutoGen/ScriptCanvas_Nodeable_Macros.jinja + Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja + Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja + Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Header.jinja + Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja + Include/ScriptCanvas/CodeGen/NodeableCodegen.h + Include/ScriptCanvas/Core/Contracts/ConnectionLimitContract.h + Include/ScriptCanvas/Core/Contracts/ContractRTTI.h + Include/ScriptCanvas/Core/Contracts/DisallowReentrantExecutionContract.h + Include/ScriptCanvas/Core/Contracts/DisplayGroupConnectedSlotLimitContract.h + Include/ScriptCanvas/Core/Contracts/DynamicTypeContract.h + Include/ScriptCanvas/Core/Contracts/IsReferenceTypeContract.h + Include/ScriptCanvas/Core/Contracts/MathOperatorContract.h + Include/ScriptCanvas/Core/Contracts/SlotTypeContract.h + Include/ScriptCanvas/Core/Contracts/SupportsMethodContract.h + Include/ScriptCanvas/Core/Contracts/TypeContract.h + Include/ScriptCanvas/Data/BehaviorContextObject.h + Include/ScriptCanvas/Data/BehaviorContextObjectPtr.h + Include/ScriptCanvas/Data/Data.h + Include/ScriptCanvas/Data/DataMacros.h + Include/ScriptCanvas/Data/DataRegistry.h + Include/ScriptCanvas/Data/NumericData.h + Include/ScriptCanvas/Deprecated/VariableDatumBase.h + Include/ScriptCanvas/Deprecated/VariableDatum.h + Include/ScriptCanvas/Deprecated/VariableHelpers.h + Include/ScriptCanvas/Execution/ErrorBus.h + Include/ScriptCanvas/Execution/ExecutionBus.h + Include/ScriptCanvas/Execution/ExecutionContext.h + Include/ScriptCanvas/Execution/ExecutionObjectCloning.h + Include/ScriptCanvas/Execution/ExecutionPerformanceTimer.h + Include/ScriptCanvas/Execution/ExecutionState.h + Include/ScriptCanvas/Execution/ExecutionStateDeclarations.h + Include/ScriptCanvas/Execution/NativeHostDeclarations.h + Include/ScriptCanvas/Execution/NativeHostDefinitions.h + Include/ScriptCanvas/Execution/RuntimeComponent.h + Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.h + Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedCloningAPI.h + Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedDebugAPI.h + Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedEBusAPI.h + Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedOut.h + Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.h + Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedPerActivation.h + Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedPure.h + Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedSingleton.h + Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedUtility.h + Include/ScriptCanvas/Execution/NodeableOut/NodeableOutNative.h + Include/ScriptCanvas/Grammar/AbstractCodeModel.h + Include/ScriptCanvas/Grammar/DebugMap.h + Include/ScriptCanvas/Grammar/ExecutionTraversalListeners.h + Include/ScriptCanvas/Grammar/ParsingMetaData.h + Include/ScriptCanvas/Grammar/ParsingUtilities.h + Include/ScriptCanvas/Grammar/Primitives.h + Include/ScriptCanvas/Grammar/PrimitivesDeclarations.h + Include/ScriptCanvas/Grammar/PrimitivesExecution.h + Include/ScriptCanvas/Grammar/SymbolNames.h + Include/ScriptCanvas/Execution/ErrorBus.h + Include/ScriptCanvas/Execution/ExecutionContext.h + Include/ScriptCanvas/Execution/ExecutionBus.h + Include/ScriptCanvas/Execution/NativeHostDeclarations.h + Include/ScriptCanvas/Execution/NativeHostDefinitions.h + Include/ScriptCanvas/Execution/RuntimeComponent.h + Include/ScriptCanvas/Internal/Nodeables/BaseTimer.h + Include/ScriptCanvas/Internal/Nodeables/BaseTimer.ScriptCanvasNodeable.xml + Include/ScriptCanvas/Internal/Nodes/BaseTimerNode.h + Include/ScriptCanvas/Internal/Nodes/BaseTimerNode.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Internal/Nodes/ExpressionNodeBase.h + Include/ScriptCanvas/Internal/Nodes/ExpressionNodeBase.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Internal/Nodes/StringFormatted.h + Include/ScriptCanvas/Internal/Nodes/StringFormatted.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Grammar/AbstractCodeModel.h + Include/ScriptCanvas/Libraries/Libraries.h + Include/ScriptCanvas/Libraries/Core/AzEventHandler.h + Include/ScriptCanvas/Libraries/Core/AzEventHandler.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/BinaryOperator.h + Include/ScriptCanvas/Libraries/Core/CoreNodes.h + Include/ScriptCanvas/Libraries/Core/ContainerTypeReflection.h + Include/ScriptCanvas/Libraries/Core/EBusEventHandler.h + Include/ScriptCanvas/Libraries/Core/EBusEventHandler.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/ExtractProperty.h + Include/ScriptCanvas/Libraries/Core/ExtractProperty.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/EventHandlerTranslationUtility.h + Include/ScriptCanvas/Libraries/Core/ForEach.h + Include/ScriptCanvas/Libraries/Core/ForEach.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/FunctionBus.h + Include/ScriptCanvas/Libraries/Core/FunctionCallNode.h + Include/ScriptCanvas/Libraries/Core/FunctionCallNode.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/FunctionCallNodeIsOutOfDate.h + Include/ScriptCanvas/Libraries/Core/FunctionDefinitionNode.h + Include/ScriptCanvas/Libraries/Core/FunctionDefinitionNode.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/GetVariable.h + Include/ScriptCanvas/Libraries/Core/GetVariable.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/Method.h + Include/ScriptCanvas/Libraries/Core/MethodOverloaded.h + Include/ScriptCanvas/Libraries/Core/MethodUtility.h + Include/ScriptCanvas/Libraries/Core/Nodeling.h + Include/ScriptCanvas/Libraries/Core/Nodeling.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.h + Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/Repeater.h + Include/ScriptCanvas/Libraries/Core/Repeater.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/RepeaterNodeable.h + Include/ScriptCanvas/Libraries/Core/RepeaterNodeable.ScriptCanvasNodeable.xml + Include/ScriptCanvas/Libraries/Core/ScriptEventBase.h + Include/ScriptCanvas/Libraries/Core/ScriptEventBase.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/SendScriptEvent.h + Include/ScriptCanvas/Libraries/Core/SendScriptEvent.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/SetVariable.h + Include/ScriptCanvas/Libraries/Core/SetVariable.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/Start.h + Include/ScriptCanvas/Libraries/Core/Start.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/UnaryOperator.h + Include/ScriptCanvas/Libraries/Entity/Entity.h + Include/ScriptCanvas/Libraries/Entity/EntityNodes.h + Include/ScriptCanvas/Libraries/Entity/RotateMethod.h + Include/ScriptCanvas/Libraries/Logic/And.h + Include/ScriptCanvas/Libraries/Logic/Any.h + Include/ScriptCanvas/Libraries/Logic/Any.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Logic/Break.h + Include/ScriptCanvas/Libraries/Logic/Break.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Logic/Cycle.h + Include/ScriptCanvas/Libraries/Logic/Cycle.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Logic/Gate.h + Include/ScriptCanvas/Libraries/Logic/Gate.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Logic/Indexer.h + Include/ScriptCanvas/Libraries/Logic/Indexer.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Logic/IsNull.h + Include/ScriptCanvas/Libraries/Logic/IsNull.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Logic/Logic.h + Include/ScriptCanvas/Libraries/Logic/Multiplexer.h + Include/ScriptCanvas/Libraries/Logic/Multiplexer.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Logic/Not.h + Include/ScriptCanvas/Libraries/Logic/Once.h + Include/ScriptCanvas/Libraries/Logic/Once.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Logic/Or.h + Include/ScriptCanvas/Libraries/Logic/OrderedSequencer.h + Include/ScriptCanvas/Libraries/Logic/OrderedSequencer.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Logic/Sequencer.h + Include/ScriptCanvas/Libraries/Logic/Sequencer.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Logic/TargetedSequencer.h + Include/ScriptCanvas/Libraries/Logic/TargetedSequencer.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Logic/WeightedRandomSequencer.h + Include/ScriptCanvas/Libraries/Logic/WeightedRandomSequencer.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Logic/While.h + Include/ScriptCanvas/Libraries/Logic/While.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Math/AABBNodes.h + Include/ScriptCanvas/Libraries/Math/ColorNodes.h + Include/ScriptCanvas/Libraries/Math/CRCNodes.h + Include/ScriptCanvas/Libraries/Math/Divide.h + Include/ScriptCanvas/Libraries/Math/Math.h + Include/ScriptCanvas/Libraries/Math/MathExpression.h + Include/ScriptCanvas/Libraries/Math/MathExpression.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Math/MathNodeUtilities.h + Include/ScriptCanvas/Libraries/Math/MathGenerics.h + Include/ScriptCanvas/Libraries/Math/MathRandom.h + Include/ScriptCanvas/Libraries/Math/Matrix3x3Nodes.h + Include/ScriptCanvas/Libraries/Math/Matrix4x4Nodes.h + Include/ScriptCanvas/Libraries/Math/Multiply.h + Include/ScriptCanvas/Libraries/Math/OBBNodes.h + Include/ScriptCanvas/Libraries/Math/PlaneNodes.h + Include/ScriptCanvas/Libraries/Math/RotationNodes.h + Include/ScriptCanvas/Libraries/Math/Subtract.h + Include/ScriptCanvas/Libraries/Math/Sum.h + Include/ScriptCanvas/Libraries/Math/TransformNodes.h + Include/ScriptCanvas/Libraries/Math/Vector2Nodes.h + Include/ScriptCanvas/Libraries/Math/Vector3Nodes.h + Include/ScriptCanvas/Libraries/Math/Vector4Nodes.h + Include/ScriptCanvas/Libraries/Comparison/Comparison.h + Include/ScriptCanvas/Libraries/Comparison/ComparisonFunctions.h + Include/ScriptCanvas/Libraries/Comparison/EqualTo.h + Include/ScriptCanvas/Libraries/Comparison/NotEqualTo.h + Include/ScriptCanvas/Libraries/Comparison/Less.h + Include/ScriptCanvas/Libraries/Comparison/Greater.h + Include/ScriptCanvas/Libraries/Comparison/LessEqual.h + Include/ScriptCanvas/Libraries/Comparison/GreaterEqual.h + Include/ScriptCanvas/Libraries/Time/Time.h + Include/ScriptCanvas/Libraries/Time/Countdown.h + Include/ScriptCanvas/Libraries/Time/Countdown.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Time/DelayNodeable.h + Include/ScriptCanvas/Libraries/Time/DelayNodeable.ScriptCanvasNodeable.xml + Include/ScriptCanvas/Libraries/Time/Duration.h + Include/ScriptCanvas/Libraries/Time/Duration.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Time/HeartBeat.h + Include/ScriptCanvas/Libraries/Time/HeartBeat.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Time/Timer.h + Include/ScriptCanvas/Libraries/Time/Timer.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Time/TimeDelayNodeable.h + Include/ScriptCanvas/Libraries/Time/TimeDelayNodeable.ScriptCanvasNodeable.xml + Include/ScriptCanvas/Libraries/Time/DurationNodeable.h + Include/ScriptCanvas/Libraries/Time/DurationNodeable.ScriptCanvasNodeable.xml + Include/ScriptCanvas/Libraries/Time/HeartBeatNodeable.h + Include/ScriptCanvas/Libraries/Time/HeartBeatNodeable.ScriptCanvasNodeable.xml + Include/ScriptCanvas/Libraries/Time/TimerNodeable.h + Include/ScriptCanvas/Libraries/Time/TimerNodeable.ScriptCanvasNodeable.xml + Include/ScriptCanvas/Libraries/Spawning/Spawning.h + Include/ScriptCanvas/Libraries/Spawning/SpawnNodeable.h + Include/ScriptCanvas/Libraries/Spawning/SpawnNodeable.ScriptCanvasNodeable.xml + Include/ScriptCanvas/Libraries/String/Contains.h + Include/ScriptCanvas/Libraries/String/Contains.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/String/Format.h + Include/ScriptCanvas/Libraries/String/Format.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/String/Print.h + Include/ScriptCanvas/Libraries/String/Print.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/String/Replace.h + Include/ScriptCanvas/Libraries/String/Replace.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/String/String.h + Include/ScriptCanvas/Libraries/String/StringMethods.h + Include/ScriptCanvas/Libraries/String/StringGenerics.h + Include/ScriptCanvas/Libraries/String/Utilities.h + Include/ScriptCanvas/Libraries/String/Utilities.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/AddFailure.h + Include/ScriptCanvas/Libraries/UnitTesting/AddFailure.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/AddSuccess.h + Include/ScriptCanvas/Libraries/UnitTesting/AddSuccess.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/Checkpoint.h + Include/ScriptCanvas/Libraries/UnitTesting/Checkpoint.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/ExpectEqual.h + Include/ScriptCanvas/Libraries/UnitTesting/ExpectEqual.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/ExpectFalse.h + Include/ScriptCanvas/Libraries/UnitTesting/ExpectFalse.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThan.h + Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThan.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThanEqual.h + Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThanEqual.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThan.h + Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThan.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThanEqual.h + Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThanEqual.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/ExpectNotEqual.h + Include/ScriptCanvas/Libraries/UnitTesting/ExpectNotEqual.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/ExpectTrue.h + Include/ScriptCanvas/Libraries/UnitTesting/ExpectTrue.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/MarkComplete.h + Include/ScriptCanvas/Libraries/UnitTesting/MarkComplete.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/UnitTestBus.h + Include/ScriptCanvas/Libraries/UnitTesting/UnitTestBusMacros.h + Include/ScriptCanvas/Libraries/UnitTesting/UnitTesting.h + Include/ScriptCanvas/Libraries/UnitTesting/UnitTestingLibrary.h + Include/ScriptCanvas/Libraries/UnitTesting/Auxiliary/Auxiliary.h + Include/ScriptCanvas/Libraries/UnitTesting/Auxiliary/AuxiliaryGenerics.h + Include/ScriptCanvas/Libraries/UnitTesting/UnitTestBusSender.h + Include/ScriptCanvas/Libraries/UnitTesting/UnitTestBusSenderMacros.h + Include/ScriptCanvas/Libraries/Operators/Operators.h + Include/ScriptCanvas/Libraries/Operators/Operator.h + Include/ScriptCanvas/Libraries/Operators/Operator.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorAt.h + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorAt.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorBack.h + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorBack.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorClear.h + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorClear.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorEmpty.h + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorEmpty.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorErase.h + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorErase.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorFront.h + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorFront.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorInsert.h + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorInsert.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorPushBack.h + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorPushBack.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorSize.h + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorSize.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Math/OperatorAdd.h + Include/ScriptCanvas/Libraries/Operators/Math/OperatorAdd.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Math/OperatorArithmetic.h + Include/ScriptCanvas/Libraries/Operators/Math/OperatorArithmetic.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Math/OperatorDiv.h + Include/ScriptCanvas/Libraries/Operators/Math/OperatorDiv.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Math/OperatorDivideByNumber.h + Include/ScriptCanvas/Libraries/Operators/Math/OperatorDivideByNumber.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Math/OperatorLength.h + Include/ScriptCanvas/Libraries/Operators/Math/OperatorLength.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerp.h + Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerp.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Math/OperatorMul.h + Include/ScriptCanvas/Libraries/Operators/Math/OperatorMul.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Math/OperatorSub.h + Include/ScriptCanvas/Libraries/Operators/Math/OperatorSub.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerpNodeable.h + Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerpNodeableNode.h + Include/ScriptCanvas/Profiler/Driller.h + Include/ScriptCanvas/Profiler/Aggregator.h + Include/ScriptCanvas/Profiler/DrillerEvents.h + Include/ScriptCanvas/Serialization/BehaviorContextObjectSerializer.h + Include/ScriptCanvas/Serialization/DatumSerializer.h + Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.h + Include/ScriptCanvas/Data/DataTrait.h + Include/ScriptCanvas/Data/PropertyTraits.h + Include/ScriptCanvas/Data/Traits.h + Include/ScriptCanvas/Variable/VariableBus.h + Include/ScriptCanvas/Variable/GraphVariable.h + Include/ScriptCanvas/Variable/GraphVariableManagerComponent.h + Include/ScriptCanvas/Variable/VariableCore.h + Include/ScriptCanvas/Variable/VariableData.h + Include/ScriptCanvas/Utils/DataUtils.h + Include/ScriptCanvas/Utils/NodeUtils.h + Include/ScriptCanvas/Utils/SerializationUtils.h + Include/ScriptCanvas/Utils/VersionConverters.h + Include/ScriptCanvas/Utils/BehaviorContextUtils.h +) + +set(SKIP_UNITY_BUILD_INCLUSION_FILES + Include/ScriptCanvas/Libraries/Core/FunctionCallNode.h + Include/ScriptCanvas/Libraries/Core/FunctionCallNodeIsOutOfDate.h +) diff --git a/Gems/ScriptCanvasPhysics/Code/CMakeLists.txt b/Gems/ScriptCanvasPhysics/Code/CMakeLists.txt index ac25c7275b..2addf3e8ca 100644 --- a/Gems/ScriptCanvasPhysics/Code/CMakeLists.txt +++ b/Gems/ScriptCanvasPhysics/Code/CMakeLists.txt @@ -32,7 +32,7 @@ ly_add_target( PRIVATE Legacy::CryCommon Gem::ScriptCanvasPhysics.Static - Gem::ScriptCanvas + Gem::ScriptCanvasAPI ) # By default, the above module is used by all application types, however, the module depends at runtime to ScriptCanvas From 5794fa6c9dc3c847be568e0f04f9feea0d48f4bf Mon Sep 17 00:00:00 2001 From: carlitosan <82187351+carlitosan@users.noreply.github.com> Date: Fri, 26 Nov 2021 10:17:14 -0800 Subject: [PATCH 11/47] non-handler static initialization for runtime assets is made recursive on dependencies Signed-off-by: carlitosan <82187351+carlitosan@users.noreply.github.com> --- .../Interpreted/ExecutionInterpretedAPI.cpp | 70 +++++++++++-------- .../Interpreted/ExecutionInterpretedAPI.h | 2 +- .../Interpreted/ExecutionStateInterpreted.cpp | 6 +- 3 files changed, 42 insertions(+), 36 deletions(-) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp index bba56847ce..bbd16dfb96 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp @@ -501,43 +501,53 @@ namespace ScriptCanvas return lua_gettop(lua); } - void InitializeInterpretedStatics(const RuntimeData& runtimeData) + void InitializeInterpretedStatics(RuntimeData& runtimeData) { -#if defined(AZ_PROFILE_BUILD) || defined(AZ_DEBUG_BUILD) - Execution::InitializeFromLuaStackFunctions(const_cast(runtimeData.m_debugMap)); -#endif - AZ_WarningOnce("ScriptCanvas", !runtimeData.m_areStaticsInitialized, "ScriptCanvas runtime data already initalized"); - - if (runtimeData.RequiresStaticInitialization()) + if (!runtimeData.m_areStaticsInitialized) { - AZ::ScriptLoadResult result{}; - AZ::ScriptSystemRequestBus::BroadcastResult(result, &AZ::ScriptSystemRequests::LoadAndGetNativeContext, runtimeData.m_script, AZ::k_scriptLoadBinary, AZ::ScriptContextIds::DefaultScriptContextId); - AZ_Assert(result.status == AZ::ScriptLoadResult::Status::Initial, "ExecutionStateInterpreted script asset was valid but failed to load."); - AZ_Assert(result.lua, "Must have a default script context and a lua_State"); - AZ_Assert(lua_istable(result.lua, -1), "No run-time execution was available for this script"); + runtimeData.m_areStaticsInitialized = true; - auto lua = result.lua; - // Lua: table - lua_getfield(lua, -1, Grammar::k_InitializeStaticsName); - // Lua: table, ? - if (lua_isfunction(lua, -1)) + for (auto& dependency : runtimeData.m_requiredAssets) { - // Lua: table, function - lua_pushvalue(lua, -2); - // Lua: table, function, table - for (auto& clonerSource : runtimeData.m_cloneSources) - { - lua_pushlightuserdata(lua, const_cast(reinterpret_cast(&clonerSource))); - } - // Lua: table, function, table, cloners... - AZ::Internal::LuaSafeCall(lua, aznumeric_caster(runtimeData.m_cloneSources.size() + 1), 0); - // Lua: table - lua_pop(lua, 1); + InitializeInterpretedStatics(dependency.Get()->GetData()); } - else + +#if defined(AZ_PROFILE_BUILD) || defined(AZ_DEBUG_BUILD) + Execution::InitializeFromLuaStackFunctions(const_cast(runtimeData.m_debugMap)); +#endif + AZ_WarningOnce("ScriptCanvas", !runtimeData.m_areStaticsInitialized, "ScriptCanvas runtime data already initalized"); + + if (runtimeData.RequiresStaticInitialization()) { + AZ::ScriptLoadResult result{}; + AZ::ScriptSystemRequestBus::BroadcastResult(result, &AZ::ScriptSystemRequests::LoadAndGetNativeContext, runtimeData.m_script, AZ::k_scriptLoadBinary, AZ::ScriptContextIds::DefaultScriptContextId); + AZ_Assert(result.status == AZ::ScriptLoadResult::Status::Initial, "ExecutionStateInterpreted script asset was valid but failed to load."); + AZ_Assert(result.lua, "Must have a default script context and a lua_State"); + AZ_Assert(lua_istable(result.lua, -1), "No run-time execution was available for this script"); + + auto lua = result.lua; + // Lua: table + lua_getfield(lua, -1, Grammar::k_InitializeStaticsName); // Lua: table, ? - lua_pop(lua, 2); + if (lua_isfunction(lua, -1)) + { + // Lua: table, function + lua_pushvalue(lua, -2); + // Lua: table, function, table + for (auto& clonerSource : runtimeData.m_cloneSources) + { + lua_pushlightuserdata(lua, const_cast(reinterpret_cast(&clonerSource))); + } + // Lua: table, function, table, cloners... + AZ::Internal::LuaSafeCall(lua, aznumeric_caster(runtimeData.m_cloneSources.size() + 1), 0); + // Lua: table + lua_pop(lua, 1); + } + else + { + // Lua: table, ? + lua_pop(lua, 2); + } } } } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.h index c86327bc8d..db8473a468 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.h @@ -43,7 +43,7 @@ namespace ScriptCanvas void InterpretedUnloadData(RuntimeData& runtimeData); - void InitializeInterpretedStatics(const RuntimeData& runtimeData); + void InitializeInterpretedStatics(RuntimeData& runtimeData); int InitializeNodeableOutKeys(lua_State* lua); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.cpp index a92c13ac63..0f090574b5 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.cpp @@ -49,11 +49,7 @@ namespace ScriptCanvas , config.asset.GetId().ToString().data()); #endif - if (!runtimeAsset->GetData().m_areStaticsInitialized) - { - runtimeAsset->GetData().m_areStaticsInitialized = true; - Execution::InitializeInterpretedStatics(runtimeAsset->GetData()); - } + Execution::InitializeInterpretedStatics(runtimeAsset->GetData()); } void ExecutionStateInterpreted::ClearLuaRegistryIndex() From ba732480d07dd0f58138e449c6765c8636fcd814 Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Mon, 29 Nov 2021 12:41:33 -0800 Subject: [PATCH 12/47] Remove LyShineExample Gem's dependency on LmbrCentral and address feedback from previous PR with similar fix for ScriptCanvas Signed-off-by: amzn-sj --- Gems/LmbrCentral/Code/CMakeLists.txt | 11 + Gems/LmbrCentral/Code/lmbrcentral_files.cmake | 53 --- .../Code/lmbrcentral_headers_files.cmake | 63 +++ Gems/LyShineExamples/Code/CMakeLists.txt | 2 +- Gems/ScriptCanvas/Code/CMakeLists.txt | 5 +- .../Code/scriptcanvasgem_common_files.cmake | 365 ------------------ Gems/ScriptCanvasPhysics/Code/CMakeLists.txt | 2 +- 7 files changed, 79 insertions(+), 422 deletions(-) create mode 100644 Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake diff --git a/Gems/LmbrCentral/Code/CMakeLists.txt b/Gems/LmbrCentral/Code/CMakeLists.txt index b047a9f65e..2df0bd0632 100644 --- a/Gems/LmbrCentral/Code/CMakeLists.txt +++ b/Gems/LmbrCentral/Code/CMakeLists.txt @@ -13,6 +13,7 @@ ly_add_target( NAME LmbrCentral.Static STATIC NAMESPACE Gem FILES_CMAKE + lmbrcentral_headers_files.cmake lmbrcentral_files.cmake ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake INCLUDE_DIRECTORIES @@ -27,6 +28,16 @@ ly_add_target( AZ::AzFramework ) +ly_add_target( + NAME LmbrCentral.API HEADERONLY + NAMESPACE Gem + FILES_CMAKE + lmbrcentral_headers_files.cmake + INCLUDE_DIRECTORIES + INTERFACE + include +) + ly_add_target( NAME LmbrCentral ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE} NAMESPACE Gem diff --git a/Gems/LmbrCentral/Code/lmbrcentral_files.cmake b/Gems/LmbrCentral/Code/lmbrcentral_files.cmake index 20a366b5f7..10c9029777 100644 --- a/Gems/LmbrCentral/Code/lmbrcentral_files.cmake +++ b/Gems/LmbrCentral/Code/lmbrcentral_files.cmake @@ -7,59 +7,6 @@ # set(FILES - include/LmbrCentral/Ai/NavigationComponentBus.h - include/LmbrCentral/Ai/NavigationAreaBus.h - include/LmbrCentral/Ai/NavigationSystemBus.h - include/LmbrCentral/Ai/NavigationSeedBus.h - include/LmbrCentral/Animation/AttachmentComponentBus.h - include/LmbrCentral/Animation/SkeletalHierarchyRequestBus.h - include/LmbrCentral/Audio/AudioEnvironmentComponentBus.h - include/LmbrCentral/Audio/AudioListenerComponentBus.h - include/LmbrCentral/Audio/AudioMultiPositionComponentBus.h - include/LmbrCentral/Audio/AudioPreloadComponentBus.h - include/LmbrCentral/Audio/AudioProxyComponentBus.h - include/LmbrCentral/Audio/AudioRtpcComponentBus.h - include/LmbrCentral/Audio/AudioSwitchComponentBus.h - include/LmbrCentral/Audio/AudioSystemComponentBus.h - include/LmbrCentral/Audio/AudioTriggerComponentBus.h - include/LmbrCentral/Bundling/BundlingSystemComponentBus.h - include/LmbrCentral/Geometry/GeometrySystemComponentBus.h - include/LmbrCentral/Dependency/DependencyMonitor.h - include/LmbrCentral/Dependency/DependencyMonitor.inl - include/LmbrCentral/Dependency/DependencyNotificationBus.h - include/LmbrCentral/Physics/WindVolumeRequestBus.h - include/LmbrCentral/Physics/ForceVolumeRequestBus.h - include/LmbrCentral/Physics/WaterNotificationBus.h - include/LmbrCentral/Rendering/DecalComponentBus.h - include/LmbrCentral/Rendering/LightComponentBus.h - include/LmbrCentral/Rendering/MaterialAsset.h - include/LmbrCentral/Rendering/MaterialHandle.h - include/LmbrCentral/Rendering/MeshAsset.h - include/LmbrCentral/Rendering/MeshModificationBus.h - include/LmbrCentral/Rendering/RenderNodeBus.h - include/LmbrCentral/Rendering/GiRegistrationBus.h - include/LmbrCentral/Rendering/RenderBoundsBus.h - include/LmbrCentral/Scripting/EditorTagComponentBus.h - include/LmbrCentral/Scripting/GameplayNotificationBus.h - include/LmbrCentral/Scripting/SimpleStateComponentBus.h - include/LmbrCentral/Scripting/SpawnerComponentBus.h - include/LmbrCentral/Scripting/RandomTimedSpawnerComponentBus.h - include/LmbrCentral/Scripting/TagComponentBus.h - include/LmbrCentral/Shape/EditorShapeComponentBus.h - include/LmbrCentral/Shape/ShapeComponentBus.h - include/LmbrCentral/Shape/SphereShapeComponentBus.h - include/LmbrCentral/Shape/BoxShapeComponentBus.h - include/LmbrCentral/Shape/CylinderShapeComponentBus.h - include/LmbrCentral/Shape/CapsuleShapeComponentBus.h - include/LmbrCentral/Shape/DiskShapeComponentBus.h - include/LmbrCentral/Shape/CompoundShapeComponentBus.h - include/LmbrCentral/Shape/QuadShapeComponentBus.h - include/LmbrCentral/Shape/SplineComponentBus.h - include/LmbrCentral/Shape/PolygonPrismShapeComponentBus.h - include/LmbrCentral/Shape/TubeShapeComponentBus.h - include/LmbrCentral/Shape/SplineAttribute.h - include/LmbrCentral/Shape/SplineAttribute.inl - include/LmbrCentral/Terrain/TerrainSystemRequestBus.h Source/Ai/NavigationSystemComponent.h Source/Ai/NavigationSystemComponent.cpp Source/Audio/AudioAreaEnvironmentComponent.h diff --git a/Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake b/Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake new file mode 100644 index 0000000000..76b5412c58 --- /dev/null +++ b/Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake @@ -0,0 +1,63 @@ +# +# Copyright (c) Contributors to the Open 3D Engine Project. +# For complete copyright and license terms please see the LICENSE at the root of this distribution. +# +# SPDX-License-Identifier: Apache-2.0 OR MIT +# +# + +set(FILES + include/LmbrCentral/Ai/NavigationComponentBus.h + include/LmbrCentral/Ai/NavigationAreaBus.h + include/LmbrCentral/Ai/NavigationSystemBus.h + include/LmbrCentral/Ai/NavigationSeedBus.h + include/LmbrCentral/Animation/AttachmentComponentBus.h + include/LmbrCentral/Animation/SkeletalHierarchyRequestBus.h + include/LmbrCentral/Audio/AudioEnvironmentComponentBus.h + include/LmbrCentral/Audio/AudioListenerComponentBus.h + include/LmbrCentral/Audio/AudioMultiPositionComponentBus.h + include/LmbrCentral/Audio/AudioPreloadComponentBus.h + include/LmbrCentral/Audio/AudioProxyComponentBus.h + include/LmbrCentral/Audio/AudioRtpcComponentBus.h + include/LmbrCentral/Audio/AudioSwitchComponentBus.h + include/LmbrCentral/Audio/AudioSystemComponentBus.h + include/LmbrCentral/Audio/AudioTriggerComponentBus.h + include/LmbrCentral/Bundling/BundlingSystemComponentBus.h + include/LmbrCentral/Geometry/GeometrySystemComponentBus.h + include/LmbrCentral/Dependency/DependencyMonitor.h + include/LmbrCentral/Dependency/DependencyMonitor.inl + include/LmbrCentral/Dependency/DependencyNotificationBus.h + include/LmbrCentral/Physics/WindVolumeRequestBus.h + include/LmbrCentral/Physics/ForceVolumeRequestBus.h + include/LmbrCentral/Physics/WaterNotificationBus.h + include/LmbrCentral/Rendering/DecalComponentBus.h + include/LmbrCentral/Rendering/LightComponentBus.h + include/LmbrCentral/Rendering/MaterialAsset.h + include/LmbrCentral/Rendering/MaterialHandle.h + include/LmbrCentral/Rendering/MeshAsset.h + include/LmbrCentral/Rendering/MeshModificationBus.h + include/LmbrCentral/Rendering/RenderNodeBus.h + include/LmbrCentral/Rendering/GiRegistrationBus.h + include/LmbrCentral/Rendering/RenderBoundsBus.h + include/LmbrCentral/Scripting/EditorTagComponentBus.h + include/LmbrCentral/Scripting/GameplayNotificationBus.h + include/LmbrCentral/Scripting/SimpleStateComponentBus.h + include/LmbrCentral/Scripting/SpawnerComponentBus.h + include/LmbrCentral/Scripting/RandomTimedSpawnerComponentBus.h + include/LmbrCentral/Scripting/TagComponentBus.h + include/LmbrCentral/Shape/EditorShapeComponentBus.h + include/LmbrCentral/Shape/ShapeComponentBus.h + include/LmbrCentral/Shape/SphereShapeComponentBus.h + include/LmbrCentral/Shape/BoxShapeComponentBus.h + include/LmbrCentral/Shape/CylinderShapeComponentBus.h + include/LmbrCentral/Shape/CapsuleShapeComponentBus.h + include/LmbrCentral/Shape/DiskShapeComponentBus.h + include/LmbrCentral/Shape/CompoundShapeComponentBus.h + include/LmbrCentral/Shape/QuadShapeComponentBus.h + include/LmbrCentral/Shape/SplineComponentBus.h + include/LmbrCentral/Shape/PolygonPrismShapeComponentBus.h + include/LmbrCentral/Shape/TubeShapeComponentBus.h + include/LmbrCentral/Shape/SplineAttribute.h + include/LmbrCentral/Shape/SplineAttribute.inl + include/LmbrCentral/Terrain/TerrainSystemRequestBus.h +) \ No newline at end of file diff --git a/Gems/LyShineExamples/Code/CMakeLists.txt b/Gems/LyShineExamples/Code/CMakeLists.txt index 5cd023db02..6e8f53d5cd 100644 --- a/Gems/LyShineExamples/Code/CMakeLists.txt +++ b/Gems/LyShineExamples/Code/CMakeLists.txt @@ -37,7 +37,7 @@ ly_add_target( BUILD_DEPENDENCIES PRIVATE Gem::LyShineExamples.Static - Gem::LmbrCentral + Gem::LmbrCentral.API ) # if enabled, LyShineExamples is used by all kinds of applications, however, the dependency to LmbrCentral is different diff --git a/Gems/ScriptCanvas/Code/CMakeLists.txt b/Gems/ScriptCanvas/Code/CMakeLists.txt index 25b0099e88..f83f0d3593 100644 --- a/Gems/ScriptCanvas/Code/CMakeLists.txt +++ b/Gems/ScriptCanvas/Code/CMakeLists.txt @@ -57,6 +57,7 @@ ly_add_target( NAME ScriptCanvas.Static STATIC NAMESPACE Gem FILES_CMAKE + scriptcanvasgem_headers.cmake scriptcanvasgem_common_files.cmake scriptcanvasgem_runtime_asset_files.cmake INCLUDE_DIRECTORIES @@ -90,7 +91,7 @@ ly_add_target( ) ly_add_target( - NAME ScriptCanvasAPI HEADERONLY + NAME ScriptCanvas.API HEADERONLY NAMESPACE Gem FILES_CMAKE scriptcanvasgem_headers.cmake @@ -102,7 +103,7 @@ ly_add_target( INTERFACE . Include - Include/ScriptCanvas + ${SCRIPT_CANVAS_AUTOGEN_BUILD_DIR} ) ly_add_target( diff --git a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake index 7984340b7a..eb50f5cb51 100644 --- a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake +++ b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake @@ -7,575 +7,210 @@ # set(FILES - Include/ScriptCanvas/SystemComponent.h Source/SystemComponent.cpp Source/ScriptCanvasCommonGem.cpp Source/PerformanceStatistician.cpp Source/PerformanceTracker.cpp - Include/ScriptCanvas/ScriptCanvasGem.h - Include/ScriptCanvas/Asset/AssetDescription.h Include/ScriptCanvas/Asset/AssetRegistry.cpp - Include/ScriptCanvas/Asset/AssetRegistry.h - Include/ScriptCanvas/Asset/AssetRegistryBus.h Include/ScriptCanvas/Asset/ExecutionLogAsset.cpp - Include/ScriptCanvas/Asset/ExecutionLogAsset.h - Include/ScriptCanvas/Asset/ExecutionLogAssetBus.h Include/ScriptCanvas/Asset/RuntimeAsset.cpp - Include/ScriptCanvas/Asset/RuntimeAsset.h Include/ScriptCanvas/Asset/RuntimeAssetHandler.cpp - Include/ScriptCanvas/Asset/RuntimeAssetHandler.h - Include/ScriptCanvas/Asset/ScriptCanvasAssetBase.h - Include/ScriptCanvas/Asset/ScriptCanvasAssetData.h Include/ScriptCanvas/Asset/SubgraphInterfaceAssetHandler.cpp - Include/ScriptCanvas/Asset/SubgraphInterfaceAssetHandler.h - Include/ScriptCanvas/Core/ScriptCanvasBus.h Include/ScriptCanvas/Core/ExecutionNotificationsBus.cpp - Include/ScriptCanvas/Core/ExecutionNotificationsBus.h - Include/ScriptCanvas/Core/GraphBus.h - Include/ScriptCanvas/Core/NodeBus.h - Include/ScriptCanvas/Core/EBusNodeBus.h - Include/ScriptCanvas/Core/NodelingBus.h - Include/ScriptCanvas/Core/ContractBus.h - Include/ScriptCanvas/Core/Attributes.h Include/ScriptCanvas/Core/Connection.cpp - Include/ScriptCanvas/Core/Connection.h - Include/ScriptCanvas/Core/ConnectionBus.h Include/ScriptCanvas/Core/Contract.cpp - Include/ScriptCanvas/Core/Contract.h - Include/ScriptCanvas/Core/Contracts.h - Include/ScriptCanvas/Core/Contracts/MethodOverloadContract.h Include/ScriptCanvas/Core/Contracts/MethodOverloadContract.cpp - Include/ScriptCanvas/Core/Contracts/RestrictedNodeContract.h Include/ScriptCanvas/Core/Contracts/RestrictedNodeContract.cpp Include/ScriptCanvas/Core/Core.cpp - Include/ScriptCanvas/Core/Core.h Include/ScriptCanvas/Core/Datum.cpp - Include/ScriptCanvas/Core/Datum.h - Include/ScriptCanvas/Core/DatumBus.h - Include/ScriptCanvas/Core/EBusHandler.h Include/ScriptCanvas/Core/EBusHandler.cpp Include/ScriptCanvas/Core/Endpoint.cpp - Include/ScriptCanvas/Core/Endpoint.h Include/ScriptCanvas/Core/Graph.cpp - Include/ScriptCanvas/Core/Graph.h - Include/ScriptCanvas/Core/GraphData.h Include/ScriptCanvas/Core/GraphData.cpp - Include/ScriptCanvas/Core/GraphScopedTypes.h - Include/ScriptCanvas/Core/MethodConfiguration.h Include/ScriptCanvas/Core/MethodConfiguration.cpp Include/ScriptCanvas/Core/ModifiableDatumView.cpp - Include/ScriptCanvas/Core/ModifiableDatumView.h Include/ScriptCanvas/Core/Node.cpp - Include/ScriptCanvas/Core/Node.h Include/ScriptCanvas/Core/Nodeable.cpp - Include/ScriptCanvas/Core/Nodeable.h Include/ScriptCanvas/Core/NodeableNode.cpp - Include/ScriptCanvas/Core/NodeableNode.h Include/ScriptCanvas/Core/NodeableNodeOverloaded.cpp - Include/ScriptCanvas/Core/NodeableNodeOverloaded.h - Include/ScriptCanvas/Core/NodeFunctionGeneric.h - Include/ScriptCanvas/Core/SerializationListener.h Include/ScriptCanvas/Core/Slot.cpp - Include/ScriptCanvas/Core/Slot.h - Include/ScriptCanvas/Core/SlotConfigurationDefaults.h Include/ScriptCanvas/Core/SlotConfigurations.cpp - Include/ScriptCanvas/Core/SlotConfigurations.h Include/ScriptCanvas/Core/SlotExecutionMap.cpp - Include/ScriptCanvas/Core/SlotExecutionMap.h Include/ScriptCanvas/Core/SlotMetadata.cpp - Include/ScriptCanvas/Core/SlotMetadata.h - Include/ScriptCanvas/Core/SlotNames.h - Include/ScriptCanvas/Core/SubgraphInterface.h Include/ScriptCanvas/Core/SubgraphInterface.cpp - Include/ScriptCanvas/Core/SubgraphInterfaceUtility.h Include/ScriptCanvas/Core/SubgraphInterfaceUtility.cpp - Include/ScriptCanvas/Translation/AbstractModelTranslator.h - Include/ScriptCanvas/Translation/Configuration.h Include/ScriptCanvas/Translation/GraphToCPlusPlus.cpp - Include/ScriptCanvas/Translation/GraphToCPlusPlus.h - Include/ScriptCanvas/Translation/GraphToLua.h Include/ScriptCanvas/Translation/GraphToLua.cpp - Include/ScriptCanvas/Translation/GraphToLuaUtility.h Include/ScriptCanvas/Translation/GraphToLuaUtility.cpp - Include/ScriptCanvas/Translation/GraphToX.h Include/ScriptCanvas/Translation/GraphToX.cpp - Include/ScriptCanvas/Translation/Translation.h Include/ScriptCanvas/Translation/Translation.cpp - Include/ScriptCanvas/Translation/TranslationContext.h Include/ScriptCanvas/Translation/TranslationContext.cpp - Include/ScriptCanvas/Translation/TranslationResult.h Include/ScriptCanvas/Translation/TranslationResult.cpp - Include/ScriptCanvas/Translation/TranslationUtilities.h Include/ScriptCanvas/Translation/TranslationUtilities.cpp - Include/ScriptCanvas/PerformanceStatistician.h - Include/ScriptCanvas/PerformanceStatisticsBus.h - Include/ScriptCanvas/PerformanceTracker.h - Include/ScriptCanvas/AutoGen/ScriptCanvas_Macros.jinja - Include/ScriptCanvas/AutoGen/ScriptCanvas_Nodeable_Macros.jinja - Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja - Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja - Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Header.jinja - Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja - Include/ScriptCanvas/CodeGen/NodeableCodegen.h Include/ScriptCanvas/Core/Contracts/ConnectionLimitContract.cpp - Include/ScriptCanvas/Core/Contracts/ConnectionLimitContract.h Include/ScriptCanvas/Core/Contracts/ContractRTTI.cpp - Include/ScriptCanvas/Core/Contracts/ContractRTTI.h Include/ScriptCanvas/Core/Contracts/DisallowReentrantExecutionContract.cpp - Include/ScriptCanvas/Core/Contracts/DisallowReentrantExecutionContract.h Include/ScriptCanvas/Core/Contracts/DisplayGroupConnectedSlotLimitContract.cpp - Include/ScriptCanvas/Core/Contracts/DisplayGroupConnectedSlotLimitContract.h Include/ScriptCanvas/Core/Contracts/DynamicTypeContract.cpp - Include/ScriptCanvas/Core/Contracts/DynamicTypeContract.h Include/ScriptCanvas/Core/Contracts/IsReferenceTypeContract.cpp - Include/ScriptCanvas/Core/Contracts/IsReferenceTypeContract.h Include/ScriptCanvas/Core/Contracts/MathOperatorContract.cpp - Include/ScriptCanvas/Core/Contracts/MathOperatorContract.h Include/ScriptCanvas/Core/Contracts/SlotTypeContract.cpp - Include/ScriptCanvas/Core/Contracts/SlotTypeContract.h Include/ScriptCanvas/Core/Contracts/SupportsMethodContract.cpp - Include/ScriptCanvas/Core/Contracts/SupportsMethodContract.h Include/ScriptCanvas/Core/Contracts/TypeContract.cpp - Include/ScriptCanvas/Core/Contracts/TypeContract.h Include/ScriptCanvas/Data/BehaviorContextObject.cpp - Include/ScriptCanvas/Data/BehaviorContextObject.h Include/ScriptCanvas/Data/BehaviorContextObjectPtr.cpp - Include/ScriptCanvas/Data/BehaviorContextObjectPtr.h Include/ScriptCanvas/Data/Data.cpp - Include/ScriptCanvas/Data/Data.h - Include/ScriptCanvas/Data/DataMacros.h Include/ScriptCanvas/Data/DataRegistry.cpp - Include/ScriptCanvas/Data/DataRegistry.h - Include/ScriptCanvas/Data/NumericData.h - Include/ScriptCanvas/Deprecated/VariableDatumBase.h Include/ScriptCanvas/Deprecated/VariableDatumBase.cpp - Include/ScriptCanvas/Deprecated/VariableDatum.h Include/ScriptCanvas/Deprecated/VariableDatum.cpp - Include/ScriptCanvas/Deprecated/VariableHelpers.h Include/ScriptCanvas/Deprecated/VariableHelpers.cpp - Include/ScriptCanvas/Execution/ErrorBus.h - Include/ScriptCanvas/Execution/ExecutionBus.h - Include/ScriptCanvas/Execution/ExecutionContext.h Include/ScriptCanvas/Execution/ExecutionContext.cpp - Include/ScriptCanvas/Execution/ExecutionObjectCloning.h Include/ScriptCanvas/Execution/ExecutionObjectCloning.cpp - Include/ScriptCanvas/Execution/ExecutionPerformanceTimer.h Include/ScriptCanvas/Execution/ExecutionPerformanceTimer.cpp - Include/ScriptCanvas/Execution/ExecutionState.h Include/ScriptCanvas/Execution/ExecutionState.cpp - Include/ScriptCanvas/Execution/ExecutionStateDeclarations.h - Include/ScriptCanvas/Execution/NativeHostDeclarations.h Include/ScriptCanvas/Execution/NativeHostDeclarations.cpp - Include/ScriptCanvas/Execution/NativeHostDefinitions.h Include/ScriptCanvas/Execution/NativeHostDefinitions.cpp - Include/ScriptCanvas/Execution/RuntimeComponent.h Include/ScriptCanvas/Execution/RuntimeComponent.cpp - Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.h Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp - Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedCloningAPI.h Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedCloningAPI.cpp - Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedDebugAPI.h Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedDebugAPI.cpp - Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedEBusAPI.h Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedEBusAPI.cpp - Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedOut.h Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedOut.cpp - Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.h Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.cpp - Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedPerActivation.h Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedPerActivation.cpp - Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedPure.h Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedPure.cpp - Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedSingleton.h Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedSingleton.cpp - Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedUtility.h Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedUtility.cpp - Include/ScriptCanvas/Execution/NodeableOut/NodeableOutNative.h - Include/ScriptCanvas/Grammar/AbstractCodeModel.h Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp - Include/ScriptCanvas/Grammar/DebugMap.h Include/ScriptCanvas/Grammar/DebugMap.cpp - Include/ScriptCanvas/Grammar/ExecutionTraversalListeners.h Include/ScriptCanvas/Grammar/ExecutionTraversalListeners.cpp - Include/ScriptCanvas/Grammar/ParsingMetaData.h Include/ScriptCanvas/Grammar/ParsingMetaData.cpp - Include/ScriptCanvas/Grammar/ParsingUtilities.h Include/ScriptCanvas/Grammar/ParsingUtilities.cpp - Include/ScriptCanvas/Grammar/Primitives.h Include/ScriptCanvas/Grammar/Primitives.cpp - Include/ScriptCanvas/Grammar/PrimitivesDeclarations.h Include/ScriptCanvas/Grammar/PrimitivesDeclarations.cpp Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp - Include/ScriptCanvas/Grammar/PrimitivesExecution.h - Include/ScriptCanvas/Grammar/SymbolNames.h - Include/ScriptCanvas/Execution/ErrorBus.h Include/ScriptCanvas/Execution/ExecutionContext.cpp - Include/ScriptCanvas/Execution/ExecutionContext.h - Include/ScriptCanvas/Execution/ExecutionBus.h Include/ScriptCanvas/Execution/NativeHostDeclarations.cpp - Include/ScriptCanvas/Execution/NativeHostDeclarations.h Include/ScriptCanvas/Execution/NativeHostDefinitions.cpp - Include/ScriptCanvas/Execution/NativeHostDefinitions.h Include/ScriptCanvas/Execution/RuntimeComponent.cpp - Include/ScriptCanvas/Execution/RuntimeComponent.h Include/ScriptCanvas/Internal/Nodeables/BaseTimer.cpp - Include/ScriptCanvas/Internal/Nodeables/BaseTimer.h - Include/ScriptCanvas/Internal/Nodeables/BaseTimer.ScriptCanvasNodeable.xml Include/ScriptCanvas/Internal/Nodes/BaseTimerNode.cpp - Include/ScriptCanvas/Internal/Nodes/BaseTimerNode.h - Include/ScriptCanvas/Internal/Nodes/BaseTimerNode.ScriptCanvasGrammar.xml Include/ScriptCanvas/Internal/Nodes/ExpressionNodeBase.cpp - Include/ScriptCanvas/Internal/Nodes/ExpressionNodeBase.h - Include/ScriptCanvas/Internal/Nodes/ExpressionNodeBase.ScriptCanvasGrammar.xml Include/ScriptCanvas/Internal/Nodes/StringFormatted.cpp - Include/ScriptCanvas/Internal/Nodes/StringFormatted.h - Include/ScriptCanvas/Internal/Nodes/StringFormatted.ScriptCanvasGrammar.xml Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp - Include/ScriptCanvas/Grammar/AbstractCodeModel.h - Include/ScriptCanvas/Libraries/Libraries.h Include/ScriptCanvas/Libraries/Libraries.cpp Include/ScriptCanvas/Libraries/Core/AzEventHandler.cpp - Include/ScriptCanvas/Libraries/Core/AzEventHandler.h - Include/ScriptCanvas/Libraries/Core/AzEventHandler.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Core/BinaryOperator.cpp - Include/ScriptCanvas/Libraries/Core/BinaryOperator.h Include/ScriptCanvas/Libraries/Core/CoreNodes.cpp - Include/ScriptCanvas/Libraries/Core/CoreNodes.h - Include/ScriptCanvas/Libraries/Core/ContainerTypeReflection.h Include/ScriptCanvas/Libraries/Core/EBusEventHandler.cpp - Include/ScriptCanvas/Libraries/Core/EBusEventHandler.h - Include/ScriptCanvas/Libraries/Core/EBusEventHandler.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Core/ExtractProperty.cpp - Include/ScriptCanvas/Libraries/Core/ExtractProperty.h - Include/ScriptCanvas/Libraries/Core/ExtractProperty.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Core/EventHandlerTranslationUtility.h Include/ScriptCanvas/Libraries/Core/EventHandlerTranslationUtility.cpp Include/ScriptCanvas/Libraries/Core/ForEach.cpp - Include/ScriptCanvas/Libraries/Core/ForEach.h - Include/ScriptCanvas/Libraries/Core/ForEach.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Core/FunctionBus.h Include/ScriptCanvas/Libraries/Core/FunctionCallNode.cpp - Include/ScriptCanvas/Libraries/Core/FunctionCallNode.h - Include/ScriptCanvas/Libraries/Core/FunctionCallNode.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Core/FunctionCallNodeIsOutOfDate.h Include/ScriptCanvas/Libraries/Core/FunctionCallNodeIsOutOfDate.cpp Include/ScriptCanvas/Libraries/Core/FunctionDefinitionNode.cpp - Include/ScriptCanvas/Libraries/Core/FunctionDefinitionNode.h - Include/ScriptCanvas/Libraries/Core/FunctionDefinitionNode.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Core/GetVariable.cpp - Include/ScriptCanvas/Libraries/Core/GetVariable.h - Include/ScriptCanvas/Libraries/Core/GetVariable.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Core/Method.cpp - Include/ScriptCanvas/Libraries/Core/Method.h Include/ScriptCanvas/Libraries/Core/MethodOverloaded.cpp - Include/ScriptCanvas/Libraries/Core/MethodOverloaded.h Include/ScriptCanvas/Libraries/Core/MethodUtility.cpp - Include/ScriptCanvas/Libraries/Core/MethodUtility.h Include/ScriptCanvas/Libraries/Core/Nodeling.cpp - Include/ScriptCanvas/Libraries/Core/Nodeling.h - Include/ScriptCanvas/Libraries/Core/Nodeling.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.cpp - Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.h - Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Core/Repeater.cpp - Include/ScriptCanvas/Libraries/Core/Repeater.h - Include/ScriptCanvas/Libraries/Core/Repeater.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Core/RepeaterNodeable.h Include/ScriptCanvas/Libraries/Core/RepeaterNodeable.cpp - Include/ScriptCanvas/Libraries/Core/RepeaterNodeable.ScriptCanvasNodeable.xml Include/ScriptCanvas/Libraries/Core/ScriptEventBase.cpp - Include/ScriptCanvas/Libraries/Core/ScriptEventBase.h - Include/ScriptCanvas/Libraries/Core/ScriptEventBase.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Core/SendScriptEvent.cpp - Include/ScriptCanvas/Libraries/Core/SendScriptEvent.h - Include/ScriptCanvas/Libraries/Core/SendScriptEvent.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Core/SetVariable.cpp - Include/ScriptCanvas/Libraries/Core/SetVariable.h - Include/ScriptCanvas/Libraries/Core/SetVariable.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Core/Start.h - Include/ScriptCanvas/Libraries/Core/Start.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Core/UnaryOperator.cpp - Include/ScriptCanvas/Libraries/Core/UnaryOperator.h Include/ScriptCanvas/Libraries/Entity/Entity.cpp - Include/ScriptCanvas/Libraries/Entity/Entity.h - Include/ScriptCanvas/Libraries/Entity/EntityNodes.h Include/ScriptCanvas/Libraries/Entity/RotateMethod.cpp - Include/ScriptCanvas/Libraries/Entity/RotateMethod.h - Include/ScriptCanvas/Libraries/Logic/And.h Include/ScriptCanvas/Libraries/Logic/Any.cpp - Include/ScriptCanvas/Libraries/Logic/Any.h - Include/ScriptCanvas/Libraries/Logic/Any.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Logic/Break.h Include/ScriptCanvas/Libraries/Logic/Break.cpp - Include/ScriptCanvas/Libraries/Logic/Break.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Logic/Cycle.cpp - Include/ScriptCanvas/Libraries/Logic/Cycle.h - Include/ScriptCanvas/Libraries/Logic/Cycle.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Logic/Gate.cpp - Include/ScriptCanvas/Libraries/Logic/Gate.h - Include/ScriptCanvas/Libraries/Logic/Gate.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Logic/Indexer.h - Include/ScriptCanvas/Libraries/Logic/Indexer.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Logic/IsNull.cpp - Include/ScriptCanvas/Libraries/Logic/IsNull.h - Include/ScriptCanvas/Libraries/Logic/IsNull.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Logic/Logic.cpp - Include/ScriptCanvas/Libraries/Logic/Logic.h - Include/ScriptCanvas/Libraries/Logic/Multiplexer.h - Include/ScriptCanvas/Libraries/Logic/Multiplexer.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Logic/Not.h Include/ScriptCanvas/Libraries/Logic/Once.cpp - Include/ScriptCanvas/Libraries/Logic/Once.h - Include/ScriptCanvas/Libraries/Logic/Once.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Logic/Or.h Include/ScriptCanvas/Libraries/Logic/OrderedSequencer.cpp - Include/ScriptCanvas/Libraries/Logic/OrderedSequencer.h - Include/ScriptCanvas/Libraries/Logic/OrderedSequencer.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Logic/Sequencer.cpp - Include/ScriptCanvas/Libraries/Logic/Sequencer.h - Include/ScriptCanvas/Libraries/Logic/Sequencer.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Logic/TargetedSequencer.cpp - Include/ScriptCanvas/Libraries/Logic/TargetedSequencer.h - Include/ScriptCanvas/Libraries/Logic/TargetedSequencer.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Logic/WeightedRandomSequencer.cpp - Include/ScriptCanvas/Libraries/Logic/WeightedRandomSequencer.h - Include/ScriptCanvas/Libraries/Logic/WeightedRandomSequencer.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Logic/While.cpp - Include/ScriptCanvas/Libraries/Logic/While.h - Include/ScriptCanvas/Libraries/Logic/While.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Math/AABBNodes.h - Include/ScriptCanvas/Libraries/Math/ColorNodes.h - Include/ScriptCanvas/Libraries/Math/CRCNodes.h - Include/ScriptCanvas/Libraries/Math/Divide.h Include/ScriptCanvas/Libraries/Math/Math.cpp - Include/ScriptCanvas/Libraries/Math/Math.h Include/ScriptCanvas/Libraries/Math/MathExpression.cpp - Include/ScriptCanvas/Libraries/Math/MathExpression.h - Include/ScriptCanvas/Libraries/Math/MathExpression.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Math/MathNodeUtilities.cpp - Include/ScriptCanvas/Libraries/Math/MathNodeUtilities.h - Include/ScriptCanvas/Libraries/Math/MathGenerics.h - Include/ScriptCanvas/Libraries/Math/MathRandom.h - Include/ScriptCanvas/Libraries/Math/Matrix3x3Nodes.h - Include/ScriptCanvas/Libraries/Math/Matrix4x4Nodes.h - Include/ScriptCanvas/Libraries/Math/Multiply.h - Include/ScriptCanvas/Libraries/Math/OBBNodes.h - Include/ScriptCanvas/Libraries/Math/PlaneNodes.h - Include/ScriptCanvas/Libraries/Math/RotationNodes.h - Include/ScriptCanvas/Libraries/Math/Subtract.h - Include/ScriptCanvas/Libraries/Math/Sum.h - Include/ScriptCanvas/Libraries/Math/TransformNodes.h - Include/ScriptCanvas/Libraries/Math/Vector2Nodes.h - Include/ScriptCanvas/Libraries/Math/Vector3Nodes.h - Include/ScriptCanvas/Libraries/Math/Vector4Nodes.h - Include/ScriptCanvas/Libraries/Comparison/Comparison.h Include/ScriptCanvas/Libraries/Comparison/Comparison.cpp - Include/ScriptCanvas/Libraries/Comparison/ComparisonFunctions.h - Include/ScriptCanvas/Libraries/Comparison/EqualTo.h - Include/ScriptCanvas/Libraries/Comparison/NotEqualTo.h - Include/ScriptCanvas/Libraries/Comparison/Less.h - Include/ScriptCanvas/Libraries/Comparison/Greater.h - Include/ScriptCanvas/Libraries/Comparison/LessEqual.h - Include/ScriptCanvas/Libraries/Comparison/GreaterEqual.h - Include/ScriptCanvas/Libraries/Time/Time.h Include/ScriptCanvas/Libraries/Time/Time.cpp Include/ScriptCanvas/Libraries/Time/Countdown.cpp - Include/ScriptCanvas/Libraries/Time/Countdown.h - Include/ScriptCanvas/Libraries/Time/Countdown.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Time/DelayNodeable.h Include/ScriptCanvas/Libraries/Time/DelayNodeable.cpp - Include/ScriptCanvas/Libraries/Time/DelayNodeable.ScriptCanvasNodeable.xml Include/ScriptCanvas/Libraries/Time/Duration.cpp - Include/ScriptCanvas/Libraries/Time/Duration.h - Include/ScriptCanvas/Libraries/Time/Duration.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Time/HeartBeat.cpp - Include/ScriptCanvas/Libraries/Time/HeartBeat.h - Include/ScriptCanvas/Libraries/Time/HeartBeat.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Time/Timer.cpp - Include/ScriptCanvas/Libraries/Time/Timer.h - Include/ScriptCanvas/Libraries/Time/Timer.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Time/TimeDelayNodeable.h Include/ScriptCanvas/Libraries/Time/TimeDelayNodeable.cpp - Include/ScriptCanvas/Libraries/Time/TimeDelayNodeable.ScriptCanvasNodeable.xml - Include/ScriptCanvas/Libraries/Time/DurationNodeable.h Include/ScriptCanvas/Libraries/Time/DurationNodeable.cpp - Include/ScriptCanvas/Libraries/Time/DurationNodeable.ScriptCanvasNodeable.xml - Include/ScriptCanvas/Libraries/Time/HeartBeatNodeable.h Include/ScriptCanvas/Libraries/Time/HeartBeatNodeable.cpp - Include/ScriptCanvas/Libraries/Time/HeartBeatNodeable.ScriptCanvasNodeable.xml - Include/ScriptCanvas/Libraries/Time/TimerNodeable.h Include/ScriptCanvas/Libraries/Time/TimerNodeable.cpp - Include/ScriptCanvas/Libraries/Time/TimerNodeable.ScriptCanvasNodeable.xml Include/ScriptCanvas/Libraries/Spawning/Spawning.cpp - Include/ScriptCanvas/Libraries/Spawning/Spawning.h Include/ScriptCanvas/Libraries/Spawning/SpawnNodeable.cpp - Include/ScriptCanvas/Libraries/Spawning/SpawnNodeable.h - Include/ScriptCanvas/Libraries/Spawning/SpawnNodeable.ScriptCanvasNodeable.xml Include/ScriptCanvas/Libraries/String/Contains.cpp - Include/ScriptCanvas/Libraries/String/Contains.h - Include/ScriptCanvas/Libraries/String/Contains.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/String/Format.cpp - Include/ScriptCanvas/Libraries/String/Format.h - Include/ScriptCanvas/Libraries/String/Format.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/String/Print.h - Include/ScriptCanvas/Libraries/String/Print.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/String/Replace.cpp - Include/ScriptCanvas/Libraries/String/Replace.h - Include/ScriptCanvas/Libraries/String/Replace.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/String/String.h Include/ScriptCanvas/Libraries/String/String.cpp - Include/ScriptCanvas/Libraries/String/StringMethods.h Include/ScriptCanvas/Libraries/String/StringMethods.cpp - Include/ScriptCanvas/Libraries/String/StringGenerics.h Include/ScriptCanvas/Libraries/String/Utilities.cpp - Include/ScriptCanvas/Libraries/String/Utilities.h - Include/ScriptCanvas/Libraries/String/Utilities.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/UnitTesting/AddFailure.cpp - Include/ScriptCanvas/Libraries/UnitTesting/AddFailure.h - Include/ScriptCanvas/Libraries/UnitTesting/AddFailure.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/UnitTesting/AddSuccess.h - Include/ScriptCanvas/Libraries/UnitTesting/AddSuccess.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/UnitTesting/Checkpoint.h - Include/ScriptCanvas/Libraries/UnitTesting/Checkpoint.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/UnitTesting/ExpectEqual.cpp - Include/ScriptCanvas/Libraries/UnitTesting/ExpectEqual.h - Include/ScriptCanvas/Libraries/UnitTesting/ExpectEqual.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/UnitTesting/ExpectFalse.cpp - Include/ScriptCanvas/Libraries/UnitTesting/ExpectFalse.h - Include/ScriptCanvas/Libraries/UnitTesting/ExpectFalse.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThan.cpp - Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThan.h - Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThan.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThanEqual.cpp - Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThanEqual.h - Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThanEqual.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThan.cpp - Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThan.h - Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThan.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThanEqual.cpp - Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThanEqual.h - Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThanEqual.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/UnitTesting/ExpectNotEqual.cpp - Include/ScriptCanvas/Libraries/UnitTesting/ExpectNotEqual.h - Include/ScriptCanvas/Libraries/UnitTesting/ExpectNotEqual.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/UnitTesting/ExpectTrue.cpp - Include/ScriptCanvas/Libraries/UnitTesting/ExpectTrue.h - Include/ScriptCanvas/Libraries/UnitTesting/ExpectTrue.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/UnitTesting/MarkComplete.h - Include/ScriptCanvas/Libraries/UnitTesting/MarkComplete.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/UnitTesting/UnitTestBus.h - Include/ScriptCanvas/Libraries/UnitTesting/UnitTestBusMacros.h Include/ScriptCanvas/Libraries/UnitTesting/UnitTesting.cpp - Include/ScriptCanvas/Libraries/UnitTesting/UnitTesting.h Include/ScriptCanvas/Libraries/UnitTesting/UnitTestingLibrary.cpp - Include/ScriptCanvas/Libraries/UnitTesting/UnitTestingLibrary.h Include/ScriptCanvas/Libraries/UnitTesting/Auxiliary/Auxiliary.cpp - Include/ScriptCanvas/Libraries/UnitTesting/Auxiliary/Auxiliary.h - Include/ScriptCanvas/Libraries/UnitTesting/Auxiliary/AuxiliaryGenerics.h - Include/ScriptCanvas/Libraries/UnitTesting/UnitTestBusSender.h Include/ScriptCanvas/Libraries/UnitTesting/UnitTestBusSender.cpp - Include/ScriptCanvas/Libraries/UnitTesting/UnitTestBusSenderMacros.h Include/ScriptCanvas/Libraries/Operators/Operators.cpp - Include/ScriptCanvas/Libraries/Operators/Operators.h Include/ScriptCanvas/Libraries/Operators/Operator.cpp - Include/ScriptCanvas/Libraries/Operators/Operator.h - Include/ScriptCanvas/Libraries/Operators/Operator.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Containers/OperatorAt.cpp - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorAt.h - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorAt.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Containers/OperatorBack.cpp - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorBack.h - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorBack.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Containers/OperatorClear.cpp - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorClear.h - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorClear.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Containers/OperatorEmpty.cpp - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorEmpty.h - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorEmpty.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Containers/OperatorErase.cpp - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorErase.h - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorErase.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Containers/OperatorFront.cpp - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorFront.h - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorFront.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Containers/OperatorInsert.cpp - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorInsert.h - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorInsert.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Containers/OperatorPushBack.cpp - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorPushBack.h - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorPushBack.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Containers/OperatorSize.cpp - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorSize.h - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorSize.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Math/OperatorAdd.cpp - Include/ScriptCanvas/Libraries/Operators/Math/OperatorAdd.h - Include/ScriptCanvas/Libraries/Operators/Math/OperatorAdd.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Math/OperatorArithmetic.cpp - Include/ScriptCanvas/Libraries/Operators/Math/OperatorArithmetic.h - Include/ScriptCanvas/Libraries/Operators/Math/OperatorArithmetic.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Math/OperatorDiv.cpp - Include/ScriptCanvas/Libraries/Operators/Math/OperatorDiv.h - Include/ScriptCanvas/Libraries/Operators/Math/OperatorDiv.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Math/OperatorDivideByNumber.cpp - Include/ScriptCanvas/Libraries/Operators/Math/OperatorDivideByNumber.h - Include/ScriptCanvas/Libraries/Operators/Math/OperatorDivideByNumber.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Math/OperatorLength.cpp - Include/ScriptCanvas/Libraries/Operators/Math/OperatorLength.h - Include/ScriptCanvas/Libraries/Operators/Math/OperatorLength.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerp.cpp - Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerp.h - Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerp.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Math/OperatorMul.cpp - Include/ScriptCanvas/Libraries/Operators/Math/OperatorMul.h - Include/ScriptCanvas/Libraries/Operators/Math/OperatorMul.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Math/OperatorSub.cpp - Include/ScriptCanvas/Libraries/Operators/Math/OperatorSub.h - Include/ScriptCanvas/Libraries/Operators/Math/OperatorSub.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerpNodeable.h Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerpNodeable.cpp - Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerpNodeableNode.h Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerpNodeableNode.cpp - Include/ScriptCanvas/Profiler/Driller.h - Include/ScriptCanvas/Profiler/Aggregator.h Include/ScriptCanvas/Profiler/Aggregator.cpp - Include/ScriptCanvas/Profiler/DrillerEvents.h Include/ScriptCanvas/Profiler/DrillerEvents.cpp - Include/ScriptCanvas/Serialization/BehaviorContextObjectSerializer.h Include/ScriptCanvas/Serialization/BehaviorContextObjectSerializer.cpp - Include/ScriptCanvas/Serialization/DatumSerializer.h Include/ScriptCanvas/Serialization/DatumSerializer.cpp - Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.h Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.cpp Include/ScriptCanvas/Data/DataTrait.cpp - Include/ScriptCanvas/Data/DataTrait.h Include/ScriptCanvas/Data/PropertyTraits.cpp - Include/ScriptCanvas/Data/PropertyTraits.h - Include/ScriptCanvas/Data/Traits.h - Include/ScriptCanvas/Variable/VariableBus.h - Include/ScriptCanvas/Variable/GraphVariable.h Include/ScriptCanvas/Variable/GraphVariable.cpp - Include/ScriptCanvas/Variable/GraphVariableManagerComponent.h Include/ScriptCanvas/Variable/GraphVariableManagerComponent.cpp - Include/ScriptCanvas/Variable/VariableCore.h Include/ScriptCanvas/Variable/VariableCore.cpp - Include/ScriptCanvas/Variable/VariableData.h Include/ScriptCanvas/Variable/VariableData.cpp - Include/ScriptCanvas/Utils/DataUtils.h Include/ScriptCanvas/Utils/DataUtils.cpp - Include/ScriptCanvas/Utils/NodeUtils.h Include/ScriptCanvas/Utils/NodeUtils.cpp - Include/ScriptCanvas/Utils/SerializationUtils.h - Include/ScriptCanvas/Utils/VersionConverters.h Include/ScriptCanvas/Utils/VersionConverters.cpp Include/ScriptCanvas/Utils/VersioningUtils.cpp Include/ScriptCanvas/Utils/VersioningUtils.cpp - Include/ScriptCanvas/Utils/BehaviorContextUtils.h Include/ScriptCanvas/Utils/BehaviorContextUtils.cpp ) set(SKIP_UNITY_BUILD_INCLUSION_FILES Include/ScriptCanvas/Libraries/Core/FunctionCallNode.cpp - Include/ScriptCanvas/Libraries/Core/FunctionCallNode.h - Include/ScriptCanvas/Libraries/Core/FunctionCallNodeIsOutOfDate.h Include/ScriptCanvas/Libraries/Core/FunctionCallNodeIsOutOfDate.cpp ) diff --git a/Gems/ScriptCanvasPhysics/Code/CMakeLists.txt b/Gems/ScriptCanvasPhysics/Code/CMakeLists.txt index 2addf3e8ca..0d25959066 100644 --- a/Gems/ScriptCanvasPhysics/Code/CMakeLists.txt +++ b/Gems/ScriptCanvasPhysics/Code/CMakeLists.txt @@ -32,7 +32,7 @@ ly_add_target( PRIVATE Legacy::CryCommon Gem::ScriptCanvasPhysics.Static - Gem::ScriptCanvasAPI + Gem::ScriptCanvas.API ) # By default, the above module is used by all application types, however, the module depends at runtime to ScriptCanvas From 64139b7636fb6e7a5c8197b09e816d728cdb2e5f Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Mon, 29 Nov 2021 14:30:15 -0800 Subject: [PATCH 13/47] Add new-line to end of file Signed-off-by: amzn-sj --- Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake b/Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake index 76b5412c58..67f526cf21 100644 --- a/Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake +++ b/Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake @@ -60,4 +60,4 @@ set(FILES include/LmbrCentral/Shape/SplineAttribute.h include/LmbrCentral/Shape/SplineAttribute.inl include/LmbrCentral/Terrain/TerrainSystemRequestBus.h -) \ No newline at end of file +) From 8e472a030b65935c8175f663b21ddfe268f2a143 Mon Sep 17 00:00:00 2001 From: lsemp3d <58790905+lsemp3d@users.noreply.github.com> Date: Mon, 29 Nov 2021 18:22:53 -0800 Subject: [PATCH 14/47] Added support for translating variables types in the variable manager Signed-off-by: lsemp3d <58790905+lsemp3d@users.noreply.github.com> --- .../EBus/Senders/AWSGameLiftRequestBus.names | 81 + .../Types/BehaviorTypes.names | 1428 +++++++++++++++++ .../Editor/Translation/TranslationHelper.h | 456 +----- .../DataTypePalette/DataTypePaletteModel.cpp | 11 +- .../ScriptCanvasNodePaletteDockWidget.cpp | 9 +- .../Include/ScriptCanvas/Data/DataTrait.h | 4 +- .../Code/Tools/TranslationGeneration.cpp | 28 + .../Code/Tools/TranslationGeneration.h | 3 + 8 files changed, 1577 insertions(+), 443 deletions(-) create mode 100644 Gems/ScriptCanvas/Assets/TranslationAssets/EBus/Senders/AWSGameLiftRequestBus.names create mode 100644 Gems/ScriptCanvas/Assets/TranslationAssets/Types/BehaviorTypes.names diff --git a/Gems/ScriptCanvas/Assets/TranslationAssets/EBus/Senders/AWSGameLiftRequestBus.names b/Gems/ScriptCanvas/Assets/TranslationAssets/EBus/Senders/AWSGameLiftRequestBus.names new file mode 100644 index 0000000000..3e32cecee8 --- /dev/null +++ b/Gems/ScriptCanvas/Assets/TranslationAssets/EBus/Senders/AWSGameLiftRequestBus.names @@ -0,0 +1,81 @@ +{ + "entries": [ + { + "base": "AWSGameLiftRequestBus", + "context": "EBusSender", + "variant": "", + "details": { + "name": "Requests", + "category": "AWS Game Lift" + }, + "methods": [ + { + "base": "ConfigureGameLiftClient", + "entry": { + "name": "In", + "tooltip": "When signaled, this will invoke Configure Game Lift Client" + }, + "exit": { + "name": "Out", + "tooltip": "Signaled after Configure Game Lift Client is invoked" + }, + "details": { + "name": "Configure Game Lift Client" + }, + "params": [ + { + "typeid": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}", + "details": { + "name": "Region" + } + } + ], + "results": [ + { + "typeid": "{A0CA880C-AFE4-43CB-926C-59AC48496112}", + "details": { + "name": "Result" + } + } + ] + }, + { + "base": "CreatePlayerId", + "entry": { + "name": "In", + "tooltip": "When signaled, this will invoke Create Player Id" + }, + "exit": { + "name": "Out", + "tooltip": "Signaled after Create Player Id is invoked" + }, + "details": { + "name": "Create Player Id" + }, + "params": [ + { + "typeid": "{A0CA880C-AFE4-43CB-926C-59AC48496112}", + "details": { + "name": "Include Brackets" + } + }, + { + "typeid": "{A0CA880C-AFE4-43CB-926C-59AC48496112}", + "details": { + "name": "Include Dashes" + } + } + ], + "results": [ + { + "typeid": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}", + "details": { + "name": "Player Id" + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/Gems/ScriptCanvas/Assets/TranslationAssets/Types/BehaviorTypes.names b/Gems/ScriptCanvas/Assets/TranslationAssets/Types/BehaviorTypes.names new file mode 100644 index 0000000000..598d058767 --- /dev/null +++ b/Gems/ScriptCanvas/Assets/TranslationAssets/Types/BehaviorTypes.names @@ -0,0 +1,1428 @@ +{ + "entries": [ + { + "base": "{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Uuid" + } + }, + { + "base": "{831C1F11-5898-4FBF-B4CF-92B757A907A8}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "FastNoiseGradientConfig" + } + }, + { + "base": "{1D00F234-8134-4A42-A357-ADAC865CF63A}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Mesh Blocker Config" + } + }, + { + "base": "{40403A44-31FE-4D1D-941C-6593759CCCBD}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "MixedGradientConfig" + } + }, + { + "base": "{0B5D866D-C7F5-5B12-81A5-74521A8230D5}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{4AADFD75-48A7-4F31-8F30-FE4505F09E35}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SphereShapeConfig" + } + }, + { + "base": "{01F6E6C5-707E-42EC-91BB-F674B9F51A40}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "BlockerConfig" + } + }, + { + "base": "{5574DD27-89D8-5A40-B7C4-FA04C68B8A0D}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{FE862126-C838-4999-9B7B-4AEEA5507A49}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "RaySplineQueryResult" + } + }, + { + "base": "{ED57731E-2821-4AA6-9BD6-9203ED0B6AB0}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AreaBlenderConfig" + } + }, + { + "base": "{0CE9FA36-1E3A-4C06-9254-B7C73A732053}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Vector4" + } + }, + { + "base": "{A62E9C87-093C-4534-AB48-DEF8EC80C190}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "DescriptorListCombinerConfig" + } + }, + { + "base": "{73BA7B92-1061-4DDB-AA5B-A0D87303CBC8}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SlopeAlignmentModifierConfig" + } + }, + { + "base": "{C0E1DF8C-D1BE-4AF4-8100-5D71788399BA}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ShaderVariantInfo" + } + }, + { + "base": "{15A4332F-7C3F-4A58-AC35-50E1CE53FB9C}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Matrix3x3" + } + }, + { + "base": "{12A1776B-61F6-4E5F-356A-AD718A62051F}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "NetworkTestPlayerComponentNetworkInput" + } + }, + { + "base": "{157193C7-B673-4A2B-8B43-5681DCC3DEC3}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Matrix4x4" + } + }, + { + "base": "{331A3D0E-BB1D-47BF-96A2-249FAA0D720D}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AzFramework::SurfaceData::SurfacePoint" + } + }, + { + "base": "{6483F481-0C18-4171-8B59-A44F2F28EAE5}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AWSMetrics_MetricsAttribute" + } + }, + { + "base": "{708A5B3C-E377-40CE-9572-BEB64C849D40}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "VertexHandle" + } + }, + { + "base": "{C81CC1CA-6841-5F6A-B1C7-E544590B481F}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{E8C6654F-0000-5496-8A61-9DAE9CA30493}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{C16F0F38-8F8F-45A2-A33B-F2758922A7C4}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "MeshVertexTangentData" + } + }, + { + "base": "{F56FB088-4C92-4453-AFE9-4E820F03FA90}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "MeshVertexBitangentData" + } + }, + { + "base": "{A7E568EC-5873-5C8A-A43E-A7228B613A21}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{00931AEB-2AD8-42CE-B1DC-FA4332F51501}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "CapsuleShapeConfig" + } + }, + { + "base": "{004ABD25-CF14-4EB3-BD41-022C247C07FA}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "OBB" + } + }, + { + "base": "{4AFDFD7F-384A-41DF-900C-9B25A4AA8D1E}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "PosterizeGradientConfig" + } + }, + { + "base": "{02FB32C4-B94E-4084-9049-3DF32F87BD76}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ClientAuthAWSCredentials" + } + }, + { + "base": "{F6B9150B-CC89-48A2-AB89-D18740CC6FA2}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "FaceVertHandles" + } + }, + { + "base": "{4BC6D515-214A-4DCE-8FCB-A6389B66A1B9}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Entity Transform" + } + }, + { + "base": "{F681BA9D-245C-4630-B20E-05DD752FAD57}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "UiOffsets" + } + }, + { + "base": "{EBEDA5EC-29D3-4F23-ABCC-C7C4EE48FA36}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "DisplaySettingsState" + } + }, + { + "base": "{344066EB-7C3D-4E92-B53D-3C9EBD546488}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "EditorMaterialComponentSlot" + } + }, + { + "base": "{3D2B920C-9EFD-40D5-AAE0-DF131C3D4931}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Name" + } + }, + { + "base": "{F965D1B2-9DE3-4900-B44B-E58D9F083ACB}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AuthenticationTokens" + } + }, + { + "base": "{1BDB5DA4-A4A8-452B-BE6D-6BD451D4E7CD}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ImageGradientConfig" + } + }, + { + "base": "{DCFE9FBF-39BF-5B3C-AD28-D61ADBAF1711}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{8FB7C786-D8A7-41C4-A703-020020EB4A4F}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ShapeAreaFalloffGradientConfig" + } + }, + { + "base": "{D24130B9-89C4-4EAA-9A5D-3469B05C5065}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "GraphModelSlotId" + } + }, + { + "base": "{7894072A-9050-4F0F-901B-34B1A0D29417}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Color" + } + }, + { + "base": "{F2EE1768-183B-483E-9778-CB3D3D0DA68A}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "MaterialData" + } + }, + { + "base": "{FF8B1DED-C1A8-4322-86D2-C8432E4B0526}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "RotationModifierConfig" + } + }, + { + "base": "{902F6253-A8FA-4350-B9F1-C176F3E2D305}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "DescriptorListConfig" + } + }, + { + "base": "{34516BA4-2B13-4A84-A46B-01E1980CA778}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "GradientSurfaceDataConfig" + } + }, + { + "base": "{8AF3B382-F187-4323-9014-B380638767E3}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Multiplayer::NetComponentId" + } + }, + { + "base": "{EBB1C475-FA03-4111-8C84-985377434B9B}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Multiplayer::RpcIndex" + } + }, + { + "base": "{E134EAE8-52A1-4E43-847B-09E546CC5B95}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "UVCoords" + } + }, + { + "base": "{28529C97-543C-5690-9FA4-9781271E6661}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{B94085B7-C0D4-466A-A791-188A4559EC8D}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "OutputDeviceTransformType" + } + }, + { + "base": "{3EC1CE83-483D-41FD-9909-D22B03E56F4E}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Render::ShadowmapSize" + } + }, + { + "base": "{9E71534D-34B3-4723-B180-2552513DDA3D}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AWSScriptBehaviorLambda" + } + }, + { + "base": "{8CD110EE-95FA-4B26-B10E-95079BE4CB11}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "DistanceBetweenFilterConfig" + } + }, + { + "base": "{A54C2B36-D5B8-46A1-A529-4EBDBD2450E7}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AABB" + } + }, + { + "base": "{C845E5EC-5580-4E12-A9B2-9AE7E5B7826F}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "EntityComponentIdPair" + } + }, + { + "base": "{E6DA080B-7ED1-4135-A78C-A6A5E495A43E}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "CollisionGroup" + } + }, + { + "base": "{F01C8BDD-6F24-4344-8945-521A8750B30B}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "PolygonPrism" + } + }, + { + "base": "{67C8C6ED-F32A-443E-A777-1CAE48B22CD7}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SurfaceTag" + } + }, + { + "base": "{48A94382-72BE-457B-BB43-0E6C245824D2}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SearchFilter" + } + }, + { + "base": "{4C0F6AD4-0D4F-4354-AD4A-0C01E948245C}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ScriptTimePoint" + } + }, + { + "base": "{05E4C08B-3A1B-4390-8144-3767D8E56A81}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Multiplayer::NetEntityId" + } + }, + { + "base": "{65D4346C-FB16-4CB0-9BDC-1185B122C4A9}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "UiAnchors" + } + }, + { + "base": "{691E0F23-37E9-434F-A1D1-E8DE5B4A3405}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SurfaceSlopeGradientConfig" + } + }, + { + "base": "{4E74B13E-6B4E-59D1-90E1-5E5C7EEE40D6}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{7602AA36-792C-4BDC-BDF8-AA16792151A3}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "CollisionEvent" + } + }, + { + "base": "{02644F52-9483-47A8-9028-37671695C34E}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "LightConfig" + } + }, + { + "base": "{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "EntityId" + } + }, + { + "base": "{1906D8A5-7DEC-4DE3-A606-9E53BB3459E7}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Matrix3x4" + } + }, + { + "base": "{17477B86-B163-4574-8FB2-4916BC218B3D}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "MeshVertexColorData" + } + }, + { + "base": "{A504D6DA-2825-4A0E-A65E-3FC76FC8AFAC}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AreaDebugConfig" + } + }, + { + "base": "{794F7DE4-188C-4031-8B00-C2BA0C351A1E}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "LevelSettingsConfig" + } + }, + { + "base": "{B88C9D87-8609-4EAB-82D6-92DFEF006629}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ShapeIntersectionFilterConfig" + } + }, + { + "base": "{3D80F623-C85C-4741-90D0-E4E66164E6BF}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Vector2" + } + }, + { + "base": "{5B085DA7-CDC9-47C7-B2DB-BA5DD5AA2FB5}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SurfaceMaskFilterConfig" + } + }, + { + "base": "{847DD984-9DBF-4789-8E25-E0334402E8AD}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Plane" + } + }, + { + "base": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "String" + } + }, + { + "base": "{63984856-F883-4F8C-9049-5A8F26477B76}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "InstanceSystemConfig" + } + }, + { + "base": "{3768D3A6-BF70-4ABC-B4EC-73C75A886916}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "GradientSampler" + } + }, + { + "base": "{B435C091-482C-4EB9-B1F4-FA5B480796DA}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "MeshVertexUVData" + } + }, + { + "base": "{EA14018E-E853-4BF5-8E13-D83BB99A54CC}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SurfaceTagWeight" + } + }, + { + "base": "{3CB05FC9-6E0F-435E-B420-F027B6716804}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SurfaceAltitudeGradientConfig" + } + }, + { + "base": "{C6FD75F7-58BA-46CE-8FBA-2D64CB4ECFF9}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ExposureControlConfig" + } + }, + { + "base": "{27B1FEC2-8C8A-47D7-A034-6609FA092B34}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ShaderVariantId" + } + }, + { + "base": "{41CC88A4-FE07-48E6-943D-998DE68AFF5C}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Entity" + } + }, + { + "base": "{6B17F9C6-DB72-52CA-80ED-EFDFDF2DF9ED}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{F27E64FB-A7FF-47F2-80DB-7E1371B014DD}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "PythonBuilderWorker" + } + }, + { + "base": "{41CA80B1-9E0D-41FB-A235-9638D2A905A5}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Render::DisplayMapperOperationType" + } + }, + { + "base": "{4FA91FA7-CF3C-51BF-8159-6496DC7D526C}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{3EE8C0D4-3792-46C0-B91C-B89A81C36B91}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AcesParameterOverrides" + } + }, + { + "base": "{5F0CD700-EC2B-468D-B708-F6EEA7782C46}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SurfaceMaskDepthFilterConfig" + } + }, + { + "base": "{569E74F6-1268-4199-9653-A3B603FC9F4F}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AWSScriptBehaviorDynamoDB" + } + }, + { + "base": "{7E304208-5FDF-4384-BC28-E7CDD2A15BEC}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "DistributionFilterConfig" + } + }, + { + "base": "{7A0851A3-2CBD-4A03-85D5-1C40221E7F61}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "TriggerEvent" + } + }, + { + "base": "{C66E5214-A24B-4722-B7F0-5991E6F8F163}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "MaterialAssignment" + } + }, + { + "base": "{110C4B14-11A8-4E9D-8638-5051013A56AC}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Number" + } + }, + { + "base": "{E35DCF28-1AC3-49E8-A0AB-2F6115348F45}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "PositionSplineQueryResult" + } + }, + { + "base": "{98A6B0CE-FAD0-4108-B019-6B01931E649F}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "VegetationSpawnerConfig" + } + }, + { + "base": "{1811456D-0C3D-58C8-ACE8-FD47F4E80E25}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{5D9958E9-9F1E-4985-B532-FFFDE75FEDFD}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Transform" + } + }, + { + "base": "{6CEBAF3A-2A5C-4508-A351-9613E32CF63F}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SurfaceSlopeFilterConfig" + } + }, + { + "base": "{DA5C6354-AA81-504B-88BF-8EF5811ABA61}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{24EC2919-F198-4871-8404-F6DE8A16275E}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "DiskShapeConfig" + } + }, + { + "base": "{B1106C14-D22B-482F-B33E-B6E154A53798}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AWSMetrics_AttributesSubmissionList" + } + }, + { + "base": "{FF875C22-2E4F-4CE3-BA49-09BF78C70A09}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "BlendShapeData" + } + }, + { + "base": "{07B9E2F7-5408-49E9-904D-CC1A9C33230E}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RPI::ShaderOptionDescriptor" + } + }, + { + "base": "{9274AD17-3212-4651-9F3B-7DCCB080E467}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SceneManifest" + } + }, + { + "base": "{F392F061-BF40-43C5-89F6-7323D6EF11F4}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SmoothStep" + } + }, + { + "base": "{F034FBA2-AC2F-4E66-8152-14DFB90D6283}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "BoxShapeConfig" + } + }, + { + "base": "{950009BC-8991-4749-9D5C-08C62AF34E7B}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "FaceHandle" + } + }, + { + "base": "{B0216514-46B5-4A57-9D9D-8D9EC94C3702}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ConstantGradientConfig" + } + }, + { + "base": "{F4460210-024D-4B3B-A10A-04B669C34230}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Multiplayer::PropertyIndex" + } + }, + { + "base": "{6EEACBC0-2D97-414C-8E87-088E7BA231A9}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "LightingPreset" + } + }, + { + "base": "{9E0F0801-348B-4FF9-AF9B-858D59404968}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "InputEventNotificationId" + } + }, + { + "base": "{0C899DAC-6B19-4BDD-AD8C-8A11EF2A6729}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "MotionEvent" + } + }, + { + "base": "{73103120-3DD3-4873-BAB3-9713FA2804FB}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Quaternion" + } + }, + { + "base": "{23C40FD4-A55F-4BD3-BE5B-DC5423F217C2}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "EmptyInstanceSpawner" + } + }, + { + "base": "{3E49974D-2EE0-4AF9-92B9-229A22B515C3}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ReferenceShapeConfig" + } + }, + { + "base": "{E59D0A4C-BA3D-4288-B409-A00B7D5566AA}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SurfaceMaskGradientConfig" + } + }, + { + "base": "{14CCBE43-52DD-4F56-92A8-2BB011A0F7A2}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AreaSystemConfig" + } + }, + { + "base": "{E6D8372B-8419-4287-B478-1353709A972F}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AssetInfo" + } + }, + { + "base": "{5C8C0729-5D41-5299-80F1-395F79B02D70}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{F8679938-6D3F-47CC-A078-3D6EC0011366}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ShaderVariantListSourceData" + } + }, + { + "base": "{8F519317-4E83-4CF0-BEC9-C5F3F3198F20}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "DitherGradientConfig" + } + }, + { + "base": "{1106FD53-8B3A-4F97-8051-E34AD70199A5}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "GradientTransformConfig" + } + }, + { + "base": "{A23453D5-79A8-49C8-B9F0-9CC35D711DD4}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "BlastActorData" + } + }, + { + "base": "{E9E2D5B3-66F1-494D-91D2-1E83D36A1AC1}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ThresholdGradientConfig" + } + }, + { + "base": "{64C7F381-3313-46E8-B23B-D7AA9A915F35}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ShaderCollectionItem" + } + }, + { + "base": "{A746CFD0-7288-42F4-837D-1CDE2EAA6923}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "PerlinGradientConfig" + } + }, + { + "base": "{3F860893-1F57-5615-92CA-389B49687A9C}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{61599E53-2B6A-40AC-B5B8-FC1C3F87275E}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AreaConfig" + } + }, + { + "base": "{BBA5CC1E-B4CA-4792-89F7-93711E98FBD1}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "DynamicSliceInstanceSpawner" + } + }, + { + "base": "{4A70FD56-10A8-460E-B822-3EF03F1EF7A0}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "String" + } + }, + { + "base": "{B980EF45-C893-56C2-9B54-44B8B14F3436}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{BB3C3018-66B1-4BAD-AD27-F385BA015C69}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SurfaceAltitudeFilterConfig" + } + }, + { + "base": "{7F4E956C-7463-4236-B320-C992D36A9C6E}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AWSScriptBehaviorS3" + } + }, + { + "base": "{957264F7-A169-4D47-B94C-659B078026D4}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "MixedGradientLayer" + } + }, + { + "base": "{35BF3504-CEC9-4406-A275-C633A17FBEFB}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Multiplayer::ClientInputId" + } + }, + { + "base": "{5B169E40-E02B-5012-A085-BE7E6CA55CEA}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{DE5C18B0-4214-4A37-B590-8D45CC450A96}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "UiPadding" + } + }, + { + "base": "{121A6DAB-26C1-46B7-83AE-BE750FDABC04}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ReferenceGradientConfig" + } + }, + { + "base": "{DF17F6F3-48C6-4B4A-BBD9-37DA03162864}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Multiplayer::HostFrameId" + } + }, + { + "base": "{B7A0A88D-4FDF-487F-A0E6-5BE04C82862A}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "PositionModifierConfig" + } + }, + { + "base": "{A7304AE2-EC26-44A4-8C00-89D9731CCB13}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ModelPreset" + } + }, + { + "base": "{3366C279-32AE-48F6-839B-7700AE117A54}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "MaterialComponentConfig" + } + }, + { + "base": "{C10E7B12-BCB6-5872-810D-D597F123DB61}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{744CCE6C-9F69-4E2F-B950-DAB8514F870B}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Physics::MaterialId" + } + }, + { + "base": "{60A9A069-9C3D-465A-B7AD-0D6CC803990A}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ComponentId" + } + }, + { + "base": "{02F01CCC-CA6F-462F-BDEC-9A7EAC730D33}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "LevelsGradientConfig" + } + }, + { + "base": "{571E9CC8-AE35-5EBA-9A82-4012B60E7581}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{9E576D4F-A74A-4326-9135-C07284D0A3B9}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AtomToolsDocumentSystemSettings" + } + }, + { + "base": "{D350732E-4727-41C8-95E0-FBAF5F2AC074}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AnimationData" + } + }, + { + "base": "{A0CA880C-AFE4-43CB-926C-59AC48496112}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Boolean" + } + }, + { + "base": "{A5A5E7F7-FC36-4BD1-8A93-21362574B9DA}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Descriptor" + } + }, + { + "base": "{742F8581-B03E-42C2-A332-2A47C588BD1F}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "TypeExposition" + } + }, + { + "base": "{8F19B652-17A5-5646-9001-120CE0D5BF02}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{1CD41DA9-91CA-4A57-A169-B42FC25FC4C3}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ScaleModifierConfig" + } + }, + { + "base": "{1DD3D37D-0855-44F9-94F8-76F0128491A1}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "InstanceData" + } + }, + { + "base": "{D7439508-ED10-4395-9D48-1FC3D7815361}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Contact" + } + }, + { + "base": "{382116B1-5843-42A3-915B-A3BFC3CFAB78}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "DescriptorWeightSelectorConfig" + } + }, + { + "base": "{D9C0BF74-6FE8-536F-9432-C964B82700BE}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{02766CCF-BDA7-46B6-9BB1-58A90C1AD6AA}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "BlendShapeAnimationData" + } + }, + { + "base": "{2AB6096D-C7C0-4C5E-AA84-7CA804A9680C}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SurfaceTagDistance" + } + }, + { + "base": "{EB603581-4654-4C17-B6DE-AE61E79EDA97}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "MaterialAssignmentId" + } + }, + { + "base": "{515CF4CF-4992-4139-BDE5-42A887432B45}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "CryRange" + } + }, + { + "base": "{9F4E062E-06A0-46D4-85DF-E0DA96467D3A}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Tag" + } + }, + { + "base": "{A435F06D-A148-4B5F-897D-39996495B6F4}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "RandomGradientConfig" + } + }, + { + "base": "{B7463F12-C981-4A0B-ACEF-4B26D431D797}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Unit Testing" + } + }, + { + "base": "{53254779-82F1-441E-9116-81E1FACFECF4}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "CylinderShapeConfig" + } + }, + { + "base": "{A53D2A38-FFE1-4828-B91E-4D5A8B712BB2}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SmoothStepGradientConfig" + } + }, + { + "base": "{D435DDB9-C513-4A2E-B0AC-9933E9360857}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SurfaceDataColliderConfig" + } + }, + { + "base": "{74BEEDB5-81CF-409F-B375-0D93D81EF2E3}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "PrefabInstanceSpawner" + } + }, + { + "base": "{C6FFF25F-FE52-4D08-8D96-D04C14048816}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ShaderSemantic" + } + }, + { + "base": "{35CA7415-DB12-4630-B0D0-4A140CE1B9A7}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "LmbrCentral::QuadShapeConfig" + } + }, + { + "base": "{1A4C0EF2-BF98-4EB3-B134-A6EF7B31B62E}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "InvertGradientConfig" + } + }, + { + "base": "{A935EBBC-D167-4C59-927C-5D98C6337B9C}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "RuntimeData" + } + }, + { + "base": "{8379EB7D-01FA-4538-B64B-A6543B4BE73D}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Vector3" + } + }, + { + "base": "{A2589BD4-42FB-40BA-A38D-CFCD6E9EA169}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "MeshData" + } + }, + { + "base": "{E6E7C0C5-07C9-44BB-A38C-930431948667}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SliceInstantiationTicket" + } + } + ] +} \ No newline at end of file diff --git a/Gems/ScriptCanvas/Code/Editor/Translation/TranslationHelper.h b/Gems/ScriptCanvas/Code/Editor/Translation/TranslationHelper.h index bd37ab0e2f..4d7eed7075 100644 --- a/Gems/ScriptCanvas/Code/Editor/Translation/TranslationHelper.h +++ b/Gems/ScriptCanvas/Code/Editor/Translation/TranslationHelper.h @@ -8,15 +8,8 @@ #pragma once -#include - -#include -#include - -#include #include -#include -#include +#include namespace Translation { @@ -27,447 +20,32 @@ namespace Translation static constexpr const char* MissingFunctionKey = "Globals.MissingFunction"; static constexpr const char* EBusHandlerOutSlot = "Globals.EBusHandler.OutSlot"; } - - static inline bool GetValue(const AZStd::string key, AZStd::string& value) - { - GraphCanvas::TranslationKey tkey; - tkey = key; - - bool result = false; - GraphCanvas::TranslationRequestBus::BroadcastResult(result, &GraphCanvas::TranslationRequests::Get, key, value); - return result; - } -} - - -namespace GraphCanvasAttributeHelper -{ - template - AZStd::string GetStringAttribute(const T* source, const AZ::Crc32& attribute) - { - AZStd::string attributeValue = ""; - if (auto attributeItem = azrtti_cast*>(AZ::FindAttribute(attribute, source->m_attributes))) - { - attributeValue = attributeItem->Get(nullptr); - } - return attributeValue; - } - - inline AZStd::string ReadStringAttribute(const AZ::AttributeArray& attributes, const AZ::Crc32& attribute) - { - AZStd::string attributeValue = ""; - if (auto attributeItem = azrtti_cast*>(AZ::FindAttribute(attribute, attributes))) - { - attributeValue = attributeItem->Get(nullptr); - return attributeValue; - } - - if (auto attributeItem = azrtti_cast*>(AZ::FindAttribute(attribute, attributes))) - { - attributeValue = attributeItem->Get(nullptr); - return attributeValue; - } - - return {}; - } } namespace ScriptCanvasEditor { - enum class TranslationContextGroup : AZ::u32 + namespace TranslationHelper { - EbusSender, - EbusHandler, - ClassMethod, - GlobalMethod, - Invalid - }; - - enum class TranslationItemType : AZ::u32 - { - Node, - Wrapper, - ExecutionInSlot, - ExecutionOutSlot, - ParamDataSlot, - ReturnDataSlot, - BusIdSlot, - Invalid - }; - - enum class TranslationKeyId : AZ::u32 - { - Name, - Tooltip, - Category, - Invalid - }; - - - namespace TranslationKeyParts - { - const char* const handler = "HANDLER_"; - const char* const name = "NAME"; - const char* const tooltip = "TOOLTIP"; - const char* const category = "CATEGORY"; - const char* const in = "IN"; - const char* const out = "OUT"; - const char* const param = "PARAM"; - const char* const output = "OUTPUT"; - const char* const busid = "BUSID"; - } - - namespace TranslationContextGroupParts - { - const char* const ebusSender = "EBus"; - const char* const ebusHandler = "Handler"; - const char* const classMethod = "Method"; - constexpr const char* const globalMethod = "GlobalMethod"; - }; - - // The context name and keys generated by TranslationHelper should match the keys - // being exported by the TSGenerateAction.cpp in the ScriptCanvasDeveloper Gem. - class TranslationHelper - { - public: - static AZStd::string GetContextName(TranslationContextGroup group, AZStd::string_view keyBase) - { - if (group == TranslationContextGroup::Invalid || keyBase.empty()) - { - // Missing information - return AZStd::string(); - } - - const char* groupPart; - - switch (group) - { - case TranslationContextGroup::EbusSender: - groupPart = TranslationContextGroupParts::ebusSender; - break; - case TranslationContextGroup::EbusHandler: - groupPart = TranslationContextGroupParts::ebusHandler; - break; - case TranslationContextGroup::ClassMethod: - groupPart = TranslationContextGroupParts::classMethod; - break; - case TranslationContextGroup::GlobalMethod: - groupPart = TranslationContextGroupParts::globalMethod; - break; - default: - AZ_Warning("TranslationComponent", false, "Invalid translation group ID."); - groupPart = ""; - } - - AZStd::string fullKey = AZStd::string::format("%s: %.*s", groupPart, - aznumeric_cast(keyBase.size()), keyBase.data()); - - return fullKey; - } - - // UserDefined - static AZStd::string GetUserDefinedNodeKey(AZStd::string_view contextName, AZStd::string_view nodeName, TranslationKeyId keyId) - { - return GetKey(TranslationContextGroup::ClassMethod, contextName, nodeName, TranslationItemType::Node, keyId); - } - //// - - static AZStd::string GetKey(TranslationContextGroup group, AZStd::string_view keyBase, AZStd::string_view keyName, TranslationItemType type, TranslationKeyId keyId, int paramIndex = 0) - { - if (group == TranslationContextGroup::Invalid || keyBase.empty() - || type == TranslationItemType::Invalid || keyId == TranslationKeyId::Invalid) - { - // Missing information - return AZStd::string(); - } - - if (type != TranslationItemType::Wrapper && keyName.empty()) - { - // Missing information - return AZStd::string(); - } - - AZStd::string fullKey; - - const char* prefix = ""; - if (group == TranslationContextGroup::EbusHandler) - { - prefix = TranslationKeyParts::handler; - } - - const char* keyPart = GetKeyPart(keyId); - - switch (type) - { - case TranslationItemType::Node: - fullKey = AZStd::string::format("%s%.*s_%.*s_%s", - prefix, - aznumeric_cast(keyBase.size()), - keyBase.data(), - aznumeric_cast(keyName.size()), - keyName.data(), - keyPart - ); - break; - case TranslationItemType::Wrapper: - fullKey = GetClassKey(group, keyBase, keyId); - break; - case TranslationItemType::ExecutionInSlot: - fullKey = AZStd::string::format("%s%.*s_%.*s_%s_%s", - prefix, - aznumeric_cast(keyBase.size()), - keyBase.data(), - aznumeric_cast(keyName.size()), - keyName.data(), - TranslationKeyParts::in, - keyPart - ); - break; - case TranslationItemType::ExecutionOutSlot: - fullKey = AZStd::string::format("%s%.*s_%.*s_%s_%s", - prefix, - aznumeric_cast(keyBase.size()), - keyBase.data(), - aznumeric_cast(keyName.size()), - keyName.data(), - TranslationKeyParts::out, - keyPart - ); - break; - case TranslationItemType::ParamDataSlot: - fullKey = AZStd::string::format("%s%.*s_%.*s_%s%d_%s", - prefix, - aznumeric_cast(keyBase.size()), - keyBase.data(), - aznumeric_cast(keyName.size()), - keyName.data(), - TranslationKeyParts::param, - paramIndex, - keyPart - ); - break; - case TranslationItemType::ReturnDataSlot: - fullKey = AZStd::string::format("%s%.*s_%.*s_%s%d_%s", - prefix, - aznumeric_cast(keyBase.size()), - keyBase.data(), - aznumeric_cast(keyName.size()), - keyName.data(), - TranslationKeyParts::output, - paramIndex, - keyPart - ); - break; - case TranslationItemType::BusIdSlot: - fullKey = AZStd::string::format("%s%.*s_%.*s_%s_%s", - prefix, - aznumeric_cast(keyBase.size()), - keyBase.data(), - aznumeric_cast(keyName.size()), - keyName.data(), - TranslationKeyParts::busid, - keyPart - ); - break; - default: - AZ_Warning("ScriptCanvas TranslationHelper", false, "Invalid translation item type."); - } - - AZStd::to_upper(fullKey.begin(), fullKey.end()); - - return fullKey; - } - - static AZStd::string GetClassKey(TranslationContextGroup group, AZStd::string_view keyBase, TranslationKeyId keyId) - { - const char* prefix = ""; - if (group == TranslationContextGroup::EbusHandler) - { - prefix = TranslationKeyParts::handler; - } - - const char* keyPart = GetKeyPart(keyId); - - AZStd::string fullKey = AZStd::string::format("%s%.*s_%s", - prefix, - aznumeric_cast(keyBase.size()), - keyBase.data(), - keyPart - ); - - AZStd::to_upper(fullKey.begin(), fullKey.end()); - - return fullKey; - } - - static AZStd::string GetGlobalMethodKey(AZStd::string_view keyName, TranslationItemType keyType, - TranslationKeyId keyId, int paramIndex = 0) - { - const char* keyPart = GetKeyPart(keyId); - - AZStd::string fullKey; - switch (keyType) - { - case TranslationItemType::Node: - fullKey = AZStd::string::format("%.*s_%s", - aznumeric_cast(keyName.size()), - keyName.data(), - keyPart - ); - break; - case TranslationItemType::ExecutionInSlot: - fullKey = AZStd::string::format("%.*s_%s_%s", - aznumeric_cast(keyName.size()), - keyName.data(), - TranslationKeyParts::in, - keyPart - ); - break; - case TranslationItemType::ExecutionOutSlot: - fullKey = AZStd::string::format("%.*s_%s_%s", - aznumeric_cast(keyName.size()), - keyName.data(), - TranslationKeyParts::out, - keyPart - ); - break; - case TranslationItemType::ParamDataSlot: - fullKey = AZStd::string::format("%.*s_%s%d_%s", - aznumeric_cast(keyName.size()), - keyName.data(), - TranslationKeyParts::param, - paramIndex, - keyPart - ); - break; - case TranslationItemType::ReturnDataSlot: - fullKey = AZStd::string::format("%.*s_%s%d_%s", - aznumeric_cast(keyName.size()), - keyName.data(), - TranslationKeyParts::output, - paramIndex, - keyPart - ); - break; - default: - AZ_Warning("ScriptCanvas TranslationHelper", false, "Invalid translation item type."); - } - - AZStd::to_upper(fullKey.begin(), fullKey.end()); - - return fullKey; - } - - static const char* GetKeyPart(TranslationKeyId keyId) - { - const char* keyPart = ""; - - switch (keyId) - { - case TranslationKeyId::Name: - keyPart = TranslationKeyParts::name; - break; - case TranslationKeyId::Tooltip: - keyPart = TranslationKeyParts::tooltip; - break; - case TranslationKeyId::Category: - keyPart = TranslationKeyParts::category; - break; - - - default: - AZ_Warning("ScriptCanvas TranslationHelper", false, "Invalid translation key ID."); - } - - return keyPart; - } - - static TranslationItemType GetItemType(ScriptCanvas::SlotDescriptor slotDescriptor) - { - if (slotDescriptor == ScriptCanvas::SlotDescriptors::ExecutionIn()) - { - return TranslationItemType::ExecutionInSlot; - } - else if (slotDescriptor == ScriptCanvas::SlotDescriptors::ExecutionOut()) - { - return TranslationItemType::ExecutionOutSlot; - } - else if (slotDescriptor == ScriptCanvas::SlotDescriptors::DataIn()) - { - return TranslationItemType::ParamDataSlot; - } - else if (slotDescriptor == ScriptCanvas::SlotDescriptors::DataOut()) - { - return TranslationItemType::ReturnDataSlot; - } - - return TranslationItemType::Invalid; - } - - static AZStd::string GetSafeTypeName(ScriptCanvas::Data::Type dataType) + inline AZStd::string GetSafeTypeName(ScriptCanvas::Data::Type dataType) { if (!dataType.IsValid()) { return ""; } - return ScriptCanvas::Data::GetName(dataType); + AZStd::string azType = dataType.GetAZType().ToString(); + + GraphCanvas::TranslationKey key; + key << "BehaviorType" << azType << "details"; + + GraphCanvas::TranslationRequests::Details details; + + details.m_name = ScriptCanvas::Data::GetName(dataType); + + GraphCanvas::TranslationRequestBus::BroadcastResult(details, &GraphCanvas::TranslationRequests::GetDetails, key, details); + + return details.m_name; } - - static AZStd::string GetKeyTranslation(TranslationContextGroup group, AZStd::string_view keyBase, AZStd::string_view keyName, TranslationItemType type, TranslationKeyId keyId, int paramIndex = 0) - { - AZStd::string translationContext = TranslationHelper::GetContextName(group, keyBase); - AZStd::string translationKey = TranslationHelper::GetKey(group, keyBase, keyName, type, keyId, paramIndex); - AZStd::string translated = QCoreApplication::translate(translationContext.c_str(), translationKey.c_str()).toUtf8().data(); - - if (translated == translationKey) - { - return AZStd::string(); - } - - return translated; - } - - static AZStd::string GetClassKeyTranslation(TranslationContextGroup group, AZStd::string_view keyBase, TranslationKeyId keyId) - { - AZStd::string translationContext = TranslationHelper::GetContextName(group, keyBase); - AZStd::string translationKey = TranslationHelper::GetClassKey(group, keyBase, keyId); - AZStd::string translated = QCoreApplication::translate(translationContext.c_str(), translationKey.c_str()).toUtf8().data(); - - if (translated == translationKey) - { - return AZStd::string(); - } - - return translated; - } - - static AZStd::string GetGlobalMethodKeyTranslation(AZStd::string_view keyName, - TranslationItemType keyType, TranslationKeyId keyId, int paramIndex = 0) - { - AZStd::string translationKey = TranslationHelper::GetGlobalMethodKey(keyName, keyType, keyId, paramIndex); - AZStd::string translated = QCoreApplication::translate(TranslationContextGroupParts::globalMethod, translationKey.c_str()).toUtf8().data(); - - if (translated == translationKey) - { - return AZStd::string(); - } - - return translated; - } - - // Use the StackedString to index the translation keys as a Json Pointer - static AZ::StackedString GetAzEventHandlerRootPointer(AZStd::string_view eventName) - { - AZ::StackedString path(AZ::StackedString::Format::JsonPointer); - path.Push(eventName); - - return path; - } - - - - }; - - + } } + diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/DataTypePalette/DataTypePaletteModel.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/DataTypePalette/DataTypePaletteModel.cpp index a31444921b..6e8550b1f8 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/DataTypePalette/DataTypePaletteModel.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/DataTypePalette/DataTypePaletteModel.cpp @@ -243,7 +243,16 @@ namespace ScriptCanvasEditor AZStd::string DataTypePaletteModel::FindTypeNameForTypeId(const AZ::TypeId& typeId) const { - return TranslationHelper::GetSafeTypeName(ScriptCanvas::Data::FromAZType(typeId)); + GraphCanvas::TranslationKey key; + key << "BehaviorType" << typeId.ToString() << "details"; + + GraphCanvas::TranslationRequests::Details details; + + details.m_name = TranslationHelper::GetSafeTypeName(ScriptCanvas::Data::FromAZType(typeId)); + + GraphCanvas::TranslationRequestBus::BroadcastResult(details, &GraphCanvas::TranslationRequests::GetDetails, key, details); + + return details.m_name; } void DataTypePaletteModel::TogglePendingPinChange(const AZ::Uuid& azVarType) diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp index 45316778fe..0bc54a493b 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp @@ -26,12 +26,18 @@ #include #include #include + #include +#include + #include #include #include #include #include + +#include + #include #include #include @@ -50,9 +56,11 @@ #include #include #include + #include #include #include + #include #include #include @@ -63,7 +71,6 @@ #include #include #include -#include "AzQtComponents/Utilities/DesktopUtilities.h" namespace ScriptCanvasEditor { diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/DataTrait.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/DataTrait.h index 6a3c95d1e1..ca25013d35 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/DataTrait.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/DataTrait.h @@ -182,7 +182,7 @@ namespace ScriptCanvas static AZ::Uuid GetAZType(const Data::Type& = {}) { return azrtti_typeid(); } static Data::Type GetSCType(const AZ::TypeId& = AZ::TypeId::CreateNull()) { return Data::Type::CRC(); } - static AZStd::string GetName(const Data::Type& = {}) { return "CRC"; } + static AZStd::string GetName(const Data::Type& = {}) { return "Tag"; } static Type GetDefault(const Data::Type& = {}) { return CRCType(); } static bool IsDefault(const Type& value, const Data::Type& = {}) { return value == GetDefault(); } }; @@ -198,7 +198,7 @@ namespace ScriptCanvas static AZ::Uuid GetAZType(const Data::Type& = {}) { return azrtti_typeid(); } static Data::Type GetSCType(const AZ::TypeId& = AZ::TypeId::CreateNull()) { return Data::Type::EntityID(); } - static AZStd::string GetName(const Data::Type& = {}) { return "EntityID"; } + static AZStd::string GetName(const Data::Type& = {}) { return "EntityId"; } static Type GetDefault(const Data::Type& = {}) { return GraphOwnerId; } static bool IsDefault(const Type& value, const Data::Type& = {}) { return value == GetDefault(); } }; diff --git a/Gems/ScriptCanvas/Code/Tools/TranslationGeneration.cpp b/Gems/ScriptCanvas/Code/Tools/TranslationGeneration.cpp index dd1f8074b1..a0f26bcec9 100644 --- a/Gems/ScriptCanvas/Code/Tools/TranslationGeneration.cpp +++ b/Gems/ScriptCanvas/Code/Tools/TranslationGeneration.cpp @@ -34,6 +34,7 @@ #include #include #include +#include "Data/DataRegistry.h" namespace ScriptCanvasEditorTools { @@ -832,6 +833,33 @@ namespace ScriptCanvasEditorTools SaveJSONData(fileName, translationRoot); } + void TranslationGeneration::TranslateDataTypes() + { + TranslationFormat translationRoot; + + auto dataRegistry = ScriptCanvas::GetDataRegistry(); + + for (auto& typePair : dataRegistry->m_creatableTypes) + { + if (ScriptCanvas::Data::IsContainerType(typePair.first)) + { + continue; + } + + const AZStd::string typeIDStr = typePair.first.GetAZType().ToString(); + AZStd::string typeName = ScriptCanvas::Data::GetName(typePair.first); + + Entry entry; + entry.m_key = typeIDStr; + entry.m_context = "BehaviorType"; + entry.m_details.m_name = typeName; + + translationRoot.m_entries.emplace_back(entry); + } + + SaveJSONData("Types/BehaviorTypes", translationRoot); + } + void TranslationGeneration::TranslateMethod(AZ::BehaviorMethod* behaviorMethod, Method& methodEntry) { // Arguments (Input Slots) diff --git a/Gems/ScriptCanvas/Code/Tools/TranslationGeneration.h b/Gems/ScriptCanvas/Code/Tools/TranslationGeneration.h index 0f84c48b22..c6d482e115 100644 --- a/Gems/ScriptCanvas/Code/Tools/TranslationGeneration.h +++ b/Gems/ScriptCanvas/Code/Tools/TranslationGeneration.h @@ -131,6 +131,9 @@ namespace ScriptCanvasEditorTools //! Generates the translation data for the specified property in the BehaviorContext void TranslateBehaviorProperty(const AZ::BehaviorProperty* behaviorProperty, const AZStd::string& className, const AZStd::string& context, Entry* entry = nullptr); + //! Generates a type map from reflected types that are suitable for BehaviorContext objects used by ScriptCanvas + void TranslateDataTypes(); + private: //! Utility to populate a BehaviorMethod's translation data From 9c9d2c70f5c9593a4087d1d44499628b8db00f2d Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Mon, 29 Nov 2021 18:26:31 -0800 Subject: [PATCH 15/47] Making sure to stop pulling server logs before terminating the server process; otherwise we might be pulling an invalid process-communicator. Updating AZCoreLogSink to also allow for piping warnings/errors/asserts Signed-off-by: Gene Walters --- Code/Legacy/CrySystem/AZCoreLogSink.h | 6 +++--- .../Source/Editor/MultiplayerEditorSystemComponent.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Code/Legacy/CrySystem/AZCoreLogSink.h b/Code/Legacy/CrySystem/AZCoreLogSink.h index 39a6131262..9d732b3dd4 100644 --- a/Code/Legacy/CrySystem/AZCoreLogSink.h +++ b/Code/Legacy/CrySystem/AZCoreLogSink.h @@ -127,7 +127,7 @@ public: CryLogAlways("%s", message); } - return true; // suppress default AzCore behavior. + return m_suppressSystemOutput; #else AZ_UNUSED(fileName); AZ_UNUSED(line); @@ -147,7 +147,7 @@ public: return false; // allow AZCore to do its default behavior. } gEnv->pLog->LogError("(%s) - %s", window, message); - return true; // suppress default AzCore behavior. + return m_suppressSystemOutput; } bool OnPreWarning(const char* window, const char* fileName, int line, const char* func, const char* message) override @@ -162,7 +162,7 @@ public: } CryWarning(VALIDATOR_MODULE_UNKNOWN, VALIDATOR_WARNING, "(%s) - %s", window, message); - return true; // suppress default AzCore behavior. + return m_suppressSystemOutput; } bool OnOutput(const char* window, const char* message) override diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp index 7cc6fbc1b5..fa855cf28c 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp @@ -160,6 +160,7 @@ namespace Multiplayer [[fallthrough]]; case eNotify_OnEndGameMode: // Kill the configured server if it's active + AZ::TickBus::Handler::BusDisconnect(); if (m_serverProcessWatcher) { m_serverProcessWatcher->TerminateProcess(0); @@ -172,9 +173,7 @@ namespace Multiplayer m_serverProcessWatcher = nullptr; m_serverProcessTracePrinter = nullptr; } - - AZ::TickBus::Handler::BusDisconnect(); - + if (INetworkInterface* editorNetworkInterface = AZ::Interface::Get()->RetrieveNetworkInterface(AZ::Name(MpEditorInterfaceName))) { editorNetworkInterface->Disconnect(m_editorConnId, AzNetworking::DisconnectReason::TerminatedByClient); @@ -251,10 +250,12 @@ namespace Multiplayer // Stop the previous server if one exists if (m_serverProcessWatcher) { + AZ::TickBus::Handler::BusDisconnect(); m_serverProcessWatcher->TerminateProcess(0); } m_serverProcessWatcher.reset(outProcess); m_serverProcessTracePrinter = AZStd::make_unique(m_serverProcessWatcher->GetCommunicator(), "EditorServer"); + AZ::TickBus::Handler::BusConnect(); } void MultiplayerEditorSystemComponent::OnGameEntitiesStarted() @@ -315,7 +316,6 @@ namespace Multiplayer // Launch the editor-server LaunchEditorServer(); - AZ::TickBus::Handler::BusConnect(); } else { From b56c6cce8949bee6c65ac8858c5e186f0f0c3dfb Mon Sep 17 00:00:00 2001 From: dmcdiarmid-ly <63674186+dmcdiarmid-ly@users.noreply.github.com> Date: Mon, 29 Nov 2021 19:47:17 -0700 Subject: [PATCH 16/47] Updated DiffuseProbeGridRender precompiled shader Signed-off-by: dmcdiarmid-ly <63674186+dmcdiarmid-ly@users.noreply.github.com> --- .../diffuseprobegridrender.azshader | Bin 218052 -> 240486 bytes ...fuseprobegridrender_dx12_0.azshadervariant | Bin 30631 -> 32739 bytes ...fuseprobegridrender_null_0.azshadervariant | Bin 589 -> 589 bytes ...seprobegridrender_vulkan_0.azshadervariant | Bin 22565 -> 23141 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/diffuseprobegridrender.azshader b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/diffuseprobegridrender.azshader index 56009d56abb497027e6d3aea639d3d232d0799b2..e7f4577c9acb92aa91ea989e7bba8ef99c4f20ca 100644 GIT binary patch delta 7474 zcmeHMdr*{B6zAOC<&`ck5f%Z##1N2O#78!2>}V4!g5U$SQP@v+6%u6CT{WEs)U?u4 z#iGU^UOq7Yc?8R)G%ngy~R%dLIor6`&M_cu;$ha}-nIguq_@{)M@Dt@#)V zh3S|%Hjkn#%m*h1#)O32-KD|Q>V)>8N_y>Mi0@jXPstesjWO zle~gy>kOvsBo zl}hG87-N~ZL93zgWsuq>sC6$>g@S3B`SZ;MxA%3J!m>4hm%TI@zz zy&DFg^XKgQ2IH)uTFNN}t-Q_cv&O1z2CA(G1Fo}aDWw*I(SNY9<8*P6HHk*72CZ1% z#Mb(>OGX~Y?=9XoRDj_OEVxS%;@$Mapi>tYCJdu2wIZqF7iRL__`%A=#^w68^t=h) z_cUaWo0~R^ssj`ejyl8J-t7#*9%gQgpati6o28C*p^ImE z>0Ub7u*V>=2=?0@*8%=l)uhVAC%KSr8w;Yrr};2f*9GCuT3f)~{AWffz;59T6tiy! z`tNxYjlH7C@4Phpcosl$jXZkGGBw3EaZ^bQXfXYt4V^(zxb`bsTXtV~6Z&KQo>Vlh zS5tQ<53}_2qmP>)jpwq{tFw#UU2dEfIi*vn5A>GTz^?)35$7vkI&p@FW`4OMv;#Jl zQFbT^~YRJDCK5K`5b%rJ{@tdEZhP5*nkM>Cr_dm_jmEO5o zA1)jb4q;wES`E^B}>k$3P{PZZbhQ zo{oPV!bv|5bW}Z`1>(*RM#|Pc(zC>uN~f@FS3UADbR+Fl#@i{&0Bc-k?JF#tjNeOU z-dP{|WCToh6{}A|09)W$>*tmgQRd7X}zanSR2sOi(Fnl3aHCaiHVEYYEM_2$R)7Y z1o4uCv4_1Px?%5$m7(3R=Z3w1SJ;05?6pdX66R<4DfEv?QG`fL+TG{x=!q}#KeTwr zKd35(waT6ksV>U5R4#!&dTnv;Ul7q1m3UpP_(N-y=*Xt?Hrub;zc_WXmlz$(#s^UO H7=`Y4imktX delta 2850 zcmeHJZ){Ul6yH7Xv9;Z3`!;7cNXJ97x(&8fkN_&M0Wx&_X*3xwMrdXPni)bQ&xw3M z287Y!T6eM?G#aV~7j&4C$MT}$3Sq&GFgA=8B`GU$Zpuc}#6@I6^sR5D)enXbet^ig zbI<*qd(XM&ch5OP-x<5wruvI`UO3%Ig(qTlo{y)vRq~$X65E$@2@N5z|l&MjBkKJS^O@%HAV6Jzyl<{%xxiY z7Uxl%W9)Y$l^%!HEC-KW&udMEB_yW7(-hswrjgSGIau2Fs%-5)sF%e{%Ym)LQ=CP& zuBU#^(uG^V7aV3;q%HC4{kmCGDkYFs4D0joS38A-zv>px6Z z;%MX{MU8BDmh5iKx%-3E#e>9|p$|xXM=RdEDq(b_5d%N(rmdTph(o_f_@+LKyw7qK z(JDkO&Qf(1%7t9WI}7jrUCWHjyxQ{T&KFgqfa*B zi$6-#U&S?%y+XAMg(PzBRo%8-Q`LRUh`u2S?Xro!nhBNkk`2B|&X1Zj*^sP=C+so1 z&a?ly;POY?x)rgAeV=u&^K*%^!NY2Gld&o)V{Nn1-8h|uE_Um#5AJ`)%UH5{(&UT3 zbwg6dw%PTMbUr@6qkh5C6lLHYZk?bEZUadxD_HC8WI4)}?a-tD&r2wY2S87*F}72a z3ZH=j%($3|ffK7@8vNnOe2N|hr?y}HF&wz9$3wvxxT7-(=r7?mYe3g0P(WoFV8r(V z2|)A0*EMU`q5=$@teM1)u>$J6!Peb2t=FU@K$LElZQ%`HhQEofziEXMb z?$ZR%?9m+WQ2Y(VcLe9LHc| z{Jwnhe*rcMFh~NZs!SZ{(OxQcv1($V@Kc_=ZOckm&%?4fuXde*_IOz!bx}UiuPlJx!#eT>nQfvl3(DCG zfJLz~ai3@EPq@!Bbv*hT&vbE~sguJ7X2D&d@;jIxnyphXJX(0~Ob?!a{vCr3^F!qr x9k#R*OT~HDThJWQE8b1qITjx*{_R)2U8uNQxYfLFue-r|w)d6SCJOsL;V(9*QL6v| diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/diffuseprobegridrender_dx12_0.azshadervariant b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/diffuseprobegridrender_dx12_0.azshadervariant index e9893c96dacf7ba371df65d3b895f19b56b0a071..2565261d622427ed4e3e9c88d063b55d3d292200 100644 GIT binary patch delta 13780 zcmb`O2~<<(_UKOrl0Xs&gOCu0Ac!D{VK5*lCIOKlwBUfKs9_MLf+DDG9hwOc6)bR| zf=CVGfQpu>Dk?1rNPz;yNNvE#9~8ON3l^=H>ebu6eV{76|K8rW-g;e&68Yx6_qX>x z`*(8gC)~r|aMeLLN^i}_%aI7Zf1>Z=gU#hN0P}E#=Hp_6|7Fh74l^9A1eX1L2p$MoF0@L>#SS2Cod%M?WR$+li7B zUXK~1y=NcJ_Y4^`i&SU8>WGui_5ei&!;$Cl$sWB$=kgtuCA(XG%K6 zR$4o&5wy_HSrS}s)oN#@RT)KykB1nx%BXcaz*jbIr=uJ|?*9h%3-{`s0T7$D08L}9)vmGqAiijxwk@jEb zTl^mU-tLKQ>L>iqgvbc;!ax#C3ZGx5+Qvf>`+D^W?<3M z>6N+uZOwj_0gG}7O9}~#I`O_4ghe--v314G6yeU#y_OYnUoH?vgHhSmiUJGq#!U=U z-96K94YbHb{0Vo}=REBWp-AMEGHF zAjR~7SJMg*VGWtrt?;yc^-~Ebj~qU*o1qKSDP4G}oiYfEI|G(f2Q2!1VOUT6;mq~s>Cv$DgxGor z$1E`vGXuBm%)JzH+B+=>e&Ws0!pbcw+Bs+Ahs6wm69e(AL1kpFh1#z=!2d+E-?bSU z|HShQv^k(Q8!bsn4tFIx2Ni6Xg|as;z!{)n8@(lXbu95z@uB~4Q)EVCaGzv00|J{D zN*i6Qjb_M7S8mmYqiIyue|=e;>3@D%{y1gWf1DH1Z+Va@o2eIfTw5I8)Yz^`gEN&n zkf!_==x53a%99-zVfGuMx5A0MmvV5I_+S);yw{2Raqz)ZF?j`irhqN0p7!u(DD9`c zR)-E#x|7bftzE&vGvj8@*0-LTu`N-Erc$leq>B%J2t&mLu9UE}hp?phVCwYce4)3u zjr@@l*~~1l|Ig1^J}YsiS3$t5=p&D;a88|G#vD$$#?Lg*SvU*`}92l22e=CF)Kc{%!y%Ug*7apoKjM@>Oyg(@jQ$l>xP^gDX6 zl}9<()WEAe!qmX0e8M0?89^}cRaO%WmM8}a=x6?J5?(nc5iy8S_UIYxRC34$yOfI$ zS2z%|eF*#_p_9T`TA=)fh6oZ7Cl3PuC<|H9iA2Paqzq3a;W$othlZ3x(?SCO0t;E! zg)p{}r0YD9VQBh+hNz&4N8s17kW*bqPYOwz>WLJV;yCwd$ao@>?M>h}ZeStLplt_9 zD)mInPT)90G=#nd8RZiAw^)crH`23{B+Y|i(DaCg%-@1IL6ek)e9(>LrIVzedm_X# zoN|eeEMRyrF;hn6|&y76Ix?|-Ld|Hnq zWm&x}*sZgeQ!HCl_sGZshYLpk#jvzI-9l0^GU+O(WCm@8mj6O!n;~=-F?tYd)ZLg( zsx~wwE{s4|7^jnz){d0qCiGk5ePqRl#hhz0KQ!EA9hGC_NYP`87=wsSU9Cwdj?~#q zj5Qoa@n(0Zf+ZrxVXtD24z~myG#i!>%d-{qAfbsiNh+|)OL{fi#q^?|XB^e9w3K6( zR;>zNL0C!WW-IiC?qqh(ur2p4qVVDLPHr}L{N?-4Mxwlbc@$;t=q+#>6)WxL<6YzJoynJTwkz^8$a~1J z#pM34Mtan31Cl2Ny0(r9M@pu3GPmGqQyYQyK-_$a9LJ@8SdBk5I~OS)f00POmytPju3fL-TH^s4CCwyjbJZ6oJUIY*ts;Ur_^JtR0uO#fFsYHjCbP1`7Ba3K=$6*zrU z#rQ?T>29ydXR&UuO{`m9ho-v++h(>n1(TBG{CLHhwGQ639yjShn%UU-tw6lSs&0g)20LlPCsMKb4Hilm1dET2nI)VI`O;)& z_n=W|tek7WaThQ$C2%p+!7z;K*~Bq)q?}e#*+jx}9&u5vfV(S!Fhuq?G4S&cIO*jV zbCkjmuxr0!&Ix=7h>hFF$Y_UKgwmToO^8>Y9lzLpG}Ns#rF$&=a!RwbTwRR|>B!)k zc1jQhcTh7q$DFr@_q=t|5v;9;s334DgrJm7ak1%}19l|uNDGRM-?bx+of8<2iG!=W zGx=!J@dxwPL^EE{FW49@@eVeIm$E5k^RC$BH~m|}xm2238gcKKZvB1M@%4Q=U2imV zeILnQW-4+3y}yvuA82p2bE&E>Si94k+>zV6Utkh2D>ZkpDP5x8(RFm0qn6|4vI#`a7uB(LE`ePiyph4`}< zuQkg1*yPA(z2-z2&>iX8)vpAtEUDwCl&|kWKC9^EXa$`a1 zh7w&&AIU*AE6$dC18h;uiat|xKfJx{z?TR5;FF-e@qAJ4Z7_^E4ShxJT}2BsZ?~Tr z0{d91l{#F94P0@74VV!w*4N%}Zm9d>%7Ty^^|gLZ4c=eYx?ivN_I7IUxN(;2+u(JR z9;|U`@fRC|eJps}{fiski+CQDR~x*b^HqJ}Q!Fg3;ilr?UZ88k7D@~vzz`qEbEzAPXR-ac=ZxLWRg6`X|k^#*;Ru>p9Q7;ZWY=WH&D+T%Uv!^!U_mqqc+TY1l;{uTt0 zB`{WzucUtF2HL#&MsEFIjcT+VM~5|SQ;yG(a?1(KX}3zNCjoOh`Bs8I#H?dmt!MSF zKhCyZ+0U}P-?P4qeVRvsdoQL}Ko~p& zVeo+-Y5~TV7?rg7!IKnX!`4woxU>`{hl;p{RQ^mbI)z00q3GWVNnjxPB7pp_;Od#z?$Pjh64=rf8&n+w}IH9I482bIpaDbXnv!KWF|S*Yoqos*)=^b1#b^ z(6rE6v4lbQP7H0}Ei~FZ2vthWM2Ggm7>K|H4p^evN&*o`3TK>|4Vuqjiz&joD+a*lCy_RC_M@*)!IY zXPU8!s}CVbviYOb9qGH%Hisu|7wy>M!Om$(<`Q6h{tI$X|U5UQ`$dU%|=>UR~wG;bD9Ug!_R^IvYH!wZYPmkwxtJfAeU}8h{Y~RUel5>cam=#8@@t;7GaLWWvsflxR!oa${dMW$6pW4dXI> zp-WW@acI`MI5|Rfa~C+p#VW)ny0ehokW@ZSW=0GJt=b}=c#W@_>yEj%DTnvP6-Z2Y z7p`6eM^+0y&NriEDrfupKlO3&zTwf(09~K?N}z8lmN<=vh#*KzM~%OSi)hX{T{-7F z$8!u*Ftau^HwCjE`@E&MqjePX^Zj3``&%>}y3ym0wWFFrt)^p`$7~-HpTOm$ihLYXi8pTW zo>m~_sean2JoW9|rE)4eEZq+}4=K)LN}ub~;N@LYdzQQSeD&f}_29y<)_}@A{G-{} zBCItg#FV+Kj)82a$UL^{48>i)VUrOG7)FAwFvf+4cZn7f3-pJ7eq&+-1 zJkZinFg&bo)2MZ=9fx(T18o{z_fd6!znZ7dY=0%512Mb_wOlb*@>Efdr9JN0njYt_ zUvXH3rR#7Wj|(0*J+45?Cksr4`h4woAplW|w$u+y78pBEsQj zUG;9b!sV6MSHqyRrNv=zNJb3=f74JZ*6pR@7PgZ8)Jhk*4fWVXkyLU$is5WawOD?| zRbY|>1)+N@rY>4V0X4nUb04}5a)y5ej1j;97^K3n0qx`dj^hJk9sOWPmCpttJY>4U zP5Vv7r_dr~CXg*e_w^R**z9{~NnZ@>K4fLZnA;a>DY7?5F*RVX_moiKAVN?;z`l5U z*yNmyJ_FdK=adT0dU@M7czgTSRo8gD(Xzf!K!rG;!8OA}!i=*B3i@nh55%$$AeL1! zt_Wd&frIKcOx|&@tNE}ib9D>_vi*QWi<=Mq2JQWapPuMS&Jda=cqGIXm zhfD1Og^qW_9)u1?FNorT5M% zlhqpZ4$0vqmoO_CTS37md3y=R?pVXl$$hbjjH5?U1@E3>Gh|jU$52c zVOeX|W@<`|@2s`H+irbd1_kkQOLe(bzn#sqa((=qWQ0cxk}xxGXYq4*Gy*gCHZj&b zE-oM<$m_UTqpLdWNGVz%VqDm$WiU-M4qNajOlER4jV-M3T2bL;dABXtp4ZQ)zfCOf z&(s(0gl8h!QJ!lSt^Bs-`P*#zj)c>ZRwt<8f$=|mAD8rR2R?yfIKDm+iwcO2bX zT+^6&yGsI*AV!=&!dvbQ309h{HKxDMg3ZcpsIP;^H#)`UQNGQ%v2E;u41?8L?O1<| zrVUK)EKxAaW3dJ148i3)<8EirzPsg?(*>bCRNQOVoL&+@wRb_c?X`y+V&bs5Z6ap4 zV`Sj*FeLnEi7V&8*z1e0)pESA3V-)H4bF0-+(>I|QbwO(ocNW;<>NYxjk8^CHOhXZO{2!r675x1T6mh}>6q$=k z9n+zF_1y6oG0Qk(2*nYZk_Z{SId8)>lb9}Ce|MSlH!ls*3vGGNc#df6jmv+(ewli4 zo}5F8V^ZM%!f&%4*G_SQKk^AZ_Rd8SWpiAm4lilkWo?fvju1q@jz4so$TBAVDISRp z%%mF*a%s(6MhjPLfinykLEW9K@i{-C5l;5#SF}UuNwE=X;2eirjHWoVagWhM&IveS z-4o|LJ<95YFFtwyLh>#kNG$Z^g84pShcJqiKXM!wg05fQMy*>Pv5nb=l`#*6AqWY6 z`@l~y{M5nEIQ-~?#8xk;BXWPhIR?(hq=+Dq)IUnm75@H4iow(=wDi>!TGG}vdbr|K zxN<}{Hyi}@>k)=InRonR_Gc)79sNhv?$YJIq#a6-jJWT6KvWeGVz0IeR+yU ziO3PvKNCSA;$=XHuwT+Mc&C`jDTMGw6L*4U=^2*~3X9SA7tWIO(Clfd*r_`Ght^JC zbqn1Cmj~mEuTv_B24)Bu&VWeyu&@Ykg(y!oxKGh8Te^v`82Ccptl<+u$EAq{TIW+4 z`m9pA9%EFO^=~XHWmP1@*kJK<7S2hK9k`4_%=TI?H6y_GL^xl`EPFHffP{7#6E{=z zqFSyeU3;y+kJ7$LKWPd*t%42krJ`SG$Ckz#*}b&up;2Y>HIXs6XbyHj+~NCPF~4Rk z$r%2S65wU>z{_MdUdC54>JV3cy$6CvYG)BKrU$1;%>?d(XlBiZaoHciM+swZ}5m~IMihLiB$eKQ5sfVHYb;JjDWAaM9Vi?n?oIXJkM}~YxK4V z-6Y!bzq;86I|csq?*wWEIq9s4`%!&kGenPTYJ~x)C2s)~!S!Z+;`bQm>%*gcMWvY77^xaFijO2)KZSQ_FJw1pqp%F@gt( zBi6jf&Z=$5`U!@5tb-WxpHG8Dwo8oFarO^?%iBErlvy^CRh&(+mZgA3ki@+hw-IqO zcZsLCgETWW4`{)`H08mxJU|aPZ+*uQs7fS_foPHVYU`kIW_!XRVf54Gh`5M)U@oXYB1KMhHfR@`Shu zq!2bn=`6&Iz?Ey9^T!cxOCms;a2cETVOwv-t%hl>gf=AgC))CEG!rC_Z7YOS#T@N!H>_5y?H0_y2Sdza+Sh83DR|t!e{5J}J$YzQet~5V$ z_Tce|e}hM6?@it1um8?}y4(D)U6e4bGMMAAicjJkT4qnjqx%(IEeT{}-A>>Zll{ckC+HIr-!He+NjEi{zc>f1o59RG0-J z2IaI+xs@mKycox6qan)@kv70g$5@COFjFE)>I*EX1gHFthR70;N_PT32WIF*@_;~@ zcp@3aIAt>pVL=l>p$rxx+1rgUc9Eo~JP`+=LO;@w$Sp{vFM)rTg(-H#zN5EasBqm9|;MkI^u~0p2R8t8BG#c(Wc_x6nx5^hEKmNwZg@qX8gIhB6Km|3U9m= zUB`bPSBzfZTN~YM&brmZYi3f8KKxu?j-q$@9)tvr3Z)8M@OebkN8pavn}co>%r`+y zO*5o4rZRiIfX5Y>XG6S|1h7JiW zaB=8Mp%ob)E@C9cI-*tqX{6*hc?5MKS{U##DK$=>O7%uf1J_aY%8EHeDBZSYo~ZjM zFbGG+zb|5Z6gwBawd}Tmzq^3)Tr5Wnm!Qg^L5YZgkAy0Q|LqL2trS;sWkIb+&2>-v zE7f&SPvk;9F=4Ugvq1tEW;_iwuC!C`M*avvn6fD`Hf>W%()Qiyo3?L`O*73v9$f2Qlw+tScKw+_mTPC((^DBO8M)?6|EZO;6$WGD^j zmMaYQBY;*CY>%%VBy3USzX*6}uzxV`gI6XO<4qNNOT(~I%i99|tJ^JjTc0<$3ZqpL z3|FbJvf!^s(A}9o; z(A`p?8+q*z0WE8#SiS4dI*Ba zbwGy#)`A4w`xrR@g*YfZz`0jYGLiJ^cm)-$a7nWdOS5-rhLyHxUgK<~V9-D22bsNS z>JvMR^)wM|eb|Rrj1s&;Oc$1LDw`#1lbL~b7N5k*k@05Y(CvfzLchvezh43{x+;Yq zEVihR(FuzwQ99ABrQNN!ohY-`#K|WNlfjrHV&#K|+iC>d=LrGTbJ;}2`#jpmE64}_ z9aQyXHv_2pH3KQa?pN5oW6|1}K1mM{7+^uhMTxUsG{yG5gI8PL;Hcm;PmTOjN9zwX zG`4@4Su>4@pw_rDX{*f0>fb39arN;q_Oxi6ZA?o7`4CF;Yhktm+`+(L5+ z#$uw+ywvwkg^DIr7IVL^$!uq-m{TAMR#}tOA~&*vV&#tb_~hN`@F+jc!%QLphw@;rG1Y42+t6^< z<2sjzeK-v+1f!PqHMQVLsxdOL#&XjTOv{`qp-vxEqFVfhz0LVDv#e-NL;jiEBCH;q zniL~9Y65a+v2HD}h7E7{7;AuNC&ub9Ze7+857PS& ze5#5XX-c0DSFP)9T^=J{)BI{dJN5v7IhjyU58c8)hiTq*qe9v34=_y5kX%!f96q)< zm8%~6R`kE`akm1bALnIy;>;EmRlCJ?+ z^&Aeha>4$=2--V5FsA8P_Cz^6fYnts13Kk!$JlZ8=&)vj$7ye5EWBNbv-Oz)iJlA$ zYul6q;4h%FBL#<5%l0Qd&or_^FR~U&?6N^C>ILCngJ|ACz>D4Vx2H}S?MgZ7)(KQx z&S(Sj@$wic;YE|(pOY#|B3M|q$kPKXY{n-3ja1>V;#fhFD9cFF^xsL9T_tQ$?h)Pr zhBLzu{+v`1uRy$uIvdM^c=uPNs%7)>KDaGw{tKz1Y=`qSiA+8B4^F&;WTEMGr9!Ix zz8l-93hJqNYH4Zc9hXuL@fxh1c($D7pNjghXH(@dVB@?yI-0E%-OP5TF-Adr?Il55 zz)PdY*=(wO19Vt?=Q-A)iET@5!U~LAEUV$Zp^w>Y8f7mg&2Ud1NE0=-vXRIZfZ%GA zI49=ycz^W_TbV{lU>+UA8nw2dZHhl9{=TAH3&0$=ml~#?HPZfP0?-s924;-**Wb&otbAgQ`}8 zKf0L|2<{$udHjy}RXbM3r)}Q6eMKzPR^d&C9hNcR^Z!7dhDsg1u%K5cysrx%7{kcR zVEKG_*Pv)f)!6mDq`he2nFja9vUW%XdXi}Vsc)O0C3EQamfJ}!u&86oru5X!n-f;2 zg4eeKum7XhnPx2h&qPjXzF4Z!d};h5&FD$W<@YXk&da%UIeGLF9eW!EBk+)YoPN(9 za)O=@UPq4DPRZN%2UDBwg@h({H`r@5I{8Z2`$%Oqw3cxwT@U4jVt*r2^y5nn_ zft$azGxJMTO%Y_T+N3}T+czOC$^&+^xW1Vbt1P3d$9lU-s_HTb)x*LuT{lsXdPHAc z1H5TtWf@&wrq4<^ zAI%nw&45D}$8)Q4avzUB4nLX;KK6tWZXT9#{dd?@;7_c?k{iP>r@5458eVz3yJI$b z*5j(DZ#^J~TK}$fAjBs#mUO8KcfACJ_59IXH~P`}moU;=|NcW42&4O^DAF`UnwLH$ z!cb4oi={4pq5WcqpYB{E+S00KVyh{rf^l}9gc0)E>*Ly?2*UG7+sU1_FY-_73oT5% z28K1=8Xcr!|MDW)`s~*|?mw-5Hlpkp1~=W(0hH@sUXmvA1AgF>+&4NMejn2*<4;J_ zt2>2|>z$Zd^|*QhX3EyU>s5ercoJsFZ(fxk58Ek9Vc+0YTaML(K?cv3cFmiR`BYC$ z_y*Lts1^ItUDB}((ysRf8MZbxYu>XFZ~z@68ps~oDGTdi!v8>?RtUS`#qNMNfHO9XzOD|nA+SlF+^WRvL(XY=r@yep1(Xl*ZG|(RXG=E zU*ur0us*`nWk1KTerk6o9{0aFaAgPZZ)}s)g_~6%zgy$sm*?k%JI%))BU&P`tY{`@ z^6bSjp`58%s?^}|TC^QXb(=&CnxQXD0h61eJ05`U&QDk0z2`M>uP&+sd_@mV3kVGN za)VBDZg^k0ex>%T_l;V36Ug@h)a&7)3jCnMK}+iggq=#_++Q4{cnckWX>FZMNaU>v z0)jwk16Mr}aVOyIIWp9(cRSUs9hH(Ekaf?1whazqv~U74zrTV^5!gaGmhKM-2gxx^ z*4pFuz_)V`!V8K);jE{!0HRw?j%(MrYoeTSqM2mBsDhLW9xG3k^{>HCf1UXBH)$Rv zKTp3r&!8rcs>-9?&ZA3)dJJDOn7R3^Gq;HXn?d>V=~tMnikvSlxWH|w^YAUE2djf} z?F>^|;6XxQrrRp#8tqhV?s!c7{pGAo0+ebW zhH=5tg4%w*!|q;Y#*_-)Xi;+ZbQO=$ZoTkK({k6``CXS>Mce09(T~EVB;*fA22c~G zx_{o;Inn_SG>mqeg>fo940a|TcFVb(485L5)|s<&u2kDE*4X<$tI!t~n83>>hL#GW zmRJSHu-r?~^eeEhLP2~oqf=VwNco@OWKMzC)*QOr@`OZ_mC7CF8;v!YZ^u~yhw6;A z?iSdL;A}^64nnm(SBCPx&E*LFWra`bCbE_&f}Rwa&Yw$&wcFXo`7XYKY}F zBXI!}p;H`82^=g@YGg|EympW-a~E(4``~>*!IEUg@xkvliJnyDY==G*&{-3!=*hX0b&E20t;yVVwP(sdqphEPjxJb~!fa|kA%(E9 z6`pm=cxD&O!v1DP{xL961aB77E+rq$V%=NM1n6oPK{ij?p1v#HG(#-14nEy*yDOZ5 z-=lOtwrBEIP*A+v_}I3iM=2Xv0~RoVWqjS^<^rI|JoDY~Mo~KZ^zJn6`7+&)WrNP2 z4<9O?yHh!LXXRY==b`7&FXMyph#_j^Fv}<6e9_~)p$09y^ED?w{C4K;qHz6<=M7n( zhn29)Vr;N?Q10srIc3+OQ%>Xe4Y%QCuyFk`{W`yd2wdHk=qkLUtJO62p+eng<~NGW z;P1lUzfpuIW7r38j6=&jICcM6Z%H7=GX>n~Zxk(6sF0g~@r|O9pI`3xKl#&Kln!4k zY7$Rge-s>THr!u z(*^~K6)lSkSnW#y6)+$mS~e+EMB1koE%n(-+uvNQO8ffyzQ2D+$eo#U=A1KU=6=pR z_zm^x_o#Xfity@od)Lz$RRSE2;+Q)NgChfju(p|owU^4CI@Yk)3~pS%H;& zI|z~^A5@o2{ni-k2irI2rmE`hM=)q)ckAX3(@F1>a@#OPk*HN~=z1VGJ zm#v>2LuEr`xF*-Y_MiV^J=<%1l;Ia>pc)7fQ7b8QhzfLoAR{7}8eafGy4UlvJVT0@ zKkdk;w6=3@+&)i#4y@$6Rg-4h(obJ)OlQkf75pL)&%-p zzy#C>`D)MsS24@$1N|y6e!WsFrFd`Yyk}hlBNJoi&PY8s9HHKnk1=%9@BK6j2LOf~7+67(#3jlppBV5#+1DEU#+wZw~UQ$2eBC`6@BXHE2H> z#`kL5@|P%La?S$XzGf7zUwp%jA&2M?K?{QTCGe}2OOV)d$};K~THecA)IVX~n`H?i ztYu_DNInv;I%Rz7jWgg^+8&;YKp$0GzyQX-=#5w)Eq$T1&)2K?h%^}@4GI+2cp@?2 zD37eoNue)r!ff(FC+s!Wq?8%BeWuHs7mK|99RV_ugOzv$U<@ zlkqfXB06Vbn#ug?0e53?O1MWzPa#@gMKRP5od#ZjSZpstGX?DEz0@?za#|fA3-VV1 z_1j!~gI1`5e3eS(9WVGF-ZWS8;~DY+XNnpw^+<2*nMAsq{`po*6qxw)z->NeeL9^h6CU~nUfv7c83Cf zpRA3d!wKXqHd}z%+$~G!ruw{mg|_Xg8`vNRV>+GQN`MxvRuVYS(Mme}h|JaXsAL%u zmsN@liJwDS@I;V{Co%UJnE_RUfan{fh_J^iWh6bX< z;>3$RprR5Ky`2PE#6ulS46DWz^6Q2uJ8|Om9#B;oN_m$AHN-=;%P_3-pciK-V64^I5C2h?7HQcjT|-O2fzlx*MgmQ`oSMjXlQN* zTt~4(=bFIxC>}=bLJ6Nm>a`_=T*%_OXiDfMY@a3zeG`-gJx4pRFNs;GkN$10&_UQfQA#04YAAY;G+hqILN}5keC8v3^VbVy(RQ!wjV4v z+@d1}KWkBWlyQMY(|3leQMl$dtdKkm`z^Yog9_kLj(V2RN7eo?)p$~bvu0@5p`d9&@l5l9P^xR1>Q6uhA0ENMv|th!uOpz~Xo^V_ z<}ygi9PfJ(cLQj6S2@WP?)N_oMx`%791ibWG)l%sxw0-JBL^6=Dlb#{neyTEuS z+dKWV_rV9=t_4B@I10NT+_=AQVe^%R9hGee%ve_O%}^eG%;I5P4pR8 zE+4~~f3wYea+_ov|ANV$mSzAUKQ=JxKLRqXXt?DaGt$rzllMwZE!LHd;;j4h9+SXK znlBuxlsA-atuE-R1mb^HC8EIWSB-48FrRPsOpm7vngKPDW{l$M6P1XX6!kD-rS&7n zM@vPKg|w}uh@nnyFuM2_Sb2O1UK;NLhBI*6qG~u4KkmT6VH@{iOHP!8iV%T|48p zr6uf24il#BN!U-zmvM3r%^Q0CA6ve8-i|zvU9LoA-M&KLi^d6A-45p-C$E0``0Nv%@TXzt5*02_y3g4w!d-NC zN%*5`oXwDaj1|)oC1nbzk=4cb!#YnKx_C(4dF@PbUSIXKmSyt3&gzLJEknhf-Ni{P z11rW0RFe*fhmW)VpoT@!X!({QDhSN?fGQ%OOVqq#W7tX+&Fqe5rApy9GHDs9 z<)?L0PnU!7GQoKFu-lOF7PufbZksSMXxHB4G((w0&x?AbT(Ap`+pW6w)~?4~^3FZx zy5v1}$WxG$B>Y(r4o3`m;UX2C{4(mTNxQ2rsvC;u*OVI)vAWmpw)BNjh$}%DrAh8; zQ`=F?&t7Q!!oH>H^Glz%T=4R_)M(%A?N@Wb!}ChzWk2sL+JVpTAY+6x13+RE#1}`T zdoS7d;_eHre}6p1xmlE+&GDX%c*FrYWEOi%hq)yev*%qXrS1^M?%J0mOkt-b3R5>E zWW*WD&_-ZAd?Gjm+@iYuc0P{X-N{5}#p5UEok=daA37%{JA{3nDB;Uman?T>k~V@c zhdcq$y%I zF(ZKX@VZSjk{wSdEodgbZ~(~|-oMFGblo20*hqD(7U>&t-rMLh87c>1&64W|2RcTc zOYA5!Ytgs(w!li?(B0Q?S%RTYsiA)-y!;u=XB2N(R~(U59Mw>)EkTishQGYgI@~qc zs%)JEpVM8FQ(n~2^8y@IhPrmiwb}i0gXg6hrq5^YR~s&S`?`xhyIgtM?F_T=!j%?X zPNO5$6a-H12d^ZKskAlQJ|IdxGH7SZr5S5dPoH*Zqh)5o)@O$WHrM8J0IK@Z=M9(L zKD&Izt)BG8h#^OZxJG_(9H?Dzq(ZCi#vJS4DrD5*pPo#9KL`!+YaH##(H2NnQZ zPDV4+z`7mpf3Xa|IfBEPO@9P3@qm^!283{O())4yQ+B29-4hofOxzn6v@0nkE;&_* zq#TgJw$^)q46eNUV$;W)jf0JGt4uh@MK7izCXH=xL~y_`qgp?_-i8YCgHd9(c_M2- z9IaWh^Q&EAu6D-D~eKCUY% zaHSDezQkno9oKHPdkj*n5i3T@B))89Gw0$k6L=BJ^*47mQ!Xl@ix3!4c%-_x zrEl5YhQ4ZbLv?W{*nc;H@b{G7B>~r6Ug~zS(e29Xwe5bH>2}Hel&442m6pcSRl1x# z9@OPxwMz6|C=Vp)ciFlQNh^t%f=SZH*0c|&<6`3D6LH(q;w9sg=sfS13r(IN#QHr- zP+%;TB^NB7=pktkG4Iap=n(vt1+dA6Q z)_ea=zGE2s}U?MuM#d;FtF_w zx@fnw7zxbsb5M^T0G8+trm;u00KsJ8iw_S7TAQS#1e z`4O-W$P3iqWcN>XJkr{9UdG1AlLNG^$QDW~jxHIg7%Gn*!P%fJ!2X-tPzzaq5Gpe~UIW{ z#QMQYKb7|~PTUE#xOc!}sFYqG7@AVr__O5qEgqZ# ztm2h{Pmugc=~1QI63z(>f|Vz03Tq2bR(R1nb4+XV=LLwc?!70p(ckFMa%F0TZr~k% zL+lO{FN(IzlqMq_^cs+?J78utn`K|o>QEo(bOG%$DRG^a_*P*2mC^uB(29Yeu)+55 z(e^F%^5|xHq6U}T%Q;YTGo#|>!QNGe2UZ;^={QW!NRZ3*X748WjA@I#Z(ZRhqwqn{p{+%C$uk{+7g9>iZs%YNBlC6Mrm9XPe> z6W!}CYj6L;|0$?V@x)n?jJ(pIk9l79z0#r`$ky?k>hJk-uw#d&`UE)dC$V1ShKP&X0LxoEcK4?@?KKnP%zQb`%qo1)zWgUPmY`@yTkNbZyx*( z85A6jmK216pNqq^dp`w(ttq9Qh_)PfuZ(tow1_Uc0vaiha}tmqrp*HEwdt_kU6ic~ zd_!m~6ELNPG`1G}{)WabMFSeU6jnN6KPnC2IB54OnB-}OW;-_7d42^5wLM}J z2;u?4yU-?7@cSE^1QF*6_5OK6-QG0e<%AX;T7aeZwR>3Xc*baVPg7y(5@1{x(gO7L zhD3+Pdyrm|9VBa#NX?W$=C%m$JN#AFH~(@n3QCjNh|e5ju2!;8iC{v2JOYZ` zWmAuWd`fAUc{JKbXULA^DL&cC?n$W9-eG&>#NyQ@`IUWqD61#wPel879fCg57aPd9 z8)YmpHxTOjy?RSp0Qoy`}7)Rkx7`lLQ5f37(HHNggO5W;q(-A?(* z@CBvN3f)~#vD?4s`XaH`{EU@@VQmlB4hC@#=P-k<8R6E9#S{XT=%%AW2RmZu5dA$i z2-NvmY$mWEh`yBp`ib{@>mFYz)MNZ4a%7xqpR~T5cNCb9V07K&&A9Iiqft~)RRD&C z#FACNHy`CJa&-IYdXhD84n%Y#0Vx4Ho9DDM37wC;K8rlkxhk2a4?MvqY=exI+w2k9 ztj-t}x`rhPxs@d*5zLn?V5_SLx+;kQ5m*|FMm^%i!9U<#$yI#v0}A=^INol5j}0FF z+}qffLVON5ZNA?BA8;dR(h%Ub>i^PPEDM}n@h9xPcyE5ZgZ_gO3LC|TJk$v34R}kv zRjvM2Qvcos$hBr6e7?O{(?ogvV4l0X+d)Jzy5w7UZlw)^czuM%{goEuSr%PF@F!?yUs@zt*CvbalIrZ7d%$QrR+LgtNMM0}31D*Srw8k7t}*0NfKMZDdS+41%f| zaRvbSn*$e=z7ejwVsgS_V7`9Pm1Q1}0@Vofu?Yk-4+*ghpS5KmkmpPoPG0W6>P6Wu zUY$h{n&XBMJBegd9*r$gsm702Dt378GK|j;|NV z>-vGe&0?AMZZm;BFytVHYOb^FAK#l$K%&fI0kt~GZ)z$bfP1qoL0M&*VKJr#YFR`w zEP7BD(?a83hIz+?#Z$E&A6mg%pdh)R2*K0#MvxXu8-m0tUIG$8j#c^OAL_|<`Q%4p z@+=4=%GdMj`}c|nKEU821%dg9Ti}M39-cy@R+QybrR89y`R_7;DAqzzhl|nKh$sdk z3dKizR3pLQ(jK@R;Qepo%7CL|N}fqq-k>#f!3;&; zkTt;4HsaVTAfrIjBJ47Np4~94k4zzn2I2!M?cf2$mZFrmNRSYqXAcbPq$%_>0Md&5qU^zPMg))iF|1)z=$jshzYix?0V;hGMSn(u^0q^{0T|XpFyd{f_W(}Z3+Om_^dkv6 zw;kdFIxaSacHV~aGjZZE4+v{@i=O)cSPMbb_dwn@!|-7Doy*`2A?7GPoD#AWRS1`a zn4|la!jeZAMKjY|0N!AWgN5bVxz#|U1j z;O!ho^c)5*;<%whY~Y(5XM=hJLz$RFRRXZ>w?m=b>R8)^TV;kqZGjnFGxYUPcsbX^ zCNf4sxr)-g!1Q*%1m0fU$$4tLpq@>^?3CPhY8Pc58&cs zBq=)X@UGA;I`Xm-I(9dc-Jw<1G!V)`;akIal>KU3n6ajh=n;pk&mr#lT*(sHCmcLXDjaOuU(2h$Q#3et@-X&hOKR@R{ z)y)hZ<%V#nE#VubAq^{PTkeJZzJbjg-`2*`*-NpC9saVTf9hTpc**(>5SY$`o--v&ss34>}`v}MK&R`!jPY{LTm|-W(*CnsWV4(CC?Vq z(9|J1)vZyel>6oD+a|rA7#E)woUjML7>?OGAZN{p$rft)&?YlL8F1DO1vpTy2FBTh zUsYram|jYiJutADCb@VDsB!LX*<~;Ykps9SBcI1DIa6s%#T*pR{0b)g7yY z5RPWBWm=kETR`h9u=rNrs+3+86v?CXqMQI@DM=)>$4Ui?&g@E~@5H>9zn1_OwG<%b zgb845kAz=ANP+Un4A+`?a2y0#`i}7|y$anB`&o6VGPI0G8DKkkkxq&7b^gg@*FVoX z`4-_JoO%Huehr3kHoFZ^*_ui9%opHRgpI!;-q`TmvK>3X^pf9U%y-X!$2NwtaU(DK zkqXMPK8?1O&p=&2{DHZd2<4E-D)eLQJk?;hB87^3H$cjt!24VJgIx=x34k_#3$_<< zZ3b7a%RRL;ILtG%6;HmddJ9l*xt!xXMkvf{+OE6$yypCC;*Ket)m~?qXEu}7_KqL_ z>uK1Bd8F@>T=D>#Pm)k-5zY$ZHojCt~*4TJeJa4zVfCK#8d0>`gBr5$S(J zYze{!&i7v>f?V=HAvOe%flY*2)C7k4w-9?rb*b(O2($TrKy11(fb!=&F9RQ}e8hXv-M2NX~TWZUzlf-qjGybfo2Hw>fTG?H_cSmT?vo5a`%TNIjz3 z&13}xAG0zSjRU>3uXuio*m*$_=4qbu_m8{t?4OYGlIJ0sgffoU`gr!%mk??2T?wY( zT4@+X5cR1aH2V$1KAl0!put4zHD{4#Klaa| ztbAsNzZ~xxz0p5d);g{jyYbzWa;$%J8sM=TV`GyYpMfNP&GVEBPyS2jUFfRoG9$`r zswC)UG?*Mj$giJ5>-441-2<90xA?U*)_8i?T=pmh?9vtNg5-rym;tY!Ja^6W0js3y z$p_@~b&5J-vV<}X%%ok)i3M5lkHni>^Al!8O7q1-#S`jl-FG_yWNWx9D%QPrQC-~9 zJzFY@Av2IED%0xT#l$vl6RuRYr4K zv7DONaND?z@e*bgHm{`~Daz;u_q*rW@hIX(P|bApU<>eRgLINx6I*Or3NpM$QW2C)0?oDiFN<1b@r)AvT*MrUE#YpO9?byoF99>Qz9ytpz*@SeV zR4}K>h7v(S9!vyf+wJY~5@-lO^D{ZxlCSjshIQxp0MhS zDJCH8K0>Kg#C1R>`gW)DWuMo4j;J!!3j(?@nmAG!ccj3DzcDcIU(vfxZZNB_b#)~}Z~ zSQV9b>d;oX7Ur7RZ4sY?g}7-O1H@)A=un zHQN>Bt*;UUIeP8?omdx~sBwD9G6%$Z0k9rU=mjobjBKod2|}d0pI&wm97pu$ne?WT z=q)8w(R-#Fsiqphyie3Pzf=ivOaE;fVY}$#r9W~&-RQ*>XNk#_*Y+2-UtL0lrsdQg zxv>OnUVnwF2?qfeo(aF>5B&9)v|5eK_>0;K4kPuW&0QgT)Df`aOn6W4hZ z^lq@|zq?bXXXQh4A5_t{vgl)2++kbX6Twn_74kD!R zFjQ1@7q__Y6L4tGt!}7pDVBGJ$&s3JCwTGrHDN~<328p``dY{+Zt=5EI8Mzfr06hD zSdn`-l%4ltqRZ?5+tC&<}qAPjola&mlovf zIi6n-wEY5uby~NLTCL9nyG4>zP}i4zO1^`e2g=;Jxt*ZCQd!*H$J~~wgIq+wK2$C4 zPWlkwdP)iAh^IGr8x;knkpGD5^(!6QUd3dB$PV0`{qKih>D@Tx(v6hlCOJJc^*Zy; zKJ&hH7W(NnAk2Tm}L-zoaFPL6m zxVPA6t;-?Zjw3rO>UihB&8t%+t(`mM2OMueZZNpFwAiyP0g`N5`~Dop)((&{ z1X&XSJ6VXVDd6`v$Qp%5kTsfug4JGDO-`{i4C=w_OV!UjsDI1y53cy+_M;zuiETvg zR#QpySF9n|zq(XSu@RCx{^C+KB}YG7NM$qs>QZ&$;4bU^7rVe=%u3Hre)xIJ7ItQ4>`o>Yy#xYej>?T%s;nr#bDB{-m! Y6R^R~36!E~cIUJaUcaq(7?|+?0aB^9X#fBK diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/diffuseprobegridrender_null_0.azshadervariant b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/diffuseprobegridrender_null_0.azshadervariant index d195b08c349f26e3e47b822c29d8eec1317b211b..a1db8345e447583ab7ffcee115776b0ea9a1d948 100644 GIT binary patch delta 15 WcmX@ha+YO-8xwn8lX*4+0|NjmMg%kf delta 15 WcmX@ha+YO-8xybJL{%)73RebDPz$RjD>>HyvfTcANb-u@>gWUNpLu3A65VO<@wf|mvgqaS^DV@OX~W22pS)%lY3N?A&&7IjEQT3Gp9!t>1z zr5aRF9i2X&9zF4JdM3Mgx|my7nlGkvg_-Pft}t7E&6@L<0;*a0#W^DVcrJVHXmK_@ zC+16;T>in#Qnr}O`p@=kl;7y^*&+Tc zBP%GsE^S+}nJuDwJI-6t@=C|Yb-@ol`})Ichn{;xQWn+EM(*|vf2yxX?&u>otIgIOeZ;43RT%!Qz&xlNM zqWizaiO+v2PVA&Ey3K{%%CA^kpY$h4jl#LdG?xPsZQe@miqEAvqzLW^?V5 zo{(zL>w%uGfNB)|R_SZf7rHwgDr!2jxL7%Ph56!KCND^42&xvn)}63g^`nVSt4;e7 z$!K`Xxq_-)A4oXm#l)ChY7mp#rBj;Y5*Tui^mtWnk|%m@5A?|BX~+a*>XFfV_ANDf zWc1bb231?tKpyUd$mRm=HTrgacISMFU8HeHX&h!4%fblLV=M(@W{+`-VRE`Q7+HZ) zK-iIR8jNPJl6#se6Z$s{xp+JyFOZQM#wj%YurvL6LH8Fc{r)?k!1>=%P^(qO+DjJkpSZZJw3_QyZ0B==?oQpjE~T=f|G4MwhEL4$ED zVNC|3%wcT?+g4>A2BTn;O7=fuK)ypb#|^f<%61rxYZJTO2BX?x-Y3z!4q@IWv3m8n zb|=Mm+%KQOU^#H-Y1@v{yC-X5s^mp<=sEZKOLp^S685RSOuB6sS%ndQy(;B-i^|rA+sta zKtpCdQcXi<&qy=PlO@IFn*#&B5HBz4LbZQ2f4S!EM0U}ec?@K2@Wa{#U^!9RKf5fRTT-x`TNPh#~ CKtzoI delta 2109 zcmZXVU1(fI6oBX6yLbP(-R#Ds`0QO|dGZ=I|IXYQQuoHKLo z%$a+C+OXccY2BQ&qPLHZzW>GEcc0a#thwTzgkx7DN?A&&q&g-&Ev;;b_m$NSxvq*S zSHCh|)px^htzVD0Rz|;*c*%Qc_m{T!Sn8HjD5`Jp$oO@C{ITCpxmc4WW_#1cda*?R ztv|l)kEg;Je;XrgqZQHj!sF5pMQYOD9jDKi3%*BGuSF__uxzFyHkOmk&rp>uw*y?A-4({5f8F0;DU6!bdu+t~xE#><7)51~)b7Tw~=`$*n2BQ%hFy`pRhVC=2 zRNxb=IjdB62OJE<(G28$S@5bzFd1wx4ray$$!{8Qu!yX`BU7Lm$OUIXP9j(kHnIoB4E8{ujTnsL#4l?w zzT>blgYD_FvR(KuLoO?h)8aU<92NFvYUkV{{{wcnCNge_{14>wTdHUDzWRwA9{d@O z$W!9|vd_tfFQ%{8t9xgK(AfRF*x5+Dj{>Ek Date: Tue, 30 Nov 2021 06:34:41 -0800 Subject: [PATCH 17/47] Missing include Signed-off-by: lsemp3d <58790905+lsemp3d@users.noreply.github.com> --- .../Code/Editor/GraphCanvas/Components/DynamicSlotComponent.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Gems/ScriptCanvas/Code/Editor/GraphCanvas/Components/DynamicSlotComponent.cpp b/Gems/ScriptCanvas/Code/Editor/GraphCanvas/Components/DynamicSlotComponent.cpp index bdd0ddf2ac..715489280d 100644 --- a/Gems/ScriptCanvas/Code/Editor/GraphCanvas/Components/DynamicSlotComponent.cpp +++ b/Gems/ScriptCanvas/Code/Editor/GraphCanvas/Components/DynamicSlotComponent.cpp @@ -11,6 +11,7 @@ #include +#include #include #include From 066178d7b9ff6fb785bd40c2bdc84af6207e442a Mon Sep 17 00:00:00 2001 From: lsemp3d <58790905+lsemp3d@users.noreply.github.com> Date: Tue, 30 Nov 2021 06:35:44 -0800 Subject: [PATCH 18/47] PR feedback Signed-off-by: lsemp3d <58790905+lsemp3d@users.noreply.github.com> --- .../Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp index 0bc54a493b..bf8482f0ca 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp @@ -27,8 +27,8 @@ #include #include -#include #include +#include #include #include From 75d6cb2527cc41d631a371fa6dcd686345fcebfc Mon Sep 17 00:00:00 2001 From: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> Date: Tue, 30 Nov 2021 15:54:01 +0100 Subject: [PATCH 19/47] Connected filterChanged signal to Update the table Model (#5901) Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> --- .../AzToolsFramework/AssetBrowser/AssetBrowserTableModel.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserTableModel.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserTableModel.cpp index 14c5e719b4..775462f63f 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserTableModel.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserTableModel.cpp @@ -30,6 +30,7 @@ namespace AzToolsFramework connect(m_filterModel, &QAbstractItemModel::rowsRemoved, this, &AssetBrowserTableModel::UpdateTableModelMaps); connect(m_filterModel, &QAbstractItemModel::layoutChanged, this, &AssetBrowserTableModel::UpdateTableModelMaps); connect(m_filterModel, &AssetBrowserFilterModel::filterChanged, this, &AssetBrowserTableModel::beginResetModel); + connect(m_filterModel, &AssetBrowserFilterModel::filterChanged, this, &AssetBrowserTableModel::UpdateTableModelMaps); connect(m_filterModel, &QAbstractItemModel::dataChanged, this, &AssetBrowserTableModel::SourceDataChanged); } From 6908a3e94555c4e190c9fc0a598e5afefcc32ff4 Mon Sep 17 00:00:00 2001 From: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> Date: Tue, 30 Nov 2021 15:07:40 +0000 Subject: [PATCH 20/47] Update intersect behavior for positioning entities in the viewport (#5906) * update intersect behavior for positioning entities in the viewport and restore SurfaceManipulator Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * tests for surface manipulator from EditorTransformComponentSelection Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * update comments in tests and remove #pragma optimize('', off)@ Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * add new file for FindClosestPickIntersection tests Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * add remaining tests for surface manipulator and snap fixes Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * some small updates and polish before PR Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * small updates following PR feedback Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> --- Code/Editor/EditorViewportWidget.cpp | 26 +- Code/Editor/EditorViewportWidget.h | 5 - .../SandboxIntegration.cpp | 2 +- Code/Editor/Viewport.cpp | 20 +- Code/Editor/Viewport.h | 3 - .../ActionDispatcher.h | 22 ++ .../AzManipulatorTestFramework.h | 3 +- .../DirectManipulatorViewportInteraction.h | 4 +- .../ImmediateModeActionDispatcher.h | 8 +- .../ViewportInteraction.h | 5 +- .../Source/ImmediateModeActionDispatcher.cpp | 48 ++-- .../Source/ViewportInteraction.cpp | 6 +- .../Manipulators/EditorVertexSelection.cpp | 24 +- .../Manipulators/EditorVertexSelection.h | 2 +- .../Manipulators/ManipulatorSnapping.cpp | 24 -- .../Manipulators/ManipulatorSnapping.h | 5 - .../Manipulators/SurfaceManipulator.cpp | 104 ++++--- .../Manipulators/SurfaceManipulator.h | 6 + .../Viewport/ViewportMessages.cpp | 42 ++- .../Viewport/ViewportMessages.h | 41 ++- .../ViewportSelection/EditorSelectionUtil.cpp | 14 + .../ViewportSelection/EditorSelectionUtil.h | 3 + .../EditorTransformComponentSelection.cpp | 96 ++++--- .../EditorTransformComponentSelection.h | 2 +- .../Tests/BoundsTestComponent.cpp | 49 ++++ .../Tests/BoundsTestComponent.h | 18 ++ ...EditorTransformComponentSelectionTests.cpp | 174 +++++++++++- .../Tests/EditorVertexSelectionTests.cpp | 253 +++++++++++++++--- .../Viewport/ViewportInteractionTests.cpp | 76 ++++++ .../Tests/aztoolsframeworktests_files.cmake | 1 + .../Viewport/ViewportInteractionImpl.cpp | 5 +- 31 files changed, 811 insertions(+), 280 deletions(-) create mode 100644 Code/Framework/AzToolsFramework/Tests/Viewport/ViewportInteractionTests.cpp diff --git a/Code/Editor/EditorViewportWidget.cpp b/Code/Editor/EditorViewportWidget.cpp index 60e4bf6d47..7323da9e95 100644 --- a/Code/Editor/EditorViewportWidget.cpp +++ b/Code/Editor/EditorViewportWidget.cpp @@ -472,7 +472,7 @@ void EditorViewportWidget::Update() { auto start = std::chrono::steady_clock::now(); - m_entityVisibilityQuery.UpdateVisibility(GetCameraState()); + m_entityVisibilityQuery.UpdateVisibility(m_renderViewport->GetCameraState()); if (ed_visibility_logTiming) { @@ -714,7 +714,7 @@ void EditorViewportWidget::RenderAll() m_debugDisplay->DepthTestOff(); m_manipulatorManager->DrawManipulators( - *m_debugDisplay, GetCameraState(), + *m_debugDisplay, m_renderViewport->GetCameraState(), BuildMouseInteractionInternal( AztfVi::MouseButtons(AztfVi::TranslateMouseButtons(QGuiApplication::mouseButtons())), keyboardModifiers, BuildMousePick(WidgetToViewport(mapFromGlobal(QCursor::pos()))))); @@ -878,31 +878,11 @@ void EditorViewportWidget::OnMenuSelectCurrentCamera() } } -AzFramework::CameraState EditorViewportWidget::GetCameraState() -{ - return m_renderViewport->GetCameraState(); -} - -AZ::Vector3 EditorViewportWidget::PickTerrain(const AzFramework::ScreenPoint& point) -{ - return LYVec3ToAZVec3(ViewToWorld(AzToolsFramework::ViewportInteraction::QPointFromScreenPoint(point), nullptr, true)); -} - -float EditorViewportWidget::TerrainHeight(const AZ::Vector2& position) -{ - return GetIEditor()->GetTerrainElevation(position.GetX(), position.GetY()); -} - void EditorViewportWidget::FindVisibleEntities(AZStd::vector& visibleEntitiesOut) { visibleEntitiesOut.assign(m_entityVisibilityQuery.Begin(), m_entityVisibilityQuery.End()); } -AzFramework::ScreenPoint EditorViewportWidget::ViewportWorldToScreen(const AZ::Vector3& worldPosition) -{ - return m_renderViewport->ViewportWorldToScreen(worldPosition); -} - QWidget* EditorViewportWidget::GetWidgetForViewportContextMenu() { return this; @@ -2132,7 +2112,7 @@ bool EditorViewportWidget::GetActiveCameraState(AzFramework::CameraState& camera { if (m_pPrimaryViewport == this) { - cameraState = GetCameraState(); + cameraState = m_renderViewport->GetCameraState(); return true; } diff --git a/Code/Editor/EditorViewportWidget.h b/Code/Editor/EditorViewportWidget.h index 0101f2ffef..3d52b2416d 100644 --- a/Code/Editor/EditorViewportWidget.h +++ b/Code/Editor/EditorViewportWidget.h @@ -205,8 +205,6 @@ private: void* GetSystemCursorConstraintWindow() const override; // AzToolsFramework::MainEditorViewportInteractionRequestBus overrides ... - AZ::Vector3 PickTerrain(const AzFramework::ScreenPoint& point) override; - float TerrainHeight(const AZ::Vector2& position) override; bool ShowingWorldSpace() override; QWidget* GetWidgetForViewportContextMenu() override; @@ -293,9 +291,6 @@ private: // This switches the active camera to the next one in the list of (default, all custom cams). void CycleCamera(); - AzFramework::CameraState GetCameraState(); - AzFramework::ScreenPoint ViewportWorldToScreen(const AZ::Vector3& worldPosition); - QPoint WidgetToViewport(const QPoint& point) const; QPoint ViewportToWidget(const QPoint& point) const; QSize WidgetToViewport(const QSize& size) const; diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp index 5a1b4dc503..9342c17a37 100644 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp +++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp @@ -1396,7 +1396,7 @@ void SandboxIntegrationManager::ContextMenu_NewEntity() { worldPosition = AzToolsFramework::FindClosestPickIntersection( view->GetViewportId(), AzFramework::ScreenPointFromVector2(m_contextMenuViewPoint), AzToolsFramework::EditorPickRayLength, - GetDefaultEntityPlacementDistance()); + AzToolsFramework::GetDefaultEntityPlacementDistance()); } CreateNewEntityAtPosition(worldPosition); diff --git a/Code/Editor/Viewport.cpp b/Code/Editor/Viewport.cpp index 613dc0c4e7..437dcead3b 100644 --- a/Code/Editor/Viewport.cpp +++ b/Code/Editor/Viewport.cpp @@ -14,14 +14,11 @@ // Qt #include -// AzCore -#include - // AzQtComponents #include +// AzToolsFramework #include -#include #include #include @@ -41,19 +38,6 @@ #undef LoadCursor #endif -AZ_CVAR( - float, - ed_defaultEntityPlacementDistance, - 10.0f, - nullptr, - AZ::ConsoleFunctorFlags::Null, - "The default distance to place an entity from the camera if no intersection is found"); - -float GetDefaultEntityPlacementDistance() -{ - return ed_defaultEntityPlacementDistance; -} - ////////////////////////////////////////////////////////////////////// // Viewport drag and drop support ////////////////////////////////////////////////////////////////////// @@ -63,7 +47,7 @@ void QtViewport::BuildDragDropContext( { context.m_hitLocation = AzToolsFramework::FindClosestPickIntersection( viewportId, AzToolsFramework::ViewportInteraction::ScreenPointFromQPoint(point), AzToolsFramework::EditorPickRayLength, - GetDefaultEntityPlacementDistance()); + AzToolsFramework::GetDefaultEntityPlacementDistance()); } void QtViewport::dragEnterEvent(QDragEnterEvent* event) diff --git a/Code/Editor/Viewport.h b/Code/Editor/Viewport.h index b8c55c7431..a71df6a9cd 100644 --- a/Code/Editor/Viewport.h +++ b/Code/Editor/Viewport.h @@ -87,9 +87,6 @@ enum EStdCursor STD_CURSOR_LAST, }; -//! The default distance an entity is placed from the camera if there is no intersection -SANDBOX_API float GetDefaultEntityPlacementDistance(); - AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING class SANDBOX_API CViewport : public IDisplayViewport diff --git a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ActionDispatcher.h b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ActionDispatcher.h index 06db67a05f..99f11c37da 100644 --- a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ActionDispatcher.h +++ b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ActionDispatcher.h @@ -39,6 +39,10 @@ namespace AzManipulatorTestFramework DerivedDispatcherT* MouseLButtonDown(); //! Set the left mouse button up. DerivedDispatcherT* MouseLButtonUp(); + //! Set the middle mouse button down. + DerivedDispatcherT* MouseMButtonDown(); + //! Set the middle mouse button up. + DerivedDispatcherT* MouseMButtonUp(); //! Send a double click event. DerivedDispatcherT* MouseLButtonDoubleClick(); //! Set the keyboard modifier button down. @@ -73,6 +77,8 @@ namespace AzManipulatorTestFramework virtual void CameraStateImpl(const AzFramework::CameraState& cameraState) = 0; virtual void MouseLButtonDownImpl() = 0; virtual void MouseLButtonUpImpl() = 0; + virtual void MouseMButtonDownImpl() = 0; + virtual void MouseMButtonUpImpl() = 0; virtual void MouseLButtonDoubleClickImpl() = 0; virtual void MousePositionImpl(const AzFramework::ScreenPoint& position) = 0; virtual void KeyboardModifierDownImpl(const AzToolsFramework::ViewportInteraction::KeyboardModifier& keyModifier) = 0; @@ -183,6 +189,22 @@ namespace AzManipulatorTestFramework return static_cast(this); } + template + DerivedDispatcherT* ActionDispatcher::MouseMButtonDown() + { + Log("Mouse middle button down"); + MouseMButtonDownImpl(); + return static_cast(this); + } + + template + DerivedDispatcherT* ActionDispatcher::MouseMButtonUp() + { + Log("Mouse middle button up"); + MouseMButtonUpImpl(); + return static_cast(this); + } + template DerivedDispatcherT* ActionDispatcher::MouseLButtonDoubleClick() { diff --git a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/AzManipulatorTestFramework.h b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/AzManipulatorTestFramework.h index 5f0179d6ad..66227c692b 100644 --- a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/AzManipulatorTestFramework.h +++ b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/AzManipulatorTestFramework.h @@ -8,6 +8,7 @@ #pragma once +#include #include #include #include @@ -40,7 +41,7 @@ namespace AzManipulatorTestFramework //! Set the angular step. virtual void SetAngularStep(float step) = 0; //! Get the viewport id. - virtual int GetViewportId() const = 0; + virtual AzFramework::ViewportId GetViewportId() const = 0; //! Updates the visibility state. //! Updates which entities are currently visible given the current camera state. virtual void UpdateVisibility() = 0; diff --git a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h index 3421116b96..7cef7b635d 100644 --- a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h +++ b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h @@ -30,7 +30,7 @@ namespace AzManipulatorTestFramework private: AZStd::shared_ptr m_customManager; - std::unique_ptr m_viewportInteraction; - std::unique_ptr m_manipulatorManager; + AZStd::unique_ptr m_viewportInteraction; + AZStd::unique_ptr m_manipulatorManager; }; } // namespace AzManipulatorTestFramework diff --git a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ImmediateModeActionDispatcher.h b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ImmediateModeActionDispatcher.h index 5d1f606e8c..8a05a15fd9 100644 --- a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ImmediateModeActionDispatcher.h +++ b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ImmediateModeActionDispatcher.h @@ -25,7 +25,7 @@ namespace AzManipulatorTestFramework using MouseInteractionEvent = AzToolsFramework::ViewportInteraction::MouseInteractionEvent; public: - explicit ImmediateModeActionDispatcher(ManipulatorViewportInteraction& viewportManipulatorInteraction); + explicit ImmediateModeActionDispatcher(ManipulatorViewportInteraction& manipulatorViewportInteraction); ~ImmediateModeActionDispatcher(); //! Clear the current event state. @@ -55,13 +55,15 @@ namespace AzManipulatorTestFramework AZStd::chrono::milliseconds EditorViewportInputTimeNow() override; protected: - // ActionDispatcher ... + // ActionDispatcher overrides ... void SetSnapToGridImpl(bool enabled) override; void SetStickySelectImpl(bool enabled) override; void GridSizeImpl(float size) override; void CameraStateImpl(const AzFramework::CameraState& cameraState) override; void MouseLButtonDownImpl() override; void MouseLButtonUpImpl() override; + void MouseMButtonDownImpl() override; + void MouseMButtonUpImpl() override; void MouseLButtonDoubleClickImpl() override; void MousePositionImpl(const AzFramework::ScreenPoint& position) override; void KeyboardModifierDownImpl(const KeyboardModifier& keyModifier) override; @@ -82,7 +84,7 @@ namespace AzManipulatorTestFramework const MouseInteractionEvent* GetMouseInteractionEvent() const; mutable AZStd::unique_ptr m_event; - ManipulatorViewportInteraction& m_viewportManipulatorInteraction; + ManipulatorViewportInteraction& m_manipulatorViewportInteraction; //! Current time that ticks up after each call to EditorViewportInputTimeNow. AZStd::chrono::milliseconds m_timeNow = AZStd::chrono::milliseconds(0); diff --git a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ViewportInteraction.h b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ViewportInteraction.h index 3c41b28851..a353140d4c 100644 --- a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ViewportInteraction.h +++ b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ViewportInteraction.h @@ -33,7 +33,7 @@ namespace AzManipulatorTestFramework void SetAngularSnapping(bool enabled) override; void SetGridSize(float size) override; void SetAngularStep(float step) override; - int GetViewportId() const override; + AzFramework::ViewportId GetViewportId() const override; void UpdateVisibility() override; void SetStickySelect(bool enabled) override; AZ::Vector3 DefaultEditorCameraPosition() const override; @@ -60,9 +60,10 @@ namespace AzManipulatorTestFramework void FindVisibleEntities(AZStd::vector& visibleEntities) override; private: + static constexpr AzFramework::ViewportId m_viewportId = 1234; //!< Arbitrary viewport id for manipulator tests. + AzFramework::EntityVisibilityQuery m_entityVisibilityQuery; AZStd::unique_ptr m_nullDebugDisplayRequests; - const int m_viewportId = 1234; // Arbitrary viewport id for manipulator tests AzFramework::CameraState m_cameraState; bool m_gridSnapping = false; bool m_angularSnapping = false; diff --git a/Code/Framework/AzManipulatorTestFramework/Source/ImmediateModeActionDispatcher.cpp b/Code/Framework/AzManipulatorTestFramework/Source/ImmediateModeActionDispatcher.cpp index 5bfe63bd99..aea93ca342 100644 --- a/Code/Framework/AzManipulatorTestFramework/Source/ImmediateModeActionDispatcher.cpp +++ b/Code/Framework/AzManipulatorTestFramework/Source/ImmediateModeActionDispatcher.cpp @@ -29,8 +29,8 @@ namespace AzManipulatorTestFramework using KeyboardModifier = AzToolsFramework::ViewportInteraction::KeyboardModifier; using MouseInteractionEvent = AzToolsFramework::ViewportInteraction::MouseInteractionEvent; - ImmediateModeActionDispatcher::ImmediateModeActionDispatcher(ManipulatorViewportInteraction& viewportManipulatorInteraction) - : m_viewportManipulatorInteraction(viewportManipulatorInteraction) + ImmediateModeActionDispatcher::ImmediateModeActionDispatcher(ManipulatorViewportInteraction& manipulatorViewportInteraction) + : m_manipulatorViewportInteraction(manipulatorViewportInteraction) { AzToolsFramework::ViewportInteraction::EditorModifierKeyRequestBus::Handler::BusConnect(); AzToolsFramework::ViewportInteraction::EditorViewportInputTimeNowRequestBus::Handler::BusConnect(); @@ -48,34 +48,34 @@ namespace AzManipulatorTestFramework // mouse down and mouse up event, to match the editor behavior we insert this event // to ensure the tests are simulating the same environment as the editor GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Move; - m_viewportManipulatorInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event); + m_manipulatorViewportInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event); } void ImmediateModeActionDispatcher::SetSnapToGridImpl(const bool enabled) { - m_viewportManipulatorInteraction.GetViewportInteraction().SetGridSnapping(enabled); + m_manipulatorViewportInteraction.GetViewportInteraction().SetGridSnapping(enabled); } void ImmediateModeActionDispatcher::SetStickySelectImpl(const bool enabled) { - m_viewportManipulatorInteraction.GetViewportInteraction().SetStickySelect(enabled); + m_manipulatorViewportInteraction.GetViewportInteraction().SetStickySelect(enabled); } void ImmediateModeActionDispatcher::GridSizeImpl(const float size) { - m_viewportManipulatorInteraction.GetViewportInteraction().SetGridSize(size); + m_manipulatorViewportInteraction.GetViewportInteraction().SetGridSize(size); } void ImmediateModeActionDispatcher::CameraStateImpl(const AzFramework::CameraState& cameraState) { - m_viewportManipulatorInteraction.GetViewportInteraction().SetCameraState(cameraState); + m_manipulatorViewportInteraction.GetViewportInteraction().SetCameraState(cameraState); } void ImmediateModeActionDispatcher::MouseLButtonDownImpl() { ToggleOn(GetMouseInteractionEvent()->m_mouseInteraction.m_mouseButtons.m_mouseButtons, MouseButton::Left); GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Down; - m_viewportManipulatorInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event); + m_manipulatorViewportInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event); // the mouse position will be the same as the previous event, thus the delta will be 0 MouseMoveAfterButton(); } @@ -83,17 +83,35 @@ namespace AzManipulatorTestFramework void ImmediateModeActionDispatcher::MouseLButtonUpImpl() { GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Up; - m_viewportManipulatorInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event); + m_manipulatorViewportInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event); ToggleOff(GetMouseInteractionEvent()->m_mouseInteraction.m_mouseButtons.m_mouseButtons, MouseButton::Left); // the mouse position will be the same as the previous event, thus the delta will be 0 MouseMoveAfterButton(); } + void ImmediateModeActionDispatcher::MouseMButtonDownImpl() + { + ToggleOn(GetMouseInteractionEvent()->m_mouseInteraction.m_mouseButtons.m_mouseButtons, MouseButton::Middle); + GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Down; + m_manipulatorViewportInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event); + // the mouse position will be the same as the previous event, thus the delta will be 0 + MouseMoveAfterButton(); + } + + void ImmediateModeActionDispatcher::MouseMButtonUpImpl() + { + GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Up; + m_manipulatorViewportInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event); + ToggleOff(GetMouseInteractionEvent()->m_mouseInteraction.m_mouseButtons.m_mouseButtons, MouseButton::Middle); + // the mouse position will be the same as the previous event, thus the delta will be 0 + MouseMoveAfterButton(); + } + void ImmediateModeActionDispatcher::MouseLButtonDoubleClickImpl() { GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::DoubleClick; ToggleOn(GetMouseInteractionEvent()->m_mouseInteraction.m_mouseButtons.m_mouseButtons, MouseButton::Left); - m_viewportManipulatorInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event); + m_manipulatorViewportInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event); ToggleOff(GetMouseInteractionEvent()->m_mouseInteraction.m_mouseButtons.m_mouseButtons, MouseButton::Left); // the mouse position will be the same as the previous event, thus the delta will be 0 MouseMoveAfterButton(); @@ -101,10 +119,10 @@ namespace AzManipulatorTestFramework void ImmediateModeActionDispatcher::MousePositionImpl(const AzFramework::ScreenPoint& position) { - const auto cameraState = m_viewportManipulatorInteraction.GetViewportInteraction().GetCameraState(); + const auto cameraState = m_manipulatorViewportInteraction.GetViewportInteraction().GetCameraState(); GetMouseInteractionEvent()->m_mouseInteraction.m_mousePick = BuildMousePick(position, cameraState); GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Move; - m_viewportManipulatorInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event); + m_manipulatorViewportInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event); } void ImmediateModeActionDispatcher::KeyboardModifierDownImpl(const KeyboardModifier& keyModifier) @@ -144,7 +162,7 @@ namespace AzManipulatorTestFramework { m_event = AZStd::unique_ptr(AZStd::make_unique()); m_event->m_mouseInteraction.m_interactionId.m_viewportId = - m_viewportManipulatorInteraction.GetViewportInteraction().GetViewportId(); + m_manipulatorViewportInteraction.GetViewportInteraction().GetViewportId(); } return m_event.get(); @@ -178,12 +196,12 @@ namespace AzManipulatorTestFramework void ImmediateModeActionDispatcher::ExpectManipulatorBeingInteractedImpl() { - EXPECT_TRUE(m_viewportManipulatorInteraction.GetManipulatorManager().ManipulatorBeingInteracted()); + EXPECT_TRUE(m_manipulatorViewportInteraction.GetManipulatorManager().ManipulatorBeingInteracted()); } void ImmediateModeActionDispatcher::ExpectManipulatorNotBeingInteractedImpl() { - EXPECT_FALSE(m_viewportManipulatorInteraction.GetManipulatorManager().ManipulatorBeingInteracted()); + EXPECT_FALSE(m_manipulatorViewportInteraction.GetManipulatorManager().ManipulatorBeingInteracted()); } ImmediateModeActionDispatcher* ImmediateModeActionDispatcher::ResetEvent() diff --git a/Code/Framework/AzManipulatorTestFramework/Source/ViewportInteraction.cpp b/Code/Framework/AzManipulatorTestFramework/Source/ViewportInteraction.cpp index 08cae0c738..e56f7d6d72 100644 --- a/Code/Framework/AzManipulatorTestFramework/Source/ViewportInteraction.cpp +++ b/Code/Framework/AzManipulatorTestFramework/Source/ViewportInteraction.cpp @@ -135,20 +135,20 @@ namespace AzManipulatorTestFramework m_angularStep = step; } - int ViewportInteraction::GetViewportId() const + AzFramework::ViewportId ViewportInteraction::GetViewportId() const { return m_viewportId; } AZ::Vector3 ViewportInteraction::ViewportScreenToWorld([[maybe_unused]] const AzFramework::ScreenPoint& screenPosition) { - return AZ::Vector3::CreateZero(); + return AzFramework::ScreenToWorld(screenPosition, m_cameraState); } AzToolsFramework::ViewportInteraction::ProjectedViewportRay ViewportInteraction::ViewportScreenToWorldRay( [[maybe_unused]] const AzFramework::ScreenPoint& screenPosition) { - return {}; + return AzToolsFramework::ViewportInteraction::ViewportScreenToWorldRay(m_cameraState, screenPosition); } float ViewportInteraction::DeviceScalingFactor() diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/EditorVertexSelection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/EditorVertexSelection.cpp index 00f5b1ac47..0c3638412c 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/EditorVertexSelection.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/EditorVertexSelection.cpp @@ -84,12 +84,12 @@ namespace AzToolsFramework break; case State::Translating: { - if (mouseInteraction.m_mouseInteraction.m_mouseButtons.Left() && + if (mouseInteraction.m_mouseInteraction.m_mouseButtons.Middle() && mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::Down && mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Shift() && mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Ctrl()) { - SnapVerticesToTerrain(mouseInteraction); + SnapVerticesToSurface(mouseInteraction); return true; } @@ -109,29 +109,23 @@ namespace AzToolsFramework } template - void EditorVertexSelectionBase::SnapVerticesToTerrain(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) + void EditorVertexSelectionBase::SnapVerticesToSurface(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) { ScopedUndoBatch surfaceSnapUndo("Snap to Surface"); ScopedUndoBatch::MarkEntityDirty(GetEntityId()); const int viewportId = mouseInteraction.m_mouseInteraction.m_interactionId.m_viewportId; - // get unsnapped terrain position (world space) - AZ::Vector3 worldSurfacePosition = AZ::Vector3::CreateZero(); - ; - ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult( - worldSurfacePosition, viewportId, &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain, - mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates); + // get unsnapped surface position (world space) + const AZ::Vector3 worldSurfacePosition = FindClosestPickIntersection( + viewportId, mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates, EditorPickRayLength, + GetDefaultEntityPlacementDistance()); AZ::Transform worldFromLocal; AZ::TransformBus::EventResult(worldFromLocal, GetEntityId(), &AZ::TransformBus::Events::GetWorldTM); const AZ::Transform localFromWorld = worldFromLocal.GetInverse(); - // convert to local space - snap if enabled - const GridSnapParameters gridSnapParams = GridSnapSettings(viewportId); - const AZ::Vector3 localFinalSurfacePosition = gridSnapParams.m_gridSnap - ? CalculateSnappedTerrainPosition(worldSurfacePosition, worldFromLocal, viewportId, gridSnapParams.m_gridSize) - : localFromWorld.TransformPoint(worldSurfacePosition); - + // convert to local space + const AZ::Vector3 localFinalSurfacePosition = localFromWorld.TransformPoint(worldSurfacePosition); SetSelectedPosition(localFinalSurfacePosition); OnEntityComponentPropertyChanged(GetEntityComponentIdPair()); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/EditorVertexSelection.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/EditorVertexSelection.h index 4894a00df6..7e5523f62a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/EditorVertexSelection.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/EditorVertexSelection.h @@ -171,7 +171,7 @@ namespace AzToolsFramework //! Snap the selected vertices to the terrain. //! Note: With a multi-selection the manipulator will be translated to the picked //! terrain position with all vertices moved relative to it. - void SnapVerticesToTerrain(const ViewportInteraction::MouseInteractionEvent& mouseInteraction); + void SnapVerticesToSurface(const ViewportInteraction::MouseInteractionEvent& mouseInteraction); //! The Actions provided by the EditorVertexSelection while it is active. //! e.g. Vertex deletion, duplication etc. diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.cpp index e4f6b3b1ea..5bea383630 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.cpp @@ -110,30 +110,6 @@ namespace AzToolsFramework return unsnappedPosition + CalculateSnappedOffset(unsnappedPosition, snapAxes, snapAxesCount, size); } - AZ::Vector3 CalculateSnappedTerrainPosition( - const AZ::Vector3& worldSurfacePosition, const AZ::Transform& worldFromLocal, const int viewportId, const float size) - { - const AZ::Transform localFromWorld = worldFromLocal.GetInverse(); - const AZ::Vector3 localSurfacePosition = localFromWorld.TransformPoint(worldSurfacePosition); - - // snap in xy plane - AZ::Vector3 localSnappedSurfacePosition = localSurfacePosition + - CalculateSnappedOffset(localSurfacePosition, AZ::Vector3::CreateAxisX(), size) + - CalculateSnappedOffset(localSurfacePosition, AZ::Vector3::CreateAxisY(), size); - - // find terrain height at xy snapped location - float terrainHeight = 0.0f; - ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult( - terrainHeight, viewportId, &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::TerrainHeight, - Vector3ToVector2(worldFromLocal.TransformPoint(localSnappedSurfacePosition))); - - // set snapped z value to terrain height - AZ::Vector3 localTerrainHeight = localFromWorld.TransformPoint(AZ::Vector3(0.0f, 0.0f, terrainHeight)); - localSnappedSurfacePosition.SetZ(localTerrainHeight.GetZ()); - - return localSnappedSurfacePosition; - } - bool GridSnapping(const int viewportId) { bool snapping = false; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.h index 660d38ac89..96f49d5276 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.h @@ -63,11 +63,6 @@ namespace AzToolsFramework AZ::Vector3 CalculateSnappedPosition( const AZ::Vector3& unsnappedPosition, const AZ::Vector3* snapAxes, size_t snapAxesCount, float size); - //! For a given point on the terrain, calculate the closest xy position snapped to the grid - //! (z position is aligned to terrain height, not snapped to z grid) - AZ::Vector3 CalculateSnappedTerrainPosition( - const AZ::Vector3& worldSurfacePosition, const AZ::Transform& worldFromLocal, int viewportId, float size); - //! Wrapper for grid snapping and grid size bus calls. GridSnapParameters GridSnapSettings(int viewportId); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.cpp index dd565eb0a8..01b8635406 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.cpp @@ -10,6 +10,7 @@ #include #include +#include namespace AzToolsFramework { @@ -17,28 +18,16 @@ namespace AzToolsFramework const AZ::Transform& worldFromLocal, const AZ::Vector3& worldSurfacePosition, const AZ::Vector3& localStartPosition, - const bool snapping, - const float gridSize, - const int viewportId) + [[maybe_unused]] const bool snapping, + [[maybe_unused]] const float gridSize, + [[maybe_unused]] const int viewportId) { - const AZ::Transform worldFromLocalUniform = AzToolsFramework::TransformUniformScale(worldFromLocal); - const AZ::Transform localFromWorldUniform = worldFromLocalUniform.GetInverse(); - - const AZ::Vector3 localFinalSurfacePosition = snapping - // note: gridSize is not scaled by scaleRecip here as localStartPosition is - // unscaled itself so the position returned by CalculateSnappedTerrainPosition - // must be in the same space (if localStartPosition were also scaled, gridSize - // would need to be multiplied by scaleRecip) - ? CalculateSnappedTerrainPosition(worldSurfacePosition, worldFromLocalUniform, viewportId, gridSize) - : localFromWorldUniform.TransformPoint(worldSurfacePosition); - - // delta/offset between initial vertex position and terrain pick position - const AZ::Vector3 localSurfaceOffset = localFinalSurfacePosition - localStartPosition; + const AZ::Transform localFromWorld = worldFromLocal.GetInverse(); StartInternal startInternal; - startInternal.m_snapOffset = localSurfaceOffset; - startInternal.m_localPosition = localStartPosition + localSurfaceOffset; - startInternal.m_localHitPosition = localFromWorldUniform.TransformVector(worldSurfacePosition); + startInternal.m_snapOffset = AZ::Vector3::CreateZero(); + startInternal.m_localPosition = localStartPosition; + startInternal.m_localHitPosition = localFromWorld.TransformPoint(worldSurfacePosition); return startInternal; } @@ -46,26 +35,19 @@ namespace AzToolsFramework const StartInternal& startInternal, const AZ::Transform& worldFromLocal, const AZ::Vector3& worldSurfacePosition, - const bool snapping, - const float gridSize, + [[maybe_unused]] const bool snapping, + [[maybe_unused]] const float gridSize, const ViewportInteraction::KeyboardModifiers keyboardModifiers, - const int viewportId) + [[maybe_unused]] const int viewportId) { - const AZ::Transform worldFromLocalUniform = AzToolsFramework::TransformUniformScale(worldFromLocal); - const AZ::Transform localFromWorldUniform = worldFromLocalUniform.GetInverse(); - - const float scaleRecip = ScaleReciprocal(worldFromLocalUniform); - - const AZ::Vector3 localFinalSurfacePosition = snapping - ? CalculateSnappedTerrainPosition(worldSurfacePosition, worldFromLocalUniform, viewportId, gridSize * scaleRecip) - : localFromWorldUniform.TransformPoint(worldSurfacePosition); + const AZ::Transform localFromWorld = worldFromLocal.GetInverse(); + const AZ::Vector3 localFinalSurfacePosition = localFromWorld.TransformPoint(worldSurfacePosition); Action action; action.m_start.m_localPosition = startInternal.m_localPosition; - action.m_start.m_snapOffset = startInternal.m_snapOffset; + action.m_start.m_snapOffset = AZ::Vector3::CreateZero(); action.m_current.m_localOffset = localFinalSurfacePosition - startInternal.m_localPosition; - // record what modifier keys are held during this action - action.m_modifiers = keyboardModifiers; + action.m_modifiers = keyboardModifiers; // record what modifier keys are held during this action return action; } @@ -78,12 +60,16 @@ namespace AzToolsFramework { SetSpace(worldFromLocal); AttachLeftMouseDownImpl(); + + // only cast rays against objects (entities/meshes etc.) we can actually see + m_rayRequest.m_onlyVisible = true; } void SurfaceManipulator::InstallLeftMouseDownCallback(const MouseActionCallback& onMouseDownCallback) { m_onLeftMouseDownCallback = onMouseDownCallback; } + void SurfaceManipulator::InstallLeftMouseUpCallback(const MouseActionCallback& onMouseUpCallback) { m_onLeftMouseUpCallback = onMouseUpCallback; @@ -95,17 +81,30 @@ namespace AzToolsFramework } void SurfaceManipulator::OnLeftMouseDownImpl( - const ViewportInteraction::MouseInteraction& interaction, float /*rayIntersectionDistance*/) + const ViewportInteraction::MouseInteraction& interaction, [[maybe_unused]] float rayIntersectionDistance) { const AZ::Transform worldFromLocalUniformScale = TransformUniformScale(GetSpace()); - const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId); + const AzFramework::ViewportId viewportId = interaction.m_interactionId.m_viewportId; - AZ::Vector3 worldSurfacePosition; - ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult( - worldSurfacePosition, interaction.m_interactionId.m_viewportId, - &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain, - interaction.m_mousePick.m_screenCoordinates); + const auto& entityComponentIdPairs = EntityComponentIdPairs(); + m_rayRequest.m_entityFilter.m_ignoreEntities.clear(); + m_rayRequest.m_entityFilter.m_ignoreEntities.reserve(entityComponentIdPairs.size()); + AZStd::transform( + entityComponentIdPairs.begin(), entityComponentIdPairs.end(), + AZStd::inserter(m_rayRequest.m_entityFilter.m_ignoreEntities, m_rayRequest.m_entityFilter.m_ignoreEntities.begin()), + [](const AZ::EntityComponentIdPair& entityComponentIdPair) + { + return entityComponentIdPair.GetEntityId(); + }); + + // calculate the start and end of the ray + RefreshRayRequest( + m_rayRequest, ViewportInteraction::ViewportScreenToWorldRay(viewportId, interaction.m_mousePick.m_screenCoordinates), + EditorPickRayLength); + + const GridSnapParameters gridSnapParams = GridSnapSettings(viewportId); + const AZ::Vector3 worldSurfacePosition = FindClosestPickIntersection(m_rayRequest, GetDefaultEntityPlacementDistance()); m_startInternal = CalculateManipulationDataStart( worldFromLocalUniformScale, worldSurfacePosition, GetLocalPosition(), gridSnapParams.m_gridSnap, gridSnapParams.m_gridSize, @@ -123,17 +122,14 @@ namespace AzToolsFramework { if (m_onLeftMouseUpCallback) { - AZ::Vector3 worldSurfacePosition = AZ::Vector3::CreateZero(); - ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult( - worldSurfacePosition, interaction.m_interactionId.m_viewportId, - &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain, - interaction.m_mousePick.m_screenCoordinates); + const AzFramework::ViewportId viewportId = interaction.m_interactionId.m_viewportId; - const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId); + const GridSnapParameters gridSnapParams = GridSnapSettings(viewportId); + const AZ::Vector3 worldSurfacePosition = FindClosestPickIntersection(m_rayRequest, GetDefaultEntityPlacementDistance()); m_onLeftMouseUpCallback(CalculateManipulationDataAction( m_startInternal, TransformUniformScale(GetSpace()), worldSurfacePosition, gridSnapParams.m_gridSnap, - gridSnapParams.m_gridSize, interaction.m_keyboardModifiers, interaction.m_interactionId.m_viewportId)); + gridSnapParams.m_gridSize, interaction.m_keyboardModifiers, viewportId)); } } @@ -141,13 +137,15 @@ namespace AzToolsFramework { if (m_onMouseMoveCallback) { - AZ::Vector3 worldSurfacePosition = AZ::Vector3::CreateZero(); - ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult( - worldSurfacePosition, interaction.m_interactionId.m_viewportId, - &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain, - interaction.m_mousePick.m_screenCoordinates); + const AzFramework::ViewportId viewportId = interaction.m_interactionId.m_viewportId; - const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId); + // update the start and end of the ray + RefreshRayRequest( + m_rayRequest, ViewportInteraction::ViewportScreenToWorldRay(viewportId, interaction.m_mousePick.m_screenCoordinates), + EditorPickRayLength); + + const GridSnapParameters gridSnapParams = GridSnapSettings(viewportId); + const AZ::Vector3 worldSurfacePosition = FindClosestPickIntersection(m_rayRequest, GetDefaultEntityPlacementDistance()); m_onMouseMoveCallback(CalculateManipulationDataAction( m_startInternal, TransformUniformScale(GetSpace()), worldSurfacePosition, gridSnapParams.m_gridSnap, diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.h index c9121c49cc..091a71d8da 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.h @@ -11,6 +11,7 @@ #include "BaseManipulator.h" #include +#include #include namespace AzToolsFramework @@ -58,10 +59,12 @@ namespace AzToolsFramework Start m_start; Current m_current; ViewportInteraction::KeyboardModifiers m_modifiers; + AZ::Vector3 LocalPosition() const { return m_start.m_localPosition + m_current.m_localOffset; } + AZ::Vector3 LocalPositionOffset() const { return m_current.m_localOffset; @@ -106,6 +109,9 @@ namespace AzToolsFramework MouseActionCallback m_onLeftMouseUpCallback = nullptr; MouseActionCallback m_onMouseMoveCallback = nullptr; + //! Cached ray request initialized at mouse down and updated during mouse move. + AzFramework::RenderGeometry::RayRequest m_rayRequest; + static StartInternal CalculateManipulationDataStart( const AZ::Transform& worldFromLocal, const AZ::Vector3& worldSurfacePosition, diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.cpp index 8f8bd3e3f9..df96836bde 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.cpp @@ -64,23 +64,12 @@ namespace AzToolsFramework return circleBoundWidth; } - AZ::Vector3 FindClosestPickIntersection( - AzFramework::ViewportId viewportId, const AzFramework::ScreenPoint& screenPoint, const float rayLength, const float defaultDistance) + AZ::Vector3 FindClosestPickIntersection(const AzFramework::RenderGeometry::RayRequest& rayRequest, const float defaultDistance) { - using AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus; - AzToolsFramework::ViewportInteraction::ProjectedViewportRay viewportRay{}; - ViewportInteractionRequestBus::EventResult( - viewportRay, viewportId, &ViewportInteractionRequestBus::Events::ViewportScreenToWorldRay, screenPoint); - - AzFramework::RenderGeometry::RayRequest ray; - ray.m_startWorldPosition = viewportRay.origin; - ray.m_endWorldPosition = viewportRay.origin + viewportRay.direction * rayLength; - ray.m_onlyVisible = true; - AzFramework::RenderGeometry::RayResult renderGeometryIntersectionResult; AzFramework::RenderGeometry::IntersectorBus::EventResult( renderGeometryIntersectionResult, AzToolsFramework::GetEntityContextId(), - &AzFramework::RenderGeometry::IntersectorBus::Events::RayIntersect, ray); + &AzFramework::RenderGeometry::IntersectorBus::Events::RayIntersect, rayRequest); // attempt a ray intersection with any visible mesh and return the intersection position if successful if (renderGeometryIntersectionResult) @@ -89,7 +78,32 @@ namespace AzToolsFramework } else { - return viewportRay.origin + viewportRay.direction * defaultDistance; + const AZ::Vector3 rayDirection = (rayRequest.m_endWorldPosition - rayRequest.m_startWorldPosition).GetNormalized(); + return rayRequest.m_startWorldPosition + rayDirection * defaultDistance; } } + + void RefreshRayRequest( + AzFramework::RenderGeometry::RayRequest& rayRequest, + const ViewportInteraction::ProjectedViewportRay& viewportRay, + const float rayLength) + { + AZ_Assert(rayLength > 0.0f, "Invalid ray length passed to RefreshRayRequest"); + rayRequest.m_startWorldPosition = viewportRay.origin; + rayRequest.m_endWorldPosition = viewportRay.origin + viewportRay.direction * rayLength; + } + + AZ::Vector3 FindClosestPickIntersection( + const AzFramework::ViewportId viewportId, + const AzFramework::ScreenPoint& screenPoint, + const float rayLength, + const float defaultDistance) + { + AzFramework::RenderGeometry::RayRequest ray; + ray.m_onlyVisible = true; // only consider visible objects + + RefreshRayRequest(ray, ViewportInteraction::ViewportScreenToWorldRay(viewportId, screenPoint), rayLength); + + return FindClosestPickIntersection(ray, defaultDistance); + } } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h index aa97eb361e..aec2d3fbca 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h @@ -15,13 +15,19 @@ #include #include #include +#include #include #include namespace AzFramework { struct ScreenPoint; -} + + namespace RenderGeometry + { + struct RayRequest; + } +} // namespace AzFramework namespace AzToolsFramework { @@ -177,6 +183,26 @@ namespace AzToolsFramework //! Type to inherit to implement ViewportInteractionRequests. using ViewportInteractionRequestBus = AZ::EBus; + //! Utility function to return a viewport ray. + inline ProjectedViewportRay ViewportScreenToWorldRay( + const AzFramework::CameraState& cameraState, const AzFramework::ScreenPoint& screenPoint) + { + const AZ::Vector3 rayOrigin = AzFramework::ScreenToWorld(screenPoint, cameraState); + const AZ::Vector3 rayDirection = (rayOrigin - cameraState.m_position).GetNormalized(); + return AzToolsFramework::ViewportInteraction::ProjectedViewportRay{ rayOrigin, rayDirection }; + } + + //! Utility function to return a viewport ray using the ViewportInteractionRequestBus. + inline ProjectedViewportRay ViewportScreenToWorldRay( + const AzFramework::ViewportId viewportId, const AzFramework::ScreenPoint& screenPoint) + { + ProjectedViewportRay viewportRay{}; + ViewportInteractionRequestBus::EventResult( + viewportRay, viewportId, &ViewportInteractionRequestBus::Events::ViewportScreenToWorldRay, screenPoint); + + return viewportRay; + } + //! Interface to return only viewport specific settings (e.g. snapping). class ViewportSettingsRequests { @@ -228,10 +254,6 @@ namespace AzToolsFramework class MainEditorViewportInteractionRequests { public: - //! Given a point in screen space, return the terrain position in world space. - virtual AZ::Vector3 PickTerrain(const AzFramework::ScreenPoint& point) = 0; - //! Return the terrain height given a world position in 2d (xy plane). - virtual float TerrainHeight(const AZ::Vector2& position) = 0; //! Is the user holding a modifier key to move the manipulator space from local to world. virtual bool ShowingWorldSpace() = 0; //! Return the widget to use as the parent for the viewport context menu. @@ -337,9 +359,18 @@ namespace AzToolsFramework //! Performs an intersection test against meshes in the scene, if there is a hit (the ray intersects //! a mesh), that position is returned, otherwise a point projected defaultDistance from the //! origin of the ray will be returned. + //! @note The intersection will only consider visible objects. AZ::Vector3 FindClosestPickIntersection( AzFramework::ViewportId viewportId, const AzFramework::ScreenPoint& screenPoint, float rayLength, float defaultDistance); + //! Overload of FindClosestPickIntersection taking a RenderGeometry::RayRequest directly. + //! @note rayRequest must contain a valid ray/line segment (start/endWorldPosition must not be at the same position). + AZ::Vector3 FindClosestPickIntersection(const AzFramework::RenderGeometry::RayRequest& rayRequest, float defaultDistance); + + //! Update the in/out parameter rayRequest based on the latest viewport ray. + void RefreshRayRequest( + AzFramework::RenderGeometry::RayRequest& rayRequest, const ViewportInteraction::ProjectedViewportRay& viewportRay, float rayLength); + //! Maps a mouse interaction event to a ClickDetector event. //! @note Function only cares about up or down events, all other events are mapped to Nil (ignored). AzFramework::ClickDetector::ClickEvent ClickDetectorEventFromViewportInteraction( diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorSelectionUtil.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorSelectionUtil.cpp index 0a7bed6b18..31ea0c3985 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorSelectionUtil.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorSelectionUtil.cpp @@ -9,6 +9,7 @@ #include "EditorSelectionUtil.h" #include +#include #include #include #include @@ -16,8 +17,21 @@ #include #include +AZ_CVAR( + float, + ed_defaultEntityPlacementDistance, + 10.0f, + nullptr, + AZ::ConsoleFunctorFlags::Null, + "The default distance to place an entity from the camera if no intersection is found"); + namespace AzToolsFramework { + float GetDefaultEntityPlacementDistance() + { + return ed_defaultEntityPlacementDistance; + } + AZ::Vector3 CalculateCenterOffset(const AZ::EntityId entityId, const EditorTransformComponentSelectionRequests::Pivot pivot) { if (Centered(pivot)) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorSelectionUtil.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorSelectionUtil.h index 5c9f47fdd3..b3a6c6afd4 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorSelectionUtil.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorSelectionUtil.h @@ -60,6 +60,9 @@ namespace AzToolsFramework //! Wrapper for EBus call to return the DPI scaling for a given viewport. float GetScreenDisplayScaling(int viewportId); + //! The default distance an entity is placed from the camera if there is no intersection. + float GetDefaultEntityPlacementDistance(); + //! A utility to return the center of several points. //! Take several positions and store the min and max of each in //! turn - when all points have been added return the center/midpoint. diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp index d3540f8c09..d3cfed4665 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp @@ -231,8 +231,8 @@ namespace AzToolsFramework { return mouseInteraction.m_mouseInteraction.m_mouseButtons.Middle() && mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::Down && - mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Ctrl() && - !mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Alt(); + !mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Alt() && + mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Ctrl(); } static bool IndividualDitto(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) @@ -243,12 +243,12 @@ namespace AzToolsFramework mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Ctrl(); } - static bool SnapTerrain(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) + static bool SnapSurface(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) { return mouseInteraction.m_mouseInteraction.m_mouseButtons.Middle() && mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::Down && - (mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Alt() || - mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Ctrl()); + mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Shift() && + mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Ctrl(); } static bool ManipulatorDitto( @@ -923,26 +923,6 @@ namespace AzToolsFramework } } - static AZ::Vector3 PickTerrainPosition(const ViewportInteraction::MouseInteraction& mouseInteraction) - { - AZ_PROFILE_FUNCTION(AzToolsFramework); - - const int viewportId = mouseInteraction.m_interactionId.m_viewportId; - // get unsnapped terrain position (world space) - AZ::Vector3 worldSurfacePosition; - ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult( - worldSurfacePosition, viewportId, &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain, - mouseInteraction.m_mousePick.m_screenCoordinates); - - // convert to local space - snap if enabled - const GridSnapParameters gridSnapParams = GridSnapSettings(viewportId); - const AZ::Vector3 finalSurfacePosition = gridSnapParams.m_gridSnap - ? CalculateSnappedTerrainPosition(worldSurfacePosition, AZ::Transform::CreateIdentity(), viewportId, gridSnapParams.m_gridSize) - : worldSurfacePosition; - - return finalSurfacePosition; - } - // is the passed entity id contained with in the entity id list template static bool IsEntitySelectedInternal(AZ::EntityId entityId, const EntityIdContainer& selectedEntityIds) @@ -1286,7 +1266,7 @@ namespace AzToolsFramework m_axisPreview.m_translation = m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); m_axisPreview.m_orientation = QuaternionFromTransformNoScaling(m_entityIdManipulators.m_manipulators->GetLocalTransform()); - // [ref 1.] + // see comment [ref 1.] above BeginRecordManipulatorCommand(); }); @@ -1321,7 +1301,7 @@ namespace AzToolsFramework m_axisPreview.m_translation = m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); m_axisPreview.m_orientation = QuaternionFromTransformNoScaling(m_entityIdManipulators.m_manipulators->GetLocalTransform()); - // [ref 1.] + // see comment [ref 1.] above BeginRecordManipulatorCommand(); }); @@ -1343,6 +1323,39 @@ namespace AzToolsFramework EndRecordManipulatorCommand(); }); + // surface + translationManipulators->InstallSurfaceManipulatorMouseDownCallback( + [this, manipulatorEntityIds]([[maybe_unused]] const SurfaceManipulator::Action& action) + { + BuildSortedEntityIdVectorFromEntityIdMap(m_entityIdManipulators.m_lookups, manipulatorEntityIds->m_entityIds); + + InitializeTranslationLookup(m_entityIdManipulators); + + m_axisPreview.m_translation = m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); + m_axisPreview.m_orientation = QuaternionFromTransformNoScaling(m_entityIdManipulators.m_manipulators->GetLocalTransform()); + + // see comment [ref 1.] above + BeginRecordManipulatorCommand(); + }); + + translationManipulators->InstallSurfaceManipulatorMouseMoveCallback( + [this, prevModifiers, manipulatorEntityIds](const SurfaceManipulator::Action& action) mutable + { + UpdateTranslationManipulator( + action, manipulatorEntityIds->m_entityIds, m_entityIdManipulators, m_pivotOverrideFrame, prevModifiers, + m_transformChangedInternally, m_spaceCluster.m_spaceLock); + }); + + translationManipulators->InstallSurfaceManipulatorMouseUpCallback( + [this, manipulatorEntityIds]([[maybe_unused]] const SurfaceManipulator::Action& action) + { + AzToolsFramework::EditorTransformChangeNotificationBus::Broadcast( + &AzToolsFramework::EditorTransformChangeNotificationBus::Events::OnEntityTransformChanged, + manipulatorEntityIds->m_entityIds); + + EndRecordManipulatorCommand(); + }); + // transfer ownership m_entityIdManipulators.m_manipulators = AZStd::move(translationManipulators); } @@ -1395,7 +1408,7 @@ namespace AzToolsFramework m_axisPreview.m_translation = m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); m_axisPreview.m_orientation = QuaternionFromTransformNoScaling(m_entityIdManipulators.m_manipulators->GetLocalTransform()); - // [ref 1.] + // see comment [ref 1.] above BeginRecordManipulatorCommand(); }); @@ -1867,6 +1880,13 @@ namespace AzToolsFramework if (!m_selectedEntityIds.empty()) { + // try snapping to a surface (mesh) if in Translation mode + if (Input::SnapSurface(mouseInteraction)) + { + PerformSnapToSurface(mouseInteraction); + return false; + } + // group copying/alignment to specific entity - 'ditto' position/orientation for group if (Input::GroupDitto(mouseInteraction) && PerformGroupDitto(entityIdUnderCursor)) { @@ -1879,13 +1899,6 @@ namespace AzToolsFramework return false; } - // try snapping to the terrain (if in Translation mode) and entity wasn't picked - if (Input::SnapTerrain(mouseInteraction)) - { - PerformSnapToTerrain(mouseInteraction); - return false; - } - // set manipulator pivot override translation or orientation (update manipulators) if (Input::ManipulatorDitto(clickOutcome, mouseInteraction)) { @@ -1973,25 +1986,28 @@ namespace AzToolsFramework return false; } - void EditorTransformComponentSelection::PerformSnapToTerrain(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) + void EditorTransformComponentSelection::PerformSnapToSurface(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) { - for (AZ::EntityId entityId : m_selectedEntityIds) + for (const AZ::EntityId& entityId : m_selectedEntityIds) { ScopedUndoBatch::MarkEntityDirty(entityId); } if (m_mode == Mode::Translation) { - const AZ::Vector3 finalSurfacePosition = PickTerrainPosition(mouseInteraction.m_mouseInteraction); + const AZ::Vector3 worldPosition = FindClosestPickIntersection( + mouseInteraction.m_mouseInteraction.m_interactionId.m_viewportId, + mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates, AzToolsFramework::EditorPickRayLength, + GetDefaultEntityPlacementDistance()); // handle modifier alternatives if (Input::IndividualDitto(mouseInteraction)) { - CopyTranslationToSelectedEntitiesIndividual(finalSurfacePosition); + CopyTranslationToSelectedEntitiesIndividual(worldPosition); } else if (Input::GroupDitto(mouseInteraction)) { - CopyTranslationToSelectedEntitiesGroup(finalSurfacePosition); + CopyTranslationToSelectedEntitiesGroup(worldPosition); } } else if (m_mode == Mode::Rotation) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.h index 10f83db739..afc290380b 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.h @@ -308,7 +308,7 @@ namespace AzToolsFramework bool PerformGroupDitto(AZ::EntityId entityId); bool PerformIndividualDitto(AZ::EntityId entityId); void PerformManipulatorDitto(AZ::EntityId entityId); - void PerformSnapToTerrain(const ViewportInteraction::MouseInteractionEvent& mouseInteraction); + void PerformSnapToSurface(const ViewportInteraction::MouseInteractionEvent& mouseInteraction); //! Responsible for keeping the space cluster in sync with the current reference frame. void UpdateSpaceCluster(ReferenceFrame referenceFrame); diff --git a/Code/Framework/AzToolsFramework/Tests/BoundsTestComponent.cpp b/Code/Framework/AzToolsFramework/Tests/BoundsTestComponent.cpp index fa5a6b344a..0b3c574e16 100644 --- a/Code/Framework/AzToolsFramework/Tests/BoundsTestComponent.cpp +++ b/Code/Framework/AzToolsFramework/Tests/BoundsTestComponent.cpp @@ -8,6 +8,8 @@ #include +#include +#include #include namespace UnitTest @@ -62,4 +64,51 @@ namespace UnitTest { return m_localBounds; } + + void RenderGeometryIntersectionTestComponent::Reflect(AZ::ReflectContext* context) + { + if (auto serializeContext = azrtti_cast(context)) + { + serializeContext->Class()->Version(1); + } + } + + void RenderGeometryIntersectionTestComponent::Activate() + { + BoundsTestComponent::Activate(); + + const AZ::EntityId entityId = GetEntityId(); + AzFramework::EntityContextId contextId = AzFramework::EntityContextId::CreateNull(); + AzFramework::EntityIdContextQueryBus::EventResult(contextId, entityId, &AzFramework::EntityIdContextQueries::GetOwningContextId); + AzFramework::RenderGeometry::IntersectionRequestBus::Handler::BusConnect({entityId, contextId}); + } + + void RenderGeometryIntersectionTestComponent::Deactivate() + { + AzFramework::RenderGeometry::IntersectionRequestBus::Handler::BusDisconnect(); + BoundsTestComponent::Deactivate(); + } + + AzFramework::RenderGeometry::RayResult RenderGeometryIntersectionTestComponent::RenderGeometryIntersect( + const AzFramework::RenderGeometry::RayRequest& ray) + { + AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity(); + AZ::TransformBus::EventResult(worldFromLocal, GetEntityId(), &AZ::TransformBus::Events::GetWorldTM); + + AzFramework::RenderGeometry::RayResult rayResult; + + float t = 0.0f; + const AZ::Obb obb = GetLocalBounds().GetTransformedObb(worldFromLocal); + const AZ::Vector3 rayDirection = ray.m_endWorldPosition - ray.m_startWorldPosition; + if (AZ::Intersect::IntersectRayObb(ray.m_startWorldPosition, rayDirection, obb, t)) + { + rayResult.m_worldPosition = ray.m_startWorldPosition + rayDirection * t; + rayResult.m_entityAndComponent = AZ::EntityComponentIdPair(GetEntityId(), GetId()); + rayResult.m_distance = t; + rayResult.m_uv = AZ::Vector2::CreateZero(); + rayResult.m_worldNormal = AZ::Vector3::CreateZero(); + } + + return rayResult; + } } // namespace UnitTest diff --git a/Code/Framework/AzToolsFramework/Tests/BoundsTestComponent.h b/Code/Framework/AzToolsFramework/Tests/BoundsTestComponent.h index 358a9f810a..2eee3c0a66 100644 --- a/Code/Framework/AzToolsFramework/Tests/BoundsTestComponent.h +++ b/Code/Framework/AzToolsFramework/Tests/BoundsTestComponent.h @@ -8,6 +8,7 @@ #pragma once +#include #include #include #include @@ -44,4 +45,21 @@ namespace UnitTest AZ::Aabb m_localBounds; //!< Local bounds that can be modified for certain tests (defaults to unit cube). }; + + class RenderGeometryIntersectionTestComponent + : public BoundsTestComponent + , public AzFramework::RenderGeometry::IntersectionRequestBus::Handler + { + public: + AZ_EDITOR_COMPONENT(RenderGeometryIntersectionTestComponent, "{6F46B5BF-60DF-4BDD-9BA7-9658E85B99C2}", BoundsTestComponent); + + static void Reflect(AZ::ReflectContext* context); + + // AZ::Component overrides ... + void Activate() override; + void Deactivate() override; + + // IntersectionRequestBus overrides ... + AzFramework::RenderGeometry::RayResult RenderGeometryIntersect(const AzFramework::RenderGeometry::RayRequest& ray) override; + }; } // namespace UnitTest diff --git a/Code/Framework/AzToolsFramework/Tests/EditorTransformComponentSelectionTests.cpp b/Code/Framework/AzToolsFramework/Tests/EditorTransformComponentSelectionTests.cpp index f4077e992b..859cc67c41 100644 --- a/Code/Framework/AzToolsFramework/Tests/EditorTransformComponentSelectionTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/EditorTransformComponentSelectionTests.cpp @@ -1663,7 +1663,7 @@ namespace UnitTest const AZ::Transform finalEntityTransform = AzToolsFramework::GetWorldTransform(m_entityId1); // ensure final world positions match - EXPECT_TRUE(finalEntityTransform.IsClose(finalTransformWorld, 0.01f)); + EXPECT_THAT(finalEntityTransform, IsCloseTolerance(finalTransformWorld, 0.01f)); } TEST_F(EditorTransformComponentSelectionManipulatorTestFixture, TranslatingEntityWithLinearManipulatorNotifiesOnEntityTransformChanged) @@ -2973,4 +2973,176 @@ namespace UnitTest EXPECT_THAT(hoveredEntityIdAccentRemoved, IsTrue()); EXPECT_THAT(hoveredEntityEntityId, Eq(AZ::EntityId(12345))); } + + class EditorTransformComponentSelectionRenderGeometryIntersectionFixture : public ToolsApplicationFixture + { + public: + void SetUpEditorFixtureImpl() override + { + auto* app = GetApplication(); + // register a simple component implementing BoundsRequestBus and EditorComponentSelectionRequestsBus + app->RegisterComponentDescriptor(BoundsTestComponent::CreateDescriptor()); + // register a component implementing RenderGeometry::IntersectionRequestBus + app->RegisterComponentDescriptor(RenderGeometryIntersectionTestComponent::CreateDescriptor()); + + auto createEntityWithGeometryIntersectionFn = [](const char* entityName) + { + AZ::Entity* entity = nullptr; + AZ::EntityId entityId = CreateDefaultEditorEntity(entityName, &entity); + + entity->Deactivate(); + entity->CreateComponent(); + entity->Activate(); + + return entityId; + }; + + m_entityIdGround = createEntityWithGeometryIntersectionFn("Entity1"); + m_entityIdBox = createEntityWithGeometryIntersectionFn("Entity2"); + + if (auto* ground = AzToolsFramework::GetEntityById(m_entityIdGround)->FindComponent()) + { + ground->m_localBounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-10.0f, -10.0f, -0.5f), AZ::Vector3(10.0f, 10.0f, 0.5f)); + } + + AzToolsFramework::SetWorldTransform(m_entityIdGround, AZ::Transform::CreateTranslation(AZ::Vector3(0.0f, 10.0f, 5.0f))); + + if (auto* box = AzToolsFramework::GetEntityById(m_entityIdBox)->FindComponent()) + { + box->m_localBounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-0.5f), AZ::Vector3(0.5f)); + } + + AzToolsFramework::SetWorldTransform( + m_entityIdBox, + AZ::Transform::CreateFromMatrix3x3AndTranslation( + AZ::Matrix3x3::CreateRotationZ(AZ::DegToRad(45.0f)), AZ::Vector3(0.0f, 10.0f, 7.0f))); + } + + AZ::EntityId m_entityIdGround; + AZ::EntityId m_entityIdBox; + }; + + using EditorTransformComponentSelectionRenderGeometryIntersectionManipulatorFixture = + IndirectCallManipulatorViewportInteractionFixtureMixin; + + TEST_F( + EditorTransformComponentSelectionRenderGeometryIntersectionManipulatorFixture, BoxCanBePlacedOnMeshSurfaceUsingSurfaceManipulator) + { + // camera (go to position format) - 0.00, 20.00, 12.00, -35.00, -180.00 + m_cameraState.m_viewportSize = AZ::Vector2(1280.0f, 720.0f); + AzFramework::SetCameraTransform( + m_cameraState, + AZ::Transform::CreateFromMatrix3x3AndTranslation( + AZ::Matrix3x3::CreateRotationZ(AZ::DegToRad(-180.0f)) * AZ::Matrix3x3::CreateRotationX(AZ::DegToRad(-35.0f)), + AZ::Vector3(0.0f, 20.0f, 12.0f))); + + // the initial starting position of the entity + const auto initialTransformWorld = AzToolsFramework::GetWorldTransform(m_entityIdBox); + // where the entity should end up (snapped to the larger ground surface) + const auto finalTransformWorld = + AZ::Transform::CreateFromQuaternionAndTranslation(initialTransformWorld.GetRotation(), AZ::Vector3(2.5f, 12.5f, 5.5f)); + + // calculate the position in screen space of the initial position of the entity + const auto initialPositionScreen = AzFramework::WorldToScreen(initialTransformWorld.GetTranslation(), m_cameraState); + // calculate the position in screen space of the final position of the entity + const auto finalPositionScreen = AzFramework::WorldToScreen(finalTransformWorld.GetTranslation(), m_cameraState); + + // select the entity (this will cause the manipulators to appear in EditorTransformComponentSelection) + AzToolsFramework::SelectEntity(m_entityIdBox); + + // press and drag the mouse (starting where the surface manipulator is) + m_actionDispatcher->CameraState(m_cameraState) + ->MousePosition(initialPositionScreen) + ->MouseLButtonDown() + ->MousePosition(finalPositionScreen) + ->MouseLButtonUp(); + + // read back the position of the entity now + const AZ::Transform finalEntityTransform = AzToolsFramework::GetWorldTransform(m_entityIdBox); + + // ensure final world positions match + EXPECT_THAT(finalEntityTransform, IsCloseTolerance(finalTransformWorld, 0.01f)); + } + + TEST_F( + EditorTransformComponentSelectionRenderGeometryIntersectionManipulatorFixture, + SurfaceManipulatorFollowsMouseAtDefaultEditorDistanceFromCameraWhenNoMeshIntersection) + { + // camera (go to position format) - 0.00, 25.00, 12.00, 0.00, -180.00 + m_cameraState.m_viewportSize = AZ::Vector2(1280.0f, 720.0f); + AzFramework::SetCameraTransform( + m_cameraState, + AZ::Transform::CreateFromMatrix3x3AndTranslation( + AZ::Matrix3x3::CreateRotationZ(AZ::DegToRad(-180.0f)), AZ::Vector3(0.0f, 25.0f, 12.0f))); + + // the initial starting position of the entity + const auto initialTransformWorld = AzToolsFramework::GetWorldTransform(m_entityIdBox); + // where the entity should end up (default distance away from the camera/near clip under where the mouse is) + const auto finalTransformWorld = + AZ::Transform::CreateFromQuaternionAndTranslation(initialTransformWorld.GetRotation(), AZ::Vector3(0.0f, 14.9f, 12.0f)); + + // calculate the position in screen space of the initial position of the entity + const auto initialPositionScreen = AzFramework::WorldToScreen(initialTransformWorld.GetTranslation(), m_cameraState); + // calculate the position in screen space of the final position of the entity + const auto finalPositionScreen = AzFramework::WorldToScreen(finalTransformWorld.GetTranslation(), m_cameraState); + + // select the entity (this will cause the manipulators to appear in EditorTransformComponentSelection) + AzToolsFramework::SelectEntity(m_entityIdBox); + + // press and drag the mouse (starting where the surface manipulator is) + m_actionDispatcher->CameraState(m_cameraState) + ->MousePosition(initialPositionScreen) + ->MouseLButtonDown() + ->MousePosition(finalPositionScreen) + ->MouseLButtonUp(); + + // read back the position of the entity now + const AZ::Transform finalEntityTransform = AzToolsFramework::GetWorldTransform(m_entityIdBox); + + const auto viewportRay = AzToolsFramework::ViewportInteraction::ViewportScreenToWorldRay(m_cameraState, initialPositionScreen); + const auto distanceAway = (finalEntityTransform.GetTranslation() - viewportRay.origin).GetLength(); + + // ensure final world positions match + EXPECT_THAT(finalEntityTransform, IsCloseTolerance(finalTransformWorld, 0.01f)); + // ensure distance away is what we expect + EXPECT_NEAR(distanceAway, AzToolsFramework::GetDefaultEntityPlacementDistance(), 0.001f); + } + + TEST_F( + EditorTransformComponentSelectionRenderGeometryIntersectionManipulatorFixture, + MiddleMouseButtonWithShiftAndCtrlHeldOnMeshSurfaceWillSnapSelectedEntityToIntersectionPoint) + { + // camera (go to position format) - 21.00, 8.00, 11.00, -22.00, 150.00 + m_cameraState.m_viewportSize = AZ::Vector2(1280.0f, 720.0f); + AzFramework::SetCameraTransform( + m_cameraState, + AZ::Transform::CreateFromMatrix3x3AndTranslation( + AZ::Matrix3x3::CreateRotationZ(AZ::DegToRad(150.0f)) * AZ::Matrix3x3::CreateRotationX(AZ::DegToRad(-22.0f)), + AZ::Vector3(21.0f, 8.0f, 11.0f))); + + // position the ground entity + AzToolsFramework::SetWorldTransform( + m_entityIdGround, + AZ::Transform::CreateFromMatrix3x3AndTranslation( + AZ::Matrix3x3::CreateRotationY(AZ::DegToRad(40.0f)) * AZ::Matrix3x3::CreateRotationZ(AZ::DegToRad(60.0f)), + AZ::Vector3(14.0f, -6.0f, 5.0f))); + + // select the other entity (a 1x1x1 box) + AzToolsFramework::SelectEntity(m_entityIdBox); + + // expected world position (value taken from editor scenario) + const auto expectedWorldPosition = AZ::Vector3(13.606657f, -2.6753534f, 5.9827675f); + const auto screenPosition = AzFramework::WorldToScreen(expectedWorldPosition, m_cameraState); + + // perform snap action + m_actionDispatcher->CameraState(m_cameraState) + ->MousePosition(screenPosition) + ->KeyboardModifierDown(AzToolsFramework::ViewportInteraction::KeyboardModifier::Control) + ->KeyboardModifierDown(AzToolsFramework::ViewportInteraction::KeyboardModifier::Shift) + ->MouseMButtonDown(); + + // read back the current entity transform after placement + const AZ::Transform finalEntityTransform = AzToolsFramework::GetWorldTransform(m_entityIdBox); + EXPECT_THAT(finalEntityTransform.GetTranslation(), IsCloseTolerance(expectedWorldPosition, 0.01f)); + } } // namespace UnitTest diff --git a/Code/Framework/AzToolsFramework/Tests/EditorVertexSelectionTests.cpp b/Code/Framework/AzToolsFramework/Tests/EditorVertexSelectionTests.cpp index 93010aa63d..228dea6b7c 100644 --- a/Code/Framework/AzToolsFramework/Tests/EditorVertexSelectionTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/EditorVertexSelectionTests.cpp @@ -10,22 +10,23 @@ #include #include #include +#include +#include +#include +#include +#include #include #include +#include #include #include #include #include #include #include -#include -#include -#include -#include -#include #include -using namespace AzToolsFramework; +#include namespace UnitTest { @@ -42,20 +43,65 @@ namespace UnitTest void Disconnect(); // FixedVerticesRequestBus/VariableVerticesRequestBus ... - bool GetVertex(size_t index, AZ::Vector3& vertex) const override { return m_vertexContainer.GetVertex(index, vertex); } - bool UpdateVertex(size_t index, const AZ::Vector3& vertex) override { return m_vertexContainer.UpdateVertex(index, vertex); }; - void AddVertex(const AZ::Vector3& vertex) override { m_vertexContainer.AddVertex(vertex); } - bool InsertVertex(size_t index, const AZ::Vector3& vertex) override { return m_vertexContainer.InsertVertex(index, vertex); } - bool RemoveVertex(size_t index) override { return m_vertexContainer.RemoveVertex(index); } - void SetVertices(const AZStd::vector& vertices) override { m_vertexContainer.SetVertices(vertices); }; - void ClearVertices() override { m_vertexContainer.Clear(); } - size_t Size() const override { return m_vertexContainer.Size(); } - bool Empty() const override { return m_vertexContainer.Empty(); } + bool GetVertex(size_t index, AZ::Vector3& vertex) const override; + bool UpdateVertex(size_t index, const AZ::Vector3& vertex) override; + void AddVertex(const AZ::Vector3& vertex) override; + bool InsertVertex(size_t index, const AZ::Vector3& vertex) override; + bool RemoveVertex(size_t index) override; + void SetVertices(const AZStd::vector& vertices) override; + void ClearVertices() override; + size_t Size() const override; + bool Empty() const override; private: AZ::VertexContainer m_vertexContainer; }; + bool TestVariableVerticesVertexContainer::GetVertex(size_t index, AZ::Vector3& vertex) const + { + return m_vertexContainer.GetVertex(index, vertex); + } + + bool TestVariableVerticesVertexContainer::UpdateVertex(size_t index, const AZ::Vector3& vertex) + { + return m_vertexContainer.UpdateVertex(index, vertex); + } + + void TestVariableVerticesVertexContainer::AddVertex(const AZ::Vector3& vertex) + { + m_vertexContainer.AddVertex(vertex); + } + + bool TestVariableVerticesVertexContainer::InsertVertex(size_t index, const AZ::Vector3& vertex) + { + return m_vertexContainer.InsertVertex(index, vertex); + } + + bool TestVariableVerticesVertexContainer::RemoveVertex(size_t index) + { + return m_vertexContainer.RemoveVertex(index); + } + + void TestVariableVerticesVertexContainer::SetVertices(const AZStd::vector& vertices) + { + m_vertexContainer.SetVertices(vertices); + } + + void TestVariableVerticesVertexContainer::ClearVertices() + { + m_vertexContainer.Clear(); + } + + size_t TestVariableVerticesVertexContainer::Size() const + { + return m_vertexContainer.Size(); + } + + bool TestVariableVerticesVertexContainer::Empty() const + { + return m_vertexContainer.Empty(); + } + void TestVariableVerticesVertexContainer::Connect(const AZ::EntityId entityId) { AZ::VariableVerticesRequestBus::Handler::BusConnect(entityId); @@ -68,17 +114,18 @@ namespace UnitTest AZ::VariableVerticesRequestBus::Handler::BusDisconnect(); } - class TestEditorVertexSelectionVariable - : public EditorVertexSelectionVariable + class TestEditorVertexSelectionVariable : public AzToolsFramework::EditorVertexSelectionVariable { public: AZ_CLASS_ALLOCATOR(TestEditorVertexSelectionVariable, AZ::SystemAllocator, 0) - void ShowVertexDeletionWarning() override { /*noop*/ } + void ShowVertexDeletionWarning() override + { + // noop + } }; - class EditorVertexSelectionFixture - : public ToolsApplicationFixture + class EditorVertexSelectionFixture : public ToolsApplicationFixture { public: void SetUpEditorFixtureImpl() override @@ -112,26 +159,25 @@ namespace UnitTest void EditorVertexSelectionFixture::RecreateVertexSelection() { + namespace aztf = AzToolsFramework; m_vertexSelection.Create( - AZ::EntityComponentIdPair(m_entityId, TestComponentId), - g_mainManipulatorManagerId, AZStd::make_unique(), - TranslationManipulators::Dimensions::Three, ConfigureTranslationManipulatorAppearance3d); + AZ::EntityComponentIdPair(m_entityId, TestComponentId), aztf::g_mainManipulatorManagerId, + AZStd::make_unique(), aztf::TranslationManipulators::Dimensions::Three, + aztf::ConfigureTranslationManipulatorAppearance3d); } void EditorVertexSelectionFixture::PopulateVertices() { for (size_t vertIndex = 0; vertIndex < EditorVertexSelectionFixture::VertexCount; ++vertIndex) { - InsertVertexAfter( - AZ::EntityComponentIdPair(m_entityId, TestComponentId), 0, AZ::Vector3::CreateZero()); + AzToolsFramework::InsertVertexAfter(AZ::EntityComponentIdPair(m_entityId, TestComponentId), 0, AZ::Vector3::CreateZero()); } } void EditorVertexSelectionFixture::ClearVertices() { for (size_t vertIndex = 0; vertIndex < EditorVertexSelectionFixture::VertexCount; ++vertIndex) { - SafeRemoveVertex( - AZ::EntityComponentIdPair(m_entityId, TestComponentId), 0); + AzToolsFramework::SafeRemoveVertex(AZ::EntityComponentIdPair(m_entityId, TestComponentId), 0); } } @@ -188,7 +234,7 @@ namespace UnitTest /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // When // just provide a placeholder mouse interaction event in this case - m_vertexSelection.SnapVerticesToTerrain(ViewportInteraction::MouseInteractionEvent{}); + m_vertexSelection.SnapVerticesToSurface(AzToolsFramework::ViewportInteraction::MouseInteractionEvent{}); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -197,8 +243,7 @@ namespace UnitTest /////////////////////////////////////////////////////////////////////////////////////////////////////////////// } - using EditorVertexSelectionManipulatorFixture = - IndirectCallManipulatorViewportInteractionFixtureMixin; + using EditorVertexSelectionManipulatorFixture = IndirectCallManipulatorViewportInteractionFixtureMixin; TEST_F(EditorVertexSelectionManipulatorFixture, CannotDeleteAllVertices) { @@ -206,25 +251,23 @@ namespace UnitTest const auto entityComponentIdPair = AZ::EntityComponentIdPair(m_entityId, TestComponentId); - const float horizontalPositions[] = {-1.5f, -0.5f, 0.5f, 1.5f}; - for (size_t vertIndex = 0; vertIndex < std::size(horizontalPositions); ++vertIndex) + const float horizontalPositions[] = { -1.5f, -0.5f, 0.5f, 1.5f }; + for (size_t vertIndex = 0; vertIndex < AZStd::size(horizontalPositions); ++vertIndex) { - InsertVertexAfter( - entityComponentIdPair, vertIndex, AZ::Vector3(horizontalPositions[vertIndex], 5.0f, 0.0f)); + AzToolsFramework::InsertVertexAfter(entityComponentIdPair, vertIndex, AZ::Vector3(horizontalPositions[vertIndex], 5.0f, 0.0f)); } - // rebuild the vertex selection after adding the new verts + // rebuild the vertex selection after adding the new vertices RecreateVertexSelection(); // build a vector of the vertex positions in screen space AZStd::vector vertexScreenPositions; - for (size_t vertIndex = 0; vertIndex < std::size(horizontalPositions); ++vertIndex) + for (size_t vertIndex = 0; vertIndex < AZStd::size(horizontalPositions); ++vertIndex) { - AZ::Vector3 localVertex; + AZ::Vector3 localVertex = AZ::Vector3::CreateZero(); bool found = false; AZ::FixedVerticesRequestBus::EventResult( - found, m_entityId, &AZ::FixedVerticesRequestBus::Handler::GetVertex, - vertIndex, localVertex); + found, m_entityId, &AZ::FixedVerticesRequestBus::Handler::GetVertex, vertIndex, localVertex); if (found) { @@ -267,9 +310,9 @@ namespace UnitTest const auto entityComponentIdPair = AZ::EntityComponentIdPair(m_entityId, TestComponentId); // add a single vertex (in front of the camera) - InsertVertexAfter(entityComponentIdPair, 0, AZ::Vector3::CreateAxisY(5.0f)); + AzToolsFramework::InsertVertexAfter(entityComponentIdPair, 0, AZ::Vector3::CreateAxisY(5.0f)); - // rebuild the vertex selection after adding the new verts + // rebuild the vertex selection after adding the new vertices RecreateVertexSelection(); AzFramework::ScreenPoint vertexScreenPosition; @@ -300,4 +343,132 @@ namespace UnitTest // deleting the last vertex through a manipulator is disallowed - size should remain the same EXPECT_THAT(vertexCountAfter, Eq(1)); } + + static AZ::EntityId CreateEntityForVertexIntersectionPlacement(EditorVertexSelectionManipulatorFixture& fixture) + { + auto* app = fixture.GetApplication(); + app->RegisterComponentDescriptor(BoundsTestComponent::CreateDescriptor()); + app->RegisterComponentDescriptor(RenderGeometryIntersectionTestComponent::CreateDescriptor()); + + AZ::Entity* entityGround = nullptr; + AZ::EntityId entityIdGround = CreateDefaultEditorEntity("EntityGround", &entityGround); + + entityGround->Deactivate(); + auto ground = entityGround->CreateComponent(); + entityGround->Activate(); + + ground->m_localBounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-10.0f, -10.0f, -0.5f), AZ::Vector3(10.0f, 10.0f, 0.5f)); + + return entityIdGround; + } + + static AZStd::vector SetupVertices( + const AZ::EntityId entityId, EditorVertexSelectionManipulatorFixture& fixture) + { + const auto entityComponentIdPair = AZ::EntityComponentIdPair(entityId, TestComponentId); + const float horizontalPositions[] = { -3.0f, -1.0f, 1.0f, 3.0f }; + for (size_t vertIndex = 0; vertIndex < AZStd::size(horizontalPositions); ++vertIndex) + { + AzToolsFramework::InsertVertexAfter(entityComponentIdPair, vertIndex, AZ::Vector3(horizontalPositions[vertIndex], 0.0f, 0.0f)); + } + + // rebuild the vertex selection after adding the new vertices + fixture.RecreateVertexSelection(); + + // build a vector of the vertex positions in screen space + AZStd::vector vertexScreenPositions; + for (size_t vertIndex = 0; vertIndex < AZStd::size(horizontalPositions); ++vertIndex) + { + AZ::Vector3 localVertex; + bool found = false; + AZ::FixedVerticesRequestBus::EventResult( + found, entityId, &AZ::FixedVerticesRequestBus::Handler::GetVertex, vertIndex, localVertex); + + if (found) + { + const AZ::Vector3 worldVertex = AzToolsFramework::GetWorldTransform(entityId).TransformPoint(localVertex); + vertexScreenPositions.push_back(AzFramework::WorldToScreen(worldVertex, fixture.m_cameraState)); + } + } + + return vertexScreenPositions; + } + + AzToolsFramework::ViewportInteraction::MouseInteractionEvent BuildMiddleMouseDownEvent( + const AzFramework::ScreenPoint& screenPosition, const AzFramework::ViewportId viewportId) + { + AzToolsFramework::ViewportInteraction::MousePick mousePick; + mousePick.m_screenCoordinates = screenPosition; + + AzToolsFramework::ViewportInteraction::MouseInteraction mouseInteraction; + mouseInteraction.m_interactionId.m_cameraId = AZ::EntityId(); + mouseInteraction.m_interactionId.m_viewportId = viewportId; + mouseInteraction.m_mouseButtons = + AzToolsFramework::ViewportInteraction::MouseButtonsFromButton(AzToolsFramework::ViewportInteraction::MouseButton::Middle); + mouseInteraction.m_mousePick = mousePick; + mouseInteraction.m_keyboardModifiers = AzToolsFramework::ViewportInteraction::KeyboardModifiers( + static_cast(AzToolsFramework::ViewportInteraction::KeyboardModifier::Shift) | + static_cast(AzToolsFramework::ViewportInteraction::KeyboardModifier::Ctrl)); + + return AzToolsFramework::ViewportInteraction::MouseInteractionEvent( + mouseInteraction, AzToolsFramework::ViewportInteraction::MouseEvent::Down, /*captured=*/false); + } + + TEST_F(EditorVertexSelectionManipulatorFixture, VertexPlacedWhereIntersectionPointIsFoundWithCustomReferenceSpace) + { + const AZ::EntityId entityIdGround = CreateEntityForVertexIntersectionPlacement(*this); + + // position ground + AzToolsFramework::SetWorldTransform( + entityIdGround, + AZ::Transform::CreateFromMatrix3x3AndTranslation( + AZ::Matrix3x3::CreateRotationX(AZ::DegToRad(-20.0f)) * AZ::Matrix3x3::CreateRotationY(AZ::DegToRad(-40.0f)) * + AZ::Matrix3x3::CreateRotationZ(AZ::DegToRad(60.0f)), + AZ::Vector3(14.0f, -6.0f, 5.0f))); + + // camera (go to position format) - 12.00, 18.00, 16.00, -38.00, -175.00 + m_cameraState.m_viewportSize = AZ::Vector2(1280.0f, 720.0f); + AzFramework::SetCameraTransform( + m_cameraState, + AZ::Transform::CreateFromMatrix3x3AndTranslation( + AZ::Matrix3x3::CreateRotationZ(AZ::DegToRad(-175.0f)) * AZ::Matrix3x3::CreateRotationX(AZ::DegToRad(-38.0f)), + AZ::Vector3(12.0f, 18.0f, 16.0f))); + + // create orientated and scaled transform for vertex selection entity transform + auto vertexSelectionTransform = AZ::Transform::CreateFromMatrix3x3AndTranslation( + AZ::Matrix3x3::CreateRotationZ(AZ::DegToRad(45.0f)), AZ::Vector3(14.0f, 7.0f, 5.0f)); + vertexSelectionTransform.MultiplyByUniformScale(3.0f); + + // set the initial starting position of the vertex selection + AzToolsFramework::SetWorldTransform(m_entityId, vertexSelectionTransform); + + auto vertexScreenPositions = SetupVertices(m_entityId, *this); + + // press and drag the mouse (starting where the surface manipulator is) + // select each vertex (by holding ctrl) + m_actionDispatcher->CameraState(m_cameraState)->MousePosition(vertexScreenPositions[0])->MouseLButtonDown()->MouseLButtonUp(); + + const auto finalPositionWorld = AZ::Vector3(14.3573294f, -8.94695091f, 7.08627319f); + // calculate the position in screen space of the final position of the entity + const auto finalPositionScreen = AzFramework::WorldToScreen(finalPositionWorld, m_cameraState); + + auto middleMouseDownEvent = + BuildMiddleMouseDownEvent(finalPositionScreen, m_viewportManipulatorInteraction->GetViewportInteraction().GetViewportId()); + + // explicitly handle mouse event in vertex selection instance + m_vertexSelection.HandleMouse(middleMouseDownEvent); + + // read back the position of the vertex now + AZ::Vector3 localVertex = AZ::Vector3::CreateZero(); + bool found = false; + AZ::FixedVerticesRequestBus::EventResult( + found, m_entityId, &AZ::FixedVerticesRequestBus::Handler::GetVertex, 0, localVertex); + + // transform to world space + const AZ::Vector3 worldVertex = vertexSelectionTransform.TransformPoint(localVertex); + + EXPECT_THAT(found, ::testing::IsTrue()); + // ensure final world positions match + EXPECT_THAT(worldVertex, IsCloseTolerance(finalPositionWorld, 0.01f)); + } } // namespace UnitTest diff --git a/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportInteractionTests.cpp b/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportInteractionTests.cpp new file mode 100644 index 0000000000..fdcc8553f2 --- /dev/null +++ b/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportInteractionTests.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace UnitTest +{ + class IndirectCallViewportInteractionIntersectionFixture : public ToolsApplicationFixture + { + public: + void SetUpEditorFixtureImpl() override + { + auto* app = GetApplication(); + // register a simple component implementing BoundsRequestBus and EditorComponentSelectionRequestsBus + app->RegisterComponentDescriptor(BoundsTestComponent::CreateDescriptor()); + // register a component implementing RenderGeometry::IntersectionRequestBus + app->RegisterComponentDescriptor(RenderGeometryIntersectionTestComponent::CreateDescriptor()); + + AZ::Entity* entityGround = nullptr; + m_entityIdGround = CreateDefaultEditorEntity("EntityGround", &entityGround); + + entityGround->Deactivate(); + auto ground = entityGround->CreateComponent(); + entityGround->Activate(); + + ground->m_localBounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-10.0f, -10.0f, -0.5f), AZ::Vector3(10.0f, 10.0f, 0.5f)); + } + + AZ::EntityId m_entityIdGround; + }; + + using IndirectCallManipulatorViewportInteractionIntersectionFixture = + IndirectCallManipulatorViewportInteractionFixtureMixin; + + TEST_F(IndirectCallManipulatorViewportInteractionIntersectionFixture, FindClosestPickIntersectionReturnsExpectedSurfacePoint) + { + // camera - 21.00, 8.00, 11.00, -22.00, 150.00 + m_cameraState.m_viewportSize = AZ::Vector2(1280.0f, 720.0f); + AzFramework::SetCameraTransform( + m_cameraState, + AZ::Transform::CreateFromMatrix3x3AndTranslation( + AZ::Matrix3x3::CreateRotationZ(AZ::DegToRad(150.0f)) * AZ::Matrix3x3::CreateRotationX(AZ::DegToRad(-22.0f)), + AZ::Vector3(21.0f, 8.0f, 11.0f))); + + m_actionDispatcher->CameraState(m_cameraState); + + AzToolsFramework::SetWorldTransform( + m_entityIdGround, + AZ::Transform::CreateFromMatrix3x3AndTranslation( + AZ::Matrix3x3::CreateRotationY(AZ::DegToRad(40.0f)) * AZ::Matrix3x3::CreateRotationZ(AZ::DegToRad(60.0f)), + AZ::Vector3(14.0f, -6.0f, 5.0f))); + + // expected world position (value taken from editor scenario) + const auto expectedWorldPosition = AZ::Vector3(13.606657f, -2.6753534f, 5.9827675f); + const auto screenPosition = AzFramework::WorldToScreen(expectedWorldPosition, m_cameraState); + + // perform ray intersection against mesh + const auto worldIntersectionPoint = AzToolsFramework::FindClosestPickIntersection( + m_viewportManipulatorInteraction->GetViewportInteraction().GetViewportId(), screenPosition, + AzToolsFramework::EditorPickRayLength, AzToolsFramework::GetDefaultEntityPlacementDistance()); + + EXPECT_THAT(worldIntersectionPoint, IsCloseTolerance(expectedWorldPosition, 0.01f)); + } +} // namespace UnitTest diff --git a/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake b/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake index 9e052de983..8e0297fb1f 100644 --- a/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake +++ b/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake @@ -136,5 +136,6 @@ set(FILES Viewport/ViewportUiDisplayTests.cpp Viewport/ViewportUiManagerTests.cpp Viewport/ViewportUiWidgetManagerTests.cpp + Viewport/ViewportInteractionTests.cpp Visibility/EditorVisibilityTests.cpp ) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ViewportInteractionImpl.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ViewportInteractionImpl.cpp index 1a015c167c..7ae3175e03 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ViewportInteractionImpl.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ViewportInteractionImpl.cpp @@ -50,10 +50,7 @@ namespace AtomToolsFramework AzToolsFramework::ViewportInteraction::ProjectedViewportRay ViewportInteractionImpl::ViewportScreenToWorldRay( const AzFramework::ScreenPoint& screenPosition) { - const AzFramework::CameraState cameraState = GetCameraState(); - const AZ::Vector3 rayOrigin = AzFramework::ScreenToWorld(screenPosition, cameraState); - const AZ::Vector3 rayDirection = (rayOrigin - cameraState.m_position).GetNormalized(); - return AzToolsFramework::ViewportInteraction::ProjectedViewportRay{ rayOrigin, rayDirection }; + return AzToolsFramework::ViewportInteraction::ViewportScreenToWorldRay(GetCameraState(), screenPosition); } float ViewportInteractionImpl::DeviceScalingFactor() From 768a196b63c45b1d09fc2c43a6b1068ab22212f6 Mon Sep 17 00:00:00 2001 From: rgba16f <82187279+rgba16f@users.noreply.github.com> Date: Tue, 30 Nov 2021 10:11:26 -0600 Subject: [PATCH 21/47] Add a way to set the vsync_interval CVar from code (#5813) * Add a way to set the render vsync from code Signed-off-by: rgba16f <82187279+rgba16f@users.noreply.github.com> * Update change with PR feedback. Missing whitespace plus a comment on why the assignment is outside the value changed check Signed-off-by: rgba16f <82187279+rgba16f@users.noreply.github.com> --- .../AzCore/AzCore/Console/ConsoleDataWrapper.inl | 9 +++++++++ .../AzFramework/AzFramework/Windowing/NativeWindow.cpp | 7 +++++++ .../AzFramework/AzFramework/Windowing/NativeWindow.h | 1 + .../AzFramework/AzFramework/Windowing/WindowBus.h | 4 ++++ .../AzFramework/Tests/Mocks/MockWindowRequests.h | 1 + .../AtomToolsFramework/Viewport/RenderViewportWidget.h | 1 + .../Code/Source/Viewport/RenderViewportWidget.cpp | 7 +++++++ 7 files changed, 30 insertions(+) diff --git a/Code/Framework/AzCore/AzCore/Console/ConsoleDataWrapper.inl b/Code/Framework/AzCore/AzCore/Console/ConsoleDataWrapper.inl index 46774f23b2..b3a59d287d 100644 --- a/Code/Framework/AzCore/AzCore/Console/ConsoleDataWrapper.inl +++ b/Code/Framework/AzCore/AzCore/Console/ConsoleDataWrapper.inl @@ -32,7 +32,16 @@ namespace AZ template inline void ConsoleDataWrapper::operator =(const BASE_TYPE& rhs) { + const BASE_TYPE currentValue = this->m_value; + // Do the value assignment outside new value check. + // Client code can supply a type for m_value that overrides the operator= function and trigger side effects + // in the operator= function body. Doing the assignment outside the value change check avoids those side + // effects not being triggered because AzCore believes the value wouldn't change. this->m_value = rhs; + if (currentValue != rhs) + { + InvokeCallback(); + } } template diff --git a/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.cpp b/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.cpp index c89d12a8ae..bb3c5e4388 100644 --- a/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.cpp +++ b/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.cpp @@ -143,6 +143,13 @@ namespace AzFramework return vsync_interval; } + bool NativeWindow::SetSyncInterval(uint32_t newSyncInterval) + { + vsync_interval = newSyncInterval; + return true; + } + + /*static*/ bool NativeWindow::GetFullScreenStateOfDefaultWindow() { NativeWindowHandle defaultWindowHandle = nullptr; diff --git a/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.h b/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.h index 0eb699475f..9c844034cb 100644 --- a/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.h +++ b/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.h @@ -132,6 +132,7 @@ namespace AzFramework void ToggleFullScreenState() override; float GetDpiScaleFactor() const override; uint32_t GetSyncInterval() const override; + bool SetSyncInterval(uint32_t newSyncInterval) override; uint32_t GetDisplayRefreshRate() const override; //! Get the full screen state of the default window. diff --git a/Code/Framework/AzFramework/AzFramework/Windowing/WindowBus.h b/Code/Framework/AzFramework/AzFramework/Windowing/WindowBus.h index d3bd0ce82c..faae925580 100644 --- a/Code/Framework/AzFramework/AzFramework/Windowing/WindowBus.h +++ b/Code/Framework/AzFramework/AzFramework/Windowing/WindowBus.h @@ -78,6 +78,10 @@ namespace AzFramework //! Returns the sync interval which tells the drivers the number of v-blanks to synchronize with virtual uint32_t GetSyncInterval() const = 0; + //! Sets the sync interval which tells the drivers the number of v-blanks to synchronize with + //! Returns if the sync interval was succesfully set + virtual bool SetSyncInterval(uint32_t newSyncInterval) = 0; + //! Returns the refresh rate of the main display virtual uint32_t GetDisplayRefreshRate() const = 0; }; diff --git a/Code/Framework/AzFramework/Tests/Mocks/MockWindowRequests.h b/Code/Framework/AzFramework/Tests/Mocks/MockWindowRequests.h index 63f73d0b28..a166df19b4 100644 --- a/Code/Framework/AzFramework/Tests/Mocks/MockWindowRequests.h +++ b/Code/Framework/AzFramework/Tests/Mocks/MockWindowRequests.h @@ -36,6 +36,7 @@ namespace UnitTest MOCK_METHOD0(ToggleFullScreenState, void()); MOCK_CONST_METHOD0(GetDpiScaleFactor, float()); MOCK_CONST_METHOD0(GetSyncInterval, uint32_t()); + MOCK_METHOD1(SetSyncInterval, bool(uint32_t)); MOCK_CONST_METHOD0(GetDisplayRefreshRate, uint32_t()); }; } // namespace UnitTest diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h index 45838a5378..3393897936 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h @@ -116,6 +116,7 @@ namespace AtomToolsFramework void ToggleFullScreenState() override; float GetDpiScaleFactor() const override; uint32_t GetSyncInterval() const override; + bool SetSyncInterval(uint32_t newSyncInterval) override; uint32_t GetDisplayRefreshRate() const override; protected: diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp index 759f939382..f6efdc57b8 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp @@ -395,4 +395,11 @@ namespace AtomToolsFramework { return 1; } + + // Editor ignores requests to change the sync interval + bool RenderViewportWidget::SetSyncInterval(uint32_t /*ignored*/) + { + return false; + } + } //namespace AtomToolsFramework From 4dd9e94bc34c3108bad5b8203eebae8ec181b94a Mon Sep 17 00:00:00 2001 From: srikappa-amzn <82230713+srikappa-amzn@users.noreply.github.com> Date: Tue, 30 Nov 2021 21:50:25 +0530 Subject: [PATCH 22/47] Add tests for deleting an entity from the level and from another prefab (#5839) * Added tests for deleting entity under level and other prefabs Signed-off-by: srikappa-amzn <82230713+srikappa-amzn@users.noreply.github.com> * Added class comments and improved variable names Signed-off-by: srikappa-amzn <82230713+srikappa-amzn@users.noreply.github.com> * Called the reflect function of PrefabFocusHandler from PrefabSystemComponent Signed-off-by: srikappa-amzn <82230713+srikappa-amzn@users.noreply.github.com> * Added function comments and made an if statement to be one line Signed-off-by: srikappa-amzn <82230713+srikappa-amzn@users.noreply.github.com> --- .../editor_entity_utils.py | 11 ++++ .../Gem/PythonTests/Prefab/TestSuite_Main.py | 8 +++ .../DeleteEntity_UnderAnotherPrefab.py | 52 +++++++++++++++++++ .../DeleteEntity_UnderLevelPrefab.py | 37 +++++++++++++ .../Prefab/PrefabFocusHandler.cpp | 14 +++++ .../Prefab/PrefabFocusHandler.h | 8 +-- .../Prefab/PrefabFocusPublicInterface.h | 14 +++++ .../Prefab/PrefabSystemComponent.cpp | 1 + 8 files changed, 142 insertions(+), 3 deletions(-) create mode 100644 AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_entity/DeleteEntity_UnderAnotherPrefab.py create mode 100644 AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_entity/DeleteEntity_UnderLevelPrefab.py diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py index 59e454479c..309601b0ba 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py @@ -459,3 +459,14 @@ class EditorEntity: """ new_translation = convert_to_azvector3(new_translation) azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalTranslation", self.id, new_translation) + + # Use this only when prefab system is enabled as it will fail otherwise. + def focus_on_owning_prefab(self) -> None: + """ + Focuses on the owning prefab instance of the given entity. + :param entity: The entity used to fetch the owning prefab to focus on. + """ + + assert self.id.isValid(), "A valid entity id is required to focus on its owning prefab." + focus_prefab_result = azlmbr.prefab.PrefabFocusPublicRequestBus(bus.Broadcast, "FocusOnOwningPrefab", self.id) + assert focus_prefab_result.IsSuccess(), f"Prefab operation 'FocusOnOwningPrefab' failed. Error: {focus_prefab_result.GetError()}" diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/Prefab/TestSuite_Main.py index c1d4836342..6e1f94d358 100644 --- a/AutomatedTesting/Gem/PythonTests/Prefab/TestSuite_Main.py +++ b/AutomatedTesting/Gem/PythonTests/Prefab/TestSuite_Main.py @@ -61,3 +61,11 @@ class TestAutomation(TestAutomationBase): def test_CreatePrefab_UnderAnotherPrefab(self, request, workspace, editor, launcher_platform): from Prefab.tests.create_prefab import CreatePrefab_UnderAnotherPrefab as test_module self._run_prefab_test(request, workspace, editor, test_module, autotest_mode=False) + + def test_DeleteEntity_UnderAnotherPrefab(self, request, workspace, editor, launcher_platform): + from Prefab.tests.delete_entity import DeleteEntity_UnderAnotherPrefab as test_module + self._run_prefab_test(request, workspace, editor, test_module, autotest_mode=False) + + def test_DeleteEntity_UnderLevelPrefab(self, request, workspace, editor, launcher_platform): + from Prefab.tests.delete_entity import DeleteEntity_UnderLevelPrefab as test_module + self._run_prefab_test(request, workspace, editor, test_module, autotest_mode=False) diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_entity/DeleteEntity_UnderAnotherPrefab.py b/AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_entity/DeleteEntity_UnderAnotherPrefab.py new file mode 100644 index 0000000000..deaaaedf30 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_entity/DeleteEntity_UnderAnotherPrefab.py @@ -0,0 +1,52 @@ +""" +Copyright (c) Contributors to the Open 3D Engine Project. +For complete copyright and license terms please see the LICENSE at the root of this distribution. + +SPDX-License-Identifier: Apache-2.0 OR MIT +""" + +def DeleteEntity_UnderAnotherPrefab(): + """ + Test description: + - Creates an entity. + - Creates a prefab out of the above entity. + - Focuses on the created prefab and destroys the entity within. + Checks that the entity is correctly destroyed. + """ + + from editor_python_test_tools.editor_entity_utils import EditorEntity + from editor_python_test_tools.prefab_utils import Prefab + + import Prefab.tests.PrefabTestUtils as prefab_test_utils + + prefab_test_utils.open_base_tests_level() + + PREFAB_FILE_NAME = 'some_prefab' + + # Creates a new entity at the root level + entity = EditorEntity.create_editor_entity() + assert entity.id.IsValid(), "Couldn't create entity." + + # Asserts if prefab creation doesn't succeed + child_prefab, child_instance = Prefab.create_prefab([entity], PREFAB_FILE_NAME) + child_entity_ids_inside_prefab = child_instance.get_direct_child_entities() + assert len( + child_entity_ids_inside_prefab) == 1, f"{len(child_entity_ids_inside_prefab)} entities found inside prefab" \ + f" when there should have been just 1 entity" + + child_entity_inside_prefab = child_entity_ids_inside_prefab[0] + child_entity_inside_prefab.focus_on_owning_prefab() + + child_entity_inside_prefab.delete() + + # Wait till prefab propagation finishes before validating entity deletion. + azlmbr.legacy.general.idle_wait_frames(1) + + child_entity_ids_inside_prefab = child_instance.get_direct_child_entities() + assert len( + child_entity_ids_inside_prefab) == 0, f"{len(child_entity_ids_inside_prefab)} entities found inside prefab" \ + f" when there should have been 0 entities" + +if __name__ == "__main__": + from editor_python_test_tools.utils import Report + Report.start_test(DeleteEntity_UnderAnotherPrefab) diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_entity/DeleteEntity_UnderLevelPrefab.py b/AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_entity/DeleteEntity_UnderLevelPrefab.py new file mode 100644 index 0000000000..807427718c --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_entity/DeleteEntity_UnderLevelPrefab.py @@ -0,0 +1,37 @@ +""" +Copyright (c) Contributors to the Open 3D Engine Project. +For complete copyright and license terms please see the LICENSE at the root of this distribution. + +SPDX-License-Identifier: Apache-2.0 OR MIT +""" + +def DeleteEntity_UnderLevelPrefab(): + """ + Test description: + - Creates an entity. + - Destroys the created entity. + Checks that the entity is correctly destroyed. + """ + + from editor_python_test_tools.editor_entity_utils import EditorEntity + import Prefab.tests.PrefabTestUtils as prefab_test_utils + + prefab_test_utils.open_base_tests_level() + + # Creates a new Entity at the root level + # Asserts if creation didn't succeed + entity = EditorEntity.create_editor_entity_at((100.0, 100.0, 100.0), name = "TestEntity") + assert entity.id.IsValid(), "Couldn't create entity" + + level_container_entity = EditorEntity(entity.get_parent_id()) + entity.delete() + + # Wait till prefab propagation finishes before validating entity deletion. + azlmbr.legacy.general.idle_wait_frames(1) + level_container_child_entities_count = len(level_container_entity.get_children_ids()) + assert level_container_child_entities_count == 0, f"The level still has {level_container_child_entities_count}" \ + f" children when it should have 0." + +if __name__ == "__main__": + from editor_python_test_tools.utils import Report + Report.start_test(DeleteEntity_UnderLevelPrefab) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.cpp index f20c11a1d8..2ab68bfc10 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.cpp @@ -34,10 +34,12 @@ namespace AzToolsFramework::Prefab PrefabPublicNotificationBus::Handler::BusConnect(); AZ::Interface::Register(this); AZ::Interface::Register(this); + PrefabFocusPublicRequestBus::Handler::BusConnect(); } PrefabFocusHandler::~PrefabFocusHandler() { + PrefabFocusPublicRequestBus::Handler::BusDisconnect(); AZ::Interface::Unregister(this); AZ::Interface::Unregister(this); PrefabPublicNotificationBus::Handler::BusDisconnect(); @@ -45,6 +47,18 @@ namespace AzToolsFramework::Prefab EditorEntityInfoNotificationBus::Handler::BusDisconnect(); } + void PrefabFocusHandler::Reflect(AZ::ReflectContext* context) + { + if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context); behaviorContext) + { + behaviorContext->EBus("PrefabFocusPublicRequestBus") + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation) + ->Attribute(AZ::Script::Attributes::Category, "Prefab") + ->Attribute(AZ::Script::Attributes::Module, "prefab") + ->Event("FocusOnOwningPrefab", &PrefabFocusPublicInterface::FocusOnOwningPrefab); + } + } + void PrefabFocusHandler::InitializeEditorInterfaces() { m_containerEntityInterface = AZ::Interface::Get(); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.h index 2e23059a01..b02106d69d 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.h @@ -30,8 +30,8 @@ namespace AzToolsFramework::Prefab //! Handles Prefab Focus mode, determining which prefab file entity changes will target. class PrefabFocusHandler final - : private PrefabFocusInterface - , private PrefabFocusPublicInterface + : public PrefabFocusPublicRequestBus::Handler + , private PrefabFocusInterface , private PrefabPublicNotificationBus::Handler , private EditorEntityContextNotificationBus::Handler , private EditorEntityInfoNotificationBus::Handler @@ -42,13 +42,15 @@ namespace AzToolsFramework::Prefab PrefabFocusHandler(); ~PrefabFocusHandler(); + static void Reflect(AZ::ReflectContext* context); + // PrefabFocusInterface overrides ... void InitializeEditorInterfaces() override; PrefabFocusOperationResult FocusOnPrefabInstanceOwningEntityId(AZ::EntityId entityId) override; TemplateId GetFocusedPrefabTemplateId(AzFramework::EntityContextId entityContextId) const override; InstanceOptionalReference GetFocusedPrefabInstance(AzFramework::EntityContextId entityContextId) const override; - // PrefabFocusPublicInterface overrides ... + // PrefabFocusPublicInterface and PrefabFocusPublicRequestBus overrides ... PrefabFocusOperationResult FocusOnOwningPrefab(AZ::EntityId entityId) override; PrefabFocusOperationResult FocusOnParentOfFocusedPrefab(AzFramework::EntityContextId entityContextId) override; PrefabFocusOperationResult FocusOnPathIndex(AzFramework::EntityContextId entityContextId, int index) override; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusPublicInterface.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusPublicInterface.h index 2fc9ef6b9a..2c0e95f1cc 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusPublicInterface.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusPublicInterface.h @@ -58,4 +58,18 @@ namespace AzToolsFramework::Prefab virtual const int GetPrefabFocusPathLength(AzFramework::EntityContextId entityContextId) const = 0; }; + /** + * The primary purpose of this bus is to facilitate writing automated tests for prefab focus mode. + * If you would like to integrate prefabs focus mode into your system, please call PrefabFocusPublicInterface + * for better performance. + */ + class PrefabFocusPublicRequests + : public AZ::EBusTraits + { + public: + static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; + }; + + using PrefabFocusPublicRequestBus = AZ::EBus; + } // namespace AzToolsFramework::Prefab diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp index 62d7a6ac1d..ed16606413 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp @@ -60,6 +60,7 @@ namespace AzToolsFramework AzToolsFramework::Prefab::PrefabConversionUtils::PrefabCatchmentProcessor::Reflect(context); AzToolsFramework::Prefab::PrefabConversionUtils::EditorInfoRemover::Reflect(context); PrefabPublicRequestHandler::Reflect(context); + PrefabFocusHandler::Reflect(context); PrefabLoader::Reflect(context); PrefabSystemScriptingHandler::Reflect(context); From 12efc846325422137e3dce89b396842912a0f6b6 Mon Sep 17 00:00:00 2001 From: Scott Romero <24445312+AMZN-ScottR@users.noreply.github.com> Date: Tue, 30 Nov 2021 08:27:27 -0800 Subject: [PATCH 23/47] [development] minor Profiler gem fixes (#5473) Fixed incorrect frame boundary guess when loading a profile capture Added some missing default initializers Removed implicit dependency on Atom timing marker constants Fixed issue with small visualizer viewport bounds when loading a saved capture Signed-off-by: AMZN-ScottR 24445312+AMZN-ScottR@users.noreply.github.com --- .../Statistics/StatisticalProfilerProxy.h | 16 ++++++++ .../AzCore/Statistics/StatisticsManager.h | 14 ++++++- Gems/Profiler/Code/Source/CpuProfilerImpl.h | 2 +- .../Profiler/Code/Source/ImGuiCpuProfiler.cpp | 41 +++++++++++-------- Gems/Profiler/Code/Source/ImGuiCpuProfiler.h | 7 ++-- 5 files changed, 57 insertions(+), 23 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Statistics/StatisticalProfilerProxy.h b/Code/Framework/AzCore/AzCore/Statistics/StatisticalProfilerProxy.h index 278b2ecc98..7fae0ca354 100644 --- a/Code/Framework/AzCore/AzCore/Statistics/StatisticalProfilerProxy.h +++ b/Code/Framework/AzCore/AzCore/Statistics/StatisticalProfilerProxy.h @@ -157,6 +157,22 @@ namespace AZ::Statistics } } + void GetAllStatistics(AZStd::vector& stats) + { + for (auto& iter : m_profilers) + { + iter.second.m_profiler.GetStatsManager().GetAllStatistics(stats); + } + } + + void GetAllStatisticsOfUnits(AZStd::vector& stats, const char* units) + { + for (auto& iter : m_profilers) + { + iter.second.m_profiler.GetStatsManager().GetAllStatisticsOfUnits(stats, units); + } + } + private: struct ProfilerInfo { diff --git a/Code/Framework/AzCore/AzCore/Statistics/StatisticsManager.h b/Code/Framework/AzCore/AzCore/Statistics/StatisticsManager.h index 5984701f4e..dc97de40c1 100644 --- a/Code/Framework/AzCore/AzCore/Statistics/StatisticsManager.h +++ b/Code/Framework/AzCore/AzCore/Statistics/StatisticsManager.h @@ -56,13 +56,25 @@ namespace AZ void GetAllStatistics(AZStd::vector& vector) { - for (auto const& it : m_statistics) + for (const auto& it : m_statistics) { NamedRunningStatistic* stat = it.second; vector.push_back(stat); } } + void GetAllStatisticsOfUnits(AZStd::vector& vector, const char* units) + { + for (const auto& it : m_statistics) + { + NamedRunningStatistic* stat = it.second; + if (stat->GetUnits() == units) + { + vector.push_back(stat); + } + } + } + //! Helper method to apply units to statistics with empty units string. AZ::u32 ApplyUnits(const AZStd::string& units) { diff --git a/Gems/Profiler/Code/Source/CpuProfilerImpl.h b/Gems/Profiler/Code/Source/CpuProfilerImpl.h index 6611fbd1e5..c97e45e69c 100644 --- a/Gems/Profiler/Code/Source/CpuProfilerImpl.h +++ b/Gems/Profiler/Code/Source/CpuProfilerImpl.h @@ -150,7 +150,7 @@ namespace Profiler AZStd::mutex m_continuousCaptureEndingMutex; - AZStd::atomic_bool m_continuousCaptureInProgress; + AZStd::atomic_bool m_continuousCaptureInProgress = false; // Stores multiple frames of profiling data, size is controlled by MaxFramesToSave. Flushed when EndContinuousCapture is called. // Ring buffer so that we can have fast append of new data + removal of old profiling data with good cache locality. diff --git a/Gems/Profiler/Code/Source/ImGuiCpuProfiler.cpp b/Gems/Profiler/Code/Source/ImGuiCpuProfiler.cpp index 26c2f9f974..1cb13fe4ac 100644 --- a/Gems/Profiler/Code/Source/ImGuiCpuProfiler.cpp +++ b/Gems/Profiler/Code/Source/ImGuiCpuProfiler.cpp @@ -23,9 +23,13 @@ #include #include #include +#include namespace Profiler { + constexpr AZStd::sys_time_t ProfilerViewEdgePadding = 5000; + constexpr size_t InitialCpuTimingStatsAllocation = 8; + namespace CpuProfilerImGuiHelper { float TicksToMs(double ticks) @@ -435,6 +439,11 @@ namespace Profiler m_tableData.clear(); m_groupRegionMap.clear(); + // Since we don't serialize the frame boundaries, we will use "Component application simulation tick" from + // ComponentApplication::Tick as a heuristic. + static const AZ::Name::Hash frameBoundaryHash = AZ::Name("Component application simulation tick").GetHash(); + + AZStd::sys_time_t frameTime = 0; for (const auto& entry : deserializedData) { const auto [groupNameItr, wasGroupNameInserted] = m_deserializedStringPool.emplace(entry.m_groupName.GetCStr()); @@ -445,10 +454,12 @@ namespace Profiler const CachedTimeRegion newRegion(*groupRegionNameItr, entry.m_stackDepth, entry.m_startTick, entry.m_endTick); m_savedData[entry.m_threadId].push_back(newRegion); - // Since we don't serialize the frame boundaries, we need to use the RPI's OnSystemTick event as a heuristic. - const static AZ::Name frameBoundaryName = AZ::Name("RPISystem: OnSystemTick"); - if (entry.m_regionName == frameBoundaryName) + if (entry.m_regionName.GetHash() == frameBoundaryHash) { + if (!m_frameEndTicks.empty()) + { + frameTime = entry.m_endTick - m_frameEndTicks.back(); + } m_frameEndTicks.push_back(entry.m_endTick); } @@ -462,9 +473,9 @@ namespace Profiler m_groupRegionMap[*groupNameItr][*regionNameItr].RecordRegion(newRegion, entry.m_threadId); } - // Update viewport bounds with some added UX fudge factor - m_viewportStartTick = deserializedData.back().m_startTick - 1000; - m_viewportEndTick = deserializedData.back().m_endTick + 1000; + // Update viewport bounds to the estimated final frame time with some padding + m_viewportStartTick = m_frameEndTicks.back() - frameTime - ProfilerViewEdgePadding; + m_viewportEndTick = m_frameEndTicks.back() + ProfilerViewEdgePadding; // Invariant: each vector in m_savedData must be sorted so that we can efficiently cull region data. for (auto& [threadId, singleThreadData] : m_savedData) @@ -642,21 +653,13 @@ namespace Profiler m_cpuTimingStatisticsWhenPause.clear(); if (auto statsProfiler = AZ::Interface::Get(); statsProfiler) { - auto& rhiMetrics = statsProfiler->GetProfiler(AZ_CRC_CE("RHI")); - - const NamedRunningStatistic* frameTimeMetric = rhiMetrics.GetStatistic(AZ_CRC_CE("Frame to Frame Time")); - if (frameTimeMetric) - { - m_frameToFrameTime = static_cast(frameTimeMetric->GetMostRecentSample()); - } - AZStd::vector statistics; - rhiMetrics.GetStatsManager().GetAllStatistics(statistics); + statistics.reserve(InitialCpuTimingStatsAllocation); + statsProfiler->GetAllStatisticsOfUnits(statistics, "clocks"); for (NamedRunningStatistic* stat : statistics) { m_cpuTimingStatisticsWhenPause.push_back({ stat->GetName(), stat->GetMostRecentSample() }); - stat->Reset(); } } } @@ -731,7 +734,11 @@ namespace Profiler void ImGuiCpuProfiler::CullFrameData() { - const AZStd::sys_time_t deleteBeforeTick = AZStd::GetTimeNowTicks() - m_frameToFrameTime * m_framesToCollect; + const AZ::TimeUs delta = AZ::GetRealTickDeltaTimeUs(); + const float deltaTimeInSeconds = AZ::TimeUsToSeconds(delta); + const AZStd::sys_time_t frameToFrameTime = static_cast(deltaTimeInSeconds * AZStd::GetTimeTicksPerSecond()); + + const AZStd::sys_time_t deleteBeforeTick = AZStd::GetTimeNowTicks() - frameToFrameTime * m_framesToCollect; // Remove old frame boundary data auto firstBoundaryToKeepItr = AZStd::upper_bound(m_frameEndTicks.begin(), m_frameEndTicks.end(), deleteBeforeTick); diff --git a/Gems/Profiler/Code/Source/ImGuiCpuProfiler.h b/Gems/Profiler/Code/Source/ImGuiCpuProfiler.h index 2e01b8fd6b..d5d27632f8 100644 --- a/Gems/Profiler/Code/Source/ImGuiCpuProfiler.h +++ b/Gems/Profiler/Code/Source/ImGuiCpuProfiler.h @@ -89,7 +89,7 @@ namespace Profiler struct CpuTimingEntry { const AZStd::string& m_name; - double m_executeDuration; + double m_executeDuration = 0; }; ImGuiCpuProfiler() = default; @@ -175,8 +175,8 @@ namespace Profiler AZ::u64 m_savedRegionCount = 0; // Viewport tick bounds, these are used to convert tick space -> screen space and cull so we only draw onscreen objects - AZStd::sys_time_t m_viewportStartTick; - AZStd::sys_time_t m_viewportEndTick; + AZStd::sys_time_t m_viewportStartTick = 0; + AZStd::sys_time_t m_viewportEndTick = 0; // Map to store each thread's TimeRegions, individual vectors are sorted by start tick // note: we use size_t as a proxy for thread_id because native_thread_id_type differs differs from @@ -215,7 +215,6 @@ namespace Profiler // Last captured CPU timing statistics AZStd::vector m_cpuTimingStatisticsWhenPause; - AZStd::sys_time_t m_frameToFrameTime{}; AZ::IO::FixedMaxPath m_lastCapturedFilePath; From 6cb53891edcac615074ce495762e2a77957dd385 Mon Sep 17 00:00:00 2001 From: Roman <69218254+amzn-rhhong@users.noreply.github.com> Date: Tue, 30 Nov 2021 08:32:11 -0800 Subject: [PATCH 24/47] Store camera settings (#6013) * load and save camera options Signed-off-by: rhhong * CR feedback Signed-off-by: rhhong --- .../Tools/EMStudio/AnimViewportToolBar.cpp | 28 +++++++++++++++++++ .../Code/Tools/EMStudio/AnimViewportToolBar.h | 4 ++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportToolBar.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportToolBar.cpp index 7bb8d49418..0cf6dd70b3 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportToolBar.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportToolBar.cpp @@ -8,8 +8,10 @@ #include #include +#include #include #include +#include #include #include @@ -109,6 +111,13 @@ namespace EMStudio cameraButton->setIcon(QIcon(":/EMotionFXAtom/Camera_category.svg")); addWidget(cameraButton); } + + LoadSettings(); + } + + AnimViewportToolBar::~AnimViewportToolBar() + { + SaveSettings(); } void AnimViewportToolBar::CreateViewOptionEntry( @@ -144,4 +153,23 @@ namespace EMStudio } } } + + void AnimViewportToolBar::LoadSettings() + { + AZStd::string renderFlagsFilename(EMStudioManager::GetInstance()->GetAppDataFolder()); + renderFlagsFilename += "AnimViewportRenderFlags.cfg"; + QSettings settings(renderFlagsFilename.c_str(), QSettings::IniFormat, this); + + const bool isChecked = settings.value("CameraFollowUp", false).toBool(); + m_followCharacterAction->setChecked(isChecked); + } + + void AnimViewportToolBar::SaveSettings() + { + AZStd::string renderFlagsFilename(EMStudioManager::GetInstance()->GetAppDataFolder()); + renderFlagsFilename += "AnimViewportRenderFlags.cfg"; + QSettings settings(renderFlagsFilename.c_str(), QSettings::IniFormat, this); + + settings.setValue("CameraFollowUp", m_followCharacterAction->isChecked()); + } } // namespace EMStudio diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportToolBar.h b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportToolBar.h index 1443c54ee9..98b07f07dd 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportToolBar.h +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportToolBar.h @@ -22,9 +22,11 @@ namespace EMStudio { public: AnimViewportToolBar(QWidget* parent = nullptr); - ~AnimViewportToolBar() = default; + ~AnimViewportToolBar(); void SetRenderFlags(EMotionFX::ActorRenderFlagBitset renderFlags); + void LoadSettings(); + void SaveSettings(); private: void CreateViewOptionEntry( From aab6e33d3032531b18acd68407c627c34a66057f Mon Sep 17 00:00:00 2001 From: lsemp3d <58790905+lsemp3d@users.noreply.github.com> Date: Tue, 30 Nov 2021 08:41:27 -0800 Subject: [PATCH 25/47] Non unity build fix Signed-off-by: lsemp3d <58790905+lsemp3d@users.noreply.github.com> --- Gems/ScriptCanvas/Code/Editor/Nodes/NodeUtils.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Gems/ScriptCanvas/Code/Editor/Nodes/NodeUtils.cpp b/Gems/ScriptCanvas/Code/Editor/Nodes/NodeUtils.cpp index 262ea8c061..7ebbd4bc6d 100644 --- a/Gems/ScriptCanvas/Code/Editor/Nodes/NodeUtils.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Nodes/NodeUtils.cpp @@ -12,6 +12,7 @@ #include #include +#include #include namespace ScriptCanvasEditor::Nodes From 3a1e6744fbcd69d16a7314a51248f540b0efa3ad Mon Sep 17 00:00:00 2001 From: Steve Pham <82231385+spham-amzn@users.noreply.github.com> Date: Tue, 30 Nov 2021 08:47:21 -0800 Subject: [PATCH 26/47] Save Data linux support (#6014) Implementation of SaveData for Linux Signed-off-by: Steve Pham <82231385+spham-amzn@users.noreply.github.com> --- .../Platform/Linux/AzTest_Traits_Linux.h | 2 - .../Linux/SaveData_SystemComponent_Linux.cpp | 173 ++++++++++++++++++ .../Platform/Linux/platform_linux_files.cmake | 2 +- 3 files changed, 174 insertions(+), 3 deletions(-) create mode 100644 Gems/SaveData/Code/Source/Platform/Linux/SaveData_SystemComponent_Linux.cpp diff --git a/Code/Framework/AzTest/AzTest/Platform/Linux/AzTest_Traits_Linux.h b/Code/Framework/AzTest/AzTest/Platform/Linux/AzTest_Traits_Linux.h index d9b48b7835..755888e1d9 100644 --- a/Code/Framework/AzTest/AzTest/Platform/Linux/AzTest_Traits_Linux.h +++ b/Code/Framework/AzTest/AzTest/Platform/Linux/AzTest_Traits_Linux.h @@ -13,8 +13,6 @@ #define AZ_TRAIT_UNIT_TEST_ENTITY_ID_GEN_TEST_COUNT 10000 #define AZ_TRAIT_UNIT_TEST_DILLER_TRIGGER_EVENT_COUNT 100000 -#define AZ_TRAIT_DISABLE_ALL_SAVE_DATA_TESTS true - #define AZ_TRAIT_DISABLE_FAILED_AP_CONNECTION_TESTS true #define AZ_TRAIT_DISABLE_FAILED_ASSET_LOAD_TESTS true diff --git a/Gems/SaveData/Code/Source/Platform/Linux/SaveData_SystemComponent_Linux.cpp b/Gems/SaveData/Code/Source/Platform/Linux/SaveData_SystemComponent_Linux.cpp new file mode 100644 index 0000000000..caa9e9bf54 --- /dev/null +++ b/Gems/SaveData/Code/Source/Platform/Linux/SaveData_SystemComponent_Linux.cpp @@ -0,0 +1,173 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +//////////////////////////////////////////////////////////////////////////////////////////////////// +namespace SaveData +{ + //////////////////////////////////////////////////////////////////////////////////////////////// + //! Platform specific implementation for the save data system component on Linux + class SaveDataSystemComponentLinux : public SaveDataSystemComponent::Implementation + { + public: + //////////////////////////////////////////////////////////////////////////////////////////// + static constexpr const char* DefaultSaveDataDirectoryName = "SaveData"; + + //////////////////////////////////////////////////////////////////////////////////////////// + // Allocator + AZ_CLASS_ALLOCATOR(SaveDataSystemComponentLinux, AZ::SystemAllocator, 0); + + //////////////////////////////////////////////////////////////////////////////////////////// + //! Constructor + //! \param[in] saveDataSystemComponent Reference to the parent being implemented + SaveDataSystemComponentLinux(SaveDataSystemComponent& saveDataSystemComponent); + + //////////////////////////////////////////////////////////////////////////////////////////// + //! Destructor + ~SaveDataSystemComponentLinux() override; + + protected: + //////////////////////////////////////////////////////////////////////////////////////////// + //! \ref SaveData::SaveDataSystemComponent::Implementation::SaveDataBuffer + void SaveDataBuffer(const SaveDataRequests::SaveDataBufferParams& saveDataBufferParams) override; + + //////////////////////////////////////////////////////////////////////////////////////////// + //! \ref SaveData::SaveDataSystemComponent::Implementation::LoadDataBuffer + void LoadDataBuffer(const SaveDataRequests::LoadDataBufferParams& loadDataBufferParams) override; + + //////////////////////////////////////////////////////////////////////////////////////////// + //! \ref SaveData::SaveDataSystemComponent::Implementation::SetSaveDataDirectoryPath + void SetSaveDataDirectoryPath(const char* saveDataDirectoryPath) override; + + private: + //////////////////////////////////////////////////////////////////////////////////////////// + //! Convenience function to construct the full save data file path. + //! \param[in] dataBufferName The name of the save data buffer. + //! \param[in] localUserId The local user id the save data buffer is associated with. + AZ::IO::Path GetSaveDataFilePath(const AZStd::string& dataBufferName, + AzFramework::LocalUserId localUserId); + + //////////////////////////////////////////////////////////////////////////////////////////// + //! The absolute path to the application's save data dircetory. + AZ::IO::Path m_saveDataDirectoryPathAbsolute; + }; + + //////////////////////////////////////////////////////////////////////////////////////////////// + AZ::IO::Path GetDefaultLinuxUserSaveDataPath() + { + // First priority for the home directory is the 'HOME' environment variable + const char* homeDir = getenv("HOME"); + if (homeDir == nullptr) + { + // If the 'HOME' environment variable is not set, then retrieve it from the 'getpwuid' + // system call + auto uid = getuid(); + auto pwuid = getpwuid(uid); + homeDir = pwuid->pw_dir; + } + + AZ_Assert(homeDir, "Unable to determine home directory for current Linux user"); + if (homeDir == nullptr) + { + homeDir = "/tmp"; + } + + AZ::IO::Path homePath {homeDir}; + + // $HOME/.local/share is the standard directory where user data is stored on Ubuntu + return homePath / ".local" / "share"; + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + AZStd::string GetExecutableName() + { + char moduleFileName[AZ_MAX_PATH_LEN]; + AZ::Utils::GetExecutablePath(moduleFileName, AZ_MAX_PATH_LEN); + + AZ::IO::Path executableFullPath {moduleFileName}; + AZStd::string moduleFileNameString {executableFullPath.Filename().Native()}; + return moduleFileNameString; + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + SaveDataSystemComponent::Implementation* SaveDataSystemComponent::Implementation::Create(SaveDataSystemComponent& saveDataSystemComponent) + { + return aznew SaveDataSystemComponentLinux(saveDataSystemComponent); + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + SaveDataSystemComponentLinux::SaveDataSystemComponentLinux(SaveDataSystemComponent& saveDataSystemComponent) + : SaveDataSystemComponent::Implementation(saveDataSystemComponent) + , m_saveDataDirectoryPathAbsolute(GetDefaultLinuxUserSaveDataPath() / + GetExecutableName().c_str() / + DefaultSaveDataDirectoryName) + { + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + SaveDataSystemComponentLinux::~SaveDataSystemComponentLinux() + { + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + void SaveDataSystemComponentLinux::SaveDataBuffer(const SaveDataRequests::SaveDataBufferParams& saveDataBufferParams) + { + const AZStd::string absoluteFilePath = GetSaveDataFilePath(saveDataBufferParams.dataBufferName, + saveDataBufferParams.localUserId).c_str(); + SaveDataBufferToFileSystem(saveDataBufferParams, absoluteFilePath); + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + void SaveDataSystemComponentLinux::LoadDataBuffer(const SaveDataRequests::LoadDataBufferParams& loadDataBufferParams) + { + const AZStd::string absoluteFilePath = GetSaveDataFilePath(loadDataBufferParams.dataBufferName, + loadDataBufferParams.localUserId).c_str(); + LoadDataBufferFromFileSystem(loadDataBufferParams, absoluteFilePath); + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + void SaveDataSystemComponentLinux::SetSaveDataDirectoryPath(const char* saveDataDirectoryPath) + { + AZ::IO::Path saveDataDirectoryBasicPath { saveDataDirectoryPath }; + + if (saveDataDirectoryBasicPath.IsAbsolute()) + { + m_saveDataDirectoryPathAbsolute = saveDataDirectoryBasicPath; + } + else + { + m_saveDataDirectoryPathAbsolute = GetDefaultLinuxUserSaveDataPath() / saveDataDirectoryBasicPath; + } + + AZ_Assert(!m_saveDataDirectoryPathAbsolute.empty(), "Cannot set an empty save data directory path."); + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + AZ::IO::Path SaveDataSystemComponentLinux::GetSaveDataFilePath(const AZStd::string& dataBufferName, + AzFramework::LocalUserId localUserId) + { + AZ::IO::Path saveDataFilePath = m_saveDataDirectoryPathAbsolute; + if (localUserId != AzFramework::LocalUserIdNone) + { + saveDataFilePath /= AZStd::string::format("User_%u", localUserId); + } + saveDataFilePath /= dataBufferName; + return saveDataFilePath; + } +} // namespace SaveData diff --git a/Gems/SaveData/Code/Source/Platform/Linux/platform_linux_files.cmake b/Gems/SaveData/Code/Source/Platform/Linux/platform_linux_files.cmake index 2ef4de6b91..42209a111c 100644 --- a/Gems/SaveData/Code/Source/Platform/Linux/platform_linux_files.cmake +++ b/Gems/SaveData/Code/Source/Platform/Linux/platform_linux_files.cmake @@ -7,7 +7,7 @@ # set(FILES - ../Common/Unimplemented/SaveData_SystemComponent_Unimplemented.cpp + SaveData_SystemComponent_Linux.cpp SaveData_Traits_Platform.h SaveData_Traits_Linux.h ) From 1f13a5bbf244517ceebafd476e80bac75ed3b625 Mon Sep 17 00:00:00 2001 From: Chris Galvan Date: Tue, 30 Nov 2021 10:48:39 -0600 Subject: [PATCH 27/47] Removed include/LmbrCentral/Rendering/RenderNodeBus.h that was red-coded. Signed-off-by: Chris Galvan --- Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake | 1 - 1 file changed, 1 deletion(-) diff --git a/Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake b/Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake index 67f526cf21..a3bc87a620 100644 --- a/Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake +++ b/Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake @@ -36,7 +36,6 @@ set(FILES include/LmbrCentral/Rendering/MaterialHandle.h include/LmbrCentral/Rendering/MeshAsset.h include/LmbrCentral/Rendering/MeshModificationBus.h - include/LmbrCentral/Rendering/RenderNodeBus.h include/LmbrCentral/Rendering/GiRegistrationBus.h include/LmbrCentral/Rendering/RenderBoundsBus.h include/LmbrCentral/Scripting/EditorTagComponentBus.h From dc3c1266624dab7871f7c09b9118139e659c4a3a Mon Sep 17 00:00:00 2001 From: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> Date: Tue, 30 Nov 2021 11:30:00 -0600 Subject: [PATCH 28/47] GetSurfacePoint - expose to BehaviorContext (#6017) * Fix GetSurfacePoint exposure to BehaviorContext. The previous way of exposing it made it unusable from ScriptCanvas, since the public API uses an "out" parameter. This introduces a private variation of the API that returns the value instead, so that it functions correctly in Script Canvas. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Added descriptive comment. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Addressed PR feedback. Fixed comment spacing and renamed private methods to remove the need for the typecast. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> --- .../Terrain/TerrainDataRequestBus.cpp | 5 ++- .../Terrain/TerrainDataRequestBus.h | 41 ++++++++++++++----- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.cpp b/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.cpp index 561408db20..f803e73462 100644 --- a/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.cpp +++ b/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.cpp @@ -26,10 +26,11 @@ namespace AzFramework::Terrain ->Event("GetSurfaceWeights", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetSurfaceWeights) ->Event("GetSurfaceWeightsFromVector2", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetSurfaceWeightsFromVector2) + ->Event("GetIsHole", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetIsHole) ->Event("GetIsHoleFromFloats", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetIsHoleFromFloats) - ->Event("GetSurfacePoint", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetSurfacePoint) + ->Event("GetSurfacePoint", &AzFramework::Terrain::TerrainDataRequestBus::Events::BehaviorContextGetSurfacePoint) ->Event("GetSurfacePointFromVector2", - &AzFramework::Terrain::TerrainDataRequestBus::Events::GetSurfacePointFromVector2) + &AzFramework::Terrain::TerrainDataRequestBus::Events::BehaviorContextGetSurfacePointFromVector2) ->Event("GetTerrainAabb", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetTerrainAabb) ->Event("GetTerrainHeightQueryResolution", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetTerrainHeightQueryResolution) diff --git a/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h b/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h index 30a2f8e044..4c73ddd770 100644 --- a/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h +++ b/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h @@ -52,8 +52,8 @@ namespace AzFramework virtual void SetTerrainAabb(const AZ::Aabb& worldBounds) = 0; //! Returns terrains height in meters at location x,y. - //! @terrainExistsPtr: Can be nullptr. If != nullptr then, if there's no terrain at location x,y or location x,y is inside a terrain HOLE then *terrainExistsPtr will become false, - //! otherwise *terrainExistsPtr will become true. + //! @terrainExistsPtr: Can be nullptr. If != nullptr then, if there's no terrain at location x,y or location x,y is inside + //! a terrain HOLE then *terrainExistsPtr will become false, otherwise *terrainExistsPtr will become true. virtual float GetHeight(const AZ::Vector3& position, Sampler sampler = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0; virtual float GetHeightFromVector2( const AZ::Vector2& position, Sampler sampler = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0; @@ -68,8 +68,7 @@ namespace AzFramework // Given an XY coordinate, return the surface normal. //! @terrainExists: Can be nullptr. If != nullptr then, if there's no terrain at location x,y or location x,y is inside a - //! terrain HOLE then *terrainExistsPtr will be set to false, - //! otherwise *terrainExistsPtr will be set to true. + //! terrain HOLE then *terrainExistsPtr will be set to false, otherwise *terrainExistsPtr will be set to true. virtual AZ::Vector3 GetNormal( const AZ::Vector3& position, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0; virtual AZ::Vector3 GetNormalFromVector2( @@ -78,8 +77,8 @@ namespace AzFramework float x, float y, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0; //! Given an XY coordinate, return the max surface type and weight. - //! @terrainExists: Can be nullptr. If != nullptr then, if there's no terrain at location x,y or location x,y is inside a terrain HOLE then *terrainExistsPtr will be set to false, - //! otherwise *terrainExistsPtr will be set to true. + //! @terrainExists: Can be nullptr. If != nullptr then, if there's no terrain at location x,y or location x,y is inside + //! a terrain HOLE then *terrainExistsPtr will be set to false, otherwise *terrainExistsPtr will be set to true. virtual SurfaceData::SurfaceTagWeight GetMaxSurfaceWeight( const AZ::Vector3& position, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0; virtual SurfaceData::SurfaceTagWeight GetMaxSurfaceWeightFromVector2( @@ -87,8 +86,8 @@ namespace AzFramework virtual SurfaceData::SurfaceTagWeight GetMaxSurfaceWeightFromFloats( float x, float y, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0; - //! Given an XY coordinate, return the set of surface types and weights. The Vector3 input position version is defined to ignore - //! the input Z value. + //! Given an XY coordinate, return the set of surface types and weights. The Vector3 input position version is defined to + //! ignore the input Z value. virtual void GetSurfaceWeights( const AZ::Vector3& inPosition, SurfaceData::SurfaceTagWeightList& outSurfaceWeights, @@ -106,13 +105,14 @@ namespace AzFramework Sampler sampleFilter = Sampler::DEFAULT, bool* terrainExistsPtr = nullptr) const = 0; - //! Convenience function for low level systems that can't do a reverse lookup from Crc to string. Everyone else should use GetMaxSurfaceWeight or GetMaxSurfaceWeightFromFloats. + //! Convenience function for low level systems that can't do a reverse lookup from Crc to string. Everyone else should use + //! GetMaxSurfaceWeight or GetMaxSurfaceWeightFromFloats. //! Not available in the behavior context. //! Returns nullptr if the position is inside a hole or outside of the terrain boundaries. virtual const char* GetMaxSurfaceName( const AZ::Vector3& position, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0; - //! Given an XY coordinate, return all terrain information at that location. The Vector3 input position version is defined + //! Given an XY coordinate, return all terrain information at that location. The Vector3 input position version is defined //! to ignore the input Z value. virtual void GetSurfacePoint( const AZ::Vector3& inPosition, @@ -130,6 +130,27 @@ namespace AzFramework SurfaceData::SurfacePoint& outSurfacePoint, Sampler sampleFilter = Sampler::DEFAULT, bool* terrainExistsPtr = nullptr) const = 0; + + private: + // Private variations of the GetSurfacePoint API exposed to BehaviorContext that returns a value instead of + // using an "out" parameter. The "out" parameter is useful for reusing memory allocated in SurfacePoint when + // using the public API, but can't easily be used from Script Canvas. + SurfaceData::SurfacePoint BehaviorContextGetSurfacePoint( + const AZ::Vector3& inPosition, + Sampler sampleFilter = Sampler::DEFAULT) const + { + SurfaceData::SurfacePoint result; + GetSurfacePoint(inPosition, result, sampleFilter); + return result; + } + SurfaceData::SurfacePoint BehaviorContextGetSurfacePointFromVector2( + const AZ::Vector2& inPosition, + Sampler sampleFilter = Sampler::DEFAULT) const + { + SurfaceData::SurfacePoint result; + GetSurfacePointFromVector2(inPosition, result, sampleFilter); + return result; + } }; using TerrainDataRequestBus = AZ::EBus; From 879012b1ae67714e028cf00454844bf552278c11 Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Tue, 30 Nov 2021 13:03:46 -0600 Subject: [PATCH 29/47] Added the --regset-file option for setreg file loading (#5768) The SettingsRegistryMergeUtils.cpp now supports specifying a path to a JSON Merge Patch formated settings registry file via the --regset-file option. The option supports specify an anchor key to merge the settings underneath that is separated from the filepath via "::" Ex. `--regset-file="Registry/custom.setreg::/Custom/Anchor"` An AZ::Console command of "sr_regset-file" has also been added to allow merging of a setting registry file as well. closes #5767 Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> --- Code/Framework/AzCore/AzCore/IO/Path/Path.h | 3 +- Code/Framework/AzCore/AzCore/IO/Path/Path.inl | 6 ++- .../Settings/SettingsRegistryConsoleUtils.cpp | 40 +++++++++++++++++-- .../Settings/SettingsRegistryConsoleUtils.h | 11 +++-- .../Settings/SettingsRegistryMergeUtils.cpp | 35 +++++++++++++--- .../SettingsRegistryMergeUtilsTests.cpp | 16 ++++++++ 6 files changed, 96 insertions(+), 15 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/IO/Path/Path.h b/Code/Framework/AzCore/AzCore/IO/Path/Path.h index 355d9ddedb..094dee16f2 100644 --- a/Code/Framework/AzCore/AzCore/IO/Path/Path.h +++ b/Code/Framework/AzCore/AzCore/IO/Path/Path.h @@ -78,7 +78,8 @@ namespace AZ::IO // native format observers //! Returns string_view stored within the PathView - constexpr AZStd::string_view Native() const noexcept; + constexpr const AZStd::string_view& Native() const noexcept; + constexpr AZStd::string_view& Native() noexcept; //! Conversion operator to retrieve string_view stored within the PathView constexpr explicit operator AZStd::string_view() const noexcept; diff --git a/Code/Framework/AzCore/AzCore/IO/Path/Path.inl b/Code/Framework/AzCore/AzCore/IO/Path/Path.inl index 1d654c1502..5ac15fc728 100644 --- a/Code/Framework/AzCore/AzCore/IO/Path/Path.inl +++ b/Code/Framework/AzCore/AzCore/IO/Path/Path.inl @@ -101,7 +101,11 @@ namespace AZ::IO } // native format observers - constexpr auto PathView::Native() const noexcept -> AZStd::string_view + constexpr auto PathView::Native() const noexcept -> const AZStd::string_view& + { + return m_path; + } + constexpr auto PathView::Native() noexcept -> AZStd::string_view& { return m_path; } diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryConsoleUtils.cpp b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryConsoleUtils.cpp index 7a8ab85ce3..e5f87f4e7f 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryConsoleUtils.cpp +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryConsoleUtils.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -36,7 +37,7 @@ namespace AZ::SettingsRegistryConsoleUtils combinedKeyValueCommand.c_str()); AZ::Debug::Trace::Output("SettingsRegistry", setOutput.c_str()); } - }; + } static void ConsoleRemoveSettingsRegistryValue(SettingsRegistryInterface& settingsRegistry, const ConsoleCommandContainer& commandArgs) { @@ -57,7 +58,7 @@ namespace AZ::SettingsRegistryConsoleUtils AZ::Debug::Trace::Output("SettingsRegistry", removeOutput.c_str()); } } - }; + } static void ConsoleDumpSettingsRegistryValue(SettingsRegistryInterface& settingsRegistry, const ConsoleCommandContainer& commandArgs) { @@ -88,13 +89,39 @@ namespace AZ::SettingsRegistryConsoleUtils } AZ::Debug::Trace::Output("SettingsRegistry", outputString.c_str()); - }; + } static void ConsoleDumpAllSettingsRegistryValues(SettingsRegistryInterface& settingsRegistry, [[maybe_unused]] const ConsoleCommandContainer& commandArgs) { ConsoleDumpSettingsRegistryValue(settingsRegistry, { "" }); - }; + } + + static void ConsoleMergeFileToSettingsRegistry(SettingsRegistryInterface& settingsRegistry, const ConsoleCommandContainer& commandArgs) + { + if (commandArgs.empty()) + { + AZ_Error("SettingsRegistryConsoleUtils", false, "Command %s requires a argument to locate json file to merge", + SettingsRegistryMergeFile); + return; + } + + auto commandArgumentsIter = commandArgs.begin(); + // Extract the JSON pointer path from the argument list + AZStd::string_view filePath{ *commandArgumentsIter++ }; + AZ::SettingsRegistryInterface::FixedValueString jsonAnchorPath; + AZ::StringFunc::Join(jsonAnchorPath, commandArgumentsIter, commandArgs.end(), ' '); + + const auto mergeFormat = AZ::IO::PathView(filePath).Extension() != ".setregpatch" ? AZ::SettingsRegistryInterface::Format::JsonMergePatch : AZ::SettingsRegistryInterface::Format::JsonPatch; + if (settingsRegistry.MergeSettingsFile(filePath, mergeFormat, jsonAnchorPath)) + { + const auto mergeFileOutput = AZ::SettingsRegistryInterface::FixedValueString::format( + R"(Merged json file "%*.s" anchored to json path "%s" into the global settings registry)" "\n", + AZ_STRING_ARG(filePath), jsonAnchorPath.c_str()); + AZ::Debug::Trace::Output("SettingsRegistry", mergeFileOutput.c_str()); + } + } + [[nodiscard]] ConsoleFunctorHandle RegisterAzConsoleCommands(SettingsRegistryInterface& registry, AZ::IConsole& azConsole) { @@ -115,6 +142,11 @@ namespace AZ::SettingsRegistryConsoleUtils resultHandle.m_consoleFunctors.emplace_back(azConsole, SettingsRegistryDumpAll, R"(Dumps all values from the global settings registry)" "\n", ConsoleFunctorFlags::Null, AZ::TypeId::CreateNull(), registry, &ConsoleDumpAllSettingsRegistryValues); + resultHandle.m_consoleFunctors.emplace_back(azConsole, SettingsRegistryMergeFile, + R"(Merges File into the global settings registry)" "\n" + R"(@param file-path - path to JSON formatted file to merge)" "\n" + R"(@param anchor-path - JSON path to anchor merge operation. Defaults to "")" "\n", + ConsoleFunctorFlags::Null, AZ::TypeId::CreateNull(), registry, &ConsoleMergeFileToSettingsRegistry); return resultHandle; } diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryConsoleUtils.h b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryConsoleUtils.h index ba0d552dde..1807a27604 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryConsoleUtils.h +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryConsoleUtils.h @@ -14,15 +14,16 @@ namespace AZ::SettingsRegistryConsoleUtils { - //! Only 4 console command are registered for the settings registry - //! "regset", "regremove", "regdump", "regdumpall" + //! The following console command are registered for the settings registry + //! "regset", "regremove", "regdump", "regdumpall", "regset-file" //! The value should be increased if more commands are needed - inline constexpr size_t MaxSettingsRegistryConsoleFunctors = 4; + inline constexpr size_t MaxSettingsRegistryConsoleFunctors = 5; inline constexpr const char* SettingsRegistrySet = "sr_regset"; inline constexpr const char* SettingsRegistryRemove = "sr_regremove"; inline constexpr const char* SettingsRegistryDump = "sr_regdump"; inline constexpr const char* SettingsRegistryDumpAll = "sr_regdumpall"; + inline constexpr const char* SettingsRegistryMergeFile = "sr_regset-file"; // RAII structure which owns the instances of the Settings Registry Console commands // registered with an AZ Console @@ -51,6 +52,10 @@ namespace AZ::SettingsRegistryConsoleUtils //! //! "sr_regdumpall" accepts 0 arguments and dumps the entire settings registry //! NOTE: this might result in a large amount of output to the console + //! + //! "sr_regset-file" accepts 1 or 2 arguments - [] + //! Merges the json formatted file into the settings registry underneath the root anchor "" + //! or if supplied [[nodiscard]] ConsoleFunctorHandle RegisterAzConsoleCommands(SettingsRegistryInterface& registry, AZ::IConsole& azConsole); } diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp index 975217a131..eed0112ad1 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp @@ -19,9 +19,6 @@ #include #include #include -#include -#include -#include #include #include @@ -983,7 +980,7 @@ namespace AZ::SettingsRegistryMergeUtils // code in the loop makes calls that mutates the `commandLine` instance, invalidating the iterators. Making a copy // ensures that the iterators remain valid. // NOLINTNEXTLINE(performance-unnecessary-value-param) - void MergeSettingsToRegistry_CommandLine(SettingsRegistryInterface& registry, AZ::CommandLine commandLine, bool executeCommands) + void MergeSettingsToRegistry_CommandLine(SettingsRegistryInterface& registry, AZ::CommandLine commandLine, bool executeRegdumpCommands) { // Iterate over all the command line options in order to parse the --regset and --regremove // arguments in the order they were supplied @@ -998,18 +995,44 @@ namespace AZ::SettingsRegistryMergeUtils continue; } } + else if (commandArgument.m_option == "regset-file") + { + AZStd::string_view fileArg(commandArgument.m_value); + AZStd::string_view jsonAnchorPath; + // double colons is treated as the separator for an anchor path + // single colon cannot be used as it is used in Windows paths + if (auto anchorPathIndex = AZ::StringFunc::Find(fileArg, "::"); + anchorPathIndex != AZStd::string_view::npos) + { + jsonAnchorPath = fileArg.substr(anchorPathIndex + 2); + fileArg = fileArg.substr(0, anchorPathIndex); + } + if (!fileArg.empty()) + { + AZ::IO::PathView filePath(fileArg); + const auto mergeFormat = filePath.Extension() != ".setregpatch" + ? AZ::SettingsRegistryInterface::Format::JsonMergePatch + : AZ::SettingsRegistryInterface::Format::JsonPatch; + if (!registry.MergeSettingsFile(filePath.Native(), mergeFormat, jsonAnchorPath)) + { + AZ_Warning("SettingsRegistryMergeUtils", false, R"(Merging of file "%.*s" to the Settings Registry has failed at anchor "%.*s".)", + AZ_STRING_ARG(filePath.Native()), AZ_STRING_ARG(jsonAnchorPath)); + continue; + } + } + } else if (commandArgument.m_option == "regremove") { if (!registry.Remove(commandArgument.m_value)) { AZ_Warning("SettingsRegistryMergeUtils", false, "Unable to remove value at JSON Pointer %s for --regremove.", - commandArgument.m_value.data()); + commandArgument.m_value.c_str()); continue; } } } - if (executeCommands) + if (executeRegdumpCommands) { constexpr bool prettifyOutput = true; const size_t regdumpSwitchValues = commandLine.GetNumSwitchValues("regdump"); diff --git a/Code/Framework/AzCore/Tests/Settings/SettingsRegistryMergeUtilsTests.cpp b/Code/Framework/AzCore/Tests/Settings/SettingsRegistryMergeUtilsTests.cpp index 00a18f7682..485593a699 100644 --- a/Code/Framework/AzCore/Tests/Settings/SettingsRegistryMergeUtilsTests.cpp +++ b/Code/Framework/AzCore/Tests/Settings/SettingsRegistryMergeUtilsTests.cpp @@ -539,6 +539,22 @@ tags=tools,renderer,metal)" EXPECT_STREQ("Bat", commandLine.GetMiscValue(2).c_str()); } + TEST_F(SettingsRegistryMergeUtilsCommandLineFixture, RegsetFileArgument_DoesNotMergeNUL) + { + AZStd::string regsetFile = AZ::IO::SystemFile::GetNullFilename(); + AZ::CommandLine commandLine; + commandLine.Parse({ "--regset-file", regsetFile }); + + AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*m_registry, commandLine, false); + + // Add a settings path to anchor loaded settings underneath + regsetFile = AZStd::string::format("%s::/AnchorPath/Of/Settings", AZ::IO::SystemFile::GetNullFilename()); + commandLine.Parse({ "--regset-file", regsetFile }); + + AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*m_registry, commandLine, false); + EXPECT_EQ(AZ::SettingsRegistryInterface::Type::NoType, m_registry->GetType("/AnchorPath/Of/Settings")); + } + using SettingsRegistryAncestorDescendantOrEqualPathFixture = SettingsRegistryMergeUtilsCommandLineFixture; TEST_F(SettingsRegistryAncestorDescendantOrEqualPathFixture, ValidateThatAncestorOrDescendantOrPathWithTheSameValue_Succeeds) From d600b1c9fd6659f79ef15fc3eba481b43b51f28c Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Tue, 30 Nov 2021 11:10:00 -0800 Subject: [PATCH 30/47] Adding GetBool method to CmdLineArg Signed-off-by: Gene Walters --- Code/Legacy/CryCommon/ICmdLine.h | 8 ++++++++ Code/Legacy/CrySystem/CmdLineArg.cpp | 17 +++++++++++++++++ Code/Legacy/CrySystem/CmdLineArg.h | 1 + 3 files changed, 26 insertions(+) diff --git a/Code/Legacy/CryCommon/ICmdLine.h b/Code/Legacy/CryCommon/ICmdLine.h index 6071671b02..80561fd85c 100644 --- a/Code/Legacy/CryCommon/ICmdLine.h +++ b/Code/Legacy/CryCommon/ICmdLine.h @@ -71,6 +71,14 @@ public: // The value of the argument as integer number. virtual const int GetIValue() const = 0; // + + // Description: + // Retrieve the value of the argument. + // Arguments: + // cmdLineValue. The cmdline value will be filled out if a valid boolean is found. + // Return Value: + // Returns true if the cmdline arg is actually a boolean string matching "true" or "false"; otherwise return false. + virtual const bool GetBoolValue(bool& cmdLineValue) const = 0; }; // Command line interface diff --git a/Code/Legacy/CrySystem/CmdLineArg.cpp b/Code/Legacy/CrySystem/CmdLineArg.cpp index 79d23ddae7..554e734055 100644 --- a/Code/Legacy/CrySystem/CmdLineArg.cpp +++ b/Code/Legacy/CrySystem/CmdLineArg.cpp @@ -42,5 +42,22 @@ const int CCmdLineArg::GetIValue() const { return atoi(m_value.c_str()); } +const bool CCmdLineArg::GetBoolValue(bool& cmdLineValue) const +{ + AZStd::string lowercaseValue(m_value); + AZStd::to_lower(lowercaseValue.begin(), lowercaseValue.end()); + if (lowercaseValue == "true") + { + cmdLineValue = true; + return true; + } + if (lowercaseValue == "false") + { + cmdLineValue = false; + return true; + } + + return false; +} diff --git a/Code/Legacy/CrySystem/CmdLineArg.h b/Code/Legacy/CrySystem/CmdLineArg.h index 5e3a629e7c..66d56be132 100644 --- a/Code/Legacy/CrySystem/CmdLineArg.h +++ b/Code/Legacy/CrySystem/CmdLineArg.h @@ -30,6 +30,7 @@ public: const ECmdLineArgType GetType() const; const float GetFValue() const; const int GetIValue() const; + const bool GetBoolValue(bool& cmdLineValue) const; private: From 7c30adb66caee3be16b8d80a48e0576212e9949e Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Tue, 30 Nov 2021 11:10:02 -0800 Subject: [PATCH 31/47] Removes _vs2019 from jenkins jobs and documentation (#5855) Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- .../EditorPythonTestTools/README.txt | 4 +- .../ap_fixtures/ap_setup_fixture.py | 2 +- .../ap_fixtures/asset_processor_fixture.py | 2 +- .../Windows/ProjectManagerDefs_windows.cpp | 2 +- .../azpy/synthetic_env.py | 2 +- .../DccScriptingInterface/config.py | 2 +- .../Code/Tests/run_EMotionFX_tests.py | 94 ---------------- README.md | 4 +- Tools/LyTestTools/README.txt | 4 +- .../managers/abstract_resource_locator.py | 6 +- .../_internal/managers/workspace.py | 2 +- .../ly_remote_console/README.txt | 3 +- .../build/Platform/Android/build_config.json | 2 +- .../build/Platform/Windows/build_config.json | 102 +++++++++--------- .../Windows/package_build_config.json | 4 +- .../package/Platform/Windows/package_env.json | 2 +- scripts/o3de/README.txt | 2 +- 17 files changed, 72 insertions(+), 167 deletions(-) delete mode 100755 Gems/EMotionFX/Code/Tests/run_EMotionFX_tests.py diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/README.txt b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/README.txt index 642d7279a4..bd9740f60f 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/README.txt +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/README.txt @@ -26,8 +26,8 @@ INSTALL It is recommended to set up these these tools with O3DE's CMake build commands. Assuming CMake is already setup on your operating system, below are some sample build commands: cd /path/to/od3e/ - mkdir windows_vs2019 - cd windows_vs2019 + mkdir windows + cd windows cmake .. -G "Visual Studio 16 2019" -DLY_PROJECTS=AutomatedTesting To manually install the project in development mode using your own installed Python interpreter: diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_setup_fixture.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_setup_fixture.py index 244ecfb516..c5b02e4f28 100755 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_setup_fixture.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_setup_fixture.py @@ -4,7 +4,7 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT -A fixture for Setting Up Asset Processor Batch workspace for tests in lmbr_test +A fixture for Setting Up Asset Processor Batch workspace for tests """ # Import builtin libraries diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/asset_processor_fixture.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/asset_processor_fixture.py index eea6cb9224..674862443e 100755 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/asset_processor_fixture.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/asset_processor_fixture.py @@ -4,7 +4,7 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT -A fixture for using the Asset Processor in lmbr_test, this will stop the asset processor after every test via +A fixture for using the Asset Processor, this will stop the asset processor after every test via the teardown. Using the fixture at class level will stop the asset processor after the suite completes. Using the fixture at test level will stop asset processor after the test completes. Calling this fixture as a test argument will still run the teardown to stop the Asset Processor. """ diff --git a/Code/Tools/ProjectManager/Platform/Windows/ProjectManagerDefs_windows.cpp b/Code/Tools/ProjectManager/Platform/Windows/ProjectManagerDefs_windows.cpp index 6b58458ccd..9fa9321cce 100644 --- a/Code/Tools/ProjectManager/Platform/Windows/ProjectManagerDefs_windows.cpp +++ b/Code/Tools/ProjectManager/Platform/Windows/ProjectManagerDefs_windows.cpp @@ -9,7 +9,7 @@ namespace O3DE::ProjectManager { - const QString ProjectBuildPathPostfix = ProjectBuildDirectoryName + "/windows_vs2019"; + const QString ProjectBuildPathPostfix = ProjectBuildDirectoryName + "/windows"; const QString GetPythonScriptPath = "python/get_python.bat"; } // namespace O3DE::ProjectManager diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/azpy/synthetic_env.py b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/azpy/synthetic_env.py index 33ac6c6814..2d0685b67d 100644 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/azpy/synthetic_env.py +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/azpy/synthetic_env.py @@ -508,7 +508,7 @@ def init_ly_pyside(env_dict=_SYNTH_ENV_DICT): site.addsitedir(str(QTFORPYTHON_PATH)) O3DE_BIN_PATH = Path.joinpath(O3DE_DEV, - 'windows_vs2019', + 'windows', 'bin', 'profile').resolve() os.environ["DYNACONF_O3DE_BIN_PATH"] = str(O3DE_BIN_PATH) diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/config.py b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/config.py index 5578bcd577..a9cf5e8ee5 100755 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/config.py +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/config.py @@ -532,7 +532,7 @@ if __name__ == '__main__': parser.add_argument('-bf', '--build-folder', type=str, required=False, - help='The name (tag) of the o3de build folder, example build or windows_vs2019.') + help='The name (tag) of the o3de build folder, example build or windows.') parser.add_argument('-pp', '--project-path', type=pathlib.Path, required=False, diff --git a/Gems/EMotionFX/Code/Tests/run_EMotionFX_tests.py b/Gems/EMotionFX/Code/Tests/run_EMotionFX_tests.py deleted file mode 100755 index e3b930e43b..0000000000 --- a/Gems/EMotionFX/Code/Tests/run_EMotionFX_tests.py +++ /dev/null @@ -1,94 +0,0 @@ -""" -Copyright (c) Contributors to the Open 3D Engine Project. -For complete copyright and license terms please see the LICENSE at the root of this distribution. - -SPDX-License-Identifier: Apache-2.0 OR MIT - -python run_EMotionFX_tests.py --config --vsVersion - -Example: -python run_EMotionFX_tests.py --config profile --vsVersion vs2017 -python run_EMotionFX_tests.py --config debug --vsVersion vs2019 - - -Requirements: - -- Provide a single script that executes all your team's automated BAT/Regression tests - -- The script should run the tests successfully if killed in the middle and restarted - -- Provide any documentation needed along with the script so that other feature teams wanting to execute your tests can execute them locally - -- The documentation should also cover where the test results are reported and how to find failing tests and their logs - - -""" - -import argparse -import os -import subprocess - - -#Setup Parser -def parser_setup(): - parser = argparse.ArgumentParser(description='Sets up for and runs the specified EMotionFX tests') - - # Configuration - parser.add_argument('--config', choices=['profile','debug'] , help='The Conrfiguration you have pre-build and want to run the tests on. Options[profile,debug]') - - #Visual Studio Version - parser.add_argument('--vsVersion', choices=['vs2017','vs2019'], help='The version of Visual Studio you used to build your branch. Options[vs2017, vs2019]') - - - - return parser - - - -#Main Program -def main(): - # Set up CLI arguments for CLI argument parser - parser = parser_setup() - - # Capture arguments and their values - args = parser.parse_args() - - - # Change directory to branch root - dev_path = os.path.join(os.path.dirname(__file__), '..', '..','..','..') - os.chdir(dev_path) - dirpath = os.getcwd() - - - vsVersion = args.vsVersion - config = args.config - - if vsVersion == 'vs2017': - if config == 'profile': - #lmbr_test.cmd scan --dir Bin64vc141.Test --only Gem\.EMotionFX\..*\.dll - subprocess.run('lmbr_test.cmd scan --dir Bin64vc141.Test --only Gem\.EMotionFX\..*\.dll', check=True) - - elif config == 'debug': - #lmbr_test.cmd scan --dir Bin64vc141.Debug.Test --only Gem\.EMotionFX\..*\.dll - subprocess.run('lmbr_test.cmd scan --dir Bin64vc141.Debug.Test --only Gem\.EMotionFX\..*\.dll', check=True) - - else: - print('INVALID ARGUMENT(s)... Ending') - elif vsVersion == 'vs2019': - if config == 'profile': - #lmbr_test.cmd scan --dir Bin64vc142.Test --only Gem\.EMotionFX\..*\.dll - subprocess.run('lmbr_test.cmd scan --dir Bin64vc142.Test --only Gem\.EMotionFX\..*\.dll', check=True) - - elif config == 'debug': - #lmbr_test.cmd scan --dir Bin64vc142.Debug.Test --only Gem\.EMotionFX\..*\.dll - subprocess.run('lmbr_test.cmd scan --dir Bin64vc141.Debug.Test --only Gem\.EMotionFX\..*\.dll', check=True) - - else: - print('INVALID ARGUMENT(s)... Ending') - else: - print('INVALID ARGUMENT(s)... Ending') - - - -if __name__ == '__main__': - main() diff --git a/README.md b/README.md index 11fec028bc..063a59de74 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ To set up a project-centric source engine, complete the following steps. For oth Example: ``` - cmake -B C:\o3de\build\windows_vs2019 -S C:\o3de -G "Visual Studio 16" -DLY_3RDPARTY_PATH=C:\o3de-packages + cmake -B C:\o3de\build\windows -S C:\o3de -G "Visual Studio 16" -DLY_3RDPARTY_PATH=C:\o3de-packages ``` > Note: Do not use trailing slashes for the <3rdParty package path>. @@ -107,7 +107,7 @@ For more details on the steps above, refer to [Setting up O3DE from GitHub](http Example: ``` - cmake -B C:\my-project\build\windows_vs2019 -S C:\my-project -G "Visual Studio 16" + cmake -B C:\my-project\build\windows -S C:\my-project -G "Visual Studio 16" ``` > Note: Do not use trailing slashes for the <3rdParty cache path>. diff --git a/Tools/LyTestTools/README.txt b/Tools/LyTestTools/README.txt index 61ad507dc4..4372bc5201 100644 --- a/Tools/LyTestTools/README.txt +++ b/Tools/LyTestTools/README.txt @@ -35,8 +35,8 @@ INSTALL It is recommended to set up these these tools with Lumberyard's CMake build commands. Assuming CMake is already setup on your operating system, below are some sample build commands: cd /path/to/lumberyard/dev/ - mkdir windows_vs2019 - cd windows_vs2019 + mkdir windows + cd windows cmake -E time cmake --build . --target ALL_BUILD --config profile To manually install the project in development mode using your own installed Python interpreter: diff --git a/Tools/LyTestTools/ly_test_tools/_internal/managers/abstract_resource_locator.py b/Tools/LyTestTools/ly_test_tools/_internal/managers/abstract_resource_locator.py index 4ff71a5b31..d11980658d 100755 --- a/Tools/LyTestTools/ly_test_tools/_internal/managers/abstract_resource_locator.py +++ b/Tools/LyTestTools/ly_test_tools/_internal/managers/abstract_resource_locator.py @@ -277,7 +277,7 @@ class AbstractResourceLocator(object): def get_shader_compiler_path(self): """ Return path to shader compiler executable - ex. engine_root/dev/windows_vs2019/bin/profile/CrySCompileServer + ex. engine_root/dev/windows/bin/profile/CrySCompileServer :return: path to CrySCompileServer executable """ return os.path.join(self.build_directory(), 'CrySCompileServer') @@ -313,7 +313,7 @@ class AbstractResourceLocator(object): def shader_compiler_config_file(self): """ Return path to the Shader Compiler config file - ex. engine_root/dev/windows_vs2019/bin/profile/config.ini + ex. engine_root/dev/windows/bin/profile/config.ini :return: path to the Shader Compiler config file """ return os.path.join(self.build_directory(), 'config.ini') @@ -321,7 +321,7 @@ class AbstractResourceLocator(object): def shader_cache(self): """ Return path to the shader cache for the current build - ex. engine_root/dev/windows_vs2019/bin/profile/Cache + ex. engine_root/dev/windows/bin/profile/Cache :return: path to the shader cache for the current build """ return os.path.join(self.build_directory(), 'Cache') diff --git a/Tools/LyTestTools/ly_test_tools/_internal/managers/workspace.py b/Tools/LyTestTools/ly_test_tools/_internal/managers/workspace.py index ac412acf84..801729f008 100755 --- a/Tools/LyTestTools/ly_test_tools/_internal/managers/workspace.py +++ b/Tools/LyTestTools/ly_test_tools/_internal/managers/workspace.py @@ -119,7 +119,7 @@ class AbstractWorkspaceManager: def clear_bin(self): """ - Clears the relative Bin folder (i.e. engine_root/dev/windows_vs2019/bin/profile/) + Clears the relative Bin folder (i.e. engine_root/dev/windows/bin/profile/) :return: None """ if os.path.exists(self.paths.build_directory()): diff --git a/Tools/RemoteConsole/ly_remote_console/README.txt b/Tools/RemoteConsole/ly_remote_console/README.txt index 497179ac15..0c5d8c67af 100644 --- a/Tools/RemoteConsole/ly_remote_console/README.txt +++ b/Tools/RemoteConsole/ly_remote_console/README.txt @@ -22,8 +22,7 @@ installed on your system. INSTALL ----------- -It is recommended to set up these these tools with the lmbr_test tool Lumberyard's root directory: - lmbr_test pysetup install +Installation of these tools happen automatically when get_python and cmake is run. To manually install the project in development mode: python -m pip install -e . diff --git a/scripts/build/Platform/Android/build_config.json b/scripts/build/Platform/Android/build_config.json index dbdafcf97d..06fa1ffb5f 100644 --- a/scripts/build/Platform/Android/build_config.json +++ b/scripts/build/Platform/Android/build_config.json @@ -92,7 +92,7 @@ "COMMAND":"../Windows/build_asset_windows.cmd", "PARAMETERS": { "CONFIGURATION":"profile", - "OUTPUT_DIRECTORY":"build\\windows_vs2019", + "OUTPUT_DIRECTORY":"build\\windows", "CMAKE_OPTIONS":"-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", "CMAKE_LY_PROJECTS":"AutomatedTesting", "CMAKE_TARGET":"AssetProcessorBatch", diff --git a/scripts/build/Platform/Windows/build_config.json b/scripts/build/Platform/Windows/build_config.json index 6f1aaa1570..c591ca0eac 100644 --- a/scripts/build/Platform/Windows/build_config.json +++ b/scripts/build/Platform/Windows/build_config.json @@ -15,24 +15,24 @@ "validation" ] }, - "debug_vs2019_pipe": { + "debug_pipe": { "TAGS": [ "nightly-incremental", "nightly-clean" ], "steps": [ - "debug_vs2019", - "test_debug_vs2019" + "debug", + "test_debug" ] }, - "profile_vs2019_pipe": { + "profile_pipe": { "TAGS": [ "default" ], "steps": [ - "profile_vs2019", - "asset_profile_vs2019", - "test_cpu_profile_vs2019" + "profile", + "asset_profile", + "test_cpu_profile" ] }, "scrubbing": { @@ -79,40 +79,40 @@ "SCRIPT_PARAMETERS": "--platform 3rdParty --type 3rdParty_all" } }, - "test_impact_analysis_profile_vs2019": { + "test_impact_analysis_profile": { "TAGS": [ ], "COMMAND": "python_windows.cmd", "PARAMETERS": { - "OUTPUT_DIRECTORY": "build/windows_vs2019", + "OUTPUT_DIRECTORY": "build/windows", "CONFIGURATION": "profile", "SCRIPT_PATH": "scripts/build/TestImpactAnalysis/tiaf_driver.py", "SCRIPT_PARAMETERS": "--config=\"%OUTPUT_DIRECTORY%/bin/TestImpactFramework/profile/Persistent/tiaf.json\" --src-branch=%BRANCH_NAME% --dst-branch=%CHANGE_TARGET% --commit=%CHANGE_ID% --s3-bucket=%TEST_IMPACT_S3_BUCKET% --mars-index-prefix=jonawals --s3-top-level-dir=%REPOSITORY_NAME% --build-number=%BUILD_NUMBER% --suite=main --test-failure-policy=continue" } }, - "debug_vs2019": { + "debug": { "TAGS": [ "weekly-build-metrics" ], "COMMAND": "build_windows.cmd", "PARAMETERS": { "CONFIGURATION": "debug", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "ALL_BUILD", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo" } }, - "test_debug_vs2019": { + "test_debug": { "TAGS": [ "weekly-build-metrics" ], "COMMAND": "build_test_windows.cmd", "PARAMETERS": { "CONFIGURATION": "debug", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "TEST_SUITE_smoke TEST_SUITE_main", @@ -122,7 +122,7 @@ "TEST_RESULTS": "True" } }, - "profile_vs2019": { + "profile": { "TAGS": [ "daily-pipeline-metrics", "weekly-build-metrics" @@ -130,14 +130,14 @@ "COMMAND": "build_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_TEST_IMPACT_INSTRUMENTATION_BIN=%TEST_IMPACT_WIN_BINARY%", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "ALL_BUILD", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo" } }, - "profile_vs2019_nounity": { + "profile_nounity": { "TAGS": [ "nightly-incremental", "nightly-clean", @@ -146,14 +146,14 @@ "COMMAND": "build_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=FALSE", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "ALL_BUILD", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo" } }, - "test_cpu_profile_vs2019": { + "test_cpu_profile": { "TAGS": [ "daily-pipeline-metrics", "weekly-build-metrics" @@ -161,7 +161,7 @@ "COMMAND": "build_test_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "TEST_SUITE_smoke TEST_SUITE_main", @@ -171,7 +171,7 @@ "TEST_RESULTS": "True" } }, - "test_gpu_profile_vs2019": { + "test_gpu_profile": { "TAGS":[ "nightly-incremental", "nightly-clean" @@ -182,7 +182,7 @@ "COMMAND": "build_test_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "TEST_SUITE_smoke TEST_SUITE_main", @@ -193,7 +193,7 @@ "TEST_SCREENSHOTS": "True" } }, - "asset_profile_vs2019": { + "asset_profile": { "TAGS": [ "weekly-build-metrics", "nightly-incremental", @@ -202,7 +202,7 @@ "COMMAND": "build_asset_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "AssetProcessorBatch", @@ -212,18 +212,18 @@ "ASSET_PROCESSOR_PLATFORMS": "pc,server" } }, - "awsi_test_profile_vs2019_pipe": { + "awsi_test_profile_pipe": { "TAGS": [ "nightly-incremental", "nightly-clean" ], "steps": [ "awsi_deployment", - "awsi_test_profile_vs2019", + "awsi_test_profile", "awsi_destruction" ] }, - "awsi_test_profile_vs2019": { + "awsi_test_profile": { "TAGS": [ "weekly-build-metrics" ], @@ -233,7 +233,7 @@ "COMMAND": "build_test_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "TEST_SUITE_awsi", @@ -243,7 +243,7 @@ "TEST_RESULTS": "True" } }, - "periodic_test_profile_vs2019": { + "periodic_test_profile": { "TAGS": [ "nightly-incremental", "nightly-clean", @@ -252,7 +252,7 @@ "COMMAND": "build_test_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "TEST_SUITE_periodic", @@ -262,7 +262,7 @@ "TEST_RESULTS": "True" } }, - "sandbox_test_profile_vs2019": { + "sandbox_test_profile": { "TAGS": [ "nightly-incremental", "nightly-clean", @@ -274,7 +274,7 @@ "COMMAND": "build_test_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "TEST_SUITE_sandbox", @@ -284,7 +284,7 @@ "TEST_RESULTS": "True" } }, - "benchmark_test_profile_vs2019": { + "benchmark_test_profile": { "TAGS": [ "nightly-incremental", "nightly-clean", @@ -293,7 +293,7 @@ "COMMAND": "build_test_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "TEST_SUITE_benchmark", @@ -303,7 +303,7 @@ "TEST_RESULTS": "True" } }, - "release_vs2019": { + "release": { "TAGS": [ "default", "nightly-incremental", @@ -313,14 +313,14 @@ "COMMAND": "build_windows.cmd", "PARAMETERS": { "CONFIGURATION": "release", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "ALL_BUILD", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo" } }, - "monolithic_release_vs2019": { + "monolithic_release": { "TAGS": [ "nightly-incremental", "nightly-clean", @@ -329,25 +329,25 @@ "COMMAND": "build_windows.cmd", "PARAMETERS": { "CONFIGURATION": "release", - "OUTPUT_DIRECTORY": "build\\mono_windows_vs2019", + "OUTPUT_DIRECTORY": "build\\mono_windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_MONOLITHIC_GAME=TRUE", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "ALL_BUILD", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo" } }, - "install_profile_vs2019": { + "install_profile": { "TAGS": [], "COMMAND": "build_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_DISABLE_TEST_MODULES=TRUE", "CMAKE_TARGET": "INSTALL", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo" } }, - "installer_vs2019": { + "installer": { "TAGS": [ "nightly-clean", "nightly-installer" @@ -358,7 +358,7 @@ "COMMAND": "build_installer_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_DISABLE_TEST_MODULES=TRUE -DLY_VERSION_ENGINE_NAME=o3de-sdk -DLY_INSTALLER_WIX_ROOT=\"!WIX! \"", "EXTRA_CMAKE_OPTIONS": "-DLY_INSTALLER_AUTO_GEN_TAG=TRUE -DLY_INSTALLER_DOWNLOAD_URL=!INSTALLER_DOWNLOAD_URL! -DLY_INSTALLER_LICENSE_URL=!INSTALLER_DOWNLOAD_URL!/license", "CMAKE_TARGET": "ALL_BUILD", @@ -366,7 +366,7 @@ "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo" } }, - "install_profile_vs2019_pipe": { + "install_profile_pipe": { "TAGS": [ "nightly-incremental", "nightly-clean" @@ -375,9 +375,9 @@ "PROJECT_REPOSITORY_NAME": "TestProject" }, "steps": [ - "install_profile_vs2019", + "install_profile", "project_generate", - "project_engineinstall_profile_vs2019" + "project_engineinstall_profile" ] }, "project_generate": { @@ -388,7 +388,7 @@ "SCRIPT_PARAMETERS": "create-project -pp %WORKSPACE%\\%PROJECT_REPOSITORY_NAME% --force" } }, - "project_enginesource_profile_vs2019": { + "project_enginesource_profile": { "TAGS": [ "project" ], @@ -398,13 +398,13 @@ "COMMAND": "build_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DCMAKE_MODULE_PATH=%WORKSPACE%/o3de/cmake", "CMAKE_TARGET": "ALL_BUILD", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo" } }, - "project_engineinstall_profile_vs2019": { + "project_engineinstall_profile": { "TAGS": [], "PIPELINE_ENV": { "EXECUTE_FROM_PROJECT": "1" @@ -413,19 +413,19 @@ "PARAMETERS": { "COMMAND_CWD": "%WORKSPACE%\\%PROJECT_REPOSITORY_NAME%", "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DCMAKE_MODULE_PATH=%WORKSPACE%/o3de/install/cmake", "CMAKE_TARGET": "ALL_BUILD", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo" } }, - "project_engineinstall_profile_vs2019_pipe": { + "project_engineinstall_profile_pipe": { "TAGS": [ "project" ], "steps": [ - "install_profile_vs2019", - "project_engineinstall_profile_vs2019" + "install_profile", + "project_engineinstall_profile" ] }, "awsi_deployment": { diff --git a/scripts/build/Platform/Windows/package_build_config.json b/scripts/build/Platform/Windows/package_build_config.json index 5eb96f1e38..1a94fb802a 100644 --- a/scripts/build/Platform/Windows/package_build_config.json +++ b/scripts/build/Platform/Windows/package_build_config.json @@ -1,9 +1,9 @@ { - "profile_vs2019_atom": { + "profile_atom": { "COMMAND":"build_windows.cmd", "PARAMETERS": { "CONFIGURATION":"profile", - "OUTPUT_DIRECTORY":"windows_vs2019", + "OUTPUT_DIRECTORY":"windows", "CMAKE_OPTIONS":"-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", "CMAKE_LY_PROJECTS":"AtomTest;AtomSampleViewer", "CMAKE_TARGET":"ALL_BUILD", diff --git a/scripts/build/package/Platform/Windows/package_env.json b/scripts/build/package/Platform/Windows/package_env.json index 970361bacc..bfe526bc16 100644 --- a/scripts/build/package/Platform/Windows/package_env.json +++ b/scripts/build/package/Platform/Windows/package_env.json @@ -27,7 +27,7 @@ { "BUILD_CONFIG_FILENAME": "build_config.json", "PLATFORM": "Windows", - "TYPE": "profile_vs2019" + "TYPE": "profile" } ] } diff --git a/scripts/o3de/README.txt b/scripts/o3de/README.txt index ded52bb264..39817c2df7 100644 --- a/scripts/o3de/README.txt +++ b/scripts/o3de/README.txt @@ -23,7 +23,7 @@ INSTALL It is recommended to set up these these tools with O3DE's CMake build commands. Assuming CMake is already setup on your operating system, below are some sample build commands: cd /path/to/od3e/ - cmake -B windows_vs2019 -S . -G"Visual Studio 16" + cmake -B windows -S . -G"Visual Studio 16" To manually install the project in development mode using your own installed Python interpreter: cd /path/to/od3e/o3de From 6d0ba68b55378c8170c72b4f2630cc1fcc902ebc Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Tue, 30 Nov 2021 11:12:07 -0800 Subject: [PATCH 32/47] Using new GetBool value when checking if we're an editor-server. Clean up MPEditorSystemComponent for unused #includes, and null-checking when piping server logs Signed-off-by: Gene Walters --- Code/Legacy/CrySystem/SystemInit.cpp | 5 ++--- .../Editor/MultiplayerEditorSystemComponent.cpp | 16 +++++++++++----- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Code/Legacy/CrySystem/SystemInit.cpp b/Code/Legacy/CrySystem/SystemInit.cpp index 6f550fcac6..70595e53c1 100644 --- a/Code/Legacy/CrySystem/SystemInit.cpp +++ b/Code/Legacy/CrySystem/SystemInit.cpp @@ -741,9 +741,8 @@ bool CSystem::Init(const SSystemInitParams& startupParams) bool suppressSystemOutput = true; if (const ICmdLineArg* isEditorServerArg = m_pCmdLine->FindArg(eCLAT_Pre, "editorsv_isDedicated")) { - AZ::CVarFixedString lowercaseValue(isEditorServerArg->GetValue()); - AZStd::to_lower(lowercaseValue.begin(), lowercaseValue.end()); - if (lowercaseValue == "true") + bool editorsv_isDedicated = false; + if (isEditorServerArg->GetBoolValue(editorsv_isDedicated) && editorsv_isDedicated) { suppressSystemOutput = false; } diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp index fa855cf28c..259d544279 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp @@ -6,7 +6,6 @@ * */ -#include "AzFramework/Process/ProcessCommunicator.h" #include #include @@ -16,11 +15,8 @@ #include #include #include -#include -#include #include -#include #include #include #include @@ -425,7 +421,17 @@ namespace Multiplayer void MultiplayerEditorSystemComponent::OnTick(float, AZ::ScriptTimePoint) { - m_serverProcessTracePrinter->Pump(); + if (m_serverProcessTracePrinter) + { + m_serverProcessTracePrinter->Pump(); + } + else + { + AZ::TickBus::Handler::BusDisconnect(); + AZ_Warning( + "MultiplayerEditorSystemComponent", false, + "The server process trace printer is NULL so we won't be able to pipe server logs to the editor. Please update the code to call AZ::TickBus::Handler::BusDisconnect whenever the editor-server is terminated.") + } } } From f05b63bcbaab605e07adad8ce66077ec79db141d Mon Sep 17 00:00:00 2001 From: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> Date: Tue, 30 Nov 2021 13:18:41 -0600 Subject: [PATCH 33/47] Enabling only optimized test runners for Editor/DynVeg/GradSignal (#5873) Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> --- .../Gem/PythonTests/editor/CMakeLists.txt | 54 ------------------- .../editor/TestSuite_Main_Optimized.py | 1 - .../PythonTests/largeworlds/CMakeLists.txt | 33 +----------- .../dyn_veg/TestSuite_Main_Optimized.py | 1 - 4 files changed, 2 insertions(+), 87 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt index bf42579970..1fc71da972 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt @@ -7,60 +7,6 @@ # if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_FOUNDATION_TEST_SUPPORTED) - ly_add_pytest( - NAME AutomatedTesting::EditorTests_Main - TEST_SUITE main - TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py - PYTEST_MARKS "not REQUIRES_gpu" - RUNTIME_DEPENDENCIES - Legacy::Editor - AZ::AssetProcessor - AutomatedTesting.Assets - COMPONENT - Editor - ) - - ly_add_pytest( - NAME AutomatedTesting::EditorTests_Main_GPU - TEST_SUITE main - TEST_SERIAL - TEST_REQUIRES gpu - PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py - PYTEST_MARKS "REQUIRES_gpu" - RUNTIME_DEPENDENCIES - Legacy::Editor - AZ::AssetProcessor - AutomatedTesting.Assets - COMPONENT - Editor - ) - - ly_add_pytest( - NAME AutomatedTesting::EditorTests_Periodic - TEST_SUITE periodic - TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Periodic.py - RUNTIME_DEPENDENCIES - Legacy::Editor - AZ::AssetProcessor - AutomatedTesting.Assets - COMPONENT - Editor - ) - - ly_add_pytest( - NAME AutomatedTesting::EditorTests_Sandbox - TEST_SUITE sandbox - TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Sandbox.py - RUNTIME_DEPENDENCIES - Legacy::Editor - AZ::AssetProcessor - AutomatedTesting.Assets - COMPONENT - Editor - ) ly_add_pytest( NAME AutomatedTesting::EditorTests_Main_Optimized diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py index ccc4ee9737..d87fd8625b 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py +++ b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py @@ -49,7 +49,6 @@ class TestAutomationNoAutoTestMode(EditorTestSuite): from .EditorScripts import AssetPicker_UI_UX as test_module -@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.") @pytest.mark.SUITE_main @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("project", ["AutomatedTesting"]) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt index 98801b49d6..ba607ede32 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt @@ -11,24 +11,10 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ ## DynVeg ## ly_add_pytest( - NAME AutomatedTesting::DynamicVegetationTests_Main + NAME AutomatedTesting::DynamicVegetationTests_Main_Optimized TEST_SERIAL TEST_SUITE main - PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Main.py - RUNTIME_DEPENDENCIES - AZ::AssetProcessor - Legacy::Editor - AutomatedTesting.GameLauncher - AutomatedTesting.Assets - COMPONENT - LargeWorlds - ) - - ly_add_pytest( - NAME AutomatedTesting::DynamicVegetationTests_Periodic - TEST_SERIAL - TEST_SUITE periodic - PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Periodic.py + PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Main_Optimized.py RUNTIME_DEPENDENCIES AZ::AssetProcessor Legacy::Editor @@ -37,7 +23,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ COMPONENT LargeWorlds ) - ly_add_pytest( NAME AutomatedTesting::DynamicVegetationTests_Periodic_Optimized TEST_SERIAL @@ -52,20 +37,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ LargeWorlds ) - ly_add_pytest( - NAME AutomatedTesting::DynamicVegetationTests_Main_Optimized - TEST_SERIAL - TEST_SUITE main - PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Main_Optimized.py - RUNTIME_DEPENDENCIES - AZ::AssetProcessor - Legacy::Editor - AutomatedTesting.Assets - AutomatedTesting.GameLauncher - COMPONENT - LargeWorlds - ) - ## LandscapeCanvas ## ly_add_pytest( diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py index ed23af51ad..d83f88cad2 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py @@ -12,7 +12,6 @@ import ly_test_tools.environment.file_system as file_system from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite -@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.") @pytest.mark.SUITE_main @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("project", ["AutomatedTesting"]) From b63064f604a5a2f66a6de8e7b7cc910012b694cb Mon Sep 17 00:00:00 2001 From: AMZN-stankowi <4838196+AMZN-stankowi@users.noreply.github.com> Date: Tue, 30 Nov 2021 11:34:54 -0800 Subject: [PATCH 34/47] Automated test for bundle mode that creates and mounts a bundle with a level.pak file in it, and verifies that occurs. (#5805) This is a regression test for bundle mode causing the editor to crash if you mount a bundle containing a level.pak file. Signed-off-by: AMZN-stankowi <4838196+AMZN-stankowi@users.noreply.github.com> --- .../asset_processor_tests/CMakeLists.txt | 13 +++ .../bundle_mode_in_editor_tests.py | 20 ++++ .../bundle_mode_tests.py | 93 +++++++++++++++++++ .../ly_test_tools/launchers/platforms/base.py | 2 +- 4 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_in_editor_tests.py create mode 100644 AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_tests.py diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt index 5a5809595e..e37a5ed99b 100644 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt @@ -103,6 +103,19 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) AZ::AssetBundlerBatch ) + ly_add_pytest( + NAME AssetPipelineTests.BundleMode + PATH ${CMAKE_CURRENT_LIST_DIR}/bundle_mode_tests.py + EXCLUDE_TEST_RUN_TARGET_FROM_IDE + TEST_SERIAL + TEST_SUITE periodic + RUNTIME_DEPENDENCIES + AZ::AssetProcessor + AZ::AssetBundlerBatch + Legacy::Editor + AutomatedTesting.Assets + ) + ly_add_pytest( NAME AssetPipelineTests.AssetBuilder PATH ${CMAKE_CURRENT_LIST_DIR}/asset_builder_tests.py diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_in_editor_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_in_editor_tests.py new file mode 100644 index 0000000000..33a55d6601 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_in_editor_tests.py @@ -0,0 +1,20 @@ +""" +Copyright (c) Contributors to the Open 3D Engine Project. +For complete copyright and license terms please see the LICENSE at the root of this distribution. + +SPDX-License-Identifier: Apache-2.0 OR MIT +""" +import azlmbr.bus +import azlmbr.editor +import azlmbr.legacy.general +import sys + +# Print out the passed in bundle_path, so the outer test can verify this was sent in correctly +bundle_path = sys.argv[1] +print('Bundle mode test running with path {}'.format(sys.argv[1])) + +# Turn on bundle mode. This will trigger some printouts that the outer test logic will validate. +azlmbr.legacy.general.set_cvar_integer("sys_report_files_not_found_in_paks", 1) +azlmbr.legacy.general.run_console(f"loadbundles {bundle_path}") + +azlmbr.editor.EditorToolsApplicationRequestBus(azlmbr.bus.Broadcast, 'ExitNoPrompt') diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_tests.py new file mode 100644 index 0000000000..af92bb1773 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_tests.py @@ -0,0 +1,93 @@ +""" +Copyright (c) Contributors to the Open 3D Engine Project. +For complete copyright and license terms please see the LICENSE at the root of this distribution. + +SPDX-License-Identifier: Apache-2.0 OR MIT +""" + +import os +import pytest +import logging +import sys +import time +pytest.importorskip('ly_test_tools') + +import ly_test_tools.environment.file_system as fs +import ly_test_tools.environment.waiter as waiter +import ly_test_tools.log.log_monitor + +from ..ap_fixtures.asset_processor_fixture import asset_processor as asset_processor +from ..ap_fixtures.bundler_batch_setup_fixture import bundler_batch_setup_fixture as bundler_batch_helper +from ..ap_fixtures.timeout_option_fixture import timeout_option_fixture as timeout + +@pytest.mark.SUITE_periodic +@pytest.mark.parametrize('launcher_platform', ['windows_editor']) +@pytest.mark.parametrize('project', ['AutomatedTesting']) +@pytest.mark.parametrize('level', ['auto_test']) +class TestBundleMode(object): + def test_bundle_mode_with_levels_mounts_bundles_correctly(self, request, editor, level, launcher_platform, + asset_processor, workspace, bundler_batch_helper): + level_pak = os.path.join("levels", level, "level.pak") + + bundles_folder = os.path.join(workspace.paths.project(), "Bundles") + bundle_request_path = os.path.join(bundles_folder, "bundle.pak") + bundle_result_path = os.path.join(bundles_folder, + bundler_batch_helper.platform_file_name( + "bundle.pak", workspace.asset_processor_platform)) + + # Create target 'Bundles' folder if it doesn't exist + if not os.path.exists(bundles_folder): + os.mkdir(bundles_folder) + # Delete target bundle file if it already exists + if os.path.exists(bundle_result_path): + fs.delete([bundle_result_path], True, False) + + # Make asset list file to use in the bundle + bundler_batch_helper.call_assetLists( + addSeed=level_pak, + assetListFile=bundler_batch_helper["asset_info_file_request"], + ) + + # Make bundle in /Bundles + bundler_batch_helper.call_bundles( + assetListFile=bundler_batch_helper["asset_info_file_result"], + outputBundlePath=bundle_request_path, + maxSize="2048", + ) + + # Ensure the bundle was created + assert os.path.exists(bundle_result_path), f"Bundle was not created at location: {bundle_result_path}" + + # The editor flips the slash direction in some of the printouts + bundle_result_path_editor_separator = bundle_result_path.replace('\\', '/') + + expected_lines = [ + # A beginning of test printout can help debug where failures occur, if this line is missing + # then the Editor didn't launch, didn't run the Python test, or didn't pass in the right parameter + f'Bundle mode test running with path {bundles_folder}', + # These printouts happen in response to the loadbundles call, and verify this bundle is actually loaded + f"[CONSOLE] Executing console command 'loadbundles {bundles_folder}'", + f'(BundlingSystem) - Loading bundles from {bundles_folder} of type .pak', + f'(Archive) - Opening archive file {bundle_result_path_editor_separator}', + ] + unexpected_lines = [] + + timeout = 180 + halt_on_unexpected = False + test_directory = os.path.join(os.path.dirname(__file__)) + test_file = os.path.join(test_directory, 'bundle_mode_in_editor_tests.py') + editor.args.extend(['-NullRenderer', '-rhi=Null', "--skipWelcomeScreenDialog", + "--autotest_mode", "--runpythontest", test_file, "--runpythonargs", bundles_folder]) + + with editor.start(launch_ap=True): + editor_log_file = os.path.join(editor.workspace.paths.project_log(), 'Editor.log') + log_monitor = ly_test_tools.log.log_monitor.LogMonitor(editor, editor_log_file) + waiter.wait_for( + lambda: editor.is_alive(), + timeout, + exc=("Log file '{}' was never opened by another process.".format(editor_log_file)), + interval=1) + log_monitor.monitor_log_for_lines(expected_lines, unexpected_lines, halt_on_unexpected, timeout) + + # Delete the bundle created and used in this test + fs.delete([bundle_result_path], True, False) diff --git a/Tools/LyTestTools/ly_test_tools/launchers/platforms/base.py b/Tools/LyTestTools/ly_test_tools/launchers/platforms/base.py index d32be10562..c9458899b4 100755 --- a/Tools/LyTestTools/ly_test_tools/launchers/platforms/base.py +++ b/Tools/LyTestTools/ly_test_tools/launchers/platforms/base.py @@ -91,7 +91,7 @@ class Launcher(object): open(os.path.join(self.workspace.paths.project_log(), artifact), 'w').close() # clear it log.info(f"Clearing pre-existing artifact {artifact} from calling Launcher.setup()") except PermissionError: - log.warn(f'Unable to remove artifact: {artifact}, skipping.') + log.warning(f'Unable to remove artifact: {artifact}, skipping.') pass # In case this is the first run, we will create default logs to prevent the logmonitor from not finding the file From 8afd47950c788dfe5f6e317f3265fcef3a0e1c15 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Tue, 30 Nov 2021 12:01:04 -0800 Subject: [PATCH 35/47] Removing an extra new-line I added by accident Signed-off-by: Gene Walters --- .../Code/Source/Editor/MultiplayerEditorSystemComponent.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp index 259d544279..ec783808a2 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp @@ -6,7 +6,6 @@ * */ - #include #include #include From b3bf02a4d5e03f11b4bec5417d2c8c606fff7475 Mon Sep 17 00:00:00 2001 From: AMZN-nggieber <52797929+AMZN-nggieber@users.noreply.github.com> Date: Tue, 30 Nov 2021 13:13:42 -0800 Subject: [PATCH 36/47] Adds Warning Dialog When Following an External Link in Project Manager (#6003) Signed-off-by: Alex Peterson <26804013+AMZN-alexpete@users.noreply.github.com> --- .../Resources/ProjectManager.qss | 10 +- .../Source/ExternalLinkDialog.cpp | 98 +++++++++++++++++++ .../Source/ExternalLinkDialog.h | 28 ++++++ .../Source/GemCatalog/GemUninstallDialog.cpp | 2 +- .../Source/GemCatalog/GemUpdateDialog.cpp | 2 +- .../ProjectManager/Source/LinkWidget.cpp | 29 +++++- .../Source/ProjectManagerSettings.cpp | 7 +- .../Source/ProjectManagerSettings.h | 1 + .../project_manager_files.cmake | 2 + 9 files changed, 170 insertions(+), 9 deletions(-) create mode 100644 Code/Tools/ProjectManager/Source/ExternalLinkDialog.cpp create mode 100644 Code/Tools/ProjectManager/Source/ExternalLinkDialog.h diff --git a/Code/Tools/ProjectManager/Resources/ProjectManager.qss b/Code/Tools/ProjectManager/Resources/ProjectManager.qss index 426f409581..1fc808b72c 100644 --- a/Code/Tools/ProjectManager/Resources/ProjectManager.qss +++ b/Code/Tools/ProjectManager/Resources/ProjectManager.qss @@ -232,6 +232,11 @@ QTabBar::tab:focus { stop: 0 #555555, stop: 1.0 #777777); } +#dialogSubTitle { + font-size:14px; + font-weight:600; +} + #horizontalSeparatingLine { color: #666666; } @@ -604,11 +609,6 @@ QProgressBar::chunk { stop: 0 #951D1F, stop: 1.0 #C92724); } -#gemCatalogDialogSubTitle { - font-size:14px; - font-weight:600; -} - /************** Filter Tag widget **************/ #FilterTagWidgetTextLabel { diff --git a/Code/Tools/ProjectManager/Source/ExternalLinkDialog.cpp b/Code/Tools/ProjectManager/Source/ExternalLinkDialog.cpp new file mode 100644 index 0000000000..122a5cbf5a --- /dev/null +++ b/Code/Tools/ProjectManager/Source/ExternalLinkDialog.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace O3DE::ProjectManager +{ + ExternalLinkDialog::ExternalLinkDialog(const QUrl& url, QWidget* parent) + : QDialog(parent) + { + setWindowTitle(tr("Leaving O3DE")); + setObjectName("ExternalLinkDialog"); + setAttribute(Qt::WA_DeleteOnClose); + setModal(true); + + QHBoxLayout* hLayout = new QHBoxLayout(); + hLayout->setMargin(30); + hLayout->setAlignment(Qt::AlignTop); + setLayout(hLayout); + + QVBoxLayout* warningLayout = new QVBoxLayout(); + warningLayout->setMargin(0); + warningLayout->setAlignment(Qt::AlignTop); + hLayout->addLayout(warningLayout); + + QLabel* warningIcon = new QLabel(this); + warningIcon->setPixmap(QIcon(":/Warning.svg").pixmap(32, 32)); + warningLayout->addWidget(warningIcon); + + warningLayout->addStretch(); + + QVBoxLayout* layout = new QVBoxLayout(); + layout->setMargin(0); + layout->setAlignment(Qt::AlignTop); + hLayout->addLayout(layout); + + // Body + QLabel* subTitleLabel = new QLabel(tr("You are about to leave O3DE Project Manager to visit an external link.")); + subTitleLabel->setObjectName("dialogSubTitle"); + layout->addWidget(subTitleLabel); + + layout->addSpacing(10); + + QLabel* bodyLabel = new QLabel(tr("If you trust this source, you can proceed to this link, or click \"Cancel\" to return.")); + layout->addWidget(bodyLabel); + + // Don't actually set linkUrl we are just using LinkLabel superficially here + LinkLabel* linkLabel = new LinkLabel(url.toString(), {}, 12); + layout->addWidget(linkLabel); + + layout->addSpacing(40); + + QCheckBox* skipDialogCheckbox = new QCheckBox(tr("Do not show this again")); + layout->addWidget(skipDialogCheckbox); + connect(skipDialogCheckbox, &QCheckBox::stateChanged, this, &ExternalLinkDialog::SetSkipDialogSetting); + + // Buttons + QDialogButtonBox* dialogButtons = new QDialogButtonBox(); + dialogButtons->setObjectName("footer"); + layout->addWidget(dialogButtons); + + QPushButton* cancelButton = dialogButtons->addButton(tr("Cancel"), QDialogButtonBox::RejectRole); + cancelButton->setProperty("secondary", true); + QPushButton* acceptButton = dialogButtons->addButton(tr("Proceed"), QDialogButtonBox::ApplyRole); + + connect(cancelButton, &QPushButton::clicked, this, &QDialog::reject); + connect(acceptButton, &QPushButton::clicked, this, &QDialog::accept); + } + + void ExternalLinkDialog::SetSkipDialogSetting(bool state) + { + auto settingsRegistry = AZ::SettingsRegistry::Get(); + if (settingsRegistry) + { + QString settingsKey = GetExternalLinkWarningKey(); + settingsRegistry->Set(settingsKey.toStdString().c_str(), state); + SaveProjectManagerSettings(); + } + } +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ExternalLinkDialog.h b/Code/Tools/ProjectManager/Source/ExternalLinkDialog.h new file mode 100644 index 0000000000..45d391e64e --- /dev/null +++ b/Code/Tools/ProjectManager/Source/ExternalLinkDialog.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#if !defined(Q_MOC_RUN) +#include +#endif + +namespace O3DE::ProjectManager +{ + class ExternalLinkDialog + : public QDialog + { + Q_OBJECT // AUTOMOC + public: + explicit ExternalLinkDialog(const QUrl& url, QWidget* parent = nullptr); + ~ExternalLinkDialog() = default; + + private slots: + void SetSkipDialogSetting(bool state); + }; +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemUninstallDialog.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemUninstallDialog.cpp index 1408e29b6d..679d9c576f 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemUninstallDialog.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemUninstallDialog.cpp @@ -31,7 +31,7 @@ namespace O3DE::ProjectManager // Body QLabel* subTitleLabel = new QLabel(tr("Are you sure you want to uninstall %1?").arg(gemName)); - subTitleLabel->setObjectName("gemCatalogDialogSubTitle"); + subTitleLabel->setObjectName("dialogSubTitle"); layout->addWidget(subTitleLabel); layout->addSpacing(10); diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemUpdateDialog.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemUpdateDialog.cpp index 82d205aab5..d973dd3749 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemUpdateDialog.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemUpdateDialog.cpp @@ -32,7 +32,7 @@ namespace O3DE::ProjectManager // Body QLabel* subTitleLabel = new QLabel(tr("%1 to the latest version of %2?").arg( updateAvaliable ? tr("Update") : tr("Force update"), gemName)); - subTitleLabel->setObjectName("gemCatalogDialogSubTitle"); + subTitleLabel->setObjectName("dialogSubTitle"); layout->addWidget(subTitleLabel); layout->addSpacing(10); diff --git a/Code/Tools/ProjectManager/Source/LinkWidget.cpp b/Code/Tools/ProjectManager/Source/LinkWidget.cpp index 9c8c78ed37..f25e38db67 100644 --- a/Code/Tools/ProjectManager/Source/LinkWidget.cpp +++ b/Code/Tools/ProjectManager/Source/LinkWidget.cpp @@ -7,6 +7,11 @@ */ #include +#include +#include + +#include + #include #include #include @@ -26,7 +31,29 @@ namespace O3DE::ProjectManager { if (m_url.isValid()) { - QDesktopServices::openUrl(m_url); + // Check if user request not to be shown external link warning dialog + bool skipDialog = false; + auto settingsRegistry = AZ::SettingsRegistry::Get(); + + if (settingsRegistry) + { + QString settingsKey = GetExternalLinkWarningKey(); + settingsRegistry->Get(skipDialog, settingsKey.toStdString().c_str()); + } + + if (!skipDialog) + { + // Style does not apply if LinkLabel is parent so use parentWidget as parent instead + ExternalLinkDialog* linkDialog = new ExternalLinkDialog(m_url.toString(), parentWidget()); + if (linkDialog->exec() == QDialog::Accepted) + { + QDesktopServices::openUrl(m_url); + } + } + else + { + QDesktopServices::openUrl(m_url); + } } emit clicked(); diff --git a/Code/Tools/ProjectManager/Source/ProjectManagerSettings.cpp b/Code/Tools/ProjectManager/Source/ProjectManagerSettings.cpp index 3049a6d70c..66480aab3e 100644 --- a/Code/Tools/ProjectManager/Source/ProjectManagerSettings.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectManagerSettings.cpp @@ -6,7 +6,7 @@ * */ -#include "ProjectManagerSettings.h" +#include #include #include @@ -51,4 +51,9 @@ namespace O3DE::ProjectManager { return QString("%1/Projects/%2/BuiltSuccessfully").arg(ProjectManagerKeyPrefix).arg(projectName); } + + QString GetExternalLinkWarningKey() + { + return QString("%1/SkipExternalLinkWarning").arg(ProjectManagerKeyPrefix); + } } diff --git a/Code/Tools/ProjectManager/Source/ProjectManagerSettings.h b/Code/Tools/ProjectManager/Source/ProjectManagerSettings.h index 3454909062..93cfbc5ceb 100644 --- a/Code/Tools/ProjectManager/Source/ProjectManagerSettings.h +++ b/Code/Tools/ProjectManager/Source/ProjectManagerSettings.h @@ -18,4 +18,5 @@ namespace O3DE::ProjectManager void SaveProjectManagerSettings(); QString GetProjectBuiltSuccessfullyKey(const QString& projectName); + QString GetExternalLinkWarningKey(); } diff --git a/Code/Tools/ProjectManager/project_manager_files.cmake b/Code/Tools/ProjectManager/project_manager_files.cmake index 43c11edacc..468e8dcbc5 100644 --- a/Code/Tools/ProjectManager/project_manager_files.cmake +++ b/Code/Tools/ProjectManager/project_manager_files.cmake @@ -78,6 +78,8 @@ set(FILES Source/TagWidget.cpp Source/TemplateButtonWidget.h Source/TemplateButtonWidget.cpp + Source/ExternalLinkDialog.h + Source/ExternalLinkDialog.cpp Source/GemCatalog/GemCatalogHeaderWidget.h Source/GemCatalog/GemCatalogHeaderWidget.cpp Source/GemCatalog/GemCatalogScreen.h From b7f051fb9aea28ed973eab3fdd9a60f18d2d4581 Mon Sep 17 00:00:00 2001 From: amzn-mike <80125227+amzn-mike@users.noreply.github.com> Date: Tue, 30 Nov 2021 15:44:20 -0600 Subject: [PATCH 37/47] Procedural Prefabs - Add mesh modifier support (#5894) * Clean up error output Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Add mesh modifiers to scene_data.py Add example usage of modifiers to scene_mesh_to_prefab.py Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Add type hints, cleanup dict creation, fix variable naming Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Add documentation Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Rename DefaultOrValue to __default_or_value Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> --- .../Editor/Scripts/scene_mesh_to_prefab.py | 14 +- .../Editor/Scripts/scene_api/scene_data.py | 174 ++++++++++++++++-- 2 files changed, 164 insertions(+), 24 deletions(-) diff --git a/AutomatedTesting/Editor/Scripts/scene_mesh_to_prefab.py b/AutomatedTesting/Editor/Scripts/scene_mesh_to_prefab.py index e832b1f82b..7b9349e270 100644 --- a/AutomatedTesting/Editor/Scripts/scene_mesh_to_prefab.py +++ b/AutomatedTesting/Editor/Scripts/scene_mesh_to_prefab.py @@ -5,7 +5,7 @@ # SPDX-License-Identifier: Apache-2.0 OR MIT # # -import os, traceback, binascii, sys, json, pathlib +import os, traceback, binascii, sys, json, pathlib, logging import azlmbr.math import azlmbr.bus @@ -15,9 +15,9 @@ import azlmbr.bus def log_exception_traceback(): - exc_type, exc_value, exc_tb = sys.exc_info() - data = traceback.format_exception(exc_type, exc_value, exc_tb) - print(str(data)) + data = traceback.format_exc() + logger = logging.getLogger('python') + logger.error(data) def get_mesh_node_names(sceneGraph): import azlmbr.scene as sceneApi @@ -114,12 +114,18 @@ def update_manifest(scene): mesh_group['id'] = '{' + str(uuid.uuid5(uuid.NAMESPACE_DNS, source_filename_only + mesh_path)) + '}' # Set our current node as the only node that is included in this MeshGroup scene_manifest.mesh_group_select_node(mesh_group, mesh_path) + scene_manifest.mesh_group_add_comment(mesh_group, "Hello World") # Explicitly remove all other nodes to prevent implicit inclusions for node in all_node_paths: if node != mesh_path: scene_manifest.mesh_group_unselect_node(mesh_group, node) + scene_manifest.mesh_group_add_cloth_rule(mesh_group, mesh_path, "Col0", 1, "Col0", 2, "Col0", 2, 3) + scene_manifest.mesh_group_add_advanced_mesh_rule(mesh_group, True, False, True, "Col0") + scene_manifest.mesh_group_add_skin_rule(mesh_group, 3, 0.002) + scene_manifest.mesh_group_add_tangent_rule(mesh_group, 1, 0) + # Create an editor entity entity_id = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "CreateEditorReadyEntity", mesh_group_name) # Add an EditorMeshComponent to the entity diff --git a/Gems/PythonAssetBuilder/Editor/Scripts/scene_api/scene_data.py b/Gems/PythonAssetBuilder/Editor/Scripts/scene_api/scene_data.py index 2578efeae2..d105ecdb43 100755 --- a/Gems/PythonAssetBuilder/Editor/Scripts/scene_api/scene_data.py +++ b/Gems/PythonAssetBuilder/Editor/Scripts/scene_api/scene_data.py @@ -95,7 +95,7 @@ class SceneManifest(): def __init__(self): self.manifest = {'values': []} - def add_mesh_group(self, name) -> dict: + def add_mesh_group(self, name: str) -> dict: meshGroup = {} meshGroup['$type'] = '{07B356B7-3635-40B5-878A-FAC4EFD5AD86} MeshGroup' meshGroup['name'] = name @@ -104,7 +104,7 @@ class SceneManifest(): self.manifest['values'].append(meshGroup) return meshGroup - def add_prefab_group(self, name, id, json) -> dict: + def add_prefab_group(self, name: str, id: str, json: dict) -> dict: prefabGroup = {} prefabGroup['$type'] = '{99FE3C6F-5B55-4D8B-8013-2708010EC715} PrefabGroup' prefabGroup['name'] = name @@ -113,30 +113,164 @@ class SceneManifest(): self.manifest['values'].append(prefabGroup) return prefabGroup - def mesh_group_select_node(self, meshGroup, nodeName): - meshGroup['nodeSelectionList']['selectedNodes'].append(nodeName) + def mesh_group_select_node(self, mesh_group: dict, node_name: str) -> None: + mesh_group['nodeSelectionList']['selectedNodes'].append(node_name) - def mesh_group_unselect_node(self, meshGroup, nodeName): - meshGroup['nodeSelectionList']['unselectedNodes'].append(nodeName) + def mesh_group_unselect_node(self, mesh_group: dict, node_name: str) -> None: + mesh_group['nodeSelectionList']['unselectedNodes'].append(node_name) - def mesh_group_add_advanced_coordinate_system(self, meshGroup, originNodeName, translation, rotation, scale): - originRule = {} - originRule['$type'] = 'CoordinateSystemRule' - originRule['useAdvancedData'] = True - originRule['originNodeName'] = '' if originNodeName is None else originNodeName + def mesh_group_add_advanced_coordinate_system(self, mesh_group: dict, origin_node_name: str, translation: object, + rotation: object, scale: float) -> None: + origin_rule = { + '$type': 'CoordinateSystemRule', + 'useAdvancedData': True, + 'originNodeName': '' if origin_node_name is None else origin_node_name + } if translation is not None: - originRule['translation'] = translation + origin_rule['translation'] = translation if rotation is not None: - originRule['rotation'] = rotation + origin_rule['rotation'] = rotation if scale != 1.0: - originRule['scale'] = scale - meshGroup['rules']['rules'].append(originRule) + origin_rule['scale'] = scale + mesh_group['rules']['rules'].append(origin_rule) - def mesh_group_add_comment(self, meshGroup, comment): - commentRule = {} - commentRule['$type'] = 'CommentRule' - commentRule['comment'] = comment - meshGroup['rules']['rules'].append(commentRule) + def mesh_group_add_comment(self, mesh_group: dict, comment: str) -> None: + commentRule = { + '$type': 'CommentRule', + 'comment': comment + } + mesh_group['rules']['rules'].append(commentRule) + + def __default_or_value(self, val, default): + return default if val is None else val + + def mesh_group_add_cloth_rule(self, mesh_group: dict, cloth_node_name: str, + inverse_masses_stream_name: str, inverse_masses_channel: int, + motion_constraints_stream_name: str, motion_constraints_channel: int, + backstop_stream_name: str, backstop_offset_channel: int, + backstop_radius_channel: int) -> None: + """ + Adds a Cloth rule. 0 = Red, 1 = Green, 2 = Blue, 3 = Alpha + :param mesh_group: Mesh Group to add the cloth rule to + :param cloth_node_name: Name of the node that the rule applies to + :param inverse_masses_stream_name: Name of the color stream to use for inverse masses + :param inverse_masses_channel: Color channel (index) for inverse masses + :param motion_constraints_stream_name: Name of the color stream to use for motion constraints + :param motion_constraints_channel: Color channel (index) for motion constraints + :param backstop_stream_name: Name of the color stream to use for backstop + :param backstop_offset_channel: Color channel (index) for backstop offset value + :param backstop_radius_channel: Color chnanel (index) for backstop radius value + """ + cloth_rule = { + '$type': 'ClothRule', + 'meshNodeName': cloth_node_name, + 'inverseMassesStreamName': self.__default_or_value(inverse_masses_stream_name, 'Default: 1.0') + } + + if inverse_masses_channel is not None: + cloth_rule['inverseMassesChannel'] = inverse_masses_channel + cloth_rule['motionConstraintsStreamName'] = self.__default_or_value(motion_constraints_stream_name, 'Default: 1.0') + if motion_constraints_channel is not None: + cloth_rule['motionConstraintsChannel'] = motion_constraints_channel + cloth_rule['backstopStreamName'] = self.__default_or_value(backstop_stream_name, 'None') + if backstop_offset_channel is not None: + cloth_rule['backstopOffsetChannel'] = backstop_offset_channel + if backstop_radius_channel is not None: + cloth_rule['backstopRadiusChannel'] = backstop_radius_channel + mesh_group['rules']['rules'].append(cloth_rule) + + def mesh_group_add_lod_rule(self, mesh_group: dict) -> dict: + """ + Adds an LOD rule + :param mesh_group: Mesh Group to add the rule to + :return: LOD rule + """ + lod_rule = { + '$type': '{6E796AC8-1484-4909-860A-6D3F22A7346F} LodRule', + 'nodeSelectionList': [] + } + + mesh_group['rules']['rules'].append(lod_rule) + return lod_rule + + def lod_rule_add_lod(self, lod_rule: dict) -> dict: + """ + Adds an LOD level to the LOD rule. Nodes are added in order. The first node added represents LOD1, 2nd LOD2, etc + :param lod_rule: LOD rule to add the LOD level to + :return: LOD level + """ + lod = {'selectedNodes': [], 'unselectedNodes': []} + lod_rule['nodeSelectionList'].append(lod) + return lod + + def lod_select_node(self, lod: dict, selected_node: str) -> None: + """ + Adds a node as a selected node + :param lod: LOD level to add the node to + :param selected_node: Path of the node + """ + lod['selectedNodes'].append(selected_node) + + def lod_unselect_node(self, lod: dict, unselected_node: str) -> None: + """ + Adds a node as an unselected node + :param lod: LOD rule to add the node to + :param unselected_node: Path of the node + """ + lod['unselectedNodes'].append(unselected_node) + + def mesh_group_add_advanced_mesh_rule(self, mesh_group: dict, use_32bit_vertices: bool, merge_meshes: bool, + use_custom_normals: bool, + vertex_color_stream: str) -> None: + """ + Adds an Advanced Mesh rule + :param mesh_group: Mesh Group to add the rule to + :param use_32bit_vertices: False = 16bit vertex position precision. True = 32bit vertex position precision + :param merge_meshes: Merge all meshes into a single mesh + :param use_custom_normals: True = use normals from DCC tool. False = average normals + :param vertex_color_stream: Color stream name to use for Vertex Coloring + """ + rule = { + '$type': 'StaticMeshAdvancedRule', + 'use32bitVertices': self.__default_or_value(use_32bit_vertices, False), + 'mergeMeshes': self.__default_or_value(merge_meshes, True), + 'useCustomNormals': self.__default_or_value(use_custom_normals, True) + } + + if vertex_color_stream is not None: + rule['vertexColorStreamName'] = vertex_color_stream + + mesh_group['rules']['rules'].append(rule) + + def mesh_group_add_skin_rule(self, mesh_group: dict, max_weights_per_vertex: int, weight_threshold: float) -> None: + """ + Adds a Skin rule + :param mesh_group: Mesh Group to add the rule to + :param max_weights_per_vertex: Max number of joints that can influence a vertex + :param weight_threshold: Weight values below this value will be treated as 0 + """ + rule = { + '$type': 'SkinRule', + 'maxWeightsPerVertex': self.__default_or_value(max_weights_per_vertex, 4), + 'weightThreshold': self.__default_or_value(weight_threshold, 0.001) + } + + mesh_group['rules']['rules'].append(rule) + + def mesh_group_add_tangent_rule(self, mesh_group: dict, tangent_space: int, tspace_method: int) -> None: + """ + Adds a Tangent rule to control tangent space generation + :param mesh_group: Mesh Group to add the rule to + :param tangent_space: Tangent space source. 0 = Scene, 1 = MikkT Tangent Generation + :param tspace_method: MikkT Generation method. 0 = TSpace, 1 = TSpaceBasic + """ + rule = { + '$type': 'TangentsRule', + 'tangentSpace': self.__default_or_value(tangent_space, 1), + 'tSpaceMethod': self.__default_or_value(tspace_method, 0) + } + + mesh_group['rules']['rules'].append(rule) def export(self): return json.dumps(self.manifest) From 858885dca932e6bda964616dab852cfe358e87ee Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Tue, 30 Nov 2021 13:46:53 -0800 Subject: [PATCH 38/47] Removes all files from linux install (#6019) Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- cmake/Platform/Linux/Packaging/postrm.in | 5 ----- cmake/Platform/Linux/Packaging/prerm.in | 3 ++- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/cmake/Platform/Linux/Packaging/postrm.in b/cmake/Platform/Linux/Packaging/postrm.in index acda38bf1e..cd6f37abe4 100644 --- a/cmake/Platform/Linux/Packaging/postrm.in +++ b/cmake/Platform/Linux/Packaging/postrm.in @@ -8,8 +8,3 @@ # set -o errexit # exit on the first failure encountered - -{ - pushd @CPACK_PACKAGING_INSTALL_PREFIX@ - popd -} &> /dev/null # hide output diff --git a/cmake/Platform/Linux/Packaging/prerm.in b/cmake/Platform/Linux/Packaging/prerm.in index 5595d7010f..843f21da24 100644 --- a/cmake/Platform/Linux/Packaging/prerm.in +++ b/cmake/Platform/Linux/Packaging/prerm.in @@ -19,5 +19,6 @@ set -o errexit # exit on the first failure encountered pushd @CPACK_PACKAGING_INSTALL_PREFIX@ # delete python downloads rm -rf python/downloaded_packages python/runtime - popd + find . -type d -name *.egg-info -prune -exec rm -rf {} \; + popd } &> /dev/null # hide output From 530bcb9428dc0e898f3392c3e1eac1947ed77da2 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Tue, 30 Nov 2021 14:17:02 -0800 Subject: [PATCH 39/47] //! for code comments autogen Signed-off-by: Gene Walters --- .../AzFramework/Process/ProcessCommunicatorTracePrinter.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.h b/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.h index 8b84c4c28d..5e14fa290d 100644 --- a/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.h +++ b/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.h @@ -18,13 +18,13 @@ public: ProcessCommunicatorTracePrinter(AzFramework::ProcessCommunicator* communicator, const char* window); ~ProcessCommunicatorTracePrinter(); - // Call this periodically to drain the buffers and write them. + //! Call this periodically to drain the buffers and write them. void Pump(); - // Drains the buffer into the string that's being built, then traces the string when it hits a newline. + //! Drains the buffer into the string that's being built, then traces the string when it hits a newline. void ParseDataBuffer(AZ::u32 readSize, bool isFromStdErr); - // Prints the current buffer to AZ_Error or AZ_TracePrintf so that it can be picked up by AZ::Debug::Trace + //! Prints the current buffer to AZ_Error or AZ_TracePrintf so that it can be picked up by AZ::Debug::Trace void WriteCurrentString(bool isFromStdError); private: From fb6e6e339fe8777bc0304b33d60098ac87f11534 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Tue, 30 Nov 2021 15:07:57 -0800 Subject: [PATCH 40/47] Add CRC validator (#5857) * Adds crc validation checks Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Fixes invalid CRCs Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Changes test to smoke suite Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * excludes some test data from the validator Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * uses pathlib instead of os.path Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * fixes wrong path to test scripts Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Escape not needed Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- Code/Framework/AzCore/AzCore/Math/Crc.h | 4 +- .../AzToolsFramework/Viewport/ActionBus.h | 10 ++-- .../Code/Source/AtomBridgeSystemComponent.cpp | 4 +- .../AssetCollectionAsyncLoaderTestComponent.h | 4 +- ...tomViewportDisplayIconsSystemComponent.cpp | 2 +- ...clusionCullingPlaneComponentController.cpp | 4 +- .../Source/Editor/EditorSystemComponent.h | 4 +- .../NodePalette/InputOutputNodePaletteItem.h | 2 +- .../NodePalette/ModuleNodePaletteItem.h | 2 +- .../NodePalette/StandardNodePaletteItem.h | 2 +- .../Shape/EditorTubeShapeComponentMode.cpp | 2 +- .../PropertyHandlerUiParticleColorKeyframe.h | 2 +- .../PropertyHandlerUiParticleFloatKeyframe.h | 2 +- .../LyShine/Code/Source/LyShineLoadScreen.cpp | 4 +- .../Code/Editor/ColliderComponentMode.cpp | 8 ++-- .../Code/Source/EditorSystemComponent.h | 2 +- .../EditorWhiteBoxDefaultMode.cpp | 4 +- scripts/commit_validation/CMakeLists.txt | 6 +-- .../commit_validation/commit_validation.py | 2 + .../tests/validators/test_crc_validator.py | 47 ++++++++++++++++++ .../validators/crc_validator.py | 48 +++++++++++++++++++ 21 files changed, 130 insertions(+), 35 deletions(-) create mode 100644 scripts/commit_validation/commit_validation/tests/validators/test_crc_validator.py create mode 100644 scripts/commit_validation/commit_validation/validators/crc_validator.py diff --git a/Code/Framework/AzCore/AzCore/Math/Crc.h b/Code/Framework/AzCore/AzCore/Math/Crc.h index 9ba2a83139..c71339e92e 100644 --- a/Code/Framework/AzCore/AzCore/Math/Crc.h +++ b/Code/Framework/AzCore/AzCore/Math/Crc.h @@ -16,7 +16,7 @@ // // When AZ_CRC("My string") is used by default it will map to AZ::Crc32("My string"). // We do have a pro-processor program which will precompute the crc for you and -// transform that macro to AZ_CRC("My string",0xabcdef00) this will expand to just 0xabcdef00. +// transform that macro to AZ_CRC("My string", 0x18fbd270) this will expand to just 0x18fbd270. // This will remove completely the "My string" from your executable, it will add it to a database and so on. // WHen you want to update the string, just change the string. // If you don't run the precompile step the code should still run fine, except it will be slower, @@ -24,7 +24,7 @@ // a constant expression. // For example // switch(id) { -// case AZ_CRC("My string",0xabcdef00): {} break; // this will compile fine +// case AZ_CRC("My string",0x18fbd270): {} break; // this will compile fine // case AZ_CRC("My string"): {} break; // this will cause "error C2051: case expression not constant" // } // So it's you choice what you do, depending on your needs. diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ActionBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ActionBus.h index 4dde676511..c0562025b6 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ActionBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ActionBus.h @@ -23,11 +23,11 @@ namespace AzToolsFramework /// @name Reverse URLs. /// Used to identify common actions and override them when necessary. //@{ - static const AZ::Crc32 s_backAction = AZ_CRC("com.o3de.action.common.back", 0xd772a2af); - static const AZ::Crc32 s_deleteAction = AZ_CRC("com.o3de.action.common.delete", 0x5731f6cb); - static const AZ::Crc32 s_duplicateAction = AZ_CRC("com.o3de.action.common.duplicate", 0x08ccf461); - static const AZ::Crc32 s_nextComponentMode = AZ_CRC("com.o3de.action.common.nextComponentMode", 0xcc26094f); - static const AZ::Crc32 s_previousComponentMode = AZ_CRC("com.o3de.action.common.previousComponentMode", 0x0d18ff39); + static const AZ::Crc32 s_backAction = AZ_CRC("com.o3de.action.common.back", 0x80c3030f); + static const AZ::Crc32 s_deleteAction = AZ_CRC("com.o3de.action.common.delete", 0x58e78eed); + static const AZ::Crc32 s_duplicateAction = AZ_CRC("com.o3de.action.common.duplicate", 0xbc5a4a23); + static const AZ::Crc32 s_nextComponentMode = AZ_CRC("com.o3de.action.common.nextComponentMode", 0xf9aca3a8); + static const AZ::Crc32 s_previousComponentMode = AZ_CRC("com.o3de.action.common.previousComponentMode", 0x0580eaec); //@} /// Specific Action properties to be sent to a type implementing diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomBridgeSystemComponent.cpp b/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomBridgeSystemComponent.cpp index d822b16486..7a980f9824 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomBridgeSystemComponent.cpp +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomBridgeSystemComponent.cpp @@ -67,12 +67,12 @@ namespace AZ void AtomBridgeSystemComponent::GetProvidedServices(ComponentDescriptor::DependencyArrayType& provided) { - provided.push_back(AZ_CRC("AtomBridgeService", 0xdb816a99)); + provided.push_back(AZ_CRC("AtomBridgeService", 0x92d990b5)); } void AtomBridgeSystemComponent::GetIncompatibleServices(ComponentDescriptor::DependencyArrayType& incompatible) { - incompatible.push_back(AZ_CRC("AtomBridgeService", 0xdb816a99)); + incompatible.push_back(AZ_CRC("AtomBridgeService", 0x92d990b5)); } void AtomBridgeSystemComponent::GetRequiredServices(ComponentDescriptor::DependencyArrayType& required) diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Editor/AssetCollectionAsyncLoaderTestComponent.h b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Editor/AssetCollectionAsyncLoaderTestComponent.h index 9ab25741af..3af1ad8907 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Editor/AssetCollectionAsyncLoaderTestComponent.h +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Editor/AssetCollectionAsyncLoaderTestComponent.h @@ -109,12 +109,12 @@ namespace AZ static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services) { - services.push_back(AZ_CRC("AssetCollectionAsyncLoaderTest", 0xdd5ab934)); + services.push_back(AZ_CRC("AssetCollectionAsyncLoaderTest", 0x66d04369)); } static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services) { - services.push_back(AZ_CRC("AssetCollectionAsyncLoaderTest", 0xdd5ab934)); + services.push_back(AZ_CRC("AssetCollectionAsyncLoaderTest", 0x66d04369)); } static void Reflect(AZ::ReflectContext* context); diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayIcons/Code/Source/AtomViewportDisplayIconsSystemComponent.cpp b/Gems/AtomLyIntegration/AtomViewportDisplayIcons/Code/Source/AtomViewportDisplayIconsSystemComponent.cpp index 38679432ea..fa7a0cf2bf 100644 --- a/Gems/AtomLyIntegration/AtomViewportDisplayIcons/Code/Source/AtomViewportDisplayIconsSystemComponent.cpp +++ b/Gems/AtomLyIntegration/AtomViewportDisplayIcons/Code/Source/AtomViewportDisplayIconsSystemComponent.cpp @@ -73,7 +73,7 @@ namespace AZ::Render void AtomViewportDisplayIconsSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) { required.push_back(AZ_CRC("RPISystem", 0xf2add773)); - required.push_back(AZ_CRC("AtomBridgeService", 0xdb816a99)); + required.push_back(AZ_CRC("AtomBridgeService", 0x92d990b5)); } void AtomViewportDisplayIconsSystemComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/OcclusionCullingPlane/OcclusionCullingPlaneComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/OcclusionCullingPlane/OcclusionCullingPlaneComponentController.cpp index 4c78a0afd7..4addbde3ef 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/OcclusionCullingPlane/OcclusionCullingPlaneComponentController.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/OcclusionCullingPlane/OcclusionCullingPlaneComponentController.cpp @@ -59,12 +59,12 @@ namespace AZ void OcclusionCullingPlaneComponentController::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { - provided.push_back(AZ_CRC("OcclusionCullingPlaneService", 0x9123f33d)); + provided.push_back(AZ_CRC("OcclusionCullingPlaneService", 0x7d036c2e)); } void OcclusionCullingPlaneComponentController::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { - incompatible.push_back(AZ_CRC("OcclusionCullingPlaneService", 0x9123f33d)); + incompatible.push_back(AZ_CRC("OcclusionCullingPlaneService", 0x7d036c2e)); } void OcclusionCullingPlaneComponentController::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) diff --git a/Gems/Blast/Code/Source/Editor/EditorSystemComponent.h b/Gems/Blast/Code/Source/Editor/EditorSystemComponent.h index 31daae1a18..fe17bfaac0 100644 --- a/Gems/Blast/Code/Source/Editor/EditorSystemComponent.h +++ b/Gems/Blast/Code/Source/Editor/EditorSystemComponent.h @@ -31,12 +31,12 @@ namespace Blast private: static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { - provided.push_back(AZ_CRC("BlastEditorService", 0x0a61cda5)); + provided.push_back(AZ_CRC("BlastEditorService", 0xeddfed0d)); } static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) { - required.push_back(AZ_CRC("BlastService", 0x75beae2d)); + required.push_back(AZ_CRC("BlastService", 0x46927a9f)); } AZStd::unique_ptr m_editorBlastChunksAssetHandler; diff --git a/Gems/GraphModel/Code/Include/GraphModel/Integration/NodePalette/InputOutputNodePaletteItem.h b/Gems/GraphModel/Code/Include/GraphModel/Integration/NodePalette/InputOutputNodePaletteItem.h index 15f308c4d2..99a32d965b 100644 --- a/Gems/GraphModel/Code/Include/GraphModel/Integration/NodePalette/InputOutputNodePaletteItem.h +++ b/Gems/GraphModel/Code/Include/GraphModel/Integration/NodePalette/InputOutputNodePaletteItem.h @@ -33,7 +33,7 @@ namespace GraphModelIntegration //! Constructor //! \param nodeName Name of the node that will show up in the Palette - //! \param editorId Unique name of the client system editor (ex: AZ_CRC("ShaderCanvas", 0xa6d1a85a)) + //! \param editorId Unique name of the client system editor (ex: AZ_CRC("ShaderCanvas", 0x0a1dff96)) //! \param dataType The type of data that the InputGraphNode or OutputGraphNode will represent InputOutputNodePaletteItem(AZStd::string_view nodeName, GraphCanvas::EditorId editorId, GraphModel::DataTypePtr dataType) : DraggableNodePaletteTreeItem(nodeName, editorId) diff --git a/Gems/GraphModel/Code/Include/GraphModel/Integration/NodePalette/ModuleNodePaletteItem.h b/Gems/GraphModel/Code/Include/GraphModel/Integration/NodePalette/ModuleNodePaletteItem.h index a0121ac035..51e1fca55b 100644 --- a/Gems/GraphModel/Code/Include/GraphModel/Integration/NodePalette/ModuleNodePaletteItem.h +++ b/Gems/GraphModel/Code/Include/GraphModel/Integration/NodePalette/ModuleNodePaletteItem.h @@ -95,7 +95,7 @@ namespace GraphModelIntegration AZ_CLASS_ALLOCATOR(ModuleNodePaletteItem, AZ::SystemAllocator, 0); //! Constructor - //! \param editorId Unique name of the client system editor (ex: AZ_CRC("ShaderCanvas", 0xa6d1a85a)) + //! \param editorId Unique name of the client system editor (ex: AZ_CRC("ShaderCanvas", 0x0a1dff96)) //! \param sourceFileId The unique id for the module node graph source file. //! \param sourceFilePath The path to the module node graph source file. This will be used for node naming and debug output. ModuleNodePaletteItem(GraphCanvas::EditorId editorId, AZ::Uuid sourceFileId, AZStd::string_view sourceFilePath) diff --git a/Gems/GraphModel/Code/Include/GraphModel/Integration/NodePalette/StandardNodePaletteItem.h b/Gems/GraphModel/Code/Include/GraphModel/Integration/NodePalette/StandardNodePaletteItem.h index 5d2914d7ad..e38e3b7478 100644 --- a/Gems/GraphModel/Code/Include/GraphModel/Integration/NodePalette/StandardNodePaletteItem.h +++ b/Gems/GraphModel/Code/Include/GraphModel/Integration/NodePalette/StandardNodePaletteItem.h @@ -34,7 +34,7 @@ namespace GraphModelIntegration //! Constructor //! \param nodeName Name of the node that will show up in the Palette - //! \param editorId Unique name of the client system editor (ex: AZ_CRC("ShaderCanvas", 0xa6d1a85a)) + //! \param editorId Unique name of the client system editor (ex: AZ_CRC("ShaderCanvas", 0x0a1dff96)) StandardNodePaletteItem(AZStd::string_view nodeName, GraphCanvas::EditorId editorId) : DraggableNodePaletteTreeItem(nodeName, editorId) { diff --git a/Gems/LmbrCentral/Code/Source/Shape/EditorTubeShapeComponentMode.cpp b/Gems/LmbrCentral/Code/Source/Shape/EditorTubeShapeComponentMode.cpp index 340752251d..fd91c84c12 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/EditorTubeShapeComponentMode.cpp +++ b/Gems/LmbrCentral/Code/Source/Shape/EditorTubeShapeComponentMode.cpp @@ -22,7 +22,7 @@ namespace LmbrCentral { AZ_CLASS_ALLOCATOR_IMPL(EditorTubeShapeComponentMode, AZ::SystemAllocator, 0) - static const AZ::Crc32 s_resetVariableRadii = AZ_CRC("com.o3de.action.tubeshape.reset_radii", 0x0f2ef8e2); + static const AZ::Crc32 s_resetVariableRadii = AZ_CRC("com.o3de.action.tubeshape.reset_radii", 0xa987659c); static const char* const s_resetRadiiTitle = "Reset Radii"; static const char* const s_resetRadiiDesc = "Reset all variable radius values to the default"; diff --git a/Gems/LyShine/Code/Editor/PropertyHandlerUiParticleColorKeyframe.h b/Gems/LyShine/Code/Editor/PropertyHandlerUiParticleColorKeyframe.h index 9fdc8e61c4..639d042b34 100644 --- a/Gems/LyShine/Code/Editor/PropertyHandlerUiParticleColorKeyframe.h +++ b/Gems/LyShine/Code/Editor/PropertyHandlerUiParticleColorKeyframe.h @@ -50,7 +50,7 @@ class PropertyHandlerUiParticleColorKeyframe public: AZ_CLASS_ALLOCATOR(PropertyHandlerUiParticleColorKeyframe, AZ::SystemAllocator, 0); - AZ::u32 GetHandlerName(void) const override { return AZ_CRC("UiParticleColorKeyframeCtrl", 0x8cb3a9f1); } + AZ::u32 GetHandlerName(void) const override { return AZ_CRC("UiParticleColorKeyframeCtrl", 0xe3ef28b6); } bool IsDefaultHandler() const override { return true; } QWidget* CreateGUI(QWidget* pParent) override; void ConsumeAttribute(PropertyUiParticleColorKeyframeCtrl* GUI, AZ::u32 attrib, AzToolsFramework::PropertyAttributeReader* attrValue, const char* debugName) override; diff --git a/Gems/LyShine/Code/Editor/PropertyHandlerUiParticleFloatKeyframe.h b/Gems/LyShine/Code/Editor/PropertyHandlerUiParticleFloatKeyframe.h index 39e5dd27c2..df3983dc3e 100644 --- a/Gems/LyShine/Code/Editor/PropertyHandlerUiParticleFloatKeyframe.h +++ b/Gems/LyShine/Code/Editor/PropertyHandlerUiParticleFloatKeyframe.h @@ -50,7 +50,7 @@ class PropertyHandlerUiParticleFloatKeyframe public: AZ_CLASS_ALLOCATOR(PropertyHandlerUiParticleFloatKeyframe, AZ::SystemAllocator, 0); - AZ::u32 GetHandlerName(void) const override { return AZ_CRC("UiParticleFloatKeyframeCtrl", 0xba9359a2); } + AZ::u32 GetHandlerName(void) const override { return AZ_CRC("UiParticleFloatKeyframeCtrl", 0x448a90ec); } bool IsDefaultHandler() const override { return true; } QWidget* CreateGUI(QWidget* pParent) override; void ConsumeAttribute(PropertyUiParticleFloatKeyframeCtrl* GUI, AZ::u32 attrib, AzToolsFramework::PropertyAttributeReader* attrValue, const char* debugName) override; diff --git a/Gems/LyShine/Code/Source/LyShineLoadScreen.cpp b/Gems/LyShine/Code/Source/LyShineLoadScreen.cpp index 279c0527bd..831bdb048a 100644 --- a/Gems/LyShine/Code/Source/LyShineLoadScreen.cpp +++ b/Gems/LyShine/Code/Source/LyShineLoadScreen.cpp @@ -31,12 +31,12 @@ namespace LyShine void LyShineLoadScreenComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { - provided.emplace_back(AZ_CRC("LyShineLoadScreenService", 0xBB5EAB17)); + provided.emplace_back(AZ_CRC("LyShineLoadScreenService", 0xbb5eab17)); } void LyShineLoadScreenComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { - incompatible.emplace_back(AZ_CRC("LyShineLoadScreenService", 0xBB5EAB17)); + incompatible.emplace_back(AZ_CRC("LyShineLoadScreenService", 0xbb5eab17)); } void LyShineLoadScreenComponent::Init() diff --git a/Gems/PhysX/Code/Editor/ColliderComponentMode.cpp b/Gems/PhysX/Code/Editor/ColliderComponentMode.cpp index e5e75d88a3..b91b3e5bb9 100644 --- a/Gems/PhysX/Code/Editor/ColliderComponentMode.cpp +++ b/Gems/PhysX/Code/Editor/ColliderComponentMode.cpp @@ -27,10 +27,10 @@ namespace PhysX namespace { //! Uri's for shortcut actions. - const AZ::Crc32 SetDimensionsSubModeActionUri = AZ_CRC("com.o3de.action.physx.setdimensionssubmode", 0x77b70dd6); - const AZ::Crc32 SetOffsetSubModeActionUri = AZ_CRC("com.o3de.action.physx.setoffsetsubmode", 0xc06132e5); - const AZ::Crc32 SetRotationSubModeActionUri = AZ_CRC("com.o3de.action.physx.setrotationsubmode", 0xc4225918); - const AZ::Crc32 ResetSubModeActionUri = AZ_CRC("com.o3de.action.physx.resetsubmode", 0xb70b120e); + const AZ::Crc32 SetDimensionsSubModeActionUri = AZ_CRC("com.o3de.action.physx.setdimensionssubmode", 0x508b1781); + const AZ::Crc32 SetOffsetSubModeActionUri = AZ_CRC("com.o3de.action.physx.setoffsetsubmode", 0x777ac743); + const AZ::Crc32 SetRotationSubModeActionUri = AZ_CRC("com.o3de.action.physx.setrotationsubmode", 0xf1a8f3ff); + const AZ::Crc32 ResetSubModeActionUri = AZ_CRC("com.o3de.action.physx.resetsubmode", 0x599d1594); } // namespace AZ_CLASS_ALLOCATOR_IMPL(ColliderComponentMode, AZ::SystemAllocator, 0); diff --git a/Gems/PhysXDebug/Code/Source/EditorSystemComponent.h b/Gems/PhysXDebug/Code/Source/EditorSystemComponent.h index 14f37ef01e..fc0d60640c 100644 --- a/Gems/PhysXDebug/Code/Source/EditorSystemComponent.h +++ b/Gems/PhysXDebug/Code/Source/EditorSystemComponent.h @@ -32,7 +32,7 @@ namespace PhysXDebug static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { - provided.push_back(AZ_CRC("PhysXDebugEditorService", 0xe3dde7d8)); + provided.push_back(AZ_CRC("PhysXDebugEditorService", 0xf8611967)); } static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) diff --git a/Gems/WhiteBox/Code/Source/SubComponentModes/EditorWhiteBoxDefaultMode.cpp b/Gems/WhiteBox/Code/Source/SubComponentModes/EditorWhiteBoxDefaultMode.cpp index 3d6d9a4c0a..608605be62 100644 --- a/Gems/WhiteBox/Code/Source/SubComponentModes/EditorWhiteBoxDefaultMode.cpp +++ b/Gems/WhiteBox/Code/Source/SubComponentModes/EditorWhiteBoxDefaultMode.cpp @@ -33,8 +33,8 @@ namespace WhiteBox AZ::Color, cl_whiteBoxVertexIndicatorColor, AZ::Color::CreateFromRgba(0, 0, 0, 102), nullptr, AZ::ConsoleFunctorFlags::Null, "The color of the vertex indicator"); - static const AZ::Crc32 HideEdge = AZ_CRC("com.o3de.action.whitebox.hide_edge", 0x6a60ae23); - static const AZ::Crc32 HideVertex = AZ_CRC("com.o3de.action.whitebox.hide_vertex", 0x4a4bd092); + static const AZ::Crc32 HideEdge = AZ_CRC("com.o3de.action.whitebox.hide_edge", 0x84f6a9b9); + static const AZ::Crc32 HideVertex = AZ_CRC("com.o3de.action.whitebox.hide_vertex", 0x5f81c937); static const char* const HideEdgeTitle = "Hide Edge"; static const char* const HideEdgeDesc = "Hide the selected edge to merge the two connected polygons"; diff --git a/scripts/commit_validation/CMakeLists.txt b/scripts/commit_validation/CMakeLists.txt index 6079515eb8..00e8506ef1 100644 --- a/scripts/commit_validation/CMakeLists.txt +++ b/scripts/commit_validation/CMakeLists.txt @@ -6,10 +6,8 @@ # # -# this ctest makes sure that the commit validation function -# also runs its tests during commit validation! ly_add_pytest( NAME test_commit_validation - PATH ${CMAKE_CURRENT_LIST_DIR} + PATH ${CMAKE_CURRENT_LIST_DIR}/commit_validation/tests + TEST_SUITE smoke ) - diff --git a/scripts/commit_validation/commit_validation/commit_validation.py b/scripts/commit_validation/commit_validation/commit_validation.py index 513244a735..be8fc4ce1e 100755 --- a/scripts/commit_validation/commit_validation/commit_validation.py +++ b/scripts/commit_validation/commit_validation/commit_validation.py @@ -181,4 +181,6 @@ EXCLUDED_VALIDATION_PATTERNS = [ 'restricted/*/Tools/*RemoteControl', '*/user/Cache/*', '*/user/log/*', + '*/user/log_test_1/*', + '*/user/log_test_2/*', ] diff --git a/scripts/commit_validation/commit_validation/tests/validators/test_crc_validator.py b/scripts/commit_validation/commit_validation/tests/validators/test_crc_validator.py new file mode 100644 index 0000000000..6fbe86ab29 --- /dev/null +++ b/scripts/commit_validation/commit_validation/tests/validators/test_crc_validator.py @@ -0,0 +1,47 @@ +# +# Copyright (c) Contributors to the Open 3D Engine Project. +# For complete copyright and license terms please see the LICENSE at the root of this distribution. +# +# SPDX-License-Identifier: Apache-2.0 OR MIT +# +# + +import unittest +from unittest.mock import patch, mock_open + +from commit_validation.tests.mocks.mock_commit import MockCommit +from commit_validation.validators.crc_validator import CrcValidator + + +class CrcValidatorTests(unittest.TestCase): + + @patch('builtins.open', mock_open(read_data='This file does not contain an AZ_CRC macro')) + def test_fileWithNoCrc_passes(self): + commit = MockCommit(files=['/someCppFile.cpp']) + error_list = [] + self.assertTrue(CrcValidator().run(commit, error_list)) + self.assertEqual(len(error_list), 0, f"Unexpected errors: {error_list}") + + @patch('builtins.open', mock_open(read_data='This file contains an invalid CRC macro AZ_CRC("My string", 0xabcdef00)')) + def test_fileWithInvalidCrc_fails(self): + commit = MockCommit(files=['/someCppFile.cpp']) + error_list = [] + self.assertFalse(CrcValidator().run(commit, error_list)) + self.assertNotEqual(len(error_list), 0, f"Errors were expected but none were returned.") + + @patch('builtins.open', mock_open(read_data='This file contains a valid CRC macro AZ_CRC("My string", 0x18fbd270)')) + def test_fileWithValidCrc_fails(self): + commit = MockCommit(files=['/someCppFile.cpp']) + error_list = [] + self.assertTrue(CrcValidator().run(commit, error_list)) + self.assertEqual(len(error_list), 0, f"Unexpected errors: {error_list}") + + @patch('builtins.open', mock_open(read_data='This file contains an invalid CRC macro AZ_CRC("My string", 0xabcdef00)')) + def test_fileExtensionIgnored_passes(self): + commit = MockCommit(files=['/someCppFile.somerandomextension']) + error_list = [] + self.assertTrue(CrcValidator().run(commit, error_list)) + self.assertEqual(len(error_list), 0, f"Unexpected errors: {error_list}") + +if __name__ == '__main__': + unittest.main() diff --git a/scripts/commit_validation/commit_validation/validators/crc_validator.py b/scripts/commit_validation/commit_validation/validators/crc_validator.py new file mode 100644 index 0000000000..db99d7b50b --- /dev/null +++ b/scripts/commit_validation/commit_validation/validators/crc_validator.py @@ -0,0 +1,48 @@ +# +# Copyright (c) Contributors to the Open 3D Engine Project. +# For complete copyright and license terms please see the LICENSE at the root of this distribution. +# +# SPDX-License-Identifier: Apache-2.0 OR MIT +# +# + +import binascii +import fnmatch +import pathlib +import re +from typing import Type, List + +from commit_validation.commit_validation import Commit, CommitValidator, SOURCE_FILE_EXTENSIONS, EXCLUDED_VALIDATION_PATTERNS, VERBOSE + +class CrcValidator(CommitValidator): + """A file-level validator that makes sure a file does not contain an invalid CRC""" + + def run(self, commit: Commit, errors: List[str]) -> bool: + for file_name in commit.get_files(): + for pattern in EXCLUDED_VALIDATION_PATTERNS: + if fnmatch.fnmatch(file_name, pattern): + if VERBOSE: print(f'{file_name}::{self.__class__.__name__} SKIPPED - Validation pattern excluded on path.') + break + else: + if pathlib.Path(file_name).suffix.lower() not in SOURCE_FILE_EXTENSIONS: + if VERBOSE: print(f'{file_name}::{self.__class__.__name__} SKIPPED - File excluded based on extension.') + continue + + with open(file_name, mode='r', encoding='utf8') as fh: + fileContents = fh.read() + matchesFound = re.findall(r'AZ_CRC\("([^"]+)",([^)]*)\)', fileContents) + for element in matchesFound: + stringInCode = element[0] + valueInCode = element[1].strip() + expectedValue = "{0:#0{1}x}".format(binascii.crc32(stringInCode.lower().encode('utf8')), 10) + if expectedValue != valueInCode: + error_message = str(f'{file_name}::{self.__class__.__name__} FAILED - Source file contains a CRC mismatch!\n' + f' AZ_CRC("{stringInCode}", {valueInCode}), expected value {expectedValue}') + if VERBOSE: print(error_message) + errors.append(error_message) + return (not errors) + + +def get_validator() -> Type[CrcValidator]: + """Returns the validator class for this module""" + return CrcValidator From 93ec5de5525ad573b203ae33ea671fe23b82c047 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Tue, 30 Nov 2021 15:09:20 -0800 Subject: [PATCH 41/47] Enables monolithic for ServerLauncher (#5883) Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- cmake/Monolithic.cmake | 1 - 1 file changed, 1 deletion(-) diff --git a/cmake/Monolithic.cmake b/cmake/Monolithic.cmake index 1e121c2b20..2310d8d0d7 100644 --- a/cmake/Monolithic.cmake +++ b/cmake/Monolithic.cmake @@ -16,7 +16,6 @@ if(LY_MONOLITHIC_GAME) ly_set(PAL_TRAIT_BUILD_HOST_TOOLS FALSE) ly_set(PAL_TRAIT_BUILD_HOST_GUI_TOOLS FALSE) ly_set(PAL_TRAIT_BUILD_TESTS_SUPPORTED FALSE) - ly_set(PAL_TRAIT_BUILD_SERVER_SUPPORTED FALSE) else() ly_set(PAL_TRAIT_MONOLITHIC_DRIVEN_LIBRARY_TYPE SHARED) ly_set(PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE GEM_MODULE) From 28096617941313ecce272038378a7ae3735cc885 Mon Sep 17 00:00:00 2001 From: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> Date: Tue, 30 Nov 2021 17:43:53 -0600 Subject: [PATCH 42/47] Xfailing 2 DynVeg tests that fail to create levels in AR (#6051) * Xfailing 2 DynVeg tests that fail to create levels in AR Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> * Adding xfail to one more test, and updating reason Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> --- .../largeworlds/dyn_veg/TestSuite_Main_Optimized.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py index d83f88cad2..2211c28060 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py @@ -148,6 +148,7 @@ class TestAutomation(EditorTestSuite): class test_SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlopes(EditorParallelTest): from .EditorScripts import SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlope as test_module + @pytest.mark.xfail(reason="Intermittently fails to create level") class test_DynamicSliceInstanceSpawner_Embedded_E2E_Editor(EditorSingleTest): from .EditorScripts import DynamicSliceInstanceSpawner_Embedded_E2E as test_module @@ -156,6 +157,7 @@ class TestAutomation(EditorTestSuite): file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")], True, True) + @pytest.mark.xfail(reason="Intermittently fails to create level") class test_DynamicSliceInstanceSpawner_External_E2E_Editor(EditorSingleTest): from .EditorScripts import DynamicSliceInstanceSpawner_External_E2E as test_module @@ -163,7 +165,8 @@ class TestAutomation(EditorTestSuite): def teardown(self, request, workspace, editor, editor_test_results, launcher_platform): file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")], True, True) - + + @pytest.mark.xfail(reason="Intermittently fails to create level") class test_LayerBlender_E2E_Editor(EditorSingleTest): from .EditorScripts import LayerBlender_E2E_Editor as test_module From 58be7c27edec0319cc76b22f5389e1f77cda398b Mon Sep 17 00:00:00 2001 From: Shirang Jia Date: Tue, 30 Nov 2021 16:46:03 -0800 Subject: [PATCH 43/47] Make scrubber/validator not depend on legacy packaging scripts (#6053) * Make validator not depend on legacy packaging scripts Signed-off-by: Shirang Jia * Remove unused glob_to_regex.py Signed-off-by: Shirang Jia * Remove unsued import path Signed-off-by: Shirang Jia --- scripts/build/package/glob_to_regex.py | 130 ------------------------- scripts/scrubbing/scrubbing_job.py | 29 ------ scripts/scrubbing/validator.py | 37 +++---- 3 files changed, 12 insertions(+), 184 deletions(-) delete mode 100755 scripts/build/package/glob_to_regex.py delete mode 100755 scripts/scrubbing/scrubbing_job.py diff --git a/scripts/build/package/glob_to_regex.py b/scripts/build/package/glob_to_regex.py deleted file mode 100755 index 53ad3d850d..0000000000 --- a/scripts/build/package/glob_to_regex.py +++ /dev/null @@ -1,130 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. -# For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# -from __future__ import absolute_import -import os -import re -import json -import sys -try: - import six -except ImportError: - import pip - pip.main(['install', 'six', '--ignore-installed', '-q']) - import six -from pathlib import Path - -this_file_path = os.path.dirname(os.path.realpath(__file__)) - -# resolve symlinks and eliminate ".." components -engine_root_path = Path(__file__).resolve().parents[3] - -def convert_glob_pattern_to_regex_pattern(glob_pattern): - # switch to forward slashes because way easier to pattern match against - pattern = re.sub(r'\\', r'/', glob_pattern) - - # Replace the dots and question marks - pattern = re.sub(r'\.', r'\\.', pattern) - pattern = re.sub(r'\?', r'.', pattern) - - # Handle the * vs ** expansions - pattern = re.sub(r'([^*])\*($|[^*])', r'\1[^/\\\\]*\2', pattern) - pattern = re.sub(r'\*\*/', r'(.*/)?', pattern) - pattern = re.sub(r'\*\*', r'.*', pattern) - - # replace the forward slashes with [/\\] so it works on PC/unix - pattern = re.sub(r'([^^])/', r'\1[/\\\\]', pattern) - return pattern - -# Convert the package json into a pair of regexes we can use to look for includes and excludes -def convert_glob_list_to_regex_list(filelist, prefix): - includes = [] - excludes = [] - for key, value in six.iteritems(filelist): - glob_pattern = os.path.join(prefix, key) - if isinstance(value, dict): - (sub_includes, sub_excludes) = convert_glob_list_to_regex_list(value, glob_pattern) - includes.extend(sub_includes) - excludes.extend(sub_excludes) - else: - # Simulate what glob would do with file walking to scope the * within a directory - # and ** across directories - regex_pattern = convert_glob_pattern_to_regex_pattern(os.path.normpath(glob_pattern)) - - # Deal with the commands. include/exclude are straight forward. Moves/renames are to be considered - # includes, and we will stick with validating the original contents for now - if value == "#include": - includes.append(regex_pattern) - elif value == "#exclude": - excludes.append(regex_pattern) - elif value.startswith('#move:'): - includes.append(regex_pattern) - elif value.startswith('#rename:'): - includes.append(regex_pattern) - else: - pass - return (includes, excludes) - -def generate_excludes_for_platform(root, platform): - if platform == 'all': - platform_exclusions_filename = os.path.join(this_file_path, 'platform_exclusions.json') - with open(platform_exclusions_filename, 'r') as platform_exclusions_file: - platform_exclusions = json.load(platform_exclusions_file) - else: - # Use real path in case root is a symlink path - if os.name == 'posix' and os.path.islink(root): - root = os.readlink(root) - # "root" is the root of the folder structure we're validating - # "engine_root_path" is the engine root where the restricted platform folder is linked - relative_folder = os.path.relpath(this_file_path, engine_root_path) - platform_exclusions_filename = os.path.join(engine_root_path, 'restricted', platform, relative_folder, platform.lower() + '_exclusions.json') - with open(platform_exclusions_filename, 'r') as platform_exclusions_file: - platform_exclusions = json.load(platform_exclusions_file) - - if platform not in platform_exclusions: - raise KeyError('No {} found in {}'.format(platform, platform_exclusions_filename)) - if '@lyengine' not in platform_exclusions[platform]: - raise KeyError('No {}/@lyengine found in {}'.format(platform, package_file_list)) - (_, excludes) = convert_glob_list_to_regex_list(platform_exclusions[platform]['@lyengine'], root) - del _ - return excludes - -def generate_include_exclude_regexes(package_platform, package_type, root, prohibited_platforms): - # The general contents will be indicated by the package file - if package_type == 'all': - package_file_list = os.path.join(this_file_path, 'package_filelists', 'all.json') - else: - # Search non-restricted platform first - package_file_list = os.path.join(this_file_path, 'Platform', package_platform, 'package_filelists', f'{package_type}.json') - if not os.path.exists(filelist): - # Use real path in case root is a symlink path - if os.name == 'posix' and os.path.islink(root): - root = os.readlink(root) - # "root" is the root of the folder structure we're validating - # "engine_root_path" is the engine root where the restricted platform folder is linked - rel_path = os.path.relpath(this_file_path, engine_root_path) - package_file_list = os.path.join(engine_root_path, 'restricted', package_platform, rel_path, 'package_filelists', - f'{package_type}.json') - with open(package_file_list, 'r') as package_file: - package = json.load(package_file) - - if '@lyengine' not in package: - raise KeyError('No @lyengine found in {}'.format(package_file_list)) - - (includes_list, excludes_list) = convert_glob_list_to_regex_list(package['@lyengine'], root) - prohibited_platforms.append('all') - - # Add the exclusions of each prohibited platform - for p in prohibited_platforms: - excludes_list.extend(generate_excludes_for_platform(root, p)) - - includes = re.compile('|'.join(includes_list), re.IGNORECASE) - excludes = re.compile('|'.join(excludes_list), re.IGNORECASE) - return (includes, excludes) - -def generate_exclude_regexes_for_platform(root, platform): - return re.compile('|'.join(generate_excludes_for_platform(root, platform)), re.IGNORECASE) diff --git a/scripts/scrubbing/scrubbing_job.py b/scripts/scrubbing/scrubbing_job.py deleted file mode 100755 index 11dbf5ea5a..0000000000 --- a/scripts/scrubbing/scrubbing_job.py +++ /dev/null @@ -1,29 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. -# For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -import os -import sys -cur_dir = cur_dir = os.path.dirname(os.path.abspath(__file__)) -sys.path.insert(0, os.path.abspath(f'{cur_dir}/../build/package')) -import util - -# Run validator -success = True -validator_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'validator.py') -engine_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) -if sys.platform == 'win32': - python = os.path.join(engine_root, 'python', 'python.cmd') -else: - python = os.path.join(engine_root, 'python', 'python.sh') -args = [python, validator_path, '--package_platform', 'Windows', '--package_type', 'all', engine_root] -return_code = util.safe_execute_system_call(args) -if return_code != 0: - success = False -if not success: - util.error('Restricted file validator failed.') -print('Restricted file validator completed successfully.') diff --git a/scripts/scrubbing/validator.py b/scripts/scrubbing/validator.py index 39f1a40a18..3b53417755 100755 --- a/scripts/scrubbing/validator.py +++ b/scripts/scrubbing/validator.py @@ -29,8 +29,6 @@ else: from io import StringIO import validator_data_LEGAL_REVIEW_REQUIRED # pull in the data we need to configure this tool -sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'build', 'package')) -from glob_to_regex import generate_include_exclude_regexes class Validator(object): """Class to contain the validator program""" @@ -212,9 +210,6 @@ class Validator(object): # TODO: Perhaps the directories to skip should become a parameter so we can use the validator # on non-Lumberyard trees. def validate_directory_tree(self, root, platform): - prohibited_platforms = validator_data_LEGAL_REVIEW_REQUIRED.get_prohibited_platforms_for_package(self.options.package_platform) - (includes, excludes) = generate_include_exclude_regexes(self.options.package_platform, self.options.package_type, root, prohibited_platforms) - """Walk from root to find all files to validate and call the validator on each file. Return 0 if no problems where found, and 1 if any validation failures occured.""" counter = 0 @@ -227,28 +222,22 @@ class Validator(object): # First deal with the files in the current directory for filename in filenames: filepath = os.path.join(dirname, filename) - include_match = includes.match(filepath) - exclude_match = excludes.match(filepath) - allowed = include_match and not exclude_match - - if self.options.all or allowed: - scanned += 1 - file_failed = self.validate_file(os.path.normpath(filepath)) - if file_failed: - platform_failed = file_failed - else: - validations += 1 - counter += 1 + scanned += 1 + file_failed = self.validate_file(os.path.normpath(filepath)) + if file_failed: + platform_failed = file_failed + else: + validations += 1 # Trim out allowlisted subdirectories in the current directory if allowed for name in bypassed_directories: if name in dirnames: dirnames.remove(name) - if counter == 0 or scanned == 0: + if scanned == 0: logging.error('No files scanned at target search directory: %s', root) platform_failed = 1 else: - print('validated {} of {} package files ({} non-package files skipped)'.format(validations, scanned, counter - scanned)) + print('validated {} of {} files'.format(validations, scanned)) return platform_failed @@ -387,8 +376,6 @@ def parse_options(): choices=platform_choices, dest='package_platform', help='Package platform to validate. Must be one of {}.'.format(platform_choices)) - parser.add_option('--package_type', action='store', type='string', default='all', dest='package_type', - help='Package type to validate.') parser.add_option('-s', '--store-exceptions', action='store', type='string', default='', dest='exception_file', help='Store list of lines that the validator gave exceptions to by matching accepted use patterns. These can be diffed with prior runs to see what is changing.') @@ -430,7 +417,6 @@ def main(): package_failed = 0 package_platform = validator.options.package_platform - package_type = validator.options.package_type prohibited_platforms = validator_data_LEGAL_REVIEW_REQUIRED.get_prohibited_platforms_for_package(package_platform) if validator.options.exception_file != '': @@ -441,19 +427,20 @@ def main(): sys.exit(1) for platform in prohibited_platforms: - print('validating {} against {} for package platform {} package type {}'.format(args[0], platform, package_platform, package_type)) + print('validating {} against {} for package platform {}'.format(args[0], platform, package_platform)) platform_failed = validator.validate(platform) if platform_failed: - print('{} FAILED validation against {} for package platform {} package type {}'.format(args[0], platform, package_platform, package_type)) + print('{} FAILED validation against {} for package platform {}'.format(args[0], platform, package_platform)) package_failed = platform_failed else: - print('{} is VALIDATED against {} for package platform {} package type {}'.format(args[0], platform, package_platform, package_type)) + print('{} is VALIDATED against {} for package platform {}'.format(args[0], platform, package_platform)) if validator.options.exception_file != '': validator.exceptions_output.close() return package_failed + if __name__ == '__main__': # pylint: disable-msg=C0103 main_results = main() From b2c13b24ffea6f5c57ddded4ac8cef05ae2422f3 Mon Sep 17 00:00:00 2001 From: bosnichd Date: Wed, 1 Dec 2021 07:49:22 -0700 Subject: [PATCH 44/47] Fix ImGui Gamepad Input (#6055) This fixes gamepad input for both of our ImGui integrations (which should probably be combined at some point). Signed-off-by: bosnichd --- .../Common/Code/Source/ImGui/ImGuiPass.cpp | 23 +++++++++++-- .../Common/Code/Source/ImGui/ImGuiPass.h | 1 + Gems/ImGui/Code/Source/ImGuiManager.cpp | 34 +++++-------------- Gems/ImGui/Code/Source/ImGuiManager.h | 5 --- 4 files changed, 31 insertions(+), 32 deletions(-) diff --git a/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.cpp b/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.cpp index 0ff8d2c165..7197b95917 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.cpp @@ -140,9 +140,18 @@ namespace AZ m_drawData.push_back(drawData); } + int ImGuiPass::GetTickOrder() + { + // We have to call ImGui::NewFrame (which happens in ImGuiPass::OnTick) after setting + // ImGui::GetIO().NavInputs (which happens in ImGuiPass::OnInputChannelEventFiltered), + // but before ImGui::Render (which happens in ImGuiPass::SetupFrameGraphDependencies). + return AZ::ComponentTickBus::TICK_PRE_RENDER; + } + void ImGuiPass::OnTick(float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint timePoint) { auto imguiContextScope = ImguiContextScope(m_imguiContext); + ImGui::NewFrame(); auto& io = ImGui::GetIO(); io.DeltaTime = deltaTime; @@ -413,6 +422,7 @@ namespace AZ void ImGuiPass::Init() { + auto imguiContextScope = ImguiContextScope(m_imguiContext); auto& io = ImGui::GetIO(); // ImGui IO Setup @@ -421,7 +431,6 @@ namespace AZ { io.KeyMap[static_cast(i)] = static_cast(i); } - io.NavActive = true; // Touch input const AzFramework::InputDevice* inputDevice = nullptr; @@ -434,6 +443,17 @@ namespace AZ io.ConfigFlags |= ImGuiConfigFlags_IsTouchScreen; } + // Gamepad input + inputDevice = nullptr; + AzFramework::InputDeviceRequestBus::EventResult(inputDevice, + AzFramework::InputDeviceGamepad::IdForIndex0, + &AzFramework::InputDeviceRequests::GetInputDevice); + if (inputDevice && inputDevice->IsSupported()) + { + io.BackendFlags |= ImGuiBackendFlags_HasGamepad; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; + } + // Set initial display size to something reasonable (this will be updated in FramePrepare) io.DisplaySize.x = 1920; io.DisplaySize.y = 1080; @@ -571,7 +591,6 @@ namespace AZ auto imguiContextScope = ImguiContextScope(m_imguiContext); ImGui::GetIO().MouseWheel = m_lastFrameMouseWheel; m_lastFrameMouseWheel = 0.0; - ImGui::NewFrame(); } void ImGuiPass::BuildCommandListInternal(const RHI::FrameGraphExecuteContext& context) diff --git a/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.h b/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.h index 018d2d46b7..6c9dd11914 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.h @@ -77,6 +77,7 @@ namespace AZ void RenderImguiDrawData(const ImDrawData& drawData); // TickBus::Handler overrides... + int GetTickOrder() override; void OnTick(float deltaTime, AZ::ScriptTimePoint timePoint) override; // AzFramework::InputTextEventListener overrides... diff --git a/Gems/ImGui/Code/Source/ImGuiManager.cpp b/Gems/ImGui/Code/Source/ImGuiManager.cpp index b30eda8825..f90aa60a88 100644 --- a/Gems/ImGui/Code/Source/ImGuiManager.cpp +++ b/Gems/ImGui/Code/Source/ImGuiManager.cpp @@ -172,7 +172,6 @@ void ImGuiManager::Initialize() // Broadcast ImGui Ready to Listeners ImGuiUpdateListenerBus::Broadcast(&IImGuiUpdateListener::OnImGuiInitialize); - m_currentControllerIndex = -1; m_button1Pressed = m_button2Pressed = false; m_menuBarStatusChanged = false; @@ -227,6 +226,7 @@ void ImGui::ImGuiManager::RestoreRenderWindowSizeToDefault() void ImGui::ImGuiManager::SetDpiScalingFactor(float dpiScalingFactor) { + ImGui::ImGuiContextScope contextScope(m_imguiContext); ImGuiIO& io = ImGui::GetIO(); // Set the global font scale to size our UI to the scaling factor // Note: Currently we use the default, 13px fixed-size IMGUI font, so this can get somewhat blurry @@ -235,6 +235,7 @@ void ImGui::ImGuiManager::SetDpiScalingFactor(float dpiScalingFactor) float ImGui::ImGuiManager::GetDpiScalingFactor() const { + ImGui::ImGuiContextScope contextScope(m_imguiContext); ImGuiIO& io = ImGui::GetIO(); return io.FontGlobalScale; } @@ -406,7 +407,7 @@ bool ImGuiManager::OnInputChannelEventFiltered(const InputChannel& inputChannel) // Cycle through ImGui Menu Bar States on Home button press if (inputChannelId == InputDeviceKeyboard::Key::NavigationHome) { - ToggleThroughImGuiVisibleState(-1); + ToggleThroughImGuiVisibleState(); } // Cycle through Standalone Editor Window States @@ -453,19 +454,10 @@ bool ImGuiManager::OnInputChannelEventFiltered(const InputChannel& inputChannel) } // Handle Controller Inputs - int inputControllerIndex = -1; - bool controllerInput = false; if (InputDeviceGamepad::IsGamepadDevice(inputDeviceId)) { - inputControllerIndex = inputDeviceId.GetIndex(); - controllerInput = true; - } - - - if (controllerInput) - { - // Only pipe in Controller Nav Inputs if we are the current Controller Index and at least 1 of the two controller modes are enabled. - if (m_currentControllerIndex == inputControllerIndex && m_controllerModeFlags) + // Only pipe in Controller Nav Inputs when at least 1 of the two controller modes are enabled. + if (m_controllerModeFlags) { const auto lyButtonToImGuiNav = s_lyInputToImGuiNavIndexMap.find(inputChannelId); if (lyButtonToImGuiNav != s_lyInputToImGuiNavIndexMap.end()) @@ -476,7 +468,7 @@ bool ImGuiManager::OnInputChannelEventFiltered(const InputChannel& inputChannel) } //Switch menu bar display only if two buttons are pressed at the same time - if (inputChannelId == InputDeviceGamepad::Button::L3) + if (inputChannelId == InputDeviceGamepad::Button::L1) { if (inputChannel.IsStateBegan()) { @@ -488,7 +480,7 @@ bool ImGuiManager::OnInputChannelEventFiltered(const InputChannel& inputChannel) m_menuBarStatusChanged = false; } } - if (inputChannelId == InputDeviceGamepad::Button::R3) + if (inputChannelId == InputDeviceGamepad::Button::R1) { if (inputChannel.IsStateBegan()) { @@ -502,7 +494,7 @@ bool ImGuiManager::OnInputChannelEventFiltered(const InputChannel& inputChannel) } if (!m_menuBarStatusChanged && m_button1Pressed && m_button2Pressed) { - ToggleThroughImGuiVisibleState(inputControllerIndex); + ToggleThroughImGuiVisibleState(); } // If we have the Discrete Input Mode Enabled.. and we are in the Visible State, then consume input here @@ -627,14 +619,13 @@ bool ImGuiManager::OnInputTextEventFiltered(const AZStd::string& textUTF8) return io.WantTextInput && m_clientMenuBarState == DisplayState::Visible;; } -void ImGuiManager::ToggleThroughImGuiVisibleState(int controllerIndex) +void ImGuiManager::ToggleThroughImGuiVisibleState() { ImGui::ImGuiContextScope contextScope(m_imguiContext); switch (m_clientMenuBarState) { case DisplayState::Hidden: - m_currentControllerIndex = controllerIndex; m_clientMenuBarState = DisplayState::Visible; // Draw the ImGui Mouse cursor if either the hardware mouse is connected, or the controller mouse is enabled. @@ -669,7 +660,6 @@ void ImGuiManager::ToggleThroughImGuiVisibleState(int controllerIndex) default: m_clientMenuBarState = DisplayState::Hidden; - m_currentControllerIndex = -1; // Enable system cursor if it's in editor and it's not editor game mode if (gEnv->IsEditor() && !gEnv->IsEditorGameMode()) @@ -686,12 +676,6 @@ void ImGuiManager::ToggleThroughImGuiVisibleState(int controllerIndex) m_setEnabledEvent.Signal(m_clientMenuBarState == DisplayState::Hidden); } -void ImGuiManager::ToggleThroughImGuiVisibleState() -{ - ToggleThroughImGuiVisibleState(-1); -} - - void ImGuiManager::RenderImGuiBuffers(const ImVec2& scaleRects) { ImGui::ImGuiContextScope contextScope(m_imguiContext); diff --git a/Gems/ImGui/Code/Source/ImGuiManager.h b/Gems/ImGui/Code/Source/ImGuiManager.h index c4fa5169f7..c0071c94c5 100644 --- a/Gems/ImGui/Code/Source/ImGuiManager.h +++ b/Gems/ImGui/Code/Source/ImGuiManager.h @@ -76,9 +76,6 @@ namespace ImGui // Sets up initial window size and listens for changes void InitWindowSize(); - // A function to toggle through the available ImGui Visibility States - void ToggleThroughImGuiVisibleState(int controllerIndex); - private: ImGuiContext* m_imguiContext = nullptr; DisplayState m_clientMenuBarState = DisplayState::Hidden; @@ -96,8 +93,6 @@ namespace ImGui std::vector m_idxBuffer; //Controller navigation - static const int MaxControllerNumber = 4; - int m_currentControllerIndex; bool m_button1Pressed, m_button2Pressed, m_menuBarStatusChanged; bool m_hardwardeMouseConnected = false; From 2065225099e73a535c8e3c1bb756a7acabf4405e Mon Sep 17 00:00:00 2001 From: amzn-mike <80125227+amzn-mike@users.noreply.github.com> Date: Wed, 1 Dec 2021 09:04:49 -0600 Subject: [PATCH 45/47] Fixed LodRuleBehavior using wrong loop index (#5915) * Fixed LodRuleBehavior using wrong loop index Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Add unit test for LOD auto-add crash Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Fix macro usage Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Fix include Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> --- .../SceneData/Behaviors/LodRuleBehavior.cpp | 2 +- .../SceneData/Behaviors/LodRuleBehavior.h | 18 +++-- .../SceneAPI/SceneData/Rules/LodRule.cpp | 1 - Code/Tools/SceneAPI/SceneData/Rules/LodRule.h | 20 ++--- .../SceneData/SceneData_testing_files.cmake | 1 + .../SceneData/Tests/GraphData/RulesTests.cpp | 78 +++++++++++++++++++ 6 files changed, 100 insertions(+), 20 deletions(-) create mode 100644 Code/Tools/SceneAPI/SceneData/Tests/GraphData/RulesTests.cpp diff --git a/Code/Tools/SceneAPI/SceneData/Behaviors/LodRuleBehavior.cpp b/Code/Tools/SceneAPI/SceneData/Behaviors/LodRuleBehavior.cpp index f51c670fc8..c47330620d 100644 --- a/Code/Tools/SceneAPI/SceneData/Behaviors/LodRuleBehavior.cpp +++ b/Code/Tools/SceneAPI/SceneData/Behaviors/LodRuleBehavior.cpp @@ -185,7 +185,7 @@ namespace AZ if (lodCount > 0) { rule->AddLod(); - selection.CopyTo(rule->GetNodeSelectionList(index)); + selection.CopyTo(rule->GetNodeSelectionList(lodLevel)); } else { diff --git a/Code/Tools/SceneAPI/SceneData/Behaviors/LodRuleBehavior.h b/Code/Tools/SceneAPI/SceneData/Behaviors/LodRuleBehavior.h index d152386940..c9416c0aa8 100644 --- a/Code/Tools/SceneAPI/SceneData/Behaviors/LodRuleBehavior.h +++ b/Code/Tools/SceneAPI/SceneData/Behaviors/LodRuleBehavior.h @@ -13,6 +13,7 @@ #include #include #include +#include namespace AZ { @@ -27,7 +28,7 @@ namespace AZ { class LodRule; - class LodRuleBehavior + class SCENE_DATA_CLASS LodRuleBehavior : public SceneCore::BehaviorComponent , public Events::ManifestMetaInfoBus::Handler , public Events::AssetImportRequestBus::Handler @@ -36,18 +37,19 @@ namespace AZ public: AZ_COMPONENT(LodRuleBehavior, "{D2E19864-9A4B-41FD-8ACC-DA6756728CB3}", SceneCore::BehaviorComponent); - ~LodRuleBehavior() override = default; + SCENE_DATA_API ~LodRuleBehavior() override = default; - void Activate() override; - void Deactivate() override; + SCENE_DATA_API void Activate() override; + SCENE_DATA_API void Deactivate() override; static void Reflect(ReflectContext* context); - void InitializeObject(const Containers::Scene& scene, DataTypes::IManifestObject& target) override; - Events::ProcessingResult UpdateManifest(Containers::Scene& scene, ManifestAction action, + SCENE_DATA_API void InitializeObject(const Containers::Scene& scene, DataTypes::IManifestObject& target) override; + SCENE_DATA_API Events::ProcessingResult UpdateManifest( + Containers::Scene& scene, ManifestAction action, RequestingApplication requester) override; - void GetVirtualTypeName(AZStd::string& name, Crc32 type) override; - void GetAllVirtualTypes(AZStd::set& types) override; + SCENE_DATA_API void GetVirtualTypeName(AZStd::string& name, Crc32 type) override; + SCENE_DATA_API void GetAllVirtualTypes(AZStd::set& types) override; private: size_t SelectLodMeshes(const Containers::Scene& scene, DataTypes::ISceneNodeSelectionList& selection, size_t lodLevel) const; diff --git a/Code/Tools/SceneAPI/SceneData/Rules/LodRule.cpp b/Code/Tools/SceneAPI/SceneData/Rules/LodRule.cpp index f893751caf..a6c624397a 100644 --- a/Code/Tools/SceneAPI/SceneData/Rules/LodRule.cpp +++ b/Code/Tools/SceneAPI/SceneData/Rules/LodRule.cpp @@ -21,7 +21,6 @@ namespace AZ { const size_t LodRule::m_maxLods; - AZ_CLASS_ALLOCATOR_IMPL(LodRule, SystemAllocator, 0) SceneNodeSelectionList& LodRule::GetNodeSelectionList(size_t index) { diff --git a/Code/Tools/SceneAPI/SceneData/Rules/LodRule.h b/Code/Tools/SceneAPI/SceneData/Rules/LodRule.h index 0d9bf0a9a6..fd7d6bacd8 100644 --- a/Code/Tools/SceneAPI/SceneData/Rules/LodRule.h +++ b/Code/Tools/SceneAPI/SceneData/Rules/LodRule.h @@ -25,26 +25,26 @@ namespace AZ } namespace SceneData { - class LodRule + class SCENE_DATA_CLASS LodRule : public DataTypes::ILodRule { public: AZ_RTTI(LodRule, "{6E796AC8-1484-4909-860A-6D3F22A7346F}", DataTypes::ILodRule); - AZ_CLASS_ALLOCATOR_DECL + AZ_CLASS_ALLOCATOR(LodRule, AZ::SystemAllocator, 0) - ~LodRule() override = default; + SCENE_DATA_API ~LodRule() override = default; - SceneNodeSelectionList& GetNodeSelectionList(size_t index); + SCENE_DATA_API SceneNodeSelectionList& GetNodeSelectionList(size_t index); - DataTypes::ISceneNodeSelectionList& GetSceneNodeSelectionList(size_t index) override; - const DataTypes::ISceneNodeSelectionList& GetSceneNodeSelectionList(size_t index) const override; - size_t GetLodCount() const override; + SCENE_DATA_API DataTypes::ISceneNodeSelectionList& GetSceneNodeSelectionList(size_t index) override; + SCENE_DATA_API const DataTypes::ISceneNodeSelectionList& GetSceneNodeSelectionList(size_t index) const override; + SCENE_DATA_API size_t GetLodCount() const override; - void AddLod(); + SCENE_DATA_API void AddLod(); static void Reflect(ReflectContext* context); - //The engine supports 6 total lods. 1 for the base model then 5 more lods. - //The rule only captures lods past level 0 so this is set to 5. + //The engine supports 6 total lods. 1 for the base model then 5 more lods. + //The rule only captures lods past level 0 so this is set to 5. static const size_t m_maxLods = 5; protected: diff --git a/Code/Tools/SceneAPI/SceneData/SceneData_testing_files.cmake b/Code/Tools/SceneAPI/SceneData/SceneData_testing_files.cmake index 51f3dfc9e7..3a51180ca1 100644 --- a/Code/Tools/SceneAPI/SceneData/SceneData_testing_files.cmake +++ b/Code/Tools/SceneAPI/SceneData/SceneData_testing_files.cmake @@ -11,5 +11,6 @@ set(FILES Tests/GraphData/MeshDataTests.cpp Tests/GraphData/MeshDataPrimitiveUtilsTests.cpp Tests/GraphData/GraphDataBehaviorTests.cpp + Tests/GraphData/RulesTests.cpp Tests/SceneManifest/SceneManifestRuleTests.cpp ) diff --git a/Code/Tools/SceneAPI/SceneData/Tests/GraphData/RulesTests.cpp b/Code/Tools/SceneAPI/SceneData/Tests/GraphData/RulesTests.cpp new file mode 100644 index 0000000000..a6ccdfa59d --- /dev/null +++ b/Code/Tools/SceneAPI/SceneData/Tests/GraphData/RulesTests.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace AZ +{ + namespace SceneData + { + struct SoftNameMock + : SceneAPI::Events::GraphMetaInfoBus::Handler + { + SoftNameMock() + { + BusConnect(); + } + + ~SoftNameMock() override + { + BusDisconnect(); + } + + void GetVirtualTypes(AZStd::set& types, const SceneAPI::Containers::Scene&, SceneAPI::Containers::SceneGraph::NodeIndex) override + { + // Indicate this node is a LOD1 type + types.emplace(AZ_CRC_CE("LODMesh1")); + } + }; + + TEST(LOD, LODRuleTest) + { + // Test that UpdateManifest doesn't crash when trying to auto-add new LOD levels + SoftNameMock softNameMock; + + SceneAPI::SceneData::LodRuleBehavior lod; + SceneAPI::Containers::Scene scene("test"); + + auto lodRule = AZStd::shared_ptr(aznew SceneAPI::SceneData::LodRule()); + scene.GetManifest().AddEntry(lodRule); + + auto group = AZStd::shared_ptr(aznew SceneAPI::SceneData::MeshGroup()); + + // Add a bunch of other rules first + // This is necessary to replicate the bug condition where the index of the rule is used instead of the index of the LOD + for (int i = 0; i < 5; ++i) + { + auto tangentsRule = AZStd::shared_ptr(aznew SceneAPI::SceneData::TangentsRule()); + group->GetRuleContainer().AddRule(tangentsRule); + } + + group->GetRuleContainer().AddRule(lodRule); + scene.GetManifest().AddEntry(group); + + auto meshData = AZStd::shared_ptr(new GraphData::MeshData()); + scene.GetGraph().AddChild(scene.GetGraph().GetRoot(), "test", meshData); + + EXPECT_EQ(lodRule->GetLodCount(), 0); + + // This should auto-add 1 LOD because of the "test" node we added above along with the SoftNameMock which will report it as an LOD1 + lod.UpdateManifest(scene, SceneAPI::Events::AssetImportRequest::Update, SceneAPI::Events::AssetImportRequest::Generic); + + EXPECT_EQ(lodRule->GetLodCount(), 1); + } + } +} From 828431f185a39846bdad5630dcdf7c7d117ed931 Mon Sep 17 00:00:00 2001 From: amzn-mike <80125227+amzn-mike@users.noreply.github.com> Date: Wed, 1 Dec 2021 09:05:35 -0600 Subject: [PATCH 46/47] Update AssetManager unit tests to not interact with the disk (#5815) * Changed AssetManager tests to use memory streams for asset reading/writing Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Fix compilation on non-unity builds Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Fixed handling of path lookups when test folder path is non-empty Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Add more detailed error message for "asset is not loaded" Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Make numThreads a constexpr Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Add FindFile function Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Remove unused lambda capture Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Remove trailing whitespace Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Add size to assert Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> --- .../AzCore/AzCore/Asset/AssetCommon.h | 4 +- .../Tests/Asset/AssetManagerLoadingTests.cpp | 176 +++++------- .../Tests/Asset/BaseAssetManagerTest.cpp | 250 ++++++++++++++++++ .../AzCore/Tests/Asset/BaseAssetManagerTest.h | 66 ++++- Code/Framework/AzCore/Tests/TestCatalog.cpp | 8 +- 5 files changed, 393 insertions(+), 111 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h b/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h index c45bb21c6d..0b181f6782 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h +++ b/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h @@ -325,13 +325,13 @@ namespace AZ T& operator*() const { - AZ_Assert(m_assetData, "Asset is not loaded"); + AZ_Assert(m_assetData, "Asset %s (%s) is not loaded", m_assetId.ToString().c_str(), m_assetHint.c_str()); return *Get(); } T* operator->() const { - AZ_Assert(m_assetData, "Asset is not loaded"); + AZ_Assert(m_assetData, "Asset %s (%s) is not loaded", m_assetId.ToString().c_str(), m_assetHint.c_str()); return Get(); } diff --git a/Code/Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp b/Code/Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp index fe38451101..043eb1aee6 100644 --- a/Code/Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp +++ b/Code/Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -131,8 +132,8 @@ namespace UnitTest * This will test the aspect of the system where ObjectStreams and asset jobs loading dependent * assets will do the work in their own thread. */ - class AssetJobsFloodTest - : public BaseAssetManagerTest + + class AssetJobsFloodTest : public DisklessAssetManagerBase { public: TestAssetManager* m_testAssetManager{ nullptr }; @@ -183,15 +184,14 @@ namespace UnitTest void SetUp() override { - BaseAssetManagerTest::SetUp(); + DisklessAssetManagerBase::SetUp(); SetupTest(); } void TearDown() override { - TearDownTest(); AssetManager::Destroy(); - BaseAssetManagerTest::TearDown(); + DisklessAssetManagerBase::TearDown(); } void SetupAssets() @@ -257,9 +257,9 @@ namespace UnitTest AssetWithSerializedData ap2; AssetWithSerializedData ap3; - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset4.txt", AZ::DataStream::ST_XML, &ap1, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset5.txt", AZ::DataStream::ST_XML, &ap2, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset6.txt", AZ::DataStream::ST_XML, &ap3, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset4.txt", &ap1, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset5.txt", &ap2, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset6.txt", &ap3, m_serializeContext)); AssetWithAssetReference assetWithPreload1; AssetWithAssetReference assetWithPreload2; @@ -273,11 +273,11 @@ namespace UnitTest noLoadAsset.m_asset = m_testAssetManager->CreateAsset(MyAsset2Id, AssetLoadBehavior::NoLoad); EXPECT_EQ(m_assetHandlerAndCatalog->m_numCreations, 4); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset1.txt", AZ::DataStream::ST_XML, &assetWithPreload1, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset2.txt", AZ::DataStream::ST_XML, &assetWithPreload2, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset3.txt", AZ::DataStream::ST_XML, &assetWithPreload3, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "DelayLoadAsset.txt", AZ::DataStream::ST_XML, &delayedAsset, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "NoLoadAsset.txt", AZ::DataStream::ST_XML, &noLoadAsset, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset1.txt", &assetWithPreload1, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset2.txt", &assetWithPreload2, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset3.txt", &assetWithPreload3, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("DelayLoadAsset.txt", &delayedAsset, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("NoLoadAsset.txt", &noLoadAsset, m_serializeContext)); AssetWithQueueAndPreLoadReferences preLoadRoot; AssetWithQueueAndPreLoadReferences preLoadA; @@ -297,16 +297,16 @@ namespace UnitTest preLoadBrokenA.m_preLoad = m_testAssetManager->CreateAsset(PreloadBrokenDepBId, AssetLoadBehavior::PreLoad); preLoadBrokenB.m_preLoad = m_testAssetManager->CreateAsset(PreloadAssetNoDataId, AssetLoadBehavior::PreLoad); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "PreLoadRoot.txt", AZ::DataStream::ST_XML, &preLoadRoot, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "PreLoadA.txt", AZ::DataStream::ST_XML, &preLoadA, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "PreLoadB.txt", AZ::DataStream::ST_XML, &noRefs, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "PreLoadC.txt", AZ::DataStream::ST_XML, &noRefs, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "QueueLoadA.txt", AZ::DataStream::ST_XML, &queueLoadA, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "QueueLoadB.txt", AZ::DataStream::ST_XML, &noRefs, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "QueueLoadC.txt", AZ::DataStream::ST_XML, &noRefs, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "PreLoadBrokenA.txt", AZ::DataStream::ST_XML, &preLoadBrokenA, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "PreLoadBrokenB.txt", AZ::DataStream::ST_XML, &preLoadBrokenB, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "PreLoadNoData.txt", AZ::DataStream::ST_XML, &noRefs, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("PreLoadRoot.txt", &preLoadRoot, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("PreLoadA.txt", &preLoadA, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("PreLoadB.txt", &noRefs, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("PreLoadC.txt", &noRefs, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("QueueLoadA.txt", &queueLoadA, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("QueueLoadB.txt", &noRefs, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("QueueLoadC.txt", &noRefs, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("PreLoadBrokenA.txt", &preLoadBrokenA, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("PreLoadBrokenB.txt", &preLoadBrokenB, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("PreLoadNoData.txt", &noRefs, m_serializeContext)); AssetWithQueueAndPreLoadReferences circularA; AssetWithQueueAndPreLoadReferences circularB; @@ -318,43 +318,15 @@ namespace UnitTest circularC.m_preLoad = m_testAssetManager->CreateAsset(CircularBId, AssetLoadBehavior::PreLoad); circularD.m_preLoad = circularC.m_preLoad; - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "CircularA.txt", AZ::DataStream::ST_XML, &circularA, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "CircularB.txt", AZ::DataStream::ST_XML, &circularB, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "CircularC.txt", AZ::DataStream::ST_XML, &circularC, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "CircularD.txt", AZ::DataStream::ST_XML, &circularD, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("CircularA.txt", &circularA, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("CircularB.txt", &circularB, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("CircularC.txt", &circularC, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("CircularD.txt", &circularD, m_serializeContext)); + m_assetHandlerAndCatalog->m_numCreations = 0; } } - void TearDownTest() - { - DeleteAssetFromDisk(GetTestFolderPath() + "TestAsset4.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "TestAsset5.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "TestAsset6.txt"); - - DeleteAssetFromDisk(GetTestFolderPath() + "TestAsset1.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "TestAsset2.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "TestAsset3.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "DelayLoadAsset.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "NoLoadAsset.txt"); - - DeleteAssetFromDisk(GetTestFolderPath() + "PreLoadRoot.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "PreLoadA.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "PreLoadB.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "PreLoadC.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "QueueLoadA.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "QueueLoadB.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "QueueLoadC.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "PreLoadBrokenA.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "PreLoadBrokenB.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "PreLoadNoData.txt"); - - DeleteAssetFromDisk(GetTestFolderPath() + "CircularA.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "CircularB.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "CircularC.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "CircularD.txt"); - } - void CheckFinishedCreationsAndDestructions() { // Make sure asset jobs have finished before validating the number of destroyed assets, because it's possible that the asset job @@ -367,7 +339,7 @@ namespace UnitTest }; static constexpr AZStd::chrono::seconds MaxDispatchTimeoutSeconds = BaseAssetManagerTest::DefaultTimeoutSeconds * 12; - + template bool DispatchEventsUntilCondition(AZ::Data::AssetManager& assetManager, Pred&& conditionPredicate, AZStd::chrono::seconds logIntervalSeconds = BaseAssetManagerTest::DefaultTimeoutSeconds, @@ -608,7 +580,7 @@ namespace UnitTest AZ::Data::AssetData::AssetStatus expected_base_status = AZ::Data::AssetData::AssetStatus::Ready; EXPECT_EQ(baseStatus, expected_base_status); } - + TEST_F(AssetJobsFloodTest, RapidAcquireAndRelease) { auto assetUuids = { @@ -641,7 +613,7 @@ namespace UnitTest { Asset asset1 = m_testAssetManager->GetAsset(assetUuid, azrtti_typeid(), AZ::Data::AssetLoadBehavior::PreLoad); - + if (checkLoaded) { asset1.BlockUntilLoadComplete(); @@ -714,8 +686,8 @@ namespace UnitTest AssetWithSerializedData ap; - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "a.txt", AZ::DataStream::ST_XML, &ap, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "b.txt", AZ::DataStream::ST_XML, &ap, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("a.txt", &ap, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("b.txt", &ap, m_serializeContext)); } auto& assetManager = AssetManager::Instance(); @@ -778,7 +750,7 @@ namespace UnitTest * Verify that loads without using the Asset Container still work correctly */ class AssetContainerDisableTest - : public BaseAssetManagerTest + : public DisklessAssetManagerBase { public: static inline const AZ::Uuid MyAsset1Id{ "{5B29FE2B-6B41-48C9-826A-C723951B0560}" }; @@ -797,7 +769,7 @@ namespace UnitTest void SetUp() override { - BaseAssetManagerTest::SetUp(); + DisklessAssetManagerBase::SetUp(); SetupTest(); } @@ -807,7 +779,7 @@ namespace UnitTest AssetManager::Instance().UnregisterHandler(m_assetHandlerAndCatalog); delete m_assetHandlerAndCatalog; AssetManager::Destroy(); - BaseAssetManagerTest::TearDown(); + DisklessAssetManagerBase::TearDown(); } void SetupAssets() @@ -849,9 +821,9 @@ namespace UnitTest AssetWithSerializedData ap2; AssetWithSerializedData ap3; - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset4.txt", AZ::DataStream::ST_XML, &ap1, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset5.txt", AZ::DataStream::ST_XML, &ap2, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset6.txt", AZ::DataStream::ST_XML, &ap3, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset4.txt", &ap1, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset5.txt", &ap2, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset6.txt", &ap3, m_serializeContext)); AssetWithAssetReference assetWithPreload1; AssetWithAssetReference assetWithPreload2; @@ -862,9 +834,9 @@ namespace UnitTest assetWithPreload3.m_asset = m_testAssetManager->CreateAsset(MyAsset6Id, AssetLoadBehavior::PreLoad); EXPECT_EQ(m_assetHandlerAndCatalog->m_numCreations, 3); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset1.txt", AZ::DataStream::ST_XML, &assetWithPreload1, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset2.txt", AZ::DataStream::ST_XML, &assetWithPreload2, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset3.txt", AZ::DataStream::ST_XML, &assetWithPreload3, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset1.txt", &assetWithPreload1, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset2.txt", &assetWithPreload2, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset3.txt", &assetWithPreload3, m_serializeContext)); m_assetHandlerAndCatalog->m_numCreations = 0; } @@ -2014,11 +1986,12 @@ namespace UnitTest CheckFinishedCreationsAndDestructions(); m_assetHandlerAndCatalog->AssetCatalogRequestBus::Handler::BusDisconnect(); } + /** * Run multiple threads that get and release assets simultaneously to test AssetManager's thread safety */ class AssetJobsMultithreadedTest - : public BaseAssetManagerTest + : public DisklessAssetManagerBase { public: static inline const AZ::Uuid MyAsset1Id{ "{5B29FE2B-6B41-48C9-826A-C723951B0560}" }; @@ -2028,6 +2001,7 @@ namespace UnitTest static inline const AZ::Uuid MyAsset5Id{ "{D9CDAB04-D206-431E-BDC0-1DD615D56197}" }; static inline const AZ::Uuid MyAsset6Id{ "{B2F139C3-5032-4B52-ADCA-D52A8F88E043}" }; + // Initialize the Job Manager with 2 threads for the Asset Manager to use. size_t GetNumJobManagerThreads() const override { return 2; } @@ -2078,9 +2052,9 @@ namespace UnitTest AssetWithSerializedData ap2; AssetWithSerializedData ap3; - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset4.txt", AZ::DataStream::ST_XML, &ap1, &context)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset5.txt", AZ::DataStream::ST_XML, &ap2, &context)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset6.txt", AZ::DataStream::ST_XML, &ap3, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset4.txt", &ap1, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset5.txt", &ap2, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset6.txt", &ap3, &context)); AssetWithAssetReference assetWithPreload1; AssetWithAssetReference assetWithPreload2; @@ -2089,9 +2063,9 @@ namespace UnitTest assetWithPreload2.m_asset = AssetManager::Instance().CreateAsset(MyAsset5Id, AssetLoadBehavior::PreLoad); assetWithPreload3.m_asset = AssetManager::Instance().CreateAsset(MyAsset6Id, AssetLoadBehavior::PreLoad); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset1.txt", AZ::DataStream::ST_XML, &assetWithPreload1, &context)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset2.txt", AZ::DataStream::ST_XML, &assetWithPreload2, &context)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset3.txt", AZ::DataStream::ST_XML, &assetWithPreload3, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset1.txt", &assetWithPreload1, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset2.txt", &assetWithPreload2, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset3.txt", &assetWithPreload3, &context)); EXPECT_TRUE(assetHandlerAndCatalog->m_numCreations == 3); assetHandlerAndCatalog->m_numCreations = 0; @@ -2191,22 +2165,22 @@ namespace UnitTest // A will be saved to disk with MyAsset1Id AssetWithAssetReference a; a.m_asset = AssetManager::Instance().CreateAsset(MyAsset2Id); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset1.txt", AZ::DataStream::ST_XML, &a, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset1.txt", &a, &context)); AssetWithAssetReference b; b.m_asset = AssetManager::Instance().CreateAsset(MyAsset3Id); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset2.txt", AZ::DataStream::ST_XML, &b, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset2.txt", &b, &context)); AssetWithAssetReference c; c.m_asset = AssetManager::Instance().CreateAsset(MyAsset4Id); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset3.txt", AZ::DataStream::ST_XML, &c, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset3.txt", &c, &context)); AssetWithAssetReference d; d.m_asset = AssetManager::Instance().CreateAsset(MyAsset5Id); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset4.txt", AZ::DataStream::ST_XML, &d, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset4.txt", &d, &context)); AssetWithAssetReference e; e.m_asset = AssetManager::Instance().CreateAsset(MyAsset6Id); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset5.txt", AZ::DataStream::ST_XML, &e, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset5.txt", &e, &context)); AssetWithAssetReference f; f.m_asset = AssetManager::Instance().CreateAsset(MyAsset1Id); // refer back to asset1 - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset6.txt", AZ::DataStream::ST_XML, &f, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset6.txt", &f, &context)); EXPECT_TRUE(assetHandlerAndCatalog->m_numCreations == 6); assetHandlerAndCatalog->m_numCreations = 0; @@ -2347,26 +2321,26 @@ namespace UnitTest // AssetD is MYASSETD AssetWithSerializedData d; d.m_data = 42; - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset4.txt", AZ::DataStream::ST_XML, &d, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset4.txt", &d, &context)); // AssetC is MYASSETC AssetWithAssetReference c; c.m_asset = db.CreateAsset(AssetId(MyAssetDId)); // point at D - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset3.txt", AZ::DataStream::ST_XML, &c, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset3.txt", &c, &context)); // AssetB is MYASSETB AssetWithAssetReference b; b.m_asset = db.CreateAsset(AssetId(MyAssetCId)); // point at C - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset2.txt", AZ::DataStream::ST_XML, &b, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset2.txt", &b, &context)); // AssetA will be written to disk as MYASSETA AssetWithAssetReference a; a.m_asset = db.CreateAsset(AssetId(MyAssetBId)); // point at B - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset1.txt", AZ::DataStream::ST_XML, &a, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset1.txt", &a, &context)); } - const size_t numThreads = 4; - AZStd::atomic_int threadCount(numThreads); + constexpr size_t NumThreads = 4; + AZStd::atomic_int threadCount(NumThreads); AZStd::condition_variable cv; AZStd::vector threads; AZStd::atomic_bool keepDispatching(true); @@ -2381,7 +2355,7 @@ namespace UnitTest AZStd::thread dispatchThread(dispatch); - for (size_t threadIdx = 0; threadIdx < numThreads; ++threadIdx) + for (size_t threadIdx = 0; threadIdx < NumThreads; ++threadIdx) { threads.emplace_back([&threadCount, &db, &cv]() { @@ -2569,7 +2543,6 @@ namespace UnitTest #if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS TEST_F(AssetJobsMultithreadedTest, DISABLED_ParallelDeepAssetReferences) #else - // temporarily disabled until sporadic failures can be root caused TEST_F(AssetJobsMultithreadedTest, ParallelDeepAssetReferences) #endif // AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS { @@ -2577,7 +2550,7 @@ namespace UnitTest } class AssetManagerTests - : public BaseAssetManagerTest + : public DisklessAssetManagerBase { protected: static inline const AZ::Uuid MyAsset1Id{ "{5B29FE2B-6B41-48C9-826A-C723951B0560}" }; @@ -2592,7 +2565,7 @@ namespace UnitTest void SetUp() override { - BaseAssetManagerTest::SetUp(); + DisklessAssetManagerBase::SetUp(); m_console = AZStd::make_unique(); AZ::Interface::Register(m_console.get()); @@ -2631,7 +2604,7 @@ namespace UnitTest AssetManager::Destroy(); AZ::Interface::Unregister(m_console.get()); m_console = nullptr; - BaseAssetManagerTest::TearDown(); + DisklessAssetManagerBase::TearDown(); } }; @@ -2982,7 +2955,7 @@ namespace UnitTest * the middle of loading. The tests help ensure that assets can't get stuck in perpetual loading states. **/ class AssetManagerClearAssetReferenceTests - : public BaseAssetManagerTest + : public DisklessAssetManagerBase { protected: static inline const AZ::Uuid RootAssetId{ "{AB13F568-C676-41FE-A7E9-341F71A78104}" }; @@ -3001,7 +2974,7 @@ namespace UnitTest void SetUp() override { - BaseAssetManagerTest::SetUp(); + DisklessAssetManagerBase::SetUp(); // create the database AssetManager::Descriptor desc; @@ -3039,21 +3012,18 @@ namespace UnitTest // Create and save the dependent asset first, so that we can get a reference to it. AssetWithSerializedData dependentBlockingAsset; - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "DependentPreloadBlockingAsset.txt", - AZ::DataStream::ST_XML, &dependentBlockingAsset, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("DependentPreloadBlockingAsset.txt", &dependentBlockingAsset, m_serializeContext)); AssetWithAssetReference dependentAsset; dependentAsset.m_asset = AssetManager::Instance().CreateAsset( NestedDependentPreloadBlockingAssetId, AssetLoadBehavior::PreLoad); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "DependentPreloadAsset.txt", - AZ::DataStream::ST_XML, &dependentAsset, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("DependentPreloadAsset.txt", &dependentAsset, m_serializeContext)); // Create and save the top-level asset. AssetWithAssetReference rootAsset; rootAsset.m_asset = AssetManager::Instance().CreateAsset( DependentPreloadAssetId, AssetLoadBehavior::PreLoad); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "RootAsset.txt", - AZ::DataStream::ST_XML, &rootAsset, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("RootAsset.txt", &rootAsset, m_serializeContext)); } void TearDown() override @@ -3065,7 +3035,7 @@ namespace UnitTest delete m_assetHandlerAndCatalog; AssetManager::Destroy(); - BaseAssetManagerTest::TearDown(); + DisklessAssetManagerBase::TearDown(); } }; diff --git a/Code/Framework/AzCore/Tests/Asset/BaseAssetManagerTest.cpp b/Code/Framework/AzCore/Tests/Asset/BaseAssetManagerTest.cpp index c6fa296cbc..532cb0a1d8 100644 --- a/Code/Framework/AzCore/Tests/Asset/BaseAssetManagerTest.cpp +++ b/Code/Framework/AzCore/Tests/Asset/BaseAssetManagerTest.cpp @@ -165,4 +165,254 @@ namespace UnitTest EXPECT_FALSE(AssetManager::Instance().HasActiveJobsOrStreamerRequests()); } + + MemoryStreamerWrapper::MemoryStreamerWrapper() + { + using ::testing::_; + using ::testing::NiceMock; + using ::testing::Return; + + ON_CALL(m_mockStreamer, SuspendProcessing()).WillByDefault([this]() + { + m_suspended = true; + }); + + ON_CALL(m_mockStreamer, ResumeProcessing()).WillByDefault([this]() + { + AZStd::unique_lock lock(m_mutex); + + m_suspended = false; + + while (!m_processingQueue.empty()) + { + FileRequestHandle requestHandle = m_processingQueue.front(); + m_processingQueue.pop(); + + const auto& onCompleteCallback = GetReadRequest(requestHandle)->m_callback; + + if (onCompleteCallback) + { + onCompleteCallback(requestHandle); + } + } + }); + + ON_CALL(m_mockStreamer, Read(_, ::testing::An(), _, _, _, _)) + .WillByDefault( + [this]( + [[maybe_unused]] AZStd::string_view relativePath, IStreamerTypes::RequestMemoryAllocator& allocator, size_t size, + AZStd::chrono::microseconds deadline, IStreamerTypes::Priority priority, [[maybe_unused]] size_t offset) + { + AZStd::unique_lock lock(m_mutex); + + ReadRequest request; + + // Save off the requested deadline and priority + request.m_deadline = deadline; + request.m_priority = priority; + request.m_data = allocator.Allocate(size, size, 8); + + const auto* virtualFile = FindFile(relativePath); + + AZ_Assert( + virtualFile->size() == size, "Streamer read request size did not match size of saved file: %d vs %d (%.*s)", + virtualFile->size(), size, + relativePath.size(), relativePath.data()); + AZ_Assert(size > 0, "Size is zero %.*s", relativePath.size(), relativePath.data()); + + memcpy(request.m_data.m_address, virtualFile->data(), size); + + // Create a real file request result and return it + request.m_request = m_context.GetNewExternalRequest(); + + m_readRequests.push_back(request); + + return request.m_request; + }); + + ON_CALL(m_mockStreamer, SetRequestCompleteCallback(_, _)) + .WillByDefault([this](FileRequestPtr& request, AZ::IO::IStreamer::OnCompleteCallback callback) -> FileRequestPtr& + { + // Save off the callback just so that we can call it when the request is "done" + AZStd::unique_lock lock(m_mutex); + ReadRequest* readRequest = GetReadRequest(request); + readRequest->m_callback = callback; + + return request; + }); + + ON_CALL(m_mockStreamer, QueueRequest(_)) + .WillByDefault([this](const auto& fileRequest) + { + if (!m_suspended) + { + decltype(ReadRequest::m_callback) onCompleteCallback; + + AZStd::unique_lock lock(m_mutex); + ReadRequest* readRequest = GetReadRequest(fileRequest); + onCompleteCallback = readRequest->m_callback; + + if (onCompleteCallback) + { + onCompleteCallback(fileRequest); + + m_readRequests.erase(readRequest); + } + } + else + { + AZStd::unique_lock lock(m_mutex); + + m_processingQueue.push(fileRequest); + } + }); + + ON_CALL(m_mockStreamer, GetRequestStatus(_)) + .WillByDefault([]([[maybe_unused]] FileRequestHandle request) + { + // Return whatever request status has been set in this class + return IO::IStreamerTypes::RequestStatus::Completed; + }); + + ON_CALL(m_mockStreamer, GetReadRequestResult(_, _, _, _)) + .WillByDefault([this]( + [[maybe_unused]] FileRequestHandle request, void*& buffer, AZ::u64& numBytesRead, + IStreamerTypes::ClaimMemory claimMemory) + { + // Make sure the requestor plans to free the data buffer we allocated. + EXPECT_EQ(claimMemory, IStreamerTypes::ClaimMemory::Yes); + + AZStd::unique_lock lock(m_mutex); + + ReadRequest* readRequest = GetReadRequest(request); + + // Provide valid data buffer results. + numBytesRead = readRequest->m_data.m_size; + buffer = readRequest->m_data.m_address; + + return true; + }); + + ON_CALL(m_mockStreamer, RescheduleRequest(_, _, _)) + .WillByDefault([this](IO::FileRequestPtr target, AZStd::chrono::microseconds newDeadline, IO::IStreamerTypes::Priority newPriority) + { + AZStd::unique_lock lock(m_mutex); + ReadRequest* readRequest = GetReadRequest(target); + + readRequest->m_deadline = newDeadline; + readRequest->m_priority = newPriority; + + return target; + }); + } + + ReadRequest* MemoryStreamerWrapper::GetReadRequest(FileRequestHandle request) + { + auto itr = AZStd::find_if( + m_readRequests.begin(), m_readRequests.end(), + [request](const ReadRequest& searchItem) -> bool + { + return (searchItem.m_request == request); + }); + + return itr; + } + + AZStd::vector* MemoryStreamerWrapper::FindFile(AZStd::string_view path) + { + auto itr = m_virtualFiles.find(path); + + if (itr == m_virtualFiles.end()) + { + // Path didn't work as-is, does it have the test folder prefixed? If so try removing it + if (AZ::StringFunc::StartsWith(path, GetTestFolderPath())) + { + AZStd::string_view pathWithoutFolder = path; + + pathWithoutFolder = AZ::StringFunc::LStrip(pathWithoutFolder, GetTestFolderPath().c_str()); + itr = m_virtualFiles.find(pathWithoutFolder); + } + else // Path isn't prefixed, so try adding it + { + itr = m_virtualFiles.find(GetTestFolderPath().append(path)); + } + } + + if (itr != m_virtualFiles.end()) + { + return &itr->second; + } + + // Currently no test expects a file not to exist so we assert to make it easy to quickly find where something went wrong + // If we ever need to test for a non-existent file this assert should just be conditionally disabled for that specific test + AZ_Assert(false, "Failed to find virtual file %*.s", path.size(), path.data()) + + return nullptr; + } + + void DisklessAssetManagerBase::SetUp() + { + using ::testing::_; + using ::testing::NiceMock; + using ::testing::Return; + + BaseAssetManagerTest::SetUp(); + + ON_CALL(m_fileIO, Size(::testing::Matcher(::testing::_), _)) + .WillByDefault( + [this](const char* path, u64& size) + { + AZStd::scoped_lock lock(m_streamerWrapper->m_mutex); + + const auto* file = m_streamerWrapper->FindFile(path); + + if (file) + { + size = file->size(); + return ResultCode::Success; + } + + AZ_Error("DisklessAssetManagerBase", false, "Failed to find virtual file %.*s", path); + + return ResultCode::Error; + }); + + m_prevFileIO = IO::FileIOBase::GetInstance(); + IO::FileIOBase::SetInstance(nullptr); + IO::FileIOBase::SetInstance(&m_fileIO); + } + + void DisklessAssetManagerBase::TearDown() + { + IO::FileIOBase::SetInstance(nullptr); + IO::FileIOBase::SetInstance(m_prevFileIO); + + BaseAssetManagerTest::TearDown(); + } + + IO::IStreamer* DisklessAssetManagerBase::CreateStreamer() + { + m_streamerWrapper = AZStd::make_unique(); + + return &(m_streamerWrapper->m_mockStreamer); + } + + void DisklessAssetManagerBase::DestroyStreamer(IO::IStreamer*) + { + m_streamerWrapper = nullptr; + } + + void DisklessAssetManagerBase::WriteAssetToDisk(const AZStd::string& assetName, const AZStd::string&) + { + AZStd::string assetFileName = GetTestFolderPath() + assetName; + + AssetWithCustomData asset; + + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile(assetFileName, &asset, m_serializeContext)); + } + + void DisklessAssetManagerBase::DeleteAssetFromDisk(const AZStd::string&) + { + + } } diff --git a/Code/Framework/AzCore/Tests/Asset/BaseAssetManagerTest.h b/Code/Framework/AzCore/Tests/Asset/BaseAssetManagerTest.h index 29c2c124cd..af48c74a60 100644 --- a/Code/Framework/AzCore/Tests/Asset/BaseAssetManagerTest.h +++ b/Code/Framework/AzCore/Tests/Asset/BaseAssetManagerTest.h @@ -20,7 +20,8 @@ #include #include #include - +#include +#include namespace UnitTest { @@ -58,7 +59,11 @@ namespace UnitTest // Subclasses can optionally override the streamer creation and destruction virtual IO::IStreamer* CreateStreamer() { return aznew IO::Streamer(AZStd::thread_desc{}, StreamerComponent::CreateStreamerStack()); } - virtual void DestroyStreamer(IO::IStreamer* streamer) { delete streamer; } + virtual void DestroyStreamer(IO::IStreamer* streamer) + { + delete streamer; + streamer = nullptr; + } void SetUp() override; void TearDown() override; @@ -66,8 +71,8 @@ namespace UnitTest static void SuppressTraceOutput(bool suppress); // Helper methods to create and destroy actual assets on the disk for true end-to-end asset loading. - void WriteAssetToDisk(const AZStd::string& assetName, const AZStd::string& assetIdGuid); - void DeleteAssetFromDisk(const AZStd::string& assetName); + virtual void WriteAssetToDisk(const AZStd::string& assetName, const AZStd::string& assetIdGuid); + virtual void DeleteAssetFromDisk(const AZStd::string& assetName); void BlockUntilAssetJobsAreComplete(); @@ -82,4 +87,57 @@ namespace UnitTest AZStd::vector m_assetsWritten; }; + + struct ReadRequest + { + AZStd::chrono::milliseconds m_deadline{}; + AZ::IO::IStreamerTypes::Priority m_priority{}; + IO::IStreamerTypes::RequestMemoryAllocatorResult m_data{ nullptr, 0, IO::IStreamerTypes::MemoryType::ReadWrite }; + AZ::IO::IStreamer::OnCompleteCallback m_callback; + IO::FileRequestPtr m_request; + }; + + struct MemoryStreamerWrapper + { + MemoryStreamerWrapper(); + ~MemoryStreamerWrapper() = default; + + ReadRequest* GetReadRequest(IO::FileRequestHandle request); + + template + bool WriteMemoryFile(const AZStd::string& filePath, TObject* object, AZ::SerializeContext* context) + { + auto& buffer = m_virtualFiles[filePath]; + ByteContainerStream stream(&buffer); + + return AZ::Utils::SaveObjectToStream(stream, DataStream::StreamType::ST_XML, object, context); + } + + AZStd::vector* FindFile(AZStd::string_view path); + + ::testing::NiceMock m_mockStreamer; + IO::StreamerContext m_context; + AZStd::atomic_bool m_suspended{ false }; + + AZStd::recursive_mutex m_mutex; + AZStd::queue m_processingQueue; // Keeps tracks of requests that have been queued while processing is suspended + AZStd::vector m_readRequests; + AZStd::unordered_map> m_virtualFiles; + }; + + struct DisklessAssetManagerBase : BaseAssetManagerTest + { + void SetUp() override; + void TearDown() override; + IO::IStreamer* CreateStreamer() override; + void DestroyStreamer(IO::IStreamer*) override; + + void WriteAssetToDisk(const AZStd::string& assetName, const AZStd::string& assetIdGuid) override; + void DeleteAssetFromDisk(const AZStd::string& assetName) override; + + AZStd::unique_ptr m_streamerWrapper; + ::testing::NiceMock m_fileIO; + IO::FileIOBase* m_prevFileIO{}; + }; + } diff --git a/Code/Framework/AzCore/Tests/TestCatalog.cpp b/Code/Framework/AzCore/Tests/TestCatalog.cpp index c633c6391b..cb8fa11c72 100644 --- a/Code/Framework/AzCore/Tests/TestCatalog.cpp +++ b/Code/Framework/AzCore/Tests/TestCatalog.cpp @@ -167,7 +167,8 @@ namespace UnitTest if (!info.m_streamName.empty()) { AZStd::string fullName = GetTestFolderPath() + info.m_streamName; - info.m_dataLen = static_cast(IO::SystemFile::Length(fullName.c_str())); + IO::FileIOBase* io = IO::FileIOBase::GetInstance(); + io->Size(fullName.c_str(), info.m_dataLen); } else { @@ -187,8 +188,11 @@ namespace UnitTest if (!info.m_streamName.empty()) { + IO::FileIOBase* io = AZ::IO::FileIOBase::GetInstance(); + AZStd::string fullName = GetTestFolderPath() + info.m_streamName; - info.m_dataLen = static_cast(IO::SystemFile::Length(fullName.c_str())); + + io->Size(fullName.c_str(), info.m_dataLen); } else { From 57d688fbc1dcd51d9dce146c70457bb5c5c8acb3 Mon Sep 17 00:00:00 2001 From: AMZN-nggieber <52797929+AMZN-nggieber@users.noreply.github.com> Date: Wed, 1 Dec 2021 08:03:36 -0800 Subject: [PATCH 47/47] Added Tests for Gem Catalog Filtering (#5999) * Added Tests for Gem Catalog Filtering Signed-off-by: nggieber <52797929+AMZN-nggieber@users.noreply.github.com> * Addressed PR feedback, Renamed all tests to Osherove naming pattern Signed-off-by: nggieber <52797929+AMZN-nggieber@users.noreply.github.com> --- Code/Tools/ProjectManager/CMakeLists.txt | 1 + .../Source/GemCatalog/GemInfo.h | 4 +- .../ProjectManager/tests/GemCatalogTests.cpp | 543 +++++++++++++++++- 3 files changed, 529 insertions(+), 19 deletions(-) diff --git a/Code/Tools/ProjectManager/CMakeLists.txt b/Code/Tools/ProjectManager/CMakeLists.txt index a47ccb62c9..9974125ffb 100644 --- a/Code/Tools/ProjectManager/CMakeLists.txt +++ b/Code/Tools/ProjectManager/CMakeLists.txt @@ -92,6 +92,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) AZ::AzTest AZ::AzFramework AZ::AzFrameworkTestShared + AZ::AzQtComponents AZ::ProjectManager.Static ) diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.h index 5c1bc90c6e..23e95cf487 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.h +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.h @@ -73,10 +73,10 @@ namespace O3DE::ProjectManager QString m_path; QString m_name = "Unknown Gem Name"; - QString m_displayName = "Unknown Gem Name"; + QString m_displayName; QString m_creator = "Unknown Creator"; GemOrigin m_gemOrigin = Local; - bool m_isAdded = false; //! Is the gem currently added and enabled in the project? + bool m_isAdded = false; //! Is the gem explicitly added (not a dependency) and enabled in the project? QString m_summary = "No summary provided."; Platforms m_platforms; Types m_types; //! Asset and/or Code and/or Tool diff --git a/Code/Tools/ProjectManager/tests/GemCatalogTests.cpp b/Code/Tools/ProjectManager/tests/GemCatalogTests.cpp index f5c6d5196a..701a1ddcef 100644 --- a/Code/Tools/ProjectManager/tests/GemCatalogTests.cpp +++ b/Code/Tools/ProjectManager/tests/GemCatalogTests.cpp @@ -8,8 +8,8 @@ #include #include -#include +#include namespace O3DE::ProjectManager { @@ -17,14 +17,22 @@ namespace O3DE::ProjectManager : public ::UnitTest::ScopedAllocatorSetupFixture { public: + void SetUp() override + { + m_gemModel.reset(new GemModel()); + } - GemCatalogTests() = default; + void TearDown() override + { + m_gemModel.release(); + } + + protected: + AZStd::unique_ptr m_gemModel; }; - TEST_F(GemCatalogTests, GemCatalog_Displays_But_Does_Not_Add_Dependencies) + TEST_F(GemCatalogTests, GemCatalog_GemWithDependencies_DisplaysButDoesNotAddDependencies) { - GemModel* gemModel = new GemModel(); - // given 3 gems a,b,c where a depends on b which depends on c GemInfo gemA, gemB, gemC; QModelIndex indexA, indexB, indexC; @@ -35,30 +43,531 @@ namespace O3DE::ProjectManager gemA.m_dependencies = QStringList({ "b" }); gemB.m_dependencies = QStringList({ "c" }); - gemModel->AddGem(gemA); - indexA = gemModel->FindIndexByNameString(gemA.m_name); + indexA = m_gemModel->AddGem(gemA); + indexB = m_gemModel->AddGem(gemB); + indexC = m_gemModel->AddGem(gemC); - gemModel->AddGem(gemB); - indexB = gemModel->FindIndexByNameString(gemB.m_name); - - gemModel->AddGem(gemC); - indexC = gemModel->FindIndexByNameString(gemC.m_name); - - gemModel->UpdateGemDependencies(); + m_gemModel->UpdateGemDependencies(); EXPECT_FALSE(GemModel::IsAdded(indexA)); EXPECT_FALSE(GemModel::IsAddedDependency(indexB) || GemModel::IsAddedDependency(indexC)); // when a is added - GemModel::SetIsAdded(*gemModel, indexA, true); + GemModel::SetIsAdded(*m_gemModel, indexA, true); // expect b and c are now dependencies of an added gem but not themselves added // cmake will handle dependencies EXPECT_TRUE(GemModel::IsAddedDependency(indexB) && GemModel::IsAddedDependency(indexC)); - EXPECT_TRUE(!GemModel::IsAdded(indexB) && !GemModel::IsAdded(indexC)); + EXPECT_FALSE(GemModel::IsAdded(indexB) || GemModel::IsAdded(indexC)); - QVector gemsToAdd = gemModel->GatherGemsToBeAdded(); + const QVector& gemsToAdd = m_gemModel->GatherGemsToBeAdded(); EXPECT_TRUE(gemsToAdd.size() == 1); EXPECT_EQ(GemModel::GetName(gemsToAdd.at(0)), gemA.m_name); } + + class GemCatalogFilterTests + : public GemCatalogTests + { + public: + void SetUp() override + { + GemCatalogTests::SetUp(); + m_proxyModel.reset(new GemSortFilterProxyModel(m_gemModel.get())); + } + + void TearDown() override + { + m_proxyModel.release(); + GemCatalogTests::TearDown(); + } + + protected: + AZStd::unique_ptr m_proxyModel; + }; + + class GemCatalogSearchFilterTests + : public GemCatalogFilterTests + { + public: + void SetUp() override + { + GemCatalogFilterTests::SetUp(); + + GemInfo gemfilterName, gemfilterDisplayName, gemfilterCreator, gemfilterSummary, gemfilterFeature; + + gemfilterName.m_name = "Name"; + gemfilterDisplayName.m_name = "D"; + gemfilterCreator.m_name = "C"; + gemfilterSummary.m_name = "S"; + gemfilterFeature.m_name = "F"; + + gemfilterDisplayName.m_displayName = "Display Name"; + gemfilterCreator.m_creator = "Johnathon Doe"; + gemfilterSummary.m_summary = "Unique Summary"; + gemfilterFeature.m_features.append("Creative Feature"); + + m_gemRows.append(m_gemModel->AddGem(gemfilterName).row()); + m_gemRows.append(m_gemModel->AddGem(gemfilterDisplayName).row()); + m_gemRows.append(m_gemModel->AddGem(gemfilterCreator).row()); + m_gemRows.append(m_gemModel->AddGem(gemfilterSummary).row()); + m_gemRows.append(m_gemModel->AddGem(gemfilterFeature).row()); + } + + protected: + enum RowOrder + { + Name, + DisplayName, + Creator, + Summary, + Features + }; + + QVector m_gemRows; + }; + + TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringName_ShowsNameGems) + { + m_proxyModel->SetSearchString("Name"); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex())); + } + + TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringDisplayName_ShowsDisplayNameGem) + { + m_proxyModel->SetSearchString("Display Name"); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex())); + } + + TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringCreator_ShowsCreatorGem) + { + m_proxyModel->SetSearchString("Johnathon Doe"); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex())); + } + + TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringSummary_ShowsSummaryGem) + { + m_proxyModel->SetSearchString("Unique Summary"); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex())); + } + + TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringFeatures_ShowsFeatureGem) + { + m_proxyModel->SetSearchString("Creative"); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex())); + } + + TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringEmpty_ShowsAll) + { + m_proxyModel->SetSearchString(""); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex())); + } + + TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringCommonCharacter_ShowsAll) + { + // All gems contain "a" in a searchable field so all should be shown + m_proxyModel->SetSearchString("a"); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex())); + } + + TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringDifferentCaseCommonCharacter_ShowsAll) + { + // No gems contain the character "A" but search should be case insensitive + m_proxyModel->SetSearchString("A"); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex())); + } + + TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringNoneContainCharacter_ShowsNone) + { + // No gems contain the character "z" or "Z" so none should be shown + m_proxyModel->SetSearchString("z"); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex())); + } + + TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringPartialMatchString_ShowsNone) + { + // Token matching is currently not supported + // The whole string must match a substring + m_proxyModel->SetSearchString("Name Token"); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex())); + } + + class GemCatalogSelectedActiveFilterTests + : public GemCatalogFilterTests + { + public: + void SetUp() override + { + GemCatalogFilterTests::SetUp(); + + GemInfo gemSelected, gemSelectedDep, gemUnselected, gemUnselectedDep, gemActive, gemInactive; + + gemSelected.m_name = "selected"; + gemSelectedDep.m_name = "selectedDep"; + gemUnselected.m_name = "unselected"; + gemUnselectedDep.m_name = "unselectedDep"; + gemActive.m_name = "active"; + gemInactive.m_name = "inactive"; + + gemSelected.m_dependencies = QStringList({ "selectedDep" }); + gemUnselected.m_dependencies = QStringList({ "unselectedDep" }); + + m_gemIndices.append(m_gemModel->AddGem(gemSelected)); + m_gemIndices.append(m_gemModel->AddGem(gemSelectedDep)); + m_gemIndices.append(m_gemModel->AddGem(gemUnselected)); + m_gemIndices.append(m_gemModel->AddGem(gemUnselectedDep)); + m_gemIndices.append(m_gemModel->AddGem(gemActive)); + m_gemIndices.append(m_gemModel->AddGem(gemInactive)); + + m_gemModel->UpdateGemDependencies(); + + // Set intial state of catalog with the to be unselected gem currently added along with active gem + GemModel::SetIsAdded(*m_gemModel, m_gemIndices[Unselected], true); + GemModel::SetWasPreviouslyAdded(*m_gemModel, m_gemIndices[Unselected], true); + GemModel::SetIsAdded(*m_gemModel, m_gemIndices[Active], true); + GemModel::SetWasPreviouslyAdded(*m_gemModel, m_gemIndices[Active], true); + + // Add selected gem and remove unselected gem + GemModel::SetIsAdded(*m_gemModel, m_gemIndices[Selected], true); + GemModel::SetIsAdded(*m_gemModel, m_gemIndices[Unselected], false); + } + + protected: + enum IndexOrder + { + Selected, + SelectedDep, + Unselected, + UnselectedDep, + Active, + Inactive + }; + + QVector m_gemIndices; + }; + + TEST_F(GemCatalogSelectedActiveFilterTests, GemCatalogFilters_SelectedActiveIntialState_AddedGemsAndDependenciesAreAdded) + { + // Check if gems are all in expected state + // if this test fails all other Selected/Active tests are invalid + EXPECT_TRUE(GemModel::IsAdded(m_gemIndices[Selected])); + EXPECT_TRUE(GemModel::IsAddedDependency(m_gemIndices[SelectedDep])); + EXPECT_FALSE(GemModel::IsAdded(m_gemIndices[Unselected])); + EXPECT_FALSE(GemModel::IsAddedDependency(m_gemIndices[UnselectedDep])); + EXPECT_TRUE(GemModel::IsAdded(m_gemIndices[Active])); + EXPECT_FALSE(GemModel::IsAdded(m_gemIndices[Inactive])); + } + + TEST_F(GemCatalogSelectedActiveFilterTests, GemCatalogFilters_SelectedActiveNoFilter_ShowsAll) + { + // Filter is clear + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Selected].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[SelectedDep].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Unselected].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[UnselectedDep].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Active].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Inactive].row(), QModelIndex())); + } + + TEST_F(GemCatalogSelectedActiveFilterTests, GemCatalogFilters_FilterSelected_ShowsSelectedAndDependencies) + { + // Check selected filter + // Selected dependencies should also be shown + m_proxyModel->SetGemSelected(GemSortFilterProxyModel::GemSelected::Selected); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Selected].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[SelectedDep].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Unselected].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[UnselectedDep].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Active].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Inactive].row(), QModelIndex())); + } + + TEST_F(GemCatalogSelectedActiveFilterTests, GemCatalogFilters_FilterUnselected_ShowsUnselectedAndDependencies) + { + // Check unselected filter + // Unselected dependencies should also be shown + m_proxyModel->SetGemSelected(GemSortFilterProxyModel::GemSelected::Unselected); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Selected].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[SelectedDep].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Unselected].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[UnselectedDep].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Active].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Inactive].row(), QModelIndex())); + } + + TEST_F(GemCatalogSelectedActiveFilterTests, GemCatalogFilters_FilterSelectedAndUnselected_ShowsAllChangesAndDependencies) + { + // Check both un/selected filter + m_proxyModel->SetGemSelected(GemSortFilterProxyModel::GemSelected::Both); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Selected].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[SelectedDep].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Unselected].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[UnselectedDep].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Active].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Inactive].row(), QModelIndex())); + } + + TEST_F(GemCatalogSelectedActiveFilterTests, GemCatalogFilters_FilterActive_ShowsActive) + { + // Check active filter + // Active dependencies should also be shown + m_proxyModel->SetGemActive(GemSortFilterProxyModel::GemActive::Active); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Selected].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[SelectedDep].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Unselected].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[UnselectedDep].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Active].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Inactive].row(), QModelIndex())); + } + + TEST_F(GemCatalogSelectedActiveFilterTests, GemCatalogFilters_FilterActive_ShowsInactive) + { + // Check inactive filter + m_proxyModel->SetGemActive(GemSortFilterProxyModel::GemActive::Inactive); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Selected].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[SelectedDep].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Unselected].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[UnselectedDep].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Active].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Inactive].row(), QModelIndex())); + } + + class GemCatalogMiscFilterTests + : public GemCatalogFilterTests + { + public: + void SetUp() override + { + GemCatalogFilterTests::SetUp(); + + GemInfo gemA, gemB, gemC; + + gemA.m_name = "Default Audio"; + gemB.m_name = "Mobile UX"; + gemC.m_name = "City Props"; + + gemA.m_gemOrigin = GemInfo::GemOrigin::Open3DEngine; + gemB.m_gemOrigin = GemInfo::GemOrigin::Local; + gemC.m_gemOrigin = GemInfo::GemOrigin::Remote; + + gemA.m_types = GemInfo::Type::Code; + gemB.m_types = GemInfo::Type::Code | GemInfo::Type::Tool; + gemC.m_types = GemInfo::Type::Asset; + + using Plat = GemInfo::Platform; + gemA.m_platforms = Plat::Windows; + gemB.m_platforms = Plat::Android | Plat::iOS; + gemC.m_platforms = Plat::Android | Plat::iOS | Plat::Linux | Plat::macOS | Plat::Windows; + + gemA.m_features = QStringList({ "Audio", "Framework", "SDK" }); + gemB.m_features = QStringList({ "Framework", "Tools", "UI" }); + gemC.m_features = QStringList({ "Assets", "Content", "Environment" }); + + m_gemRows.append(m_gemModel->AddGem(gemA).row()); + m_gemRows.append(m_gemModel->AddGem(gemB).row()); + m_gemRows.append(m_gemModel->AddGem(gemC).row()); + } + + protected: + enum RowOrder + { + DefaultAudio, + MobileUX, + CityProps + }; + + QVector m_gemRows; + }; + + TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_MiscNoFilter_ShowsAll) + { + // No filter + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + } + + TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterSingleOrigin_ShowsOriginMatch) + { + m_proxyModel->SetGemOrigins(GemInfo::GemOrigin::Open3DEngine); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + + m_proxyModel->SetGemOrigins(GemInfo::GemOrigin::Local); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + + m_proxyModel->SetGemOrigins(GemInfo::GemOrigin::Remote); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + } + + TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterMultipleOrigins_ShowsMultipleOriginMatches) + { + m_proxyModel->SetGemOrigins(GemInfo::GemOrigin::Open3DEngine | GemInfo::GemOrigin::Local); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + } + + TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterSingleType_ShowsTypeMatch) + { + m_proxyModel->SetTypes(GemInfo::Type::Code); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + + m_proxyModel->SetTypes(GemInfo::Type::Tool); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + + m_proxyModel->SetTypes(GemInfo::Type::Asset); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + } + + TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterMultipleTypes_ShowsMultipleTypeMatches) + { + m_proxyModel->SetTypes(GemInfo::Type::Tool | GemInfo::Type::Asset); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + } + + TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterSinglePlatform_ShowsPlatformMatch) + { + m_proxyModel->SetPlatforms(GemInfo::Platform::Windows); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + + m_proxyModel->SetPlatforms(GemInfo::Platform::Android); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + + m_proxyModel->SetPlatforms(GemInfo::Platform::macOS); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + } + + TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterMultiplePlatforms_ShowsMultiplePlatformMatches) + { + m_proxyModel->SetPlatforms(GemInfo::Platform::Android | GemInfo::Platform::iOS); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + } + + TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterSingleFeature_ShowsFeatureMatch) + { + m_proxyModel->SetFeatures({ "Audio" }); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + + m_proxyModel->SetFeatures({ "Tools", }); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + + m_proxyModel->SetFeatures({ "Environment" }); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + } + + TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterMultipleFeatures_ShowsMultipleFeatureMatches) + { + m_proxyModel->SetFeatures({ "Assets", "Framework" }); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + } + + TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterPartialMatchFeature_ShowsNone) + { + // Features must be an exact match to filter by them directly + m_proxyModel->SetFeatures({ "Frame" }); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + } }