Skip to content

Commit

Permalink
Changed code to get it to compile on all platforms
Browse files Browse the repository at this point in the history
  • Loading branch information
EPICGameGuy committed Jun 29, 2023
1 parent 6cade35 commit 4ad67e7
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 70 deletions.
8 changes: 8 additions & 0 deletions Config/FilterPlugin.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[FilterPlugin]
; This section lists additional files which will be packaged along with your plugin. Paths should be listed relative to the root plugin directory, and
; may include "...", "*", and "?" wildcards to match directories, files, and individual characters respectively.
;
; Examples:
; /README.txt
; /Extras/...
; /Binaries/ThirdParty/*.dll
142 changes: 73 additions & 69 deletions Source/JsonSerialization/Private/JsonSerialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,34 +18,86 @@ void FJsonSerializationModule::ShutdownModule()
// we call this function before unloading the module.
}

template<typename T>
static TArray<TSharedPtr<FJsonValue>> SerializePropertyAsJsonArray(const T* Data, FArrayProperty* Property, TSet<const UObject*>& TraversedObjects)
// The two serialization functions depend on each other. I don't think you can forward declare template functions
// so they're both in this struct
template<typename T = UObject>
struct FUObjectSerializer
{
const uint8* PropData = Property->ContainerPtrToValuePtr<uint8>(Data);
FScriptArrayHelper Helper(Property, PropData);
TArray<TSharedPtr<FJsonValue>> ValueArray;
static TArray<TSharedPtr<FJsonValue>> SerializePropertyAsJsonArray(const T* Data, FArrayProperty* Property, TSet<const UObject*>& TraversedObjects)
{
const uint8* PropData = Property->ContainerPtrToValuePtr<uint8>(Data);
FScriptArrayHelper Helper(Property, PropData);
TArray<TSharedPtr<FJsonValue>> ValueArray;

for (int32 i = 0, n = Helper.Num(); i < n; ++i)
{
const uint8* InnerPropData = Helper.GetRawPtr(i);
if (FArrayProperty* ArrayProperty = CastField<FArrayProperty>(Property->Inner)) // Array
{
TArray<TSharedPtr<FJsonValue>> InnerArray = FUObjectSerializer<void>::SerializePropertyAsJsonArray(InnerPropData, ArrayProperty, TraversedObjects);
ValueArray.Emplace(new FJsonValueArray(InnerArray));
}
else if (FStructProperty* StructProperty = CastField<FStructProperty>(Property->Inner)) // Struct
{
TSharedPtr<FJsonObject> StructObject = MakeShareable(new FJsonObject);
const uint8* StructPropData = StructProperty->ContainerPtrToValuePtr<uint8>(InnerPropData);
for (TFieldIterator<FProperty> PropertyItr(StructProperty->Struct); PropertyItr; ++PropertyItr)
{
FUObjectSerializer<void>::SerializePropertyAsJsonObjectField((void*)StructPropData, StructObject, *PropertyItr, TraversedObjects);
}
ValueArray.Emplace(new FJsonValueObject(StructObject));
}
else if (FObjectProperty* ObjectProperty = CastField<FObjectProperty>(Property->Inner)) // Object
{
const UObject* SubObject = ObjectProperty->GetObjectPropertyValue_InContainer(InnerPropData);
if (SubObject->IsValidLowLevel() && !TraversedObjects.Contains(SubObject))
{
TraversedObjects.Add(SubObject);
TSharedPtr<FJsonObject> JsonSubObject = MakeShared<FJsonObject>();
for (TFieldIterator<FProperty> PropertyItr(SubObject->GetClass()); PropertyItr; ++PropertyItr)
{
SerializePropertyAsJsonObjectField(SubObject, JsonSubObject, *PropertyItr, TraversedObjects);
}
ValueArray.Emplace(new FJsonValueObject(JsonSubObject));
}
}
else
{
TSharedPtr<FJsonValue> JsonValue;
const uint8* InnerInnerPropData = Property->Inner->ContainerPtrToValuePtr<uint8>(InnerPropData);
ValueArray.Emplace(FJsonObjectConverter::UPropertyToJsonValue(Property->Inner, InnerInnerPropData));
}
}
return ValueArray;
}

for (int32 i = 0, n = Helper.Num(); i < n; ++i)
static void SerializePropertyAsJsonObjectField(const T* Data, TSharedPtr<FJsonObject> OuterObject, FProperty* Property, TSet<const UObject*>& TraversedObjects)
{
const uint8* InnerPropData = Helper.GetRawPtr(i);
if (FArrayProperty* ArrayProperty = CastField<FArrayProperty>(Property->Inner)) // Array
if (Property->GetName() == "UberGraphFrame"
|| Property->HasAnyPropertyFlags(CPF_Transient))
{
TArray<TSharedPtr<FJsonValue>> InnerArray = SerializePropertyAsJsonArray(InnerPropData, ArrayProperty, TraversedObjects);
ValueArray.Emplace(new FJsonValueArray(InnerArray));
// Don't include "UberGraphFrame" or any transient properties
return;
}
else if (FStructProperty* StructProperty = CastField<FStructProperty>(Property->Inner)) // Struct

if (FArrayProperty* ArrayProperty = CastField<FArrayProperty>(Property)) // Array
{
TArray<TSharedPtr<FJsonValue>> Values = SerializePropertyAsJsonArray(Data, ArrayProperty, TraversedObjects);
OuterObject->SetArrayField(Property->GetAuthoredName(), Values);
}
else if (FStructProperty* StructProperty = CastField<FStructProperty>(Property)) // Struct
{
TSharedPtr<FJsonObject> StructObject = MakeShareable(new FJsonObject);
const uint8* StructPropData = StructProperty->ContainerPtrToValuePtr<uint8>(InnerPropData);
const uint8* PropData = Property->ContainerPtrToValuePtr<uint8>(Data);
for (TFieldIterator<FProperty> PropertyItr(StructProperty->Struct); PropertyItr; ++PropertyItr)
{
SerializePropertyAsJsonObjectField((void*)StructPropData, StructObject, *PropertyItr, TraversedObjects);
FUObjectSerializer<void>::SerializePropertyAsJsonObjectField((void*)PropData, StructObject, *PropertyItr, TraversedObjects);
}
ValueArray.Emplace(new FJsonValueObject(StructObject));
OuterObject->SetObjectField(Property->GetAuthoredName(), StructObject);
}
else if (FObjectProperty* ObjectProperty = CastField<FObjectProperty>(Property->Inner)) // Object
else if (FObjectProperty* ObjectProperty = CastField<FObjectProperty>(Property)) // Object
{
const UObject* SubObject = ObjectProperty->GetObjectPropertyValue_InContainer(InnerPropData);
const UObject* SubObject = ObjectProperty->GetObjectPropertyValue_InContainer(Data);
if (SubObject->IsValidLowLevel() && !TraversedObjects.Contains(SubObject))
{
TraversedObjects.Add(SubObject);
Expand All @@ -54,65 +106,17 @@ static TArray<TSharedPtr<FJsonValue>> SerializePropertyAsJsonArray(const T* Data
{
SerializePropertyAsJsonObjectField(SubObject, JsonSubObject, *PropertyItr, TraversedObjects);
}
ValueArray.Emplace(new FJsonValueObject(JsonSubObject));
OuterObject->SetObjectField(Property->GetAuthoredName(), JsonSubObject);
}
}
else
{
TSharedPtr<FJsonValue> JsonValue;
const uint8* InnerInnerPropData = Property->Inner->ContainerPtrToValuePtr<uint8>(InnerPropData);
ValueArray.Emplace(FJsonObjectConverter::UPropertyToJsonValue(Property->Inner, InnerInnerPropData));
}
}
return ValueArray;
}

template<typename T>
static void SerializePropertyAsJsonObjectField(const T* Data, TSharedPtr<FJsonObject> OuterObject, FProperty* Property, TSet<const UObject*>& TraversedObjects)
{
if (Property->GetName() == "UberGraphFrame"
|| Property->HasAnyPropertyFlags(CPF_Transient))
{
// Don't include "UberGraphFrame" or any transient properties
return;
}

if (FArrayProperty* ArrayProperty = CastField<FArrayProperty>(Property)) // Array
{
TArray<TSharedPtr<FJsonValue>> Values = SerializePropertyAsJsonArray(Data, ArrayProperty, TraversedObjects);
OuterObject->SetArrayField(Property->GetAuthoredName(), Values);
}
else if (FStructProperty* StructProperty = CastField<FStructProperty>(Property)) // Struct
{
TSharedRef<FJsonObject> StructObject = MakeShareable(new FJsonObject);
const uint8* PropData = Property->ContainerPtrToValuePtr<uint8>(Data);
for (TFieldIterator<FProperty> PropertyItr(StructProperty->Struct); PropertyItr; ++PropertyItr)
{
SerializePropertyAsJsonObjectField((void*)PropData, StructObject, *PropertyItr, TraversedObjects);
const uint8* PropData = Property->ContainerPtrToValuePtr<uint8>(Data);
OuterObject->SetField(Property->GetAuthoredName(), FJsonObjectConverter::UPropertyToJsonValue(Property, PropData));
}
OuterObject->SetObjectField(Property->GetAuthoredName(), StructObject.ToSharedPtr());
}
else if (FObjectProperty* ObjectProperty = CastField<FObjectProperty>(Property)) // Object
{
const UObject* SubObject = ObjectProperty->GetObjectPropertyValue_InContainer(Data);
if (SubObject->IsValidLowLevel() && !TraversedObjects.Contains(SubObject))
{
TraversedObjects.Add(SubObject);
TSharedPtr<FJsonObject> JsonSubObject = MakeShared<FJsonObject>();
for (TFieldIterator<FProperty> PropertyItr(SubObject->GetClass()); PropertyItr; ++PropertyItr)
{
SerializePropertyAsJsonObjectField(SubObject, JsonSubObject, *PropertyItr, TraversedObjects);
}
OuterObject->SetObjectField(Property->GetAuthoredName(), JsonSubObject);
}
}
else
{
TSharedPtr<FJsonValue> JsonValue;
const uint8* PropData = Property->ContainerPtrToValuePtr<uint8>(Data);
OuterObject->SetField(Property->GetAuthoredName(), FJsonObjectConverter::UPropertyToJsonValue(Property, PropData));
}
}
};

TSharedPtr<FJsonObject> FJsonSerializationModule::SerializeUObjectToJson(const UObject* Object)
{
Expand All @@ -123,7 +127,7 @@ TSharedPtr<FJsonObject> FJsonSerializationModule::SerializeUObjectToJson(const U

for (TFieldIterator<FProperty> PropertyItr(Object->GetClass()); PropertyItr; ++PropertyItr)
{
SerializePropertyAsJsonObjectField(Object, JsonObject, *PropertyItr, TraversedObjects);
FUObjectSerializer<UObject>::SerializePropertyAsJsonObjectField(Object, JsonObject, *PropertyItr, TraversedObjects);
}

return JsonObject;
Expand Down
1 change: 1 addition & 0 deletions Source/JsonSerialization/Public/JsonSerialization.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#pragma once

#include "CoreMinimal.h"
#include "Dom/JsonObject.h"
#include "Modules/ModuleManager.h"

class JSONSERIALIZATION_API FJsonSerializationModule : public IModuleInterface
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "JsonObjectWrapper.h"
#include "JsonSerializationBlueprintFunctionLibrary.generated.h"

/**
Expand All @@ -16,5 +17,5 @@ class JSONSERIALIZATION_API UJsonSerializationBlueprintFunctionLibrary : public

public:
UFUNCTION(BlueprintPure, Category = "Json Serialization")
static struct FJsonObjectWrapper ObjectToJson(const UObject* Object);
static FJsonObjectWrapper ObjectToJson(const UObject* Object);
};

0 comments on commit 4ad67e7

Please sign in to comment.