You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#preflight 6221270ea00412627d0b7dd3 #jira UE-122078 #lockdown Julien.Marchand #rb Andrew.Davidson #ROBOMERGE-AUTHOR: fred.kimberley #ROBOMERGE-SOURCE: CL 19253774 in //UE5/Release-5.0/... via CL 19257968 #ROBOMERGE-BOT: UE5 (Release-Engine-Staging -> Main) (v924-19243027) [CL 19263535 by fred kimberley in ue5-main branch]
182 lines
8.1 KiB
C++
182 lines
8.1 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "Containers/Array.h"
|
|
#include "CoreTypes.h"
|
|
#include "Math/Quat.h"
|
|
#include "Math/Vector.h"
|
|
#include "Misc/SecureHash.h"
|
|
#include "Serialization/Archive.h"
|
|
|
|
|
|
// LWC initiative changes the support of some geometry-related types from float to doubles.
|
|
// As we want to be able to send data to apps built without LWC support, we send data with
|
|
// the legacy float serialization.
|
|
// When the support of pre-LWC products is no longer required, we can safely toggle this
|
|
// macro off and send LWC types natively (as doubles).
|
|
#define DL_SEND_LWC_TYPES_AS_F32 1
|
|
|
|
namespace Reflect
|
|
{
|
|
|
|
// clang-format off
|
|
enum EStoreType : uint8
|
|
{
|
|
_bool = 1,
|
|
_i8, _i16, _i32, _i64,
|
|
_u8, _u16, _u32, _u64,
|
|
_f32, _f64,
|
|
_str,
|
|
_vector, _vector4, _quat,
|
|
_linearcolor,
|
|
_md5hash,
|
|
_transform,
|
|
_storeTypeLast
|
|
};
|
|
|
|
enum ESerialModifier : uint8
|
|
{
|
|
_default = 0 << 5,
|
|
_array = 1 << 5,
|
|
_alt1 = 2 << 5,
|
|
};
|
|
|
|
static constexpr uint8 _storeTypeMask = 0b0001'1111u;
|
|
static constexpr uint8 _modifierMask = 0b1110'0000u;
|
|
static_assert((_storeTypeLast & _modifierMask) == 0, "enum overlap");
|
|
|
|
enum class ESerialMethod : uint8
|
|
{
|
|
None = 0,
|
|
Bool_Default = _bool | _default,
|
|
Uint8_Default = _u8 | _default,
|
|
Int32_Default = _i32 | _default,
|
|
Int32_Array = _i32 | _array,
|
|
Uint32_Default = _u32 | _default,
|
|
Uint64_Default = _u64 | _default,
|
|
Uint32_Packed = _u32 | _alt1,
|
|
String_Default = _str | _default,
|
|
String_Array = _str | _array,
|
|
Float_Default = _f32 | _default,
|
|
Float_Array = _f32 | _array,
|
|
Double_Default = _f64 | _default,
|
|
Vector_f32 = _vector | _default, // FVector serialized as FVector3f
|
|
Vector_f64 = _vector | _alt1, // FVector serialized as FVector3d (native since 5.0)
|
|
Quat_f32 = _quat | _default, // FQuat serialized as FQuat4f
|
|
Quat_f64 = _quat | _alt1, // FQuat serialized as FQuat4d (native since 5.0)
|
|
LinearColor_Default= _linearcolor| _default,
|
|
MD5Hash_Default = _md5hash | _default,
|
|
Transform_Default = _transform | _default, // Added in 5.0, uses LWC.
|
|
Transform_Array = _transform | _array, // Added in 5.0, uses LWC.
|
|
|
|
_NotImplementedYet = 0xff
|
|
};
|
|
|
|
|
|
static constexpr EStoreType GetStoreType(ESerialMethod Method) { return EStoreType(uint8(Method) & _storeTypeMask); }
|
|
|
|
// This list maps which serialization method should be used for each Type reflected by directlink
|
|
template<typename T> struct TDefaultSerialMethod;
|
|
template<> struct TDefaultSerialMethod<bool> { constexpr static ESerialMethod Value = ESerialMethod::Uint8_Default; };
|
|
template<> struct TDefaultSerialMethod<uint8> { constexpr static ESerialMethod Value = ESerialMethod::Uint8_Default; };
|
|
template<> struct TDefaultSerialMethod<int32> { constexpr static ESerialMethod Value = ESerialMethod::Int32_Default; };
|
|
template<> struct TDefaultSerialMethod<uint32> { constexpr static ESerialMethod Value = ESerialMethod::Uint32_Default; };
|
|
template<> struct TDefaultSerialMethod<uint64> { constexpr static ESerialMethod Value = ESerialMethod::Uint64_Default; };
|
|
template<> struct TDefaultSerialMethod<FString> { constexpr static ESerialMethod Value = ESerialMethod::String_Default; };
|
|
template<> struct TDefaultSerialMethod<float> { constexpr static ESerialMethod Value = ESerialMethod::Float_Default; };
|
|
template<> struct TDefaultSerialMethod<double> { constexpr static ESerialMethod Value = ESerialMethod::Double_Default; };
|
|
template<> struct TDefaultSerialMethod<TArray<int32>> { constexpr static ESerialMethod Value = ESerialMethod::Int32_Array; };
|
|
template<> struct TDefaultSerialMethod<TArray<FString>> { constexpr static ESerialMethod Value = ESerialMethod::String_Array; };
|
|
template<> struct TDefaultSerialMethod<TArray<float>> { constexpr static ESerialMethod Value = ESerialMethod::Float_Array; };
|
|
template<> struct TDefaultSerialMethod<FLinearColor> { constexpr static ESerialMethod Value = ESerialMethod::LinearColor_Default;};
|
|
template<> struct TDefaultSerialMethod<FMD5Hash> { constexpr static ESerialMethod Value = ESerialMethod::MD5Hash_Default; };
|
|
template<> struct TDefaultSerialMethod<FTransform> { constexpr static ESerialMethod Value = ESerialMethod::Transform_Default; };
|
|
template<> struct TDefaultSerialMethod<TArray<FTransform>> { constexpr static ESerialMethod Value = ESerialMethod::Transform_Array; };
|
|
#if DL_SEND_LWC_TYPES_AS_F32
|
|
// for compatibility with pre-LWC endpoints, we send LWC-aware types as their f32 variants
|
|
template<> struct TDefaultSerialMethod<FVector> { constexpr static ESerialMethod Value = ESerialMethod::Vector_f32; };
|
|
template<> struct TDefaultSerialMethod<FQuat> { constexpr static ESerialMethod Value = ESerialMethod::Quat_f32; };
|
|
#else
|
|
template<> struct TDefaultSerialMethod<FVector> { constexpr static ESerialMethod Value = ESerialMethod::Vector_f64; };
|
|
template<> struct TDefaultSerialMethod<FQuat>> { constexpr static ESerialMethod Value = ESerialMethod::Quat_f64; };
|
|
#endif
|
|
|
|
|
|
template<typename T> EStoreType GetStoreTypeForType() { return GetStoreType(TDefaultSerialMethod<T>::Value); }
|
|
template<typename T> bool CanSerializeWithMethod(ESerialMethod Method) { return GetStoreTypeForType<T>() == GetStoreType(Method); }
|
|
|
|
|
|
// Serialization implementations
|
|
template<ESerialMethod Code, typename T>
|
|
void Serial(FArchive& Ar, T* Param) { Ar << *Param; }
|
|
|
|
template<> inline void Serial<ESerialMethod::Uint32_Packed>(FArchive& Ar, uint32* ValuePtr) { Ar.SerializeIntPacked(*ValuePtr); }
|
|
|
|
template<> inline void Serial<ESerialMethod::Vector_f32>(FArchive& Ar, FVector* ValuePtr)
|
|
{
|
|
if (Ar.IsLoading())
|
|
{
|
|
FVector3f Tmp;
|
|
Ar << Tmp;
|
|
*ValuePtr = FVector(Tmp);
|
|
}
|
|
else if (Ar.IsSaving())
|
|
{
|
|
FVector3f Tmp(*ValuePtr);
|
|
Ar << Tmp;
|
|
}
|
|
}
|
|
|
|
template<> inline void Serial<ESerialMethod::Quat_f32>(FArchive& Ar, FQuat* ValuePtr)
|
|
{
|
|
if (Ar.IsLoading())
|
|
{
|
|
FQuat4f Tmp;
|
|
Ar << Tmp;
|
|
*ValuePtr = FQuat(Tmp);
|
|
}
|
|
else if (Ar.IsSaving())
|
|
{
|
|
FQuat4f Tmp(*ValuePtr);
|
|
Ar << Tmp;
|
|
}
|
|
}
|
|
|
|
|
|
inline bool SerialAny(FArchive& Ar, void* data, ESerialMethod Method)
|
|
{
|
|
#define SerialAny_Case(enumvalue, casttype) case enumvalue: Serial<enumvalue>(Ar, (casttype*)data); return true;
|
|
switch (Method)
|
|
{
|
|
SerialAny_Case(ESerialMethod::Bool_Default , bool );
|
|
SerialAny_Case(ESerialMethod::Uint8_Default , uint8 );
|
|
SerialAny_Case(ESerialMethod::Int32_Default , int32 );
|
|
SerialAny_Case(ESerialMethod::Uint32_Default , uint32 );
|
|
SerialAny_Case(ESerialMethod::Uint64_Default , uint64 );
|
|
SerialAny_Case(ESerialMethod::Uint32_Packed , uint32 );
|
|
SerialAny_Case(ESerialMethod::String_Default , FString );
|
|
SerialAny_Case(ESerialMethod::Double_Default , double );
|
|
SerialAny_Case(ESerialMethod::Float_Default , float );
|
|
SerialAny_Case(ESerialMethod::Int32_Array , TArray<int32> );
|
|
SerialAny_Case(ESerialMethod::String_Array , TArray<FString> );
|
|
SerialAny_Case(ESerialMethod::Float_Array , TArray<float> );
|
|
SerialAny_Case(ESerialMethod::Vector_f32 , FVector );
|
|
SerialAny_Case(ESerialMethod::Vector_f64 , FVector );
|
|
SerialAny_Case(ESerialMethod::Quat_f32 , FQuat );
|
|
SerialAny_Case(ESerialMethod::Quat_f64 , FQuat );
|
|
SerialAny_Case(ESerialMethod::LinearColor_Default, FLinearColor );
|
|
SerialAny_Case(ESerialMethod::MD5Hash_Default , FMD5Hash );
|
|
SerialAny_Case(ESerialMethod::Transform_Default , FTransform );
|
|
SerialAny_Case(ESerialMethod::Transform_Array , TArray<FTransform>);
|
|
|
|
case ESerialMethod::None: return true;
|
|
case ESerialMethod::_NotImplementedYet:
|
|
default: ensure(false);
|
|
}
|
|
return false;
|
|
#undef SerialAny_Case
|
|
}
|
|
|
|
} // namespace Reflect
|