UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
Field.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3/*=============================================================================
4Field.h: Declares FField property system fundamentals
5=============================================================================*/
6
7#pragma once
8
9#include "Containers/Array.h"
11#include "Containers/Map.h"
14#include "CoreTypes.h"
15#include "Delegates/Delegate.h"
16#include "HAL/PlatformMath.h"
18#include "HAL/UnrealMemory.h"
20#include "Math/RandomStream.h"
22#include "Misc/CString.h"
23#include "Misc/EnumClassFlags.h"
24#include "Misc/Guid.h"
25#include "Misc/Optional.h"
30#include "Templates/EnableIf.h"
32#include "Templates/IsEnum.h"
33#include "Templates/NoDestroy.h"
34#include "Templates/Requires.h"
35#include "Templates/TypeHash.h"
38#include "UObject/CoreNative.h"
40#include "UObject/NameTypes.h"
41#include "UObject/Object.h"
44#include "UObject/Script.h"
47#include "UObject/UnrealNames.h"
49
50#include <type_traits>
51
52class FField;
53class FFieldVariant;
54class FProperty;
56class UClass;
57class UField;
58class UPackage;
59class UStruct;
60
66{
67public:
69private:
71
73 FName Name;
75 EClassFlags ClassFlags;
77 uint64 Id;
79 EClassCastFlags CastFlags;
81 FFieldClass* SuperClass;
83 FField* DefaultObject;
85 FConstructFunction* ConstructFn;
87 std::atomic<int32> UniqueNameIndexCounter = 0;
88
90 COREUOBJECT_API FField* ConstructDefaultObject();
91
92public:
93
98
101
102 consteval explicit FFieldClass(
104 const TCHAR* InCPPName,
105 uint64 InId,
109 )
110 : Name()
111 , ClassFlags()
112 , Id(InId)
113 , CastFlags(InCastFlags)
114 , SuperClass(InSuperClass)
115 , DefaultObject()
116 , ConstructFn(InConstructFn)
117 {
118 }
119
120#if UE_WITH_CONSTINIT_UOBJECT
121 bool IsFullyConstructed() const
122 {
123 return Name != FName();
124 }
125#endif
126
127 inline FString GetName() const
128 {
129#if UE_WITH_CONSTINIT_UOBJECT
131#endif
132 return Name.ToString();
133 }
134 inline FName GetFName() const
135 {
136#if UE_WITH_CONSTINIT_UOBJECT
138#endif
139 return Name;
140 }
141 inline uint64 GetId() const
142 {
143 return Id;
144 }
145 inline uint64 GetCastFlags() const
146 {
147 return CastFlags;
148 }
149 inline bool HasAnyCastFlags(const uint64 InCastFlags) const
150 {
151 return !!(CastFlags & InCastFlags);
152 }
153 inline bool HasAllCastFlags(const uint64 InCastFlags) const
154 {
155 return (CastFlags & InCastFlags) == InCastFlags;
156 }
157 inline bool IsChildOf(const FFieldClass* InClass) const
158 {
159 const uint64 OtherClassId = InClass->GetId();
160 return OtherClassId ? !!(CastFlags & OtherClassId) : IsChildOf_Walk(InClass);
161 }
162 COREUOBJECT_API FString GetDescription() const;
165 {
166 return ConstructFn(InOwner, InName, InFlags);
167 }
168
170 {
171 return SuperClass;
172 }
173
175 {
176 if (!DefaultObject)
177 {
178 DefaultObject = ConstructDefaultObject();
179 check(DefaultObject);
180 }
181 return DefaultObject;
182 }
183
185 {
186 return EnumHasAnyFlags(ClassFlags, FlagsToCheck) != 0;
187 }
188
190 {
191 return ++UniqueNameIndexCounter;
192 }
193
195 {
196 check(false);
197 return Ar;
198 }
200
201private:
202 bool IsChildOf_Walk(const FFieldClass* InBaseClass) const
203 {
205 {
206 if (TempField == InBaseClass)
207 {
208 return true;
209 }
210 }
211 return false;
212 }
213
214#if UE_WITH_CONSTINIT_UOBJECT
215 friend struct FRegisterFieldClass;
216#endif // UE_WITH_CONSTINIT_UOBJECT
217};
218
219#if UE_WITH_CONSTINIT_UOBJECT
221{
223};
224#endif // UE_WITH_CONSTINIT_UOBJECT
225
226#if !CHECK_PUREVIRTUALS
227 #define DECLARE_FIELD_NEW_IMPLEMENTATION(TClass) \
228 ThisClass* Mem = (ThisClass*)FMemory::Malloc(InSize); \
229 new (Mem) TClass(EC_InternalUseOnlyConstructor, TClass::StaticClass()); \
230 return Mem;
231#else
232 #define DECLARE_FIELD_NEW_IMPLEMENTATION(TClass) \
233 ThisClass* Mem = (ThisClass*)FMemory::Malloc(InSize); \
234 return Mem;
235#endif
236
237#if UE_WITH_CONSTINIT_UOBJECT
238#define UE_DEFINE_GET_FIELD_CLASS_PRIVATE virtual FFieldClass* GetFieldClassPrivate() override { return &ConstInitClass; }
239#define UE_DECLARE_FIELD_CLASS_STATIC_CONSTINIT static constinit TNoDestroy<FFieldClass> ConstInitClass;
240#define UE_DEFINE_FIELD_CLASS_STATIC_CONSTINIT(TClass) \
241 constinit TNoDestroy<FFieldClass> TClass::ConstInitClass{ NoDestroyConstEval, \
242 ConstEval, \
243 TEXT(PREPROCESSOR_TO_STRING(TClass)), \
244 TClass::StaticClassCastFlagsPrivate(), \
245 TClass::StaticClassCastFlags(), \
246 &TClass::Super::ConstInitClass, \
247 &TClass::Construct };
248#else
249#define UE_DEFINE_GET_FIELD_CLASS_PRIVATE
250#define UE_DECLARE_FIELD_CLASS_STATIC_CONSTINIT
251#define UE_DEFINE_FIELD_CLASS_STATIC_CONSTINIT(...)
252#endif
253
254#define DECLARE_FIELD(TClass, TSuperClass, TStaticFlags) \
255 DECLARE_FIELD_API(TClass, TSuperClass, TStaticFlags, NO_API)
256
257#define DECLARE_FIELD_API(TClass, TSuperClass, TStaticFlags, TRequiredAPI) \
258private: \
259 TClass& operator=(TClass&&) = delete; \
260 TClass& operator=(const TClass&) = delete; \
261 UE_DEFINE_GET_FIELD_CLASS_PRIVATE \
262public: \
263 using Super = PREPROCESSOR_REMOVE_OPTIONAL_PARENS(TSuperClass);\
264 using ThisClass = TClass;\
265 TClass(EInternal InInernal, FFieldClass* InClass) \
266 : Super(EC_InternalUseOnlyConstructor, InClass) \
267 { \
268 } \
269 static TRequiredAPI FFieldClass* StaticClass(); \
270 UE_DECLARE_FIELD_CLASS_STATIC_CONSTINIT \
271 static TRequiredAPI FField* Construct(const FFieldVariant& InOwner, const FName& InName, EObjectFlags InObjectFlags); \
272 inline static constexpr EClassCastFlags StaticClassCastFlagsPrivate() \
273 { \
274 return TStaticFlags; \
275 } \
276 inline static constexpr EClassCastFlags StaticClassCastFlags() \
277 { \
278 return TStaticFlags | Super::StaticClassCastFlags(); \
279 } \
280 inline void* operator new(const size_t InSize, void* InMem) \
281 { \
282 return InMem; \
283 } \
284 inline void* operator new(const size_t InSize) \
285 { \
286 DECLARE_FIELD_NEW_IMPLEMENTATION(TClass) \
287 } \
288 inline void operator delete(void* InMem) noexcept \
289 { \
290 FMemory::Free(InMem); \
291 } \
292 friend FArchive &operator<<( FArchive& Ar, ThisClass*& Res ) \
293 { \
294 return Ar << (FField*&)Res; \
295 } \
296 friend void operator<<(FStructuredArchive::FSlot InSlot, ThisClass*& Res) \
297 { \
298 InSlot << (FField*&)Res; \
299 } \
300 virtual SIZE_T GetFieldSize() const override \
301 { \
302 return sizeof(TClass); \
303 }
304
305#if !CHECK_PUREVIRTUALS
306 #define IMPLEMENT_FIELD_CONSTRUCT_IMPLEMENTATION(TClass) \
307 FField* Instance = new TClass(InOwner, InName, InFlags); \
308 return Instance;
309#else
310 #define IMPLEMENT_FIELD_CONSTRUCT_IMPLEMENTATION(TClass) \
311 return nullptr;
312#endif
313
314#if UE_WITH_CONSTINIT_UOBJECT
315#define IMPLEMENT_FIELD(TClass) \
316 FField* TClass::Construct(const FFieldVariant& InOwner, const FName& InName, EObjectFlags InFlags) \
317 { \
318 IMPLEMENT_FIELD_CONSTRUCT_IMPLEMENTATION(TClass) \
319 } \
320 UE_DEFINE_FIELD_CLASS_STATIC_CONSTINIT(TClass) \
321 static FRegisterFieldClass Register_FieldClass_##TClass( \
322 &TClass::ConstInitClass, TEXT(UE_STRINGIZE(TClass))); \
323 FFieldClass* TClass::StaticClass() \
324 { \
325 checkf(ConstInitClass->IsFullyConstructed(), \
326 UE_STRINGIZE(TClass) TEXT(": FieldClass not fully constructed before ::StaticClass called")); \
327 return &ConstInitClass; \
328 }
329#else // UE_WITH_CONSTINIT_UOBJECT
330#define IMPLEMENT_FIELD(TClass) \
331FField* TClass::Construct(const FFieldVariant& InOwner, const FName& InName, EObjectFlags InFlags) \
332{ \
333 IMPLEMENT_FIELD_CONSTRUCT_IMPLEMENTATION(TClass) \
334} \
335FFieldClass* TClass::StaticClass() \
336{ \
337 static FFieldClass StaticFieldClass(TEXT(PREPROCESSOR_TO_STRING(TClass)), TClass::StaticClassCastFlagsPrivate(), TClass::StaticClassCastFlags(), TClass::Super::StaticClass(), &TClass::Construct); \
338 return &StaticFieldClass; \
339}
340#endif // UE_WITH_CONSTINIT_UOBJECT
341
342class FField;
343class FLinkerLoad;
344class FProperty;
345class UObject;
346
353{
354 union FFieldObjectUnion
355 {
356 FField* Field;
357 UObject* Object;
358 UPTRINT Unknown;
359 } Container;
360
361 static constexpr uintptr_t UObjectMask = 0x1;
362
363 constexpr void ConditionallyMarkAsReachable()
364 {
366 {
368 {
370 }
371 }
372 }
373
374public:
375
376 constexpr FFieldVariant()
377 {
378 Container.Field = nullptr;
379 }
380
382 {
383 Container.Field = const_cast<FField*>(InField);
384 check(!IsUObject());
385 }
386
387#if UE_WITH_CONSTINIT_UOBJECT
388 explicit consteval FFieldVariant(EConstEval, UObject* InObject)
389 {
390 // Object is not tagged here - when the engine starts up, pointers will be tagged during UObject bootstrap
391 Container.Object = InObject;
392 }
393
394 explicit consteval FFieldVariant(EConstEval, const FField* InField)
395 {
396 Container.Field = const_cast<FField*>(InField);
397 }
398#endif
399
400 template <
401 typename T
402 UE_REQUIRES(std::is_convertible_v<T, const UObject*>)
403 >
404 FFieldVariant(T&& InObject)
405 {
406 Container.Object = const_cast<UObject*>(ImplicitConv<const UObject*>(InObject));
407 Container.Object = (UObject*)((uintptr_t)Container.Object | UObjectMask);
408 ConditionallyMarkAsReachable();
409 }
410
412 : FFieldVariant()
413 {
414 }
415
417 : Container(Other.Container)
418 {
419 ConditionallyMarkAsReachable();
420 }
421
423 {
424 Container = Other.Container;
425 ConditionallyMarkAsReachable();
426 return *this;
427 }
428
430 : Container(Other.Container)
431 {
432 ConditionallyMarkAsReachable();
433 }
434
436 {
437 Container = Other.Container;
438 ConditionallyMarkAsReachable();
439 return *this;
440 }
441
442 inline bool IsUObject() const
443 {
444 return (uintptr_t)Container.Object & UObjectMask;
445 }
446 inline bool IsValid() const
447 {
448 return !!ToUObjectUnsafe();
449 }
450 COREUOBJECT_API bool IsValidLowLevel() const;
451 inline operator bool() const
452 {
453 return IsValid();
454 }
455 COREUOBJECT_API bool IsA(const UClass* InClass) const;
456 COREUOBJECT_API bool IsA(const FFieldClass* InClass) const;
457 template <typename T>
458 bool IsA() const
459 {
460 static_assert(sizeof(T) > 0, "T must not be an incomplete type");
461 return IsA(T::StaticClass());
462 }
463
464 template <typename T>
465 T* Get() const
466 {
467 static_assert(sizeof(T) > 0, "T must not be an incomplete type");
468 if (IsA(T::StaticClass()))
469 {
470 if constexpr (std::is_base_of_v<UObject, T>)
471 {
472 return static_cast<T*>(ToUObjectUnsafe());
473 }
474 else
475 {
476 return static_cast<T*>(ToFieldUnsafe());
477 }
478 }
479 return nullptr;
480 }
481
483 {
484 if (IsUObject())
485 {
486 return ToUObjectUnsafe();
487 }
488 else
489 {
490 return nullptr;
491 }
492 }
494 {
495 if (!IsUObject())
496 {
497 return ToFieldUnsafe();
498 }
499 else
500 {
501 return nullptr;
502 }
503 }
506 {
507 return Container.Field;
508 }
511 {
512 return (UObject*)((uintptr_t)Container.Object & ~UObjectMask);
513 }
514
515 /* Return the raw value of the union without masking any tag bits away regardless of what type it is */
516 void* GetRawPointer() const
517 {
518 return (void*)Container.Unknown;
519 }
522 COREUOBJECT_API FString GetFullName() const;
523 COREUOBJECT_API FString GetPathName() const;
524 COREUOBJECT_API FString GetName() const;
525 COREUOBJECT_API FString GetClassName() const;
527 COREUOBJECT_API bool IsNative() const;
529
530 bool operator==(const FFieldVariant& Other) const
531 {
532 return Container.Field == Other.Container.Field;
533 }
534 bool operator!=(const FFieldVariant& Other) const
535 {
536 return Container.Field != Other.Container.Field;
537 }
538
539#if WITH_METADATA
540 COREUOBJECT_API bool HasMetaData(const FName& Key) const;
541#endif // WITH_METADATA
542
545 {
546 return GetTypeHash(InFieldVariant.GetRawPointer());
547 }
548};
549
556{
558
559 union
560 {
563#if UE_WITH_CONSTINIT_UOBJECT
564 // Share storage for compiled-in name with ClassPrivate which can be re-acquired through the object's vtable at runtime
565 // When there is a 4-byte solution for compiled-in FNames, this will be removed.
566 const UTF8CHAR* NameTempUTF8;
567#endif //UE_WITH_CONSTINIT_UOBJECT
568 };
569
570#if UE_WITH_CONSTINIT_UOBJECT
572#endif
573
574public:
575 typedef FField Super;
579
581#if UE_WITH_CONSTINIT_UOBJECT
583#endif // UE_WITH_CONSTINIT_UOBJECT
584
585 virtual SIZE_T GetFieldSize() const
586 {
587 return sizeof(FField);
588 }
589
591 {
592 return CASTCLASS_UField;
593 }
594 inline static constexpr EClassCastFlags StaticClassCastFlags()
595 {
596 return CASTCLASS_UField;
597 }
598
601
604
607
610
611 // Constructors.
614#if WITH_EDITORONLY_DATA
616#endif // WITH_EDITORONLY_DATA
617 COREUOBJECT_API virtual ~FField();
618
619#if UE_WITH_CONSTINIT_UOBJECT
620 explicit consteval FField(EConstEval, FFieldClass* InFieldClass, UE::CodeGen::ConstInit::FFieldOwnerParam InOwner, FField* InNext, EObjectFlags InFlags, const UTF8CHAR* InNameUTF8)
623 , Next(InNext)
624 , NamePrivate()
627 , MetaDataMap(nullptr)
628#endif
629 {
630 }
631#endif
632
633 // Begin UObject interface: the following functions mimic UObject interface for easier transition from UProperties to FProperties
634 COREUOBJECT_API virtual void Serialize(FArchive& Ar);
635 COREUOBJECT_API virtual void PostLoad();
637 COREUOBJECT_API virtual void BeginDestroy();
639 COREUOBJECT_API bool IsRooted() const;
640 COREUOBJECT_API bool IsNative() const;
641 COREUOBJECT_API bool IsValidLowLevel() const;
642 COREUOBJECT_API bool IsIn(const UObject* InOwner) const;
643 COREUOBJECT_API bool IsIn(const FField* InOwner) const;
645 // End UObject interface
646
647 // Begin UField interface.
649 COREUOBJECT_API virtual void Bind();
650 // End UField interface
651
658
660 COREUOBJECT_API virtual void PostDuplicate(const FField& InField);
661
662#if UE_WITH_CONSTINIT_UOBJECT
663 // For a const-initialized property, initialize the FName from a cached string and tag the owner pointer
666#endif
667
668protected:
673 {
674 checkfSlow((NewFlags & ~RF_AllFlags) == 0, TEXT("%s flagged as 0x%x but is trying to set flags to RF_AllFlags"), *GetFName().ToString(), (int32)FlagsPrivate);
676 }
677public:
684 {
685 checkfSlow((FlagsPrivate & ~RF_AllFlags) == 0, TEXT("%s flagged as RF_AllFlags"), *GetFName().ToString());
686 return FlagsPrivate;
687 }
688
690 {
691 checkSlow(!(NewFlags & (RF_MarkAsNative | RF_MarkAsRootSet))); // These flags can't be used outside of constructors / internal code
693 }
695 {
696 checkSlow(!(NewFlags & (RF_MarkAsNative | RF_MarkAsRootSet)) || NewFlags == RF_AllFlags); // These flags can't be used outside of constructors / internal code
698 }
706 {
707 checkSlow(!(FlagsToCheck & (RF_MarkAsNative | RF_MarkAsRootSet)) || FlagsToCheck == RF_AllFlags); // These flags can't be used outside of constructors / internal code
708 return (GetFlags() & FlagsToCheck) != 0;
709 }
717 {
718 checkSlow(!(FlagsToCheck & (RF_MarkAsNative | RF_MarkAsRootSet)) || FlagsToCheck == RF_AllFlags); // These flags can't be used outside of constructors / internal code
719 return ((GetFlags() & FlagsToCheck) == FlagsToCheck);
720 }
721
722 inline FFieldClass* GetClass() const
723 {
724 return ClassPrivate;
725 }
726 inline uint64 GetCastFlags() const
727 {
728 return GetClass()->GetCastFlags();
729 }
730
731 inline bool IsA(const FFieldClass* FieldType) const
732 {
734 return GetClass()->IsChildOf(FieldType);
735 }
736
737 template<typename T>
738 bool IsA() const
739 {
740 if constexpr (!!(T::StaticClassCastFlagsPrivate()))
741 {
742 return !!(GetCastFlags() & T::StaticClassCastFlagsPrivate());
743 }
744 else
745 {
746 return GetClass()->IsChildOf(T::StaticClass());
747 }
748 }
749
750 UE_DEPRECATED(5.0, "HasAnyCastFlags is deprecated. Not all FField has CastFlag. Use IsA instead.")
752 {
753 return !!(GetCastFlags() & InCastFlags);
754 }
755
756 UE_DEPRECATED(5.0, "HasAllCastFlags is deprecated. Not all FField has CastFlag. Use IsA instead.")
758 {
759 return (GetCastFlags() & InCastFlags) == InCastFlags;
760 }
761
762 void AppendName(FString& ResultString) const
763 {
764 GetFName().AppendString(ResultString);
765 }
766
769 {
770 return Owner;
771 }
772
774 inline UObject* GetOwnerUObject() const
775 {
777 while (!TempOuter.IsUObject() && TempOuter.IsValid())
778 {
779 // It's ok to use the 'Unsafe' variant of ToField here since we just checked IsUObject above
781 }
782 return TempOuter.ToUObject();
783 }
784
790
793
796
799
802
805
808
809 template <typename T>
810 T* GetOwner() const
811 {
812 static_assert(sizeof(T) > 0, "T must not be an incomplete type");
813 return Owner.Get<T>();
814 }
815
816 template <typename T>
820 {
821 static_assert(sizeof(T) > 0, "T must not be an incomplete type");
822 T* Result = Owner.Get<T>();
823 check(Result);
824 return Result;
825 }
826
827 template <typename T>
828 T* GetTypedOwner() const
829 {
830 static_assert(sizeof(T) > 0, "T must not be an incomplete type");
831 return static_cast<T*>(GetTypedOwner(T::StaticClass()));
832 }
833
834 inline FName GetFName() const
835 {
837 if (IsThisNotNull(this, "FField::GetFName"))
839 {
840 return NamePrivate;
841 }
842 else
843 {
844 return NAME_None;
845 }
846 }
847
848 inline FString GetName() const
849 {
851 if (IsThisNotNull(this, "FField::GetName"))
853 {
854 return NamePrivate.ToString();
855 }
856 else
857 {
858 return TEXT("None");
859 }
860 }
861
862 inline void GetName(FString& OutName) const
863 {
865 if (IsThisNotNull(this, "FField::GetName"))
867 {
869 }
870 else
871 {
872 OutName = TEXT("None");
873 }
874 }
875
876 COREUOBJECT_API void Rename(const FName& NewName);
877
878 COREUOBJECT_API FString GetPathName(const UObject* StopOuter = nullptr) const;
879 COREUOBJECT_API void GetPathName(const UObject* StopOuter, FStringBuilderBase& ResultString) const;
880 COREUOBJECT_API FString GetFullName() const;
881
887 COREUOBJECT_API FString GetAuthoredName() const;
888
890 virtual FField* GetInnerFieldByName(const FName& InName)
891 {
892 return nullptr;
893 }
894
897 {
898 }
899
900#if WITH_METADATA
901private:
904
905public:
912 bool HasMetaData(const TCHAR* Key) const { return FindMetaData(Key) != nullptr; }
913 bool HasMetaData(const FName& Key) const { return FindMetaData(Key) != nullptr; }
914
921 COREUOBJECT_API const FString* FindMetaData(const TCHAR* Key) const;
922 COREUOBJECT_API const FString* FindMetaData(const FName& Key) const;
923
930 COREUOBJECT_API const FString& GetMetaData(const TCHAR* Key) const;
931 COREUOBJECT_API const FString& GetMetaData(const FName& Key) const;
932
943
950 COREUOBJECT_API void SetMetaData(const TCHAR* Key, const TCHAR* InValue);
951 COREUOBJECT_API void SetMetaData(const FName& Key, const TCHAR* InValue);
952
953 COREUOBJECT_API void SetMetaData(const TCHAR* Key, FString&& InValue);
954 COREUOBJECT_API void SetMetaData(const FName& Key, FString&& InValue);
955
962 bool GetBoolMetaData(const TCHAR* Key) const
963 {
964 const FString& BoolString = GetMetaData(Key);
965 // FString == operator does case insensitive comparison
966 return (BoolString == "true");
967 }
968 bool GetBoolMetaData(const FName& Key) const
969 {
970 const FString& BoolString = GetMetaData(Key);
971 // FString == operator does case insensitive comparison
972 return (BoolString == "true");
973 }
974
981 int32 GetIntMetaData(const TCHAR* Key) const
982 {
983 const FString& INTString = GetMetaData(Key);
985 return Value;
986 }
987 int32 GetIntMetaData(const FName& Key) const
988 {
989 const FString& INTString = GetMetaData(Key);
991 return Value;
992 }
993
1000 float GetFloatMetaData(const TCHAR* Key) const
1001 {
1002 const FString& FLOATString = GetMetaData(Key);
1003 // FString == operator does case insensitive comparison
1005 return Value;
1006 }
1007 float GetFloatMetaData(const FName& Key) const
1008 {
1009 const FString& FLOATString = GetMetaData(Key);
1010 // FString == operator does case insensitive comparison
1012 return Value;
1013 }
1014
1021 double GetDoubleMetaData(const TCHAR* Key) const
1022 {
1023 const FString& DOUBLEString = GetMetaData(Key);
1024 // FString == operator does case insensitive comparison
1026 return Value;
1027 }
1028 double GetDoubleMetaData(const FName& Key) const
1029 {
1030 const FString& DOUBLEString = GetMetaData(Key);
1031 // FString == operator does case insensitive comparison
1033 return Value;
1034 }
1035
1042 COREUOBJECT_API UClass* GetClassMetaData(const TCHAR* Key) const;
1043 COREUOBJECT_API UClass* GetClassMetaData(const FName& Key) const;
1044
1046 COREUOBJECT_API void RemoveMetaData(const TCHAR* Key);
1047 COREUOBJECT_API void RemoveMetaData(const FName& Key);
1048
1051
1054
1056 static COREUOBJECT_API void CopyMetaData(const FField* InSourceField, FField* InDestField);
1057#endif // WITH_METADATA
1058
1059#if WITH_EDITORONLY_DATA
1060public:
1067 COREUOBJECT_API FString GetFullGroupName(bool bStartWithOuter) const;
1068
1075
1083 COREUOBJECT_API FText GetToolTipText(bool bShortTooltip = false) const;
1084
1087
1091#endif // WITH_EDITORONLY_DATA
1092
1093public:
1096
1099
1101};
1102
1103// Support for casting between different FFIeld types
1104
1105template<typename FieldType>
1107{
1108 return Src && Src->IsA<FieldType>() ? static_cast<FieldType*>(Src) : nullptr;
1109}
1110
1111template<typename FieldType>
1113{
1114 return Src && Src->IsA<FieldType>() ? static_cast<const FieldType*>(Src) : nullptr;
1115}
1116
1117template<typename FieldType>
1119{
1120 return (Src && (Src->GetClass() == FieldType::StaticClass())) ? static_cast<FieldType*>(Src) : nullptr;
1121}
1122
1123template<typename FieldType>
1125{
1126 return (Src && (Src->GetClass() == FieldType::StaticClass())) ? static_cast<const FieldType*>(Src) : nullptr;
1127}
1128
1129template<typename FieldType>
1133{
1134#if !DO_CHECK
1135 return (FieldType*)Src;
1136#else
1137 FieldType* CastResult = Src && Src->IsA<FieldType>() ? static_cast<FieldType*>(Src) : nullptr;
1138 checkf(CastResult, TEXT("CastFieldChecked failed with 0x%016llx"), (int64)(PTRINT)Src);
1139 return CastResult;
1140#endif // !DO_CHECK
1141}
1142
1143template<typename FieldType>
1145inline const FieldType* CastFieldChecked(const FField* Src)
1147{
1148#if !DO_CHECK
1149 return (const FieldType*)Src;
1150#else
1151 const FieldType* CastResult = Src && Src->IsA<FieldType>() ? static_cast<const FieldType*>(Src) : nullptr;
1152 checkf(CastResult, TEXT("CastFieldChecked failed with 0x%016llx"), (int64)(PTRINT)Src);
1153 return CastResult;
1154#endif // !DO_CHECK
1155}
1156
1157template<typename FieldType>
1159{
1160#if !DO_CHECK
1161 return (FieldType*)Src;
1162#else
1163 FieldType* CastResult = Src && Src->IsA<FieldType>() ? static_cast<FieldType*>(Src) : nullptr;
1164 checkf(CastResult || !Src, TEXT("CastFieldCheckedNullAllowed failed with 0x%016llx"), (int64)(PTRINT)Src);
1165 return CastResult;
1166#endif // !DO_CHECK
1167}
1168
1169template<typename FieldType>
1171{
1172#if !DO_CHECK
1173 return (const FieldType*)Src;
1174#else
1175 const FieldType* CastResult = Src && Src->IsA<FieldType>() ? static_cast<const FieldType*>(Src) : nullptr;
1176 checkf(CastResult || !Src, TEXT("CastFieldCheckedNullAllowed failed with 0x%016llx"), (int64)(PTRINT)Src);
1177 return CastResult;
1178#endif // !DO_CHECK
1179}
1180
1184template <typename FieldType>
1186{
1187 if (Ar.IsLoading())
1188 {
1190 Ar << PropertyTypeName;
1192 {
1194 check(Field);
1195 Field->Serialize(Ar);
1196 }
1197 else
1198 {
1199 Field = nullptr;
1200 }
1201 }
1202 else
1203 {
1204 FName PropertyTypeName = Field ? Field->GetClass()->GetFName() : NAME_None;
1205 Ar << PropertyTypeName;
1206 if (Field)
1207 {
1208 Field->Serialize(Ar);
1209 }
1210 }
1211}
1212
1217{
1218 if (InField)
1219 {
1220 return InField->GetFName();
1221 }
1222 else
1223 {
1224 return NAME_None;
1225 }
1226}
1230inline FString GetNameSafe(const FField* InField)
1231{
1232 if (InField)
1233 {
1234 return InField->GetName();
1235 }
1236 else
1237 {
1238 return TEXT("none");
1239 }
1240}
1248COREUOBJECT_API FString GetPathNameSafe(const FField* InField, const UObject* StopOuter = nullptr);
1256template <typename FieldType>
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define checkfSlow(expr, format,...)
Definition AssertionMacros.h:333
#define check(expr)
Definition AssertionMacros.h:314
#define checkf(expr, format,...)
Definition AssertionMacros.h:315
bool IsThisNotNull(const void *This, const ANSICHAR *Function)
Definition CoreGlobals.cpp:999
#define PURE_VIRTUAL(func,...)
Definition CoreMiscDefines.h:103
#define UE_NONCOPYABLE(TypeName)
Definition CoreMiscDefines.h:457
#define UE_DEPRECATED(Version, Message)
Definition CoreMiscDefines.h:302
#define WITH_METADATA
Definition CoreMiscDefines.h:32
EConstEval
Definition CoreMiscDefines.h:161
@ ConstEval
Definition CoreMiscDefines.h:161
FName GetFNameSafe(const FField *InField)
Definition Field.h:1216
void SerializeSingleField(FArchive &Ar, FieldType *&Field, FFieldVariant Owner)
Definition Field.h:1185
COREUOBJECT_API FString GetFullNameSafe(const FField *InField)
Definition Field.cpp:1138
FieldType * CastFieldCheckedNullAllowed(FField *Src)
Definition Field.h:1158
FString GetNameSafe(const FField *InField)
Definition Field.h:1230
FieldType * FindFProperty(const TCHAR *InFieldPath)
Definition Field.h:1257
UE_FORCEINLINE_HINT FieldType * CastField(FField *Src)
Definition Field.h:1106
COREUOBJECT_API FString GetPathNameSafe(const FField *InField, const UObject *StopOuter=nullptr)
Definition Field.cpp:1150
COREUOBJECT_API FField * FindFPropertyByPath(const TCHAR *InFieldPath)
Definition Field.cpp:1162
UE_FORCEINLINE_HINT FieldType * ExactCastField(FField *Src)
Definition Field.h:1118
FUNCTION_NON_NULL_RETURN_START FieldType * CastFieldChecked(FField *Src) FUNCTION_NON_NULL_RETURN_END
Definition Field.h:1131
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::SIZE_T SIZE_T
An unsigned integer the same size as a pointer, the same as UPTRINT.
Definition Platform.h:1150
FPlatformTypes::TYPE_OF_NULLPTR TYPE_OF_NULLPTR
The type of the C++ nullptr keyword.
Definition Platform.h:1157
FPlatformTypes::PTRINT PTRINT
A signed integer the same size as a pointer.
Definition Platform.h:1148
FPlatformTypes::TCHAR TCHAR
Either ANSICHAR or WIDECHAR, depending on whether the platform supports wide characters or the requir...
Definition Platform.h:1135
FPlatformTypes::int64 int64
A 64-bit signed integer.
Definition Platform.h:1127
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
FPlatformTypes::UPTRINT UPTRINT
An unsigned integer the same size as a pointer.
Definition Platform.h:1146
FPlatformTypes::UTF8CHAR UTF8CHAR
An 8-bit character containing a UTF8 (Unicode, 8-bit, variable-width) code unit.
Definition Platform.h:1137
#define UE_IF_NOT_CONSTEVAL
Definition Platform.h:787
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
#define FUNCTION_NON_NULL_RETURN_END
Definition Platform.h:807
#define FUNCTION_NON_NULL_RETURN_START
Definition Platform.h:804
FPlatformTypes::uint64 uint64
A 64-bit unsigned integer.
Definition Platform.h:1117
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define DECLARE_MULTICAST_DELEGATE_ThreeParams(DelegateName, Param1Type, Param2Type, Param3Type)
Definition DelegateCombinations.h:67
constexpr bool EnumHasAnyFlags(Enum Flags, Enum Contains)
Definition EnumClassFlags.h:35
#define PRAGMA_ENABLE_DEPRECATION_WARNINGS
Definition GenericPlatformCompilerPreSetup.h:12
#define PRAGMA_DISABLE_DEPRECATION_WARNINGS
Definition GenericPlatformCompilerPreSetup.h:8
const bool
Definition NetworkReplayStreaming.h:178
#define EInternalObjectFlags_AllFlags
Definition ObjectMacros.h:678
EClassCastFlags
Definition ObjectMacros.h:333
@ CASTCLASS_UField
Definition ObjectMacros.h:336
EClassFlags
Definition ObjectMacros.h:199
EInternalObjectFlags
Definition ObjectMacros.h:631
EObjectFlags
Definition ObjectMacros.h:552
@ RF_MarkAsRootSet
Object will be marked as root set on construction and not be garbage collected, even if unreferenced ...
Definition ObjectMacros.h:568
@ RF_NoFlags
No flags, used to avoid a cast.
Definition ObjectMacros.h:555
@ RF_MarkAsNative
Object (UField) will be marked as native on construction (DO NOT USE THIS FLAG in HasAnyFlags() etc)
Definition ObjectMacros.h:561
#define RF_AllFlags
All flags, used mainly for error checking.
Definition ObjectMacros.h:612
EInternal
Definition ObjectMacros.h:175
#define UE_REQUIRES(...)
Definition Requires.h:86
if(Failed) console_printf("Failed.\n")
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition Archive.h:1208
UE_FORCEINLINE_HINT bool IsLoading() const
Definition Archive.h:236
Definition Field.h:66
friend FArchive & operator<<(FArchive &Ar, FFieldClass &InField)
Definition Field.h:194
uint64 GetId() const
Definition Field.h:141
uint64 GetCastFlags() const
Definition Field.h:145
static COREUOBJECT_API TArray< FFieldClass * > & GetAllFieldClasses()
Definition Field.cpp:79
COREUOBJECT_API ~FFieldClass()
Definition Field.cpp:73
FString GetName() const
Definition Field.h:127
FField * Construct(const FFieldVariant &InOwner, const FName &InName, EObjectFlags InFlags=RF_NoFlags) const
Definition Field.h:164
FName GetFName() const
Definition Field.h:134
FField *(const FFieldVariant &, const FName &, EObjectFlags) FConstructFunction
Definition Field.h:68
consteval FFieldClass(EConstEval, const TCHAR *InCPPName, uint64 InId, EClassCastFlags InCastFlags, FFieldClass *InSuperClass, FConstructFunction *InConstructFn)
Definition Field.h:102
bool IsChildOf(const FFieldClass *InClass) const
Definition Field.h:157
FField * GetDefaultObject()
Definition Field.h:174
COREUOBJECT_API FString GetDescription() const
Definition Field.cpp:96
COREUOBJECT_API FText GetDisplayNameText() const
Definition Field.cpp:101
FFieldClass * GetSuperClass() const
Definition Field.h:169
COREUOBJECT_API FFieldClass(const TCHAR *InCPPName, uint64 InId, EClassCastFlags InCastFlags, FFieldClass *InSuperClass, FConstructFunction *InConstructFn)
int32 GetNextUniqueNameIndex()
Definition Field.h:189
bool HasAllCastFlags(const uint64 InCastFlags) const
Definition Field.h:153
bool HasAnyClassFlags(EClassFlags FlagsToCheck) const
Definition Field.h:184
bool HasAnyCastFlags(const uint64 InCastFlags) const
Definition Field.h:149
static COREUOBJECT_API TMap< FName, FFieldClass * > & GetNameToFieldClassMap()
Definition Field.cpp:84
Definition Field.h:353
COREUOBJECT_API FName GetFName() const
Definition Field.cpp:194
constexpr FFieldVariant & operator=(const FFieldVariant &Other)
Definition Field.h:422
bool operator==(const FFieldVariant &Other) const
Definition Field.h:530
COREUOBJECT_API FFieldVariant GetOwnerVariant() const
Definition Field.cpp:124
UObject * ToUObject() const
Definition Field.h:482
COREUOBJECT_API bool IsValidLowLevel() const
Definition Field.cpp:245
constexpr FFieldVariant(TYPE_OF_NULLPTR)
Definition Field.h:411
FFieldVariant(T &&InObject)
Definition Field.h:404
FField * ToField() const
Definition Field.h:493
T * Get() const
Definition Field.h:465
COREUOBJECT_API bool IsNative() const
Definition Field.cpp:219
constexpr FFieldVariant & operator=(FFieldVariant &&Other)
Definition Field.h:435
COREUOBJECT_API UClass * GetOwnerClass() const
Definition Field.cpp:145
void * GetRawPointer() const
Definition Field.h:516
friend uint32 GetTypeHash(const FFieldVariant &InFieldVariant)
Definition Field.h:544
COREUOBJECT_API FString GetFullName() const
Definition Field.cpp:158
FFieldVariant(const FField *InField)
Definition Field.h:381
bool IsUObject() const
Definition Field.h:442
COREUOBJECT_API UPackage * GetOutermost() const
Definition Field.cpp:232
bool operator!=(const FFieldVariant &Other) const
Definition Field.h:534
bool IsValid() const
Definition Field.h:446
constexpr FFieldVariant(FFieldVariant &&Other)
Definition Field.h:429
constexpr FFieldVariant(const FFieldVariant &Other)
Definition Field.h:416
bool IsA() const
Definition Field.h:458
UE_FORCEINLINE_HINT FField * ToFieldUnsafe() const
Definition Field.h:505
UE_FORCEINLINE_HINT UObject * ToUObjectUnsafe() const
Definition Field.h:510
COREUOBJECT_API FString GetPathName() const
Definition Field.cpp:170
COREUOBJECT_API FString GetName() const
Definition Field.cpp:182
COREUOBJECT_API FString GetClassName() const
Definition Field.cpp:206
constexpr FFieldVariant()
Definition Field.h:376
Definition Field.h:556
T * GetTypedOwner() const
Definition Field.h:828
FFieldClass * ClassPrivate
Definition Field.h:562
static constexpr EClassCastFlags StaticClassCastFlags()
Definition Field.h:594
bool IsA() const
Definition Field.h:738
UE_FORCEINLINE_HINT UObject * InternalGetOwnerAsUObjectUnsafe() const
Definition Field.h:786
static COREUOBJECT_API FName GenerateFFieldName(FFieldVariant InOwner, FFieldClass *InClass)
Definition Field.cpp:871
COREUOBJECT_API FString GetAuthoredName() const
Definition Field.cpp:620
virtual COREUOBJECT_API void Bind()
Definition Field.cpp:421
bool HasAnyFlags(EObjectFlags FlagsToCheck) const
Definition Field.h:705
virtual COREUOBJECT_API void PostLoad()
Definition Field.cpp:425
FString GetName() const
Definition Field.h:848
virtual COREUOBJECT_API void GetPreloadDependencies(TArray< UObject * > &OutDeps)
Definition Field.cpp:465
T * GetOwner() const
Definition Field.h:810
bool HasAllFlags(EObjectFlags FlagsToCheck) const
Definition Field.h:716
static constexpr EClassCastFlags StaticClassCastFlagsPrivate()
Definition Field.h:590
virtual COREUOBJECT_API void PostDuplicate(const FField &InField)
Definition Field.cpp:841
static COREUOBJECT_API FFieldClass * StaticClass()
Definition Field.cpp:293
FField Super
Definition Field.h:575
static COREUOBJECT_API FField * Construct(const FFieldVariant &InOwner, const FName &InName, EObjectFlags InFlags)
Definition Field.cpp:277
COREUOBJECT_API UField * GetOwnerUField() const
Definition Field.cpp:408
COREUOBJECT_API bool IsRooted() const
Definition Field.cpp:487
COREUOBJECT_API FString GetFullName() const
Definition Field.cpp:599
FFieldVariant Owner
Definition Field.h:600
virtual FField * GetInnerFieldByName(const FName &InName)
Definition Field.h:890
COREUOBJECT_API bool IsNative() const
Definition Field.cpp:506
FFieldClass FieldTypeClass
Definition Field.h:578
COREUOBJECT_API bool IsIn(const UObject *InOwner) const
Definition Field.cpp:524
bool IsA(const FFieldClass *FieldType) const
Definition Field.h:731
COREUOBJECT_API UStruct * GetOwnerStruct() const
Definition Field.cpp:393
virtual COREUOBJECT_API void AddReferencedObjects(FReferenceCollector &Collector)
Definition Field.cpp:474
FField ThisClass
Definition Field.h:576
FField * Next
Definition Field.h:603
virtual COREUOBJECT_API ~FField()
Definition Field.cpp:323
COREUOBJECT_API FLinkerLoad * GetLinker() const
Definition Field.cpp:554
virtual SIZE_T GetFieldSize() const
Definition Field.h:585
static COREUOBJECT_API FField * TryConstruct(const FName &FieldTypeName, const FFieldVariant &InOwner, const FName &InName, EObjectFlags InFlags)
Definition Field.cpp:862
void SetFlagsTo(EObjectFlags NewFlags)
Definition Field.h:672
UObject * GetOwnerUObject() const
Definition Field.h:774
COREUOBJECT_API void Rename(const FName &NewName)
Definition Field.cpp:630
void ClearFlags(EObjectFlags NewFlags)
Definition Field.h:694
FFieldClass * GetClass() const
Definition Field.h:722
EObjectFlags FlagsPrivate
Definition Field.h:609
virtual void GetInnerFields(TArray< FField * > &OutFields)
Definition Field.h:896
COREUOBJECT_API UClass * GetOwnerClass() const
Definition Field.cpp:372
void GetName(FString &OutName) const
Definition Field.h:862
FUNCTION_NON_NULL_RETURN_START T * GetOwnerChecked() const FUNCTION_NON_NULL_RETURN_END
Definition Field.h:818
COREUOBJECT_API UPackage * GetOutermost() const
Definition Field.cpp:414
COREUOBJECT_API FString GetPathName(const UObject *StopOuter=nullptr) const
Definition Field.cpp:565
FFieldVariant GetOwnerVariant() const
Definition Field.h:768
bool HasAllCastFlags(const uint64 InCastFlags) const
Definition Field.h:757
void AppendName(FString &ResultString) const
Definition Field.h:762
virtual COREUOBJECT_API void AddCppProperty(FProperty *Property)
Definition Field.cpp:560
FName GetFName() const
Definition Field.h:834
FField BaseFieldClass
Definition Field.h:577
bool HasAnyCastFlags(const uint64 InCastFlags) const
Definition Field.h:751
void SetFlags(EObjectFlags NewFlags)
Definition Field.h:689
FName NamePrivate
Definition Field.h:606
COREUOBJECT_API bool IsValidLowLevel() const
Definition Field.cpp:517
uint64 GetCastFlags() const
Definition Field.h:726
virtual COREUOBJECT_API void BeginDestroy()
Definition Field.cpp:470
EObjectFlags GetFlags() const
Definition Field.h:683
Definition LinkerLoad.h:124
Definition NameTypes.h:617
CORE_API FString ToString() const
Definition UnrealNames.cpp:3537
CORE_API void AppendString(FWideString &Out) const
Definition UnrealNames.cpp:3717
Definition UnrealType.h:174
Definition UObjectGlobals.h:2492
Definition TextKey.h:75
Definition Text.h:385
Definition Array.h:670
Definition UnrealString.h.inl:34
Definition Class.h:3793
Definition Class.h:181
Definition Object.h:95
Definition Package.h:216
Definition Class.h:480
FString GetDisplayNameText(const UEnum *Enum, int64 Value, const FString &Fallback)
Definition Collision.cpp:642
Definition FieldSystemNoiseAlgo.cpp:6
bool GIsIncrementalReachabilityPending
Definition GarbageCollection.cpp:620
void MarkAsReachable(const UObject *Obj)
Definition GarbageCollection.cpp:603
static UE_FORCEINLINE_HINT int32 Atoi(const CharType *String)
Definition CString.h:1173
static UE_FORCEINLINE_HINT float Atof(const CharType *String)
Definition CString.h:1185
static UE_FORCEINLINE_HINT double Atod(const CharType *String)
Definition CString.h:1191
Definition LinkedListBuilder.h:212
Definition NoDestroy.h:18