From 5d5087e0d34b327521c346395996ceb778bb5633 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Tue, 9 Nov 2021 11:11:15 -0800 Subject: [PATCH] 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) {