##// END OF EJS Templates
Merge branch 'feature/AcquisitionV5' into develop
perrinel -
r515:00548e297dac merge
parent child
Show More
@@ -0,0 +1,25
1 #ifndef SCIQLOP_ACQUISITIONDATAPACKET_H
2 #define SCIQLOP_ACQUISITIONDATAPACKET_H
3
4 #include <QObject>
5
6 #include <Common/DateUtils.h>
7 #include <Common/MetaTypes.h>
8 #include <Data/IDataSeries.h>
9 #include <Data/SqpRange.h>
10
11 #include <memory>
12
13 /**
14 * @brief The AcquisitionDataPacket struct holds the information of an acquisition request result
15 * part.
16 */
17 struct AcquisitionDataPacket {
18 std::shared_ptr<IDataSeries> m_DateSeries;
19 SqpRange m_Range;
20 };
21
22 SCIQLOP_REGISTER_META_TYPE(ACQUISITIONDATAPACKET_REGISTRY, AcquisitionDataPacket)
23 SCIQLOP_REGISTER_META_TYPE(ACQUISITIONDATAPACKETVECTOR_REGISTRY, QVector<AcquisitionDataPacket>)
24
25 #endif // SCIQLOP_ACQUISITIONREQUEST_H
@@ -0,0 +1,38
1 #ifndef SCIQLOP_ACQUISITIONREQUEST_H
2 #define SCIQLOP_ACQUISITIONREQUEST_H
3
4 #include <QObject>
5
6 #include <QUuid>
7
8 #include <Common/DateUtils.h>
9 #include <Common/MetaTypes.h>
10 #include <Data/DataProviderParameters.h>
11 #include <Data/IDataProvider.h>
12 #include <Data/SqpRange.h>
13
14 #include <memory>
15
16 /**
17 * @brief The AcquisitionRequest struct holds the information of an acquisition request
18 */
19 struct AcquisitionRequest {
20 AcquisitionRequest()
21 {
22
23 m_AcqIdentifier = QUuid::createUuid();
24 m_Size = 0;
25 }
26
27 QUuid m_AcqIdentifier;
28 QUuid m_vIdentifier;
29 DataProviderParameters m_DataProviderParameters;
30 SqpRange m_RangeRequested;
31 SqpRange m_CacheRangeRequested;
32 int m_Size;
33 std::shared_ptr<IDataProvider> m_Provider;
34 };
35
36 SCIQLOP_REGISTER_META_TYPE(ACQUISITIONREQUEST_REGISTRY, AcquisitionRequest)
37
38 #endif // SCIQLOP_ACQUISITIONREQUEST_H
@@ -0,0 +1,61
1 #ifndef SCIQLOP_VARIABLEACQUISITIONWORKER_H
2 #define SCIQLOP_VARIABLEACQUISITIONWORKER_H
3
4 #include "CoreGlobal.h"
5
6 #include <Data/DataProviderParameters.h>
7 #include <QLoggingCategory>
8 #include <QObject>
9 #include <QUuid>
10
11 #include <Data/AcquisitionDataPacket.h>
12 #include <Data/IDataSeries.h>
13 #include <Data/SqpRange.h>
14
15 #include <QLoggingCategory>
16
17 #include <Common/spimpl.h>
18
19 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableAcquisitionWorker)
20
21 class Variable;
22 class IDataProvider;
23
24 /// This class aims to handle all acquisition request
25 class SCIQLOP_CORE_EXPORT VariableAcquisitionWorker : public QObject {
26 Q_OBJECT
27 public:
28 explicit VariableAcquisitionWorker(QObject *parent = 0);
29 virtual ~VariableAcquisitionWorker();
30
31 void pushVariableRequest(QUuid vIdentifier, SqpRange rangeRequested,
32 SqpRange cacheRangeRequested, DataProviderParameters parameters,
33 std::shared_ptr<IDataProvider> provider);
34
35 void abortProgressRequested(QUuid vIdentifier);
36
37 void initialize();
38 void finalize();
39 signals:
40 void dataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
41 const SqpRange &cacheRangeRequested,
42 QVector<AcquisitionDataPacket> dataAcquired);
43
44 void variableRequestInProgress(QUuid vIdentifier, double progress);
45
46 public slots:
47 void onVariableDataAcquired(QUuid acqIdentifier, std::shared_ptr<IDataSeries> dataSeries,
48 SqpRange dataRangeAcquired);
49 void onVariableRetrieveDataInProgress(QUuid acqIdentifier, double progress);
50
51 private slots:
52 void onExecuteRequest(QUuid acqIdentifier);
53
54 private:
55 void waitForFinish();
56
57 class VariableAcquisitionWorkerPrivate;
58 spimpl::unique_impl_ptr<VariableAcquisitionWorkerPrivate> impl;
59 };
60
61 #endif // SCIQLOP_VARIABLEACQUISITIONWORKER_H
@@ -0,0 +1,40
1 #ifndef SCIQLOP_VARIABLECACHESTRATEGY_H
2 #define SCIQLOP_VARIABLECACHESTRATEGY_H
3
4 #include "CoreGlobal.h"
5
6 #include <QLoggingCategory>
7 #include <QObject>
8
9 #include <Data/SqpRange.h>
10
11 #include <QLoggingCategory>
12
13 #include <Common/spimpl.h>
14 #include <utility>
15
16
17 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableCacheStrategy)
18
19 class Variable;
20
21 /**
22 * Possible types of zoom operation
23 */
24 enum class CacheStrategy { FixedTolerance, TwoThreashold };
25
26 /// This class aims to hande the cache strategy.
27 class SCIQLOP_CORE_EXPORT VariableCacheStrategy : public QObject {
28 Q_OBJECT
29 public:
30 explicit VariableCacheStrategy(QObject *parent = 0);
31
32 std::pair<SqpRange, SqpRange> computeCacheRange(const SqpRange &vRange,
33 const SqpRange &rangeRequested);
34
35 private:
36 class VariableCacheStrategyPrivate;
37 spimpl::unique_impl_ptr<VariableCacheStrategyPrivate> impl;
38 };
39
40 #endif // SCIQLOP_VARIABLECACHESTRATEGY_H
@@ -0,0 +1,38
1 #ifndef SCIQLOP_VARIABLESYNCHRONIZATIONGROUP_H
2 #define SCIQLOP_VARIABLESYNCHRONIZATIONGROUP_H
3
4 #include "CoreGlobal.h"
5
6 #include <QLoggingCategory>
7 #include <QObject>
8 #include <QUuid>
9
10 #include <Data/SqpRange.h>
11
12 #include <set>
13
14 #include <QLoggingCategory>
15
16 #include <Common/spimpl.h>
17
18 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableSynchronizationGroup)
19
20 class Variable;
21
22 /// This class aims to hande the cache strategy.
23 class SCIQLOP_CORE_EXPORT VariableSynchronizationGroup : public QObject {
24 Q_OBJECT
25 public:
26 explicit VariableSynchronizationGroup(QObject *parent = 0);
27
28 void addVariableId(QUuid vIdentifier);
29 void removeVariableId(QUuid vIdentifier);
30
31 const std::set<QUuid> &getIds() const noexcept;
32
33 private:
34 class VariableSynchronizationGroupPrivate;
35 spimpl::unique_impl_ptr<VariableSynchronizationGroupPrivate> impl;
36 };
37
38 #endif // SCIQLOP_VARIABLESYNCHRONIZATIONGROUP_H
@@ -0,0 +1,225
1 #include "Variable/VariableAcquisitionWorker.h"
2
3 #include "Variable/Variable.h"
4
5 #include <Data/AcquisitionRequest.h>
6 #include <Data/SqpRange.h>
7
8 #include <unordered_map>
9 #include <utility>
10
11 #include <QMutex>
12 #include <QReadWriteLock>
13 #include <QThread>
14
15 Q_LOGGING_CATEGORY(LOG_VariableAcquisitionWorker, "VariableAcquisitionWorker")
16
17 struct VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate {
18
19 explicit VariableAcquisitionWorkerPrivate() : m_Lock{QReadWriteLock::Recursive} {}
20
21 void lockRead() { m_Lock.lockForRead(); }
22 void lockWrite() { m_Lock.lockForWrite(); }
23 void unlock() { m_Lock.unlock(); }
24
25 void removeVariableRequest(QUuid vIdentifier);
26
27 QMutex m_WorkingMutex;
28 QReadWriteLock m_Lock;
29
30 std::map<QUuid, QVector<AcquisitionDataPacket> > m_AcqIdentifierToAcqDataPacketVectorMap;
31 std::map<QUuid, AcquisitionRequest> m_AcqIdentifierToAcqRequestMap;
32 std::map<QUuid, std::pair<QUuid, QUuid> > m_VIdentifierToCurrrentAcqIdNextIdPairMap;
33 };
34
35
36 VariableAcquisitionWorker::VariableAcquisitionWorker(QObject *parent)
37 : QObject{parent}, impl{spimpl::make_unique_impl<VariableAcquisitionWorkerPrivate>()}
38 {
39 }
40
41 VariableAcquisitionWorker::~VariableAcquisitionWorker()
42 {
43 qCInfo(LOG_VariableAcquisitionWorker()) << tr("VariableAcquisitionWorker destruction")
44 << QThread::currentThread();
45 this->waitForFinish();
46 }
47
48
49 void VariableAcquisitionWorker::pushVariableRequest(QUuid vIdentifier, SqpRange rangeRequested,
50 SqpRange cacheRangeRequested,
51 DataProviderParameters parameters,
52 std::shared_ptr<IDataProvider> provider)
53 {
54 qCInfo(LOG_VariableAcquisitionWorker())
55 << tr("TORM VariableAcquisitionWorker::pushVariableRequest ") << cacheRangeRequested;
56
57 // Request creation
58 auto acqRequest = AcquisitionRequest{};
59 acqRequest.m_vIdentifier = vIdentifier;
60 acqRequest.m_DataProviderParameters = parameters;
61 acqRequest.m_RangeRequested = rangeRequested;
62 acqRequest.m_CacheRangeRequested = cacheRangeRequested;
63 acqRequest.m_Size = parameters.m_Times.size();
64 acqRequest.m_Provider = provider;
65
66 // Register request
67 impl->lockWrite();
68 impl->m_AcqIdentifierToAcqRequestMap.insert(
69 std::make_pair(acqRequest.m_AcqIdentifier, acqRequest));
70
71 auto it = impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
72 if (it != impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
73 // A current request already exists, we can replace the next one
74 it->second.second = acqRequest.m_AcqIdentifier;
75 impl->unlock();
76 }
77 else {
78 // First request for the variable, it must be stored and executed
79 impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.insert(
80 std::make_pair(vIdentifier, std::make_pair(acqRequest.m_AcqIdentifier, QUuid())));
81 impl->unlock();
82
83 QMetaObject::invokeMethod(this, "onExecuteRequest", Qt::QueuedConnection,
84 Q_ARG(QUuid, acqRequest.m_AcqIdentifier));
85 }
86 }
87
88 void VariableAcquisitionWorker::abortProgressRequested(QUuid vIdentifier)
89 {
90 // TODO
91 }
92
93 void VariableAcquisitionWorker::onVariableRetrieveDataInProgress(QUuid acqIdentifier,
94 double progress)
95 {
96 // TODO
97 }
98
99 void VariableAcquisitionWorker::onVariableDataAcquired(QUuid acqIdentifier,
100 std::shared_ptr<IDataSeries> dataSeries,
101 SqpRange dataRangeAcquired)
102 {
103 qCDebug(LOG_VariableAcquisitionWorker()) << tr("onVariableDataAcquired on range ")
104 << acqIdentifier << dataRangeAcquired;
105 impl->lockWrite();
106 auto aIdToARit = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier);
107 if (aIdToARit != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
108 // Store the result
109 auto dataPacket = AcquisitionDataPacket{};
110 dataPacket.m_Range = dataRangeAcquired;
111 dataPacket.m_DateSeries = dataSeries;
112
113 auto aIdToADPVit = impl->m_AcqIdentifierToAcqDataPacketVectorMap.find(acqIdentifier);
114 if (aIdToADPVit != impl->m_AcqIdentifierToAcqDataPacketVectorMap.cend()) {
115 // A current request result already exists, we can update it
116 aIdToADPVit->second.push_back(dataPacket);
117 }
118 else {
119 // First request result for the variable, it must be stored
120 impl->m_AcqIdentifierToAcqDataPacketVectorMap.insert(
121 std::make_pair(acqIdentifier, QVector<AcquisitionDataPacket>() << dataPacket));
122 }
123
124
125 // Decrement the counter of the request
126 auto &acqRequest = aIdToARit->second;
127 acqRequest.m_Size = acqRequest.m_Size - 1;
128
129 // if the counter is 0, we can return data then run the next request if it exists and
130 // removed the finished request
131 if (acqRequest.m_Size == 0) {
132 // Return the data
133 aIdToADPVit = impl->m_AcqIdentifierToAcqDataPacketVectorMap.find(acqIdentifier);
134 if (aIdToADPVit != impl->m_AcqIdentifierToAcqDataPacketVectorMap.cend()) {
135 emit dataProvided(acqRequest.m_vIdentifier, acqRequest.m_RangeRequested,
136 acqRequest.m_CacheRangeRequested, aIdToADPVit->second);
137 }
138
139 // Execute the next one
140 auto it
141 = impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(acqRequest.m_vIdentifier);
142
143 if (it != impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
144 if (it->second.second.isNull()) {
145 // There is no next request, we can remove the varibale request
146 impl->removeVariableRequest(acqRequest.m_vIdentifier);
147 }
148 else {
149 auto acqIdentifierToRemove = it->second.first;
150 // Move the next request to the current request
151 it->second.first = it->second.second;
152 it->second.second = QUuid();
153 // Remove AcquisitionRequest and results;
154 impl->m_AcqIdentifierToAcqRequestMap.erase(acqIdentifierToRemove);
155 impl->m_AcqIdentifierToAcqDataPacketVectorMap.erase(acqIdentifierToRemove);
156 // Execute the current request
157 QMetaObject::invokeMethod(this, "onExecuteRequest", Qt::QueuedConnection,
158 Q_ARG(QUuid, it->second.first));
159 }
160 }
161 else {
162 qCCritical(LOG_VariableAcquisitionWorker())
163 << tr("Impossible to execute the acquisition on an unfound variable ");
164 }
165 }
166 }
167 else {
168 qCCritical(LOG_VariableAcquisitionWorker())
169 << tr("Impossible to retrieve AcquisitionRequest for the incoming data");
170 }
171 impl->unlock();
172 }
173
174 void VariableAcquisitionWorker::onExecuteRequest(QUuid acqIdentifier)
175 {
176 qCInfo(LOG_VariableAcquisitionWorker()) << tr("onExecuteRequest") << QThread::currentThread();
177 impl->lockRead();
178 auto it = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier);
179 if (it != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
180 auto request = it->second;
181 impl->unlock();
182 request.m_Provider->requestDataLoading(acqIdentifier, request.m_DataProviderParameters);
183 }
184 else {
185 impl->unlock();
186 // TODO log no acqIdentifier recognized
187 }
188 }
189
190 void VariableAcquisitionWorker::initialize()
191 {
192 qCDebug(LOG_VariableAcquisitionWorker()) << tr("VariableAcquisitionWorker init")
193 << QThread::currentThread();
194 impl->m_WorkingMutex.lock();
195 qCDebug(LOG_VariableAcquisitionWorker()) << tr("VariableAcquisitionWorker init END");
196 }
197
198 void VariableAcquisitionWorker::finalize()
199 {
200 impl->m_WorkingMutex.unlock();
201 }
202
203 void VariableAcquisitionWorker::waitForFinish()
204 {
205 QMutexLocker locker{&impl->m_WorkingMutex};
206 }
207
208 void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::removeVariableRequest(
209 QUuid vIdentifier)
210 {
211 lockWrite();
212 auto it = m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
213
214 if (it != m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
215 // A current request already exists, we can replace the next one
216
217 m_AcqIdentifierToAcqRequestMap.erase(it->second.first);
218 m_AcqIdentifierToAcqDataPacketVectorMap.erase(it->second.first);
219
220 m_AcqIdentifierToAcqRequestMap.erase(it->second.second);
221 m_AcqIdentifierToAcqDataPacketVectorMap.erase(it->second.second);
222 }
223 m_VIdentifierToCurrrentAcqIdNextIdPairMap.erase(vIdentifier);
224 unlock();
225 }
@@ -0,0 +1,52
1 #include "Variable/VariableCacheStrategy.h"
2
3 #include "Settings/SqpSettingsDefs.h"
4
5 #include "Variable/Variable.h"
6 #include "Variable/VariableController.h"
7
8 Q_LOGGING_CATEGORY(LOG_VariableCacheStrategy, "VariableCacheStrategy")
9
10 struct VariableCacheStrategy::VariableCacheStrategyPrivate {
11 VariableCacheStrategyPrivate() : m_CacheStrategy{CacheStrategy::FixedTolerance} {}
12
13 CacheStrategy m_CacheStrategy;
14 };
15
16
17 VariableCacheStrategy::VariableCacheStrategy(QObject *parent)
18 : QObject{parent}, impl{spimpl::make_unique_impl<VariableCacheStrategyPrivate>()}
19 {
20 }
21
22 std::pair<SqpRange, SqpRange>
23 VariableCacheStrategy::computeCacheRange(const SqpRange &vRange, const SqpRange &rangeRequested)
24 {
25
26 auto varRanges = std::pair<SqpRange, SqpRange>{};
27
28 auto toleranceFactor = SqpSettings::toleranceValue(GENERAL_TOLERANCE_AT_UPDATE_KEY,
29 GENERAL_TOLERANCE_AT_UPDATE_DEFAULT_VALUE);
30 auto tolerance = toleranceFactor * (rangeRequested.m_TEnd - rangeRequested.m_TStart);
31
32 switch (impl->m_CacheStrategy) {
33 case CacheStrategy::FixedTolerance: {
34 varRanges.first = rangeRequested;
35 varRanges.second
36 = SqpRange{rangeRequested.m_TStart - tolerance, rangeRequested.m_TEnd + tolerance};
37 break;
38 }
39
40 case CacheStrategy::TwoThreashold: {
41 // TODO Implement
42 break;
43 }
44 default:
45 qCCritical(LOG_VariableCacheStrategy())
46 << tr("Impossible to use compute the cache range with an unknow cache strategy");
47 // No action
48 break;
49 }
50
51 return varRanges;
52 }
@@ -0,0 +1,32
1 #include "Variable/VariableSynchronizationGroup.h"
2
3 #include "Variable/Variable.h"
4
5
6 Q_LOGGING_CATEGORY(LOG_VariableSynchronizationGroup, "VariableSynchronizationGroup")
7
8 struct VariableSynchronizationGroup::VariableSynchronizationGroupPrivate {
9
10 std::set<QUuid> m_VariableIdSet;
11 };
12
13
14 VariableSynchronizationGroup::VariableSynchronizationGroup(QObject *parent)
15 : QObject{parent}, impl{spimpl::make_unique_impl<VariableSynchronizationGroupPrivate>()}
16 {
17 }
18
19 void VariableSynchronizationGroup::addVariableId(QUuid vIdentifier)
20 {
21 impl->m_VariableIdSet.insert(vIdentifier);
22 }
23
24 void VariableSynchronizationGroup::removeVariableId(QUuid vIdentifier)
25 {
26 impl->m_VariableIdSet.erase(vIdentifier);
27 }
28
29 const std::set<QUuid> &VariableSynchronizationGroup::getIds() const noexcept
30 {
31 return impl->m_VariableIdSet;
32 }
@@ -43,6 +43,16 public:
43 43 /// @sa IDataSeries::valuesUnit()
44 44 Unit valuesUnit() const override { return m_ValuesUnit; }
45 45
46
47 SqpRange range() const override
48 {
49 if (!m_XAxisData->cdata().isEmpty()) {
50 return SqpRange{m_XAxisData->cdata().first(), m_XAxisData->cdata().last()};
51 }
52
53 return SqpRange{};
54 }
55
46 56 void clear()
47 57 {
48 58 m_XAxisData->clear();
@@ -34,35 +34,37 public:
34 34 virtual ~IDataProvider() noexcept = default;
35 35
36 36 /**
37 * @brief requestDataLoading provide datas for the data identified by identifier and parameters
37 * @brief requestDataLoading provide datas for the data identified by acqIdentifier and
38 * parameters
38 39 */
39 virtual void requestDataLoading(QUuid identifier, const DataProviderParameters &parameters) = 0;
40 virtual void requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters)
41 = 0;
40 42
41 43 /**
42 * @brief requestDataAborting stop data loading of the data identified by identifier
44 * @brief requestDataAborting stop data loading of the data identified by acqIdentifier
43 45 */
44 virtual void requestDataAborting(QUuid identifier) = 0;
46 virtual void requestDataAborting(QUuid acqIdentifier) = 0;
45 47
46 48 signals:
47 49 /**
48 50 * @brief dataProvided send dataSeries under dateTime and that corresponds of the data
49 * identified by identifier
51 * identified by acqIdentifier
50 52 */
51 void dataProvided(QUuid identifier, std::shared_ptr<IDataSeries> dateSerie,
52 const SqpRange &dateTime);
53 void dataProvided(QUuid acqIdentifier, std::shared_ptr<IDataSeries> dateSeriesAcquired,
54 const SqpRange &dataRangeAcquired);
53 55
54 56 /**
55 57 * @brief dataProvided send dataSeries under dateTime and that corresponds of the data
56 58 * identified by identifier
57 59 */
58 void dataProvidedProgress(QUuid identifier, double progress);
60 void dataProvidedProgress(QUuid acqIdentifier, double progress);
59 61
60 62
61 63 /**
62 * @brief requestConstructed send a request for the data identified by identifier
64 * @brief requestConstructed send a request for the data identified by acqIdentifier
63 65 * @callback is the methode call by the reply of the request when it is finished.
64 66 */
65 void requestConstructed(const QNetworkRequest &request, QUuid identifier,
67 void requestConstructed(const QNetworkRequest &request, QUuid acqIdentifier,
66 68 std::function<void(QNetworkReply *, QUuid)> callback);
67 69 };
68 70
@@ -2,6 +2,7
2 2 #define SCIQLOP_IDATASERIES_H
3 3
4 4 #include <Common/MetaTypes.h>
5 #include <Data/SqpRange.h>
5 6
6 7 #include <memory>
7 8
@@ -55,8 +56,10 public:
55 56 virtual Unit valuesUnit() const = 0;
56 57
57 58 virtual void merge(IDataSeries *dataSeries) = 0;
59 virtual std::shared_ptr<IDataSeries> subData(const SqpRange &range) = 0;
58 60
59 61 virtual std::unique_ptr<IDataSeries> clone() const = 0;
62 virtual SqpRange range() const = 0;
60 63
61 64 virtual void lockRead() = 0;
62 65 virtual void lockWrite() = 0;
@@ -19,7 +19,9 public:
19 19 explicit ScalarSeries(QVector<double> xAxisData, QVector<double> valuesData,
20 20 const Unit &xAxisUnit, const Unit &valuesUnit);
21 21
22 std::unique_ptr<IDataSeries> clone() const;
22 std::unique_ptr<IDataSeries> clone() const override;
23
24 std::shared_ptr<IDataSeries> subData(const SqpRange &range) override;
23 25 };
24 26
25 27 #endif // SCIQLOP_SCALARSERIES_H
@@ -9,6 +9,10
9 9 // General settings //
10 10 // //////////////// //
11 11
12
13 struct SCIQLOP_CORE_EXPORT SqpSettings {
14 static double toleranceValue(const QString &key, double defaultValue) noexcept;
15 };
12 16 extern SCIQLOP_CORE_EXPORT const QString GENERAL_TOLERANCE_AT_INIT_KEY;
13 17 extern SCIQLOP_CORE_EXPORT const double GENERAL_TOLERANCE_AT_INIT_DEFAULT_VALUE;
14 18
@@ -28,20 +28,27 public:
28 28 const QVariantHash &metadata = {});
29 29
30 30 QString name() const noexcept;
31 SqpRange dateTime() const noexcept;
32 void setDateTime(const SqpRange &dateTime) noexcept;
31 SqpRange range() const noexcept;
32 void setRange(const SqpRange &range) noexcept;
33 SqpRange cacheRange() const noexcept;
34 void setCacheRange(const SqpRange &cacheRange) noexcept;
33 35
34 36 /// @return the data of the variable, nullptr if there is no data
35 IDataSeries *dataSeries() const noexcept;
37 std::shared_ptr<IDataSeries> dataSeries() const noexcept;
36 38
37 39 QVariantHash metadata() const noexcept;
38 40
39 bool contains(const SqpRange &dateTime) const noexcept;
40 bool intersect(const SqpRange &dateTime) const noexcept;
41 bool isInside(const SqpRange &dateTime) const noexcept;
41 bool contains(const SqpRange &range) const noexcept;
42 bool intersect(const SqpRange &range) const noexcept;
43 bool isInside(const SqpRange &range) const noexcept;
42 44
43 public slots:
45 bool cacheContains(const SqpRange &range) const noexcept;
46 bool cacheIntersect(const SqpRange &range) const noexcept;
47 bool cacheIsInside(const SqpRange &range) const noexcept;
48
49 QVector<SqpRange> provideNotInCacheRangeList(const SqpRange &range) const noexcept;
44 50 void setDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept;
51 void mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept;
45 52
46 53 signals:
47 54 void updated();
@@ -53,5 +60,6 private:
53 60
54 61 // Required for using shared_ptr in signals/slots
55 62 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_REGISTRY, std::shared_ptr<Variable>)
63 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_VECTOR_REGISTRY, QVector<std::shared_ptr<Variable> >)
56 64
57 65 #endif // SCIQLOP_VARIABLE_H
@@ -3,6 +3,7
3 3
4 4 #include "CoreGlobal.h"
5 5
6 #include <Data/AcquisitionDataPacket.h>
6 7 #include <Data/SqpRange.h>
7 8
8 9 #include <QLoggingCategory>
@@ -18,6 +19,13 class VariableModel;
18 19
19 20 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableController)
20 21
22
23 /**
24 * Possible types of zoom operation
25 */
26 enum class AcquisitionZoomType { ZoomOut, ZoomIn, PanRight, PanLeft, Unknown };
27
28
21 29 /**
22 30 * @brief The VariableController class aims to handle the variables in SciQlop.
23 31 */
@@ -57,6 +65,7 public:
57 65 */
58 66 void abortProgress(std::shared_ptr<Variable> variable);
59 67
68 static AcquisitionZoomType getZoomType(const SqpRange &range, const SqpRange &oldRange);
60 69 signals:
61 70 /// Signal emitted when a variable is about to be deleted from the controller
62 71 void variableAboutToBeDeleted(std::shared_ptr<Variable> variable);
@@ -65,8 +74,9 signals:
65 74 void rangeChanged(std::shared_ptr<Variable> variable, const SqpRange &range);
66 75
67 76 public slots:
68 /// Request the data loading of the variable whithin dateTime
69 void onRequestDataLoading(std::shared_ptr<Variable> variable, const SqpRange &dateTime);
77 /// Request the data loading of the variable whithin range
78 void onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables, const SqpRange &range,
79 const SqpRange &oldRange, bool synchronise);
70 80 /**
71 81 * Creates a new variable and adds it to the model
72 82 * @param name the name of the new variable
@@ -80,10 +90,20 public slots:
80 90 void onDateTimeOnSelection(const SqpRange &dateTime);
81 91
82 92
93 void onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
94 const SqpRange &cacheRangeRequested,
95 QVector<AcquisitionDataPacket> dataAcquired);
96
83 97 void onVariableRetrieveDataInProgress(QUuid identifier, double progress);
84 98
99 /// Cancel the current request for the variable
85 100 void onAbortProgressRequested(std::shared_ptr<Variable> variable);
86 101
102 /// synchronization group methods
103 void onAddSynchronizationGroupId(QUuid synchronizationGroupId);
104 void onRemoveSynchronizationGroupId(QUuid synchronizationGroupId);
105 void onAddSynchronized(std::shared_ptr<Variable> variable, QUuid synchronizationGroupId);
106
87 107 void initialize();
88 108 void finalize();
89 109
@@ -11,3 +11,31 std::unique_ptr<IDataSeries> ScalarSeries::clone() const
11 11 {
12 12 return std::make_unique<ScalarSeries>(*this);
13 13 }
14
15 std::shared_ptr<IDataSeries> ScalarSeries::subData(const SqpRange &range)
16 {
17 auto subXAxisData = QVector<double>();
18 auto subValuesData = QVector<double>();
19 this->lockRead();
20 {
21 const auto &currentXData = this->xAxisData()->cdata();
22 const auto &currentValuesData = this->valuesData()->cdata();
23
24 auto xDataBegin = currentXData.cbegin();
25 auto xDataEnd = currentXData.cend();
26
27 auto lowerIt = std::lower_bound(xDataBegin, xDataEnd, range.m_TStart);
28 auto upperIt = std::upper_bound(xDataBegin, xDataEnd, range.m_TEnd);
29 auto distance = std::distance(xDataBegin, lowerIt);
30
31 auto valuesDataIt = currentValuesData.cbegin() + distance;
32 for (auto xAxisDataIt = lowerIt; xAxisDataIt != upperIt; ++xAxisDataIt, ++valuesDataIt) {
33 subXAxisData.append(*xAxisDataIt);
34 subValuesData.append(*valuesDataIt);
35 }
36 }
37 this->unlock();
38
39 return std::make_shared<ScalarSeries>(subXAxisData, subValuesData, this->xAxisUnit(),
40 this->valuesUnit());
41 }
@@ -13,15 +13,16 Q_LOGGING_CATEGORY(LOG_NetworkController, "NetworkController")
13 13
14 14 struct NetworkController::NetworkControllerPrivate {
15 15 explicit NetworkControllerPrivate(NetworkController *parent) : m_WorkingMutex{} {}
16
17 void lockRead() { m_Lock.lockForRead(); }
18 void lockWrite() { m_Lock.lockForWrite(); }
19 void unlock() { m_Lock.unlock(); }
20
16 21 QMutex m_WorkingMutex;
17 22
18 23 QReadWriteLock m_Lock;
19 24 std::unordered_map<QNetworkReply *, QUuid> m_NetworkReplyToVariableId;
20 25 std::unique_ptr<QNetworkAccessManager> m_AccessManager{nullptr};
21
22 void lockRead() { m_Lock.lockForRead(); }
23 void lockWrite() { m_Lock.lockForWrite(); }
24 void unlock() { m_Lock.unlock(); }
25 26 };
26 27
27 28 NetworkController::NetworkController(QObject *parent)
@@ -1,5 +1,16
1 1 #include "Settings/SqpSettingsDefs.h"
2 2
3 #include <QSettings>
4
5
6 /// Gets a tolerance value from application settings. If the setting can't be found, the default
7 /// value passed in parameter is returned
8 double SqpSettings::toleranceValue(const QString &key, double defaultValue) noexcept
9 {
10 return QSettings{}.value(key, defaultValue).toDouble();
11 }
12
13
3 14 const QString GENERAL_TOLERANCE_AT_INIT_KEY = QStringLiteral("toleranceInit");
4 15 const double GENERAL_TOLERANCE_AT_INIT_DEFAULT_VALUE = 0.2;
5 16
@@ -3,6 +3,7
3 3 #include <Data/IDataSeries.h>
4 4 #include <Data/SqpRange.h>
5 5
6 #include <QMutex>
6 7 #include <QReadWriteLock>
7 8 #include <QThread>
8 9
@@ -11,15 +12,22 Q_LOGGING_CATEGORY(LOG_Variable, "Variable")
11 12 struct Variable::VariablePrivate {
12 13 explicit VariablePrivate(const QString &name, const SqpRange &dateTime,
13 14 const QVariantHash &metadata)
14 : m_Name{name}, m_DateTime{dateTime}, m_Metadata{metadata}, m_DataSeries{nullptr}
15 : m_Name{name}, m_Range{dateTime}, m_Metadata{metadata}, m_DataSeries{nullptr}
15 16 {
16 17 }
17 18
19 void lockRead() { m_Lock.lockForRead(); }
20 void lockWrite() { m_Lock.lockForWrite(); }
21 void unlock() { m_Lock.unlock(); }
22
18 23 QString m_Name;
19 24
20 SqpRange m_DateTime; // The dateTime available in the view and loaded. not the cache.
25 SqpRange m_Range;
26 SqpRange m_CacheRange;
21 27 QVariantHash m_Metadata;
22 std::unique_ptr<IDataSeries> m_DataSeries;
28 std::shared_ptr<IDataSeries> m_DataSeries;
29
30 QReadWriteLock m_Lock;
23 31 };
24 32
25 33 Variable::Variable(const QString &name, const SqpRange &dateTime, const QVariantHash &metadata)
@@ -29,58 +37,175 Variable::Variable(const QString &name, const SqpRange &dateTime, const QVariant
29 37
30 38 QString Variable::name() const noexcept
31 39 {
32 return impl->m_Name;
40 impl->lockRead();
41 auto name = impl->m_Name;
42 impl->unlock();
43 return name;
44 }
45
46 SqpRange Variable::range() const noexcept
47 {
48 impl->lockRead();
49 auto range = impl->m_Range;
50 impl->unlock();
51 return range;
33 52 }
34 53
35 SqpRange Variable::dateTime() const noexcept
54 void Variable::setRange(const SqpRange &range) noexcept
36 55 {
37 return impl->m_DateTime;
56 impl->lockWrite();
57 impl->m_Range = range;
58 impl->unlock();
38 59 }
39 60
40 void Variable::setDateTime(const SqpRange &dateTime) noexcept
61 SqpRange Variable::cacheRange() const noexcept
41 62 {
42 impl->m_DateTime = dateTime;
63 impl->lockRead();
64 auto cacheRange = impl->m_CacheRange;
65 impl->unlock();
66 return cacheRange;
67 }
68
69 void Variable::setCacheRange(const SqpRange &cacheRange) noexcept
70 {
71 impl->lockWrite();
72 impl->m_CacheRange = cacheRange;
73 impl->unlock();
43 74 }
44 75
45 76 void Variable::setDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
46 77 {
47 qCDebug(LOG_Variable()) << "Variable::setDataSeries" << QThread::currentThread()->objectName();
78 qCDebug(LOG_Variable()) << "TORM Variable::setDataSeries"
79 << QThread::currentThread()->objectName();
48 80 if (!dataSeries) {
49 81 /// @todo ALX : log
50 82 return;
51 83 }
84 impl->lockWrite();
85 impl->m_DataSeries = dataSeries->clone();
86 impl->unlock();
87 }
52 88
89 void Variable::mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
90 {
91 qCDebug(LOG_Variable()) << "TORM Variable::mergeDataSeries"
92 << QThread::currentThread()->objectName();
93 if (!dataSeries) {
94 /// @todo ALX : log
95 return;
96 }
97
98 // Add or merge the data
53 99 // Inits the data series of the variable
100 impl->lockWrite();
54 101 if (!impl->m_DataSeries) {
55 102 impl->m_DataSeries = dataSeries->clone();
56 103 }
57 104 else {
58 105 impl->m_DataSeries->merge(dataSeries.get());
59 // emit updated();
60 106 }
107 impl->unlock();
108
109 // sub the data
110 auto subData = this->dataSeries()->subData(this->cacheRange());
111 qCDebug(LOG_Variable()) << "TORM: Variable::mergeDataSeries sub" << subData->range();
112 this->setDataSeries(subData);
113 qCDebug(LOG_Variable()) << "TORM: Variable::mergeDataSeries set" << this->dataSeries()->range();
61 114 }
62 115
63 IDataSeries *Variable::dataSeries() const noexcept
116 std::shared_ptr<IDataSeries> Variable::dataSeries() const noexcept
64 117 {
65 return impl->m_DataSeries.get();
118 impl->lockRead();
119 auto dataSeries = impl->m_DataSeries;
120 impl->unlock();
121
122 return dataSeries;
66 123 }
67 124
68 125 QVariantHash Variable::metadata() const noexcept
69 126 {
70 return impl->m_Metadata;
127 impl->lockRead();
128 auto metadata = impl->m_Metadata;
129 impl->unlock();
130 return metadata;
71 131 }
72 132
73 bool Variable::contains(const SqpRange &dateTime) const noexcept
133 bool Variable::contains(const SqpRange &range) const noexcept
74 134 {
75 return impl->m_DateTime.contains(dateTime);
135 impl->lockRead();
136 auto res = impl->m_Range.contains(range);
137 impl->unlock();
138 return res;
76 139 }
77 140
78 bool Variable::intersect(const SqpRange &dateTime) const noexcept
141 bool Variable::intersect(const SqpRange &range) const noexcept
79 142 {
80 return impl->m_DateTime.intersect(dateTime);
143
144 impl->lockRead();
145 auto res = impl->m_Range.intersect(range);
146 impl->unlock();
147 return res;
148 }
149
150 bool Variable::isInside(const SqpRange &range) const noexcept
151 {
152 impl->lockRead();
153 auto res = range.contains(SqpRange{impl->m_Range.m_TStart, impl->m_Range.m_TEnd});
154 impl->unlock();
155 return res;
156 }
157
158 bool Variable::cacheContains(const SqpRange &range) const noexcept
159 {
160 impl->lockRead();
161 auto res = impl->m_CacheRange.contains(range);
162 impl->unlock();
163 return res;
164 }
165
166 bool Variable::cacheIntersect(const SqpRange &range) const noexcept
167 {
168 impl->lockRead();
169 auto res = impl->m_CacheRange.intersect(range);
170 impl->unlock();
171 return res;
172 }
173
174 bool Variable::cacheIsInside(const SqpRange &range) const noexcept
175 {
176 impl->lockRead();
177 auto res = range.contains(SqpRange{impl->m_CacheRange.m_TStart, impl->m_CacheRange.m_TEnd});
178 impl->unlock();
179 return res;
81 180 }
82 181
83 bool Variable::isInside(const SqpRange &dateTime) const noexcept
182
183 QVector<SqpRange> Variable::provideNotInCacheRangeList(const SqpRange &range) const noexcept
84 184 {
85 return dateTime.contains(SqpRange{impl->m_DateTime.m_TStart, impl->m_DateTime.m_TEnd});
185 auto notInCache = QVector<SqpRange>{};
186
187 if (!this->cacheContains(range)) {
188 if (range.m_TEnd <= impl->m_CacheRange.m_TStart
189 || range.m_TStart >= impl->m_CacheRange.m_TEnd) {
190 notInCache << range;
191 }
192 else if (range.m_TStart < impl->m_CacheRange.m_TStart
193 && range.m_TEnd <= impl->m_CacheRange.m_TEnd) {
194 notInCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TStart};
195 }
196 else if (range.m_TStart < impl->m_CacheRange.m_TStart
197 && range.m_TEnd > impl->m_CacheRange.m_TEnd) {
198 notInCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TStart}
199 << SqpRange{impl->m_CacheRange.m_TEnd, range.m_TEnd};
200 }
201 else if (range.m_TStart < impl->m_CacheRange.m_TEnd) {
202 notInCache << SqpRange{impl->m_CacheRange.m_TEnd, range.m_TEnd};
203 }
204 else {
205 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
206 << QThread::currentThread();
207 }
208 }
209
210 return notInCache;
86 211 }
@@ -1,7 +1,10
1 1 #include <Variable/Variable.h>
2 #include <Variable/VariableAcquisitionWorker.h>
2 3 #include <Variable/VariableCacheController.h>
4 #include <Variable/VariableCacheStrategy.h>
3 5 #include <Variable/VariableController.h>
4 6 #include <Variable/VariableModel.h>
7 #include <Variable/VariableSynchronizationGroup.h>
5 8
6 9 #include <Data/DataProviderParameters.h>
7 10 #include <Data/IDataProvider.h>
@@ -13,19 +16,97
13 16 #include <QUuid>
14 17 #include <QtCore/QItemSelectionModel>
15 18
19 #include <set>
16 20 #include <unordered_map>
17 21
18 22 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
19 23
24 namespace {
25
26 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &grapheRange,
27 const SqpRange &oldGraphRange)
28 {
29 auto zoomType = VariableController::getZoomType(grapheRange, oldGraphRange);
30
31 auto varRangeRequested = varRange;
32 switch (zoomType) {
33 case AcquisitionZoomType::ZoomIn: {
34 auto deltaLeft = grapheRange.m_TStart - oldGraphRange.m_TStart;
35 auto deltaRight = oldGraphRange.m_TEnd - grapheRange.m_TEnd;
36 varRangeRequested.m_TStart += deltaLeft;
37 varRangeRequested.m_TEnd -= deltaRight;
38 break;
39 }
40
41 case AcquisitionZoomType::ZoomOut: {
42 auto deltaLeft = oldGraphRange.m_TStart - grapheRange.m_TStart;
43 auto deltaRight = grapheRange.m_TEnd - oldGraphRange.m_TEnd;
44 varRangeRequested.m_TStart -= deltaLeft;
45 varRangeRequested.m_TEnd += deltaRight;
46 break;
47 }
48 case AcquisitionZoomType::PanRight: {
49 auto deltaRight = grapheRange.m_TEnd - oldGraphRange.m_TEnd;
50 varRangeRequested.m_TStart += deltaRight;
51 varRangeRequested.m_TEnd += deltaRight;
52 break;
53 }
54 case AcquisitionZoomType::PanLeft: {
55 auto deltaLeft = oldGraphRange.m_TStart - grapheRange.m_TStart;
56 varRangeRequested.m_TStart -= deltaLeft;
57 varRangeRequested.m_TEnd -= deltaLeft;
58 break;
59 }
60 case AcquisitionZoomType::Unknown: {
61 qCCritical(LOG_VariableController())
62 << VariableController::tr("Impossible to synchronize: zoom type unknown");
63 break;
64 }
65 default:
66 qCCritical(LOG_VariableController()) << VariableController::tr(
67 "Impossible to synchronize: zoom type not take into account");
68 // No action
69 break;
70 }
71
72 return varRangeRequested;
73 }
74 }
75
20 76 struct VariableController::VariableControllerPrivate {
21 77 explicit VariableControllerPrivate(VariableController *parent)
22 78 : m_WorkingMutex{},
23 79 m_VariableModel{new VariableModel{parent}},
24 80 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
25 m_VariableCacheController{std::make_unique<VariableCacheController>()}
81 m_VariableCacheController{std::make_unique<VariableCacheController>()},
82 m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
83 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()}
84 {
85
86 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
87 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
88 }
89
90
91 virtual ~VariableControllerPrivate()
26 92 {
93 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
94 m_VariableAcquisitionWorkerThread.quit();
95 m_VariableAcquisitionWorkerThread.wait();
27 96 }
28 97
98
99 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested);
100
101 QVector<SqpRange> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
102 const SqpRange &dateTime);
103
104 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
105 std::shared_ptr<IDataSeries>
106 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
107
108 void registerProvider(std::shared_ptr<IDataProvider> provider);
109
29 110 QMutex m_WorkingMutex;
30 111 /// Variable model. The VariableController has the ownership
31 112 VariableModel *m_VariableModel;
@@ -34,12 +115,20 struct VariableController::VariableControllerPrivate {
34 115
35 116 TimeController *m_TimeController{nullptr};
36 117 std::unique_ptr<VariableCacheController> m_VariableCacheController;
118 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
119 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
120 QThread m_VariableAcquisitionWorkerThread;
37 121
38 122 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
39 123 m_VariableToProviderMap;
40 124 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
125 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
126 m_GroupIdToVariableSynchronizationGroupMap;
127 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
128 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
41 129 };
42 130
131
43 132 VariableController::VariableController(QObject *parent)
44 133 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
45 134 {
@@ -48,6 +137,20 VariableController::VariableController(QObject *parent)
48 137
49 138 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
50 139 &VariableController::onAbortProgressRequested);
140
141 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
142 &VariableController::onDataProvided);
143 connect(impl->m_VariableAcquisitionWorker.get(),
144 &VariableAcquisitionWorker::variableRequestInProgress, this,
145 &VariableController::onVariableRetrieveDataInProgress);
146
147 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
148 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
149 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
150 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
151
152
153 impl->m_VariableAcquisitionWorkerThread.start();
51 154 }
52 155
53 156 VariableController::~VariableController()
@@ -121,45 +224,34 void VariableController::createVariable(const QString &name, const QVariantHash
121 224 return;
122 225 }
123 226
124 auto dateTime = impl->m_TimeController->dateTime();
227 auto range = impl->m_TimeController->dateTime();
125 228
126 if (auto newVariable = impl->m_VariableModel->createVariable(name, dateTime, metadata)) {
229 if (auto newVariable = impl->m_VariableModel->createVariable(name, range, metadata)) {
127 230 auto identifier = QUuid::createUuid();
128 231
129 232 // store the provider
233 impl->registerProvider(provider);
234
235 // Associate the provider
130 236 impl->m_VariableToProviderMap[newVariable] = provider;
131 237 impl->m_VariableToIdentifierMap[newVariable] = identifier;
132 238
133 auto addDateTimeAcquired = [ this, varW = std::weak_ptr<Variable>{newVariable} ](
134 QUuid identifier, auto dataSeriesAcquired, auto dateTimeToPutInCache)
135 {
136 if (auto variable = varW.lock()) {
137 auto varIdentifier = impl->m_VariableToIdentifierMap.at(variable);
138 if (varIdentifier == identifier) {
139 impl->m_VariableCacheController->addDateTime(variable, dateTimeToPutInCache);
140 variable->setDataSeries(dataSeriesAcquired);
141 emit variable->updated();
142 }
143 }
144 };
145 239
146 connect(provider.get(), &IDataProvider::dataProvided, addDateTimeAcquired);
147 connect(provider.get(), &IDataProvider::dataProvidedProgress, this,
148 &VariableController::onVariableRetrieveDataInProgress);
149 this->onRequestDataLoading(newVariable, dateTime);
240 impl->processRequest(newVariable, range);
150 241 }
151 242 }
152 243
153 244 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
154 245 {
246 // TODO check synchronisation
155 247 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
156 248 << QThread::currentThread()->objectName();
157 249 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
158 250
159 251 for (const auto &selectedRow : qAsConst(selectedRows)) {
160 252 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
161 selectedVariable->setDateTime(dateTime);
162 this->onRequestDataLoading(selectedVariable, dateTime);
253 selectedVariable->setRange(dateTime);
254 impl->processRequest(selectedVariable, dateTime);
163 255
164 256 // notify that rescale operation has to be done
165 257 emit rangeChanged(selectedVariable, dateTime);
@@ -167,14 +259,38 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
167 259 }
168 260 }
169 261
170 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
262 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
263 const SqpRange &cacheRangeRequested,
264 QVector<AcquisitionDataPacket> dataAcquired)
171 265 {
172 auto findReply = [identifier](const auto &entry) { return identifier == entry.second; };
266 auto var = impl->findVariable(vIdentifier);
267 if (var != nullptr) {
268 var->setRange(rangeRequested);
269 var->setCacheRange(cacheRangeRequested);
270 qCDebug(LOG_VariableController()) << tr("1: onDataProvided") << rangeRequested;
271 qCDebug(LOG_VariableController()) << tr("2: onDataProvided") << cacheRangeRequested;
272
273 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
274 qCDebug(LOG_VariableController()) << tr("3: onDataProvided")
275 << retrievedDataSeries->range();
276 var->mergeDataSeries(retrievedDataSeries);
277 qCDebug(LOG_VariableController()) << tr("4: onDataProvided");
278 emit var->updated();
279 }
280 else {
281 qCCritical(LOG_VariableController()) << tr("Impossible to provide data to a null variable");
282 }
283 }
173 284
174 auto end = impl->m_VariableToIdentifierMap.cend();
175 auto it = std::find_if(impl->m_VariableToIdentifierMap.cbegin(), end, findReply);
176 if (it != end) {
177 impl->m_VariableModel->setDataProgress(it->first, progress);
285 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
286 {
287 auto var = impl->findVariable(identifier);
288 if (var != nullptr) {
289 impl->m_VariableModel->setDataProgress(var, progress);
290 }
291 else {
292 qCCritical(LOG_VariableController())
293 << tr("Impossible to notify progression of a null variable");
178 294 }
179 295 }
180 296
@@ -194,33 +310,111 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> vari
194 310 }
195 311 }
196 312
313 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
314 {
315 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
316 << QThread::currentThread()->objectName()
317 << synchronizationGroupId;
318 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
319 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
320 std::make_pair(synchronizationGroupId, vSynchroGroup));
321 }
197 322
198 void VariableController::onRequestDataLoading(std::shared_ptr<Variable> variable,
199 const SqpRange &dateTime)
323 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
200 324 {
201 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
202 << QThread::currentThread()->objectName();
203 // we want to load data of the variable for the dateTime.
204 // First we check if the cache contains some of them.
205 // For the other, we ask the provider to give them.
206 if (variable) {
325 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
326 }
207 327
208 auto dateTimeListNotInCache
209 = impl->m_VariableCacheController->provideNotInCacheDateTimeList(variable, dateTime);
328 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
329 QUuid synchronizationGroupId)
210 330
211 if (!dateTimeListNotInCache.empty()) {
212 // Ask the provider for each data on the dateTimeListNotInCache
213 auto identifier = impl->m_VariableToIdentifierMap.at(variable);
214 impl->m_VariableToProviderMap.at(variable)->requestDataLoading(
215 identifier,
216 DataProviderParameters{std::move(dateTimeListNotInCache), variable->metadata()});
331 {
332 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
333 << synchronizationGroupId;
334 auto vToVIdit = impl->m_VariableToIdentifierMap.find(variable);
335 if (vToVIdit != impl->m_VariableToIdentifierMap.cend()) {
336 auto itSynchroGroup
337 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
338 if (itSynchroGroup != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
339 impl->m_VariableIdGroupIdMap.insert(
340 std::make_pair(vToVIdit->second, synchronizationGroupId));
341 itSynchroGroup->second->addVariableId(vToVIdit->second);
217 342 }
218 343 else {
219 emit variable->updated();
344 qCCritical(LOG_VariableController())
345 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
346 << variable->name();
220 347 }
221 348 }
222 349 else {
223 qCCritical(LOG_VariableController()) << tr("Impossible to load data of a variable null");
350 qCCritical(LOG_VariableController())
351 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
352 }
353 }
354
355
356 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
357 const SqpRange &range, const SqpRange &oldRange,
358 bool synchronise)
359 {
360 // NOTE: oldRange isn't really necessary since oldRange == variable->range().
361
362 qCInfo(LOG_VariableController()) << "VariableController::onRequestDataLoading"
363 << QThread::currentThread()->objectName();
364 // we want to load data of the variable for the dateTime.
365 // First we check if the cache contains some of them.
366 // For the other, we ask the provider to give them.
367
368 foreach (auto var, variables) {
369 qCDebug(LOG_VariableController()) << "processRequest for" << var->name();
370 impl->processRequest(var, range);
371 }
372
373 if (synchronise) {
374 // Get the group ids
375 qCDebug(LOG_VariableController())
376 << "VariableController::onRequestDataLoading for synchro var ENABLE";
377 auto groupIds = std::set<QUuid>();
378 foreach (auto var, variables) {
379 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(var);
380 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
381 auto vId = varToVarIdIt->second;
382 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
383 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
384 auto gId = varIdToGroupIdIt->second;
385 if (groupIds.find(gId) == groupIds.cend()) {
386 qCDebug(LOG_VariableController()) << "Synchro detect group " << gId;
387 groupIds.insert(gId);
388 }
389 }
390 }
391 }
392
393 // We assume here all group ids exist
394 foreach (auto gId, groupIds) {
395 auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId);
396 auto vSyncIds = vSynchronizationGroup->getIds();
397 qCDebug(LOG_VariableController()) << "Var in synchro group ";
398 for (auto vId : vSyncIds) {
399 auto var = impl->findVariable(vId);
400
401 // Don't process already processed var
402 if (!variables.contains(var)) {
403 if (var != nullptr) {
404 qCDebug(LOG_VariableController()) << "processRequest synchro for"
405 << var->name();
406 auto vSyncRangeRequested
407 = computeSynchroRangeRequested(var->range(), range, oldRange);
408 impl->processRequest(var, vSyncRangeRequested);
409 }
410 else {
411 qCCritical(LOG_VariableController())
412
413 << tr("Impossible to synchronize a null variable");
414 }
415 }
416 }
417 }
224 418 }
225 419 }
226 420
@@ -241,3 +435,109 void VariableController::waitForFinish()
241 435 {
242 436 QMutexLocker locker{&impl->m_WorkingMutex};
243 437 }
438
439 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
440 {
441 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
442 auto zoomType = AcquisitionZoomType::Unknown;
443 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
444 zoomType = AcquisitionZoomType::ZoomOut;
445 }
446 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
447 zoomType = AcquisitionZoomType::PanRight;
448 }
449 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
450 zoomType = AcquisitionZoomType::PanLeft;
451 }
452 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
453 zoomType = AcquisitionZoomType::ZoomIn;
454 }
455 else {
456 qCCritical(LOG_VariableController()) << "getZoomType: Unknown type detected";
457 }
458 return zoomType;
459 }
460
461 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
462 const SqpRange &rangeRequested)
463 {
464
465 auto varRangesRequested
466 = m_VariableCacheStrategy->computeCacheRange(var->range(), rangeRequested);
467 auto notInCacheRangeList = var->provideNotInCacheRangeList(varRangesRequested.second);
468
469 if (!notInCacheRangeList.empty()) {
470 auto identifier = m_VariableToIdentifierMap.at(var);
471 auto varProvider = m_VariableToProviderMap.at(var);
472 if (varProvider != nullptr) {
473 m_VariableAcquisitionWorker->pushVariableRequest(
474 identifier, varRangesRequested.first, varRangesRequested.second,
475 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
476 varProvider);
477 }
478 else {
479 qCCritical(LOG_VariableController())
480 << "Impossible to provide data with a null provider";
481 }
482 }
483 else {
484 var->setRange(rangeRequested);
485 var->setCacheRange(varRangesRequested.second);
486 var->setDataSeries(var->dataSeries()->subData(varRangesRequested.second));
487 emit var->updated();
488 }
489 }
490
491 std::shared_ptr<Variable>
492 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
493 {
494 std::shared_ptr<Variable> var;
495 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
496
497 auto end = m_VariableToIdentifierMap.cend();
498 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
499 if (it != end) {
500 var = it->first;
501 }
502 else {
503 qCCritical(LOG_VariableController())
504 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
505 }
506
507 return var;
508 }
509
510 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
511 const QVector<AcquisitionDataPacket> acqDataPacketVector)
512 {
513 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
514 << acqDataPacketVector.size();
515 std::shared_ptr<IDataSeries> dataSeries;
516 if (!acqDataPacketVector.isEmpty()) {
517 dataSeries = acqDataPacketVector[0].m_DateSeries;
518 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
519 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
520 }
521 }
522 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
523 << acqDataPacketVector.size();
524 return dataSeries;
525 }
526
527 void VariableController::VariableControllerPrivate::registerProvider(
528 std::shared_ptr<IDataProvider> provider)
529 {
530 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
531 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
532 << provider->objectName();
533 m_ProviderSet.insert(provider);
534 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
535 &VariableAcquisitionWorker::onVariableDataAcquired);
536 connect(provider.get(), &IDataProvider::dataProvidedProgress,
537 m_VariableAcquisitionWorker.get(),
538 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
539 }
540 else {
541 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
542 }
543 }
@@ -160,9 +160,9 QVariant VariableModel::data(const QModelIndex &index, int role) const
160 160 case NAME_COLUMN:
161 161 return variable->name();
162 162 case TSTART_COLUMN:
163 return dateTimeVariant(variable->dateTime().m_TStart);
163 return dateTimeVariant(variable->range().m_TStart);
164 164 case TEND_COLUMN:
165 return dateTimeVariant(variable->dateTime().m_TEnd);
165 return dateTimeVariant(variable->range().m_TEnd);
166 166 default:
167 167 // No action
168 168 break;
@@ -64,8 +64,8 void TestOneDimArrayData::testDataByComponentIndex_data()
64 64 // Test cases
65 65 QTest::newRow("validIndex") << QVector<double>{1., 2., 3., 4., 5.} << 0
66 66 << QVector<double>{1., 2., 3., 4., 5.};
67 QTest::newRow("invalidIndex1")
68 << QVector<double>{1., 2., 3., 4., 5.} << -1 << QVector<double>{};
67 QTest::newRow("invalidIndex1") << QVector<double>{1., 2., 3., 4., 5.} << -1
68 << QVector<double>{};
69 69 QTest::newRow("invalidIndex2") << QVector<double>{1., 2., 3., 4., 5.} << 1 << QVector<double>{};
70 70 }
71 71
@@ -75,8 +75,8 void TestTwoDimArrayData::testCtor_data()
75 75 QTest::newRow("malformedInput (components of the array data haven't the same size")
76 76 << DataContainer{{1., 2., 3., 4., 5.}, {6., 7., 8.}, {11., 12.}} << true
77 77 << DataContainer{{}, {}, {}};
78 QTest::newRow("invalidInput (less than tow components")
79 << DataContainer{{1., 2., 3., 4., 5.}} << false << DataContainer{{}, {}, {}};
78 QTest::newRow("invalidInput (less than tow components") << DataContainer{{1., 2., 3., 4., 5.}}
79 << false << DataContainer{{}, {}, {}};
80 80 }
81 81
82 82 void TestTwoDimArrayData::testCtor()
@@ -31,8 +31,8 struct VisualizationGraphHelper {
31 31 static QVector<QCPAbstractPlottable *> create(std::shared_ptr<Variable> variable,
32 32 QCustomPlot &plot) noexcept;
33 33
34 static void updateData(QVector<QCPAbstractPlottable *> plotableVect, IDataSeries *dataSeries,
35 const SqpRange &dateTime);
34 static void updateData(QVector<QCPAbstractPlottable *> plotableVect,
35 std::shared_ptr<IDataSeries> dataSeries, const SqpRange &dateTime);
36 36 };
37 37
38 38 #endif // SCIQLOP_VISUALIZATIONGRAPHHELPER_H
@@ -16,11 +16,6 class QCPRange;
16 16 class SqpRange;
17 17 class Variable;
18 18
19 /**
20 * Possible types of zoom operation
21 */
22 enum class VisualizationGraphWidgetZoomType { ZoomOut, ZoomIn, PanRight, PanLeft, Unknown };
23
24 19 namespace Ui {
25 20 class VisualizationGraphWidget;
26 21 } // namespace Ui
@@ -32,7 +27,8 public:
32 27 explicit VisualizationGraphWidget(const QString &name = {}, QWidget *parent = 0);
33 28 virtual ~VisualizationGraphWidget();
34 29
35 void enableSynchronize(bool enable);
30 /// If acquisition isn't enable, requestDataLoading signal cannot be emit
31 void enableAcquisition(bool enable);
36 32
37 33 void addVariable(std::shared_ptr<Variable> variable);
38 34 void addVariableUsingGraph(std::shared_ptr<Variable> variable);
@@ -51,9 +47,12 public:
51 47
52 48
53 49 signals:
54 void requestDataLoading(std::shared_ptr<Variable> variable, const SqpRange &dateTime);
55 void synchronize(const SqpRange &dateTime, const SqpRange &oldDateTime,
56 VisualizationGraphWidgetZoomType zoomType);
50 void synchronize(const SqpRange &range, const SqpRange &oldRange);
51 void requestDataLoading(QVector<std::shared_ptr<Variable> > variable, const SqpRange &range,
52 const SqpRange &oldRange, bool synchronise);
53
54
55 void variableAdded(std::shared_ptr<Variable> var);
57 56
58 57
59 58 private:
@@ -6,6 +6,10
6 6 #include <QLoggingCategory>
7 7 #include <QWidget>
8 8
9 #include <memory>
10
11 #include <Common/spimpl.h>
12
9 13 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationZoneWidget)
10 14
11 15 namespace Ui {
@@ -38,8 +42,15 public:
38 42 bool contains(const Variable &variable) const override;
39 43 QString name() const override;
40 44
45
46 private slots:
47 void onVariableAdded(std::shared_ptr<Variable> variable);
48
41 49 private:
42 50 Ui::VisualizationZoneWidget *ui;
51
52 class VisualizationZoneWidgetPrivate;
53 spimpl::unique_impl_ptr<VisualizationZoneWidgetPrivate> impl;
43 54 };
44 55
45 56 #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H
@@ -60,7 +60,7 public:
60 60
61 61 virtual ~SqpApplicationPrivate()
62 62 {
63 qCInfo(LOG_SqpApplication()) << tr("SqpApplicationPrivate destruction");
63 qCDebug(LOG_SqpApplication()) << tr("SqpApplicationPrivate destruction");
64 64 m_DataSourceControllerThread.quit();
65 65 m_DataSourceControllerThread.wait();
66 66
@@ -35,21 +35,21 QSharedPointer<QCPAxisTicker> axisTicker(bool isTimeAxis)
35 35 }
36 36 }
37 37
38 void updateScalarData(QCPAbstractPlottable *component, ScalarSeries &scalarSeries,
38 void updateScalarData(QCPAbstractPlottable *component, std::shared_ptr<ScalarSeries> scalarSeries,
39 39 const SqpRange &dateTime)
40 40 {
41 41 qCDebug(LOG_VisualizationGraphHelper()) << "TORM: updateScalarData"
42 42 << QThread::currentThread()->objectName();
43 43 if (auto qcpGraph = dynamic_cast<QCPGraph *>(component)) {
44 scalarSeries.lockRead();
44 scalarSeries->lockRead();
45 45 {
46 const auto &xData = scalarSeries.xAxisData()->cdata();
47 const auto &valuesData = scalarSeries.valuesData()->cdata();
46 const auto &xData = scalarSeries->xAxisData()->cdata();
47 const auto &valuesData = scalarSeries->valuesData()->cdata();
48 48
49 49 auto xDataBegin = xData.cbegin();
50 50 auto xDataEnd = xData.cend();
51 51
52 qCInfo(LOG_VisualizationGraphHelper()) << "TORM: Current points in cache"
52 qCInfo(LOG_VisualizationGraphHelper()) << "TODEBUG: Current points in cache"
53 53 << xData.count();
54 54
55 55 auto sqpDataContainer = QSharedPointer<SqpDataContainer>::create();
@@ -65,10 +65,10 void updateScalarData(QCPAbstractPlottable *component, ScalarSeries &scalarSerie
65 65 sqpDataContainer->appendGraphData(QCPGraphData(*xAxisDataIt, *valuesDataIt));
66 66 }
67 67
68 qCInfo(LOG_VisualizationGraphHelper()) << "TORM: Current points displayed"
68 qCInfo(LOG_VisualizationGraphHelper()) << "TODEBUG: Current points displayed"
69 69 << sqpDataContainer->size();
70 70 }
71 scalarSeries.unlock();
71 scalarSeries->unlock();
72 72
73 73
74 74 // Display all data
@@ -79,14 +79,14 void updateScalarData(QCPAbstractPlottable *component, ScalarSeries &scalarSerie
79 79 }
80 80 }
81 81
82 QCPAbstractPlottable *createScalarSeriesComponent(ScalarSeries &scalarSeries, QCustomPlot &plot,
83 const SqpRange &dateTime)
82 QCPAbstractPlottable *createScalarSeriesComponent(std::shared_ptr<ScalarSeries> scalarSeries,
83 QCustomPlot &plot, const SqpRange &dateTime)
84 84 {
85 85 auto component = plot.addGraph();
86 86
87 87 if (component) {
88 88 // // Graph data
89 component->setData(scalarSeries.xAxisData()->data(), scalarSeries.valuesData()->data(),
89 component->setData(scalarSeries->xAxisData()->data(), scalarSeries->valuesData()->data(),
90 90 true);
91 91
92 92 updateScalarData(component, scalarSeries, dateTime);
@@ -102,8 +102,8 QCPAbstractPlottable *createScalarSeriesComponent(ScalarSeries &scalarSeries, QC
102 102 // ticker (depending on the type of unit)
103 103 axis->setTicker(axisTicker(unit.m_TimeUnit));
104 104 };
105 setAxisProperties(plot.xAxis, scalarSeries.xAxisUnit());
106 setAxisProperties(plot.yAxis, scalarSeries.valuesUnit());
105 setAxisProperties(plot.xAxis, scalarSeries->xAxisUnit());
106 setAxisProperties(plot.yAxis, scalarSeries->valuesUnit());
107 107
108 108 // Display all data
109 109 component->rescaleAxes();
@@ -127,8 +127,8 QVector<QCPAbstractPlottable *> VisualizationGraphHelper::create(std::shared_ptr
127 127 if (variable) {
128 128 // Gets the data series of the variable to call the creation of the right components
129 129 // according to its type
130 if (auto scalarSeries = dynamic_cast<ScalarSeries *>(variable->dataSeries())) {
131 result.append(createScalarSeriesComponent(*scalarSeries, plot, variable->dateTime()));
130 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(variable->dataSeries())) {
131 result.append(createScalarSeriesComponent(scalarSeries, plot, variable->range()));
132 132 }
133 133 else {
134 134 qCDebug(LOG_VisualizationGraphHelper())
@@ -144,11 +144,12 QVector<QCPAbstractPlottable *> VisualizationGraphHelper::create(std::shared_ptr
144 144 }
145 145
146 146 void VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *> plotableVect,
147 IDataSeries *dataSeries, const SqpRange &dateTime)
147 std::shared_ptr<IDataSeries> dataSeries,
148 const SqpRange &dateTime)
148 149 {
149 if (auto scalarSeries = dynamic_cast<ScalarSeries *>(dataSeries)) {
150 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(dataSeries)) {
150 151 if (plotableVect.size() == 1) {
151 updateScalarData(plotableVect.at(0), *scalarSeries, dateTime);
152 updateScalarData(plotableVect.at(0), scalarSeries, dateTime);
152 153 }
153 154 else {
154 155 qCCritical(LOG_VisualizationGraphHelper()) << QObject::tr(
@@ -23,28 +23,18 const auto HORIZONTAL_ZOOM_MODIFIER = Qt::NoModifier;
23 23 /// Key pressed to enable zoom on vertical axis
24 24 const auto VERTICAL_ZOOM_MODIFIER = Qt::ControlModifier;
25 25
26 /// Gets a tolerance value from application settings. If the setting can't be found, the default
27 /// value passed in parameter is returned
28 double toleranceValue(const QString &key, double defaultValue) noexcept
29 {
30 return QSettings{}.value(key, defaultValue).toDouble();
31 }
32
33 26 } // namespace
34 27
35 28 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
36 29
37 30 explicit VisualizationGraphWidgetPrivate()
38 : m_DoSynchronize{true}, m_IsCalibration{false}, m_RenderingDelegate{nullptr}
31 : m_DoAcquisition{true}, m_IsCalibration{false}, m_RenderingDelegate{nullptr}
39 32 {
40 33 }
41 34
42 // Return the operation when range changed
43 VisualizationGraphWidgetZoomType getZoomType(const QCPRange &t1, const QCPRange &t2);
44
45 35 // 1 variable -> n qcpplot
46 36 std::multimap<std::shared_ptr<Variable>, QCPAbstractPlottable *> m_VariableToPlotMultiMap;
47 bool m_DoSynchronize;
37 bool m_DoAcquisition;
48 38 bool m_IsCalibration;
49 39 QCPItemTracer *m_TextTracer;
50 40 /// Delegate used to attach rendering features to the plot
@@ -98,50 +88,37 VisualizationGraphWidget::~VisualizationGraphWidget()
98 88 delete ui;
99 89 }
100 90
101 void VisualizationGraphWidget::enableSynchronize(bool enable)
91 void VisualizationGraphWidget::enableAcquisition(bool enable)
102 92 {
103 impl->m_DoSynchronize = enable;
93 impl->m_DoAcquisition = enable;
104 94 }
105 95
106 96 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable)
107 97 {
98 auto calibrationState = impl->m_IsCalibration;
99 impl->m_IsCalibration = true;
108 100 // Uses delegate to create the qcpplot components according to the variable
109 101 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
102 impl->m_IsCalibration = calibrationState;
110 103
111 104 for (auto createdPlottable : qAsConst(createdPlottables)) {
112 105 impl->m_VariableToPlotMultiMap.insert({variable, createdPlottable});
113 106 }
114 107
115 108 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
109
110 emit variableAdded(variable);
116 111 }
117 112 void VisualizationGraphWidget::addVariableUsingGraph(std::shared_ptr<Variable> variable)
118 113 {
119
120 // when adding a variable, we need to set its time range to the current graph range
121 auto grapheRange = ui->widget->xAxis->range();
122 auto dateTime = SqpRange{grapheRange.lower, grapheRange.upper};
123 variable->setDateTime(dateTime);
124
125 auto variableDateTimeWithTolerance = dateTime;
126
127 // add tolerance for each side
128 auto toleranceFactor
129 = toleranceValue(GENERAL_TOLERANCE_AT_INIT_KEY, GENERAL_TOLERANCE_AT_INIT_DEFAULT_VALUE);
130 auto tolerance = toleranceFactor * (dateTime.m_TEnd - dateTime.m_TStart);
131 variableDateTimeWithTolerance.m_TStart -= tolerance;
132 variableDateTimeWithTolerance.m_TEnd += tolerance;
133
134 114 // Uses delegate to create the qcpplot components according to the variable
135 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
136
137 for (auto createdPlottable : qAsConst(createdPlottables)) {
138 impl->m_VariableToPlotMultiMap.insert({variable, createdPlottable});
139 }
115 this->addVariable(variable);
140 116
141 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
117 // Request range for the variable
118 auto graphRange = ui->widget->xAxis->range();
142 119
143 // CHangement detected, we need to ask controller to request data loading
144 emit requestDataLoading(variable, variableDateTimeWithTolerance);
120 emit requestDataLoading(QVector<std::shared_ptr<Variable> >() << variable,
121 SqpRange{graphRange.lower, graphRange.upper}, variable->range(), false);
145 122 }
146 123
147 124 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
@@ -239,103 +216,31 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
239 216
240 217 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
241 218 {
242 qCInfo(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::onRangeChanged")
243 << QThread::currentThread()->objectName();
219 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: VisualizationGraphWidget::onRangeChanged")
220 << QThread::currentThread()->objectName() << "DoAcqui"
221 << impl->m_DoAcquisition;
244 222
245 auto dateTimeRange = SqpRange{t1.lower, t1.upper};
223 auto graphRange = SqpRange{t1.lower, t1.upper};
224 auto oldGraphRange = SqpRange{t2.lower, t2.upper};
246 225
247 auto zoomType = impl->getZoomType(t1, t2);
248 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
249 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
226 if (impl->m_DoAcquisition) {
227 QVector<std::shared_ptr<Variable> > variableUnderGraphVector;
250 228
251 auto variable = it->first;
252 auto currentDateTime = dateTimeRange;
253
254 auto toleranceFactor = toleranceValue(GENERAL_TOLERANCE_AT_UPDATE_KEY,
255 GENERAL_TOLERANCE_AT_UPDATE_DEFAULT_VALUE);
256 auto tolerance = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
257 auto variableDateTimeWithTolerance = currentDateTime;
258 variableDateTimeWithTolerance.m_TStart -= tolerance;
259 variableDateTimeWithTolerance.m_TEnd += tolerance;
260
261 qCDebug(LOG_VisualizationGraphWidget()) << "r" << currentDateTime;
262 qCDebug(LOG_VisualizationGraphWidget()) << "t" << variableDateTimeWithTolerance;
263 qCDebug(LOG_VisualizationGraphWidget()) << "v" << variable->dateTime();
264 // If new range with tol is upper than variable datetime parameters. we need to request new
265 // data
266 if (!variable->contains(variableDateTimeWithTolerance)) {
267
268 auto variableDateTimeWithTolerance = currentDateTime;
269 if (!variable->isInside(currentDateTime)) {
270 auto variableDateTime = variable->dateTime();
271 if (variable->contains(variableDateTimeWithTolerance)) {
272 qCDebug(LOG_VisualizationGraphWidget())
273 << tr("TORM: Detection zoom in that need request:");
274 // add tolerance for each side
275 tolerance
276 = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
277 variableDateTimeWithTolerance.m_TStart -= tolerance;
278 variableDateTimeWithTolerance.m_TEnd += tolerance;
279 }
280 else if (variableDateTime.m_TStart < currentDateTime.m_TStart) {
281 qCInfo(LOG_VisualizationGraphWidget()) << tr("TORM: Detection pan to right:");
282
283 auto diffEndToKeepDelta = currentDateTime.m_TEnd - variableDateTime.m_TEnd;
284 currentDateTime.m_TStart = variableDateTime.m_TStart + diffEndToKeepDelta;
285 // Tolerance have to be added to the right
286 // add tolerance for right (end) side
287 tolerance
288 = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
289 variableDateTimeWithTolerance.m_TEnd += tolerance;
290 }
291 else if (variableDateTime.m_TEnd > currentDateTime.m_TEnd) {
292 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: Detection pan to left: ");
293 auto diffStartToKeepDelta
294 = variableDateTime.m_TStart - currentDateTime.m_TStart;
295 currentDateTime.m_TEnd = variableDateTime.m_TEnd - diffStartToKeepDelta;
296 // Tolerance have to be added to the left
297 // add tolerance for left (start) side
298 tolerance
299 = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
300 variableDateTimeWithTolerance.m_TStart -= tolerance;
301 }
302 else {
303 qCCritical(LOG_VisualizationGraphWidget())
304 << tr("Detection anormal zoom detection: ");
305 }
306 }
307 else {
308 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: Detection zoom out: ");
309 // add tolerance for each side
310 tolerance = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
311 variableDateTimeWithTolerance.m_TStart -= tolerance;
312 variableDateTimeWithTolerance.m_TEnd += tolerance;
313 zoomType = VisualizationGraphWidgetZoomType::ZoomOut;
314 }
315 if (!variable->contains(dateTimeRange)) {
316 qCDebug(LOG_VisualizationGraphWidget())
317 << "TORM: Modif on variable datetime detected" << currentDateTime;
318 variable->setDateTime(currentDateTime);
319 }
320
321 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: Request data detection: ");
322 // CHangement detected, we need to ask controller to request data loading
323 emit requestDataLoading(variable, variableDateTimeWithTolerance);
229 for (auto it = impl->m_VariableToPlotMultiMap.begin(),
230 end = impl->m_VariableToPlotMultiMap.end();
231 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
232 variableUnderGraphVector.push_back(it->first);
324 233 }
325 else {
326 qCInfo(LOG_VisualizationGraphWidget())
327 << tr("TORM: Detection zoom in that doesn't need request: ");
328 zoomType = VisualizationGraphWidgetZoomType::ZoomIn;
234 emit requestDataLoading(std::move(variableUnderGraphVector), graphRange, oldGraphRange,
235 !impl->m_IsCalibration);
236
237 if (!impl->m_IsCalibration) {
238 qCDebug(LOG_VisualizationGraphWidget())
239 << tr("TORM: VisualizationGraphWidget::Synchronize notify !!")
240 << QThread::currentThread()->objectName() << graphRange << oldGraphRange;
241 emit synchronize(graphRange, oldGraphRange);
329 242 }
330 243 }
331
332 if (impl->m_DoSynchronize && !impl->m_IsCalibration) {
333 auto oldDateTime = SqpRange{t2.lower, t2.upper};
334 qCDebug(LOG_VisualizationGraphWidget())
335 << tr("TORM: VisualizationGraphWidget::Synchronize notify !!")
336 << QThread::currentThread()->objectName();
337 emit synchronize(dateTimeRange, oldDateTime, zoomType);
338 }
339 244 }
340 245
341 246 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
@@ -390,38 +295,13 void VisualizationGraphWidget::onDataCacheVariableUpdated()
390 295 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
391 296 auto variable = it->first;
392 297 qCDebug(LOG_VisualizationGraphWidget())
393 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S"
394 << variable->dateTime();
298 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S" << variable->range();
395 299 qCDebug(LOG_VisualizationGraphWidget())
396 300 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
397 if (dateTime.contains(variable->dateTime()) || dateTime.intersect(variable->dateTime())) {
301 if (dateTime.contains(variable->range()) || dateTime.intersect(variable->range())) {
398 302
399 303 VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *>{} << it->second,
400 variable->dataSeries(), variable->dateTime());
304 variable->dataSeries(), variable->range());
401 305 }
402 306 }
403 307 }
404
405 VisualizationGraphWidgetZoomType
406 VisualizationGraphWidget::VisualizationGraphWidgetPrivate::getZoomType(const QCPRange &t1,
407 const QCPRange &t2)
408 {
409 // t1.lower <= t2.lower && t2.upper <= t1.upper
410 auto zoomType = VisualizationGraphWidgetZoomType::Unknown;
411 if (t1.lower <= t2.lower && t2.upper <= t1.upper) {
412 zoomType = VisualizationGraphWidgetZoomType::ZoomOut;
413 }
414 else if (t1.lower > t2.lower && t1.upper > t2.upper) {
415 zoomType = VisualizationGraphWidgetZoomType::PanRight;
416 }
417 else if (t1.lower < t2.lower && t1.upper < t2.upper) {
418 zoomType = VisualizationGraphWidgetZoomType::PanLeft;
419 }
420 else if (t1.lower > t2.lower && t2.upper > t1.upper) {
421 zoomType = VisualizationGraphWidgetZoomType::ZoomIn;
422 }
423 else {
424 qCCritical(LOG_VisualizationGraphWidget()) << "getZoomType: Unknown type detected";
425 }
426 return zoomType;
427 }
@@ -1,12 +1,14
1 1 #include "Visualization/VisualizationZoneWidget.h"
2 2
3 #include "Data/SqpRange.h"
4 3
5 4 #include "Visualization/IVisualizationWidgetVisitor.h"
6 5 #include "Visualization/VisualizationGraphWidget.h"
7 6 #include "ui_VisualizationZoneWidget.h"
8 7
8 #include <Data/SqpRange.h>
9 #include <Variable/VariableController.h>
9 10
11 #include <QUuid>
10 12 #include <SqpApplication.h>
11 13
12 14 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
@@ -32,8 +34,16 QString defaultGraphName(const QLayout &layout)
32 34
33 35 } // namespace
34 36
37 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
38
39 explicit VisualizationZoneWidgetPrivate() : m_SynchronisationGroupId{QUuid::createUuid()} {}
40 QUuid m_SynchronisationGroupId;
41 };
42
35 43 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
36 : QWidget{parent}, ui{new Ui::VisualizationZoneWidget}
44 : QWidget{parent},
45 ui{new Ui::VisualizationZoneWidget},
46 impl{spimpl::make_unique_impl<VisualizationZoneWidgetPrivate>()}
37 47 {
38 48 ui->setupUi(this);
39 49
@@ -43,6 +53,10 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *p
43 53 setAttribute(Qt::WA_DeleteOnClose);
44 54 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
45 55 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
56
57 // Synchronisation id
58 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronizationGroupId",
59 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
46 60 }
47 61
48 62 VisualizationZoneWidget::~VisualizationZoneWidget()
@@ -65,14 +79,12 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<V
65 79 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
66 80 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
67 81
68 this->addGraph(graphWidget);
69
70 graphWidget->addVariable(variable);
71 82
72 83 // Lambda to synchronize zone widget
73 auto synchronizeZoneWidget = [this, graphWidget](const SqpRange &dateTime,
74 const SqpRange &oldDateTime,
75 VisualizationGraphWidgetZoomType zoomType) {
84 auto synchronizeZoneWidget = [this, graphWidget](const SqpRange &grapheRange,
85 const SqpRange &oldGraphRange) {
86
87 auto zoomType = VariableController::getZoomType(grapheRange, oldGraphRange);
76 88 auto frameLayout = ui->visualizationZoneFrame->layout();
77 89 for (auto i = 0; i < frameLayout->count(); ++i) {
78 90 auto graphChild
@@ -81,9 +93,9 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<V
81 93
82 94 auto graphChildRange = graphChild->graphRange();
83 95 switch (zoomType) {
84 case VisualizationGraphWidgetZoomType::ZoomIn: {
85 auto deltaLeft = dateTime.m_TStart - oldDateTime.m_TStart;
86 auto deltaRight = oldDateTime.m_TEnd - dateTime.m_TEnd;
96 case AcquisitionZoomType::ZoomIn: {
97 auto deltaLeft = grapheRange.m_TStart - oldGraphRange.m_TStart;
98 auto deltaRight = oldGraphRange.m_TEnd - grapheRange.m_TEnd;
87 99 graphChildRange.m_TStart += deltaLeft;
88 100 graphChildRange.m_TEnd -= deltaRight;
89 101 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomIn");
@@ -92,42 +104,42 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<V
92 104 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
93 105 << deltaRight;
94 106 qCCritical(LOG_VisualizationZoneWidget())
95 << tr("TORM: dt") << dateTime.m_TEnd - dateTime.m_TStart;
107 << tr("TORM: dt") << grapheRange.m_TEnd - grapheRange.m_TStart;
96 108
97 109 break;
98 110 }
99 111
100 case VisualizationGraphWidgetZoomType::ZoomOut: {
112 case AcquisitionZoomType::ZoomOut: {
101 113 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomOut");
102 auto deltaLeft = oldDateTime.m_TStart - dateTime.m_TStart;
103 auto deltaRight = dateTime.m_TEnd - oldDateTime.m_TEnd;
114 auto deltaLeft = oldGraphRange.m_TStart - grapheRange.m_TStart;
115 auto deltaRight = grapheRange.m_TEnd - oldGraphRange.m_TEnd;
104 116 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
105 117 << deltaLeft;
106 118 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
107 119 << deltaRight;
108 120 qCCritical(LOG_VisualizationZoneWidget())
109 << tr("TORM: dt") << dateTime.m_TEnd - dateTime.m_TStart;
121 << tr("TORM: dt") << grapheRange.m_TEnd - grapheRange.m_TStart;
110 122 graphChildRange.m_TStart -= deltaLeft;
111 123 graphChildRange.m_TEnd += deltaRight;
112 124 break;
113 125 }
114 case VisualizationGraphWidgetZoomType::PanRight: {
126 case AcquisitionZoomType::PanRight: {
115 127 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: PanRight");
116 auto deltaRight = dateTime.m_TEnd - oldDateTime.m_TEnd;
128 auto deltaRight = grapheRange.m_TEnd - oldGraphRange.m_TEnd;
117 129 graphChildRange.m_TStart += deltaRight;
118 130 graphChildRange.m_TEnd += deltaRight;
119 131 qCCritical(LOG_VisualizationZoneWidget())
120 << tr("TORM: dt") << dateTime.m_TEnd - dateTime.m_TStart;
132 << tr("TORM: dt") << grapheRange.m_TEnd - grapheRange.m_TStart;
121 133 break;
122 134 }
123 case VisualizationGraphWidgetZoomType::PanLeft: {
135 case AcquisitionZoomType::PanLeft: {
124 136 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: PanLeft");
125 auto deltaLeft = oldDateTime.m_TStart - dateTime.m_TStart;
137 auto deltaLeft = oldGraphRange.m_TStart - grapheRange.m_TStart;
126 138 graphChildRange.m_TStart -= deltaLeft;
127 139 graphChildRange.m_TEnd -= deltaLeft;
128 140 break;
129 141 }
130 case VisualizationGraphWidgetZoomType::Unknown: {
142 case AcquisitionZoomType::Unknown: {
131 143 qCCritical(LOG_VisualizationZoneWidget())
132 144 << tr("Impossible to synchronize: zoom type unknown");
133 145 break;
@@ -138,7 +150,7 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<V
138 150 // No action
139 151 break;
140 152 }
141 graphChild->enableSynchronize(false);
153 graphChild->enableAcquisition(false);
142 154 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: Range before: ")
143 155 << graphChild->graphRange();
144 156 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: Range after : ")
@@ -146,13 +158,19 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<V
146 158 qCCritical(LOG_VisualizationZoneWidget())
147 159 << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart;
148 160 graphChild->setGraphRange(graphChildRange);
149 graphChild->enableSynchronize(true);
161 graphChild->enableAcquisition(true);
150 162 }
151 163 }
152 164 };
153 165
154 166 // connection for synchronization
155 167 connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
168 connect(graphWidget, &VisualizationGraphWidget::variableAdded, this,
169 &VisualizationZoneWidget::onVariableAdded);
170
171 this->addGraph(graphWidget);
172
173 graphWidget->addVariable(variable);
156 174
157 175 return graphWidget;
158 176 }
@@ -198,3 +216,10 QString VisualizationZoneWidget::name() const
198 216 {
199 217 return ui->zoneNameLabel->text();
200 218 }
219
220 void VisualizationZoneWidget::onVariableAdded(std::shared_ptr<Variable> variable)
221 {
222 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronized",
223 Qt::QueuedConnection, Q_ARG(std::shared_ptr<Variable>, variable),
224 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
225 }
@@ -28,9 +28,6
28 28 </property>
29 29 <item>
30 30 <widget class="QScrollArea" name="scrollArea">
31 <property name="styleSheet">
32 <string notr="true">background-color: transparent;</string>
33 </property>
34 31 <property name="frameShape">
35 32 <enum>QFrame::NoFrame</enum>
36 33 </property>
@@ -19,9 +19,9 class SCIQLOP_AMDA_EXPORT AmdaProvider : public IDataProvider {
19 19 public:
20 20 explicit AmdaProvider();
21 21
22 void requestDataLoading(QUuid token, const DataProviderParameters &parameters) override;
22 void requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters) override;
23 23
24 void requestDataAborting(QUuid identifier) override;
24 void requestDataAborting(QUuid acqIdentifier) override;
25 25
26 26 private:
27 27 void retrieveData(QUuid token, const SqpRange &dateTime, const QVariantHash &data);
@@ -55,21 +55,22 AmdaProvider::AmdaProvider()
55 55 }
56 56 }
57 57
58 void AmdaProvider::requestDataLoading(QUuid token, const DataProviderParameters &parameters)
58 void AmdaProvider::requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters)
59 59 {
60 60 // NOTE: Try to use multithread if possible
61 61 const auto times = parameters.m_Times;
62 62 const auto data = parameters.m_Data;
63 63 for (const auto &dateTime : qAsConst(times)) {
64 retrieveData(token, dateTime, data);
64 this->retrieveData(acqIdentifier, dateTime, data);
65 QThread::msleep(200);
65 66 }
66 67 }
67 68
68 void AmdaProvider::requestDataAborting(QUuid identifier)
69 void AmdaProvider::requestDataAborting(QUuid acqIdentifier)
69 70 {
70 71 if (auto app = sqpApp) {
71 72 auto &networkController = app->networkController();
72 networkController.onReplyCanceled(identifier);
73 networkController.onReplyCanceled(acqIdentifier);
73 74 }
74 75 }
75 76
@@ -81,7 +82,7 void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVa
81 82 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
82 83 return;
83 84 }
84 qCInfo(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData") << dateTime;
85 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData") << dateTime;
85 86
86 87 // /////////// //
87 88 // Creates URL //
@@ -96,8 +97,7 void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVa
96 97
97 98 // LAMBDA
98 99 auto httpDownloadFinished
99 = [this, dateTime, tempFile, token](QNetworkReply *reply, QUuid dataId) noexcept {
100 Q_UNUSED(dataId);
100 = [this, dateTime, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
101 101
102 102 // Don't do anything if the reply was abort
103 103 if (reply->error() != QNetworkReply::OperationCanceledError) {
@@ -111,7 +111,7 void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVa
111 111
112 112 // Parse results file
113 113 if (auto dataSeries = AmdaResultParser::readTxt(tempFile->fileName())) {
114 emit dataProvided(token, dataSeries, dateTime);
114 emit dataProvided(dataId, dataSeries, dateTime);
115 115 }
116 116 else {
117 117 /// @todo ALX : debug
@@ -17,15 +17,16 Q_DECLARE_LOGGING_CATEGORY(LOG_CosinusProvider)
17 17 class SCIQLOP_MOCKPLUGIN_EXPORT CosinusProvider : public IDataProvider {
18 18 public:
19 19 /// @sa IDataProvider::requestDataLoading(). The current impl isn't thread safe.
20 void requestDataLoading(QUuid token, const DataProviderParameters &parameters) override;
20 void requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters) override;
21 21
22 22
23 23 /// @sa IDataProvider::requestDataAborting(). The current impl isn't thread safe.
24 void requestDataAborting(QUuid identifier) override;
24 void requestDataAborting(QUuid acqIdentifier) override;
25 25
26 26
27 27 private:
28 std::shared_ptr<IDataSeries> retrieveData(QUuid token, const SqpRange &dateTime);
28 std::shared_ptr<IDataSeries> retrieveData(QUuid acqIdentifier,
29 const SqpRange &dataRangeRequested);
29 30
30 31 QHash<QUuid, bool> m_VariableToEnableProvider;
31 32 };
@@ -11,15 +11,16
11 11
12 12 Q_LOGGING_CATEGORY(LOG_CosinusProvider, "CosinusProvider")
13 13
14 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(QUuid token, const SqpRange &dateTime)
14 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(QUuid acqIdentifier,
15 const SqpRange &dataRangeRequested)
15 16 {
16 17 // TODO: Add Mutex
17 18 auto dataIndex = 0;
18 19
19 20 // Gets the timerange from the parameters
20 21 double freq = 100.0;
21 double start = std::ceil(dateTime.m_TStart * freq); // 100 htz
22 double end = std::floor(dateTime.m_TEnd * freq); // 100 htz
22 double start = std::ceil(dataRangeRequested.m_TStart * freq); // 100 htz
23 double end = std::floor(dataRangeRequested.m_TEnd * freq); // 100 htz
23 24
24 25 // We assure that timerange is valid
25 26 if (end < start) {
@@ -38,7 +39,7 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(QUuid token, const Sq
38 39 int progress = 0;
39 40 auto progressEnd = dataCount;
40 41 for (auto time = start; time < end; ++time, ++dataIndex) {
41 auto it = m_VariableToEnableProvider.find(token);
42 auto it = m_VariableToEnableProvider.find(acqIdentifier);
42 43 if (it != m_VariableToEnableProvider.end() && it.value()) {
43 44 const auto timeOnFreq = time / freq;
44 45
@@ -50,7 +51,7 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(QUuid token, const Sq
50 51 if (currentProgress != progress) {
51 52 progress = currentProgress;
52 53
53 emit dataProvidedProgress(token, progress);
54 emit dataProvidedProgress(acqIdentifier, progress);
54 55 }
55 56 }
56 57 else {
@@ -61,35 +62,37 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(QUuid token, const Sq
61 62 }
62 63 }
63 64 }
64 emit dataProvidedProgress(token, 0.0);
65 emit dataProvidedProgress(acqIdentifier, 0.0);
65 66
66 67 return std::make_shared<ScalarSeries>(std::move(xAxisData), std::move(valuesData),
67 68 Unit{QStringLiteral("t"), true}, Unit{});
68 69 }
69 70
70 void CosinusProvider::requestDataLoading(QUuid token, const DataProviderParameters &parameters)
71 void CosinusProvider::requestDataLoading(QUuid acqIdentifier,
72 const DataProviderParameters &parameters)
71 73 {
72 74 // TODO: Add Mutex
73 m_VariableToEnableProvider[token] = true;
75 m_VariableToEnableProvider[acqIdentifier] = true;
74 76 qCDebug(LOG_CosinusProvider()) << "CosinusProvider::requestDataLoading"
75 77 << QThread::currentThread()->objectName();
76 78 // NOTE: Try to use multithread if possible
77 79 const auto times = parameters.m_Times;
78 80
79 81 for (const auto &dateTime : qAsConst(times)) {
80 if (m_VariableToEnableProvider[token]) {
81 auto scalarSeries = this->retrieveData(token, dateTime);
82 emit dataProvided(token, scalarSeries, dateTime);
82 if (m_VariableToEnableProvider[acqIdentifier]) {
83 auto scalarSeries = this->retrieveData(acqIdentifier, dateTime);
84 qCCritical(LOG_CosinusProvider()) << "CosinusProvider::dataProvided";
85 emit dataProvided(acqIdentifier, scalarSeries, dateTime);
83 86 }
84 87 }
85 88 }
86 89
87 void CosinusProvider::requestDataAborting(QUuid identifier)
90 void CosinusProvider::requestDataAborting(QUuid acqIdentifier)
88 91 {
89 92 // TODO: Add Mutex
90 qCDebug(LOG_CosinusProvider()) << "CosinusProvider::requestDataAborting" << identifier
93 qCDebug(LOG_CosinusProvider()) << "CosinusProvider::requestDataAborting" << acqIdentifier
91 94 << QThread::currentThread()->objectName();
92 auto it = m_VariableToEnableProvider.find(identifier);
95 auto it = m_VariableToEnableProvider.find(acqIdentifier);
93 96 if (it != m_VariableToEnableProvider.end()) {
94 97 it.value() = false;
95 98 }
General Comments 1
Under Review
author

Auto status change to "Under Review"

You need to be logged in to leave comments. Login now