From d02433cb665c1e618e06cdbaf0bbe7001e8fc057 Mon Sep 17 00:00:00 2001
From: Mikhail Svechnikov <m.svechnikov@fz-juelich.de>
Date: Mon, 6 Feb 2023 17:47:54 +0100
Subject: [PATCH] replace data items serialization in JobItem and RealItem

---
 GUI/Model/Data/DataItem.cpp |  1 +
 GUI/Model/Data/DataItem.h   |  2 ++
 GUI/Model/Data/RealItem.cpp | 33 ++++++++++++++++++++++-----------
 GUI/Model/Data/RealItem.h   |  4 +++-
 GUI/Model/Job/JobItem.cpp   | 13 ++++---------
 GUI/Model/Job/JobItem.h     |  2 +-
 6 files changed, 33 insertions(+), 22 deletions(-)

diff --git a/GUI/Model/Data/DataItem.cpp b/GUI/Model/Data/DataItem.cpp
index 9d9eeceb191..a524f09ab14 100644
--- a/GUI/Model/Data/DataItem.cpp
+++ b/GUI/Model/Data/DataItem.cpp
@@ -38,6 +38,7 @@ const QString y_axis_default_name = "Y [nbins]";
 
 DataItem::DataItem(const QString& modelType)
     : SessionItem(modelType)
+    , TYPE(modelType)
     , m_fileName("undefined")
     , m_axesUnits(ComboProperty::fromList({"nbins"}))
     , m_xAxis(std::make_unique<BasicAxisItem>())
diff --git a/GUI/Model/Data/DataItem.h b/GUI/Model/Data/DataItem.h
index e301da06295..47bddef98f5 100644
--- a/GUI/Model/Data/DataItem.h
+++ b/GUI/Model/Data/DataItem.h
@@ -39,6 +39,8 @@ protected:
     explicit DataItem(const QString& modelType);
 
 public:
+    const QString TYPE{"uninitialized"};
+
     // Returns datafield, owned by this class
     Datafield* datafield() { return m_datafield.get(); }
     const Datafield* datafield() const { return m_datafield.get(); }
diff --git a/GUI/Model/Data/RealItem.cpp b/GUI/Model/Data/RealItem.cpp
index 5a1b3d60f93..a6f0e7d95c7 100644
--- a/GUI/Model/Data/RealItem.cpp
+++ b/GUI/Model/Data/RealItem.cpp
@@ -88,6 +88,18 @@ SpecularDataItem* RealItem::specularDataItem() const
     return dynamic_cast<SpecularDataItem*>(dataItem());
 }
 
+DataItem* RealItem::initFromType(const QString &type)
+{
+    if (type == SpecularDataItem::M_TYPE)
+        initAsSpecularItem();
+    else if (type == IntensityDataItem::M_TYPE)
+        initAsIntensityItem();
+    else
+        ASSERT(false);
+
+    return m_dataItem.get();
+}
+
 void RealItem::initAsSpecularItem()
 {
     const size_t rank = 1;
@@ -120,11 +132,12 @@ DataItem* RealItem::nativeDataItem() const
     return m_nativeDataItem.get();
 }
 
-void RealItem::initNativeData()
+DataItem* RealItem::initNativeData()
 {
     const size_t rank = isSpecularData() ? 1 : 2;
     initDataItem(rank, m_nativeDataItem);
     updateDataFileName();
+    return m_nativeDataItem.get();
 }
 
 void RealItem::removeNativeData()
@@ -385,24 +398,20 @@ void RealItem::writeTo(QXmlStreamWriter* w, const QString& projectDir) const
     // data
     if (m_dataItem) {
         w->writeStartElement(Tag::Data);
-        XML::writeItemAndChildItems(w, m_dataItem.get(), projectDir);
+        XML::writeAttribute(w, XML::Attrib::type, m_dataItem->TYPE);
+        m_dataItem->writeTo(w, projectDir);
         w->writeEndElement();
     }
 
     // native data
     if (m_nativeDataItem) {
         w->writeStartElement(Tag::NativeData);
-        XML::writeItemAndChildItems(w, m_nativeDataItem.get(), projectDir);
+        XML::writeAttribute(w, XML::Attrib::type, m_nativeDataItem->TYPE);
+        m_nativeDataItem->writeTo(w, projectDir);
         w->writeEndElement();
     }
 }
 
-template <class T>
-inline T* readItemToEnd(QXmlStreamReader* reader, SessionItem* parent_item, const QString& tag)
-{
-    return dynamic_cast<T*>(XML::readItemAndChildItems(reader, parent_item, tag));
-}
-
 QString RealItem::readFrom(QXmlStreamReader* r, const QString& projectDir,
                            MessageService* messageService)
 {
@@ -441,13 +450,15 @@ QString RealItem::readFrom(QXmlStreamReader* r, const QString& projectDir,
 
             // data
         } else if (tag == Tag::Data) {
-            m_dataItem.reset(readItemToEnd<DataItem>(r, this, tag));
+            QString type;
+            XML::readAttribute(r, XML::Attrib::type, &type);
+            initFromType(type)->readFrom(r);
             dataError = m_dataItem->loadDatafield(messageService, projectDir);
             XML::gotoEndElementOfTag(r, tag);
 
             // native data
         } else if (tag == Tag::NativeData) {
-            m_nativeDataItem.reset(readItemToEnd<DataItem>(r, this, tag));
+            initNativeData()->readFrom(r); // requires initialized m_dataItem
             nativeDataError = m_nativeDataItem->loadDatafield(messageService, projectDir);
             XML::gotoEndElementOfTag(r, tag);
 
diff --git a/GUI/Model/Data/RealItem.h b/GUI/Model/Data/RealItem.h
index ab00dc4f22b..5294cca49cc 100644
--- a/GUI/Model/Data/RealItem.h
+++ b/GUI/Model/Data/RealItem.h
@@ -53,6 +53,7 @@ public:
     IntensityDataItem* intensityDataItem() const;
     SpecularDataItem* specularDataItem() const;
 
+    DataItem* initFromType(const QString& type);
     void initAsSpecularItem();
     void initAsIntensityItem();
 
@@ -63,7 +64,8 @@ public:
 
     bool hasNativeData() const;
     DataItem* nativeDataItem() const;
-    void initNativeData();
+
+    DataItem *initNativeData();
     void removeNativeData();
 
     QString nativeDataUnits() const;
diff --git a/GUI/Model/Job/JobItem.cpp b/GUI/Model/Job/JobItem.cpp
index 730abea94ee..4159e1542f6 100644
--- a/GUI/Model/Job/JobItem.cpp
+++ b/GUI/Model/Job/JobItem.cpp
@@ -308,10 +308,11 @@ DataItem* JobItem::createNewDataItem()
     return dataItem;
 }
 
-void JobItem::createSumulatedDataItem()
+DataItem* JobItem::createSumulatedDataItem()
 {
     ASSERT(!simulatedDataItem());
     m_simulatedDataItem.reset(createNewDataItem());
+    return m_simulatedDataItem.get();
 }
 
 IntensityDataItem* JobItem::intensityDataItem()
@@ -497,7 +498,7 @@ void JobItem::writeTo(QXmlStreamWriter* w, const QString& projectDir) const
     // simulated data
     if (m_simulatedDataItem) {
         w->writeStartElement(Tag::SimulatedData);
-        XML::writeItemAndChildItems(w, m_simulatedDataItem.get(), projectDir);
+        m_simulatedDataItem->writeTo(w, projectDir);
         w->writeEndElement();
     }
 
@@ -509,12 +510,6 @@ void JobItem::writeTo(QXmlStreamWriter* w, const QString& projectDir) const
     }
 }
 
-template <class T>
-inline T* readItemToEnd(QXmlStreamReader* reader, SessionItem* parent_item, const QString& tag)
-{
-    return dynamic_cast<T*>(XML::readItemAndChildItems(reader, parent_item, tag));
-}
-
 void JobItem::readFrom(QXmlStreamReader* r, const QString& projectDir,
                        MessageService* messageService)
 {
@@ -611,7 +606,7 @@ void JobItem::readFrom(QXmlStreamReader* r, const QString& projectDir,
 
             // simulated data
         } else if (tag == Tag::SimulatedData) {
-            m_simulatedDataItem.reset(readItemToEnd<DataItem>(r, this, Tag::SimulatedData));
+            createSumulatedDataItem()->readFrom(r);
             simError = m_simulatedDataItem->loadDatafield(messageService, projectDir);
             XML::gotoEndElementOfTag(r, tag);
 
diff --git a/GUI/Model/Job/JobItem.h b/GUI/Model/Job/JobItem.h
index 6f14787b288..1dbf6eac4ef 100644
--- a/GUI/Model/Job/JobItem.h
+++ b/GUI/Model/Job/JobItem.h
@@ -121,7 +121,7 @@ public:
 
     // data
 
-    void createSumulatedDataItem();
+    DataItem* createSumulatedDataItem();
     IntensityDataItem* intensityDataItem();
     DataItem* simulatedDataItem();
 
-- 
GitLab