From 3595efca866fd2fae0d8046f2557c32b23470dd0 Mon Sep 17 00:00:00 2001 From: Tobias Knopff <t.knopff@fz-juelich.de> Date: Fri, 16 Jul 2021 17:11:00 +0200 Subject: [PATCH] Make DataLoaders1D independent of concrete DataLoaders --- GUI/DataLoaders/DataLoaderUtil.cpp | 28 +++++++++ GUI/DataLoaders/DataLoaderUtil.h | 24 ++++++++ GUI/DataLoaders/DataLoadersRegistration.cpp | 45 ++++++++++++++ GUI/Models/DataLoaders1D.cpp | 61 ++++++------------- GUI/Models/DataLoaders1D.h | 19 ++++-- .../SpecularDataImportWidget.cpp | 3 +- 6 files changed, 131 insertions(+), 49 deletions(-) create mode 100644 GUI/DataLoaders/DataLoaderUtil.cpp create mode 100644 GUI/DataLoaders/DataLoaderUtil.h create mode 100644 GUI/DataLoaders/DataLoadersRegistration.cpp diff --git a/GUI/DataLoaders/DataLoaderUtil.cpp b/GUI/DataLoaders/DataLoaderUtil.cpp new file mode 100644 index 00000000000..7333459b916 --- /dev/null +++ b/GUI/DataLoaders/DataLoaderUtil.cpp @@ -0,0 +1,28 @@ +// ************************************************************************************************ +// +// BornAgain: simulate and fit reflection and scattering +// +//! @file GUI/DataLoaders/UserDefinedDataLoader1D.cpp +//! @brief Implements class UserDefinedDataLoader1D +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2021 +//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) +// +// ************************************************************************************************ + +#include "GUI/DataLoaders/DataLoaderUtil.h" +#include "GUI/DataLoaders/UserDefinedDataLoader1D.h" +#include "GUI/Models/DataLoaders1D.h" + +void cloneAsUserDefinedLoader(AbstractDataLoader* loader, const QString& name) +{ + loader->applyImportSettings(); + auto clonedLoader = dynamic_cast<AbstractDataLoader1D*>(loader->clone()); + const auto defaultProperties = loader->serialize(); + + DataLoaders1D::instance().addUserDefinedLoader + (new UserDefinedDataLoader1D(clonedLoader, name, defaultProperties)); +} + diff --git a/GUI/DataLoaders/DataLoaderUtil.h b/GUI/DataLoaders/DataLoaderUtil.h new file mode 100644 index 00000000000..e4f90be4ee0 --- /dev/null +++ b/GUI/DataLoaders/DataLoaderUtil.h @@ -0,0 +1,24 @@ +// ************************************************************************************************ +// +// BornAgain: simulate and fit reflection and scattering +// +//! @file GUI/DataLoaders/UserDefinedDataLoader1D.h +//! @brief Utility functions for data loaders +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2021 +//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) +// +// ************************************************************************************************ + +#ifndef BORNAGAIN_GUI_DATALOADERS_DATALOADERUTIL_H +#define BORNAGAIN_GUI_DATALOADERS_DATALOADERUTIL_H + +class AbstractDataLoader; +class QString; + +//! clones the loader as a user defined loader and puts it in DataLoaders1D store +void cloneAsUserDefinedLoader(AbstractDataLoader* loader, const QString& name); + +#endif // BORNAGAIN_GUI_DATALOADERS_DATALOADERUTIL_H diff --git a/GUI/DataLoaders/DataLoadersRegistration.cpp b/GUI/DataLoaders/DataLoadersRegistration.cpp new file mode 100644 index 00000000000..58733b9de2d --- /dev/null +++ b/GUI/DataLoaders/DataLoadersRegistration.cpp @@ -0,0 +1,45 @@ +// ************************************************************************************************ +// +// BornAgain: simulate and fit reflection and scattering +// +//! @file GUI/DataLoaders/DataLoadersRegistration.cpp +//! @brief Perform the registration of the dataloaders at the corresponding sites +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2021 +//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) +// +// ************************************************************************************************ + +#include "GUI/Models/DataLoaders1D.h" +#include "GUI/DataLoaders/AutomaticDataLoader1D.h" +#include "GUI/DataLoaders/QREDataLoader.h" + +namespace { + +QREDataLoader* createQREDataLoader() +{ + return new QREDataLoader(); +} + +AutomaticDataLoader1D* createAutomaticDataLoader1D() +{ + return new AutomaticDataLoader1D(); +} + +bool register_dataloaders() { + // the ordering in here defines the ordering in the selection combo box in the open file dialog + // and also in the selection combo box on the format configuration page. Furthermore the first + // returned loader will be used as default in the open file dialog if it is started for the + // first time + DataLoaders1D::instance().addBuiltInLoader + (QREDataLoader().persistentClassName(), createQREDataLoader); + DataLoaders1D::instance().addBuiltInLoader + (AutomaticDataLoader1D().persistentClassName(), createAutomaticDataLoader1D); + + return true; +} + +bool registration = register_dataloaders(); +} diff --git a/GUI/Models/DataLoaders1D.cpp b/GUI/Models/DataLoaders1D.cpp index d8661e217b3..e77d4007a42 100644 --- a/GUI/Models/DataLoaders1D.cpp +++ b/GUI/Models/DataLoaders1D.cpp @@ -13,23 +13,7 @@ // ************************************************************************************************ #include "GUI/Models/DataLoaders1D.h" -#include "GUI/DataLoaders/AutomaticDataLoader1D.h" -#include "GUI/DataLoaders/QREDataLoader.h" -#include "GUI/DataLoaders/UserDefinedDataLoader1D.h" - -namespace { - -// the one and only instance of DataLoaders1D -DataLoaders1D dataLoaders1D; - -} // namespace - -DataLoaders1D* DataLoaders1D::m_instance = nullptr; - -DataLoaders1D::DataLoaders1D() -{ - m_instance = this; -} +#include "GUI/Models/AbstractDataLoader1D.h" DataLoaders1D::~DataLoaders1D() { @@ -39,23 +23,25 @@ DataLoaders1D::~DataLoaders1D() DataLoaders1D& DataLoaders1D::instance() { - return *m_instance; + static DataLoaders1D inst; + + return inst; +} + +void DataLoaders1D::addBuiltInLoader(const QString& name, + const std::function<AbstractDataLoader1D*()>& create) +{ + m_createLoaders.emplace(name, create); + m_builtInLoaders.push_back(create()); } -void DataLoaders1D::initBuiltInLoaders() +void DataLoaders1D::addUserDefinedLoader(AbstractDataLoader* loader) { - // the ordering in here defines the ordering in the selection combo box in the open file dialog - // and also in the selection combo box on the format configuration page. Furthermore the first - // returned loader will be used as default in the open file dialog if it is started for the - // first time - m_builtInLoaders << new QREDataLoader(); - m_builtInLoaders << new AutomaticDataLoader1D(); + m_userDefinedLoaders.push_back(loader); } QVector<AbstractDataLoader*> DataLoaders1D::loaders() const { - if (m_builtInLoaders.isEmpty()) - const_cast<DataLoaders1D*>(this)->initBuiltInLoaders(); return m_builtInLoaders + m_userDefinedLoaders; } @@ -64,22 +50,13 @@ QVector<AbstractDataLoader*> DataLoaders1D::recentlyUsedLoaders() const return m_recentlyUsedLoaders; } -void DataLoaders1D::cloneAsUserDefinedLoader(AbstractDataLoader* loader, const QString& name) -{ - loader->applyImportSettings(); - auto clonedLoader = dynamic_cast<AbstractDataLoader1D*>(loader->clone()); - const auto defaultProperties = loader->serialize(); - - m_userDefinedLoaders << new UserDefinedDataLoader1D(clonedLoader, name, defaultProperties); -} - AbstractDataLoader1D* DataLoaders1D::createFromPersistentName(const QString& persistentClassName) { - if (persistentClassName == AutomaticDataLoader1D().persistentClassName()) - return new AutomaticDataLoader1D(); - - if (persistentClassName == QREDataLoader().persistentClassName()) - return new QREDataLoader(); + std::map<QString,std::function<AbstractDataLoader1D*()>>::const_iterator it = + m_createLoaders.find(persistentClassName); - return nullptr; + if (it != m_createLoaders.end()) + return it->second(); + else + return nullptr; } diff --git a/GUI/Models/DataLoaders1D.h b/GUI/Models/DataLoaders1D.h index b94f54fe8f8..e5eee7004be 100644 --- a/GUI/Models/DataLoaders1D.h +++ b/GUI/Models/DataLoaders1D.h @@ -17,6 +17,9 @@ #include <QVector> +#include <map> +#include <functional> + class AbstractDataLoader; class AbstractDataLoader1D; @@ -24,12 +27,18 @@ class AbstractDataLoader1D; class DataLoaders1D { public: - DataLoaders1D(); ~DataLoaders1D(); //! The one and only instance static DataLoaders1D& instance(); + //! Register a built-in loader with the given class name and factory function + void addBuiltInLoader(const QString& persistentClassName, + const std::function<AbstractDataLoader1D*()>& create); + + //! Register a built-in loader with the given class name and factory function + void addUserDefinedLoader(AbstractDataLoader* loader); + //! all defined loaders. A null element in the list defines a separator //! The returned pointers are the same over the lifetime of the DataLoaders instance, therefore //! they can be used for comparison. @@ -41,22 +50,20 @@ public: //! Notify loader was recently used void setRecentlyUsedLoader(const AbstractDataLoader* loader); - //! Clone the loader and create a user defined loader with its current settings and the given - //! name - void cloneAsUserDefinedLoader(AbstractDataLoader* loader, const QString& name); - //! Create loader from the given persistent name AbstractDataLoader1D* createFromPersistentName(const QString& persistentClassName); private: + DataLoaders1D() = default; + //! create all default built in loaders void initBuiltInLoaders(); private: - static DataLoaders1D* m_instance; QVector<AbstractDataLoader*> m_builtInLoaders; QVector<AbstractDataLoader*> m_recentlyUsedLoaders; QVector<AbstractDataLoader*> m_userDefinedLoaders; + std::map<QString,std::function<AbstractDataLoader1D*()>> m_createLoaders; }; #endif // BORNAGAIN_GUI_MODELS_DATALOADERS1D_H diff --git a/GUI/Views/SpecularDataWidgets/SpecularDataImportWidget.cpp b/GUI/Views/SpecularDataWidgets/SpecularDataImportWidget.cpp index ee053348263..567b66cf33e 100644 --- a/GUI/Views/SpecularDataWidgets/SpecularDataImportWidget.cpp +++ b/GUI/Views/SpecularDataWidgets/SpecularDataImportWidget.cpp @@ -13,6 +13,7 @@ // ************************************************************************************************ #include "GUI/Views/SpecularDataWidgets/SpecularDataImportWidget.h" +#include "GUI/DataLoaders/DataLoaderUtil.h" #include "GUI/Models/AbstractDataLoaderResultModel.h" #include "GUI/Models/DataItemUtils.h" #include "GUI/Models/DataLoaders1D.h" @@ -333,7 +334,7 @@ void SpecularDataImportWidget::onCreateNewFormatButton() if (!ok || name.isEmpty()) return; - DataLoaders1D::instance().cloneAsUserDefinedLoader(m_loader, name); + cloneAsUserDefinedLoader(m_loader, name); fillLoaderCombo(); m_ui->formatSelectionComboBox->setCurrentText(name); -- GitLab