Json数据映射到蓝图Struct

Json数据怎么映射到蓝图了?蓝图的文件都是uasset文件,有点类似二进制的文件,从应用层想把数据进行互相映射,没有提供相应的API,那就另想别的方法,所有的资源运行都在内存中,所以直接从内存中去操作!蓝图的Struct在内存中的映射和代码层的Struct在内存中的映射其实是一样的,数据结构有点类似单向链表,具体的有知道的,麻烦告知一下,不慎感激!

既然有了解决方案,下一步就是代码操作了,代码直接奉上!

​​​​​​​

// Fill out your copyright notice in the Description page of Project Settings.

#include "JsonConverter.h"
#include "Engine/Blueprint.h"
#include "Runtime/CoreUObject/Public/UObject/UnrealType.h"
#include "Engine/UserDefinedStruct.h"

JsonConverter *GetJsonConverter()
{
	static JsonConverter conv;
	return &conv;
}

JsonConverter::JsonConverter()
{
}

JsonConverter::~JsonConverter()
{

}

//---------Json映射到Struct-------------------------
void JsonConverter::ImportJasonToUStruct(const FString &content, UCustomStruct *msgUObject)
{
	if (content.IsEmpty() || msgUObject == nullptr)
	{
		return;
	}
	
	UClass *tmpClass = msgUObject->GetClass();

	UStructProperty *StructProperty = (UStructProperty *)tmpClass->FindPropertyByName(FName(TEXT("Table")));
	if (StructProperty == nullptr)
	{
		return;
	}

	void *StructAddress = StructProperty->ContainerPtrToValuePtr(msgUObject);

	TSharedPtr JsonObject;
	TSharedRef> Reader = TJsonReaderFactory<>::Create(content);
	if (FJsonSerializer::Deserialize(Reader, JsonObject))
	{
		TMap> JsonValues = JsonObject->Values;
		for (auto &Iter: JsonValues)
		{
			UProperty *Property = GetProperty(StructProperty->Struct, Iter.Key);
			if (Property == nullptr)
			{
				continue;
			}
			void* Address = Property->ContainerPtrToValuePtr(StructAddress);
			JsonDataReflectUObjectData(Iter.Key, JsonObject, Iter.Value->Type, Property, Address);
		}
	}
}

void JsonConverter::JsonDataReflectUObjectData(const FString &JsonKey, TSharedPtr JsonValue, EJson ValueType, UProperty *Property, void *Address)
{
	if (ValueType == EJson::Null || ValueType == EJson::None || JsonKey.IsEmpty() || !JsonValue.IsValid())
	{
		return;
	}

	switch (ValueType)
	{
		case EJson::Boolean:
		{
			bool value = false;
			if (JsonValue->TryGetBoolField(JsonKey, value))
			{
				((UBoolProperty *)Property)->SetPropertyValue_InContainer(Address, value);
			}
		}
		break;
		case EJson::Number:
		{
			int32 value;
			if (JsonValue->TryGetNumberField(JsonKey, value))
			{
				((UIntProperty *)Property)->SetPropertyValue_InContainer(Address, value);
			}
		}
		break;
		case EJson::String:
		{
			FString StrValue;
			if (JsonValue->TryGetStringField(JsonKey, StrValue))
			{
				//CastChecked(Property)->SetPropertyValue_InContainer(Address, StrValue);
				((UStrProperty*)Property)->SetPropertyValue_InContainer(Address, StrValue);
			}
		}
		break;
		case EJson::Array:
		{
			const TArray> *JsonArray;
			if (JsonValue->TryGetArrayField(JsonKey, JsonArray))
			{
				DeserializeJsonArray(*JsonArray, Property, Address);
			}
		}
		break;
		case EJson::Object:
		{
			const TSharedPtr* JsonObject;
			if (JsonValue->TryGetObjectField(JsonKey, JsonObject))
			{
				DeserializeJsonObject(JsonKey, *JsonObject, Property, Address);
			}
		}
		break;
	}
}

void JsonConverter::DeserializeJsonArray(const TArray> &JsonArray, UProperty *Property, void *StructAddress)
{
	UArrayProperty *ArrProperty = Cast(Property);
	FScriptArrayHelper ArrHelper(ArrProperty, StructAddress);
	ArrHelper.EmptyValues();

	TMap> JsonValues;
	const TSharedPtr* FileMessageObject;
	for (int i = 0; i < JsonArray.Num(); i++)
	{
		if (JsonArray[i].Get()->TryGetObject(FileMessageObject))
		{
			const int32 NewEntryIndex = ArrHelper.AddValue();
			uint8 *EntryAddress = ArrHelper.GetRawPtr(NewEntryIndex);

			JsonValues = (*FileMessageObject)->Values;
			for (auto &Iter : JsonValues)
			{
				if (ArrProperty->Inner->IsA())
				{
					UStructProperty *PropertyStruct = Cast(ArrProperty->Inner);
					UProperty *Property = GetProperty(PropertyStruct->Struct, Iter.Key);
					JsonDataReflectUObjectData(Iter.Key, *FileMessageObject, Iter.Value->Type, Property, EntryAddress);
				}
			}
		}
	}
}

void JsonConverter::DeserializeJsonObject(const FString &JsonKey, TSharedPtr JsonObject, UProperty *Property, void *StructAddress)
{
	if (JsonKey.IsEmpty() || !JsonObject.IsValid())
	{
		return;
	}

	const TArray> *JsonArray;
	if (!JsonObject->TryGetArrayField(JsonKey, JsonArray))
	{
		return;
	}

	DeserializeJsonArray(*JsonArray, Property, StructAddress);
}

UProperty* JsonConverter::GetProperty(UStruct *StructClass, const FString &Name)
{
	for (UProperty* Property = StructClass->PropertyLink; Property != NULL; Property = Property->PropertyLinkNext)
	{
		if (Property->GetName().Contains(Name))
		{
			return Property;
		}
	}
	return NULL;
}
//-------------------------------------------------


//--------------Struct映射到JsonString-----------------
FString JsonConverter::ExportToJasonFromUStruct(UCustomStruct *msgUObject)
{
	FString JsonString = TEXT("");
	if (msgUObject == nullptr)
	{
		return JsonString;
	}

	UStructProperty *StructProperty = (UStructProperty *)msgUObject->GetClass()->FindPropertyByName(FName(TEXT("Table")));
	void *StructAddress = StructProperty->ContainerPtrToValuePtr(msgUObject);
	if (StructProperty == nullptr)
	{
		return JsonString;
	}

	TSharedRef>> JsonWriter = TJsonWriterFactory>::Create(&JsonString);
	JsonWriter->WriteObjectStart();
	UScriptStruct *Struct = StructProperty->Struct;
	for (TFieldIterator It(Struct); It; ++It)
	{
		UProperty *Property = *It;
		FString Name = Property->GetName();

		for (int32 Index = 0; Index < Property->ArrayDim; Index++)
		{
			void *ValuePtr = Property->ContainerPtrToValuePtr(StructAddress, Index);
			{
				ExportChildProperty(Property, JsonWriter, ValuePtr);
			}
		}
	}

	JsonWriter->WriteObjectEnd();
	JsonWriter->Close();

	UE_LOG(LogTemp, Warning, TEXT("JsonString = %s"), *JsonString);
	return JsonString;
}

void JsonConverter::ExportChildProperty(UProperty *Property, TSharedRef>> &JsonWriter, void *Address)
{
	FString Key = GetPropertyName(Property);
	if (Property->IsA())
	{
		bool Value = ((UBoolProperty *)Property)->GetPropertyValue_InContainer(Address);
		JsonWriter->WriteValue(Key, Value);
	}
	else if (Property->IsA() || Property->IsA() || Property->IsA()
		|| Property->IsA() || Property->IsA())
	{
		double Value = ((UIntProperty *)Property)->GetPropertyValue_InContainer(Address);
		UE_LOG(LogTemp, Warning, TEXT("Key = %s   Value = %f"), *Key, Value);
		JsonWriter->WriteValue(Key, Value);
	}
	else if (Property->IsA())
	{
		FString Value = ((UStrProperty *)Property)->GetPropertyValue_InContainer(Address);
		UE_LOG(LogTemp, Warning, TEXT("Key = %s   Value = %s"), *Key, *Value);
		JsonWriter->WriteValue(Key, Value);
	}
	else if (Property->IsA())
	{
		UArrayProperty *ArrayProperty = Cast(Property);
		FScriptArrayHelper Helper(ArrayProperty, Address);
		FString Key = GetPropertyName(Property);
		JsonWriter->WriteArrayStart(Key);
		UProperty *CurProperty = nullptr;
		UE_LOG(LogTemp, Warning, TEXT("Number = %d"), Helper.Num());
		for (int32 i = 0; i < Helper.Num(); i++)
		{
			if (ArrayProperty->Inner->IsA())
			{
				UStructProperty *PropertyStruct = Cast(ArrayProperty->Inner);
				if (PropertyStruct != nullptr)
				{
					JsonWriter->WriteObjectStart();
					UStruct *P = PropertyStruct->Struct;
					void *Address = (void *)Helper.GetRawPtr(i);

					for (UProperty* Property = P->PropertyLink; Property != NULL; Property = Property->PropertyLinkNext)
					{
						ExportChildProperty(Property, JsonWriter, Address);
					}
					JsonWriter->WriteObjectEnd();
				}
			}
		}
		JsonWriter->WriteArrayEnd();
	}
}

FString JsonConverter::GetPropertyName(UProperty *Property)
{
	FString PropertyName = Property->GetName();
	FString Left;
	FString Right;
	if (PropertyName.Split("_", &Left, &Right))
	{
		return Left;
	}

	return "";
}
//-----------------------------------------------------

 

你可能感兴趣的:(Json数据映射到蓝图Struct)