5#ifndef NY_REFLECTION_HELPER
6#define NY_REFLECTION_HELPER
8#include "CoreMinimal.h"
17#if ENGINE_MINOR_VERSION >= 25
19 template<
typename FieldType>
20 FORCEINLINE
static FieldType* CastProperty(FField* Src)
22 return Src && Src->HasAnyCastFlags(FieldType::StaticClassCastFlagsPrivate()) ?
static_cast<FieldType*
>(Src) :
nullptr;
25 template<
typename FieldType>
26 FORCEINLINE
static const FieldType* CastProperty(
const FField* Src)
28 return Src && Src->HasAnyCastFlags(FieldType::StaticClassCastFlagsPrivate()) ?
static_cast<const FieldType*
>(Src) :
nullptr;
31 FORCEINLINE
static FField* GetStructChildren(
const UStruct* Struct)
33 return Struct ? Struct->ChildProperties :
nullptr;
37 template <
typename To,
typename From>
38 static To* SmartCastProperty(From* Src)
40 To* Result = CastProperty<To>(Src);
41 if (Result ==
nullptr)
44 if (ArrayProp !=
nullptr)
46 Result = CastProperty<To>(ArrayProp->Inner);
53 template <
typename To,
typename From>
56 return TCastImpl<From, To>::DoCast(Src);
59 template <
typename To,
typename From>
62 return CastProperty<To>(
const_cast<From*
>(Src));
67 return Struct ? Struct->Children :
nullptr;
71 template <
typename To,
typename From>
74 To* Result =
dynamic_cast<To*
>(Src);
75 if (Result ==
nullptr)
78 if (ArrayProp !=
nullptr)
80 Result =
dynamic_cast<To*
>(ArrayProp->Inner);
88 template <
typename PropertyType,
typename VariableType>
94 LogDlgSystemReflectionHelper,
96 TEXT(
"Failed to get %s %s from Object that is null (not valid)"),
97 *PropertyType::StaticClass()->GetName(), *VariableName.ToString()
99 return VariableType{};
102 for (
auto* Property =
Object->GetClass()->PropertyLink; Property !=
nullptr; Property = Property->PropertyLinkNext)
104 const PropertyType* CastedProperty = CastProperty<PropertyType>(Property);
105 if (CastedProperty !=
nullptr && CastedProperty->GetFName() == VariableName)
107 return CastedProperty->GetPropertyValue_InContainer(
Object, 0);
112 LogDlgSystemReflectionHelper,
114 TEXT(
"Failed to get %s %s from %s - property not found!"),
115 *PropertyType::StaticClass()->GetName(), *VariableName.ToString(), *
Object->GetName()
117 return VariableType{};
121 template <
typename PropertyType,
typename VariableType>
127 LogDlgSystemReflectionHelper,
129 TEXT(
"Failed to modify %s %s of Object that is null (not valid)"),
130 *PropertyType::StaticClass()->GetName(), *VariableName.ToString()
138 SetVariable<PropertyType>(
Object, VariableName, Value);
143 for (
auto* Property =
Object->GetClass()->PropertyLink; Property !=
nullptr; Property = Property->PropertyLinkNext)
145 const PropertyType* CastedProperty = CastProperty<PropertyType>(Property);
146 if (CastedProperty !=
nullptr && CastedProperty->GetFName() == VariableName)
148 const VariableType OldValue = CastedProperty->GetPropertyValue_InContainer(
Object, 0);
149 CastedProperty->SetPropertyValue_InContainer(
Object, OldValue + Value);
155 LogDlgSystemReflectionHelper,
157 TEXT(
"Failed to modify %s %s from %s - property not found!"),
158 *PropertyType::StaticClass()->GetName(), *VariableName.ToString(), *
Object->GetName()
164 template <
typename PropertyType,
typename VariableType>
170 LogDlgSystemReflectionHelper,
172 TEXT(
"Failed to set %s %s of Object that is null (not valid)"),
173 *PropertyType::StaticClass()->GetName(), *VariableName.ToString()
178 for (
auto* Property =
Object->GetClass()->PropertyLink; Property !=
nullptr; Property = Property->PropertyLinkNext)
180 const PropertyType* CastedProperty = CastProperty<PropertyType>(Property);
181 if (CastedProperty !=
nullptr && CastedProperty->GetFName() == VariableName)
183 CastedProperty->SetPropertyValue_InContainer(
Object, NewValue);
189 LogDlgSystemReflectionHelper,
191 TEXT(
"Failed to set %s %s from %s - property not found!"),
192 *PropertyType::StaticClass()->GetName(), *VariableName.ToString(), *
Object->GetName()
198 template <
typename ContainerType>
200 const UClass* ParticipantClass,
202 ContainerType& OutContainer,
203 const TArray<UClass*>& BlacklistedClasses
206 if (!IsValid(ParticipantClass) || !PropertyClass)
211 auto IsPropertyAtStartOfBlacklistedClass = [&BlacklistedClasses](
FNYProperty* CheckProperty) ->
bool
213 for (UClass* Class : BlacklistedClasses)
221 if (Class->PropertyLink == CheckProperty)
231 auto* Property = ParticipantClass->PropertyLink;
232 while (Property !=
nullptr && !IsPropertyAtStartOfBlacklistedClass(Property))
234 if (Property->GetClass() == PropertyClass)
236 OutContainer.Add(Property->GetFName());
238 Property = Property->PropertyLinkNext;
DEFINE_LOG_CATEGORY_STATIC(LogApexAPI, Log, All)
UArrayProperty FNYArrayProperty
static To * SmartCastProperty(From *Src)
static void GetVariableNames(const UClass *ParticipantClass, const FNYPropertyClass *PropertyClass, ContainerType &OutContainer, const TArray< UClass * > &BlacklistedClasses)
static void ModifyVariable(UObject *Object, FName VariableName, const VariableType Value, bool bDelta)
static FORCEINLINE To * CastProperty(From *Src)
static FORCEINLINE UField * GetStructChildren(const UStruct *Struct)
static void SetVariable(UObject *Object, FName VariableName, const VariableType NewValue)
static VariableType GetVariable(const UObject *Object, FName VariableName)
static FORCEINLINE const To * CastProperty(const From *Src)