Skip to content

Commit

Permalink
Merge pull request #435 from getnamo/feat-serialization
Browse files Browse the repository at this point in the history
Add struct <-> binary serialization; ~5x Faster than json de/serializ…
  • Loading branch information
getnamo authored Jul 26, 2024
2 parents 65a681a + d07907f commit cbce668
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 3 deletions.
64 changes: 64 additions & 0 deletions Source/CoreUtility/Private/CUBlueprintLibrary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -573,4 +573,68 @@ void UCUBlueprintLibrary::CallFunctionOnThreadGraphReturn(const FString& Functio
}
}

bool UCUBlueprintLibrary::SerializeStruct(UStruct* Struct, void* StructPtr, TArray<uint8>& OutBytes)
{
if (!Struct || !StructPtr)
{
return false;
}

FMemoryWriter MemoryWriter(OutBytes, true);
Struct->SerializeBin(MemoryWriter, StructPtr);

return true;
}

bool UCUBlueprintLibrary::DeserializeStruct(UStruct* Struct, void* StructPtr, const TArray<uint8>& InBytes)
{
if (!Struct || !StructPtr || InBytes.Num() == 0)
{
return false;
}

FMemoryReader MemoryReader(InBytes, true);

//Bi-directional, also works as a deserialization
Struct->SerializeBin(MemoryReader, StructPtr);

return true;
}

DEFINE_FUNCTION(UCUBlueprintLibrary::execBytesToStruct)
{
// Extract the parameters
P_GET_TARRAY_REF(uint8, InBytes);
Stack.StepCompiledIn<FStructProperty>(NULL);
FStructProperty* StructProp = CastField<FStructProperty>(Stack.MostRecentProperty);
void* StructPtr = Stack.MostRecentPropertyAddress;

P_FINISH;

// Deserialize the struct
bool bSuccess = DeserializeStruct(StructProp->Struct, StructPtr, InBytes);

// Return the success status
*(bool*)RESULT_PARAM = bSuccess;
}

//custom thunk needed to handle wildcard structs
DEFINE_FUNCTION(UCUBlueprintLibrary::execStructToBytes)
{
// Extract the parameters
Stack.StepCompiledIn<FStructProperty>(NULL);
FStructProperty* StructProp = CastField<FStructProperty>(Stack.MostRecentProperty);
void* StructPtr = Stack.MostRecentPropertyAddress;

P_GET_TARRAY_REF(uint8, OutBytes);

P_FINISH;

// Serialize the struct
bool bSuccess = SerializeStruct(StructProp->Struct, StructPtr, OutBytes);

// Return the success status
*(bool*)RESULT_PARAM = bSuccess;
}

#pragma warning( pop )
16 changes: 16 additions & 0 deletions Source/CoreUtility/Public/CUBlueprintLibrary.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,4 +181,20 @@ class COREUTILITY_API UCUBlueprintLibrary : public UBlueprintFunctionLibrary
*/
UFUNCTION(BlueprintCallable, Category = "CoreUtility|Threading", meta = (Latent, LatentInfo = "LatentInfo", WorldContext = "WorldContextObject"))
static void CallFunctionOnThreadGraphReturn(const FString& Function, ESIOCallbackType ThreadType, struct FLatentActionInfo LatentInfo, UObject* WorldContextObject = nullptr);


UFUNCTION(BlueprintCallable, Category = "SocketIOFunctions", CustomThunk, meta = (CustomStructureParam = "AnyStruct"))
static bool StructToBytes(TFieldPath<FProperty> AnyStruct, TArray<uint8>& OutBytes);

DECLARE_FUNCTION(execStructToBytes);


UFUNCTION(BlueprintCallable, Category = "SocketIOFunctions", CustomThunk, meta = (CustomStructureParam = "OutAnyStruct"))
static bool BytesToStruct(const TArray<uint8>& InBytes, TFieldPath<FProperty> OutAnyStruct);

DECLARE_FUNCTION(execBytesToStruct);

//C++ binary utility
static bool SerializeStruct(UStruct* Struct, void* StructPtr, TArray<uint8>& OutBytes);
static bool DeserializeStruct(UStruct* Struct, void* StructPtr, const TArray<uint8>& InBytes);
};
2 changes: 1 addition & 1 deletion Source/SIOJson/Private/SIOJConvert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "JsonObjectConverter.h"
#include "UObject/PropertyPortFlags.h"
#include "Misc/Base64.h"
#include "Serialization/MemoryWriter.h"

typedef TJsonWriterFactory< TCHAR, TCondensedJsonPrintPolicy<TCHAR> > FCondensedJsonStringWriterFactory;
typedef TJsonWriter< TCHAR, TCondensedJsonPrintPolicy<TCHAR> > FCondensedJsonStringWriter;
Expand Down Expand Up @@ -848,7 +849,6 @@ bool USIOJConvert::JsonFileToUStruct(const FString& FilePath, UStruct* Struct, v
return JsonObjectToUStruct(ToJsonObject(JsonString), Struct, StructPtr, IsBlueprintStruct);
}


bool USIOJConvert::ToJsonFile(const FString& FilePath, UStruct* Struct, void* StructPtr, bool IsBlueprintStruct /*= false*/)
{
//Get json object with trimmed values
Expand Down
3 changes: 1 addition & 2 deletions Source/SIOJson/Public/SIOJConvert.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ class SIOJSON_API USIOJConvert : public UObject

//Files - convenience read/write files
static bool JsonFileToUStruct(const FString& FilePath, UStruct* Struct, void* StructPtr, bool IsBlueprintStruct = false);
static bool ToJsonFile(const FString& FilePath, UStruct* Struct, void* StructPtr, bool IsBlueprintStruct = false);

static bool ToJsonFile(const FString& FilePath, UStruct* Struct, void* StructPtr, bool IsBlueprintStruct = false);

//typically from callbacks
static class USIOJsonValue* ToSIOJsonValue(const TArray<TSharedPtr<FJsonValue>>& JsonValueArray);
Expand Down

0 comments on commit cbce668

Please sign in to comment.