From 4de1e0ed1feadc5a4b1506bd6ea61597f84d0663 Mon Sep 17 00:00:00 2001
From: Gennady Pospelov <g.pospelov@fz-juelich.de>
Date: Fri, 17 Mar 2017 14:13:06 +0100
Subject: [PATCH] New templated convenience function to get groupItem.

---
 GUI/coregui/Models/DetectorItems.cpp          |  7 ++---
 GUI/coregui/Models/InstrumentItem.cpp         |  4 +--
 .../Models/InterferenceFunctionItems.cpp      | 27 +++++++++----------
 GUI/coregui/Models/MinimizerItem.cpp          |  4 +--
 .../Models/ParticleDistributionItem.cpp       | 17 +++++-------
 GUI/coregui/Models/ParticleItem.cpp           |  6 ++---
 GUI/coregui/Models/SessionItem.h              |  9 +++++++
 GUI/coregui/Models/TransformToDomain.cpp      | 13 +++------
 .../Views/InfoWidgets/DistributionWidget.cpp  |  5 ++--
 .../Views/SampleDesigner/ParticleView.cpp     |  9 ++-----
 dev-tools/log/perf_history.txt                |  3 +++
 11 files changed, 44 insertions(+), 60 deletions(-)

diff --git a/GUI/coregui/Models/DetectorItems.cpp b/GUI/coregui/Models/DetectorItems.cpp
index 1320967034e..e0cb20c597b 100644
--- a/GUI/coregui/Models/DetectorItems.cpp
+++ b/GUI/coregui/Models/DetectorItems.cpp
@@ -74,11 +74,8 @@ void DetectorItem::register_resolution_function()
 
 std::unique_ptr<IResolutionFunction2D> DetectorItem::createResolutionFunction() const
 {
-    auto resfuncItem
-        = dynamic_cast<ResolutionFunctionItem*>(getGroupItem(DetectorItem::P_RESOLUTION_FUNCTION));
-    Q_ASSERT(resfuncItem);
-
-    return resfuncItem->createResolutionFunction(axesToDomainUnitsFactor());
+    auto& resfuncItem = groupItem<ResolutionFunctionItem>(DetectorItem::P_RESOLUTION_FUNCTION);
+    return resfuncItem.createResolutionFunction(axesToDomainUnitsFactor());
 }
 
 void DetectorItem::addMasksToDomain(IDetector2D* detector) const
diff --git a/GUI/coregui/Models/InstrumentItem.cpp b/GUI/coregui/Models/InstrumentItem.cpp
index dbb976a4349..109f3ad0bf6 100644
--- a/GUI/coregui/Models/InstrumentItem.cpp
+++ b/GUI/coregui/Models/InstrumentItem.cpp
@@ -47,9 +47,7 @@ BeamItem *InstrumentItem::beamItem() const
 
 DetectorItem* InstrumentItem::detectorItem() const
 {
-    DetectorItem* result = dynamic_cast<DetectorItem*>(getGroupItem(P_DETECTOR));
-    Q_ASSERT(result);
-    return result;
+    return &groupItem<DetectorItem>(P_DETECTOR);
 }
 
 GroupItem* InstrumentItem::detectorGroup()
diff --git a/GUI/coregui/Models/InterferenceFunctionItems.cpp b/GUI/coregui/Models/InterferenceFunctionItems.cpp
index 6bf782d1659..0d29976c49b 100644
--- a/GUI/coregui/Models/InterferenceFunctionItems.cpp
+++ b/GUI/coregui/Models/InterferenceFunctionItems.cpp
@@ -68,8 +68,8 @@ InterferenceFunctionRadialParaCrystalItem::createInterferenceFunction() const
     result->setDomainSize(getItemValue(P_DOMAIN_SIZE).toDouble());
     result->setKappa(getItemValue(P_KAPPA).toDouble());
 
-    auto pdfItem = dynamic_cast<FTDistribution1DItem*>(getGroupItem(P_PDF));
-    result->setProbabilityDistribution(*pdfItem->createFTDistribution());
+    auto& pdfItem = groupItem<FTDistribution1DItem>(P_PDF);
+    result->setProbabilityDistribution(*pdfItem.createFTDistribution());
     return std::move(result);
 }
 
@@ -121,23 +121,20 @@ InterferenceFunction2DParaCrystalItem::InterferenceFunction2DParaCrystalItem()
 std::unique_ptr<IInterferenceFunction>
 InterferenceFunction2DParaCrystalItem::createInterferenceFunction() const
 {
-    auto latticeItem = dynamic_cast<Lattice2DItem*>(
-        getGroupItem(InterferenceFunction2DLatticeItem::P_LATTICE_TYPE));
+    auto& latticeItem = groupItem<Lattice2DItem>(InterferenceFunction2DLatticeItem::P_LATTICE_TYPE);
 
     std::unique_ptr<InterferenceFunction2DParaCrystal> result(
-        new InterferenceFunction2DParaCrystal(*latticeItem->createLattice()));
+        new InterferenceFunction2DParaCrystal(*latticeItem.createLattice()));
 
     result->setDampingLength(getItemValue(P_DAMPING_LENGTH).toDouble());
     result->setDomainSizes(getItemValue(P_DOMAIN_SIZE1).toDouble(),
                            getItemValue(P_DOMAIN_SIZE2).toDouble());
     result->setIntegrationOverXi(getItemValue(P_XI_INTEGRATION).toBool());
 
-    auto pdf1Item = dynamic_cast<FTDistribution2DItem*>(
-        getGroupItem(InterferenceFunction2DParaCrystalItem::P_PDF1));
-    auto pdf2Item = dynamic_cast<FTDistribution2DItem*>(
-        getGroupItem(InterferenceFunction2DParaCrystalItem::P_PDF2));
-    result->setProbabilityDistributions(*pdf1Item->createFTDistribution(),
-                                        *pdf2Item->createFTDistribution());
+    auto& pdf1Item = groupItem<FTDistribution2DItem>(InterferenceFunction2DParaCrystalItem::P_PDF1);
+    auto& pdf2Item = groupItem<FTDistribution2DItem>(InterferenceFunction2DParaCrystalItem::P_PDF2);
+    result->setProbabilityDistributions(*pdf1Item.createFTDistribution(),
+                                        *pdf2Item.createFTDistribution());
 
     return std::move(result);
 }
@@ -217,12 +214,12 @@ InterferenceFunction2DLatticeItem::InterferenceFunction2DLatticeItem()
 std::unique_ptr<IInterferenceFunction>
 InterferenceFunction2DLatticeItem::createInterferenceFunction() const
 {
-    auto latticeItem = dynamic_cast<Lattice2DItem*>(getGroupItem(P_LATTICE_TYPE));
+    auto& latticeItem = groupItem<Lattice2DItem>(P_LATTICE_TYPE);
     std::unique_ptr<InterferenceFunction2DLattice> result(
-        new InterferenceFunction2DLattice(*latticeItem->createLattice()));
+        new InterferenceFunction2DLattice(*latticeItem.createLattice()));
 
-    auto pdfItem = dynamic_cast<FTDecayFunction2DItem*>(getGroupItem(P_DECAY_FUNCTION));
-    result->setDecayFunction(*pdfItem->createFTDecayFunction());
+    auto& pdfItem = groupItem<FTDecayFunction2DItem>(P_DECAY_FUNCTION);
+    result->setDecayFunction(*pdfItem.createFTDecayFunction());
 
     return std::move(result);
 }
diff --git a/GUI/coregui/Models/MinimizerItem.cpp b/GUI/coregui/Models/MinimizerItem.cpp
index 239f830aad3..6e312cd35be 100644
--- a/GUI/coregui/Models/MinimizerItem.cpp
+++ b/GUI/coregui/Models/MinimizerItem.cpp
@@ -42,9 +42,7 @@ MinimizerContainerItem::MinimizerContainerItem() : MinimizerItem(Constants::Mini
 
 std::unique_ptr<IMinimizer> MinimizerContainerItem::createMinimizer() const
 {
-    auto minimizer = static_cast<MinimizerItem *>(getGroupItem(P_MINIMIZERS));
-    Q_ASSERT(minimizer);
-    return minimizer->createMinimizer();
+    return groupItem<MinimizerItem>(P_MINIMIZERS).createMinimizer();
 }
 
 // ----------------------------------------------------------------------------
diff --git a/GUI/coregui/Models/ParticleDistributionItem.cpp b/GUI/coregui/Models/ParticleDistributionItem.cpp
index fca6f11f73f..1d832e79419 100644
--- a/GUI/coregui/Models/ParticleDistributionItem.cpp
+++ b/GUI/coregui/Models/ParticleDistributionItem.cpp
@@ -72,18 +72,15 @@ std::unique_ptr<ParticleDistribution> ParticleDistributionItem::createParticleDi
     if (!P_particle)
         throw GUIHelpers::Error("DomainObjectBuilder::buildParticleDistribution()"
                                 " -> Error! No correct particle defined");
-    auto distr_item = dynamic_cast<DistributionItem*>(
-                getGroupItem(ParticleDistributionItem::P_DISTRIBUTION));
-    Q_ASSERT(distr_item);
+    auto& distr_item = groupItem<DistributionItem>(ParticleDistributionItem::P_DISTRIBUTION);
 
     RealLimits limits = RealLimits::limitless();
-    if(distr_item->isTag(DistributionItem::P_LIMITS)) {
-        auto limitsItem = dynamic_cast<RealLimitsItem*>(
-                    distr_item->getGroupItem(DistributionItem::P_LIMITS));
-        limits = limitsItem->createRealLimits();
+    if(distr_item.isTag(DistributionItem::P_LIMITS)) {
+        auto& limitsItem = distr_item.groupItem<RealLimitsItem>(DistributionItem::P_LIMITS);
+        limits = limitsItem.createRealLimits();
     }
 
-    auto P_distribution = distr_item->createDistribution();
+    auto P_distribution = distr_item.createDistribution();
 
     auto prop
         = getItemValue(ParticleDistributionItem::P_DISTRIBUTED_PARAMETER).value<ComboProperty>();
@@ -92,8 +89,8 @@ std::unique_ptr<ParticleDistribution> ParticleDistributionItem::createParticleDi
     std::string domain_par
         = ParameterTreeUtils::parameterNameToDomainName(par_name, childParticle()).toStdString();
 
-    int nbr_samples = distr_item->getItemValue(DistributionItem::P_NUMBER_OF_SAMPLES).toInt();
-    double sigma_factor = distr_item->getItemValue(DistributionItem::P_SIGMA_FACTOR).toDouble();
+    int nbr_samples = distr_item.getItemValue(DistributionItem::P_NUMBER_OF_SAMPLES).toInt();
+    double sigma_factor = distr_item.getItemValue(DistributionItem::P_SIGMA_FACTOR).toDouble();
     ParameterDistribution par_distr(domain_par, *P_distribution, nbr_samples, sigma_factor, limits);
     auto result = GUIHelpers::make_unique<ParticleDistribution>(*P_particle, par_distr);
     double abundance = getItemValue(ParticleItem::P_ABUNDANCE).toDouble();
diff --git a/GUI/coregui/Models/ParticleItem.cpp b/GUI/coregui/Models/ParticleItem.cpp
index 4e604712a65..ceccf6342ed 100644
--- a/GUI/coregui/Models/ParticleItem.cpp
+++ b/GUI/coregui/Models/ParticleItem.cpp
@@ -80,10 +80,8 @@ std::unique_ptr<Particle> ParticleItem::createParticle() const
     double abundance = getItemValue(ParticleItem::P_ABUNDANCE).toDouble();
     P_particle->setAbundance(abundance);
 
-    auto ffItem = static_cast<FormFactorItem*>(getGroupItem(ParticleItem::P_FORM_FACTOR));
-    Q_ASSERT(ffItem);
-    auto P_ff = ffItem->createFormFactor();
-    P_particle->setFormFactor(*P_ff);
+    auto& ffItem = groupItem<FormFactorItem>(ParticleItem::P_FORM_FACTOR);
+    P_particle->setFormFactor(*ffItem.createFormFactor());
 
     TransformToDomain::setTransformationInfo(P_particle.get(), *this);
 
diff --git a/GUI/coregui/Models/SessionItem.h b/GUI/coregui/Models/SessionItem.h
index 695d77bf6cd..cc1decc3b2b 100644
--- a/GUI/coregui/Models/SessionItem.h
+++ b/GUI/coregui/Models/SessionItem.h
@@ -97,6 +97,7 @@ public:
 
     SessionItem *setGroupProperty(const QString &name, const QString &value) const;
     SessionItem *getGroupItem(const QString &groupName) const;
+    template<typename T> T& groupItem(const QString &groupName) const;
 
     // access data stored in roles
     virtual QVariant data(int role) const;
@@ -171,4 +172,12 @@ T& SessionItem::item(const QString& tag) const
     return *t;
 }
 
+template<typename T>
+T& SessionItem::groupItem(const QString& groupName) const
+{
+    T* t = dynamic_cast<T*>(getGroupItem(groupName));
+    Q_ASSERT(t);
+    return *t;
+}
+
 #endif // SESSIONITEM_H
diff --git a/GUI/coregui/Models/TransformToDomain.cpp b/GUI/coregui/Models/TransformToDomain.cpp
index e092aa44af7..569fca3a851 100644
--- a/GUI/coregui/Models/TransformToDomain.cpp
+++ b/GUI/coregui/Models/TransformToDomain.cpp
@@ -214,17 +214,10 @@ void TransformToDomain::setRotationInfo(IParticle* result, const SessionItem& it
     QVector<SessionItem*> children = item.childItems();
     for (int i = 0; i < children.size(); ++i) {
         if (children[i]->modelType() == Constants::TransformationType) {
-            RotationItem* rot_item = dynamic_cast<RotationItem*>(
-                children[i]->getGroupItem(TransformationItem::P_ROT));
-            if (!rot_item) {
-                throw GUIHelpers::Error("DomainObjectBuilder::setRotationInfo() "
-                                        "-> Error! ParticleItem's child is"
-                                        " not a rotation.");
-            }
-            std::unique_ptr<IRotation> P_rotation(rot_item->createRotation());
-            if (P_rotation.get()) {
+            auto& rot_item = children[i]->groupItem<RotationItem>(TransformationItem::P_ROT);
+            std::unique_ptr<IRotation> P_rotation(rot_item.createRotation());
+            if (P_rotation)
                 result->setRotation(*P_rotation);
-            }
             break;
         }
     }
diff --git a/GUI/coregui/Views/InfoWidgets/DistributionWidget.cpp b/GUI/coregui/Views/InfoWidgets/DistributionWidget.cpp
index d53badca2a9..e11e5dda7d7 100644
--- a/GUI/coregui/Views/InfoWidgets/DistributionWidget.cpp
+++ b/GUI/coregui/Views/InfoWidgets/DistributionWidget.cpp
@@ -210,9 +210,8 @@ void DistributionWidget::plot_multiple_values()
 
     RealLimits limits;
     if (m_item->isTag(DistributionItem::P_LIMITS)) {
-        auto limitsItem
-            = dynamic_cast<RealLimitsItem*>(m_item->getGroupItem(DistributionItem::P_LIMITS));
-        limits = limitsItem->createRealLimits();
+        auto& limitsItem = m_item->groupItem<RealLimitsItem>(DistributionItem::P_LIMITS);
+        limits = limitsItem.createRealLimits();
     }
     plotLimits(limits);
 
diff --git a/GUI/coregui/Views/SampleDesigner/ParticleView.cpp b/GUI/coregui/Views/SampleDesigner/ParticleView.cpp
index 4c91ed2ab63..0ac100e7002 100644
--- a/GUI/coregui/Views/SampleDesigner/ParticleView.cpp
+++ b/GUI/coregui/Views/SampleDesigner/ParticleView.cpp
@@ -98,12 +98,7 @@ void ParticleView::update_appearance()
 
 void ParticleView::updatePixmap()
 {
-    GroupProperty_t group_property
-        = dynamic_cast<GroupItem *>(
-              getItem()->getItem(ParticleItem::P_FORM_FACTOR))
-              ->groupProperty();
-    QString current_ff_type = group_property->currentType();
-    QString filename
-        = QString(":/widgetbox/images/ff_%1_32.png").arg(current_ff_type);
+    QString ff_type = getItem()->item<GroupItem>(ParticleItem::P_FORM_FACTOR).currentType();
+    QString filename = QString(":/widgetbox/images/ff_%1_32.png").arg(ff_type);
     m_pixmap = QPixmap(filename);
 }
diff --git a/dev-tools/log/perf_history.txt b/dev-tools/log/perf_history.txt
index b6468533a4e..176284b6105 100644
--- a/dev-tools/log/perf_history.txt
+++ b/dev-tools/log/perf_history.txt
@@ -593,3 +593,6 @@
 | 2017-03-16 15:53:02 | scgsun   | Linux x86_64 | 2.7    | 93.3001   | 18.0506    | 0.7573     | 0.6264          | 3.9816          | 0.4498    | 2.7937        | 0.6295            | 2.9224         | 1.0736 | 1.9965      | 2.0363    | 0.7836    |
 
 16.03.2017 17:17:08 | domain2gui 1415 msec | gui2domain 1431 msec | realTime 1018 msec | 
+
+# after groupProperty refactoring
+17.03.2017 14:11:39 | domain2gui 1290 msec | gui2domain 1392 msec | realTime 983 msec |
-- 
GitLab