From 4d03130678b75c4e8bdd301abf8cb4d94e189cf7 2017-09-14 07:19:26 From: Alexandre Leroux Date: 2017-09-14 07:19:26 Subject: [PATCH] commit VC --- diff --git a/app/src/Main.cpp b/app/src/Main.cpp index 9f0d81e..5c8b223 100644 --- a/app/src/Main.cpp +++ b/app/src/Main.cpp @@ -41,13 +41,11 @@ const auto PLUGIN_DIRECTORY_NAME = QStringLiteral("plugins"); int main(int argc, char *argv[]) { - // QLoggingCategory::setFilterRules( - // "*.warning=false\n" - // "*.info=false\n" - // "*.debug=false\n" - // "AmdaProvider.info=true\n" - // "NetworkController.info=true\n" - // "VariableAcquisitionWorker.info=true\n"); + QLoggingCategory::setFilterRules( + "*.warning=false\n" + "*.info=false\n" + "*.debug=false\n" + "VariableController.info=true\n"); SqpApplication a{argc, argv}; SqpApplication::setOrganizationName("LPP"); diff --git a/core/include/Data/AcquisitionRequest.h b/core/include/Data/AcquisitionRequest.h index 859078d..b2c5363 100644 --- a/core/include/Data/AcquisitionRequest.h +++ b/core/include/Data/AcquisitionRequest.h @@ -17,8 +17,8 @@ /** * @brief The AcquisitionRequest struct holds the information of an variable request */ -struct AcquisitionRequest { - AcquisitionRequest() +struct Acquisition { + Acquisition() { m_AcqIdentifier = QUuid::createUuid(); m_Size = 0; diff --git a/core/include/Data/VariableRequest.h b/core/include/Data/VariableRequest.h index efec09e..1e08378 100644 --- a/core/include/Data/VariableRequest.h +++ b/core/include/Data/VariableRequest.h @@ -6,19 +6,42 @@ #include #include +#include #include #include #include +class DataProviderParameters; +class IDataProvider; + /** * @brief The VariableRequest struct holds the information of an acquisition request */ struct VariableRequest { + void addResult(std::shared_ptr dataSeries) + { + if (!m_Result) { + m_Result = dataSeries->clone(); + } + else { + m_Result->merge(dataSeries.get()); + } + + ++m_ExecCount; + } + + bool isFinished() const { return m_ProviderParameters.m_Times.size() == m_ExecCount; } + + // Parameters SqpRange m_RangeRequested{INVALID_RANGE}; SqpRange m_CacheRangeRequested{INVALID_RANGE}; - std::shared_ptr m_DataSeries{nullptr}; - bool m_CanUpdate{false}; + std::shared_ptr m_Provider{nullptr}; + DataProviderParameters m_ProviderParameters{}; + + // Results + std::shared_ptr m_Result{nullptr}; + int m_ExecCount{0}; }; SCIQLOP_REGISTER_META_TYPE(VARIABLEREQUEST_REGISTRY, VariableRequest) diff --git a/core/include/Variable/VariableAcquisitionWorker.h b/core/include/Variable/VariableAcquisitionWorker.h index 967886f..f7b40b5 100644 --- a/core/include/Variable/VariableAcquisitionWorker.h +++ b/core/include/Variable/VariableAcquisitionWorker.h @@ -11,6 +11,7 @@ #include #include #include +#include #include @@ -28,24 +29,19 @@ public: explicit VariableAcquisitionWorker(QObject *parent = 0); virtual ~VariableAcquisitionWorker(); - QUuid pushVariableRequest(QUuid varRequestId, QUuid vIdentifier, SqpRange rangeRequested, - SqpRange cacheRangeRequested, DataProviderParameters parameters, - std::shared_ptr provider); + void pushVariableRequest(std::shared_ptr variable, VariableRequest request); void abortProgressRequested(QUuid vIdentifier); void initialize(); void finalize(); signals: - void dataProvided(QUuid vIdentifier, const SqpRange &rangeRequested, - const SqpRange &cacheRangeRequested, - QVector dataAcquired); - + void dataProvided(std::shared_ptr variable, VariableRequest request); void variableRequestInProgress(QUuid vIdentifier, double progress); public slots: - void onVariableDataAcquired(QUuid acqIdentifier, std::shared_ptr dataSeries, - SqpRange dataRangeAcquired); + void onDataAcquired(QUuid acquisitionId, std::shared_ptr dataSeries, + SqpRange range); void onVariableAcquisitionCanceled(QUuid acqIdentifier); void onVariableRetrieveDataInProgress(QUuid acqIdentifier, double progress); @@ -56,7 +52,7 @@ private: spimpl::unique_impl_ptr impl; private slots: - void onExecuteRequest(QUuid acqIdentifier); + void executeAcquisition(QUuid acquisitionId); }; #endif // SCIQLOP_VARIABLEACQUISITIONWORKER_H diff --git a/core/include/Variable/VariableController.h b/core/include/Variable/VariableController.h index a7243be..8a56dfb 100644 --- a/core/include/Variable/VariableController.h +++ b/core/include/Variable/VariableController.h @@ -17,6 +17,7 @@ class QItemSelectionModel; class TimeController; class Variable; class VariableModel; +class VariableRequest; Q_DECLARE_LOGGING_CATEGORY(LOG_VariableController) @@ -78,8 +79,8 @@ signals: public slots: /// Request the data loading of the variable whithin range - void onRequestDataLoading(QVector > variables, const SqpRange &range, - const SqpRange &oldRange, bool synchronise); + void onRequestDataLoading(const QVector > &variables, + const SqpRange &range, const SqpRange &oldRange, bool synchronise); /** * Creates a new variable and adds it to the model * @param name the name of the new variable @@ -93,10 +94,7 @@ public slots: /// Update the temporal parameters of every selected variable to dateTime void onDateTimeOnSelection(const SqpRange &dateTime); - - void onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested, - const SqpRange &cacheRangeRequested, - QVector dataAcquired); + void onDataProvided(std::shared_ptr variable, VariableRequest request); void onVariableRetrieveDataInProgress(QUuid identifier, double progress); diff --git a/core/include/Variable/VariableSynchronizationGroup.h b/core/include/Variable/VariableSynchronizationGroup.h deleted file mode 100644 index ffb5ce8..0000000 --- a/core/include/Variable/VariableSynchronizationGroup.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef SCIQLOP_VARIABLESYNCHRONIZATIONGROUP_H -#define SCIQLOP_VARIABLESYNCHRONIZATIONGROUP_H - -#include "CoreGlobal.h" - -#include -#include -#include - -#include - -#include - -#include - -#include - -Q_DECLARE_LOGGING_CATEGORY(LOG_VariableSynchronizationGroup) - -class Variable; - -/// This class aims to hande the cache strategy. -class SCIQLOP_CORE_EXPORT VariableSynchronizationGroup : public QObject { - Q_OBJECT -public: - explicit VariableSynchronizationGroup(QObject *parent = 0); - - void addVariableId(QUuid vIdentifier); - void removeVariableId(QUuid vIdentifier); - - const std::set &getIds() const noexcept; - -private: - class VariableSynchronizationGroupPrivate; - spimpl::unique_impl_ptr impl; -}; - -#endif // SCIQLOP_VARIABLESYNCHRONIZATIONGROUP_H diff --git a/core/include/Variable/VariableSynchronizer.h b/core/include/Variable/VariableSynchronizer.h new file mode 100644 index 0000000..caf6ec2 --- /dev/null +++ b/core/include/Variable/VariableSynchronizer.h @@ -0,0 +1,68 @@ +#ifndef SCIQLOP_VARIABLESYNCHRONIZER_H +#define SCIQLOP_VARIABLESYNCHRONIZER_H + +#include "CoreGlobal.h" + +#include + +#include +#include + +#include +#include + +Q_DECLARE_LOGGING_CATEGORY(LOG_VariableSynchronizer) + +class Variable; + +/** + * @brief The VariableAcquisitionWorker class handles synchronization between variables + */ +class SCIQLOP_CORE_EXPORT VariableSynchronizer : public QObject { + Q_OBJECT +public: + using GroupId = QUuid; + + explicit VariableSynchronizer(QObject *parent = 0); + + /** + * Adds a synchronization group under the identifier passed as a parameter. If a group with this + * identifier already exists, the method does nothing. + * @param groupId the group identifier + */ + void addGroup(GroupId groupId) noexcept; + + /** + * Adds a variable to a synchronization group. If the variable is already registered under + * another group, or the synchronization doesn't exist, the method does nothing + * @param variable the variable to synchronize + * @param groupId the synchronization group identifier + */ + void addVariable(std::shared_ptr variable, GroupId groupId) noexcept; + + /** + * Removes the synchronization group under the identifier passed as a parameter. If no group + * exists with this identifier, the method does nothing. + * @param groupId the group identifier + */ + void removeGroup(GroupId groupId) noexcept; + + /** + * Removes a variable from a synchronization group. If the synchronization group doesn't exist + * or if the variable isn't in it, the method does nothing + * @param variable the variable to desynchronize + * @param groupId the synchronization group identifier + */ + void removeVariable(std::shared_ptr variable, GroupId groupId) noexcept; + + /// @return the variables in the same group than the variable passed as a parameter (including + /// the variable) + std::set > + synchronizedVariables(std::shared_ptr variable) const noexcept; + +private: + class VariableSynchronizerPrivate; + spimpl::unique_impl_ptr impl; +}; + +#endif // SCIQLOP_VARIABLESYNCHRONIZER_H diff --git a/core/src/Variable/VariableAcquisitionWorker.cpp b/core/src/Variable/VariableAcquisitionWorker.cpp index c0b277d..957c6ae 100644 --- a/core/src/Variable/VariableAcquisitionWorker.cpp +++ b/core/src/Variable/VariableAcquisitionWorker.cpp @@ -2,9 +2,8 @@ #include "Variable/Variable.h" -#include +#include #include - #include #include @@ -20,6 +19,12 @@ namespace { using AcquisitionId = QUuid; using VariableId = QUuid; +struct Acquisition { + std::shared_ptr m_Variable{nullptr}; + VariableRequest m_Request{}; + AcquisitionId m_Id{QUuid::createUuid()}; +}; + } // namespace struct VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate { @@ -30,21 +35,42 @@ struct VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate { void lockWrite() { m_Lock.lockForWrite(); } void unlock() { m_Lock.unlock(); } - void eraseRequest(AcquisitionId id); - std::map::iterator insertRequest(AcquisitionId id, - AcquisitionRequest request); + void eraseAcquisition(AcquisitionId id) + { + auto it = m_Acquisitions.find(id); + if (it != m_Acquisitions.end()) { + // Removes from index + m_AcquisitionsIndex.erase(it->second.m_Variable); - void removeVariableRequest(QUuid vIdentifier); + // Removes request + m_Acquisitions.erase(it); + } + } + + std::map::iterator insertAcquisition(Acquisition acquisition) + { + auto variable = acquisition.m_Variable; + + // Inserts acquisition + auto result + = m_Acquisitions.insert(std::make_pair(acquisition.m_Id, std::move(acquisition))); + if (result.second) { + // Inserts index + m_AcquisitionsIndex[variable] = &result.first->second; + return result.first; + } + else { + return m_Acquisitions.end(); + } + } QMutex m_WorkingMutex; QReadWriteLock m_Lock; - /// Current acquisitions (by variable) - std::map m_Requests; - std::map m_RequestsIndex; + std::map m_Acquisitions; + std::map, Acquisition *> m_AcquisitionsIndex; }; - VariableAcquisitionWorker::VariableAcquisitionWorker(QObject *parent) : QObject{parent}, impl{spimpl::make_unique_impl()} { @@ -57,56 +83,37 @@ VariableAcquisitionWorker::~VariableAcquisitionWorker() this->waitForFinish(); } - -QUuid VariableAcquisitionWorker::pushVariableRequest(QUuid varRequestId, QUuid vIdentifier, - SqpRange rangeRequested, - SqpRange cacheRangeRequested, - DataProviderParameters parameters, - std::shared_ptr provider) +void VariableAcquisitionWorker::pushVariableRequest(std::shared_ptr variable, + VariableRequest request) { - qCDebug(LOG_VariableAcquisitionWorker()) - << tr("TORM VariableAcquisitionWorker::pushVariableRequest ") << cacheRangeRequested; - auto varRequestIdCanceled = QUuid(); - - // Request creation - auto acqRequest = AcquisitionRequest{}; - acqRequest.m_VarRequestId = varRequestId; - acqRequest.m_vIdentifier = vIdentifier; - acqRequest.m_DataProviderParameters = parameters; - acqRequest.m_RangeRequested = rangeRequested; - acqRequest.m_CacheRangeRequested = cacheRangeRequested; - acqRequest.m_Size = parameters.m_Times.size(); - acqRequest.m_Provider = provider; - impl->lockWrite(); - // Checks if there is a current acquisition on variable - auto currentRequestIt = impl->m_RequestsIndex.find(vIdentifier); - if (currentRequestIt != impl->m_RequestsIndex.cend()) { - auto request = currentRequestIt->second; - QtConcurrent::run( - [ provider = request->m_Provider, acqIdentifier = request->m_AcqIdentifier ]() { - provider->requestDataAborting(acqIdentifier); - }); - varRequestIdCanceled = request->m_VarRequestId; - - impl->eraseRequest(request->m_AcqIdentifier); + // Checks if there is a current request for variable + auto oldAcquisitionIt = impl->m_AcquisitionsIndex.find(variable); + if (oldAcquisitionIt != impl->m_AcquisitionsIndex.cend()) { + auto &oldAcquisition = *oldAcquisitionIt->second; + /// @todo ALX + // QtConcurrent::run( + // [ provider = request->m_Provider, acqIdentifier = request->m_AcqIdentifier ]() + // { + // provider->requestDataAborting(acqIdentifier); + // }); + + impl->eraseAcquisition(oldAcquisition.m_Id); } - // Sets the new acquisition request as the current request for the variable - auto newRequestIt = impl->insertRequest(acqRequest.m_AcqIdentifier, std::move(acqRequest)); - if (newRequestIt != impl->m_Requests.end()) { - qCInfo(LOG_VariableAcquisitionWorker()) << "EXECUTE REQUEST" << acqRequest.m_AcqIdentifier; - QMetaObject::invokeMethod(this, "onExecuteRequest", Qt::QueuedConnection, - Q_ARG(QUuid, newRequestIt->first)); + // Sets request for variable + Acquisition newAcquisition{variable, std::move(request)}; + auto newAcquisitionIt = impl->insertAcquisition(std::move(newAcquisition)); + if (newAcquisitionIt != impl->m_Acquisitions.end()) { + impl->unlock(); + + QMetaObject::invokeMethod(this, "executeAcquisition", Qt::QueuedConnection, + Q_ARG(QUuid, newAcquisitionIt->first)); } else { - /// @todo ALX : log + impl->unlock(); } - - impl->unlock(); - - return varRequestIdCanceled; } void VariableAcquisitionWorker::abortProgressRequested(QUuid vIdentifier) @@ -120,27 +127,25 @@ void VariableAcquisitionWorker::onVariableRetrieveDataInProgress(QUuid acqIdenti // TODO } -void VariableAcquisitionWorker::onVariableDataAcquired(QUuid acqIdentifier, - std::shared_ptr dataSeries, - SqpRange dataRangeAcquired) +void VariableAcquisitionWorker::onDataAcquired(QUuid acquisitionId, + std::shared_ptr dataSeries, + SqpRange range) { - qCDebug(LOG_VariableAcquisitionWorker()) - << tr("onVariableDataAcquired on range ") << acqIdentifier << dataRangeAcquired; impl->lockWrite(); - auto it = impl->m_Requests.find(acqIdentifier); - if (it != impl->m_Requests.cend()) { - auto &request = it->second; + auto it = impl->m_Acquisitions.find(acquisitionId); + if (it != impl->m_Acquisitions.cend()) { + auto &acquisition = it->second; + auto &request = acquisition.m_Request; + + qInfo(LOG_VariableAcquisitionWorker()) << "Data acquired for " << printRange(range); // Store the result - auto dataPacket = AcquisitionDataPacket{dataSeries, dataRangeAcquired}; - request.m_DataPackets.push_back(dataPacket); - request.m_Size = request.m_Size - 1; - - if (request.m_Size == 0) { - emit dataProvided(request.m_vIdentifier, request.m_RangeRequested, - request.m_CacheRangeRequested, request.m_DataPackets); - impl->eraseRequest(acqIdentifier); + request.addResult(dataSeries); + + if (request.isFinished()) { + emit dataProvided(acquisition.m_Variable, std::move(request)); + impl->eraseAcquisition(acquisitionId); } } impl->unlock(); @@ -148,8 +153,6 @@ void VariableAcquisitionWorker::onVariableDataAcquired(QUuid acqIdentifier, void VariableAcquisitionWorker::onVariableAcquisitionCanceled(QUuid acqIdentifier) { - impl->lockWrite(); - impl->unlock(); } void VariableAcquisitionWorker::initialize() @@ -170,53 +173,14 @@ void VariableAcquisitionWorker::waitForFinish() QMutexLocker locker{&impl->m_WorkingMutex}; } - -void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::eraseRequest(AcquisitionId id) -{ - auto it = m_Requests.find(id); - if (it != m_Requests.end()) { - // Removes from index - m_RequestsIndex.erase(it->second.m_vIdentifier); - - // Removes request - m_Requests.erase(it); - } -} - -std::map::iterator -VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::insertRequest( - AcquisitionId id, AcquisitionRequest request) -{ - // Inserts request - auto variableId = request.m_vIdentifier; - auto result = m_Requests.insert(std::make_pair(id, std::move(request))); - - if (result.second) { - // Inserts index - m_RequestsIndex[variableId] = &result.first->second; - - return result.first; - } - else { - return m_Requests.end(); - } -} - -void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::removeVariableRequest( - QUuid vIdentifier) -{ - /// @todo ALX - // m_Acquisitions.erase(vIdentifier); -} - -void VariableAcquisitionWorker::onExecuteRequest(QUuid acqIdentifier) +void VariableAcquisitionWorker::executeAcquisition(QUuid acquisitionId) { impl->lockRead(); - auto it = impl->m_Requests.find(acqIdentifier); - if (it != impl->m_Requests.cend()) { - auto &request = it->second; + auto it = impl->m_Acquisitions.find(acquisitionId); + if (it != impl->m_Acquisitions.cend()) { + auto &request = it->second.m_Request; impl->unlock(); - request.m_Provider->requestDataLoading(acqIdentifier, request.m_DataProviderParameters); + request.m_Provider->requestDataLoading(acquisitionId, request.m_ProviderParameters); } else { impl->unlock(); diff --git a/core/src/Variable/VariableController.cpp b/core/src/Variable/VariableController.cpp index 4b961f3..bd61810 100644 --- a/core/src/Variable/VariableController.cpp +++ b/core/src/Variable/VariableController.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include @@ -17,8 +17,6 @@ #include #include -#include -#include #include Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController") @@ -82,6 +80,7 @@ struct VariableController::VariableControllerPrivate { m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}}, m_VariableCacheStrategy{std::make_unique()}, m_VariableAcquisitionWorker{std::make_unique()}, + m_VariableSynchronizer{std::make_unique()}, q{parent} { m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread); @@ -106,219 +105,47 @@ struct VariableController::VariableControllerPrivate { return; } + variable->setRange(rangeRequested); + // Gets ranges in/out of variable range auto requestRange = m_VariableCacheStrategy->computeStrategyRanges(variable->range(), rangeRequested); auto notInCacheRanges = variable->provideNotInCacheRangeList(requestRange.second); - auto inCacheRanges = variable->provideInCacheRangeList(requestRange.second); // Creates request for out-of-cache ranges if (!notInCacheRanges.isEmpty()) { // Gets provider for request if (auto provider = m_Providers.at(variable)) { - VariableRequest request{requestRange.first, requestRange.second}; - // m_VariableAcquisitionWorker->pushVariableRequest(); + DataProviderParameters providerParameters{std::move(notInCacheRanges), + variable->metadata()}; + VariableRequest request{requestRange.first, requestRange.second, provider, + std::move(providerParameters)}; + m_VariableAcquisitionWorker->pushVariableRequest(variable, std::move(request)); } - } - - // Calls UI update for in-cache range - if (!inCacheRanges.isEmpty()) { - emit q->updateVarDisplaying(variable, inCacheRanges.first()); - } - } - std::shared_ptr findVariable(QUuid vIdentifier) - { - /// @todo ALX - std::shared_ptr var; - auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; }; - - auto end = m_VariableToIdentifierMap.cend(); - auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply); - if (it != end) { - var = it->first; + // Calls UI update for in-cache range + auto inCacheRanges = variable->provideInCacheRangeList(requestRange.second); + if (!inCacheRanges.isEmpty()) { + emit q->updateVarDisplaying(variable, inCacheRanges.first()); + } } else { - qCCritical(LOG_VariableController()) - << tr("Impossible to find the variable with the identifier: ") << vIdentifier; - } - - return var; - } - std::shared_ptr - retrieveDataSeries(const QVector acqDataPacketVector) - { - /// @todo ALX - qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size") - << acqDataPacketVector.size(); - std::shared_ptr dataSeries; - if (!acqDataPacketVector.isEmpty()) { - dataSeries = acqDataPacketVector[0].m_DateSeries; - for (int i = 1; i < acqDataPacketVector.size(); ++i) { - dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get()); - } + // No request to make: we simply update variable ranges + variable->setCacheRange(requestRange.second); + emit variable->updated(); } - qCDebug(LOG_VariableController()) - << tr("TORM: retrieveDataSeries acqDataPacketVector size END") - << acqDataPacketVector.size(); - return dataSeries; } void registerProvider(std::shared_ptr provider) { Q_ASSERT(provider != nullptr); connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(), - &VariableAcquisitionWorker::onVariableDataAcquired); + &VariableAcquisitionWorker::onDataAcquired); connect(provider.get(), &IDataProvider::dataProvidedProgress, m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::onVariableRetrieveDataInProgress); } - QUuid acceptVariableRequest(QUuid varId, std::shared_ptr dataSeries) - { - /// @todo ALX - QUuid varRequestId; - // auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId); - // if (varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.cend()) { - // auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second; - // varRequestId = varRequestIdQueue.front(); - // auto varRequestIdToVarIdVarRequestMapIt - // = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId); - // if (varRequestIdToVarIdVarRequestMapIt != - // m_VarRequestIdToVarIdVarRequestMap.cend()) { - // auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second; - // auto varIdToVarRequestMapIt = varIdToVarRequestMap.find(varId); - // if (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) { - // qCDebug(LOG_VariableController()) << tr("acceptVariableRequest"); - // auto &varRequest = varIdToVarRequestMapIt->second; - // varRequest.m_DataSeries = dataSeries; - // varRequest.m_CanUpdate = true; - // } - // else { - // qCDebug(LOG_VariableController()) << tr("Impossible to - // acceptVariableRequest " - // "of a unknown variable id - // attached " - // "to a variableRequestId") - // << varRequestId << varId; - // } - // } - // else { - // qCCritical(LOG_VariableController()) - // << tr("Impossible to acceptVariableRequest of a unknown - // variableRequestId") - // << varRequestId; - // } - - // qCDebug(LOG_VariableController()) - // << tr("1: erase REQUEST in QUEUE ?") << varRequestIdQueue.size(); - // varRequestIdQueue.pop_front(); - // qCDebug(LOG_VariableController()) - // << tr("2: erase REQUEST in QUEUE ?") << varRequestIdQueue.size(); - // if (varRequestIdQueue.empty()) { - // m_VarIdToVarRequestIdQueueMap.erase(varId); - // } - // } - // else { - // qCCritical(LOG_VariableController()) - // << tr("Impossible to acceptVariableRequest of a unknown variable id") << - // varId; - // } - - return varRequestId; - } - void updateVariableRequest(QUuid varRequestId) - { - /// @todo ALX - // auto varRequestIdToVarIdVarRequestMapIt - // = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId); - // if (varRequestIdToVarIdVarRequestMapIt != - // m_VarRequestIdToVarIdVarRequestMap.cend()) { - // bool processVariableUpdate = true; - // auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second; - // for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin(); - // (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) && - // processVariableUpdate; - // ++varIdToVarRequestMapIt) { - // processVariableUpdate &= varIdToVarRequestMapIt->second.m_CanUpdate; - // qCDebug(LOG_VariableController()) - // << tr("updateVariableRequest") << processVariableUpdate; - // } - - // if (processVariableUpdate) { - // for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin(); - // varIdToVarRequestMapIt != varIdToVarRequestMap.cend(); - // ++varIdToVarRequestMapIt) { - // if (auto var = findVariable(varIdToVarRequestMapIt->first)) { - // auto &varRequest = varIdToVarRequestMapIt->second; - // var->setRange(varRequest.m_RangeRequested); - // var->setCacheRange(varRequest.m_CacheRangeRequested); - // qCDebug(LOG_VariableController()) - // << tr("1: onDataProvided") << varRequest.m_RangeRequested; - // qCDebug(LOG_VariableController()) - // << tr("2: onDataProvided") << - // varRequest.m_CacheRangeRequested; - // var->mergeDataSeries(varRequest.m_DataSeries); - // qCDebug(LOG_VariableController()) - // << tr("3: onDataProvided") << - // varRequest.m_DataSeries->range(); - // qCDebug(LOG_VariableController()) << tr("4: onDataProvided"); - - // /// @todo MPL: confirm - // // Variable update is notified only if there is no pending request - // for it - // if - // (m_VarIdToVarRequestIdQueueMap.count(varIdToVarRequestMapIt->first) - // == 0) { - // emit var->updated(); - // } - // } - // else { - // qCCritical(LOG_VariableController()) - // << tr("Impossible to update data to a null variable"); - // } - // } - - // // cleaning varRequestId - // qCDebug(LOG_VariableController()) << tr("0: erase REQUEST in MAP ?") - // << - // m_VarRequestIdToVarIdVarRequestMap.size(); - // m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId); - // qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in MAP ?") - // << - // m_VarRequestIdToVarIdVarRequestMap.size(); - // } - // } - // else { - // qCCritical(LOG_VariableController()) - // << tr("Cannot updateVariableRequest for a unknow varRequestId") << - // varRequestId; - // } - } - - void cancelVariableRequest(QUuid varRequestId) - { - /// @todo ALX - // // cleaning varRequestId - // m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId); - - // for (auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.begin(); - // varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.end();) { - // auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second; - // varRequestIdQueue.erase( - // std::remove(varRequestIdQueue.begin(), varRequestIdQueue.end(), - // varRequestId), - // varRequestIdQueue.end()); - // if (varRequestIdQueue.empty()) { - // varIdToVarRequestIdQueueMapIt - // = m_VarIdToVarRequestIdQueueMap.erase(varIdToVarRequestIdQueueMapIt); - // } - // else { - // ++varIdToVarRequestIdQueueMapIt; - // } - // } - } - QMutex m_WorkingMutex; /// Variable model. The VariableController has the ownership VariableModel *m_VariableModel; @@ -329,11 +156,10 @@ struct VariableController::VariableControllerPrivate { std::unique_ptr m_VariableAcquisitionWorker; QThread m_VariableAcquisitionWorkerThread; + /// Handler for variables synchronization + std::unique_ptr m_VariableSynchronizer; + std::unordered_map, std::shared_ptr > m_Providers; - std::unordered_map, QUuid> m_VariableToIdentifierMap; - std::map > - m_GroupIdToVariableSynchronizationGroupMap; - std::map m_VariableIdGroupIdMap; VariableController *q; }; @@ -394,9 +220,6 @@ VariableController::cloneVariable(std::shared_ptr variable) noexcept // Adds clone to model impl->m_VariableModel->addVariable(duplicate); - // Generates clone identifier - impl->m_VariableToIdentifierMap[duplicate] = QUuid::createUuid(); - // Registers provider auto variableProvider = impl->m_Providers.at(variable); auto duplicateProvider = variableProvider != nullptr ? variableProvider->clone() : nullptr; @@ -427,9 +250,6 @@ void VariableController::deleteVariable(std::shared_ptr variable) noex // make some treatments before the deletion emit variableAboutToBeDeleted(variable); - // Deletes identifier - impl->m_VariableToIdentifierMap.erase(variable); - // Deletes provider auto nbProvidersDeleted = impl->m_Providers.erase(variable); qCDebug(LOG_VariableController()) @@ -466,18 +286,14 @@ VariableController::createVariable(const QString &name, const QVariantHash &meta auto range = impl->m_TimeController->dateTime(); if (auto newVariable = impl->m_VariableModel->createVariable(name, range, metadata)) { - auto identifier = QUuid::createUuid(); - - // store the provider - impl->registerProvider(provider); - // Associate the provider - impl->m_Providers[newVariable] = provider; - impl->m_VariableToIdentifierMap[newVariable] = identifier; + auto newVariableProvider = provider != nullptr ? provider->clone() : nullptr; + impl->m_Providers[newVariable] = newVariableProvider; + if (newVariableProvider) { + impl->registerProvider(newVariableProvider); + } impl->processRequest(newVariable, range); - /// @todo ALX - // impl->updateVariableRequest(varRequestId); return newVariable; } @@ -498,32 +314,34 @@ void VariableController::onDateTimeOnSelection(const SqpRange &dateTime) emit rangeChanged(selectedVariable, dateTime); } } - - /// @todo ALX - // impl->updateVariableRequest(varRequestId); } -void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested, - const SqpRange &cacheRangeRequested, - QVector dataAcquired) +void VariableController::onDataProvided(std::shared_ptr variable, VariableRequest request) { - qCInfo(LOG_VariableController()) << "VariableController::onDataProvided"; - auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired); - auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries); - if (!varRequestId.isNull()) { - impl->updateVariableRequest(varRequestId); + Q_ASSERT(variable != nullptr); + + if (!impl->m_VariableModel->containsVariable(variable)) { + qCCritical(LOG_VariableController()) + << QObject::tr("Can't update date of variable %1: variable is not registered (anymore)") + .arg(variable->name()); + return; } + + variable->setCacheRange(request.m_CacheRangeRequested); + variable->mergeDataSeries(request.m_Result); + emit variable->updated(); } void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress) { - if (auto var = impl->findVariable(identifier)) { - impl->m_VariableModel->setDataProgress(var, progress); - } - else { - qCCritical(LOG_VariableController()) - << tr("Impossible to notify progression of a null variable"); - } + /// @todo ALX + // if (auto var = impl->findVariable(identifier)) { + // impl->m_VariableModel->setDataProgress(var, progress); + // } + // else { + // qCCritical(LOG_VariableController()) + // << tr("Impossible to notify progression of a null variable"); + // } } void VariableController::onAbortProgressRequested(std::shared_ptr variable) @@ -545,145 +363,59 @@ void VariableController::onAbortProgressRequested(std::shared_ptr vari void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId) { - qCDebug(LOG_VariableController()) - << "TORM: VariableController::onAddSynchronizationGroupId" - << QThread::currentThread()->objectName() << synchronizationGroupId; - auto vSynchroGroup = std::make_shared(); - impl->m_GroupIdToVariableSynchronizationGroupMap.insert( - std::make_pair(synchronizationGroupId, vSynchroGroup)); + impl->m_VariableSynchronizer->addGroup(synchronizationGroupId); } void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId) { - impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId); + impl->m_VariableSynchronizer->removeGroup(synchronizationGroupId); } void VariableController::onAddSynchronized(std::shared_ptr variable, QUuid synchronizationGroupId) - { - qCDebug(LOG_VariableController()) - << "TORM: VariableController::onAddSynchronized" << synchronizationGroupId; - auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable); - if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) { - auto groupIdToVSGIt - = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId); - if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) { - impl->m_VariableIdGroupIdMap.insert( - std::make_pair(varToVarIdIt->second, synchronizationGroupId)); - groupIdToVSGIt->second->addVariableId(varToVarIdIt->second); - } - else { - qCCritical(LOG_VariableController()) - << tr("Impossible to synchronize a variable with an unknown sycnhronization group") - << variable->name(); - } - } - else { - qCCritical(LOG_VariableController()) - << tr("Impossible to synchronize a variable with no identifier") << variable->name(); - } + impl->m_VariableSynchronizer->addVariable(variable, synchronizationGroupId); } void VariableController::desynchronize(std::shared_ptr variable, QUuid synchronizationGroupId) { - // Gets variable id - auto variableIt = impl->m_VariableToIdentifierMap.find(variable); - if (variableIt == impl->m_VariableToIdentifierMap.cend()) { - qCCritical(LOG_VariableController()) - << tr("Can't desynchronize variable %1: variable identifier not found") - .arg(variable->name()); - return; - } - - // Gets synchronization group - auto groupIt = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId); - if (groupIt == impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) { - qCCritical(LOG_VariableController()) - << tr("Can't desynchronize variable %1: unknown synchronization group") - .arg(variable->name()); - return; - } - - auto variableId = variableIt->second; - - // Removes variable from synchronization group - auto synchronizationGroup = groupIt->second; - synchronizationGroup->removeVariableId(variableId); - - // Removes link between variable and synchronization group - impl->m_VariableIdGroupIdMap.erase(variableId); + impl->m_VariableSynchronizer->removeVariable(variable, synchronizationGroupId); } -void VariableController::onRequestDataLoading(QVector > variables, +void VariableController::onRequestDataLoading(const QVector > &variables, const SqpRange &range, const SqpRange &oldRange, bool synchronise) { - // NOTE: oldRange isn't really necessary since oldRange == variable->range(). + // Set of variables that have been processed + std::set > processedVariables; + std::map, SqpRange> oldRanges; - // 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. + // Process requests for all variables for (const auto &var : variables) { impl->processRequest(var, range); + processedVariables.insert(var); } + // Handles synchronisation if (synchronise) { - // Get the group ids - qCDebug(LOG_VariableController()) - << "TORM VariableController::onRequestDataLoading for synchro var ENABLE"; - auto groupIds = std::set{}; - auto groupIdToOldRangeMap = std::map{}; - for (const auto &var : variables) { - auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(var); - if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) { - auto vId = varToVarIdIt->second; - auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId); - if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) { - auto gId = varIdToGroupIdIt->second; - groupIdToOldRangeMap.insert(std::make_pair(gId, var->range())); - if (groupIds.find(gId) == groupIds.cend()) { - qCDebug(LOG_VariableController()) << "Synchro detect group " << gId; - groupIds.insert(gId); - } - } - } - } - - // We assume here all group ids exist - for (const auto &gId : groupIds) { - auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId); - auto vSyncIds = vSynchronizationGroup->getIds(); - qCDebug(LOG_VariableController()) << "Var in synchro group "; - for (auto vId : vSyncIds) { - auto var = impl->findVariable(vId); - - // Don't process already processed var - if (!variables.contains(var)) { - if (var != nullptr) { - qCDebug(LOG_VariableController()) - << "processRequest synchro for" << var->name(); - auto vSyncRangeRequested = computeSynchroRangeRequested( - var->range(), range, groupIdToOldRangeMap.at(gId)); - qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested; - impl->processRequest(var, vSyncRangeRequested); - } - else { - qCCritical(LOG_VariableController()) - - << tr("Impossible to synchronize a null variable"); - } + for (const auto &variable : variables) { + // Finds the variables in the same synchronization group + auto synchronizedVariables + = impl->m_VariableSynchronizer->synchronizedVariables(variable); + for (const auto &synchronizedVariable : synchronizedVariables) { + // Processes variable (if it hasn't been already processed) + if (processedVariables.count(synchronizedVariable) == 0) { + auto rangeRequested = computeSynchroRangeRequested( + synchronizedVariable->range(), range, oldRange); + impl->processRequest(synchronizedVariable, rangeRequested); + processedVariables.insert(synchronizedVariable); } } } } - - /// @todo ALX - // impl->updateVariableRequest(varRequestId); } - void VariableController::initialize() { qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread(); diff --git a/core/src/Variable/VariableController.cpp~RF14af5971.TMP b/core/src/Variable/VariableController.cpp~RF14af5971.TMP deleted file mode 100644 index 50b88cc..0000000 --- a/core/src/Variable/VariableController.cpp~RF14af5971.TMP +++ /dev/null @@ -1,775 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include