diff --git a/GUI/Model/Device/MaskItems.cpp b/GUI/Model/Device/MaskItems.cpp index d11a347986119a34e82faeb4d1d9e99afaaed52f..ce59a80659aae089eb52c45b073aac11c0da01ce 100644 --- a/GUI/Model/Device/MaskItems.cpp +++ b/GUI/Model/Device/MaskItems.cpp @@ -303,13 +303,13 @@ void PolygonItem::serialize(Streamer& s) if (s.xmlReader()) { QVector<PolygonPointItem*> pts; - s.rwVec("points", pts); + Serialize::rwVector(s, "points", pts); for (const auto* point : pts) addPoint(point->posX(), point->posY()); qDeleteAll(pts); } else { auto p = points(); - s.rwVec("points", p); + Serialize::rwVector(s, "points", p); } } diff --git a/GUI/Model/Sample/LayerItem.cpp b/GUI/Model/Sample/LayerItem.cpp index 33385ad008bdeb14504e9b60d2ec622060a35cbc..ec8a9bda91c153e51faf6dcf12e1bb480c3c77ed 100644 --- a/GUI/Model/Sample/LayerItem.cpp +++ b/GUI/Model/Sample/LayerItem.cpp @@ -189,5 +189,5 @@ void LayerItem::serialize(Streamer& s) Serialize::rwProperty(s, m_numSlices); Serialize::rwProperty(s, m_thickness); s.rwIC2("Roughness", m_topRoughness); - s.rwVec("Layouts", m_layouts, m_materialItems); + Serialize::rwVector(s, "Layouts", m_layouts, m_materialItems); } diff --git a/GUI/Model/Sample/MaterialItems.cpp b/GUI/Model/Sample/MaterialItems.cpp index 78b23991c0d845e7e1bbbf155ebb9f900c72729d..4b083210329da4d6ee870636db6328d162eb0418 100644 --- a/GUI/Model/Sample/MaterialItems.cpp +++ b/GUI/Model/Sample/MaterialItems.cpp @@ -164,7 +164,7 @@ void MaterialItems::serialize(Streamer& s) if (s.xmlReader()) clear(); s.assertVersion(0); - s.rwVec("MaterialItems", m_materialItems); + Serialize::rwVector(s, "MaterialItems", m_materialItems); } void MaterialItems::initFrom(const MaterialItems& from) diff --git a/GUI/Model/Sample/MultiLayerItem.cpp b/GUI/Model/Sample/MultiLayerItem.cpp index 40e05514f556532b618664cc1ee4030518d434e3..91cc36403a08ad8e6e07932c59012f62d289ead2 100644 --- a/GUI/Model/Sample/MultiLayerItem.cpp +++ b/GUI/Model/Sample/MultiLayerItem.cpp @@ -149,7 +149,7 @@ void MultiLayerItem::serialize(Streamer& s) Serialize::rwProperty(s, m_crossCorrelationLength); Serialize::rwProperty(s, m_externalField); s.rwT("Materials", m_materials); - s.rwVec("Layers", m_layers, &m_materials); + Serialize::rwVector(s, "Layers", m_layers, &m_materials); if (s.xmlReader()) { // set non-stored infos diff --git a/GUI/Model/Sample/MultiLayerItems.cpp b/GUI/Model/Sample/MultiLayerItems.cpp index a6a38d9cf3ad4070ea812c6e2add6c67c2279aec..14aa7915709061369a13802d6dfff7e41c118566 100644 --- a/GUI/Model/Sample/MultiLayerItems.cpp +++ b/GUI/Model/Sample/MultiLayerItems.cpp @@ -56,5 +56,5 @@ QStringList MultiLayerItems::multiLayerNames() const void MultiLayerItems::serialize(Streamer& s) { s.assertVersion(0); - s.rwVec("Multilayers", m_multiLayers); + Serialize::rwVector(s, "Multilayers", m_multiLayers); } diff --git a/GUI/Model/XML/Streamer.h b/GUI/Model/XML/Streamer.h index 83ddfab9b4863a8be5be17b51953b2bdca98afd0..fed83a338cbf9a73c204b7ae4488923b683bf649 100644 --- a/GUI/Model/XML/Streamer.h +++ b/GUI/Model/XML/Streamer.h @@ -54,10 +54,6 @@ public: //! As writer, does nothing. void assertVersion(unsigned expectedVersion) const; - //! serialize a list with a known and fixed type which is not a base class, but the real class - template <typename T, typename... Args> - void rwVec(const QString& tag, QVector<T>& vec, Args... argsForConstructor); - //! serialize a list with a base class type, which can contain derived types. For this we need //! the catalog of possible classes/types to identify the current type and to re-create this //! type after serialization @@ -119,6 +115,13 @@ private: QXmlStreamReader* m_r = nullptr; }; +//! Functions to serialize various data types. +//! +//! Serialization means writing to or reading from an XML stream. +//! +//! This namespace is spread over several source files +//! in order to keep include dependencies unidirectional. + namespace Serialize { void rwValue(Streamer& s, const QString& tag, bool& val); @@ -129,6 +132,11 @@ void rwValue(Streamer& s, const QString& tag, QColor& col); void rwValue(Streamer& s, const QString& tag, QByteArray& val); void rwValue(Streamer& s, const QString& tag, R3& val); +//! serialize a list with a known and fixed type which is not a base class, but the real class +template <typename T, typename... Args> +void rwVector(Streamer& s, const QString& tag, QVector<T>& vec, Args... argsForConstructor); + + } // namespace Serialize // ************************************************************************************************ @@ -137,29 +145,30 @@ void rwValue(Streamer& s, const QString& tag, R3& val); //! serialize a list with a known and fixed type which is not a base class, but the real class template <typename T, typename... Args> -void Streamer::rwVec(const QString& tag, QVector<T>& vec, Args... argsForConstructor) +void Serialize::rwVector(Streamer& s, const QString& tag, QVector<T>& vec, + Args... argsForConstructor) { - if (m_w) { - m_w->writeStartElement(tag); - m_w->writeAttribute("n", QString::number(vec.size())); + if (QXmlStreamWriter* w = s.xmlWriter()) { + w->writeStartElement(tag); + w->writeAttribute("n", QString::number(vec.size())); int i = 0; for (auto* p : vec) { - m_w->writeStartElement("E" + QString::number(i++)); - p->serialize(*this); - m_w->writeEndElement(); + w->writeStartElement("E" + QString::number(i++)); + p->serialize(s); + w->writeEndElement(); } - m_w->writeEndElement(); - } else { - m_r->readNextStartElement(); - assertCurrentTag(tag); - const int n = m_r->attributes().value("n").toInt(); + w->writeEndElement(); + } else if (QXmlStreamReader* r = s.xmlReader()) { + r->readNextStartElement(); + s.assertCurrentTag(tag); + const int n = r->attributes().value("n").toInt(); for (int i = 0; i < n; i++) { - gotoStartElementOfTag("E" + QString::number(i)); + s.gotoStartElementOfTag("E" + QString::number(i)); vec << new typename std::remove_pointer<T>::type(argsForConstructor...); - vec.last()->serialize(*this); - gotoEndElementOfTag("E" + QString::number(i)); + vec.last()->serialize(s); + s.gotoEndElementOfTag("E" + QString::number(i)); } - gotoEndElementOfTag(tag); + s.gotoEndElementOfTag(tag); } } @@ -170,18 +179,18 @@ template <typename Catalog, typename... Args> void Streamer::rwCat(const QString& tag, QVector<typename Catalog::CatalogedType*>& vec, Args... argsForConstructor) { - if (m_w) { - m_w->writeStartElement(tag); - m_w->writeAttribute("n", QString::number(vec.size())); + if (QXmlStreamWriter* w = xmlWriter()) { + w->writeStartElement(tag); + w->writeAttribute("n", QString::number(vec.size())); int i = 0; for (auto* p : vec) { write<Catalog>("E" + QString::number(i++), p); } - m_w->writeEndElement(); - } else { - m_r->readNextStartElement(); + w->writeEndElement(); + } else if (QXmlStreamReader* r = xmlReader()) { + r->readNextStartElement(); assertCurrentTag(tag); - const int n = m_r->attributes().value("n").toInt(); + const int n = r->attributes().value("n").toInt(); for (int i = 0; i < n; i++) { typename Catalog::CatalogedType* p = nullptr; read<Catalog>("E" + QString::number(i), p, argsForConstructor...); @@ -195,10 +204,10 @@ template <typename Catalog, typename... ArgsForCreation> void Streamer::rwSel(SelectionProperty<typename Catalog::CatalogedType*>& d, ArgsForCreation... argsForCreation) { - if (m_w) { + if (QXmlStreamWriter* w = xmlWriter()) { typename Catalog::CatalogedType* p = d.get(); write<Catalog>(d.persistentTag(), p); - } else { + } else if (QXmlStreamReader* r = xmlReader()) { typename Catalog::CatalogedType* p = nullptr; read<Catalog>(d.persistentTag(), p, argsForCreation...); d.set(p); @@ -209,15 +218,15 @@ void Streamer::rwSel(SelectionProperty<typename Catalog::CatalogedType*>& d, template <typename ItemClass> void Streamer::rwIC(const QString& tag, ItemClass*& p) { - if (m_w) { - m_w->writeStartElement(tag); - m_w->writeAttribute("valid", p ? "1" : "0"); + if (QXmlStreamWriter* w = xmlWriter()) { + w->writeStartElement(tag); + w->writeAttribute("valid", p ? "1" : "0"); if (p != nullptr) p->serialize(*this); - m_w->writeEndElement(); - } else { + w->writeEndElement(); + } else if (QXmlStreamReader* r = xmlReader()) { gotoStartElementOfTag(tag); - const bool valid = m_r->attributes().value("valid").toUInt() > 0; + const bool valid = r->attributes().value("valid").toUInt() > 0; p = valid ? new ItemClass() : nullptr; if (p != nullptr) p->serialize(*this); @@ -232,15 +241,15 @@ template <typename ItemClass, typename... ArgsForConstructor> void Streamer::rwIC2(const QString& tag, std::unique_ptr<ItemClass>& up, ArgsForConstructor... argsForConstructor) { - if (m_w) { - m_w->writeStartElement(tag); - m_w->writeAttribute("valid", up ? "1" : "0"); + if (QXmlStreamWriter* w = xmlWriter()) { + w->writeStartElement(tag); + w->writeAttribute("valid", up ? "1" : "0"); if (up) up->serialize(*this); - m_w->writeEndElement(); - } else { + w->writeEndElement(); + } else if (QXmlStreamReader* r = xmlReader()) { gotoStartElementOfTag(tag); - const bool valid = m_r->attributes().value("valid").toUInt() > 0; + const bool valid = r->attributes().value("valid").toUInt() > 0; if (valid) { up.reset(new ItemClass(argsForConstructor...)); up->serialize(*this); @@ -254,11 +263,11 @@ void Streamer::rwIC2(const QString& tag, std::unique_ptr<ItemClass>& up, template <typename T> void Streamer::rwT(const QString& tag, T& t) { - if (m_w) { - m_w->writeStartElement(tag); + if (QXmlStreamWriter* w = xmlWriter()) { + w->writeStartElement(tag); t.serialize(*this); - m_w->writeEndElement(); - } else { + w->writeEndElement(); + } else if (QXmlStreamReader* r = xmlReader()) { gotoStartElementOfTag(tag); t.serialize(*this); gotoEndElementOfTag(tag); @@ -270,10 +279,10 @@ void Streamer::rwT(const QString& tag, T& t) template <typename type> void Streamer::rwSI(const QString& tag, SessionItem* property) { - if (m_w) { + if (QXmlStreamWriter* w = xmlWriter()) { auto v = property->value().value<type>(); Serialize::rwValue(*this, tag, v); - } else { + } else if (QXmlStreamReader* r = xmlReader()) { type v; Serialize::rwValue(*this, tag, v); property->setValue(v); @@ -283,11 +292,11 @@ void Streamer::rwSI(const QString& tag, SessionItem* property) template <typename BaseClass> void Streamer::rwBaseClass(const QString& tag, BaseClass* p) { - if (m_w) { - m_w->writeStartElement(tag); + if (QXmlStreamWriter* w = xmlWriter()) { + w->writeStartElement(tag); p->BaseClass::serialize(*this); - m_w->writeEndElement(); - } else { + w->writeEndElement(); + } else if (QXmlStreamReader* r = xmlReader()) { gotoStartElementOfTag(tag); p->BaseClass::serialize(*this); gotoEndElementOfTag(tag); @@ -301,15 +310,15 @@ template <typename ItemClass> void Streamer::rwWithInit(const QString& tag, std::unique_ptr<ItemClass>& up, const std::function<void(ItemClass*)>& initializer) { - if (m_w) { - m_w->writeStartElement(tag); - m_w->writeAttribute("valid", up ? "1" : "0"); + if (QXmlStreamWriter* w = xmlWriter()) { + w->writeStartElement(tag); + w->writeAttribute("valid", up ? "1" : "0"); if (up) up->serialize(*this); - m_w->writeEndElement(); - } else { + w->writeEndElement(); + } else if (QXmlStreamReader* r = xmlReader()) { gotoStartElementOfTag(tag); - const bool valid = m_r->attributes().value("valid").toUInt() > 0; + const bool valid = r->attributes().value("valid").toUInt() > 0; if (valid) { up.reset(new ItemClass()); if (initializer)