UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
MovieSceneEvaluationTreeFormatter.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"
10#include "Misc/StringBuilder.h"
11#include "MovieSceneFwd.h"
13#include "Templates/Tuple.h"
14
15#if !NO_LOGGING
16
17template<typename DataType>
19{
21
23
32
35
39
41
43
47
48 void LogTree()
49 {
50 LogRows.Reset();
51 DataIndices.Reset();
52
53 BuildLogRows(INDEX_NONE, &Tree.RootNode, 0);
54 AccumulateWidths();
55 AccumulateLeftOffsets();
56 OutputLogRows();
57
58 OutputData();
59 }
60
61private:
63 {
64 if (LogRows.Num() <= InDepth)
65 {
66 LogRows.SetNum(InDepth + 1);
67 }
69
70 TArrayView<const DataType> NodeData = Tree.GetDataForSingleNode(*InNode);
71 const int32 NodeWidth = GetItemMinWidth(NodeData.Num());
72 const int32 CurItemIndex = LogRow.Add(FLogRowItem{InParentRowItemIndex, InNode, NodeWidth});
73
74 if (InNode->ChildrenID.IsValid())
75 {
76 TArrayView<const FMovieSceneEvaluationTreeNode> ChildNodes = Tree.ChildNodes.Get(InNode->ChildrenID);
77 for (const FMovieSceneEvaluationTreeNode& ChildNode : ChildNodes)
78 {
79 BuildLogRows(CurItemIndex, &ChildNode, InDepth + 1);
80 }
81 }
82 }
83
84 void AccumulateWidths()
85 {
86 for (int32 RowIndex = LogRows.Num() - 1; RowIndex >= 0; --RowIndex)
87 {
88 FLogRow& LogRow = LogRows[RowIndex];
89
90 if (RowIndex > 0)
91 {
92 FLogRow& ParentLogRow = LogRows[RowIndex - 1];
93
94 for (FLogRowItem& RowItem : LogRow)
95 {
96 if (RowItem.ChildrenWidthTotal > 0)
97 {
98 RowItem.Width = FMath::Max(RowItem.Width, RowItem.ChildrenWidthTotal + ParentItemMargin);
99 }
100
101 if (ensure(ParentLogRow.IsValidIndex(RowItem.ParentRowItemIndex)))
102 {
103 FLogRowItem& ParentRowItem = ParentLogRow[RowItem.ParentRowItemIndex];
104 ParentRowItem.ChildrenWidthTotal += RowItem.Width;
105 }
106 }
107 }
108 else
109 {
110 for (FLogRowItem& RowItem : LogRow)
111 {
112 if (RowItem.ChildrenWidthTotal > 0)
113 {
114 RowItem.Width = FMath::Max(RowItem.Width, RowItem.ChildrenWidthTotal + ParentItemMargin);
115 }
116 }
117 }
118 }
119 }
120
121 void AccumulateLeftOffsets()
122 {
123 for (int32 RowIndex = 1; RowIndex < LogRows.Num(); ++RowIndex)
124 {
125 FLogRow& LogRow = LogRows[RowIndex];
126 FLogRow& ParentLogRow = LogRows[RowIndex - 1];
127
130
131 for (int32 ItemIndex = 0; ItemIndex < LogRow.Num(); ++ItemIndex)
132 {
133 FLogRowItem& RowItem = LogRow[ItemIndex];
134 if (ensure(ParentLogRow.IsValidIndex(RowItem.ParentRowItemIndex)))
135 {
136 FLogRowItem& ParentRowItem = ParentLogRow[RowItem.ParentRowItemIndex];
137
138 if (RowItem.ParentRowItemIndex != CurParentRowItemIndex)
139 {
141 CurParentRowItemIndex = RowItem.ParentRowItemIndex;
142 }
143
144 RowItem.LeftOffset = NextLeftOffset;
145 NextLeftOffset += RowItem.Width;
146 }
147 }
148 }
149 }
150
151 void OutputLogRows()
152 {
153 TStringBuilder<1024> Builder;
154
155 for (const FLogRow& LogRow : LogRows)
156 {
157 Builder.Reset();
158
159 for (const FLogRowItem& RowItem : LogRow)
160 {
161 // Indent
162 const int32 CurLeftOffset = Builder.Len();
163 ensure(RowItem.LeftOffset >= CurLeftOffset);
164 int32 IndentWidth = FMath::Max(0, RowItem.LeftOffset - CurLeftOffset);
165 for (int32 Index = 0; Index < IndentWidth; ++Index)
166 {
167 Builder.Append(TEXT(" "));
168 }
169
170 // Build display string: [====== 0,1,2 ======]
171 const FString DataString = LexToStringAllDataIndexes(RowItem.Node);
172
173 const int32 Padding = FMath::Max(0, RowItem.Width - DataString.Len() - 4);
174 const int32 PaddingLeft = Padding / 2;
176
177 Builder.Append(TEXT("["));
178 for (int32 Index = 0; Index < PaddingLeft; ++Index)
179 {
180 Builder.Append(TEXT("="));
181 }
182 Builder.Append(TEXT(" "));
183
184 Builder.Append(DataString);
185
186 Builder.Append(TEXT(" "));
187 for (int32 Index = 0; Index < PaddingLeft; ++Index)
188 {
189 Builder.Append(TEXT("="));
190 }
191 Builder.Append(TEXT("]"));
192 }
193
194 FString RowString(Builder.ToString());
196 }
197 }
198
199 void OutputData()
200 {
201 if (!DataFormatter.IsBound())
202 {
203 UE_LOG(LogMovieScene, Log, TEXT("No data formatter provided."));
204 return;
205 }
206
209
210 for (auto It : DataIndices)
211 {
213 Dummy.DataID.EntryIndex = It.Key.template Get<0>();
214 TArrayView<const DataType> DataView = Tree.GetDataForSingleNode(Dummy);
215 const int32 DataIndex = It.Key.template Get<1>();
216 if (ensure(DataView.IsValidIndex(DataIndex)))
217 {
218 const FDataInfo DataInfo = It.Value;
219
220 DataStringBuilder.Appendf(TEXT("%d: "), DataInfo.template Get<0>());
221 DataStringBuilder.Appendf(TEXT("%s "), *LexToString(DataInfo.template Get<1>()));
222
223 const DataType& Data = DataView[DataIndex];
224 DataFormatter.Execute(Data, DataStringBuilder);
225 const FString DataString = DataStringBuilder.ToString();
226 UE_LOG(LogMovieScene, Log, TEXT("%s"), *DataString);
227 }
228 }
229 }
230
231 FString LexToStringAllDataIndexes(const FMovieSceneEvaluationTreeNode* Node)
232 {
234 TArrayView<const DataType> DataView = Tree.GetDataForSingleNode(*Node);
235 for (int32 Index = 0; Index < DataView.Num(); ++Index)
236 {
237 if (Index > 0)
238 {
239 DataBuilder.Append(TEXT(","));
240 }
241
242 const DataType& Data = DataView[Index];
243 const FDataIndex Key(Node->DataID.EntryIndex, Index);
244 const FDataInfo DefaultValue(DataIndices.Num(), Node->Range);
245 const FDataInfo ActualValue = DataIndices.FindOrAdd(Key, DefaultValue);
246 DataBuilder.Append(LexToString(ActualValue.template Get<0>()));
247 }
248 if (DataView.Num() == 0)
249 {
250 DataBuilder.Append(TEXT("nil"));
251 }
252 return DataBuilder.ToString();
253 }
254
255 static int32 GetItemMinWidth(int32 NumData)
256 {
257 // [= 0,1,2 =]
258 if (NumData > 0)
259 {
260 return
261 NumData + // unit digit
262 FMath::Max(0, NumData - 9) + // tens digit
263 FMath::Max(0, NumData - 99) + // hundred digit
264 (NumData - 1) + // commas
265 4 + 2; // brackets with minimal padding
266 }
267 else
268 {
269 return
270 3 + // nil
271 4 + 2; // brackes with minimal padding
272 }
273 }
274};
275
276#endif
277
#define ensure( InExpression)
Definition AssertionMacros.h:464
@ INDEX_NONE
Definition CoreMiscDefines.h:150
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
const TCHAR * LexToString(EAnalyticsRecordEventMode Mode)
Definition IAnalyticsProvider.cpp:5
#define UE_LOG(CategoryName, Verbosity, Format,...)
Definition LogMacros.h:270
Definition ArrayView.h:139
UE_FORCEINLINE_HINT constexpr SizeType Num() const
Definition ArrayView.h:380
UE_FORCEINLINE_HINT constexpr bool IsValidIndex(SizeType Index) const
Definition ArrayView.h:359
Definition Array.h:670
Definition UnrealString.h.inl:34
const CharType * ToString() UE_LIFETIMEBOUND
Definition StringBuilder.h:135
BuilderType & Append(const OtherCharType *const String, const int32 Length)
Definition StringBuilder.h:238
void Reset()
Definition StringBuilder.h:190
int32 Len() const
Definition StringBuilder.h:114
Definition StringBuilder.h:509
GeometryCollection::Facades::FMuscleActivationData Data
Definition MuscleActivationConstraints.h:15
U16 Index
Definition radfft.cpp:71
Definition MovieSceneEvaluationTree.h:273
FEvaluationTreeEntryHandle DataID
Definition MovieSceneEvaluationTree.h:306
TRange< FFrameNumber > Range
Definition MovieSceneEvaluationTree.h:300
Definition MovieSceneEvaluationTreeFormatter.h:25
int32 ParentRowItemIndex
Definition MovieSceneEvaluationTreeFormatter.h:26
int32 Width
Definition MovieSceneEvaluationTreeFormatter.h:28
const FMovieSceneEvaluationTreeNode * Node
Definition MovieSceneEvaluationTreeFormatter.h:27
int32 LeftOffset
Definition MovieSceneEvaluationTreeFormatter.h:30
int32 ChildrenWidthTotal
Definition MovieSceneEvaluationTreeFormatter.h:29
Definition MovieSceneEvaluationTreeFormatter.h:19
TMovieSceneEvaluationTreeFormatter(const TMovieSceneEvaluationTree< DataType > &InTree)
Definition MovieSceneEvaluationTreeFormatter.h:44
TArray< FLogRowItem > FLogRow
Definition MovieSceneEvaluationTreeFormatter.h:33
const TMovieSceneEvaluationTree< DataType > & Tree
Definition MovieSceneEvaluationTreeFormatter.h:22
FOnFormatData DataFormatter
Definition MovieSceneEvaluationTreeFormatter.h:42
TTuple< int32, TRange< FFrameNumber > > FDataInfo
Definition MovieSceneEvaluationTreeFormatter.h:37
TTuple< int32, int32 > FDataIndex
Definition MovieSceneEvaluationTreeFormatter.h:36
DECLARE_DELEGATE_TwoParams(FOnFormatData, const DataType &, TStringBuilder< 256 > &)
TMap< FDataIndex, FDataInfo > DataIndices
Definition MovieSceneEvaluationTreeFormatter.h:38
TArray< FLogRow > LogRows
Definition MovieSceneEvaluationTreeFormatter.h:34
int32 ParentItemMargin
Definition MovieSceneEvaluationTreeFormatter.h:40
void LogTree()
Definition MovieSceneEvaluationTreeFormatter.h:48
Definition MovieSceneEvaluationTree.h:603
Definition Tuple.h:652