#include "DataSource/DataSourceController.h" #include "DataSource/DataSourceItem.h" #include #include #include #include #include Q_LOGGING_CATEGORY(LOG_DataSourceController, "DataSourceController") namespace { /** * Builds the metadata of the variable that will be generated from the loading of an item * @param dataSourceItem the data source item from which to generate the metadata * @return the metadata of the variable */ QVariantHash variableMetadata(const DataSourceItem &dataSourceItem) { // Variable metadata contains... // ... all metadata of the item auto result = dataSourceItem.data(); // ... and the name of the plugin, recovered from root item result.insert(QStringLiteral("plugin"), dataSourceItem.rootItem().name()); return result; } } // namespace class DataSourceController::DataSourceControllerPrivate { public: QMutex m_WorkingMutex; /// Data sources registered QHash m_DataSources; /// Data sources structures std::map > m_DataSourceItems; /// Data providers registered /// @remarks Data providers are stored as shared_ptr as they can be sent to a variable and /// continue to live without necessarily the data source controller std::map > m_DataProviders; }; DataSourceController::DataSourceController(QObject *parent) : impl{spimpl::make_unique_impl()} { qCDebug(LOG_DataSourceController()) << tr("DataSourceController construction") << QThread::currentThread(); } DataSourceController::~DataSourceController() { qCDebug(LOG_DataSourceController()) << tr("DataSourceController destruction") << QThread::currentThread(); this->waitForFinish(); } QUuid DataSourceController::registerDataSource(const QString &dataSourceName) noexcept { auto dataSourceUid = QUuid::createUuid(); impl->m_DataSources.insert(dataSourceUid, dataSourceName); return dataSourceUid; } void DataSourceController::setDataSourceItem( const QUuid &dataSourceUid, std::unique_ptr dataSourceItem) noexcept { if (!dataSourceItem) { qCWarning(LOG_DataSourceController()) << tr("Data source item can't be registered (null item)"); return; } if (impl->m_DataSources.contains(dataSourceUid)) { // The data provider is implicitly converted to a shared_ptr impl->m_DataSourceItems.insert(std::make_pair(dataSourceUid, std::move(dataSourceItem))); // Retrieves the data source item to emit the signal with it auto it = impl->m_DataSourceItems.find(dataSourceUid); if (it != impl->m_DataSourceItems.end()) { emit dataSourceItemSet(it->second.get()); } } else { qCWarning(LOG_DataSourceController()) << tr("Can't set data source item for uid %1 : no " "data source has been registered with the uid") .arg(dataSourceUid.toString()); } } void DataSourceController::setDataProvider(const QUuid &dataSourceUid, std::unique_ptr dataProvider) noexcept { if (impl->m_DataSources.contains(dataSourceUid)) { impl->m_DataProviders.insert(std::make_pair(dataSourceUid, std::move(dataProvider))); } else { qCWarning(LOG_DataSourceController()) << tr("Can't set data provider for uid %1 : no data " "source has been registered with the uid") .arg(dataSourceUid.toString()); } } void DataSourceController::loadProductItem(const QUuid &dataSourceUid, const DataSourceItem &productItem) noexcept { if (productItem.type() == DataSourceItemType::PRODUCT || productItem.type() == DataSourceItemType::COMPONENT) { /// Retrieves the data provider of the data source (if any) auto it = impl->m_DataProviders.find(dataSourceUid); auto dataProvider = (it != impl->m_DataProviders.end()) ? it->second : nullptr; emit variableCreationRequested(productItem.name(), variableMetadata(productItem), dataProvider); } else { qCWarning(LOG_DataSourceController()) << tr("Can't load an item that is not a product"); } } void DataSourceController::initialize() { qCDebug(LOG_DataSourceController()) << tr("DataSourceController init") << QThread::currentThread(); impl->m_WorkingMutex.lock(); qCDebug(LOG_DataSourceController()) << tr("DataSourceController init END"); } void DataSourceController::finalize() { impl->m_WorkingMutex.unlock(); } void DataSourceController::waitForFinish() { QMutexLocker locker{&impl->m_WorkingMutex}; }