Writer API Alternatives
Previously we're deserializing FColor
by writing into its member fields separately, which is a bit cumbersome. In this case DataConfig do support better alternatives.
Since we know that FColor
is POD type we can construct one by filling in correct bit pattern. In this case FDcPropertyWriter
allow struct property to be coerced from a blob:
// DataConfigExtra/Private/DataConfig/Extra/SerDe/DcSerDeColor.cpp
template<>
FDcResult TemplatedWriteColorDispatch<EDcColorDeserializeMethod::WriteBlob>(const FColor& Color, FDcDeserializeContext& Ctx)
{
return Ctx.Writer->WriteBlob({
(uint8*)&Color, // treat `Color` as opaque blob data
sizeof(FColor)
});
}
Alternatively we can get FProperty
and data pointer in place and setting the value through Unreal's FProperty
API:
// DataConfigExtra/Private/DataConfig/Extra/SerDe/DcSerDeColor.cpp
template<>
FDcResult TemplatedWriteColorDispatch<EDcColorDeserializeMethod::WriteDataEntry>(const FColor& Color, FDcDeserializeContext& Ctx)
{
FDcPropertyDatum Datum;
DC_TRY(Ctx.Writer->WriteDataEntry(FStructProperty::StaticClass(), Datum));
Datum.CastFieldChecked<FStructProperty>()->CopySingleValue(Datum.DataPtr, &Color);
return DcOk();
}
Note that we already know that Datum.DataPtr
points to a allocated FColor
instance. Thus we can simply cast it into a FColor*
and directly manipulate the pointer.
// DataConfigExtra/Private/DataConfig/Extra/SerDe/DcSerDeColor.cpp
template<>
FDcResult TemplatedWriteColorDispatch<EDcColorDeserializeMethod::WritePointer>(const FColor& Color, FDcDeserializeContext& Ctx)
{
FDcPropertyDatum Datum;
DC_TRY(Ctx.Writer->WriteDataEntry(FStructProperty::StaticClass(), Datum));
FColor* ColorPtr = (FColor*)Datum.DataPtr;
*ColorPtr = Color; // deserialize by assignment
return DcOk();
}
Note that these techniques also applies on serialization:
// DataConfigExtra/Private/DataConfig/Extra/SerDe/DcSerDeColor.cpp
FDcResult HandlerColorSerialize(FDcSerializeContext& Ctx)
{
FDcPropertyDatum Datum;
DC_TRY(Ctx.Reader->ReadDataEntry(FStructProperty::StaticClass(), Datum));
FColor* ColorPtr = (FColor*)Datum.DataPtr;
DC_TRY(Ctx.Writer->WriteString(TEXT("#") + ColorPtr->ToHex()));
return DcOk();
}