CCCPaste

fx serialization shit


template <typename T>
concept C_IsIntType = C_IsAnyOf<T, int16, uint16, int32, uint32, int64, uint64>;

template <typename T>
concept C_IsFloatType = std::is_same_v<T, float32>;

template <typename T>
concept C_IsSerializable = C_IsIntType<T> || C_IsFloatType<T>;


struct FxSerializerValue
{
public:
enum Type
{
eInt,
eFloat,
};

public:
FxSerializerValue() = delete;

template <typename T>
requires C_IsIntType<T>
explicit FxSerializerValue(T value) : Type(eInt), IntValue(value)
{
}

template <typename T>
requires C_IsFloatType<T>
explicit FxSerializerValue(T value) : Type(eFloat), FloatValue(value)
{
}

public:
Type Type;

union
{
int64 IntValue;
float32 FloatValue;
};
};

class FxSerializer
{
public:
FxSerializer() { Values.Create(16); }

FxSerializer(const FxSerializer& other) = delete;


template <typename T>
requires C_IsSerializable<T>
FxSerializer& operator<<(T value)
{
Values.Insert(FxSerializerValue { value });
return *this;
}

template <typename T>
requires C_IsSerializable<T>
FxSerializer& Add(T& member)
{
if (bInWriteMode) {
(*this) << member;
}
else {
(*this) >> member;
}

return *this;
}

void SetWriteMode() { bInWriteMode = true; }
void SetReadMode() { bInWriteMode = false; }

template <typename T>
requires C_IsSerializable<T>
FxSerializer& operator>>(T& value)
{
if (WriteIndex > Values.Size()) {
return *this;
}

FxSerializerValue& stored_value = Values[WriteIndex++];

if constexpr (C_IsIntType<T>) {
value = stored_value.IntValue;
}
else if constexpr (C_IsFloatType<T>) {
value = stored_value.FloatValue;
}

return *this;
}


void Rewind() { WriteIndex = 0; }

public:
int WriteIndex = 0;
FxPagedArray<FxSerializerValue> Values;

bool bInWriteMode = true;
};

#define FX_SERIALIZABLE_MEMBERS(...) \
template <typename... TMemberTypes> \
void SerializerDefineRecursive(FxSerializer& s, TMemberTypes&... types) \
{ \
(s.Add(types), ...); \
} \
void SerializeNow(FxSerializer& s) { SerializerDefineRecursive(s, __VA_ARGS__); } \
void Serialize(FxSerializer& s) \
{ \
s.SetWriteMode(); \
SerializeNow(s); \
} \
void Deserialize(FxSerializer& s) \
{ \
s.SetReadMode(); \
SerializeNow(s); \
}


struct SerializeTest
{
FX_SERIALIZABLE_MEMBERS(X, Y);

void Print() { FxLogInfo("Object: [{}, {}]", X, Y); }

float X = 0;
int Y = 0;
};