33 UE_LOG(LogDlgJsonWriter, Verbose, TEXT(
"ConvertScalarPropertyToJsonValue, Property = `%s`"), *Property->GetPathName());
35 if (ValuePtr ==
nullptr)
38 return MakeShared<FJsonValueNull>();
49 auto GetJsonStringForEnum = [&ValuePtr](
const UEnum* EnumDefinition,
const FNYNumericProperty* NumericProperty) -> TSharedPtr<FJsonValue>
51 const FString StringValue = EnumDefinition->GetNameByIndex(NumericProperty->GetSignedIntPropertyValue(ValuePtr)).ToString();
52 return MakeShared<FJsonValueString>(StringValue);
56 auto AddIndexMetadata = [
this, Property](TSharedRef<FJsonObject> JsonObject)
60 JsonObject->SetField(TEXT(
"__index__"), MakeShared<FJsonValueNumber>(
IndexInArray));
65 if (
const auto* EnumProperty = FNYReflectionHelper::CastProperty<FNYEnumProperty>(Property))
67 return GetJsonStringForEnum(EnumProperty->GetEnum(), EnumProperty->GetUnderlyingProperty());
71 if (
const auto* NumericProperty = FNYReflectionHelper::CastProperty<FNYNumericProperty>(Property))
74 if (UEnum* EnumDef = NumericProperty->GetIntPropertyEnum())
76 return GetJsonStringForEnum(EnumDef, NumericProperty);
80 if (NumericProperty->IsInteger())
87 return MakeShared<FJsonValueString>(FString::Printf(TEXT(
"%lld"), NumericProperty->GetSignedIntPropertyValue(ValuePtr)));
90 return MakeShared<FJsonValueNumber>(NumericProperty->GetSignedIntPropertyValue(ValuePtr));
92 if (NumericProperty->IsFloatingPoint())
94 return MakeShared<FJsonValueNumber>(NumericProperty->GetFloatingPointPropertyValue(ValuePtr));
98 return MakeShared<FJsonValueNull>();
102 if (
const auto* BoolProperty = FNYReflectionHelper::CastProperty<FNYBoolProperty>(Property))
104 return MakeShared<FJsonValueBoolean>(BoolProperty->GetOptionalPropertyValue(ValuePtr));
108 if (
const auto* StringProperty = FNYReflectionHelper::CastProperty<FNYStrProperty>(Property))
110 return MakeShared<FJsonValueString>(StringProperty->GetOptionalPropertyValue(ValuePtr));
114 if (
const auto* NameProperty = FNYReflectionHelper::CastProperty<FNYNameProperty>(Property))
116 auto* NamePtr =
static_cast<const FName*
>(ValuePtr);
117 if (NamePtr ==
nullptr)
119 UE_LOG(LogDlgJsonWriter,
121 TEXT(
"Got Property = `%s` of type FNYNameProperty but the Value it not an FName"),
122 *NameProperty->GetName())
123 return MakeShared<FJsonValueNull>();
125 if (!NamePtr->IsValidIndexFast() || !NamePtr->IsValid())
127 UE_LOG(LogDlgJsonWriter,
Error, TEXT(
"Got Property = `%s` of type FName but it is not valid :("), *NameProperty->GetNameCPP())
128 return MakeShared<FJsonValueNull>();
131 return MakeShared<FJsonValueString>(NamePtr->ToString());
135 if (
const auto* TextProperty = FNYReflectionHelper::CastProperty<FNYTextProperty>(Property))
137 return MakeShared<FJsonValueString>(TextProperty->GetOptionalPropertyValue(ValuePtr).ToString());
141 if (
const auto* ArrayProperty = FNYReflectionHelper::CastProperty<FNYArrayProperty>(Property))
143 TArray<TSharedPtr<FJsonValue>>
Array;
145 for (int32 Index = 0, Num = Helper.Num(); Index < Num; Index++)
157 return MakeShared<FJsonValueArray>(
Array);
161 if (
const auto* SetProperty = FNYReflectionHelper::CastProperty<FNYSetProperty>(Property))
163 TArray<TSharedPtr<FJsonValue>>
Array;
164 const FScriptSetHelper Helper(SetProperty, ValuePtr);
168 for (int32 Index = 0; Index < Helper.GetMaxIndex(); Index++)
170 if (!Helper.IsValidIndex(Index))
176 TSharedPtr<FJsonValue> Elem =
PropertyToJsonValue(SetProperty->ElementProp, ContainerPtr, Helper.GetElementPtr(Index));
185 return MakeShared<FJsonValueArray>(
Array);
189 if (
const auto* MapProperty = FNYReflectionHelper::CastProperty<FNYMapProperty>(Property))
191 const TSharedRef<FJsonObject> OutObject = MakeShared<FJsonObject>();
196 for (int32 Index = 0; Index < Helper.GetMaxIndex(); Index++)
198 if (!Helper.IsValidIndex(Index))
206 const TSharedPtr<FJsonValue> KeyElement =
PropertyToJsonValue(Helper.GetKeyProperty(), ContainerPtr, MapKeyPtr);
210 const TSharedPtr<FJsonValue> ValueElement =
PropertyToJsonValue(Helper.GetValueProperty(), ContainerPtr, MapValuePtr);
212 if (KeyElement.IsValid() && ValueElement.IsValid())
217 if (
auto* KeyStructProperty = FNYReflectionHelper::CastProperty<FNYStructProperty>(MapProperty->KeyProp))
220 MapProperty->KeyProp->ExportTextItem(KeyString, MapKeyPtr, MapKeyPtr,
nullptr, PPF_None);
225 KeyString = KeyElement->AsString();
229 if (KeyString.IsEmpty())
231 MapProperty->KeyProp->ExportTextItem(KeyString, MapKeyPtr, MapKeyPtr,
nullptr, PPF_None);
233 if (KeyString.IsEmpty())
235 UE_LOG(LogDlgJsonWriter,
Error, TEXT(
"Unable to convert key to string for property `%s`."), *MapProperty->GetNameCPP())
236 KeyString = FString::Printf(TEXT(
"Unparsed Key %d"), Index);
240 OutObject->SetField(KeyString, ValueElement);
245 return MakeShared<FJsonValueObject>(OutObject);
249 if (
const auto* StructProperty = FNYReflectionHelper::CastProperty<FNYStructProperty>(Property))
252 UScriptStruct::ICppStructOps* TheCppStructOps = StructProperty->Struct->GetCppStructOps();
253 if (StructProperty->Struct != FJsonObjectWrapper::StaticStruct() && TheCppStructOps && TheCppStructOps->HasExportTextItem())
257 TheCppStructOps->ExportTextItem(OutValueStr, ValuePtr, ValuePtr,
nullptr, PPF_None,
nullptr);
258 return MakeShared<FJsonValueString>(OutValueStr);
262 TSharedRef<FJsonObject> OutObject = MakeShared<FJsonObject>();
263 AddIndexMetadata(OutObject);
266 return MakeShared<FJsonValueObject>(OutObject);
270 return MakeShared<FJsonValueNull>();
274 if (
const auto* ObjectProperty = FNYReflectionHelper::CastProperty<FNYObjectProperty>(Property))
276 auto returnNullptr = [
this, &ObjectProperty]() -> TSharedPtr<FJsonValue>
281 return MakeShared<FJsonValueString>(TEXT(
""));
284 return MakeShared<FJsonValueNull>();
289 const UObject* ObjectPtr = ObjectProperty->GetObjectPropertyValue_InContainer(ValuePtr);
292 const UObject* ContainerObjectPtr = ObjectProperty->GetObjectPropertyValue_InContainer(ContainerPtr);
293 if (ObjectPtr ==
nullptr || ContainerObjectPtr ==
nullptr)
301 TEXT(
"Property = `%s` Is a FNYObjectProperty but got null from ContainerPtrToValuePtr from it's StructObject (NOTE: UObjects can be nullptrs)"),
302 *Property->GetPathName()
305 return returnNullptr();
307 if (!ObjectPtr->IsValidLowLevelFast())
313 TEXT(
"ObjectPtr.IsValidLowLevelFast is false for Property = `%s`. Memory corruption for UObjects?"),
314 *Property->GetPathName()
316 return returnNullptr();
322 return MakeShared<FJsonValueString>(ObjectPtr->GetPathName());
326 TSharedRef<FJsonObject> OutObject = MakeShared<FJsonObject>();
327 AddIndexMetadata(OutObject);
330 const UClass* ObjectClass = ObjectProperty->PropertyClass;
333 return MakeShared<FJsonValueObject>(OutObject);
337 return MakeShared<FJsonValueNull>();
342 Property->ExportTextItem(ValueString, ValuePtr, ValuePtr,
nullptr, PPF_None);
343 return MakeShared<FJsonValueString>(ValueString);
413 if (StructDefinition ==
nullptr || ContainerPtr ==
nullptr)
419 UE_LOG(LogDlgJsonWriter, Verbose, TEXT(
"UStructToJsonAttributes, StructDefinition = `%s`"), *StructDefinition->GetPathName());
423 if (StructDefinition == FJsonObjectWrapper::StaticStruct())
426 const FJsonObjectWrapper* ProxyObject =
static_cast<const FJsonObjectWrapper*
>(ContainerPtr);
427 if (ProxyObject->JsonObject.IsValid())
429 OutJsonAttributes = ProxyObject->JsonObject->Values;
436 if (StructDefinition->IsA<UClass>())
438 const UObject* UnrealObject =
static_cast<const UObject*
>(ContainerPtr);
439 if (!UnrealObject->IsValidLowLevelFast())
444 TEXT(
"UStructToJsonObject: StructDefinition = `%s` is a UClass and expected ContainerPtr to be an UObject. Memory corruption?"),
445 *StructDefinition->GetPathName()
451 OutJsonAttributes.Add(TEXT(
"__type__"), MakeShared<FJsonValueString>(UnrealObject->GetClass()->GetName()));
454 StructDefinition = UnrealObject->GetClass();
456 if (!StructDefinition->IsValidLowLevelFast())
461 TEXT(
"UStructToJsonObject: StructDefinition = `%s` is a UClass and expected ContainerPtr.Class to be valid. Memory corruption?"),
462 *StructDefinition->GetPathName()
468 for (TFieldIterator<const FNYProperty> It(StructDefinition); It; ++It)
470 const auto* Property = *It;
471 if (!ensure(Property))
480 UE_LOG(LogDlgJsonWriter, Verbose, TEXT(
"Property = `%s` Does not have the required CheckFlags"), *Property->GetPathName());
489 UE_LOG(LogDlgJsonWriter, Verbose, TEXT(
"Property = `%s` Marked as skiped"), *Property->GetPathName());
495 const void* ValuePtr =
nullptr;
499 ValuePtr = ContainerPtr;
504 ValuePtr = Property->ContainerPtrToValuePtr<
void>(ContainerPtr, 0);
508 const TSharedPtr<FJsonValue> JsonValue =
PropertyToJsonValue(Property, ContainerPtr, ValuePtr);
509 if (!JsonValue.IsValid())
511 const auto* PropertyClass = Property->GetClass();
520 TEXT(
"UStructToJsonObject - Unhandled property, Class = `%s`, Name =`%s`, inside Struct = `%s`. (NOTE: UObjects can be nullptrs)"),
521 *PropertyClass->GetName(), *Property->GetPathName(), *StructDefinition->GetPathName()
530 TEXT(
"UStructToJsonObject - Unhandled property, Class = `%s`, Name =`%s`, inside Struct = `%s`"),
531 *PropertyClass->GetName(), *Property->GetPathName(), *StructDefinition->GetPathName()
540 const FString VariableName = Property->GetName();
541 OutJsonAttributes.Add(VariableName, JsonValue);