DataSourceController.cpp
143 lines
| 5.1 KiB
| text/x-c
|
CppLexer
Alexandre Leroux
|
r171 | #include "DataSource/DataSourceController.h" | ||
#include "DataSource/DataSourceItem.h" | ||||
r21 | ||||
Alexandre Leroux
|
r127 | #include <Data/IDataProvider.h> | ||
r21 | #include <QMutex> | |||
#include <QThread> | ||||
r25 | #include <QDir> | |||
#include <QStandardPaths> | ||||
Q_LOGGING_CATEGORY(LOG_DataSourceController, "DataSourceController") | ||||
r21 | ||||
Alexandre Leroux
|
r551 | 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 | ||||
r21 | class DataSourceController::DataSourceControllerPrivate { | |||
public: | ||||
QMutex m_WorkingMutex; | ||||
Alexandre Leroux
|
r37 | /// Data sources registered | ||
Alexandre Leroux
|
r36 | QHash<QUuid, QString> m_DataSources; | ||
Alexandre Leroux
|
r37 | /// Data sources structures | ||
std::map<QUuid, std::unique_ptr<DataSourceItem> > m_DataSourceItems; | ||||
Alexandre Leroux
|
r127 | /// Data providers registered | ||
Alexandre Leroux
|
r167 | /// @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<QUuid, std::shared_ptr<IDataProvider> > m_DataProviders; | ||||
r21 | }; | |||
DataSourceController::DataSourceController(QObject *parent) | ||||
: impl{spimpl::make_unique_impl<DataSourceControllerPrivate>()} | ||||
{ | ||||
r76 | qCDebug(LOG_DataSourceController()) << tr("DataSourceController construction") | |||
<< QThread::currentThread(); | ||||
r21 | } | |||
DataSourceController::~DataSourceController() | ||||
{ | ||||
r76 | qCDebug(LOG_DataSourceController()) << tr("DataSourceController destruction") | |||
<< QThread::currentThread(); | ||||
r21 | this->waitForFinish(); | |||
} | ||||
Alexandre Leroux
|
r36 | QUuid DataSourceController::registerDataSource(const QString &dataSourceName) noexcept | ||
{ | ||||
auto dataSourceUid = QUuid::createUuid(); | ||||
impl->m_DataSources.insert(dataSourceUid, dataSourceName); | ||||
return dataSourceUid; | ||||
} | ||||
Alexandre Leroux
|
r37 | void DataSourceController::setDataSourceItem( | ||
const QUuid &dataSourceUid, std::unique_ptr<DataSourceItem> dataSourceItem) noexcept | ||||
{ | ||||
Alexandre Leroux
|
r357 | if (!dataSourceItem) { | ||
qCWarning(LOG_DataSourceController()) | ||||
<< tr("Data source item can't be registered (null item)"); | ||||
return; | ||||
} | ||||
Alexandre Leroux
|
r37 | if (impl->m_DataSources.contains(dataSourceUid)) { | ||
Alexandre Leroux
|
r167 | // The data provider is implicitly converted to a shared_ptr | ||
Alexandre Leroux
|
r37 | 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()) { | ||||
Alexandre Leroux
|
r92 | emit dataSourceItemSet(it->second.get()); | ||
Alexandre Leroux
|
r37 | } | ||
} | ||||
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()); | ||||
} | ||||
} | ||||
Alexandre Leroux
|
r127 | void DataSourceController::setDataProvider(const QUuid &dataSourceUid, | ||
std::unique_ptr<IDataProvider> 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()); | ||||
} | ||||
} | ||||
Alexandre Leroux
|
r167 | void DataSourceController::loadProductItem(const QUuid &dataSourceUid, | ||
const DataSourceItem &productItem) noexcept | ||||
Alexandre Leroux
|
r146 | { | ||
Alexandre Leroux
|
r414 | if (productItem.type() == DataSourceItemType::PRODUCT | ||
|| productItem.type() == DataSourceItemType::COMPONENT) { | ||||
Alexandre Leroux
|
r168 | /// 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; | ||||
Alexandre Leroux
|
r169 | |||
Alexandre Leroux
|
r551 | emit variableCreationRequested(productItem.name(), variableMetadata(productItem), | ||
dataProvider); | ||||
Alexandre Leroux
|
r168 | } | ||
else { | ||||
qCWarning(LOG_DataSourceController()) << tr("Can't load an item that is not a product"); | ||||
} | ||||
Alexandre Leroux
|
r146 | } | ||
r21 | void DataSourceController::initialize() | |||
{ | ||||
r76 | qCDebug(LOG_DataSourceController()) << tr("DataSourceController init") | |||
<< QThread::currentThread(); | ||||
r21 | impl->m_WorkingMutex.lock(); | |||
Alexandre Leroux
|
r32 | qCDebug(LOG_DataSourceController()) << tr("DataSourceController init END"); | ||
r21 | } | |||
void DataSourceController::finalize() | ||||
{ | ||||
impl->m_WorkingMutex.unlock(); | ||||
} | ||||
void DataSourceController::waitForFinish() | ||||
{ | ||||
Alexandre Leroux
|
r32 | QMutexLocker locker{&impl->m_WorkingMutex}; | ||
r21 | } | |||