VariableController.cpp
241 lines
| 8.5 KiB
| text/x-c
|
CppLexer
r219 | #include <Variable/Variable.h> | |||
r209 | #include <Variable/VariableCacheController.h> | |||
Alexandre Leroux
|
r106 | #include <Variable/VariableController.h> | ||
Alexandre Leroux
|
r108 | #include <Variable/VariableModel.h> | ||
Alexandre Leroux
|
r106 | |||
Alexandre Leroux
|
r154 | #include <Data/DataProviderParameters.h> | ||
#include <Data/IDataProvider.h> | ||||
#include <Data/IDataSeries.h> | ||||
r179 | #include <Time/TimeController.h> | |||
Alexandre Leroux
|
r154 | |||
#include <QDateTime> | ||||
Alexandre Leroux
|
r106 | #include <QMutex> | ||
#include <QThread> | ||||
Alexandre Leroux
|
r347 | #include <QUuid> | ||
r281 | #include <QtCore/QItemSelectionModel> | |||
Alexandre Leroux
|
r106 | |||
r209 | #include <unordered_map> | |||
Alexandre Leroux
|
r106 | Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController") | ||
struct VariableController::VariableControllerPrivate { | ||||
Alexandre Leroux
|
r148 | explicit VariableControllerPrivate(VariableController *parent) | ||
r209 | : m_WorkingMutex{}, | |||
m_VariableModel{new VariableModel{parent}}, | ||||
r281 | m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}}, | |||
r209 | m_VariableCacheController{std::make_unique<VariableCacheController>()} | |||
Alexandre Leroux
|
r106 | { | ||
} | ||||
QMutex m_WorkingMutex; | ||||
Alexandre Leroux
|
r148 | /// Variable model. The VariableController has the ownership | ||
VariableModel *m_VariableModel; | ||||
r281 | QItemSelectionModel *m_VariableSelectionModel; | |||
r179 | ||||
r209 | ||||
r181 | TimeController *m_TimeController{nullptr}; | |||
r209 | std::unique_ptr<VariableCacheController> m_VariableCacheController; | |||
r219 | ||||
std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> > | ||||
m_VariableToProviderMap; | ||||
Alexandre Leroux
|
r386 | std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap; | ||
Alexandre Leroux
|
r106 | }; | ||
VariableController::VariableController(QObject *parent) | ||||
Alexandre Leroux
|
r148 | : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)} | ||
Alexandre Leroux
|
r106 | { | ||
r337 | qCDebug(LOG_VariableController()) << tr("VariableController construction") | |||
<< QThread::currentThread(); | ||||
r388 | ||||
connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this, | ||||
&VariableController::onAbortProgressRequested); | ||||
Alexandre Leroux
|
r106 | } | ||
VariableController::~VariableController() | ||||
{ | ||||
r337 | qCDebug(LOG_VariableController()) << tr("VariableController destruction") | |||
<< QThread::currentThread(); | ||||
Alexandre Leroux
|
r106 | this->waitForFinish(); | ||
} | ||||
Alexandre Leroux
|
r154 | VariableModel *VariableController::variableModel() noexcept | ||
Alexandre Leroux
|
r108 | { | ||
Alexandre Leroux
|
r154 | return impl->m_VariableModel; | ||
Alexandre Leroux
|
r108 | } | ||
r281 | QItemSelectionModel *VariableController::variableSelectionModel() noexcept | |||
{ | ||||
return impl->m_VariableSelectionModel; | ||||
} | ||||
r179 | void VariableController::setTimeController(TimeController *timeController) noexcept | |||
{ | ||||
impl->m_TimeController = timeController; | ||||
} | ||||
Alexandre Leroux
|
r303 | void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept | ||
{ | ||||
if (!variable) { | ||||
qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null"; | ||||
return; | ||||
} | ||||
Alexandre Leroux
|
r309 | // Spreads in SciQlop that the variable will be deleted, so that potential receivers can | ||
// make some treatments before the deletion | ||||
emit variableAboutToBeDeleted(variable); | ||||
Alexandre Leroux
|
r304 | |||
Alexandre Leroux
|
r386 | // Deletes identifier | ||
impl->m_VariableToIdentifierMap.erase(variable); | ||||
Alexandre Leroux
|
r304 | // Deletes provider | ||
auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable); | ||||
qCDebug(LOG_VariableController()) | ||||
<< tr("Number of providers deleted for variable %1: %2") | ||||
.arg(variable->name(), QString::number(nbProvidersDeleted)); | ||||
Alexandre Leroux
|
r303 | |||
Alexandre Leroux
|
r305 | // Clears cache | ||
impl->m_VariableCacheController->clear(variable); | ||||
Alexandre Leroux
|
r306 | // Deletes from model | ||
impl->m_VariableModel->deleteVariable(variable); | ||||
} | ||||
Alexandre Leroux
|
r303 | |||
void VariableController::deleteVariables( | ||||
const QVector<std::shared_ptr<Variable> > &variables) noexcept | ||||
{ | ||||
for (auto variable : qAsConst(variables)) { | ||||
deleteVariable(variable); | ||||
} | ||||
} | ||||
r388 | void VariableController::abortProgress(std::shared_ptr<Variable> variable) | |||
{ | ||||
} | ||||
Alexandre Leroux
|
r377 | void VariableController::createVariable(const QString &name, const QVariantHash &metadata, | ||
Alexandre Leroux
|
r154 | std::shared_ptr<IDataProvider> provider) noexcept | ||
Alexandre Leroux
|
r143 | { | ||
r179 | ||||
if (!impl->m_TimeController) { | ||||
qCCritical(LOG_VariableController()) | ||||
<< tr("Impossible to create variable: The time controller is null"); | ||||
return; | ||||
} | ||||
r209 | auto dateTime = impl->m_TimeController->dateTime(); | |||
Alexandre Leroux
|
r377 | |||
if (auto newVariable = impl->m_VariableModel->createVariable(name, dateTime, metadata)) { | ||||
r359 | auto identifier = QUuid::createUuid(); | |||
r209 | ||||
r219 | // store the provider | |||
impl->m_VariableToProviderMap[newVariable] = provider; | ||||
Alexandre Leroux
|
r386 | impl->m_VariableToIdentifierMap[newVariable] = identifier; | ||
r293 | ||||
Alexandre Leroux
|
r334 | auto addDateTimeAcquired = [ this, varW = std::weak_ptr<Variable>{newVariable} ]( | ||
r359 | QUuid identifier, auto dataSeriesAcquired, auto dateTimeToPutInCache) | |||
Alexandre Leroux
|
r334 | { | ||
if (auto variable = varW.lock()) { | ||||
Alexandre Leroux
|
r386 | auto varIdentifier = impl->m_VariableToIdentifierMap.at(variable); | ||
r359 | if (varIdentifier == identifier) { | |||
Alexandre Leroux
|
r347 | impl->m_VariableCacheController->addDateTime(variable, dateTimeToPutInCache); | ||
variable->setDataSeries(dataSeriesAcquired); | ||||
r399 | emit variable->updated(); | |||
Alexandre Leroux
|
r347 | } | ||
Alexandre Leroux
|
r334 | } | ||
}; | ||||
r293 | ||||
connect(provider.get(), &IDataProvider::dataProvided, addDateTimeAcquired); | ||||
r391 | connect(provider.get(), &IDataProvider::dataProvidedProgress, this, | |||
&VariableController::onVariableRetrieveDataInProgress); | ||||
r294 | this->onRequestDataLoading(newVariable, dateTime); | |||
Alexandre Leroux
|
r154 | } | ||
Alexandre Leroux
|
r143 | } | ||
r281 | void VariableController::onDateTimeOnSelection(const SqpDateTime &dateTime) | |||
{ | ||||
r337 | qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection" | |||
<< QThread::currentThread()->objectName(); | ||||
r281 | auto selectedRows = impl->m_VariableSelectionModel->selectedRows(); | |||
for (const auto &selectedRow : qAsConst(selectedRows)) { | ||||
if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) { | ||||
selectedVariable->setDateTime(dateTime); | ||||
r282 | this->onRequestDataLoading(selectedVariable, dateTime); | |||
r281 | } | |||
} | ||||
} | ||||
r369 | void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress) | |||
{ | ||||
auto findReply = [identifier](const auto &entry) { return identifier == entry.second; }; | ||||
Alexandre Leroux
|
r386 | auto end = impl->m_VariableToIdentifierMap.cend(); | ||
auto it = std::find_if(impl->m_VariableToIdentifierMap.cbegin(), end, findReply); | ||||
r369 | if (it != end) { | |||
impl->m_VariableModel->setDataProgress(it->first, progress); | ||||
} | ||||
} | ||||
r388 | void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable) | |||
{ | ||||
qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested" | ||||
<< QThread::currentThread()->objectName(); | ||||
r389 | auto it = impl->m_VariableToIdentifierMap.find(variable); | |||
if (it != impl->m_VariableToIdentifierMap.cend()) { | ||||
r388 | impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second); | |||
} | ||||
else { | ||||
qCWarning(LOG_VariableController()) | ||||
<< tr("Aborting progression of inexistant variable detected !!!") | ||||
<< QThread::currentThread()->objectName(); | ||||
} | ||||
} | ||||
r219 | ||||
r276 | void VariableController::onRequestDataLoading(std::shared_ptr<Variable> variable, | |||
const SqpDateTime &dateTime) | ||||
r219 | { | |||
r337 | qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading" | |||
<< QThread::currentThread()->objectName(); | ||||
r219 | // we want to load data of the variable for the dateTime. | |||
// First we check if the cache contains some of them. | ||||
// For the other, we ask the provider to give them. | ||||
if (variable) { | ||||
auto dateTimeListNotInCache | ||||
= impl->m_VariableCacheController->provideNotInCacheDateTimeList(variable, dateTime); | ||||
r276 | if (!dateTimeListNotInCache.empty()) { | |||
// Ask the provider for each data on the dateTimeListNotInCache | ||||
Alexandre Leroux
|
r386 | auto identifier = impl->m_VariableToIdentifierMap.at(variable); | ||
r276 | impl->m_VariableToProviderMap.at(variable)->requestDataLoading( | |||
Alexandre Leroux
|
r378 | identifier, | ||
DataProviderParameters{std::move(dateTimeListNotInCache), variable->metadata()}); | ||||
r276 | } | |||
else { | ||||
emit variable->updated(); | ||||
} | ||||
r219 | } | |||
else { | ||||
qCCritical(LOG_VariableController()) << tr("Impossible to load data of a variable null"); | ||||
} | ||||
} | ||||
Alexandre Leroux
|
r106 | void VariableController::initialize() | ||
{ | ||||
qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread(); | ||||
impl->m_WorkingMutex.lock(); | ||||
qCDebug(LOG_VariableController()) << tr("VariableController init END"); | ||||
} | ||||
void VariableController::finalize() | ||||
{ | ||||
impl->m_WorkingMutex.unlock(); | ||||
} | ||||
void VariableController::waitForFinish() | ||||
{ | ||||
QMutexLocker locker{&impl->m_WorkingMutex}; | ||||
} | ||||