Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,25 @@ namespace serialization_detail
using DeserializedType = const json&;

static auto createBaseElement() { return SerializedType {}; }
static auto createBaseElement(juce::String id) { return SerializedType {}; }
static void addChildElement (SerializedType&, SerializedType&&) {} //NOSONAR
static auto getChildElement (DeserializedType, int) { return false; }
static auto getChildElement (DeserializedType, juce::String) { return false; }

static int getNumChildElements (DeserializedType) { return 0; }
static int getNumAttributes (DeserializedType) { return 0; }
static juce::String getAttributeName (DeserializedType, int i) { return ""; }

template <typename, typename C>
static SerializedType serialize (const C&)
static auto getAttribute (DeserializedType, juce::String id) { return false; }

template <typename SerializedType , typename C>
static SerializedType serialize (const C&, SerializedType t, juce::String id)
{
return {};
}

template <typename SerializedType , typename C>
static SerializedType serialize (const C&, SerializedType t)
{
return {};
}
Expand All @@ -35,6 +48,11 @@ namespace serialization_detail
static void deserialize (DeserializedType, C&)
{
}

template <typename, typename C>
static void deserialize (juce::String, C&)
{
}
};

// The reason we need this "detail" namespace is so that we can define these static method
Expand Down Expand Up @@ -85,97 +103,157 @@ class BaseSerializer
return serial;
}

/** Serializer for serial type */
template <typename Serializer, typename T>
static std::enable_if_t<std::is_same_v<T, SerialType<Serializer>>, SerialType<Serializer>>
serialize (T x)
{
return x;
}

/** Deserializer for serial types */
template <typename Serializer, typename T>
static std::enable_if_t<std::is_same_v<T, SerialType<Serializer>>, void>
deserialize (DeserialType<Serializer> serial, T& x)
{
x = serial;
}
// /** Serializer for arithmetic types */
// template <typename Serializer, typename T>
// static std::enable_if_t<std::is_arithmetic_v<T>, SerialType<Serializer>>
// serialize (T x)
// {
// return Serializer::serializeArithmeticType (x);
// }
// /** Deserializer for arithmetic types */
// template <typename Serializer, typename T>
// static std::enable_if_t<std::is_arithmetic_v<T>, void>
// deserialize (DeserialType<Serializer> serial, T& x)
// {
// x = Serializer::template deserializeArithmeticType<T> (serial);
// }

/** Serializes an arithmetic type. */

/** Serializer for arithmetic types */
template <typename Serializer, typename T>
static std::enable_if_t<std::is_arithmetic_v<T>, SerialType<Serializer>>
serialize (T x)
serialize(SerialType<Serializer>& parent, juce::String id, T x)
{
return Serializer::serializeArithmeticType (x);
return Serializer::serializeArithmeticType(parent, id, x);
}

/** Deserializer for arithmetic types */
/** Deserializes an arithmetic type. */
template <typename Serializer, typename T>
static std::enable_if_t<std::is_arithmetic_v<T>, void>
deserialize (DeserialType<Serializer> serial, T& x)
static std::enable_if_t<std::is_arithmetic_v<T>, T>
deserialize(DeserialType<Serializer> serial, juce::String id,T& x)
{
x = Serializer::template deserializeArithmeticType<T> (serial);
x = Serializer::template deserializeArithmeticType<T>(serial, id);
}

/** Serializer for enum types */
template <typename Serializer, typename T>
static std::enable_if_t<std::is_enum_v<T>, SerialType<Serializer>>
serialize (T x)
{
return Serializer::serializeEnumType (x);
}

/** Deserializer for enum types */




/** Serializes an enum type. */
template <typename Serializer, typename T>
static std::enable_if_t<std::is_enum_v<T>, void>
deserialize (DeserialType<Serializer> serial, T& x)
static SerialType<Serializer> serializeEnumType(SerialType<Serializer>& parent, juce::String id, T x)
{
x = Serializer::template deserializeEnumType<T> (serial);
return Serializer::serializeEnumType(parent, id, x);
}

/** Serializer for string types */
/** Deserializes an enum type. */
template <typename Serializer, typename T>
static std::enable_if_t<IsString<T>, SerialType<Serializer>>
serialize (const T& x)
static T deserializeEnumType(DeserialType<Serializer> serial, juce::String id, T& x)
{
return Serializer::serializeString (x);
x = Serializer::template deserializeEnumType<T>(serial, id);
}

/** Deserializer for string types */
// /** Serializer for enum types */
// template <typename Serializer, typename T>
// static std::enable_if_t<std::is_enum_v<T>, SerialType<Serializer>>
// serialize (T x)
// {
// return Serializer::serializeEnumType (x);
// }
//
// /** Deserializer for enum types */
// template <typename Serializer, typename T>
// static std::enable_if_t<std::is_enum_v<T>, void>
// deserialize (DeserialType<Serializer> serial, T& x) {
// x = Serializer::template deserializeEnumType<T> (serial);
// }

// /** Serializer for string types */
// template <typename Serializer, typename T>
// static std::enable_if_t<IsString<T>, SerialType<Serializer>>
// serialize (const T& x)
// {
// return Serializer::serializeString (x);
// }
//
// /** Deserializer for string types */
// template <typename Serializer, typename T>
// static std::enable_if_t<IsString<T>, void>
// deserialize (DeserialType<Serializer> serial, T& x)
// {
// x = Serializer::template deserializeString<T> (serial);
// }
/** Serializes a string. */
template <typename Serializer, typename T>
static std::enable_if_t<IsString<T>, void>
deserialize (DeserialType<Serializer> serial, T& x)
static std::enable_if_t<std::is_same_v<T, std::string> || std::is_same_v<T, juce::String>, SerialType<Serializer>>
serializeString(SerialType<Serializer>& parent, juce::String id, const T& x)
{
x = Serializer::template deserializeString<T> (serial);
return Serializer::serializeString(parent, id, x);
}

#if JUCE_MODULE_AVAILABLE_juce_graphics
/** Serializer for juce::Point types */
/** Deserializes a string. */
template <typename Serializer, typename T>
static std::enable_if_t<IsPoint<T>, SerialType<Serializer>>
serialize (const T& point)
static std::enable_if_t<std::is_same_v<T, std::string> || std::is_same_v<T, juce::String>, T>
deserializeString(DeserialType<Serializer> serial, juce::String id, T& x)
{
auto serial = Serializer::createBaseElement();
Serializer::addChildElement (serial, serialize<Serializer> (point.x));
Serializer::addChildElement (serial, serialize<Serializer> (point.y));
return serial;
x = Serializer::template deserializeString<T>(serial, id);
}

/** Deserializer for juce::Point types */
template <typename Serializer, typename T>
static std::enable_if_t<IsPoint<T>, void>
deserialize (DeserialType<Serializer> serial, T& point)
{
if (Serializer::getNumChildElements (serial) != 2)
#if JUCE_MODULE_AVAILABLE_juce_graphics
// /** Serializer for juce::Point types */
// template <typename Serializer, typename T>
// static std::enable_if_t<IsPoint<T>, SerialType<Serializer>>
// serialize (const T& point)
// {
// auto serial = Serializer::createBaseElement();
// Serializer::addChildElement (serial, serialize<Serializer> (point.x));
// Serializer::addChildElement (serial, serialize<Serializer> (point.y));
// return serial;
// }

// /** Deserializer for juce::Point types */
// template <typename Serializer, typename T>
// static std::enable_if_t<IsPoint<T>, void>
// deserialize (DeserialType<Serializer> serial, T& point)
// {
// if (Serializer::getNumChildElements (serial) != 2)
// {
// jassertfalse; // the serialized data does not contain the correct number of elements to fill this array!
// point = {};
// return;
// }
//
// deserialize<Serializer> (Serializer::getChildElement (serial, 0), point.x);
// deserialize<Serializer> (Serializer::getChildElement (serial, 1), point.y);
// }

/** Serializer for juce::Point types */
template <typename Serializer, typename T>
static std::enable_if_t<IsPoint<T>, SerialType<Serializer>>
serialize (const T& point, SerialType<Serializer> &parent)
{
jassertfalse; // the serialized data does not contain the correct number of elements to fill this array!
point = {};
return;

Serializer::addChildElement (parent, "x", (point.x) );
Serializer::addChildElement (parent, "y" (point.y));
return parent;
}

/** Deserializer for juce::Point types */
template <typename Serializer, typename T>
static std::enable_if_t<IsPoint<T>, void>
deserialize (DeserialType<Serializer> serial, T& point) {
if (Serializer::getNumChildElements(serial) != 2) {
jassertfalse; // the serialized data does not contain the correct number of elements to fill this array!
point = {};
return;
}
point.x = Serializer::template deserializeArithmeticType<int>(serial, "point_x");
point.y = Serializer::template deserializeArithmeticType<int>(serial, "point_y");

}

deserialize<Serializer> (Serializer::getChildElement (serial, 0), point.x);
deserialize<Serializer> (Serializer::getChildElement (serial, 1), point.y);
}
#endif

/** Serializer for container types */
Expand Down Expand Up @@ -285,6 +363,13 @@ class BaseSerializer
return T::template serialize<Serializer> (object);
}


/** Serializer for types with custom serialization behaviour */
template <typename Serializer, typename T>
static std::enable_if_t<HasCustomSerialization<T>, SerialType<Serializer>> serialize (const T& object, SerialType<Serializer>& parent)
{
return T::template serialize<Serializer> (object, parent);
}
/** Deserializer for types with custom deserialization behaviour */
template <typename Serializer, typename T>
static std::enable_if_t<HasCustomDeserialization<T>, void> deserialize (DeserialType<Serializer> serial, T& object)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ namespace Serialization
return Serializer::template serialize<Serializer> (objectToSerialize);
}

template <typename Serializer, typename TypeToSerialize>
typename Serializer::SerializedType serialize (const TypeToSerialize& objectToSerialize,typename Serializer::SerializedType& serial)
{
static_assert (std::is_base_of_v<BaseSerializer, Serializer> || std::is_same_v<serialization_detail::DummySerializer, Serializer>,
"Serializer type must be derived from BaseSerializer");

return Serializer::template serialize<Serializer> (objectToSerialize, serial);
}

/** Serialize an object to a file with a given serializer */
template <typename Serializer, typename TypeToSerialize>
void serialize (const TypeToSerialize& objectToSerialize, const juce::File& targetFile)
Expand All @@ -40,6 +49,26 @@ namespace Serialization
Serializer::template deserialize<Serializer> (deserial, objectToDeserialize);
}

/** Deserialize an object with a given serializer */
template <typename Serializer, typename TypeToDeserialize>
void deserialize (const typename Serializer::SerializedType& serial, juce::String id, TypeToDeserialize& objectToDeserialize)
{
static_assert (std::is_base_of_v<BaseSerializer, Serializer> || std::is_same_v<serialization_detail::DummySerializer, Serializer>,
"Serializer type must be derived from BaseSerializer");

const auto deserial = Serializer::template getDeserial<Serializer> (serial);
Serializer::template deserialize<Serializer> (deserial, id, objectToDeserialize);
}

template <typename Serializer, typename TypeToDeserialize>
void deserialize (const typename Serializer::DeserializedType& serial, juce::String id, TypeToDeserialize& objectToDeserialize)
{
static_assert (std::is_base_of_v<BaseSerializer, Serializer> || std::is_same_v<serialization_detail::DummySerializer, Serializer>,
"Serializer type must be derived from BaseSerializer");

//const auto deserial = Serializer::template getDeserial<Serializer> (serial);
Serializer::template deserialize<Serializer> (serial, id, objectToDeserialize);
}
/** Deserialize an object from a file with a given serializer */
template <typename Serializer, typename TypeToDeserialize>
void deserialize (const juce::File& file, TypeToDeserialize& objectToDeserialize)
Expand All @@ -60,5 +89,11 @@ namespace Serialization
{
deserialize<Serializer> (Serializer::fromBinaryData (data, dataSize), objectToDeserialize);
}
/** Deserialize an object from a file with a given serializer */
template <typename Serializer, typename TypeToDeserialize>
void deserialize (const juce::XmlElement* xml, TypeToDeserialize& objectToDeserialize)
{
deserialize<Serializer> (Serializer::fromXML (xml), objectToDeserialize);
}
} // namespace Serialization
} // namespace chowdsp
Loading