Hi,
Recently, I have been trying to write some APIs for connecting between client and server. Right now, I will get the JSON string from the HTTP response and convert it to the FJsonWrapper object. But this will be messy if I just expose this to blueprint or C++ since other people need to use the get field function, layer by layer to get the thing they want. So I am thinking of using a struct or maybe a class to contain the generic variable so other people can use it.
Right now I tried to use a struct to contain the Template variable but this is not working with USTRUCT() macro and also T is not supported by UPROPERTY(). Here are some of my thoughts.
Template<typename T> // wrong
USTRUCT(BlueprintType)
struct FPageWrapper{
GENERATED_BODY()
UPROPERTY(BlueprintReadWrite)
int32 Page;
UPROPERTY(BlueprintReadWrite)
int32 Capacity;
UPROPERTY(BlueprintReadWrite) // wrong
T Model;
};
In this code, the T for the Model variable will be other structure type, like FCities, FStreets, etc. Then when I use this I can just call it and use the FJsonObjectConverter::JsonObjectToUStruct() to either convert the struct to FPageWrapper or maybe Model.
Like this:
// Thought 1
FPageWrapper Wrapper;
FJsonObjectWrapper JsonResponse.JsonObject = FString convert to TSharedPtr<FJsonObject>;
Wrapper.page = JsonResponse.JsonObject->GetNumberField("Page");
Wrapper.Capacity= JsonResponse.JsonObject->GetNumberField("Capacity");
FJsonObjectConverter::JsonObjectToUStruct(JsonResponse.JsonObject->GetObjectField("data"), Wrapper.Model);
// Or maybe thought 2
bool GetResponseStruct(FString& InJson, FStructProperty* OutStruct, void* StructPtr)
{
const TSharedRef< TJsonReader<> >& Reader =
TJsonReaderFactory<>::Create(InJsonString);
TSharedPtr<FJsonObject> Object;
FJsonSerializer::Deserialize(Reader, /*out*/ Object);
return FJsonObjectConverter::JsonObjectToUStruct(Object.ToSharedRef(),OutStruct->Struct,StructPtr);
}
bool Deserialize(const FString InJson, int32& OutStruct)
{
check(0);
return false;
}
DEFINE_FUNCTION(execDeserialize)
{
P_GET_PROPERTY_REF(FStrProperty,InJson);
Stack.StepCompiledIn<FStructProperty>(NULL);
void* StructPtr = Stack.MostRecentPropertyAddress;
FStructProperty* OutStruct = CastField<FStructProperty>(Stack.MostRecentProperty);
P_FINISH;
bool bSuccess = false;
P_NATIVE_BEGIN;
bSuccess = GetResponseStruct(InJsonString,OutStruct,StructPtr);
P_NATIVE_END;
*(bool*)RESULT_PARAM = bSuccess;
}
// Or maybe a template class
template<typename T>
class FPageWrapper
{
public:
UPROPERTY(BlueprintReadWrite)
int32 Page;
UPROPERTY(BlueprintReadWrite)
int32 Capacity;
UPROPERTY()
T Model;
void DeserializeList(const FString& JsonString)
{
TSharedPtr<FJsonObject> JsonObject;
TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(JsonString);
if (FJsonSerializer::Deserialize(Reader, JsonObject))
{
Page= JsonObject->GetStringField("Page");
Capacity= JsonObject->GetBoolField("Capacity");
FJsonObjectConverter::JsonArrayToUStruct(JsonObject->GetObjectField("Data"), &Model, 0, 0);
}
}
};
These are just thoughts, the code may contain errors. And I do not just have a page-type struct, I also need to consider the tree-type JSON object.
So my question is: “Is there any built-in variable type for this Model variable that can take a variety of structures?”
Hope I explain my question and thoughts clearly.
Thanks for your reply.