A Demo Project for the UnrealEngineSDK
Loading...
Searching...
No Matches
DlgConfigWriter.cpp
Go to the documentation of this file.
1// Copyright Csaba Molnar, Daniel Butum. All Rights Reserved.
3
4#include "Misc/FileHelper.h"
5#include "UObject/EnumProperty.h"
6
7#include "DlgHelper.h"
9
10DEFINE_LOG_CATEGORY(LogDlgConfigWriter);
11
12const TCHAR* FDlgConfigWriter::EOL_LF = TEXT("\n");
13const TCHAR* FDlgConfigWriter::EOL_CRLF = TEXT("\r\n");
14const TCHAR* FDlgConfigWriter::EOL = EOL_LF;
15const FString FDlgConfigWriter::EOL_String{EOL};
16
17
19FDlgConfigWriter::FDlgConfigWriter(const FString InComplexNamePrefix,
20 bool bInDontWriteEmptyContainer) :
21 ComplexNamePrefix(InComplexNamePrefix),
22 bDontWriteEmptyContainer(bInDontWriteEmptyContainer)
23{
24}
25
27void FDlgConfigWriter::Write(const UStruct* const StructDefinition, const void* const Object)
28{
30 WriteComplexMembersToString(StructDefinition, Object, "", EOL, ConfigText);
31}
32
34void FDlgConfigWriter::WriteComplexMembersToString(const UStruct* StructDefinition,
35 const void* Object,
36 const FString& PreString,
37 const FString& PostString,
38 FString& Target)
39{
40 if (StructDefinition == nullptr)
41 {
42 return;
43 }
44
45 // order
46 TArray<const FNYProperty*> Primitives;
47 TArray<const FNYProperty*> PrimitiveContainers;
48 TArray<const FNYProperty*> ComplexElements;
49 TArray<const FNYProperty*> ComplexContainers;
50
51 constexpr int32 PropCategoryNum = 4;
52 TArray<const FNYProperty*>* PropCategory[PropCategoryNum] = { &Primitives, &PrimitiveContainers, &ComplexElements, &ComplexContainers };
53
54 // Handle UObject inheritance (children of class)
55 if (StructDefinition->IsA<UClass>())
56 {
57 const UObject* UnrealObject = static_cast<const UObject*>(Object);
58 if (!UnrealObject->IsValidLowLevelFast())
59 {
60 return;
61 }
62
63 StructDefinition = UnrealObject->GetClass();
64 }
65 if (!StructDefinition->IsValidLowLevelFast())
66 {
67 return;
68 }
69
70 // Populate categories
71 for (TFieldIterator<FNYProperty> It(StructDefinition); It; ++It)
72 {
73 const auto* Property = *It;
74 if (IsPrimitive(Property))
75 {
76 Primitives.Add(Property);
77 }
78 else if (IsContainer(Property))
79 {
80 if (IsPrimitiveContainer(Property))
81 {
82 PrimitiveContainers.Add(Property);
83 }
84 else
85 {
86 ComplexContainers.Add(Property);
87 }
88 }
89 else
90 {
91 ComplexElements.Add(Property);
92 }
93 }
94
95 constexpr bool bContainerElement = false;
96 for (int32 i = 0; i < PropCategoryNum; ++i)
97 {
98 for (const auto* Prop : *PropCategory[i])
99 {
100 WritePropertyToString(Prop, Object, bContainerElement, PreString, PostString, false, Target);
101 }
102 }
103
104}
105
108 const void* Object,
109 bool bContainerElement,
110 const FString& PreString,
111 const FString& PostString,
112 bool bPointerAsRef,
113 FString& Target)
114{
115 if (CanSkipProperty(Property))
116 {
117 return true;
118 }
119
120 // Primitive: bool, int, float, FString, FName
121 if (WritePrimitiveElementToString(Property, Object, bContainerElement, PreString, PostString, Target))
122 {
123 return true;
124 }
125
126 // Primitive Array: Array[int], Array[bool]
127 if (WritePrimitiveArrayToString(Property, Object, PreString, PostString, Target))
128 {
129 return true;
130 }
131
132 // Complex element: UStruct, UObject
133 if (WriteComplexElementToString(Property, Object, bContainerElement, PreString, PostString, bPointerAsRef, Target))
134 {
135 return true;
136 }
137
138 // Complex Array: Array[UStruct], Array[UObject]
139 if (WriteComplexArrayToString(Property, Object, PreString, PostString, Target))
140 {
141 return true;
142 }
143
144 // Map
145 if (WriteMapToString(Property, Object, PreString, PostString, Target))
146 {
147 return true;
148 }
149
150 // Set
151 if (WriteSetToString(Property, Object, PreString, PostString, Target))
152 {
153 return true;
154 }
155
156 return false;
157}
158
161 const void* Object,
162 bool bInContainer,
163 const FString& PreS,
164 const FString& PostS,
165 FString& Target)
166{
167 // Try every possible primitive type
168 if (WritePrimitiveElementToStringTemplated<FNYBoolProperty, bool>(Property, Object, bInContainer, BoolToString, PreS, PostS, Target))
169 {
170 return true;
171 }
172 if (WritePrimitiveElementToStringTemplated<FNYIntProperty, int32>(Property, Object, bInContainer, IntToString, PreS, PostS, Target))
173 {
174 return true;
175 }
176 if (WritePrimitiveElementToStringTemplated<FNYInt64Property, int64>(Property, Object, bInContainer, IntToString, PreS, PostS, Target))
177 {
178 return true;
179 }
180 if (WritePrimitiveElementToStringTemplated<FNYFloatProperty, float>(Property, Object, bInContainer, FloatToString, PreS, PostS, Target))
181 {
182 return true;
183 }
184 if (WritePrimitiveElementToStringTemplated<FNYStrProperty, FString>(Property, Object, bInContainer, StringToString, PreS, PostS, Target))
185 {
186 return true;
187 }
188 if (WritePrimitiveElementToStringTemplated<FNYNameProperty, FName>(Property, Object, bInContainer, NameToString, PreS, PostS, Target))
189 {
190 return true;
191 }
192 if (WritePrimitiveElementToStringTemplated<FNYTextProperty, FText>(Property, Object, bInContainer, TextToString, PreS, PostS, Target))
193 {
194 return true;
195 }
196
197 // TODO: enum in container - why isn't it implemented in the reader?
198 if (!bInContainer)
199 {
200 const auto* EnumProp = FNYReflectionHelper::CastProperty<FNYEnumProperty>(Property);
201 if (EnumProp != nullptr)
202 {
203 const void* Value = EnumProp->ContainerPtrToValuePtr<uint8>(Object);
204 const FName EnumName = EnumProp->GetEnum()->GetNameByIndex(EnumProp->GetUnderlyingProperty()->GetSignedIntPropertyValue(Value));
205 Target += PreS + Property->GetName() + " " + NameToString(EnumName) + PostS;
206 return true;
207 }
208 }
209
210 return false;
211}
212
215 const void* Object,
216 const FString& PreString,
217 const FString& PostString,
218 FString& Target)
219{
220 const auto* ArrayProp = FNYReflectionHelper::CastProperty<FNYArrayProperty>(Property);
221 if (ArrayProp == nullptr)
222 {
223 return false;
224 }
225
226 // Try every possible primitive array type
227 if (WritePrimitiveArrayToStringTemplated<FNYBoolProperty, bool>(ArrayProp, Object, BoolToString, PreString, PostString, Target))
228 {
229 return true;
230 }
231 if (WritePrimitiveArrayToStringTemplated<FNYIntProperty, int32>(ArrayProp, Object, IntToString, PreString, PostString, Target))
232 {
233 return true;
234 }
235 if (WritePrimitiveArrayToStringTemplated<FNYInt64Property, int64>(ArrayProp, Object, IntToString, PreString, PostString, Target))
236 {
237 return true;
238 }
239 if (WritePrimitiveArrayToStringTemplated<FNYFloatProperty, float>(ArrayProp, Object, FloatToString, PreString, PostString, Target))
240 {
241 return true;
242 }
243 if (WritePrimitiveArrayToStringTemplated<FNYStrProperty, FString>(ArrayProp, Object, StringToString, PreString, PostString, Target))
244 {
245 return true;
246 }
247 if (WritePrimitiveArrayToStringTemplated<FNYNameProperty, FName>(ArrayProp, Object, NameToString, PreString, PostString, Target))
248 {
249 return true;
250 }
251 if (WritePrimitiveArrayToStringTemplated<FNYTextProperty, FText>(ArrayProp, Object, TextToString, PreString, PostString, Target))
252 {
253 return true;
254 }
255
256 return false;
257}
258
261 const void* Object,
262 bool bContainerElement,
263 const FString& PreString,
264 const FString& PostString,
265 bool bPointerAsRef,
266 FString& Target)
267{
268 if (Property == nullptr)
269 {
270 return false;
271 }
272
273 // UStruct
274 if (const auto* StructProperty = FNYReflectionHelper::CastProperty<FNYStructProperty>(Property))
275 {
276 const void* StructObject = StructProperty->ContainerPtrToValuePtr<void>(Object, 0);
277 if (StructObject == nullptr)
278 {
279 return true;
280 }
281
282 WriteComplexToString(StructProperty->Struct,
283 Property,
284 StructObject,
285 PreString,
286 PostString,
287 bContainerElement,
288 false,
289 Target);
290 return true;
291 }
292
293 // UObject
294 if (const auto* ObjectProperty = FNYReflectionHelper::CastProperty<FNYObjectProperty>(Property))
295 {
296 UObject** ObjPtrPtr = ((UObject**)ObjectProperty->ContainerPtrToValuePtr<void>(Object, 0));
297 const FString Path = *ObjPtrPtr != nullptr ? (*ObjPtrPtr)->GetPathName() : "";
298 auto WritePathName = [&]()
299 {
300 if (bContainerElement)
301 {
302 Target += PreString + "\"" + Path + "\"" + PostString;
303 }
304 else
305 {
306 Target += PreString + Property->GetName() + " \"" + Path + "\"" + PostString;
307 }
308 };
309
310 if (CanSaveAsReference(ObjectProperty, *ObjPtrPtr) || bPointerAsRef)
311 {
312 WritePathName();
313 }
314 else
315 {
316 // Write nullptr as empty string
317 if (*ObjPtrPtr == nullptr || ObjectProperty->PropertyClass == nullptr)
318 {
319 WritePathName();
320 return true;
321 }
322
323 WriteComplexToString(ObjectProperty->PropertyClass,
324 Property,
325 *ObjPtrPtr,
326 PreString,
327 PostString,
328 bContainerElement,
329 true,
330 Target);
331 }
332 return true;
333 }
334
335 return false;
336}
337
339void FDlgConfigWriter::WriteComplexToString(const UStruct* StructDefinition,
340 const FNYProperty* Property,
341 const void* Object,
342 const FString& PreString,
343 const FString& PostString,
344 bool bContainerElement,
345 bool bWriteType,
346 FString& Target)
347{
348 if (CanSkipProperty(Property) || StructDefinition == nullptr)
349 {
350 return;
351 }
352
353 const UObject* UnrealObject = static_cast<const UObject*>(Object);
354 if (bWriteType && !UnrealObject->IsValidLowLevelFast())
355 {
356 return;
357 }
358
359 const bool bLinePerMember = WouldWriteNonPrimitive(StructDefinition, Object);
360
361 // WARNING: bWriteType implicates objectproperty, if that changes this code (cause of the object cast) should be updated accordingly
362 const FString TypeString = bWriteType ? GetNameWithoutPrefix(Property, UnrealObject) + " ": "";
363 if (bContainerElement)
364 {
365 if (TypeString.Len() > 0)
366 {
367 Target += PreString + TypeString + (bLinePerMember ? EOL + PreString + "{" + EOL : "{ ");
368 }
369 else
370 {
371 Target += PreString + (bLinePerMember ? "{" + EOL_String : "{ ");
372 }
373 }
374 else
375 {
376 Target += PreString + TypeString + Property->GetName() + (bLinePerMember ? EOL + PreString + "{" + EOL : " { ");
377 }
378
379 // Write the properties of the Struct/Object
380 WriteComplexMembersToString(StructDefinition, Object, (bLinePerMember ? PreString + "\t" : " "), (bLinePerMember ? EOL_String : ""), Target);
381
382 if (bLinePerMember)
383 {
384 Target += PreString + "}" + PostString;
385 }
386 else
387 {
388 Target += " }" + PostString;
389 }
390}
391
394 const void* Object,
395 const FString& PreString,
396 const FString& PostString,
397 FString& Target)
398{
399 const auto* ArrayProp = FNYReflectionHelper::CastProperty<FNYArrayProperty>(Property);
400 if (ArrayProp == nullptr)
401 {
402 return false;
403 }
404 if (FNYReflectionHelper::CastProperty<FNYStructProperty>(ArrayProp->Inner) == nullptr
405 && FNYReflectionHelper::CastProperty<FNYObjectProperty>(ArrayProp->Inner) == nullptr)
406 {
407 return false;
408 }
409
410 // Empty Array
411 const FDlgConstScriptArrayHelper Helper(ArrayProp, ArrayProp->ContainerPtrToValuePtr<uint8>(Object));
412 if (Helper.Num() == 0 && bDontWriteEmptyContainer)
413 {
414 return true;
415 }
416
417 const bool bWriteIndex = CanWriteIndex(Property);
418 FString TypeText = "";
419 auto* ObjProp = FNYReflectionHelper::CastProperty<FNYObjectProperty>(ArrayProp->Inner);
420 if (ObjProp != nullptr && ObjProp->PropertyClass != nullptr)
421 {
422 TypeText = GetStringWithoutPrefix(ObjProp->PropertyClass->GetName()) + " ";
423 }
424
425 if (Helper.Num() == 1 && !WouldWriteNonPrimitive(GetComplexType(ArrayProp->Inner), Helper.GetConstRawPtr(0)))
426 {
427 Target += PreString + TypeText + ArrayProp->Inner->GetName() + " {";
428 for (int32 i = 0; i < Helper.Num(); ++i)
429 {
430 WriteComplexElementToString(ArrayProp->Inner, Helper.GetConstRawPtr(i), true, " ", "", CanSaveAsReference(ArrayProp, nullptr), Target);
431 }
432 Target += " }" + PostString;
433 }
434 else
435 {
436 Target += PreString + TypeText + ArrayProp->Inner->GetName() + EOL;
437 Target += PreString + "{" + EOL;
438 for (int32 i = 0; i < Helper.Num(); ++i)
439 {
440 if (bWriteIndex)
441 {
442 Target += PreString + "\t// " + FString::FromInt(i) + EOL;
443 }
444 WriteComplexElementToString(ArrayProp->Inner, Helper.GetConstRawPtr(i), true, PreString + "\t", EOL, CanSaveAsReference(ArrayProp, nullptr), Target);
445 }
446 Target += PreString + "}" + EOL;
447 }
448
449 return true;
450}
451
454 const void* Object,
455 const FString& PreString,
456 const FString& PostString,
457 FString& Target)
458{
459 const auto* MapProp = FNYReflectionHelper::CastProperty<FNYMapProperty>(Property);
460 if (MapProp == nullptr)
461 {
462 return false;
463 }
464
465 // Empty map
466 const FScriptMapHelper Helper(MapProp, MapProp->ContainerPtrToValuePtr<uint8>(Object));
467 if (Helper.Num() == 0 && bDontWriteEmptyContainer)
468 {
469 return true;
470 }
471
472 // NOTE: Because we access the value with GetPropertyValue_InContainer, we can't use GetValuePtr, instead use GetPairPtr
473 if (IsPrimitive(MapProp->KeyProp) && IsPrimitive(MapProp->ValueProp))
474 {
475 // Both Key and Value are primitives
476 Target += PreString + MapProp->GetName() + " { ";
477
478 // GetMaxIndex() instead of Num() - the container is not contiguous
479 // elements are in [0, GetMaxIndex[, some of them are invalid (Num() returns with the valid element num)
480 for (int32 i = 0; i < Helper.GetMaxIndex(); ++i)
481 {
482 if (!Helper.IsValidIndex(i))
483 {
484 continue;
485 }
486
487 WritePrimitiveElementToString(MapProp->KeyProp, Helper.GetPairPtr(i), true, "", " ", Target);
488 WritePrimitiveElementToString(MapProp->ValueProp, Helper.GetPairPtr(i), true, "", " ", Target);
489 }
490 Target += "}" + PostString;
491 }
492 else
493 {
494 // Either Key or Value is not a primitive
495 Target += PreString + MapProp->GetName() + EOL;
496 Target += PreString + "{" + EOL;
497
498 // GetMaxIndex() instead of Num() - the container is not contiguous
499 // elements are in [0, GetMaxIndex[, some of them are invalid (Num() returns with the valid element num)
500 for (int32 i = 0; i < Helper.GetMaxIndex(); ++i)
501 {
502 if (!Helper.IsValidIndex(i))
503 {
504 continue;
505 }
506
507 WritePropertyToString(MapProp->KeyProp, Helper.GetPairPtr(i), true, PreString + "\t", EOL, CanSaveAsReference(MapProp, nullptr), Target);
508 WritePropertyToString(MapProp->ValueProp, Helper.GetPairPtr(i), true, PreString + "\t", EOL, CanSaveAsReference(MapProp, nullptr), Target);
509 }
510 Target += PreString + "}" + EOL;
511 }
512
513 return true;
514}
515
518 const void* Object,
519 const FString& PreString,
520 const FString& PostString,
521 FString& Target)
522{
523 const auto* SetProp = FNYReflectionHelper::CastProperty<FNYSetProperty>(Property);
524 if (SetProp == nullptr)
525 {
526 return false;
527 }
528
529 // Empty set
530 const FScriptSetHelper Helper(SetProp, SetProp->ContainerPtrToValuePtr<uint8>(Object));
531 if (Helper.Num() == 0 && bDontWriteEmptyContainer)
532 {
533 return true;
534 }
535
536 // Only write primitive set elements
537 if (IsPrimitive(SetProp->ElementProp))
538 {
539 const bool bLinePerItem = CanWriteOneLinePerItem(SetProp);
540
541 // Add space indentation
542 FString SubPreString = PreString;
543 for (int32 i = 0; i < SetProp->GetName().Len() + 3; ++i)
544 {
545 SubPreString += " ";
546 }
547
548 // SetName {
549 Target += PreString + SetProp->GetName() + " {";
550 if (!bLinePerItem)
551 {
552 // Add space because there is no new line
553 Target += " ";
554 }
555
556 // Set content
557 // GetMaxIndex() instead of Num() - the container is not contiguous, elements are in [0, GetMaxIndex[, some of them is invalid (Num() returns with the valid element num)
558 for (int32 i = 0; i < Helper.GetMaxIndex(); ++i)
559 {
560 if (!Helper.IsValidIndex(i))
561 {
562 continue;
563 }
564
565 if (bLinePerItem)
566 {
567 WritePrimitiveElementToString(SetProp->ElementProp, Helper.GetElementPtr(i), true, EOL + SubPreString, "", Target);
568 }
569 else
570 {
571 WritePrimitiveElementToString(SetProp->ElementProp, Helper.GetElementPtr(i), true, "", " ", Target);
572 }
573 }
574
575 // }
576 Target += (bLinePerItem ? " " : "") + FString("}") + PostString;
577 }
578 else
579 {
580 UE_LOG(LogDlgConfigWriter, Warning, TEXT("Set not exported: unsuported set member (%s)"), *SetProp->ElementProp->GetName());
581 }
582
583 return true;
584}
585
588{
589 return FNYReflectionHelper::CastProperty<FNYBoolProperty>(Property) != nullptr ||
590 FNYReflectionHelper::CastProperty<FNYIntProperty>(Property) != nullptr ||
591 FNYReflectionHelper::CastProperty<FNYInt64Property>(Property) != nullptr ||
592 FNYReflectionHelper::CastProperty<FNYFloatProperty>(Property) != nullptr ||
593 FNYReflectionHelper::CastProperty<FNYStrProperty>(Property) != nullptr ||
594 FNYReflectionHelper::CastProperty<FNYNameProperty>(Property) != nullptr ||
595 FNYReflectionHelper::CastProperty<FNYTextProperty>(Property) != nullptr ||
596 FNYReflectionHelper::CastProperty<FNYEnumProperty>(Property) != nullptr;
597}
600{
601 return FNYReflectionHelper::CastProperty<FNYArrayProperty>(Property) != nullptr ||
602 FNYReflectionHelper::CastProperty<FNYMapProperty>(Property) != nullptr ||
603 FNYReflectionHelper::CastProperty<FNYSetProperty>(Property) != nullptr;
604}
607{
608 // Array
609 if (FNYReflectionHelper::CastProperty<FNYArrayProperty>(Property) != nullptr
610 && IsPrimitive(FNYReflectionHelper::CastProperty<FNYArrayProperty>(Property)->Inner))
611 {
612 return true;
613 }
614
615 // Map
616 if (FNYReflectionHelper::CastProperty<FNYMapProperty>(Property) != nullptr &&
617 IsPrimitive(FNYReflectionHelper::CastProperty<FNYMapProperty>(Property)->KeyProp) &&
618 IsPrimitive(FNYReflectionHelper::CastProperty<FNYMapProperty>(Property)->ValueProp))
619 {
620 return true;
621 }
622
623 // Set
624 if (FNYReflectionHelper::CastProperty<FNYSetProperty>(Property) != nullptr
625 && IsPrimitive(FNYReflectionHelper::CastProperty<FNYSetProperty>(Property)->ElementProp))
626 {
627 return true;
628 }
629
630 return false;
631}
633const UStruct* FDlgConfigWriter::GetComplexType(const FNYProperty* Property)
634{
635 if (const auto* StructProperty = FNYReflectionHelper::CastProperty<FNYStructProperty>(Property))
636 {
637 return StructProperty->Struct;
638 }
639
640 if (const auto* ObjectProperty = FNYReflectionHelper::CastProperty<FNYObjectProperty>(Property))
641 {
642 return ObjectProperty->PropertyClass;
643 }
644
645 return nullptr;
646}
648bool FDlgConfigWriter::WouldWriteNonPrimitive(const UStruct* StructDefinition, const void* Owner)
649{
650 if (StructDefinition == nullptr || Owner == nullptr)
651 {
652 return false;
653 }
654
655 for (TFieldIterator<const FNYProperty> It(StructDefinition); It; ++It)
656 {
657 const auto* Property = *It;
658
659 // Ignore primitives
660 if (IsPrimitive(Property))
661 {
662 continue;
663 }
664
665 if (IsContainer(Property))
666 {
667 // Map
668 if (const auto* MapProperty = FNYReflectionHelper::CastProperty<FNYMapProperty>(Property))
669 {
670 const FScriptMapHelper Helper(MapProperty, Property->ContainerPtrToValuePtr<uint8>(Owner));
671 if (Helper.Num() > 0)
672 {
673 return true;
674 }
675 }
676
677 // Array
678 if (const auto* ArrayProperty = FNYReflectionHelper::CastProperty<FNYArrayProperty>(Property))
679 {
680 const FScriptArrayHelper Helper(ArrayProperty, Property->ContainerPtrToValuePtr<uint8>(Owner));
681 if (Helper.Num() > 0)
682 {
683 return true;
684 }
685 }
686
687 // Set
688 if (const auto* SetProperty = FNYReflectionHelper::CastProperty<FNYSetProperty>(Property))
689 {
690 const FScriptSetHelper Helper(SetProperty, Property->ContainerPtrToValuePtr<uint8>(Owner));
691 if (Helper.Num() > 0)
692 {
693 return true;
694 }
695 }
696 }
697 else
698 {
699 if (FNYReflectionHelper::CastProperty<FNYStructProperty>(Property) != nullptr)
700 {
701 return true;
702 }
703
704 if (const auto* ObjectProperty = FNYReflectionHelper::CastProperty<FNYObjectProperty>(Property))
705 {
706 UObject** ObjPtrPtr = ((UObject**)ObjectProperty->ContainerPtrToValuePtr<void>(Owner, 0));
707 if (ObjPtrPtr != nullptr && !CanSaveAsReference(Property, *ObjPtrPtr))
708 return true;
709 }
710 }
711
712 }
713
714 return false;
715}
717FString FDlgConfigWriter::GetNameWithoutPrefix(const FNYProperty* Property, const UObject* ObjectPtr)
718{
719 if (const auto* StructProperty = FNYReflectionHelper::CastProperty<FNYStructProperty>(Property))
720 {
721 return GetStringWithoutPrefix(StructProperty->Struct->GetName());
722 }
723
724 if (const auto* ObjectProperty = FNYReflectionHelper::CastProperty<FNYObjectProperty>(Property))
725 {
726 // Get the Class from the ObjectProperty
727 if (ObjectPtr == nullptr)
728 {
729 return GetStringWithoutPrefix(ObjectProperty->PropertyClass->GetName());
730 }
731
732 if (ObjectPtr->GetClass())
733 {
734 return GetStringWithoutPrefix(ObjectPtr->GetClass()->GetName());
735 }
736 }
737
738 return "";
739}
742{
743 int32 Count = String.Len();
744 for (int32 i = 0; i < ComplexNamePrefix.Len() && i < String.Len() && ComplexNamePrefix[i] == String[i]; ++i)
745 {
746 Count -= 1;
747 }
748
749 return String.Right(Count);
750}
DEFINE_LOG_CATEGORY(LogDlgConfigWriter)
UProperty FNYProperty
bool WriteMapToString(const FNYProperty *Property, const void *Object, const FString &PreString, const FString &PostString, FString &Target)
const std::function< FString(const FString &) StringToString)
static const FString EOL_String
FDlgConfigWriter(const FString InComplexNamePrefix="", bool bInDontWriteEmptyContainer=true)
const std::function< FString(const float &) FloatToString)
const std::function< FString(const int64 &) IntToString)
const std::function< FString(const bool &) BoolToString)
const bool bDontWriteEmptyContainer
const std::function< FString(const FName &) NameToString)
bool WritePrimitiveArrayToString(const FNYProperty *Property, const void *Object, const FString &PreString, const FString &PostString, FString &Target)
const void * TopLevelObjectPtr
void Write(const UStruct *StructDefinition, const void *Object) override
bool WriteSetToString(const FNYProperty *Property, const void *Object, const FString &PreString, const FString &PostString, FString &Target)
static const TCHAR * EOL
bool IsContainer(const FNYProperty *Property)
bool IsPrimitiveContainer(const FNYProperty *Property)
static const TCHAR * EOL_LF
void WriteComplexToString(const UStruct *StructDefinition, const FNYProperty *Property, const void *Object, const FString &PreString, const FString &PostString, bool bContainerElement, bool bWriteType, FString &Target)
bool WriteComplexArrayToString(const FNYProperty *Property, const void *Object, const FString &PreString, const FString &PostString, FString &Target)
bool WouldWriteNonPrimitive(const UStruct *StructDefinition, const void *Owner)
bool WriteComplexElementToString(const FNYProperty *Property, const void *Object, bool bContainerElement, const FString &PreString, const FString &PostString, bool bPointerAsRef, FString &Target)
const std::function< FString(const FText &) TextToString)
bool WritePrimitiveElementToString(const FNYProperty *Property, const void *Object, bool bContainerElement, const FString &PreString, const FString &PostString, FString &Target)
FString GetStringWithoutPrefix(const FString &String)
bool IsPrimitive(const FNYProperty *Property)
const FString ComplexNamePrefix
static const TCHAR * EOL_CRLF
void WriteComplexMembersToString(const UStruct *StructDefinition, const void *Object, const FString &PreString, const FString &PostString, FString &Target)
const UStruct * GetComplexType(const FNYProperty *Property)
FString GetNameWithoutPrefix(const FNYProperty *StructDefinition, const UObject *ObjectPtr=nullptr)
bool WritePropertyToString(const FNYProperty *Property, const void *Object, bool bContainerElement, const FString &PreString, const FString &PostString, bool bPointerAsRef, FString &Target)
FORCEINLINE const uint8 * GetConstRawPtr(int32 Index=0) const
Definition DlgHelper.h:49
virtual bool CanSaveAsReference(const FNYProperty *Property, const UObject *Object)
Definition IDlgWriter.h:83
static bool CanWriteOneLinePerItem(const FNYProperty *Property)
Definition IDlgWriter.h:63
static bool CanSkipProperty(const FNYProperty *Property)
Definition IDlgWriter.h:41
static bool CanWriteIndex(const FNYProperty *Property)
Definition IDlgWriter.h:73