// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreTypes.h" #include "Containers/Ticker.h" #include "Framework/Commands/UICommandList.h" #include "Input/DragAndDrop.h" // TraceAnalysis #include "Trace/StoreConnection.h" // TraceInsightsCore #include "InsightsCore/Common/AvailabilityCheck.h" #include "InsightsCore/Common/Stopwatch.h" // TraceInsights #include "Insights/IInsightsManager.h" #include "Insights/InsightsCommands.h" #include "Insights/InsightsSettings.h" #include "Insights/IUnrealInsightsModule.h" //////////////////////////////////////////////////////////////////////////////////////////////////// namespace UE::Trace { class FStoreClient; } namespace TraceServices { class IAnalysisService; class IModuleService; } class FInsightsTestRunner; namespace UE::Insights { class SSessionInfoWindow; class FInsightsMenuBuilder; /** * Struct that holds data about in progress async operations */ struct FAsyncTaskData { FString Name; FGraphEventRef GraphEvent; FAsyncTaskData(FGraphEventRef InGraphEvent, const FString InName) { Name = InName; GraphEvent = InGraphEvent; } }; //////////////////////////////////////////////////////////////////////////////////////////////////// /** * This class manages following areas: * Connecting/disconnecting to source trace * Global Unreal Insights application state and settings */ class FInsightsManager : public TSharedFromThis, public ::Insights::IInsightsManager { friend class FInsightsActionManager; public: /** Creates the main manager, only one instance can exist. */ FInsightsManager(TSharedRef TraceAnalysisService, TSharedRef TraceModuleService); /** Virtual destructor. */ virtual ~FInsightsManager(); /** * Creates an instance of the main manager and initializes global instance with the previously created instance of the manager. * @param TraceAnalysisService The trace analysis service * @param TraceModuleService The trace module service */ static TSharedPtr CreateInstance(TSharedRef TraceAnalysisService, TSharedRef TraceModuleService); /** @return the global instance of the main manager (FInsightsManager). */ static TSharedPtr Get(); ////////////////////////////////////////////////// // IInsightsComponent virtual void Initialize(IUnrealInsightsModule& InsightsModule) override; virtual void Shutdown() override; virtual void RegisterMajorTabs(IUnrealInsightsModule& InsightsModule) override; virtual void UnregisterMajorTabs() override; virtual bool Exec(const TCHAR* Cmd, FOutputDevice& Ar) override; ////////////////////////////////////////////////// TSharedRef GetAnalysisService() const { return AnalysisService; } TSharedRef GetModuleService() const { return ModuleService; } ////////////////////////////////////////////////// // Trace Store Connection wrapper bool ConnectToStore(const TCHAR* Host, uint32 Port = 0) { return TraceStoreConnection.ConnectToStore(Host, Port); } bool ReconnectToStore() { return TraceStoreConnection.ReconnectToStore(); } UE::Trace::FStoreClient* GetStoreClient() const { return TraceStoreConnection.GetStoreClient(); } FCriticalSection& GetStoreClientCriticalSection() const { return TraceStoreConnection.GetStoreClientCriticalSection(); } bool GetStoreAddressAndPort(uint32& OutStoreAddress, uint32& OutStorePort) const { return TraceStoreConnection.GetStoreAddressAndPort(OutStoreAddress, OutStorePort); } FString GetStoreDir() const { return TraceStoreConnection.GetStoreDir(); } const FString& GetLastStoreHost() const { return TraceStoreConnection.GetLastStoreHost(); } uint32 GetLastStorePort() const { return TraceStoreConnection.GetLastStorePort(); } const bool IsLocalHost() const { return TraceStoreConnection.IsLocalHost(); } const bool CanChangeStoreSettings() const { return TraceStoreConnection.CanChangeStoreSettings(); } ////////////////////////////////////////////////// // Trace Session /** @return an instance of the trace analysis session. */ TSharedPtr GetSession() const; /** @return the id of the trace being analyzed. */ uint32 GetTraceId() const { return CurrentTraceId; } /** @return the filename of the trace being analyzed. */ const FString& GetTraceFilename() const { return CurrentTraceFilename; } ////////////////////////////////////////////////// /** @return UI command list for the main manager. */ const TSharedRef GetCommandList() const; /** @return an instance of the main commands. */ static const FInsightsCommands& GetCommands(); /** @return an instance of the main action manager. */ static FInsightsActionManager& GetActionManager(); /** @return an instance of the main settings. */ static FInsightsSettings& GetSettings(); ////////////////////////////////////////////////// // Session Info void AssignSessionInfoWindow(const TSharedRef& InSessionInfoWindow) { SessionInfoWindow = InSessionInfoWindow; } void RemoveSessionInfoWindow() { SessionInfoWindow.Reset(); } /** * Converts profiler window weak pointer to a shared pointer and returns it. * Make sure the returned pointer is valid before trying to dereference it. */ TSharedPtr GetSessionInfoWindow() const { return SessionInfoWindow.Pin(); } //////////////////////////////////////////////////////////////////////////////////////////////////// // Getters and setters used by Toggle Commands. /** @return true, if UI is allowed to display debug info. */ const bool IsDebugInfoEnabled() const { return bIsDebugInfoEnabled; } void SetDebugInfo(const bool bDebugInfoEnabledState) { bIsDebugInfoEnabled = bDebugInfoEnabledState; } //////////////////////////////////////////////////////////////////////////////////////////////////// /** * Shows the open file dialog for choosing a trace file. * @param OutTraceFile - The chosen trace file, if successful * @return True, if successful. */ bool ShowOpenTraceFileDialog(FString& OutTraceFile) const; /** * Shows the open file dialog and starts analysis session for the chosen trace file, in a new Unreal Insights instance. */ void OpenTraceFile() const; /** * Starts analysis session for the specified trace file, in a new Unreal Insights instance. * @param TraceFilename - The trace file to analyze */ void OpenTraceFile(const FString& TraceFilename) const; void ToggleAutoLoadLiveSession() { bIsAutoLoadLiveSessionEnabled = !bIsAutoLoadLiveSessionEnabled; } bool IsAutoLoadLiveSessionEnabled() const { return bIsAutoLoadLiveSessionEnabled; } void AutoLoadLiveSession(); /** * Creates a new analysis session instance and loads the latest available trace that is live. * Replaces the current analysis session. On failure, if InRetryTime is > 0, will retry connecting every frame for RetryTime seconds * @param InRetryTime - On failure, how many seconds to retry connecting during FInsightsManager::Tick */ void LoadLastLiveSession(float InRetryTime = 1.0f); /** * Creates a new analysis session instance using the specified trace id. * Replaces the current analysis session. * @param TraceId - The id of the trace to analyze * @param InAutoQuit - The Application will close when session analysis is complete or fails to start */ void LoadTrace(uint32 TraceId, bool InAutoQuit = false); /** * Shows the open file dialog and creates a new analysis session instance for the chosen trace file. * Replaces the current analysis session. */ void LoadTraceFile(); /** * Creates a new analysis session instance and loads a trace file from the specified location. * Replaces the current analysis session. * @param TraceFilename - The trace file to analyze * @param InAutoQuit - The Application will close when session analysis is complete or fails to start */ void LoadTraceFile(const FString& TraceFilename, bool InAutoQuit = false); uint16 ListenForDirectTrace(); bool OnDragOver(const FDragDropEvent& DragDropEvent); bool OnDrop(const FDragDropEvent& DragDropEvent); void UpdateAppTitle(); /** Opens the Settings dialog. */ void OpenSettings(); void UpdateSessionDuration(); void CheckMemoryUsage(); bool IsAnalysisComplete() const { return bIsAnalysisComplete; } double GetSessionDuration() const { return SessionDuration; } double GetAnalysisDuration() const { return AnalysisDuration; } double GetAnalysisSpeedFactor() const { return AnalysisSpeedFactor; } TSharedPtr GetInsightsMenuBuilder() { return InsightsMenuBuilder; } const FName& GetLogListingName() const { return LogListingName; } void ScheduleCommand(const FString& InCmd); /** Resets (closes) current session instance. */ void ResetSession(bool bNotify = true); void OpenTraceControlWindow(); //////////////////////////////////////////////////////////////////////////////////////////////////// // SessionChangedEvent public: /** The event to execute when the session has changed. */ virtual ::Insights::IInsightsManager::FSessionChangedEvent& GetSessionChangedEvent() override { return SessionChangedEvent; } private: /** The event to execute when the session has changed. */ ::Insights::IInsightsManager::FSessionChangedEvent SessionChangedEvent; //////////////////////////////////////////////////////////////////////////////////////////////////// // SessionAnalysisCompletedEvent public: /** The event to execute when session analysis is complete. */ virtual ::Insights::IInsightsManager::FSessionAnalysisCompletedEvent& GetSessionAnalysisCompletedEvent() override { return SessionAnalysisCompletedEvent; } private: /** The event to execute when session analysis is completed. */ ::Insights::IInsightsManager::FSessionAnalysisCompletedEvent SessionAnalysisCompletedEvent; //////////////////////////////////////////////////////////////////////////////////////////////////// private: /** Binds our UI commands to delegates. */ void BindCommands(); /** Called to spawn the Session Info major tab. */ TSharedRef SpawnSessionInfoTab(const FSpawnTabArgs& Args); /** Callback called when the Session Info major tab is closed. */ void OnSessionInfoTabClosed(TSharedRef TabBeingClosed); /** Updates this manager, done through FCoreTicker. */ bool Tick(float DeltaTime); /** Extract messages from the session */ void PollAnalysisInfo(); void OnSessionChanged(); void OnSessionAnalysisCompleted(); void SpawnAndActivateTabs(); void ActivateTimingInsightsTab(); bool HandleResponseFileCmd(const TCHAR* ResponseFile, FOutputDevice& Ar); void RegisterTraceControlTab(); TSharedRef SpawnTraceControlTab(const FSpawnTabArgs& Args); void OnTraceControlTabClosed(TSharedRef TabBeingClosed); private: bool bIsInitialized = false; /** If true, the "high system memory usage warning" will be disabled until the system memory usage first drops below a certain threshold. */ bool bMemUsageLimitHysteresis = false; /** The timestamp when has occurred the last check for system memory usage. */ uint64 MemUsageLimitLastTimestamp = 0; /** The name of the Unreal Insights log listing. */ FName LogListingName; /** Name used for Analysis log in Message Log. */ FName AnalysisLogListingName; /** The delegate to be invoked when this manager ticks. */ FTickerDelegate OnTick; /** Handle to the registered OnTick. */ FTSTicker::FDelegateHandle OnTickHandle; TSharedRef AnalysisService; TSharedRef ModuleService; /** The trace analysis session. */ TSharedPtr Session; /** The id of the trace being analyzed. */ uint32 CurrentTraceId = 0; /** The filename of the trace being analyzed. */ FString CurrentTraceFilename; /** List of UI commands for this manager. This will be filled by this and corresponding classes. */ TSharedRef CommandList; /** An instance of the main action manager. */ FInsightsActionManager ActionManager; /** An instance of the main settings. */ FInsightsSettings Settings; /** A weak pointer to the Session Info window. */ TWeakPtr SessionInfoWindow; /** If enabled, UI can display additional info for debugging purposes. */ bool bIsDebugInfoEnabled = false; bool bIsMainTabSet = false; bool bIsSessionInfoSet = false; bool bIsAnalysisComplete = false; bool bSessionAnalysisCompletedAutoQuit = false; float RetryLoadLastLiveSessionTimer = 0.0f; bool bIsAutoLoadLiveSessionEnabled = false; TSet AutoLoadedTraceIds; // list of trace ids for the auto loaded live sessions UE::Insights::FStopwatch AnalysisStopwatch; double SessionDuration = 0.0; double AnalysisDuration = 0.0; double AnalysisSpeedFactor = 0.0; TSharedPtr InsightsMenuBuilder; TSharedPtr TestRunner; FString SessionAnalysisCompletedCmd; static const TCHAR* AutoQuitMsg; static const TCHAR* AutoQuitMsgOnFail; TDoubleLinkedList InProgressAsyncTasks; /** A shared pointer to the global instance of the main manager. */ static TSharedPtr Instance; /** The Trace Store connection */ UE::Trace::FStoreConnection TraceStoreConnection; FGuid InstanceId; TWeakPtr TraceControl; }; } // namespace UE::Insights