A Demo Project for the UnrealEngineSDK
Loading...
Searching...
No Matches
VRLogComponent.h
Go to the documentation of this file.
1// Fill out your copyright notice in the Description page of Project Settings.
2
3#pragma once
4
5#include "CoreMinimal.h"
6#include "Engine/Canvas.h"
7#include "Engine/TextureRenderTarget2D.h"
8#include "Engine/Console.h"
9#include "Containers/UnrealString.h"
10#include "Core/Public/Misc/OutputDeviceHelper.h"
11#include "VRLogComponent.generated.h"
12
16UENUM(BlueprintType)
17enum class EBPVRConsoleDrawType : uint8
18{
21// VRConsole_Draw_ConsoleAndOutputLog
22};
23
24
29struct FVRLogMessage
30{
31 TSharedRef<FString> Message;
32 ELogVerbosity::Type Verbosity;
33 FName Category;
34 FName Style;
36 FVRLogMessage(const TSharedRef<FString>& NewMessage, FName NewCategory, FName NewStyle = NAME_None)
37 : Message(NewMessage)
38 , Verbosity(ELogVerbosity::Log)
39 , Category(NewCategory)
40 , Style(NewStyle)
41 {
42 }
43
44 FVRLogMessage(const TSharedRef<FString>& NewMessage, ELogVerbosity::Type NewVerbosity, FName NewCategory, FName NewStyle = NAME_None)
45 : Message(NewMessage)
46 , Verbosity(NewVerbosity)
47 , Category(NewCategory)
48 , Style(NewStyle)
49 {
50 }
51};
52
53// Custom Log output history class to hold the VR logs.
56{
57public:
60 bool bIsDirty;
61 int32 MaxLineLength;
64 {
65 MaxLineLength = 130;
66 bIsDirty = false;
67 MaxStoredMessages = 1000;
68 GLog->AddOutputDevice(this);
69 GLog->SerializeBacklog(this);
70 }
71
73 {
74 // At shutdown, GLog may already be null
75 if (GLog != NULL)
76 {
77 GLog->RemoveOutputDevice(this);
78 }
79 }
80
82 const TArray< TSharedPtr<FVRLogMessage> >& GetMessages() const
83 {
84 return Messages;
85 }
86
87protected:
88
89 virtual void Serialize(const TCHAR* V, ELogVerbosity::Type Verbosity, const class FName& Category) override
90 {
91 // Capture all incoming messages and store them in history
92 CreateLogMessages(V, Verbosity, Category, Messages);
93 }
94
95 bool CreateLogMessages(const TCHAR* V, ELogVerbosity::Type Verbosity, const class FName& Category, TArray< TSharedPtr<FVRLogMessage> >& OutMessages)
96 {
97 if (Verbosity == ELogVerbosity::SetColor)
98 {
99 // Skip Color Events
100 return false;
101 }
102 else
103 {
104 FName Style;
105 if (Category == NAME_Cmd)
106 {
107 Style = FName(TEXT("Log.Command"));
108 }
109 else if (Verbosity == ELogVerbosity::Error)
110 {
111 Style = FName(TEXT("Log.Error"));
112 }
113 else if (Verbosity == ELogVerbosity::Warning)
114 {
115 Style = FName(TEXT("Log.Warning"));
116 }
117 else
118 {
119 Style = FName(TEXT("Log.Normal"));
120 }
121
122 // Forget timestamps, I don't care about them and we have limited texture space to draw too
123 // Determine how to format timestamps
124 static ELogTimes::Type LogTimestampMode = ELogTimes::None;
125 /*if (UObjectInitialized() && !GExitPurge)
126 {
127 // Logging can happen very late during shutdown, even after the UObject system has been torn down, hence the init check above
128 LogTimestampMode = GetDefault<UEditorStyleSettings>()->LogTimestampMode;
129 }*/
130
131 const int32 OldNumMessages = OutMessages.Num();
132
133 // handle multiline strings by breaking them apart by line
134 TArray<FTextRange> LineRanges;
135 FString CurrentLogDump = V;
136 FTextRange::CalculateLineRangesFromString(CurrentLogDump, LineRanges);
137
138 bool bIsFirstLineInMessage = true;
139 for (const FTextRange& LineRange : LineRanges)
140 {
141 if (!LineRange.IsEmpty())
142 {
143 FString Line = CurrentLogDump.Mid(LineRange.BeginIndex, LineRange.Len());
144 Line = Line.ConvertTabsToSpaces(4);
145
146 // Hard-wrap lines to avoid them being too long
147 /*static const */int32 HardWrapLen = MaxLineLength;
148 for (int32 CurrentStartIndex = 0; CurrentStartIndex < Line.Len();)
149 {
150 int32 HardWrapLineLen = 0;
151 if (bIsFirstLineInMessage)
152 {
153 FString MessagePrefix = FOutputDeviceHelper::FormatLogLine(Verbosity, Category, nullptr, LogTimestampMode);
154
155 HardWrapLineLen = FMath::Min(HardWrapLen - MessagePrefix.Len(), Line.Len() - CurrentStartIndex);
156 FString HardWrapLine = Line.Mid(CurrentStartIndex, HardWrapLineLen);
157
158 OutMessages.Add(MakeShareable(new FVRLogMessage(MakeShareable(new FString(MessagePrefix + HardWrapLine)), Verbosity, Category, Style)));
159 }
160 else
161 {
162 HardWrapLineLen = FMath::Min(HardWrapLen, Line.Len() - CurrentStartIndex);
163 FString HardWrapLine = Line.Mid(CurrentStartIndex, HardWrapLineLen);
164
165 OutMessages.Add(MakeShareable(new FVRLogMessage(MakeShareable(new FString(MoveTemp(HardWrapLine))), Verbosity, Category, Style)));
166 }
167
168 bIsFirstLineInMessage = false;
169 CurrentStartIndex += HardWrapLineLen;
170 }
171 }
172 }
173
174 int numMessages = OutMessages.Num();
175 if (numMessages > MaxStoredMessages)
176 {
177 OutMessages.RemoveAt(0, numMessages - MaxStoredMessages, true);
178 }
179 if (OldNumMessages != numMessages)
180 bIsDirty = true;
181
182 return OldNumMessages != numMessages;//OutMessages.Num();
183 }
184 }
185
186private:
187
189 TArray< TSharedPtr<FVRLogMessage> > Messages;
190};
191
196UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = (VRExpansionPlugin))
197class VREXPANSIONPLUGIN_API UVRLogComponent : public UActorComponent
198{
199 GENERATED_BODY()
200
201public:
202 UVRLogComponent(const FObjectInitializer& ObjectInitializer);
204
206
207 FVROutputLogHistory OutputLogHistory;
208
209 virtual void PostInitProperties() override
210 {
211 Super::PostInitProperties();
212 OutputLogHistory.MaxStoredMessages = FMath::Clamp(MaxStoredMessages, 100, 100000);
213 OutputLogHistory.MaxLineLength = FMath::Clamp(MaxLineLength, 50, 1000);
214 }
216 UPROPERTY(BlueprintReadWrite,EditAnywhere, Category = "VRLogComponent|Console")
217 int32 MaxLineLength;
218
219 UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRLogComponent|Console")
220 int32 MaxStoredMessages;
221
222 // Sets the console input text, can be used to clear the console or enter full or partial commands
223 UFUNCTION(BlueprintCallable, Category = "VRLogComponent|Console", meta = (bIgnoreSelf = "true"))
224 void SetConsoleText(FString Text);
225
226 // Sends a key to the console - Console considers Released as final, flashes the cursor
227 UFUNCTION(BlueprintCallable, Category = "VRLogComponent|Console", meta = (bIgnoreSelf = "true"))
228 void SendKeyEventToConsole(FKey Key, EInputEvent KeyEvent);
229
230 // Sends text to the console - Optionally returns at the end to "enter" the text, end flashes the cursor
231 UFUNCTION(BlueprintCallable, Category = "VRLogComponent|Console", meta = (bIgnoreSelf = "true"))
232 void AppendTextToConsole(FString Text, bool bReturnAtEnd = false);
233
234 // Draw the console to a render target 2D
235 UFUNCTION(BlueprintCallable, Category = "VRLogComponent|Console", meta = (bIgnoreSelf = "true", DisplayName = "DrawConsoleToCanvasRenderTarget2D"))
236 bool DrawConsoleToRenderTarget2D(EBPVRConsoleDrawType DrawType, UTextureRenderTarget2D * Texture, float ScrollOffset, bool bForceDraw);
237
238
239 void DrawConsole(bool bLowerHalfOnly, UCanvas* Canvas);
240 void DrawOutputLog(bool bUpperHalfOnly, UCanvas* Canvas, float ScrollOffset);
241
242};
EBPVRConsoleDrawType
UENUM(BlueprintType)
virtual void Serialize(const TCHAR *V, ELogVerbosity::Type Verbosity, const class FName &Category) override
bool CreateLogMessages(const TCHAR *V, ELogVerbosity::Type Verbosity, const class FName &Category, TArray< TSharedPtr< FVRLogMessage > > &OutMessages)
TArray< TSharedPtr< FVRLogMessage > > Messages
const TArray< TSharedPtr< FVRLogMessage > > & GetMessages() const
UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = (VRExpansionPlugin))
FVROutputLogHistory OutputLogHistory
virtual void PostInitProperties() override
int32 MaxLineLength
UPROPERTY(BlueprintReadWrite,EditAnywhere, Category = "VRLogComponent|Console")
int32 MaxStoredMessages
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRLogComponent|Console")
TSharedRef< FString > Message
FVRLogMessage(const TSharedRef< FString > &NewMessage, FName NewCategory, FName NewStyle=NAME_None)
ELogVerbosity::Type Verbosity
FVRLogMessage(const TSharedRef< FString > &NewMessage, ELogVerbosity::Type NewVerbosity, FName NewCategory, FName NewStyle=NAME_None)