##// END OF EJS Templates
Settings binding (4)...
Settings binding (4) Loads settings when opening the dialog, and save settings when closing it (if it's by the OK button)

File last commit:

r442:dd79727b8dcb
r469:7a2eb58d2083
Show More
VariableController.cpp
244 lines | 8.6 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);
// notify that rescale operation has to be done
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};
}