2019-12-26 23:06:02 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
2019-06-03 15:32:00 -04:00
# include "UserInterfaceCommand.h"
# include "Async/TaskGraphInterfaces.h"
2020-01-14 04:50:47 -05:00
//#include "Brushes/SlateImageBrush.h"
2019-06-03 15:32:00 -04:00
# include "Containers/Ticker.h"
2020-10-08 05:07:59 -04:00
# include "CoreGlobals.h"
2019-06-03 15:32:00 -04:00
# include "Framework/Application/SlateApplication.h"
# include "Framework/Docking/LayoutService.h"
# include "Framework/Docking/TabManager.h"
# include "HAL/PlatformApplicationMisc.h"
# include "HAL/PlatformProcess.h"
# include "Interfaces/IPluginManager.h"
# include "ISlateReflectorModule.h"
# include "ISourceCodeAccessModule.h"
# include "Misc/CommandLine.h"
# include "Misc/ConfigCacheIni.h"
2020-01-14 04:50:47 -05:00
# include "Misc/Parse.h"
2019-06-03 15:32:00 -04:00
# include "Modules/ModuleManager.h"
# include "StandaloneRenderer.h"
2024-08-01 10:28:39 -04:00
# include "Styling/AppStyle.h"
2019-06-03 15:32:00 -04:00
# include "Widgets/Docking/SDockTab.h"
2024-08-01 10:28:39 -04:00
// TraceInsightsCore
# include "InsightsCore/Version.h"
2019-06-03 15:32:00 -04:00
2024-08-01 10:28:39 -04:00
// TraceInsights
# include "Insights/IUnrealInsightsModule.h"
// TraceInsightsFrontend
# include "InsightsFrontend/ITraceInsightsFrontendModule.h"
2019-06-03 15:32:00 -04:00
////////////////////////////////////////////////////////////////////////////////////////////////////
# define IDEAL_FRAMERATE 60
2021-04-14 09:17:09 -04:00
# define BACKGROUND_FRAMERATE 4
# define IDLE_INPUT_SECONDS 5.0f
2019-06-03 15:32:00 -04:00
////////////////////////////////////////////////////////////////////////////////////////////////////
namespace UserInterfaceCommand
{
TSharedRef < FWorkspaceItem > DeveloperTools = FWorkspaceItem : : NewGroup ( NSLOCTEXT ( " UnrealInsights " , " DeveloperToolsMenu " , " Developer Tools " ) ) ;
2021-04-14 09:17:09 -04:00
bool IsApplicationBackground ( )
{
return ! FPlatformApplicationMisc : : IsThisApplicationForeground ( ) & & ( FPlatformTime : : Seconds ( ) - FSlateApplication : : Get ( ) . GetLastUserInteractionTime ( ) ) > IDLE_INPUT_SECONDS ;
}
void AdaptiveSleep ( float Seconds )
{
const double IdealFrameTime = 1.0 / IDEAL_FRAMERATE ;
if ( Seconds > IdealFrameTime )
{
// While in background, pump message at ideal frame time and get out of background as soon as input is received
const double WakeupTime = FPlatformTime : : Seconds ( ) + Seconds ;
while ( IsApplicationBackground ( ) & & FPlatformTime : : Seconds ( ) < WakeupTime )
{
FSlateApplication : : Get ( ) . PumpMessages ( ) ;
FPlatformProcess : : Sleep ( ( float ) FMath : : Clamp ( WakeupTime - FPlatformTime : : Seconds ( ) , 0.0 , IdealFrameTime ) ) ;
}
}
else
{
FPlatformProcess : : Sleep ( Seconds ) ;
}
}
2019-06-03 15:32:00 -04:00
}
////////////////////////////////////////////////////////////////////////////////////////////////////
2024-08-01 10:28:39 -04:00
void FUserInterfaceCommand : : Run ( bool bFrontendMode , const FString & TraceFileToOpen )
2020-01-16 07:28:54 -05:00
{
2020-06-23 18:40:00 -04:00
// Crank up a normal Slate application using the platform's standalone renderer.
FSlateApplication : : InitializeAsStandaloneApplication ( GetStandardStandaloneRenderer ( ) ) ;
2019-06-03 15:32:00 -04:00
// Load required modules.
2024-08-01 10:28:39 -04:00
FModuleManager : : Get ( ) . LoadModuleChecked ( " TraceInsightsCore " ) ;
if ( bFrontendMode )
{
FModuleManager : : Get ( ) . LoadModuleChecked ( " TraceInsightsFrontend " ) ;
}
else
{
FModuleManager : : Get ( ) . LoadModuleChecked ( " TraceInsights " ) ;
}
2019-06-03 15:32:00 -04:00
// Load plug-ins.
IPluginManager : : Get ( ) . LoadModulesForEnabledPlugins ( ELoadingPhase : : PreDefault ) ;
2020-01-24 09:34:25 -05:00
IPluginManager : : Get ( ) . LoadModulesForEnabledPlugins ( ELoadingPhase : : Default ) ;
2019-06-03 15:32:00 -04:00
// Load optional modules.
2020-06-24 13:38:03 -04:00
if ( FModuleManager : : Get ( ) . ModuleExists ( TEXT ( " SettingsEditor " ) ) )
{
FModuleManager : : Get ( ) . LoadModule ( " SettingsEditor " ) ;
}
2019-06-03 15:32:00 -04:00
2024-08-01 10:28:39 -04:00
InitializeSlateApplication ( bFrontendMode , TraceFileToOpen ) ;
2019-06-03 15:32:00 -04:00
2024-04-04 14:01:37 -04:00
IPluginManager : : Get ( ) . LoadModulesForEnabledPlugins ( ELoadingPhase : : PostDefault ) ;
2024-08-01 10:28:39 -04:00
//////////////////////////////////////////////////
2019-06-03 15:32:00 -04:00
// Initialize source code access.
2024-08-01 10:28:39 -04:00
2019-06-03 15:32:00 -04:00
// Load the source code access module.
ISourceCodeAccessModule & SourceCodeAccessModule = FModuleManager : : LoadModuleChecked < ISourceCodeAccessModule > ( FName ( " SourceCodeAccess " ) ) ;
// Manually load in the source code access plugins, as standalone programs don't currently support plugins.
# if PLATFORM_MAC
2020-11-02 14:48:49 -04:00
IModuleInterface & XCodeSourceCodeAccessModule = FModuleManager : : LoadModuleChecked < IModuleInterface > ( FName ( " XCodeSourceCodeAccess " ) ) ;
SourceCodeAccessModule . SetAccessor ( FName ( " XCodeSourceCodeAccess " ) ) ;
2019-06-03 15:32:00 -04:00
# elif PLATFORM_WINDOWS
2020-11-02 14:48:49 -04:00
IModuleInterface & VisualStudioSourceCodeAccessModule = FModuleManager : : LoadModuleChecked < IModuleInterface > ( FName ( " VisualStudioSourceCodeAccess " ) ) ;
SourceCodeAccessModule . SetAccessor ( FName ( " VisualStudioSourceCodeAccess " ) ) ;
2019-06-03 15:32:00 -04:00
# endif
2024-08-01 10:28:39 -04:00
//////////////////////////////////////////////////
2019-06-03 15:32:00 -04:00
# if WITH_SHARED_POINTER_TESTS
2021-04-22 13:07:08 -04:00
SharedPointerTesting : : TestSharedPointer < ESPMode : : NotThreadSafe > ( ) ;
2019-06-03 15:32:00 -04:00
SharedPointerTesting : : TestSharedPointer < ESPMode : : ThreadSafe > ( ) ;
# endif
2024-05-22 04:06:05 -04:00
const bool bDisableFramerateThrottle = FParse : : Param ( FCommandLine : : Get ( ) , TEXT ( " DisableFramerateThrottle " ) ) ;
2019-06-03 15:32:00 -04:00
// Enter main loop.
double DeltaTime = 0.0 ;
double LastTime = FPlatformTime : : Seconds ( ) ;
const float IdealFrameTime = 1.0f / IDEAL_FRAMERATE ;
2021-04-14 09:17:09 -04:00
const float BackgroundFrameTime = 1.0f / BACKGROUND_FRAMERATE ;
2019-06-03 15:32:00 -04:00
2019-09-12 14:21:26 -04:00
while ( ! IsEngineExitRequested ( ) )
2019-06-03 15:32:00 -04:00
{
// Save the state of the tabs here rather than after close of application (the tabs are undesirably saved out with ClosedTab state on application close).
//UserInterfaceCommand::UserConfiguredNewLayout = FGlobalTabmanager::Get()->PersistLayout();
FTaskGraphInterface : : Get ( ) . ProcessThreadUntilIdle ( ENamedThreads : : GameThread ) ;
FSlateApplication : : Get ( ) . PumpMessages ( ) ;
FSlateApplication : : Get ( ) . Tick ( ) ;
2022-09-29 20:32:42 -04:00
FTSTicker : : GetCoreTicker ( ) . Tick ( static_cast < float > ( DeltaTime ) ) ;
2019-06-03 15:32:00 -04:00
// Throttle frame rate.
2024-08-01 10:28:39 -04:00
const float FrameTime = ! bDisableFramerateThrottle & & UserInterfaceCommand : : IsApplicationBackground ( ) ? BackgroundFrameTime : IdealFrameTime ;
2024-05-22 04:06:05 -04:00
2022-09-29 20:32:42 -04:00
UserInterfaceCommand : : AdaptiveSleep ( FMath : : Max < float > ( 0.0f , FrameTime - static_cast < float > ( FPlatformTime : : Seconds ( ) - LastTime ) ) ) ;
2019-06-03 15:32:00 -04:00
double CurrentTime = FPlatformTime : : Seconds ( ) ;
DeltaTime = CurrentTime - LastTime ;
LastTime = CurrentTime ;
FStats : : AdvanceFrame ( false ) ;
2020-01-20 10:25:29 -05:00
FCoreDelegates : : OnEndFrame . Broadcast ( ) ;
2024-08-01 10:28:39 -04:00
GLog - > FlushThreadedLogs ( ) ;
2020-10-08 05:07:59 -04:00
GFrameCounter + + ;
2019-06-03 15:32:00 -04:00
}
2020-01-14 04:50:47 -05:00
ShutdownSlateApplication ( ) ;
2019-06-03 15:32:00 -04:00
}
////////////////////////////////////////////////////////////////////////////////////////////////////
2024-08-01 10:28:39 -04:00
void FUserInterfaceCommand : : InitializeSlateApplication ( bool bFrontendMode , const FString & TraceFileToOpen )
2019-06-03 15:32:00 -04:00
{
2021-07-19 08:55:22 -04:00
FSlateApplication : : InitHighDPI ( true ) ;
2019-10-03 16:26:48 -04:00
2020-01-14 04:50:47 -05:00
//const FSlateBrush* AppIcon = new FSlateImageBrush(FPaths::EngineContentDir() / "Editor/Slate/Icons/Insights/AppIcon_24x.png", FVector2D(24.0f, 24.0f));
//FSlateApplication::Get().SetAppIcon(AppIcon);
2019-06-03 15:32:00 -04:00
// Set the application name.
2020-01-14 04:50:47 -05:00
const FText ApplicationTitle = FText : : Format ( NSLOCTEXT ( " UnrealInsights " , " AppTitle " , " Unreal Insights {0} " ) , FText : : FromString ( TEXT ( UNREAL_INSIGHTS_VERSION_STRING_EX ) ) ) ;
FGlobalTabmanager : : Get ( ) - > SetApplicationTitle ( ApplicationTitle ) ;
2019-06-03 15:32:00 -04:00
// Load widget reflector.
const bool bAllowDebugTools = FParse : : Param ( FCommandLine : : Get ( ) , TEXT ( " DebugTools " ) ) ;
if ( bAllowDebugTools )
{
FModuleManager : : LoadModuleChecked < ISlateReflectorModule > ( " SlateReflector " ) . RegisterTabSpawner ( UserInterfaceCommand : : DeveloperTools ) ;
}
2024-08-01 10:28:39 -04:00
//////////////////////////////////////////////////
2019-06-03 15:32:00 -04:00
2023-07-24 11:40:19 -04:00
FString StoreHost = TEXT ( " 127.0.0.1 " ) ;
2020-02-05 14:26:36 -05:00
uint32 StorePort = 0 ;
bool bUseCustomStoreAddress = false ;
2023-07-24 11:40:19 -04:00
if ( FParse : : Value ( FCommandLine : : Get ( ) , TEXT ( " -Store= " ) , StoreHost , true ) )
2020-02-05 14:26:36 -05:00
{
2023-07-24 11:40:19 -04:00
int32 Index = INDEX_NONE ;
if ( StoreHost . FindChar ( TEXT ( ' : ' ) , Index ) )
2020-02-05 14:26:36 -05:00
{
2023-07-24 11:40:19 -04:00
StorePort = FCString : : Atoi ( * StoreHost . RightChop ( Index + 1 ) ) ;
StoreHost . LeftInline ( Index ) ;
2020-02-05 14:26:36 -05:00
}
bUseCustomStoreAddress = true ;
}
2023-07-24 11:40:19 -04:00
if ( FParse : : Value ( FCommandLine : : Get ( ) , TEXT ( " -StoreHost= " ) , StoreHost , true ) )
2020-02-05 14:26:36 -05:00
{
bUseCustomStoreAddress = true ;
}
if ( FParse : : Value ( FCommandLine : : Get ( ) , TEXT ( " -StorePort= " ) , StorePort ) )
{
bUseCustomStoreAddress = true ;
}
2024-08-01 10:28:39 -04:00
//////////////////////////////////////////////////
2023-07-20 05:22:57 -04:00
2024-08-01 10:28:39 -04:00
if ( ! bFrontendMode ) // viewer mode
2023-07-20 05:22:57 -04:00
{
2024-08-01 10:28:39 -04:00
FModuleManager : : Get ( ) . LoadModuleChecked ( " TraceInsights " ) ;
IUnrealInsightsModule & TraceInsightsModule = FModuleManager : : LoadModuleChecked < IUnrealInsightsModule > ( " TraceInsights " ) ;
2020-09-24 00:43:27 -04:00
2024-08-01 10:28:39 -04:00
// This parameter will cause the application to close when analysis fails to start or completes successfully.
const bool bAutoQuit = FParse : : Param ( FCommandLine : : Get ( ) , TEXT ( " AutoQuit " ) ) ;
const bool bInitializeTesting = FParse : : Param ( FCommandLine : : Get ( ) , TEXT ( " InsightsTest " ) ) ;
if ( bInitializeTesting )
2022-03-07 08:10:36 -05:00
{
2024-08-01 10:28:39 -04:00
const bool bInitAutomationModules = true ;
TraceInsightsModule . InitializeTesting ( bInitAutomationModules , bAutoQuit ) ;
2022-03-07 08:10:36 -05:00
}
2024-08-01 10:28:39 -04:00
uint32 TraceId = 0 ;
FString TraceIdString ;
bool bUseTraceId = FParse : : Value ( FCommandLine : : Get ( ) , TEXT ( " -OpenTraceId= " ) , TraceIdString ) ;
if ( bUseTraceId )
{
if ( TraceIdString . StartsWith ( TEXT ( " 0x " ) ) )
{
TCHAR * End ;
TraceId = FCString : : Strtoi ( * TraceIdString + 2 , & End , 16 ) ;
}
else
{
TCHAR * End ;
TraceId = FCString : : Strtoi ( * TraceIdString , & End , 10 ) ;
}
}
FString Cmd ;
if ( FParse : : Value ( FCommandLine : : Get ( ) , TEXT ( " -ExecOnAnalysisCompleteCmd= " ) , Cmd , false ) )
2022-03-07 08:10:36 -05:00
{
TraceInsightsModule . ScheduleCommand ( Cmd ) ;
}
const bool bNoUI = FParse : : Param ( FCommandLine : : Get ( ) , TEXT ( " NoUI " ) ) ;
2021-07-29 08:37:01 -04:00
if ( ! bNoUI )
{
TraceInsightsModule . CreateSessionViewer ( bAllowDebugTools ) ;
}
2022-03-07 08:10:36 -05:00
if ( bUseTraceId )
2020-01-23 05:11:17 -05:00
{
2023-07-24 11:40:19 -04:00
TraceInsightsModule . ConnectToStore ( * StoreHost , StorePort ) ;
2022-03-07 08:10:36 -05:00
TraceInsightsModule . StartAnalysisForTrace ( TraceId , bAutoQuit ) ;
2020-01-23 05:11:17 -05:00
}
else
{
2024-08-01 10:28:39 -04:00
TraceInsightsModule . StartAnalysisForTraceFile ( * TraceFileToOpen , bAutoQuit ) ;
2020-01-23 05:11:17 -05:00
}
}
2024-08-01 10:28:39 -04:00
else // frontend mode
2022-03-07 08:10:36 -05:00
{
2024-08-01 10:28:39 -04:00
FModuleManager : : Get ( ) . LoadModuleChecked ( " TraceInsightsFrontend " ) ;
ITraceInsightsFrontendModule & TraceInsightsFrontendModule = FModuleManager : : LoadModuleChecked < ITraceInsightsFrontendModule > ( " TraceInsightsFrontend " ) ;
// Ensure target platform manager is referenced early as it must be created on the main thread.
2024-04-04 14:01:37 -04:00
FModuleManager : : Get ( ) . LoadModuleChecked ( " DesktopPlatform " ) ;
FConfigCacheIni : : InitializeConfigSystem ( ) ;
GetTargetPlatformManager ( ) ;
FModuleManager : : Get ( ) . LoadModuleChecked ( " Messaging " ) ;
FModuleManager : : Get ( ) . LoadModuleChecked ( " OutputLog " ) ;
2024-08-01 10:28:39 -04:00
// Load optional modules.
2024-04-04 14:01:37 -04:00
FModuleManager : : Get ( ) . LoadModule ( " DeviceManager " ) ;
FModuleManager : : Get ( ) . LoadModule ( " SessionFrontend " ) ;
2024-08-01 10:28:39 -04:00
FString AutomationTests ;
bool bRunAutomationTests =
FParse : : Value ( FCommandLine : : Get ( ) , TEXT ( " -ExecBrowserAutomationTest= " ) , AutomationTests , false ) | |
FParse : : Value ( FCommandLine : : Get ( ) , TEXT ( " -RunAutomationTests= " ) , AutomationTests , false ) ;
2023-07-20 05:22:57 -04:00
2024-08-01 10:28:39 -04:00
TraceInsightsFrontendModule . ConnectToStore ( * StoreHost , StorePort ) ;
2022-03-07 08:10:36 -05:00
2024-08-01 10:28:39 -04:00
UE : : Insights : : FCreateFrontendWindowParams Params ;
2022-03-07 08:10:36 -05:00
Params . bAllowDebugTools = bAllowDebugTools ;
2024-08-01 10:28:39 -04:00
Params . bInitializeTesting = FParse : : Param ( FCommandLine : : Get ( ) , TEXT ( " InsightsTest " ) ) ;
2022-03-07 08:10:36 -05:00
Params . bStartProcessWithStompMalloc = FParse : : Param ( FCommandLine : : Get ( ) , TEXT ( " stompmalloc " ) ) ;
2024-05-22 04:06:05 -04:00
Params . bDisableFramerateThrottle = FParse : : Param ( FCommandLine : : Get ( ) , TEXT ( " DisableFramerateThrottle " ) ) ;
2024-09-18 07:58:52 -04:00
Params . bAutoQuit = FParse : : Param ( FCommandLine : : Get ( ) , TEXT ( " AutoQuit " ) ) ;
2024-08-01 10:28:39 -04:00
TraceInsightsFrontendModule . CreateFrontendWindow ( Params ) ;
2023-07-20 05:22:57 -04:00
2024-08-01 10:28:39 -04:00
if ( bRunAutomationTests )
2023-07-20 05:22:57 -04:00
{
2024-08-01 10:28:39 -04:00
TraceInsightsFrontendModule . RunAutomationTests ( AutomationTests ) ;
2023-07-20 05:22:57 -04:00
}
2022-03-07 08:10:36 -05:00
}
2019-06-03 15:32:00 -04:00
}
////////////////////////////////////////////////////////////////////////////////////////////////////
2020-01-14 04:50:47 -05:00
void FUserInterfaceCommand : : ShutdownSlateApplication ( )
2019-06-03 15:32:00 -04:00
{
2020-01-14 04:50:47 -05:00
IUnrealInsightsModule & TraceInsightsModule = FModuleManager : : LoadModuleChecked < IUnrealInsightsModule > ( " TraceInsights " ) ;
TraceInsightsModule . ShutdownUserInterface ( ) ;
2019-06-03 15:32:00 -04:00
// Shut down application.
FSlateApplication : : Shutdown ( ) ;
}
////////////////////////////////////////////////////////////////////////////////////////////////////