Ark Server API (ASA) - Wiki
Loading...
Searching...
No Matches
TimeGuard.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "Containers/Map.h"
6#include "CoreGlobals.h"
7#include "CoreTypes.h"
8#include "Delegates/Delegate.h"
9#include "HAL/PlatformTime.h"
10#include "Misc/Build.h"
11#include "Misc/DateTime.h"
12
13#ifndef DO_TIMEGUARD
14 // By default we are disabled, DO_TIMEGUARD can be set in XXX.Target.cs if so desired%
15 #define DO_TIMEGUARD 0
16#endif
17
18#ifndef DO_LIGHTWEIGHT_TIMEGUARD
19 // By default, enable lightweight timeguards if logging is enabled, except on servers
20 #define DO_LIGHTWEIGHT_TIMEGUARD ( WITH_ENGINE && !UE_SERVER && !NO_LOGGING && !WITH_EDITOR )
21#endif
22
24
25DECLARE_DELEGATE_RetVal(const FString, FTimerNameDelegate);
26
27class FTimeGuard
28{
29
30public:
31
32 struct FGuardInfo
33 {
34 int Count;
35 float Min;
36 float Max;
37 float Total;
38 FDateTime FirstTime;
39 FDateTime LastTime;
40
41 FGuardInfo() :
42 Count(0)
43 , Min(FLT_MAX)
44 , Max(-FLT_MAX)
45 , Total(0)
46 {}
47 };
48
49public:
50
51
52 FORCEINLINE FTimeGuard(FTimerNameDelegate InNameDelegate, const float InTargetMS = 0.0)
53 : Name(nullptr), ObjectName(NAME_None)
54 {
55 NameDelegate = (bEnabled && IsInGameThread()) ? InNameDelegate : nullptr;
56
57 if (NameDelegate.IsBound())
58 {
59 TargetTimeMS = (InTargetMS > 0) ? InTargetMS : FrameTimeThresholdMS;
60 StartTime = FPlatformTime::Seconds();
61 }
62 }
63
64 FORCEINLINE FTimeGuard(TCHAR const* InName, FName InObjectName = NAME_None, const float InTargetMS = 0.0)
65 : Name(nullptr), ObjectName(NAME_None)
66 {
67 Name = (bEnabled && IsInGameThread()) ? InName : nullptr;
68
69 if (Name)
70 {
71 ObjectName = InObjectName;
72 TargetTimeMS = (InTargetMS > 0) ? InTargetMS : FrameTimeThresholdMS;
73 StartTime = FPlatformTime::Seconds();
74 }
75 }
76
77 /**
78 * Updates the stat with the time spent
79 */
80 FORCEINLINE ~FTimeGuard()
81 {
82 if (Name)
83 {
84 double delta = (FPlatformTime::Seconds() - StartTime) * 1000;
85
86 if (delta > TargetTimeMS)
87 {
88 if ( ObjectName != NAME_None )
89 {
90 ReportHitch( *FString::Printf(TEXT("%s %s"), Name, *ObjectName.ToString()), delta, true );
91 }
92 else
93 {
94 ReportHitch(Name, delta, false);
95 }
96 }
97 }
98 else if (NameDelegate.IsBound())
99 {
100 double delta = (FPlatformTime::Seconds() - StartTime) * 1000;
101
102 if (delta > TargetTimeMS)
103 {
104 FString Temp = NameDelegate.Execute();
105 ReportHitch(*Temp, delta, true);
106 }
107 }
108 }
109
110 // Can be used externally to extract / clear data
111 static void ClearData();
112 static void SetEnabled(bool InEnable);
113 static void SetFrameTimeThresholdMS(float InTimeMS);
114 static void GetData(TMap<const TCHAR*, FGuardInfo>& Dest);
115
116protected:
117
118 // Used for reporting
119 static void ReportHitch(const TCHAR* InName, float TimeMS, bool VolatileName );
120 static TMap<const TCHAR*, FGuardInfo> HitchData;
121 static TSet<const TCHAR *> VolatileNames; // any names which come in volatile we allocate them to a static string and put them in this array
122 static FCriticalSection ReportMutex;
123 static bool bEnabled;
124 static float FrameTimeThresholdMS;
125
126protected:
127
128 // Per-stat tracking
129 TCHAR const* Name;
130 FName ObjectName;
131 FTimerNameDelegate NameDelegate;
132 float TargetTimeMS;
133 double StartTime;
134};
135
136UE_DEPRECATED(4.21, "FLightweightTimeGuard has been renamed to FTimeGuard.")
137typedef FTimeGuard FLightweightTimeGuard;
138
139#define SCOPE_TIME_GUARD(name)
140 FTimeGuard ANONYMOUS_VARIABLE(TimeGuard)(name);
141
142#define SCOPE_TIME_GUARD_MS(name, timeMs)
143 FTimeGuard ANONYMOUS_VARIABLE(TimeGuard)(name, NAME_None, timeMs);
144
145#define SCOPE_TIME_GUARD_NAMED(name, fname)
146 FTimeGuard ANONYMOUS_VARIABLE(TimeGuard)(name, fname);
147
148#define SCOPE_TIME_GUARD_NAMED_MS(name, fname, timems)
149 FTimeGuard ANONYMOUS_VARIABLE(TimeGuard)(name, fname, timems);
150
151
152
153
154#define SCOPE_TIME_GUARD_DELEGATE(inDelegate)
155 FTimeGuard ANONYMOUS_VARIABLE(TimeGuard)(inDelegate);
156
157#define SCOPE_TIME_GUARD_DELEGATE_MS(inDelegate, timems)
158 FTimeGuard ANONYMOUS_VARIABLE(TimeGuard)(inDelegate, timems);
159
160#define CLEAR_TIME_GUARDS FTimeGuard::ClearData
161
162#define ENABLE_TIME_GUARDS(bEnabled) FTimeGuard::SetEnabled(bEnabled)
163
164#else
165
166#define SCOPE_TIME_GUARD(name)
167#define SCOPE_TIME_GUARD_MS(name, timeMs)
168#define SCOPE_TIME_GUARD_NAMED(name, fname)
169#define SCOPE_TIME_GUARD_NAMED_MS(name, fname, timeMs)
170#define CLEAR_TIME_GUARDS()
171#define ENABLE_TIME_GUARDS(bEnabled)
172
173#endif // DO_TIMEGUARD
174
175// Lightweight time guard, suitable for shipping builds with logging.
176// Note: Threshold of 0 disables the timeguard
178
179 #define LIGHTWEIGHT_TIME_GUARD_BEGIN( Name, ThresholdMS )
180 float PREPROCESSOR_JOIN(__TimeGuard_ThresholdMS_, Name) = ThresholdMS;
181 uint64 PREPROCESSOR_JOIN(__TimeGuard_StartCycles_, Name) = ( ThresholdMS > 0.0f ) ? FPlatformTime::Cycles64() : 0;
182
183 #define LIGHTWEIGHT_TIME_GUARD_END( Name, NameStringCode )
184 if ( PREPROCESSOR_JOIN(__TimeGuard_ThresholdMS_, Name) > 0.0f )
185 {
186 float PREPROCESSOR_JOIN(__TimeGuard_MSElapsed_,Name) = FPlatformTime::ToMilliseconds64( FPlatformTime::Cycles64() - PREPROCESSOR_JOIN(__TimeGuard_StartCycles_,Name) );
187 if ( PREPROCESSOR_JOIN(__TimeGuard_MSElapsed_,Name) > PREPROCESSOR_JOIN(__TimeGuard_ThresholdMS_, Name) )
188 {
189 FString ReportName = NameStringCode;
190 UE_LOG(LogCore, Warning, TEXT("LIGHTWEIGHT_TIME_GUARD: %s - %s took %.2fms!"), TEXT(#Name), *ReportName, PREPROCESSOR_JOIN(__TimeGuard_MSElapsed_,Name));
191 }
192 }
193#else
194 #define LIGHTWEIGHT_TIME_GUARD_BEGIN( Name, ThresholdMS )
195 #define LIGHTWEIGHT_TIME_GUARD_END( Name, NameStringCode )
196#endif
#define WITH_ENGINE
Definition Build.h:8
#define UE_SERVER
Definition Build.h:45
#define WITH_EDITOR
Definition Build.h:7
#define NO_LOGGING
Definition Build.h:326
#define DO_LIGHTWEIGHT_TIMEGUARD
Definition TimeGuard.h:20
#define DO_TIMEGUARD
Definition TimeGuard.h:15