114 UE_LOG(LogDlgJsonParser, Verbose, TEXT(
"ConvertScalarJsonValueToProperty, Property = `%s`"), *Property->GetPathName());
116 if (ValuePtr ==
nullptr)
123 if (
auto* EnumProperty = FNYReflectionHelper::CastProperty<FNYEnumProperty>(Property))
125 if (JsonValue->Type == EJson::String)
128 const UEnum* Enum = EnumProperty->GetEnum();
130 const FString StrValue = JsonValue->AsString();
131 const int64
IntValue = Enum->GetValueByName(
FName(*StrValue));
134 UE_LOG(LogDlgJsonParser,
136 TEXT(
"ConvertScalarJsonValueToProperty - Unable import enum `%s` from string value `%s` for property `%s`"),
137 *Enum->CppType, *StrValue, *Property->GetNameCPP());
140 EnumProperty->GetUnderlyingProperty()->SetIntPropertyValue(ValuePtr,
IntValue);
146 EnumProperty->GetUnderlyingProperty()->SetIntPropertyValue(ValuePtr,
static_cast<int64
>(JsonValue->AsNumber()));
153 if (
auto* NumericProperty = FNYReflectionHelper::CastProperty<FNYNumericProperty>(Property))
155 if (NumericProperty->IsEnum() && JsonValue->Type == EJson::String)
158 const UEnum* Enum = NumericProperty->GetIntPropertyEnum();
160 const FString StrValue = JsonValue->AsString();
161 const int64
IntValue = Enum->GetValueByName(
FName(*StrValue));
167 TEXT(
"ConvertScalarJsonValueToProperty - Unable import enum %s from string value %s for property %s"),
168 *Enum->CppType, *StrValue, *Property->GetNameCPP()
172 NumericProperty->SetIntPropertyValue(ValuePtr,
IntValue);
174 else if (NumericProperty->IsInteger())
176 if (JsonValue->Type == EJson::String)
179 NumericProperty->SetIntPropertyValue(ValuePtr, FCString::Atoi64(*JsonValue->AsString()));
184 NumericProperty->SetIntPropertyValue(ValuePtr,
static_cast<int64
>(JsonValue->AsNumber()));
187 else if (NumericProperty->IsFloatingPoint())
190 NumericProperty->SetFloatingPointPropertyValue(ValuePtr, JsonValue->AsNumber());
197 TEXT(
"ConvertScalarJsonValueToProperty - Unable to set numeric property type %s for property %s"),
198 *Property->GetClass()->GetName(), *Property->GetNameCPP()
207 if (
auto* BoolProperty = FNYReflectionHelper::CastProperty<FNYBoolProperty>(Property))
210 BoolProperty->SetPropertyValue(ValuePtr, JsonValue->AsBool());
215 if (
auto* StringProperty = FNYReflectionHelper::CastProperty<FNYStrProperty>(Property))
218 FString
String = JsonValue->AsString();
219 StringProperty->SetPropertyValue(ValuePtr,
String);
224 if (
auto* NameProperty = FNYReflectionHelper::CastProperty<FNYNameProperty>(Property))
227 const FName StringFName =
FName(*JsonValue->AsString());
228 NameProperty->SetPropertyValue(ValuePtr, StringFName);
233 if (
auto* TextProperty = FNYReflectionHelper::CastProperty<FNYTextProperty>(Property))
235 if (JsonValue->Type == EJson::String)
238 const FString
String = JsonValue->AsString();
239 TextProperty->SetPropertyValue(ValuePtr, FText::FromString(
String));
241 else if (JsonValue->Type == EJson::Object)
243 const TSharedPtr<FJsonObject> Obj = JsonValue->AsObject();
244 check(Obj.IsValid());
253 TEXT(
"ConvertScalarJsonValueToProperty - Attempted to import FText from JSON object with invalid keys for property %s"),
254 *Property->GetNameCPP()
258 TextProperty->SetPropertyValue(ValuePtr, Text);
265 TEXT(
"ConvertScalarJsonValueToProperty - Attempted to import FText from JSON that was neither string nor object for property %s"),
266 *Property->GetNameCPP()
275 if (
auto* ArrayProperty = FNYReflectionHelper::CastProperty<FNYArrayProperty>(Property))
277 if (JsonValue->Type == EJson::Array)
279 const TArray<TSharedPtr<FJsonValue>> ArrayValue = JsonValue->AsArray();
280 const int32 ArrayNum = ArrayValue.Num();
284 Helper.EmptyValues();
285 Helper.Resize(ArrayNum);
288 bool bReturnStatus =
true;
289 for (int32 Index = 0; Index < ArrayNum; Index++)
291 const TSharedPtr<FJsonValue>& ArrayValueItem = ArrayValue[Index];
292 if (ArrayValueItem.IsValid())
294 if (!
JsonValueToProperty(ArrayValueItem, ArrayProperty->Inner, ContainerPtr, Helper.GetRawPtr(Index)))
296 bReturnStatus =
false;
300 TEXT(
"ConvertScalarJsonValueToProperty - Unable to deserialize array element [%d] for property %s"),
301 Index, *Property->GetNameCPP()
307 return bReturnStatus;
310 UE_LOG(LogDlgJsonParser,
312 TEXT(
"ConvertScalarJsonValueToProperty - Attempted to import TArray from non-array JSON key for property %s"),
313 *Property->GetNameCPP());
318 if (
auto* SetProperty = FNYReflectionHelper::CastProperty<FNYSetProperty>(Property))
320 if (JsonValue->Type == EJson::Array)
322 const TArray<TSharedPtr<FJsonValue>> ArrayValue = JsonValue->AsArray();
323 const int32 ArrayNum = ArrayValue.Num();
325 FScriptSetHelper Helper(SetProperty, ValuePtr);
326 Helper.EmptyElements();
329 bool bReturnStatus =
true;
330 for (int32 Index = 0; Index < ArrayNum; ++Index)
332 const TSharedPtr<FJsonValue>& ArrayValueItem = ArrayValue[Index];
333 if (ArrayValueItem.IsValid())
335 const int32 NewIndex = Helper.AddDefaultValue_Invalid_NeedsRehash();
336 if (!
JsonValueToProperty(ArrayValueItem, SetProperty->ElementProp, ContainerPtr, Helper.GetElementPtr(NewIndex)))
338 bReturnStatus =
false;
342 TEXT(
"ConvertScalarJsonValueToProperty - Unable to deserialize set element [%d] for property %s"),
344 *Property->GetNameCPP()
351 return bReturnStatus;
357 TEXT(
"ConvertScalarJsonValueToProperty - Attempted to import TSet from non-array (JsonValue->Type = `%s`) JSON key for property %s"),
364 if (
auto* MapProperty = FNYReflectionHelper::CastProperty<FNYMapProperty>(Property))
366 if (JsonValue->Type == EJson::Object)
368 const TSharedPtr<FJsonObject> ObjectValue = JsonValue->AsObject();
370 Helper.EmptyValues();
373 bool bReturnStatus =
true;
374 for (
const auto& Entry : ObjectValue->Values)
376 if (Entry.Value.IsValid())
378 const int32 NewIndex = Helper.AddDefaultValue_Invalid_NeedsRehash();
382 const TSharedPtr<FJsonValueString> KeyAsString = MakeShared<FJsonValueString>(Entry.Key);
383 const bool bKeySuccess =
JsonValueToProperty(KeyAsString, Helper.GetKeyProperty(), ContainerPtr, Helper.GetKeyPtr(NewIndex));
386 const bool bValueSuccess =
JsonValueToProperty(Entry.Value, Helper.GetValueProperty(), ContainerPtr, Helper.GetValuePtr(NewIndex));
388 if (!bKeySuccess || !bValueSuccess)
390 Helper.RemoveAt(NewIndex);
391 bReturnStatus =
false;
395 TEXT(
"ConvertScalarJsonValueToProperty - Unable to deserialize map element [key: %s] for property %s"),
396 *Entry.Key, *Property->GetNameCPP()
403 return bReturnStatus;
406 UE_LOG(LogDlgJsonParser,
408 TEXT(
"ConvertScalarJsonValueToProperty - Attempted to import TMap from non-object JSON key for property %s"),
409 *Property->GetNameCPP());
414 if (
auto* StructProperty = FNYReflectionHelper::CastProperty<FNYStructProperty>(Property))
416 static const FName NAME_DateTime(TEXT(
"DateTime"));
417 static const FName NAME_Color(TEXT(
"Color"));
418 static const FName NAME_LinearColor(TEXT(
"LinearColor"));
421 if (JsonValue->Type == EJson::Object)
423 const TSharedPtr<FJsonObject> Obj = JsonValue->AsObject();
424 check(Obj.IsValid());
430 TEXT(
"ConvertScalarJsonValueToProperty - JsonObjectToUStruct failed for property %s"),
431 *Property->GetNameCPP()
438 else if (JsonValue->Type == EJson::String && StructProperty->Struct->GetFName() == NAME_LinearColor)
440 const FString ColorString = JsonValue->AsString();
441 const FColor IntermediateColor = FColor::FromHex(ColorString);
442 FLinearColor& ColorOut = *
static_cast<FLinearColor*
>(ValuePtr);
443 ColorOut = IntermediateColor;
445 else if (JsonValue->Type == EJson::String && StructProperty->Struct->GetFName() == NAME_Color)
447 const FString ColorString = JsonValue->AsString();
448 FColor& ColorOut = *
static_cast<FColor*
>(ValuePtr);
449 ColorOut = FColor::FromHex(ColorString);
451 else if (JsonValue->Type == EJson::String && StructProperty->Struct->GetFName() == NAME_DateTime)
453 const FString DateString = JsonValue->AsString();
454 FDateTime& DateTimeOut = *
static_cast<FDateTime*
>(ValuePtr);
455 if (DateString == TEXT(
"min"))
458 DateTimeOut = FDateTime::MinValue();
460 else if (DateString == TEXT(
"max"))
463 DateTimeOut = FDateTime::MaxValue();
465 else if (DateString == TEXT(
"now"))
468 DateTimeOut = FDateTime::UtcNow();
470 else if (FDateTime::ParseIso8601(*DateString, DateTimeOut))
474 else if (FDateTime::Parse(DateString, DateTimeOut))
483 TEXT(
"ConvertScalarJsonValueToProperty - Unable to import FDateTime for property %s"),
484 *Property->GetNameCPP()
489 else if (JsonValue->Type == EJson::String &&
490 StructProperty->Struct->GetCppStructOps() &&
491 StructProperty->Struct->GetCppStructOps()->HasImportTextItem())
494 UScriptStruct::ICppStructOps* TheCppStructOps = StructProperty->Struct->GetCppStructOps();
496 const FString ImportTextString = JsonValue->AsString();
497 const TCHAR* ImportTextPtr = *ImportTextString;
498 if (!TheCppStructOps->ImportTextItem(ImportTextPtr, ValuePtr, PPF_None,
nullptr,
static_cast<FOutputDevice*
>(GWarn)))
501 Property->ImportText(ImportTextPtr, ValuePtr, PPF_None,
nullptr);
504 else if (JsonValue->Type == EJson::String)
508 const FString ImportTextString = JsonValue->AsString();
509 const TCHAR* ImportTextPtr = *ImportTextString;
510 Property->ImportText(ImportTextPtr, ValuePtr, PPF_None,
nullptr);
517 TEXT(
"ConvertScalarJsonValueToProperty - Attempted to import UStruct from non-object JSON key for property %s"),
518 *Property->GetNameCPP()
527 if (
auto* ObjectProperty = FNYReflectionHelper::CastProperty<FNYObjectProperty>(Property))
531 auto* ObjectPtrPtr =
static_cast<UObject**
>(ObjectProperty->ContainerPtrToValuePtr<
void>(ValuePtr, 0));
532 if (ObjectPtrPtr ==
nullptr)
537 TEXT(
"PropertyName = `%s` Is a FNYObjectProperty but can't get non null ContainerPtrToValuePtr from it's StructObject"),
538 *Property->GetNameCPP()
545 const UObject* ContainerObjectPtr = ObjectProperty->GetObjectPropertyValue_InContainer(ContainerPtr);
546 if (ContainerObjectPtr !=
nullptr)
548 *ObjectPtrPtr =
nullptr;
552 if (JsonValue->IsNull())
556 const UClass* ObjectClass = ObjectProperty->PropertyClass;
560 if (JsonValue->Type == EJson::String)
562 const FString Path = JsonValue->AsString();
563 if (!Path.TrimStartAndEnd().IsEmpty())
572 check(JsonValue->Type == EJson::Object);
573 const TSharedPtr<FJsonObject> JsonObject = JsonValue->AsObject();
574 check(JsonObject.IsValid());
576 const FString SpecialKeyType = TEXT(
"__type__");
577 if (!JsonObject->HasField(SpecialKeyType))
582 TEXT(
"ConvertScalarJsonValueToProperty - PropertyName = `%s` JSON does not have the __type__ special property."),
583 *Property->GetNameCPP()
589 FString JsonObjectType;
590 check(JsonObject->TryGetStringField(SpecialKeyType, JsonObjectType));
593 if (ChildClass ==
nullptr)
598 TEXT(
"ConvertScalarJsonValueToProperty - Trying to load by string reference. Could not find class `%s` for FNYObjectProperty = `%s`. Ignored."),
599 *JsonObjectType, *Property->GetNameCPP()
606 if (*ObjectPtrPtr ==
nullptr || !(*ObjectPtrPtr)->IsValidLowLevelFast())
611 TEXT(
"JsonValueToProperty - PropertyName = `%s` Is a FNYObjectProperty but could not build any valid UObject"),
612 *Property->GetNameCPP()
623 TEXT(
"JsonValueToProperty - JsonObjectToUStruct failed for property %s"),
624 *Property->GetNameCPP()
633 check(JsonValue->Type != EJson::Object);
634 const FString Buffer = JsonValue->AsString();
635 if (Property->ImportText(*Buffer, ValuePtr, PPF_None,
nullptr) ==
nullptr)
640 TEXT(
"JsonValueToProperty - Unable import property type %s from string value for property %s"),
641 *Property->GetClass()->GetName(), *Property->GetNameCPP()