##// END OF EJS Templates
Add implementation for the range rescale. Variable is ignored here...
Add implementation for the range rescale. Variable is ignored here Add variable for tolerance Remove unused code

File last commit:

r437:9fabd78ca3ee
r438:4113f5669532
Show More
VariableController.cpp
242 lines | 8.5 KiB | text/x-c | CppLexer
/ core / src / Variable / VariableController.cpp
#include <Variable/Variable.h>
#include <Variable/VariableCacheController.h>
#include <Variable/VariableController.h>
#include <Variable/VariableModel.h>
#include <Data/DataProviderParameters.h>
#include <Data/IDataProvider.h>
#include <Data/IDataSeries.h>
#include <Time/TimeController.h>
#include <QDateTime>
#include <QMutex>
#include <QThread>
#include <QUuid>
#include <QtCore/QItemSelectionModel>
#include <unordered_map>
Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
struct VariableController::VariableControllerPrivate {
explicit VariableControllerPrivate(VariableController *parent)
: m_WorkingMutex{},
m_VariableModel{new VariableModel{parent}},
m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
m_VariableCacheController{std::make_unique<VariableCacheController>()}
{
}
QMutex m_WorkingMutex;
/// Variable model. The VariableController has the ownership
VariableModel *m_VariableModel;
QItemSelectionModel *m_VariableSelectionModel;
TimeController *m_TimeController{nullptr};
std::unique_ptr<VariableCacheController> m_VariableCacheController;
std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
m_VariableToProviderMap;
std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
};
VariableController::VariableController(QObject *parent)
: QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
{
qCDebug(LOG_VariableController()) << tr("VariableController construction")
<< QThread::currentThread();
connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
&VariableController::onAbortProgressRequested);
}
VariableController::~VariableController()
{
qCDebug(LOG_VariableController()) << tr("VariableController destruction")
<< QThread::currentThread();
this->waitForFinish();
}
VariableModel *VariableController::variableModel() noexcept
{
return impl->m_VariableModel;
}
QItemSelectionModel *VariableController::variableSelectionModel() noexcept
{
return impl->m_VariableSelectionModel;
}
void VariableController::setTimeController(TimeController *timeController) noexcept
{
impl->m_TimeController = timeController;
}
void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
{
if (!variable) {
qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
return;
}
// Spreads in SciQlop that the variable will be deleted, so that potential receivers can
// make some treatments before the deletion
emit variableAboutToBeDeleted(variable);
// Deletes identifier
impl->m_VariableToIdentifierMap.erase(variable);
// 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));
// Clears cache
impl->m_VariableCacheController->clear(variable);
// Deletes from model
impl->m_VariableModel->deleteVariable(variable);
}
void VariableController::deleteVariables(
const QVector<std::shared_ptr<Variable> > &variables) noexcept
{
for (auto variable : qAsConst(variables)) {
deleteVariable(variable);
}
}
void VariableController::abortProgress(std::shared_ptr<Variable> variable)
{
}
void VariableController::createVariable(const QString &name, const QVariantHash &metadata,
std::shared_ptr<IDataProvider> provider) noexcept
{
if (!impl->m_TimeController) {
qCCritical(LOG_VariableController())
<< tr("Impossible to create variable: The time controller is null");
return;
}
auto dateTime = impl->m_TimeController->dateTime();
if (auto newVariable = impl->m_VariableModel->createVariable(name, dateTime, metadata)) {
auto identifier = QUuid::createUuid();
// store the provider
impl->m_VariableToProviderMap[newVariable] = provider;
impl->m_VariableToIdentifierMap[newVariable] = identifier;
auto addDateTimeAcquired = [ this, varW = std::weak_ptr<Variable>{newVariable} ](
QUuid identifier, auto dataSeriesAcquired, auto dateTimeToPutInCache)
{
if (auto variable = varW.lock()) {
auto varIdentifier = impl->m_VariableToIdentifierMap.at(variable);
if (varIdentifier == identifier) {
impl->m_VariableCacheController->addDateTime(variable, dateTimeToPutInCache);
variable->setDataSeries(dataSeriesAcquired);
emit variable->updated();
}
}
};
connect(provider.get(), &IDataProvider::dataProvided, addDateTimeAcquired);
connect(provider.get(), &IDataProvider::dataProvidedProgress, this,
&VariableController::onVariableRetrieveDataInProgress);
this->onRequestDataLoading(newVariable, dateTime);
}
}
void VariableController::onDateTimeOnSelection(const SqpDateTime &dateTime)
{
qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
<< QThread::currentThread()->objectName();
auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
for (const auto &selectedRow : qAsConst(selectedRows)) {
if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
selectedVariable->setDateTime(dateTime);
this->onRequestDataLoading(selectedVariable, dateTime);
emit rangeChanged(selectedVariable, dateTime);
}
}
}
void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
{
auto findReply = [identifier](const auto &entry) { return identifier == entry.second; };
auto end = impl->m_VariableToIdentifierMap.cend();
auto it = std::find_if(impl->m_VariableToIdentifierMap.cbegin(), end, findReply);
if (it != end) {
impl->m_VariableModel->setDataProgress(it->first, progress);
}
}
void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
{
qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
<< QThread::currentThread()->objectName();
auto it = impl->m_VariableToIdentifierMap.find(variable);
if (it != impl->m_VariableToIdentifierMap.cend()) {
impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
}
else {
qCWarning(LOG_VariableController())
<< tr("Aborting progression of inexistant variable detected !!!")
<< QThread::currentThread()->objectName();
}
}
void VariableController::onRequestDataLoading(std::shared_ptr<Variable> variable,
const SqpDateTime &dateTime)
{
qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
<< QThread::currentThread()->objectName();
// 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);
if (!dateTimeListNotInCache.empty()) {
// Ask the provider for each data on the dateTimeListNotInCache
auto identifier = impl->m_VariableToIdentifierMap.at(variable);
impl->m_VariableToProviderMap.at(variable)->requestDataLoading(
identifier,
DataProviderParameters{std::move(dateTimeListNotInCache), variable->metadata()});
}
else {
emit variable->updated();
}
}
else {
qCCritical(LOG_VariableController()) << tr("Impossible to load data of a variable null");
}
}
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};
}