NazaraEngine/include/Nazara/Core/Serialization.inl

297 lines
7.0 KiB
C++

// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Export.hpp
#include <Nazara/Core/EnumSerialization.hpp>
namespace Nz
{
template<typename T>
inline bool Serialize(SerializationContext& context, std::string_view name, const T& value)
{
return Serialize(context, name, value, TypeTag<std::decay_t<T>>());
}
template<typename T>
bool Serialize(SerializationContext& context, std::string_view name, const T& value, TypeTag<T>)
{
if (!context.PushObject(name))
return false;
if (!Serialize(context, value, TypeTag<std::decay_t<T>>()))
return false;
return context.PopObject();
}
/*!
* \ingroup core
* \brief Serializes a boolean
* \return true if serialization succeeded
*
* \param context Context for the serialization
* \param value Boolean to serialize
*
* \see Serialize, Unserialize
*/
inline bool Serialize(SerializationContext& context, std::string_view name, const bool& value, TypeTag<bool>)
{
return context.Write(name, value);
}
/*!
* \ingroup core
* \brief Serializes a std::string
* \return true if successful
*
* \param context Context for the serialization
* \param value String to serialize
*/
inline bool Serialize(SerializationContext& context, std::string_view name, const std::string& value, TypeTag<std::string>)
{
return context.Write(name, value);
}
template<typename T, size_t N>
bool Serialize(SerializationContext& context, std::string_view name, const T(&values)[N])
{
if (!context.PushArray(name))
return false;
for (size_t i = 0; i < N; ++i)
{
if (!Serialize(context, "", values[i]))
return false;
}
return context.PopArray();
}
template<typename T, size_t N>
bool Serialize(SerializationContext& context, std::string_view name, const std::array<T, N>& values)
{
if (!context.PushArray(name))
return false;
for (auto&& value : values)
{
if (!Serialize(context, "", value))
return false;
}
return context.PopArray();
}
template<typename T>
bool Serialize(SerializationContext& context, std::string_view name, const std::vector<T>& values)
{
if (!context.PushArray(name))
return false;
for (auto&& value : values)
{
if (!Serialize(context, "", value))
return false;
}
return context.PopArray();
}
template<typename E, typename T>
bool Serialize(SerializationContext& context, std::string_view name, const Nz::EnumArray<E, T>& values)
{
if (!context.PushArray(name))
return false;
for (auto&& value : values)
{
if (!Serialize(context, "", value))
return false;
}
return context.PopArray();
}
/*!
* \ingroup core
* \brief Serializes an arithmetic type
* \return true if serialization succeeded
*
* \param context Context for the serialization
* \param value Arithmetic type to serialize
*
* \see Serialize, Unserialize
*/
template<Numeric T>
inline bool Serialize(SerializationContext& context, std::string_view name, const T& value, TypeTag<T>)
{
return context.Write(name, value);
}
template<Enum T>
inline bool Serialize(SerializationContext& context, std::string_view name, const T& value, TypeTag<T>)
{
switch (context.GetEnumSerializationMode())
{
case EnumSerializationMode::Binary:
return Serialize(context, name, std::underlying_type_t<T>(value), TypeTag<std::decay_t<std::underlying_type_t<T>>>());
case EnumSerializationMode::String:
return Serialize(context, name, std::string(EnumToString(value)), TypeTag<std::string>());
}
return false;
}
template<typename T>
inline bool Unserialize(SerializationContext& context, std::string_view name, T* value)
{
return Unserialize(context, name, value, TypeTag<std::decay_t<T>>());
}
template<typename T>
bool Unserialize(SerializationContext& context, std::string_view name, T* value, TypeTag<T>)
{
if (!context.PushObject(name))
return false;
if (!Unserialize(context, value, TypeTag<T>()))
return false;
return context.PopObject();
}
/*!
* \ingroup core
* \brief Unserializes a boolean
* \return true if unserialization succedeed
*
* \param context Context for the unserialization
* \param value Pointer to boolean to unserialize
*
* \see Serialize, Unserialize
*/
inline bool Unserialize(SerializationContext& context, std::string_view name, bool* value, TypeTag<bool>)
{
return context.Read(name, value);
}
/*!
* \brief Unserializes a string
* \return true if successful
*
* \param context Context of unserialization
* \param string std::string to unserialize
*/
inline bool Unserialize(SerializationContext& context, std::string_view name, std::string* string, TypeTag<std::string>)
{
return context.Read(name, string);
}
template<typename T, size_t N>
bool Unserialize(SerializationContext& context, std::string_view name, T(*values)[N])
{
if (!context.PushArray(name))
return false;
for (size_t i = 0; i < N; ++i)
{
if (!Unserialize(context, "", &(*values[i])))
return false;
}
return context.PopArray();
}
template<typename T, size_t N>
bool Unserialize(SerializationContext& context, std::string_view name, std::array<T, N>* values)
{
if (!context.PushArray(name))
return false;
for (auto&& value : *values)
{
if (!Unserialize(context, "", &value))
return false;
}
return context.PopArray();
}
template<typename T>
bool Unserialize(SerializationContext& context, std::string_view name, std::vector<T>* values)
{
if (!context.PushArray(name))
return false;
for (auto&& value : *values)
{
if (!Unserialize(context, "", &value))
return false;
}
return context.PopArray();
}
template<typename E, typename T>
bool Unserialize(SerializationContext& context, std::string_view name, Nz::EnumArray<E, T>* values)
{
if (!context.PushArray(name))
return false;
for (auto&& value : *values)
{
if (!Unserialize(context, "", &value))
return false;
}
return context.PopArray();
}
/*!
* \ingroup core
* \brief Unserializes an arithmetic type
* \return true if unserialization succedeed
*
* \param context Context for the unserialization
* \param value Pointer to arithmetic type to serialize
*
* \remark Produce a NazaraAssert if pointer to value is invalid
*
* \see Serialize, Unserialize
*/
template<Numeric T>
inline bool Unserialize(SerializationContext& context, std::string_view name, T* value, TypeTag<T>)
{
return context.Read(name, value);
}
template<Enum T>
bool Unserialize(SerializationContext& context, std::string_view name, T* value, TypeTag<T>)
{
switch (context.GetEnumSerializationMode())
{
case EnumSerializationMode::Binary:
{
std::underlying_type_t<T> v = 0;
if (!Unserialize(context, name, &v, TypeTag<std::decay_t<std::underlying_type_t<T>>>()))
return false;
*value = static_cast<T>(v);
return true;
}
case EnumSerializationMode::String:
{
std::string str;
if (!Unserialize(context, name, &str, TypeTag<std::string>()))
return false;
*value = EnumFromString<T>(str);
return true;
}
}
return false;
}
}