##// END OF EJS Templates
Run request canceling when unit isn"t found in the file. Clean log.
perrinel -
r832:4ab17865bd43
parent child
Show More
@@ -1,416 +1,416
1 #include "Variable/VariableAcquisitionWorker.h"
1 #include "Variable/VariableAcquisitionWorker.h"
2
2
3 #include "Variable/Variable.h"
3 #include "Variable/Variable.h"
4
4
5 #include <Data/AcquisitionRequest.h>
5 #include <Data/AcquisitionRequest.h>
6 #include <Data/SqpRange.h>
6 #include <Data/SqpRange.h>
7
7
8 #include <unordered_map>
8 #include <unordered_map>
9 #include <utility>
9 #include <utility>
10
10
11 #include <QMutex>
11 #include <QMutex>
12 #include <QReadWriteLock>
12 #include <QReadWriteLock>
13 #include <QThread>
13 #include <QThread>
14
14
15 #include <cmath>
15 #include <cmath>
16
16
17 Q_LOGGING_CATEGORY(LOG_VariableAcquisitionWorker, "VariableAcquisitionWorker")
17 Q_LOGGING_CATEGORY(LOG_VariableAcquisitionWorker, "VariableAcquisitionWorker")
18
18
19 struct VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate {
19 struct VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate {
20
20
21 explicit VariableAcquisitionWorkerPrivate(VariableAcquisitionWorker *parent)
21 explicit VariableAcquisitionWorkerPrivate(VariableAcquisitionWorker *parent)
22 : m_Lock{QReadWriteLock::Recursive}, q{parent}
22 : m_Lock{QReadWriteLock::Recursive}, q{parent}
23 {
23 {
24 }
24 }
25
25
26 void lockRead() { m_Lock.lockForRead(); }
26 void lockRead() { m_Lock.lockForRead(); }
27 void lockWrite() { m_Lock.lockForWrite(); }
27 void lockWrite() { m_Lock.lockForWrite(); }
28 void unlock() { m_Lock.unlock(); }
28 void unlock() { m_Lock.unlock(); }
29
29
30 void removeVariableRequest(QUuid vIdentifier);
30 void removeVariableRequest(QUuid vIdentifier);
31
31
32 /// Remove the current request and execute the next one if exist
32 /// Remove the current request and execute the next one if exist
33 void updateToNextRequest(QUuid vIdentifier);
33 void updateToNextRequest(QUuid vIdentifier);
34
34
35 /// Remove and/or abort all AcqRequest in link with varRequestId
35 /// Remove and/or abort all AcqRequest in link with varRequestId
36 void cancelVarRequest(QUuid varRequestId);
36 void cancelVarRequest(QUuid varRequestId);
37 void removeAcqRequest(QUuid acqRequestId);
37 void removeAcqRequest(QUuid acqRequestId);
38
38
39 QMutex m_WorkingMutex;
39 QMutex m_WorkingMutex;
40 QReadWriteLock m_Lock;
40 QReadWriteLock m_Lock;
41
41
42 std::map<QUuid, QVector<AcquisitionDataPacket> > m_AcqIdentifierToAcqDataPacketVectorMap;
42 std::map<QUuid, QVector<AcquisitionDataPacket> > m_AcqIdentifierToAcqDataPacketVectorMap;
43 std::map<QUuid, AcquisitionRequest> m_AcqIdentifierToAcqRequestMap;
43 std::map<QUuid, AcquisitionRequest> m_AcqIdentifierToAcqRequestMap;
44 std::map<QUuid, std::pair<QUuid, QUuid> > m_VIdentifierToCurrrentAcqIdNextIdPairMap;
44 std::map<QUuid, std::pair<QUuid, QUuid> > m_VIdentifierToCurrrentAcqIdNextIdPairMap;
45 VariableAcquisitionWorker *q;
45 VariableAcquisitionWorker *q;
46 };
46 };
47
47
48
48
49 VariableAcquisitionWorker::VariableAcquisitionWorker(QObject *parent)
49 VariableAcquisitionWorker::VariableAcquisitionWorker(QObject *parent)
50 : QObject{parent}, impl{spimpl::make_unique_impl<VariableAcquisitionWorkerPrivate>(this)}
50 : QObject{parent}, impl{spimpl::make_unique_impl<VariableAcquisitionWorkerPrivate>(this)}
51 {
51 {
52 }
52 }
53
53
54 VariableAcquisitionWorker::~VariableAcquisitionWorker()
54 VariableAcquisitionWorker::~VariableAcquisitionWorker()
55 {
55 {
56 qCInfo(LOG_VariableAcquisitionWorker()) << tr("VariableAcquisitionWorker destruction")
56 qCInfo(LOG_VariableAcquisitionWorker()) << tr("VariableAcquisitionWorker destruction")
57 << QThread::currentThread();
57 << QThread::currentThread();
58 this->waitForFinish();
58 this->waitForFinish();
59 }
59 }
60
60
61
61
62 QUuid VariableAcquisitionWorker::pushVariableRequest(QUuid varRequestId, QUuid vIdentifier,
62 QUuid VariableAcquisitionWorker::pushVariableRequest(QUuid varRequestId, QUuid vIdentifier,
63 SqpRange rangeRequested,
63 SqpRange rangeRequested,
64 SqpRange cacheRangeRequested,
64 SqpRange cacheRangeRequested,
65 DataProviderParameters parameters,
65 DataProviderParameters parameters,
66 std::shared_ptr<IDataProvider> provider)
66 std::shared_ptr<IDataProvider> provider)
67 {
67 {
68 qCDebug(LOG_VariableAcquisitionWorker())
68 qCDebug(LOG_VariableAcquisitionWorker())
69 << tr("TORM VariableAcquisitionWorker::pushVariableRequest ") << cacheRangeRequested;
69 << tr("TORM VariableAcquisitionWorker::pushVariableRequest ") << cacheRangeRequested;
70 auto varRequestIdCanceled = QUuid();
70 auto varRequestIdCanceled = QUuid();
71
71
72 // Request creation
72 // Request creation
73 auto acqRequest = AcquisitionRequest{};
73 auto acqRequest = AcquisitionRequest{};
74 qCDebug(LOG_VariableAcquisitionWorker()) << tr("PushVariableRequest ") << vIdentifier
74 qCDebug(LOG_VariableAcquisitionWorker()) << tr("PushVariableRequest ") << vIdentifier
75 << varRequestId;
75 << varRequestId;
76 acqRequest.m_VarRequestId = varRequestId;
76 acqRequest.m_VarRequestId = varRequestId;
77 acqRequest.m_vIdentifier = vIdentifier;
77 acqRequest.m_vIdentifier = vIdentifier;
78 acqRequest.m_DataProviderParameters = parameters;
78 acqRequest.m_DataProviderParameters = parameters;
79 acqRequest.m_RangeRequested = rangeRequested;
79 acqRequest.m_RangeRequested = rangeRequested;
80 acqRequest.m_CacheRangeRequested = cacheRangeRequested;
80 acqRequest.m_CacheRangeRequested = cacheRangeRequested;
81 acqRequest.m_Size = parameters.m_Times.size();
81 acqRequest.m_Size = parameters.m_Times.size();
82 acqRequest.m_Provider = provider;
82 acqRequest.m_Provider = provider;
83
83
84
84
85 // Register request
85 // Register request
86 impl->lockWrite();
86 impl->lockWrite();
87 impl->m_AcqIdentifierToAcqRequestMap.insert(
87 impl->m_AcqIdentifierToAcqRequestMap.insert(
88 std::make_pair(acqRequest.m_AcqIdentifier, acqRequest));
88 std::make_pair(acqRequest.m_AcqIdentifier, acqRequest));
89
89
90 auto it = impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
90 auto it = impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
91 if (it != impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
91 if (it != impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
92 // A current request already exists, we can replace the next one
92 // A current request already exists, we can replace the next one
93 auto oldAcqId = it->second.second;
93 auto oldAcqId = it->second.second;
94 auto acqIdentifierToAcqRequestMapIt = impl->m_AcqIdentifierToAcqRequestMap.find(oldAcqId);
94 auto acqIdentifierToAcqRequestMapIt = impl->m_AcqIdentifierToAcqRequestMap.find(oldAcqId);
95 if (acqIdentifierToAcqRequestMapIt != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
95 if (acqIdentifierToAcqRequestMapIt != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
96 auto oldAcqRequest = acqIdentifierToAcqRequestMapIt->second;
96 auto oldAcqRequest = acqIdentifierToAcqRequestMapIt->second;
97 varRequestIdCanceled = oldAcqRequest.m_VarRequestId;
97 varRequestIdCanceled = oldAcqRequest.m_VarRequestId;
98 }
98 }
99
99
100 it->second.second = acqRequest.m_AcqIdentifier;
100 it->second.second = acqRequest.m_AcqIdentifier;
101 impl->unlock();
101 impl->unlock();
102
102
103 // remove old acqIdentifier from the worker
103 // remove old acqIdentifier from the worker
104 impl->cancelVarRequest(varRequestIdCanceled);
104 impl->cancelVarRequest(varRequestIdCanceled);
105 // impl->m_AcqIdentifierToAcqRequestMap.erase(oldAcqId);
105 // impl->m_AcqIdentifierToAcqRequestMap.erase(oldAcqId);
106 }
106 }
107 else {
107 else {
108 // First request for the variable, it must be stored and executed
108 // First request for the variable, it must be stored and executed
109 impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.insert(
109 impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.insert(
110 std::make_pair(vIdentifier, std::make_pair(acqRequest.m_AcqIdentifier, QUuid())));
110 std::make_pair(vIdentifier, std::make_pair(acqRequest.m_AcqIdentifier, QUuid())));
111 impl->unlock();
111 impl->unlock();
112
112
113 QMetaObject::invokeMethod(this, "onExecuteRequest", Qt::QueuedConnection,
113 QMetaObject::invokeMethod(this, "onExecuteRequest", Qt::QueuedConnection,
114 Q_ARG(QUuid, acqRequest.m_AcqIdentifier));
114 Q_ARG(QUuid, acqRequest.m_AcqIdentifier));
115 }
115 }
116
116
117 return varRequestIdCanceled;
117 return varRequestIdCanceled;
118 }
118 }
119
119
120 void VariableAcquisitionWorker::abortProgressRequested(QUuid vIdentifier)
120 void VariableAcquisitionWorker::abortProgressRequested(QUuid vIdentifier)
121 {
121 {
122 impl->lockRead();
122 impl->lockRead();
123
123
124 auto it = impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
124 auto it = impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
125 if (it != impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
125 if (it != impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
126 auto currentAcqId = it->second.first;
126 auto currentAcqId = it->second.first;
127
127
128 auto it = impl->m_AcqIdentifierToAcqRequestMap.find(currentAcqId);
128 auto it = impl->m_AcqIdentifierToAcqRequestMap.find(currentAcqId);
129 if (it != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
129 if (it != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
130 auto request = it->second;
130 auto request = it->second;
131 impl->unlock();
131 impl->unlock();
132
132
133 // Remove the current request from the worker
133 // Remove the current request from the worker
134 impl->updateToNextRequest(vIdentifier);
134 impl->updateToNextRequest(vIdentifier);
135
135
136 // notify the request aborting to the provider
136 // notify the request aborting to the provider
137 request.m_Provider->requestDataAborting(currentAcqId);
137 request.m_Provider->requestDataAborting(currentAcqId);
138 }
138 }
139 else {
139 else {
140 impl->unlock();
140 impl->unlock();
141 qCWarning(LOG_VariableAcquisitionWorker())
141 qCWarning(LOG_VariableAcquisitionWorker())
142 << tr("Impossible to abort an unknown acquisition request") << currentAcqId;
142 << tr("Impossible to abort an unknown acquisition request") << currentAcqId;
143 }
143 }
144 }
144 }
145 else {
145 else {
146 impl->unlock();
146 impl->unlock();
147 }
147 }
148 }
148 }
149
149
150 void VariableAcquisitionWorker::onVariableRetrieveDataInProgress(QUuid acqIdentifier,
150 void VariableAcquisitionWorker::onVariableRetrieveDataInProgress(QUuid acqIdentifier,
151 double progress)
151 double progress)
152 {
152 {
153 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM: onVariableRetrieveDataInProgress ")
153 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM: onVariableRetrieveDataInProgress ")
154 << acqIdentifier << progress;
154 << acqIdentifier << progress;
155 impl->lockRead();
155 impl->lockRead();
156 auto aIdToARit = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier);
156 auto aIdToARit = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier);
157 if (aIdToARit != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
157 if (aIdToARit != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
158 auto currentPartSize = (aIdToARit->second.m_Size != 0) ? 100 / aIdToARit->second.m_Size : 0;
158 auto currentPartSize = (aIdToARit->second.m_Size != 0) ? 100 / aIdToARit->second.m_Size : 0;
159
159
160 auto currentPartProgress
160 auto currentPartProgress
161 = std::isnan(progress) ? 0.0 : (progress * currentPartSize) / 100.0;
161 = std::isnan(progress) ? 0.0 : (progress * currentPartSize) / 100.0;
162 auto currentAlreadyProgress = aIdToARit->second.m_Progression * currentPartSize;
162 auto currentAlreadyProgress = aIdToARit->second.m_Progression * currentPartSize;
163
163
164 auto finalProgression = currentAlreadyProgress + currentPartProgress;
164 auto finalProgression = currentAlreadyProgress + currentPartProgress;
165 emit variableRequestInProgress(aIdToARit->second.m_vIdentifier, finalProgression);
165 emit variableRequestInProgress(aIdToARit->second.m_vIdentifier, finalProgression);
166 qCDebug(LOG_VariableAcquisitionWorker())
166 qCDebug(LOG_VariableAcquisitionWorker())
167 << tr("TORM: onVariableRetrieveDataInProgress ")
167 << tr("TORM: onVariableRetrieveDataInProgress ")
168 << QThread::currentThread()->objectName() << aIdToARit->second.m_vIdentifier
168 << QThread::currentThread()->objectName() << aIdToARit->second.m_vIdentifier
169 << currentPartSize << currentAlreadyProgress << currentPartProgress << finalProgression;
169 << currentPartSize << currentAlreadyProgress << currentPartProgress << finalProgression;
170 if (finalProgression == 100.0) {
170 if (finalProgression == 100.0) {
171 emit variableRequestInProgress(aIdToARit->second.m_vIdentifier, 0.0);
171 emit variableRequestInProgress(aIdToARit->second.m_vIdentifier, 0.0);
172 }
172 }
173 }
173 }
174 impl->unlock();
174 impl->unlock();
175 }
175 }
176
176
177 void VariableAcquisitionWorker::onVariableAcquisitionFailed(QUuid acqIdentifier)
177 void VariableAcquisitionWorker::onVariableAcquisitionFailed(QUuid acqIdentifier)
178 {
178 {
179 qCDebug(LOG_VariableAcquisitionWorker()) << tr("onVariableAcquisitionFailed")
179 qCDebug(LOG_VariableAcquisitionWorker()) << tr("onVariableAcquisitionFailed")
180 << QThread::currentThread();
180 << QThread::currentThread();
181 impl->lockRead();
181 impl->lockRead();
182 auto it = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier);
182 auto it = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier);
183 if (it != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
183 if (it != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
184 auto request = it->second;
184 auto request = it->second;
185 impl->unlock();
185 impl->unlock();
186 qCInfo(LOG_VariableAcquisitionWorker()) << tr("onVariableAcquisitionFailed")
186 qCDebug(LOG_VariableAcquisitionWorker()) << tr("onVariableAcquisitionFailed")
187 << acqIdentifier << request.m_vIdentifier
187 << acqIdentifier << request.m_vIdentifier
188 << QThread::currentThread();
188 << QThread::currentThread();
189 emit variableCanceledRequested(request.m_vIdentifier);
189 emit variableCanceledRequested(request.m_vIdentifier);
190 }
190 }
191 else {
191 else {
192 impl->unlock();
192 impl->unlock();
193 // TODO log no acqIdentifier recognized
193 // TODO log no acqIdentifier recognized
194 }
194 }
195 }
195 }
196
196
197 void VariableAcquisitionWorker::onVariableDataAcquired(QUuid acqIdentifier,
197 void VariableAcquisitionWorker::onVariableDataAcquired(QUuid acqIdentifier,
198 std::shared_ptr<IDataSeries> dataSeries,
198 std::shared_ptr<IDataSeries> dataSeries,
199 SqpRange dataRangeAcquired)
199 SqpRange dataRangeAcquired)
200 {
200 {
201 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM: onVariableDataAcquired on range ")
201 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM: onVariableDataAcquired on range ")
202 << acqIdentifier << dataRangeAcquired;
202 << acqIdentifier << dataRangeAcquired;
203 impl->lockWrite();
203 impl->lockWrite();
204 auto aIdToARit = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier);
204 auto aIdToARit = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier);
205 if (aIdToARit != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
205 if (aIdToARit != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
206 // Store the result
206 // Store the result
207 auto dataPacket = AcquisitionDataPacket{};
207 auto dataPacket = AcquisitionDataPacket{};
208 dataPacket.m_Range = dataRangeAcquired;
208 dataPacket.m_Range = dataRangeAcquired;
209 dataPacket.m_DateSeries = dataSeries;
209 dataPacket.m_DateSeries = dataSeries;
210
210
211 auto aIdToADPVit = impl->m_AcqIdentifierToAcqDataPacketVectorMap.find(acqIdentifier);
211 auto aIdToADPVit = impl->m_AcqIdentifierToAcqDataPacketVectorMap.find(acqIdentifier);
212 if (aIdToADPVit != impl->m_AcqIdentifierToAcqDataPacketVectorMap.cend()) {
212 if (aIdToADPVit != impl->m_AcqIdentifierToAcqDataPacketVectorMap.cend()) {
213 // A current request result already exists, we can update it
213 // A current request result already exists, we can update it
214 aIdToADPVit->second.push_back(dataPacket);
214 aIdToADPVit->second.push_back(dataPacket);
215 }
215 }
216 else {
216 else {
217 // First request result for the variable, it must be stored
217 // First request result for the variable, it must be stored
218 impl->m_AcqIdentifierToAcqDataPacketVectorMap.insert(
218 impl->m_AcqIdentifierToAcqDataPacketVectorMap.insert(
219 std::make_pair(acqIdentifier, QVector<AcquisitionDataPacket>() << dataPacket));
219 std::make_pair(acqIdentifier, QVector<AcquisitionDataPacket>() << dataPacket));
220 }
220 }
221
221
222
222
223 // Decrement the counter of the request
223 // Decrement the counter of the request
224 auto &acqRequest = aIdToARit->second;
224 auto &acqRequest = aIdToARit->second;
225 acqRequest.m_Progression = acqRequest.m_Progression + 1;
225 acqRequest.m_Progression = acqRequest.m_Progression + 1;
226
226
227 // if the counter is 0, we can return data then run the next request if it exists and
227 // if the counter is 0, we can return data then run the next request if it exists and
228 // removed the finished request
228 // removed the finished request
229 if (acqRequest.m_Size == acqRequest.m_Progression) {
229 if (acqRequest.m_Size == acqRequest.m_Progression) {
230 auto varId = acqRequest.m_vIdentifier;
230 auto varId = acqRequest.m_vIdentifier;
231 auto rangeRequested = acqRequest.m_RangeRequested;
231 auto rangeRequested = acqRequest.m_RangeRequested;
232 auto cacheRangeRequested = acqRequest.m_CacheRangeRequested;
232 auto cacheRangeRequested = acqRequest.m_CacheRangeRequested;
233 // Return the data
233 // Return the data
234 aIdToADPVit = impl->m_AcqIdentifierToAcqDataPacketVectorMap.find(acqIdentifier);
234 aIdToADPVit = impl->m_AcqIdentifierToAcqDataPacketVectorMap.find(acqIdentifier);
235 if (aIdToADPVit != impl->m_AcqIdentifierToAcqDataPacketVectorMap.cend()) {
235 if (aIdToADPVit != impl->m_AcqIdentifierToAcqDataPacketVectorMap.cend()) {
236 emit dataProvided(varId, rangeRequested, cacheRangeRequested, aIdToADPVit->second);
236 emit dataProvided(varId, rangeRequested, cacheRangeRequested, aIdToADPVit->second);
237 }
237 }
238 impl->unlock();
238 impl->unlock();
239
239
240 // Update to the next request
240 // Update to the next request
241 impl->updateToNextRequest(acqRequest.m_vIdentifier);
241 impl->updateToNextRequest(acqRequest.m_vIdentifier);
242 }
242 }
243 else {
243 else {
244 impl->unlock();
244 impl->unlock();
245 }
245 }
246 }
246 }
247 else {
247 else {
248 impl->unlock();
248 impl->unlock();
249 qCWarning(LOG_VariableAcquisitionWorker())
249 qCWarning(LOG_VariableAcquisitionWorker())
250 << tr("Impossible to retrieve AcquisitionRequest for the incoming data.");
250 << tr("Impossible to retrieve AcquisitionRequest for the incoming data.");
251 }
251 }
252 }
252 }
253
253
254 void VariableAcquisitionWorker::onExecuteRequest(QUuid acqIdentifier)
254 void VariableAcquisitionWorker::onExecuteRequest(QUuid acqIdentifier)
255 {
255 {
256 qCDebug(LOG_VariableAcquisitionWorker()) << tr("onExecuteRequest") << QThread::currentThread();
256 qCDebug(LOG_VariableAcquisitionWorker()) << tr("onExecuteRequest") << QThread::currentThread();
257 impl->lockRead();
257 impl->lockRead();
258 auto it = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier);
258 auto it = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier);
259 if (it != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
259 if (it != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
260 auto request = it->second;
260 auto request = it->second;
261 impl->unlock();
261 impl->unlock();
262 emit variableRequestInProgress(request.m_vIdentifier, 0.1);
262 emit variableRequestInProgress(request.m_vIdentifier, 0.1);
263 request.m_Provider->requestDataLoading(acqIdentifier, request.m_DataProviderParameters);
263 request.m_Provider->requestDataLoading(acqIdentifier, request.m_DataProviderParameters);
264 }
264 }
265 else {
265 else {
266 impl->unlock();
266 impl->unlock();
267 // TODO log no acqIdentifier recognized
267 // TODO log no acqIdentifier recognized
268 }
268 }
269 }
269 }
270
270
271 void VariableAcquisitionWorker::initialize()
271 void VariableAcquisitionWorker::initialize()
272 {
272 {
273 qCDebug(LOG_VariableAcquisitionWorker()) << tr("VariableAcquisitionWorker init")
273 qCDebug(LOG_VariableAcquisitionWorker()) << tr("VariableAcquisitionWorker init")
274 << QThread::currentThread();
274 << QThread::currentThread();
275 impl->m_WorkingMutex.lock();
275 impl->m_WorkingMutex.lock();
276 qCDebug(LOG_VariableAcquisitionWorker()) << tr("VariableAcquisitionWorker init END");
276 qCDebug(LOG_VariableAcquisitionWorker()) << tr("VariableAcquisitionWorker init END");
277 }
277 }
278
278
279 void VariableAcquisitionWorker::finalize()
279 void VariableAcquisitionWorker::finalize()
280 {
280 {
281 impl->m_WorkingMutex.unlock();
281 impl->m_WorkingMutex.unlock();
282 }
282 }
283
283
284 void VariableAcquisitionWorker::waitForFinish()
284 void VariableAcquisitionWorker::waitForFinish()
285 {
285 {
286 QMutexLocker locker{&impl->m_WorkingMutex};
286 QMutexLocker locker{&impl->m_WorkingMutex};
287 }
287 }
288
288
289 void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::removeVariableRequest(
289 void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::removeVariableRequest(
290 QUuid vIdentifier)
290 QUuid vIdentifier)
291 {
291 {
292 lockWrite();
292 lockWrite();
293 auto it = m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
293 auto it = m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
294
294
295 if (it != m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
295 if (it != m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
296 // A current request already exists, we can replace the next one
296 // A current request already exists, we can replace the next one
297
297
298 m_AcqIdentifierToAcqRequestMap.erase(it->second.first);
298 m_AcqIdentifierToAcqRequestMap.erase(it->second.first);
299 m_AcqIdentifierToAcqDataPacketVectorMap.erase(it->second.first);
299 m_AcqIdentifierToAcqDataPacketVectorMap.erase(it->second.first);
300
300
301 m_AcqIdentifierToAcqRequestMap.erase(it->second.second);
301 m_AcqIdentifierToAcqRequestMap.erase(it->second.second);
302 m_AcqIdentifierToAcqDataPacketVectorMap.erase(it->second.second);
302 m_AcqIdentifierToAcqDataPacketVectorMap.erase(it->second.second);
303 }
303 }
304 m_VIdentifierToCurrrentAcqIdNextIdPairMap.erase(vIdentifier);
304 m_VIdentifierToCurrrentAcqIdNextIdPairMap.erase(vIdentifier);
305 unlock();
305 unlock();
306 }
306 }
307
307
308 void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::updateToNextRequest(
308 void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::updateToNextRequest(
309 QUuid vIdentifier)
309 QUuid vIdentifier)
310 {
310 {
311 lockRead();
311 lockRead();
312 auto it = m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
312 auto it = m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
313 if (it != m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
313 if (it != m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
314 if (it->second.second.isNull()) {
314 if (it->second.second.isNull()) {
315 unlock();
315 unlock();
316 // There is no next request, we can remove the variable request
316 // There is no next request, we can remove the variable request
317 removeVariableRequest(vIdentifier);
317 removeVariableRequest(vIdentifier);
318 }
318 }
319 else {
319 else {
320 auto acqIdentifierToRemove = it->second.first;
320 auto acqIdentifierToRemove = it->second.first;
321 // Move the next request to the current request
321 // Move the next request to the current request
322 auto nextRequestId = it->second.second;
322 auto nextRequestId = it->second.second;
323 it->second.first = nextRequestId;
323 it->second.first = nextRequestId;
324 it->second.second = QUuid();
324 it->second.second = QUuid();
325 unlock();
325 unlock();
326 // Remove AcquisitionRequest and results;
326 // Remove AcquisitionRequest and results;
327 lockWrite();
327 lockWrite();
328 m_AcqIdentifierToAcqRequestMap.erase(acqIdentifierToRemove);
328 m_AcqIdentifierToAcqRequestMap.erase(acqIdentifierToRemove);
329 m_AcqIdentifierToAcqDataPacketVectorMap.erase(acqIdentifierToRemove);
329 m_AcqIdentifierToAcqDataPacketVectorMap.erase(acqIdentifierToRemove);
330 unlock();
330 unlock();
331 // Execute the current request
331 // Execute the current request
332 QMetaObject::invokeMethod(q, "onExecuteRequest", Qt::QueuedConnection,
332 QMetaObject::invokeMethod(q, "onExecuteRequest", Qt::QueuedConnection,
333 Q_ARG(QUuid, nextRequestId));
333 Q_ARG(QUuid, nextRequestId));
334 }
334 }
335 }
335 }
336 else {
336 else {
337 unlock();
337 unlock();
338 qCCritical(LOG_VariableAcquisitionWorker())
338 qCCritical(LOG_VariableAcquisitionWorker())
339 << tr("Impossible to execute the acquisition on an unfound variable ");
339 << tr("Impossible to execute the acquisition on an unfound variable ");
340 }
340 }
341 }
341 }
342
342
343 void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::cancelVarRequest(
343 void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::cancelVarRequest(
344 QUuid varRequestId)
344 QUuid varRequestId)
345 {
345 {
346 qCDebug(LOG_VariableAcquisitionWorker())
346 qCDebug(LOG_VariableAcquisitionWorker())
347 << "VariableAcquisitionWorkerPrivate::cancelVarRequest 0";
347 << "VariableAcquisitionWorkerPrivate::cancelVarRequest 0";
348 lockRead();
348 lockRead();
349 // get all AcqIdentifier in link with varRequestId
349 // get all AcqIdentifier in link with varRequestId
350 QVector<QUuid> acqIdsToRm;
350 QVector<QUuid> acqIdsToRm;
351 auto cend = m_AcqIdentifierToAcqRequestMap.cend();
351 auto cend = m_AcqIdentifierToAcqRequestMap.cend();
352 for (auto it = m_AcqIdentifierToAcqRequestMap.cbegin(); it != cend; ++it) {
352 for (auto it = m_AcqIdentifierToAcqRequestMap.cbegin(); it != cend; ++it) {
353 if (it->second.m_VarRequestId == varRequestId) {
353 if (it->second.m_VarRequestId == varRequestId) {
354 acqIdsToRm << it->first;
354 acqIdsToRm << it->first;
355 }
355 }
356 }
356 }
357 unlock();
357 unlock();
358 // run aborting or removing of acqIdsToRm
358 // run aborting or removing of acqIdsToRm
359
359
360 for (auto acqId : acqIdsToRm) {
360 for (auto acqId : acqIdsToRm) {
361 removeAcqRequest(acqId);
361 removeAcqRequest(acqId);
362 }
362 }
363 qCDebug(LOG_VariableAcquisitionWorker())
363 qCDebug(LOG_VariableAcquisitionWorker())
364 << "VariableAcquisitionWorkerPrivate::cancelVarRequest end";
364 << "VariableAcquisitionWorkerPrivate::cancelVarRequest end";
365 }
365 }
366
366
367 void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::removeAcqRequest(
367 void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::removeAcqRequest(
368 QUuid acqRequestId)
368 QUuid acqRequestId)
369 {
369 {
370 qCDebug(LOG_VariableAcquisitionWorker())
370 qCDebug(LOG_VariableAcquisitionWorker())
371 << "VariableAcquisitionWorkerPrivate::removeAcqRequest";
371 << "VariableAcquisitionWorkerPrivate::removeAcqRequest";
372 QUuid vIdentifier;
372 QUuid vIdentifier;
373 std::shared_ptr<IDataProvider> provider;
373 std::shared_ptr<IDataProvider> provider;
374 lockRead();
374 lockRead();
375 auto acqIt = m_AcqIdentifierToAcqRequestMap.find(acqRequestId);
375 auto acqIt = m_AcqIdentifierToAcqRequestMap.find(acqRequestId);
376 if (acqIt != m_AcqIdentifierToAcqRequestMap.cend()) {
376 if (acqIt != m_AcqIdentifierToAcqRequestMap.cend()) {
377 vIdentifier = acqIt->second.m_vIdentifier;
377 vIdentifier = acqIt->second.m_vIdentifier;
378 provider = acqIt->second.m_Provider;
378 provider = acqIt->second.m_Provider;
379
379
380 auto it = m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
380 auto it = m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
381 if (it != m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
381 if (it != m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
382 if (it->second.first == acqRequestId) {
382 if (it->second.first == acqRequestId) {
383 // acqRequest is currently running -> let's aborting it
383 // acqRequest is currently running -> let's aborting it
384 unlock();
384 unlock();
385
385
386 // Remove the current request from the worker
386 // Remove the current request from the worker
387 updateToNextRequest(vIdentifier);
387 updateToNextRequest(vIdentifier);
388
388
389 // notify the request aborting to the provider
389 // notify the request aborting to the provider
390 provider->requestDataAborting(acqRequestId);
390 provider->requestDataAborting(acqRequestId);
391 }
391 }
392 else if (it->second.second == acqRequestId) {
392 else if (it->second.second == acqRequestId) {
393 it->second.second = QUuid();
393 it->second.second = QUuid();
394 unlock();
394 unlock();
395 }
395 }
396 else {
396 else {
397 unlock();
397 unlock();
398 }
398 }
399 }
399 }
400 else {
400 else {
401 unlock();
401 unlock();
402 }
402 }
403 }
403 }
404 else {
404 else {
405 unlock();
405 unlock();
406 }
406 }
407
407
408 lockWrite();
408 lockWrite();
409
409
410 m_AcqIdentifierToAcqDataPacketVectorMap.erase(acqRequestId);
410 m_AcqIdentifierToAcqDataPacketVectorMap.erase(acqRequestId);
411 m_AcqIdentifierToAcqRequestMap.erase(acqRequestId);
411 m_AcqIdentifierToAcqRequestMap.erase(acqRequestId);
412
412
413 unlock();
413 unlock();
414 qCDebug(LOG_VariableAcquisitionWorker())
414 qCDebug(LOG_VariableAcquisitionWorker())
415 << "VariableAcquisitionWorkerPrivate::removeAcqRequest END";
415 << "VariableAcquisitionWorkerPrivate::removeAcqRequest END";
416 }
416 }
@@ -1,973 +1,971
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableAcquisitionWorker.h>
2 #include <Variable/VariableAcquisitionWorker.h>
3 #include <Variable/VariableCacheStrategy.h>
3 #include <Variable/VariableCacheStrategy.h>
4 #include <Variable/VariableCacheStrategyFactory.h>
4 #include <Variable/VariableCacheStrategyFactory.h>
5 #include <Variable/VariableController.h>
5 #include <Variable/VariableController.h>
6 #include <Variable/VariableModel.h>
6 #include <Variable/VariableModel.h>
7 #include <Variable/VariableSynchronizationGroup.h>
7 #include <Variable/VariableSynchronizationGroup.h>
8
8
9 #include <Data/DataProviderParameters.h>
9 #include <Data/DataProviderParameters.h>
10 #include <Data/IDataProvider.h>
10 #include <Data/IDataProvider.h>
11 #include <Data/IDataSeries.h>
11 #include <Data/IDataSeries.h>
12 #include <Data/VariableRequest.h>
12 #include <Data/VariableRequest.h>
13 #include <Time/TimeController.h>
13 #include <Time/TimeController.h>
14
14
15 #include <QMutex>
15 #include <QMutex>
16 #include <QThread>
16 #include <QThread>
17 #include <QUuid>
17 #include <QUuid>
18 #include <QtCore/QItemSelectionModel>
18 #include <QtCore/QItemSelectionModel>
19
19
20 #include <deque>
20 #include <deque>
21 #include <set>
21 #include <set>
22 #include <unordered_map>
22 #include <unordered_map>
23
23
24 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
24 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
25
25
26 namespace {
26 namespace {
27
27
28 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
28 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
29 const SqpRange &oldGraphRange)
29 const SqpRange &oldGraphRange)
30 {
30 {
31 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
31 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
32
32
33 auto varRangeRequested = varRange;
33 auto varRangeRequested = varRange;
34 switch (zoomType) {
34 switch (zoomType) {
35 case AcquisitionZoomType::ZoomIn: {
35 case AcquisitionZoomType::ZoomIn: {
36 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
36 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
37 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
37 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
38 varRangeRequested.m_TStart += deltaLeft;
38 varRangeRequested.m_TStart += deltaLeft;
39 varRangeRequested.m_TEnd -= deltaRight;
39 varRangeRequested.m_TEnd -= deltaRight;
40 break;
40 break;
41 }
41 }
42
42
43 case AcquisitionZoomType::ZoomOut: {
43 case AcquisitionZoomType::ZoomOut: {
44 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
44 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
45 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
45 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
46 varRangeRequested.m_TStart -= deltaLeft;
46 varRangeRequested.m_TStart -= deltaLeft;
47 varRangeRequested.m_TEnd += deltaRight;
47 varRangeRequested.m_TEnd += deltaRight;
48 break;
48 break;
49 }
49 }
50 case AcquisitionZoomType::PanRight: {
50 case AcquisitionZoomType::PanRight: {
51 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
51 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
52 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
52 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
53 varRangeRequested.m_TStart += deltaLeft;
53 varRangeRequested.m_TStart += deltaLeft;
54 varRangeRequested.m_TEnd += deltaRight;
54 varRangeRequested.m_TEnd += deltaRight;
55 break;
55 break;
56 }
56 }
57 case AcquisitionZoomType::PanLeft: {
57 case AcquisitionZoomType::PanLeft: {
58 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
58 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
59 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
59 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
60 varRangeRequested.m_TStart -= deltaLeft;
60 varRangeRequested.m_TStart -= deltaLeft;
61 varRangeRequested.m_TEnd -= deltaRight;
61 varRangeRequested.m_TEnd -= deltaRight;
62 break;
62 break;
63 }
63 }
64 case AcquisitionZoomType::Unknown: {
64 case AcquisitionZoomType::Unknown: {
65 qCCritical(LOG_VariableController())
65 qCCritical(LOG_VariableController())
66 << VariableController::tr("Impossible to synchronize: zoom type unknown");
66 << VariableController::tr("Impossible to synchronize: zoom type unknown");
67 break;
67 break;
68 }
68 }
69 default:
69 default:
70 qCCritical(LOG_VariableController()) << VariableController::tr(
70 qCCritical(LOG_VariableController()) << VariableController::tr(
71 "Impossible to synchronize: zoom type not take into account");
71 "Impossible to synchronize: zoom type not take into account");
72 // No action
72 // No action
73 break;
73 break;
74 }
74 }
75
75
76 return varRangeRequested;
76 return varRangeRequested;
77 }
77 }
78 }
78 }
79
79
80 enum class VariableRequestHandlerState { OFF, RUNNING, PENDING };
80 enum class VariableRequestHandlerState { OFF, RUNNING, PENDING };
81
81
82 struct VariableRequestHandler {
82 struct VariableRequestHandler {
83
83
84 VariableRequestHandler()
84 VariableRequestHandler()
85 {
85 {
86 m_CanUpdate = false;
86 m_CanUpdate = false;
87 m_State = VariableRequestHandlerState::OFF;
87 m_State = VariableRequestHandlerState::OFF;
88 }
88 }
89
89
90 QUuid m_VarId;
90 QUuid m_VarId;
91 VariableRequest m_RunningVarRequest;
91 VariableRequest m_RunningVarRequest;
92 VariableRequest m_PendingVarRequest;
92 VariableRequest m_PendingVarRequest;
93 VariableRequestHandlerState m_State;
93 VariableRequestHandlerState m_State;
94 bool m_CanUpdate;
94 bool m_CanUpdate;
95 };
95 };
96
96
97 struct VariableController::VariableControllerPrivate {
97 struct VariableController::VariableControllerPrivate {
98 explicit VariableControllerPrivate(VariableController *parent)
98 explicit VariableControllerPrivate(VariableController *parent)
99 : m_WorkingMutex{},
99 : m_WorkingMutex{},
100 m_VariableModel{new VariableModel{parent}},
100 m_VariableModel{new VariableModel{parent}},
101 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
101 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
102 // m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
102 // m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
103 m_VariableCacheStrategy{VariableCacheStrategyFactory::createCacheStrategy(
103 m_VariableCacheStrategy{VariableCacheStrategyFactory::createCacheStrategy(
104 CacheStrategy::SingleThreshold)},
104 CacheStrategy::SingleThreshold)},
105 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
105 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
106 q{parent}
106 q{parent}
107 {
107 {
108
108
109 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
109 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
110 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
110 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
111 }
111 }
112
112
113
113
114 virtual ~VariableControllerPrivate()
114 virtual ~VariableControllerPrivate()
115 {
115 {
116 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
116 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
117 m_VariableAcquisitionWorkerThread.quit();
117 m_VariableAcquisitionWorkerThread.quit();
118 m_VariableAcquisitionWorkerThread.wait();
118 m_VariableAcquisitionWorkerThread.wait();
119 }
119 }
120
120
121
121
122 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested,
122 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested,
123 QUuid varRequestId);
123 QUuid varRequestId);
124
124
125 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
125 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
126 std::shared_ptr<IDataSeries>
126 std::shared_ptr<IDataSeries>
127 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
127 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
128
128
129 void registerProvider(std::shared_ptr<IDataProvider> provider);
129 void registerProvider(std::shared_ptr<IDataProvider> provider);
130
130
131 void storeVariableRequest(QUuid varId, QUuid varRequestId, const VariableRequest &varRequest);
131 void storeVariableRequest(QUuid varId, QUuid varRequestId, const VariableRequest &varRequest);
132 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries);
132 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries);
133 void updateVariables(QUuid varRequestId);
133 void updateVariables(QUuid varRequestId);
134 void updateVariableRequest(QUuid varRequestId);
134 void updateVariableRequest(QUuid varRequestId);
135 void cancelVariableRequest(QUuid varRequestId);
135 void cancelVariableRequest(QUuid varRequestId);
136 void executeVarRequest(std::shared_ptr<Variable> var, VariableRequest &varRequest);
136 void executeVarRequest(std::shared_ptr<Variable> var, VariableRequest &varRequest);
137
137
138 QMutex m_WorkingMutex;
138 QMutex m_WorkingMutex;
139 /// Variable model. The VariableController has the ownership
139 /// Variable model. The VariableController has the ownership
140 VariableModel *m_VariableModel;
140 VariableModel *m_VariableModel;
141 QItemSelectionModel *m_VariableSelectionModel;
141 QItemSelectionModel *m_VariableSelectionModel;
142
142
143
143
144 TimeController *m_TimeController{nullptr};
144 TimeController *m_TimeController{nullptr};
145 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
145 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
146 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
146 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
147 QThread m_VariableAcquisitionWorkerThread;
147 QThread m_VariableAcquisitionWorkerThread;
148
148
149 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
149 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
150 m_VariableToProviderMap;
150 m_VariableToProviderMap;
151 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
151 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
152 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
152 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
153 m_GroupIdToVariableSynchronizationGroupMap;
153 m_GroupIdToVariableSynchronizationGroupMap;
154 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
154 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
155 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
155 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
156
156
157 std::map<QUuid, std::list<QUuid> > m_VarGroupIdToVarIds;
157 std::map<QUuid, std::list<QUuid> > m_VarGroupIdToVarIds;
158 std::map<QUuid, std::unique_ptr<VariableRequestHandler> > m_VarIdToVarRequestHandler;
158 std::map<QUuid, std::unique_ptr<VariableRequestHandler> > m_VarIdToVarRequestHandler;
159
159
160 VariableController *q;
160 VariableController *q;
161 };
161 };
162
162
163
163
164 VariableController::VariableController(QObject *parent)
164 VariableController::VariableController(QObject *parent)
165 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
165 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
166 {
166 {
167 qCDebug(LOG_VariableController()) << tr("VariableController construction")
167 qCDebug(LOG_VariableController()) << tr("VariableController construction")
168 << QThread::currentThread();
168 << QThread::currentThread();
169
169
170 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
170 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
171 &VariableController::onAbortProgressRequested);
171 &VariableController::onAbortProgressRequested);
172
172
173 connect(impl->m_VariableAcquisitionWorker.get(),
173 connect(impl->m_VariableAcquisitionWorker.get(),
174 &VariableAcquisitionWorker::variableCanceledRequested, this,
174 &VariableAcquisitionWorker::variableCanceledRequested, this,
175 &VariableController::onAbortAcquisitionRequested);
175 &VariableController::onAbortAcquisitionRequested);
176
176
177 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
177 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
178 &VariableController::onDataProvided);
178 &VariableController::onDataProvided);
179 connect(impl->m_VariableAcquisitionWorker.get(),
179 connect(impl->m_VariableAcquisitionWorker.get(),
180 &VariableAcquisitionWorker::variableRequestInProgress, this,
180 &VariableAcquisitionWorker::variableRequestInProgress, this,
181 &VariableController::onVariableRetrieveDataInProgress);
181 &VariableController::onVariableRetrieveDataInProgress);
182
182
183
183
184 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
184 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
185 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
185 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
186 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
186 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
187 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
187 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
188
188
189
189
190 impl->m_VariableAcquisitionWorkerThread.start();
190 impl->m_VariableAcquisitionWorkerThread.start();
191 }
191 }
192
192
193 VariableController::~VariableController()
193 VariableController::~VariableController()
194 {
194 {
195 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
195 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
196 << QThread::currentThread();
196 << QThread::currentThread();
197 this->waitForFinish();
197 this->waitForFinish();
198 }
198 }
199
199
200 VariableModel *VariableController::variableModel() noexcept
200 VariableModel *VariableController::variableModel() noexcept
201 {
201 {
202 return impl->m_VariableModel;
202 return impl->m_VariableModel;
203 }
203 }
204
204
205 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
205 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
206 {
206 {
207 return impl->m_VariableSelectionModel;
207 return impl->m_VariableSelectionModel;
208 }
208 }
209
209
210 void VariableController::setTimeController(TimeController *timeController) noexcept
210 void VariableController::setTimeController(TimeController *timeController) noexcept
211 {
211 {
212 impl->m_TimeController = timeController;
212 impl->m_TimeController = timeController;
213 }
213 }
214
214
215 std::shared_ptr<Variable>
215 std::shared_ptr<Variable>
216 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
216 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
217 {
217 {
218 if (impl->m_VariableModel->containsVariable(variable)) {
218 if (impl->m_VariableModel->containsVariable(variable)) {
219 // Clones variable
219 // Clones variable
220 auto duplicate = variable->clone();
220 auto duplicate = variable->clone();
221
221
222 // Adds clone to model
222 // Adds clone to model
223 impl->m_VariableModel->addVariable(duplicate);
223 impl->m_VariableModel->addVariable(duplicate);
224
224
225 // Generates clone identifier
225 // Generates clone identifier
226 impl->m_VariableToIdentifierMap[duplicate] = QUuid::createUuid();
226 impl->m_VariableToIdentifierMap[duplicate] = QUuid::createUuid();
227
227
228 // Registers provider
228 // Registers provider
229 auto variableProvider = impl->m_VariableToProviderMap.at(variable);
229 auto variableProvider = impl->m_VariableToProviderMap.at(variable);
230 auto duplicateProvider = variableProvider != nullptr ? variableProvider->clone() : nullptr;
230 auto duplicateProvider = variableProvider != nullptr ? variableProvider->clone() : nullptr;
231
231
232 impl->m_VariableToProviderMap[duplicate] = duplicateProvider;
232 impl->m_VariableToProviderMap[duplicate] = duplicateProvider;
233 if (duplicateProvider) {
233 if (duplicateProvider) {
234 impl->registerProvider(duplicateProvider);
234 impl->registerProvider(duplicateProvider);
235 }
235 }
236
236
237 return duplicate;
237 return duplicate;
238 }
238 }
239 else {
239 else {
240 qCCritical(LOG_VariableController())
240 qCCritical(LOG_VariableController())
241 << tr("Can't create duplicate of variable %1: variable not registered in the model")
241 << tr("Can't create duplicate of variable %1: variable not registered in the model")
242 .arg(variable->name());
242 .arg(variable->name());
243 return nullptr;
243 return nullptr;
244 }
244 }
245 }
245 }
246
246
247 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
247 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
248 {
248 {
249 if (!variable) {
249 if (!variable) {
250 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
250 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
251 return;
251 return;
252 }
252 }
253
253
254 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
254 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
255 // make some treatments before the deletion
255 // make some treatments before the deletion
256 emit variableAboutToBeDeleted(variable);
256 emit variableAboutToBeDeleted(variable);
257
257
258 // Deletes identifier
258 // Deletes identifier
259 impl->m_VariableToIdentifierMap.erase(variable);
259 impl->m_VariableToIdentifierMap.erase(variable);
260
260
261 // Deletes provider
261 // Deletes provider
262 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
262 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
263 qCDebug(LOG_VariableController())
263 qCDebug(LOG_VariableController())
264 << tr("Number of providers deleted for variable %1: %2")
264 << tr("Number of providers deleted for variable %1: %2")
265 .arg(variable->name(), QString::number(nbProvidersDeleted));
265 .arg(variable->name(), QString::number(nbProvidersDeleted));
266
266
267
267
268 // Deletes from model
268 // Deletes from model
269 impl->m_VariableModel->deleteVariable(variable);
269 impl->m_VariableModel->deleteVariable(variable);
270 }
270 }
271
271
272 void VariableController::deleteVariables(
272 void VariableController::deleteVariables(
273 const QVector<std::shared_ptr<Variable> > &variables) noexcept
273 const QVector<std::shared_ptr<Variable> > &variables) noexcept
274 {
274 {
275 for (auto variable : qAsConst(variables)) {
275 for (auto variable : qAsConst(variables)) {
276 deleteVariable(variable);
276 deleteVariable(variable);
277 }
277 }
278 }
278 }
279
279
280 std::shared_ptr<Variable>
280 std::shared_ptr<Variable>
281 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
281 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
282 std::shared_ptr<IDataProvider> provider) noexcept
282 std::shared_ptr<IDataProvider> provider) noexcept
283 {
283 {
284 if (!impl->m_TimeController) {
284 if (!impl->m_TimeController) {
285 qCCritical(LOG_VariableController())
285 qCCritical(LOG_VariableController())
286 << tr("Impossible to create variable: The time controller is null");
286 << tr("Impossible to create variable: The time controller is null");
287 return nullptr;
287 return nullptr;
288 }
288 }
289
289
290 auto range = impl->m_TimeController->dateTime();
290 auto range = impl->m_TimeController->dateTime();
291
291
292 if (auto newVariable = impl->m_VariableModel->createVariable(name, metadata)) {
292 if (auto newVariable = impl->m_VariableModel->createVariable(name, metadata)) {
293 auto varId = QUuid::createUuid();
293 auto varId = QUuid::createUuid();
294
294
295 // Create the handler
295 // Create the handler
296 auto varRequestHandler = std::make_unique<VariableRequestHandler>();
296 auto varRequestHandler = std::make_unique<VariableRequestHandler>();
297 varRequestHandler->m_VarId = varId;
297 varRequestHandler->m_VarId = varId;
298
298
299 impl->m_VarIdToVarRequestHandler.insert(
299 impl->m_VarIdToVarRequestHandler.insert(
300 std::make_pair(varId, std::move(varRequestHandler)));
300 std::make_pair(varId, std::move(varRequestHandler)));
301
301
302 // store the provider
302 // store the provider
303 impl->registerProvider(provider);
303 impl->registerProvider(provider);
304
304
305 // Associate the provider
305 // Associate the provider
306 impl->m_VariableToProviderMap[newVariable] = provider;
306 impl->m_VariableToProviderMap[newVariable] = provider;
307 impl->m_VariableToIdentifierMap[newVariable] = varId;
307 impl->m_VariableToIdentifierMap[newVariable] = varId;
308
308
309 this->onRequestDataLoading(QVector<std::shared_ptr<Variable> >{newVariable}, range, false);
309 this->onRequestDataLoading(QVector<std::shared_ptr<Variable> >{newVariable}, range, false);
310
310
311 // auto varRequestId = QUuid::createUuid();
311 // auto varRequestId = QUuid::createUuid();
312 // qCInfo(LOG_VariableController()) << "createVariable: " << varId << varRequestId;
312 // qCInfo(LOG_VariableController()) << "createVariable: " << varId << varRequestId;
313 // impl->processRequest(newVariable, range, varRequestId);
313 // impl->processRequest(newVariable, range, varRequestId);
314 // impl->updateVariableRequest(varRequestId);
314 // impl->updateVariableRequest(varRequestId);
315
315
316 return newVariable;
316 return newVariable;
317 }
317 }
318 }
318 }
319
319
320 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
320 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
321 {
321 {
322 // NOTE: Even if acquisition request is aborting, the graphe range will be changed
322 // NOTE: Even if acquisition request is aborting, the graphe range will be changed
323 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
323 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
324 << QThread::currentThread()->objectName();
324 << QThread::currentThread()->objectName();
325 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
325 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
326 auto variables = QVector<std::shared_ptr<Variable> >{};
326 auto variables = QVector<std::shared_ptr<Variable> >{};
327
327
328 for (const auto &selectedRow : qAsConst(selectedRows)) {
328 for (const auto &selectedRow : qAsConst(selectedRows)) {
329 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
329 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
330 variables << selectedVariable;
330 variables << selectedVariable;
331
331
332 // notify that rescale operation has to be done
332 // notify that rescale operation has to be done
333 emit rangeChanged(selectedVariable, dateTime);
333 emit rangeChanged(selectedVariable, dateTime);
334 }
334 }
335 }
335 }
336
336
337 if (!variables.isEmpty()) {
337 if (!variables.isEmpty()) {
338 this->onRequestDataLoading(variables, dateTime, true);
338 this->onRequestDataLoading(variables, dateTime, true);
339 }
339 }
340 }
340 }
341
341
342 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
342 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
343 const SqpRange &cacheRangeRequested,
343 const SqpRange &cacheRangeRequested,
344 QVector<AcquisitionDataPacket> dataAcquired)
344 QVector<AcquisitionDataPacket> dataAcquired)
345 {
345 {
346 qCInfo(LOG_VariableController()) << tr("onDataProvided") << QThread::currentThread();
346 qCDebug(LOG_VariableController()) << tr("onDataProvided") << QThread::currentThread();
347 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
347 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
348 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
348 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
349 if (!varRequestId.isNull()) {
349 if (!varRequestId.isNull()) {
350 impl->updateVariables(varRequestId);
350 impl->updateVariables(varRequestId);
351 }
351 }
352 }
352 }
353
353
354 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
354 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
355 {
355 {
356 qCDebug(LOG_VariableController())
356 qCDebug(LOG_VariableController())
357 << "TORM: variableController::onVariableRetrieveDataInProgress"
357 << "TORM: variableController::onVariableRetrieveDataInProgress"
358 << QThread::currentThread()->objectName() << progress;
358 << QThread::currentThread()->objectName() << progress;
359 if (auto var = impl->findVariable(identifier)) {
359 if (auto var = impl->findVariable(identifier)) {
360 impl->m_VariableModel->setDataProgress(var, progress);
360 impl->m_VariableModel->setDataProgress(var, progress);
361 }
361 }
362 else {
362 else {
363 qCCritical(LOG_VariableController())
363 qCCritical(LOG_VariableController())
364 << tr("Impossible to notify progression of a null variable");
364 << tr("Impossible to notify progression of a null variable");
365 }
365 }
366 }
366 }
367
367
368 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
368 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
369 {
369 {
370 qCDebug(LOG_VariableController()) << "TORM: variableController::onAbortProgressRequested"
371 << QThread::currentThread()->objectName() << variable->name();
370
372
371 auto itVar = impl->m_VariableToIdentifierMap.find(variable);
373 auto itVar = impl->m_VariableToIdentifierMap.find(variable);
372 if (itVar == impl->m_VariableToIdentifierMap.cend()) {
374 if (itVar == impl->m_VariableToIdentifierMap.cend()) {
373 qCCritical(LOG_VariableController())
375 qCCritical(LOG_VariableController())
374 << tr("Impossible to onAbortProgressRequested request for unknown variable");
376 << tr("Impossible to onAbortProgressRequested request for unknown variable");
375 return;
377 return;
376 }
378 }
377
379
378 auto varId = itVar->second;
380 auto varId = itVar->second;
379
381
380 auto itVarHandler = impl->m_VarIdToVarRequestHandler.find(varId);
382 auto itVarHandler = impl->m_VarIdToVarRequestHandler.find(varId);
381 if (itVarHandler == impl->m_VarIdToVarRequestHandler.cend()) {
383 if (itVarHandler == impl->m_VarIdToVarRequestHandler.cend()) {
382 qCCritical(LOG_VariableController())
384 qCCritical(LOG_VariableController())
383 << tr("Impossible to onAbortProgressRequested for variable with unknown handler");
385 << tr("Impossible to onAbortProgressRequested for variable with unknown handler");
384 return;
386 return;
385 }
387 }
386
388
387 auto varHandler = itVarHandler->second.get();
389 auto varHandler = itVarHandler->second.get();
388
390
389 // case where a variable has a running request
391 // case where a variable has a running request
390 if (varHandler->m_State != VariableRequestHandlerState::OFF) {
392 if (varHandler->m_State != VariableRequestHandlerState::OFF) {
391 impl->cancelVariableRequest(varHandler->m_RunningVarRequest.m_VariableGroupId);
393 impl->cancelVariableRequest(varHandler->m_RunningVarRequest.m_VariableGroupId);
392 }
394 }
393 }
395 }
394
396
395 void VariableController::onAbortAcquisitionRequested(QUuid vIdentifier)
397 void VariableController::onAbortAcquisitionRequested(QUuid vIdentifier)
396 {
398 {
397 qCDebug(LOG_VariableController()) << "TORM: variableController::onAbortAcquisitionRequested"
399 qCDebug(LOG_VariableController()) << "TORM: variableController::onAbortAcquisitionRequested"
398 << QThread::currentThread()->objectName() << vIdentifier;
400 << QThread::currentThread()->objectName() << vIdentifier;
399
401
400 if (auto var = impl->findVariable(vIdentifier)) {
402 if (auto var = impl->findVariable(vIdentifier)) {
401 this->onAbortProgressRequested(var);
403 this->onAbortProgressRequested(var);
402 }
404 }
403 else {
405 else {
404 qCCritical(LOG_VariableController())
406 qCCritical(LOG_VariableController())
405 << tr("Impossible to abort Acquisition Requestof a null variable");
407 << tr("Impossible to abort Acquisition Requestof a null variable");
406 }
408 }
407 }
409 }
408
410
409 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
411 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
410 {
412 {
411 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
413 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
412 << QThread::currentThread()->objectName()
414 << QThread::currentThread()->objectName()
413 << synchronizationGroupId;
415 << synchronizationGroupId;
414 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
416 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
415 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
417 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
416 std::make_pair(synchronizationGroupId, vSynchroGroup));
418 std::make_pair(synchronizationGroupId, vSynchroGroup));
417 }
419 }
418
420
419 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
421 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
420 {
422 {
421 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
423 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
422 }
424 }
423
425
424 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
426 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
425 QUuid synchronizationGroupId)
427 QUuid synchronizationGroupId)
426
428
427 {
429 {
428 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
430 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
429 << synchronizationGroupId;
431 << synchronizationGroupId;
430 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
432 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
431 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
433 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
432 auto groupIdToVSGIt
434 auto groupIdToVSGIt
433 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
435 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
434 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
436 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
435 impl->m_VariableIdGroupIdMap.insert(
437 impl->m_VariableIdGroupIdMap.insert(
436 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
438 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
437 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
439 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
438 }
440 }
439 else {
441 else {
440 qCCritical(LOG_VariableController())
442 qCCritical(LOG_VariableController())
441 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
443 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
442 << variable->name();
444 << variable->name();
443 }
445 }
444 }
446 }
445 else {
447 else {
446 qCCritical(LOG_VariableController())
448 qCCritical(LOG_VariableController())
447 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
449 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
448 }
450 }
449 }
451 }
450
452
451 void VariableController::desynchronize(std::shared_ptr<Variable> variable,
453 void VariableController::desynchronize(std::shared_ptr<Variable> variable,
452 QUuid synchronizationGroupId)
454 QUuid synchronizationGroupId)
453 {
455 {
454 // Gets variable id
456 // Gets variable id
455 auto variableIt = impl->m_VariableToIdentifierMap.find(variable);
457 auto variableIt = impl->m_VariableToIdentifierMap.find(variable);
456 if (variableIt == impl->m_VariableToIdentifierMap.cend()) {
458 if (variableIt == impl->m_VariableToIdentifierMap.cend()) {
457 qCCritical(LOG_VariableController())
459 qCCritical(LOG_VariableController())
458 << tr("Can't desynchronize variable %1: variable identifier not found")
460 << tr("Can't desynchronize variable %1: variable identifier not found")
459 .arg(variable->name());
461 .arg(variable->name());
460 return;
462 return;
461 }
463 }
462
464
463 // Gets synchronization group
465 // Gets synchronization group
464 auto groupIt = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
466 auto groupIt = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
465 if (groupIt == impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
467 if (groupIt == impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
466 qCCritical(LOG_VariableController())
468 qCCritical(LOG_VariableController())
467 << tr("Can't desynchronize variable %1: unknown synchronization group")
469 << tr("Can't desynchronize variable %1: unknown synchronization group")
468 .arg(variable->name());
470 .arg(variable->name());
469 return;
471 return;
470 }
472 }
471
473
472 auto variableId = variableIt->second;
474 auto variableId = variableIt->second;
473
475
474 // Removes variable from synchronization group
476 // Removes variable from synchronization group
475 auto synchronizationGroup = groupIt->second;
477 auto synchronizationGroup = groupIt->second;
476 synchronizationGroup->removeVariableId(variableId);
478 synchronizationGroup->removeVariableId(variableId);
477
479
478 // Removes link between variable and synchronization group
480 // Removes link between variable and synchronization group
479 impl->m_VariableIdGroupIdMap.erase(variableId);
481 impl->m_VariableIdGroupIdMap.erase(variableId);
480 }
482 }
481
483
482 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
484 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
483 const SqpRange &range, bool synchronise)
485 const SqpRange &range, bool synchronise)
484 {
486 {
485 // variables is assumed synchronized
487 // variables is assumed synchronized
486 // TODO: Asser variables synchronization
488 // TODO: Asser variables synchronization
487 // we want to load data of the variable for the dateTime.
489 // we want to load data of the variable for the dateTime.
488 if (variables.isEmpty()) {
490 if (variables.isEmpty()) {
489 return;
491 return;
490 }
492 }
491
493
492 auto varRequestId = QUuid::createUuid();
494 auto varRequestId = QUuid::createUuid();
493 qCCritical(LOG_VariableController()) << "VariableController::onRequestDataLoading"
495 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
494 << QThread::currentThread()->objectName() << varRequestId
496 << QThread::currentThread()->objectName() << varRequestId
495 << range;
497 << range;
496
498
497 if (!synchronise) {
499 if (!synchronise) {
498 auto varIds = std::list<QUuid>{};
500 auto varIds = std::list<QUuid>{};
499 for (const auto &var : variables) {
501 for (const auto &var : variables) {
500 auto vId = impl->m_VariableToIdentifierMap.at(var);
502 auto vId = impl->m_VariableToIdentifierMap.at(var);
501 varIds.push_back(vId);
503 varIds.push_back(vId);
502 }
504 }
503 impl->m_VarGroupIdToVarIds.insert(std::make_pair(varRequestId, varIds));
505 impl->m_VarGroupIdToVarIds.insert(std::make_pair(varRequestId, varIds));
504 for (const auto &var : variables) {
506 for (const auto &var : variables) {
505 qCInfo(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId
507 qCInfo(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId
506 << varIds.size();
508 << varIds.size();
507 impl->processRequest(var, range, varRequestId);
509 impl->processRequest(var, range, varRequestId);
508 }
510 }
509 }
511 }
510 else {
512 else {
511 auto vId = impl->m_VariableToIdentifierMap.at(variables.first());
513 auto vId = impl->m_VariableToIdentifierMap.at(variables.first());
512 qCInfo(LOG_VariableController()) << "Var in synchro group 0" << vId;
513 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
514 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
514 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
515 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
515 auto groupId = varIdToGroupIdIt->second;
516 auto groupId = varIdToGroupIdIt->second;
516
517
517 auto vSynchronizationGroup
518 auto vSynchronizationGroup
518 = impl->m_GroupIdToVariableSynchronizationGroupMap.at(groupId);
519 = impl->m_GroupIdToVariableSynchronizationGroupMap.at(groupId);
519 auto vSyncIds = vSynchronizationGroup->getIds();
520 auto vSyncIds = vSynchronizationGroup->getIds();
520
521
521 qCInfo(LOG_VariableController()) << "Var in synchro group 1" << groupId;
522
523 auto varIds = std::list<QUuid>{};
522 auto varIds = std::list<QUuid>{};
524 for (auto vId : vSyncIds) {
523 for (auto vId : vSyncIds) {
525 varIds.push_back(vId);
524 varIds.push_back(vId);
526 }
525 }
527 impl->m_VarGroupIdToVarIds.insert(std::make_pair(varRequestId, varIds));
526 impl->m_VarGroupIdToVarIds.insert(std::make_pair(varRequestId, varIds));
528
527
529 for (auto vId : vSyncIds) {
528 for (auto vId : vSyncIds) {
530 auto var = impl->findVariable(vId);
529 auto var = impl->findVariable(vId);
531
530
532 // Don't process already processed var
531 // Don't process already processed var
533 if (var != nullptr) {
532 if (var != nullptr) {
534 qCInfo(LOG_VariableController()) << "processRequest synchro for" << var->name()
533 qCDebug(LOG_VariableController()) << "processRequest synchro for" << var->name()
535 << varRequestId;
534 << varRequestId;
536 auto vSyncRangeRequested
535 auto vSyncRangeRequested
537 = variables.contains(var)
536 = variables.contains(var)
538 ? range
537 ? range
539 : computeSynchroRangeRequested(var->range(), range,
538 : computeSynchroRangeRequested(var->range(), range,
540 variables.first()->range());
539 variables.first()->range());
541 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
540 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
542 impl->processRequest(var, vSyncRangeRequested, varRequestId);
541 impl->processRequest(var, vSyncRangeRequested, varRequestId);
543 }
542 }
544 else {
543 else {
545 qCCritical(LOG_VariableController())
544 qCCritical(LOG_VariableController())
546
545
547 << tr("Impossible to synchronize a null variable");
546 << tr("Impossible to synchronize a null variable");
548 }
547 }
549 }
548 }
550 }
549 }
551 }
550 }
552
551
553 impl->updateVariables(varRequestId);
552 impl->updateVariables(varRequestId);
554 }
553 }
555
554
556
555
557 void VariableController::initialize()
556 void VariableController::initialize()
558 {
557 {
559 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
558 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
560 impl->m_WorkingMutex.lock();
559 impl->m_WorkingMutex.lock();
561 qCDebug(LOG_VariableController()) << tr("VariableController init END");
560 qCDebug(LOG_VariableController()) << tr("VariableController init END");
562 }
561 }
563
562
564 void VariableController::finalize()
563 void VariableController::finalize()
565 {
564 {
566 impl->m_WorkingMutex.unlock();
565 impl->m_WorkingMutex.unlock();
567 }
566 }
568
567
569 void VariableController::waitForFinish()
568 void VariableController::waitForFinish()
570 {
569 {
571 QMutexLocker locker{&impl->m_WorkingMutex};
570 QMutexLocker locker{&impl->m_WorkingMutex};
572 }
571 }
573
572
574 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
573 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
575 {
574 {
576 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
575 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
577 auto zoomType = AcquisitionZoomType::Unknown;
576 auto zoomType = AcquisitionZoomType::Unknown;
578 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
577 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
579 qCDebug(LOG_VariableController()) << "zoomtype: ZoomOut";
578 qCDebug(LOG_VariableController()) << "zoomtype: ZoomOut";
580 zoomType = AcquisitionZoomType::ZoomOut;
579 zoomType = AcquisitionZoomType::ZoomOut;
581 }
580 }
582 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
581 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
583 qCDebug(LOG_VariableController()) << "zoomtype: PanRight";
582 qCDebug(LOG_VariableController()) << "zoomtype: PanRight";
584 zoomType = AcquisitionZoomType::PanRight;
583 zoomType = AcquisitionZoomType::PanRight;
585 }
584 }
586 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
585 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
587 qCDebug(LOG_VariableController()) << "zoomtype: PanLeft";
586 qCDebug(LOG_VariableController()) << "zoomtype: PanLeft";
588 zoomType = AcquisitionZoomType::PanLeft;
587 zoomType = AcquisitionZoomType::PanLeft;
589 }
588 }
590 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
589 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
591 qCDebug(LOG_VariableController()) << "zoomtype: ZoomIn";
590 qCDebug(LOG_VariableController()) << "zoomtype: ZoomIn";
592 zoomType = AcquisitionZoomType::ZoomIn;
591 zoomType = AcquisitionZoomType::ZoomIn;
593 }
592 }
594 else {
593 else {
595 qCDebug(LOG_VariableController()) << "getZoomType: Unknown type detected";
594 qCDebug(LOG_VariableController()) << "getZoomType: Unknown type detected";
596 }
595 }
597 return zoomType;
596 return zoomType;
598 }
597 }
599
598
600 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
599 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
601 const SqpRange &rangeRequested,
600 const SqpRange &rangeRequested,
602 QUuid varRequestId)
601 QUuid varRequestId)
603 {
602 {
604 auto itVar = m_VariableToIdentifierMap.find(var);
603 auto itVar = m_VariableToIdentifierMap.find(var);
605 if (itVar == m_VariableToIdentifierMap.cend()) {
604 if (itVar == m_VariableToIdentifierMap.cend()) {
606 qCCritical(LOG_VariableController())
605 qCCritical(LOG_VariableController())
607 << tr("Impossible to process request for unknown variable");
606 << tr("Impossible to process request for unknown variable");
608 return;
607 return;
609 }
608 }
610
609
611 auto varId = itVar->second;
610 auto varId = itVar->second;
612
611
613 auto itVarHandler = m_VarIdToVarRequestHandler.find(varId);
612 auto itVarHandler = m_VarIdToVarRequestHandler.find(varId);
614 if (itVarHandler == m_VarIdToVarRequestHandler.cend()) {
613 if (itVarHandler == m_VarIdToVarRequestHandler.cend()) {
615 qCCritical(LOG_VariableController())
614 qCCritical(LOG_VariableController())
616 << tr("Impossible to process request for variable with unknown handler");
615 << tr("Impossible to process request for variable with unknown handler");
617 return;
616 return;
618 }
617 }
619
618
620 auto oldRange = var->range();
619 auto oldRange = var->range();
621
620
622 auto varHandler = itVarHandler->second.get();
621 auto varHandler = itVarHandler->second.get();
623
622
624 if (varHandler->m_State != VariableRequestHandlerState::OFF) {
623 if (varHandler->m_State != VariableRequestHandlerState::OFF) {
625 oldRange = varHandler->m_RunningVarRequest.m_RangeRequested;
624 oldRange = varHandler->m_RunningVarRequest.m_RangeRequested;
626 }
625 }
627
626
628 auto varRequest = VariableRequest{};
627 auto varRequest = VariableRequest{};
629 varRequest.m_VariableGroupId = varRequestId;
628 varRequest.m_VariableGroupId = varRequestId;
630 auto varStrategyRangesRequested
629 auto varStrategyRangesRequested
631 = m_VariableCacheStrategy->computeRange(oldRange, rangeRequested);
630 = m_VariableCacheStrategy->computeRange(oldRange, rangeRequested);
632 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
631 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
633 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
632 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
634
633
635 switch (varHandler->m_State) {
634 switch (varHandler->m_State) {
636 case VariableRequestHandlerState::OFF: {
635 case VariableRequestHandlerState::OFF: {
637 qCCritical(LOG_VariableController()) << tr("Process Request OFF")
636 qCDebug(LOG_VariableController()) << tr("Process Request OFF")
638 << varRequest.m_RangeRequested
637 << varRequest.m_RangeRequested
639 << varRequest.m_CacheRangeRequested;
638 << varRequest.m_CacheRangeRequested;
640 varHandler->m_RunningVarRequest = varRequest;
639 varHandler->m_RunningVarRequest = varRequest;
641 varHandler->m_State = VariableRequestHandlerState::RUNNING;
640 varHandler->m_State = VariableRequestHandlerState::RUNNING;
642 executeVarRequest(var, varRequest);
641 executeVarRequest(var, varRequest);
643 break;
642 break;
644 }
643 }
645 case VariableRequestHandlerState::RUNNING: {
644 case VariableRequestHandlerState::RUNNING: {
646 qCCritical(LOG_VariableController()) << tr("Process Request RUNNING")
645 qCDebug(LOG_VariableController()) << tr("Process Request RUNNING")
647 << varRequest.m_RangeRequested
646 << varRequest.m_RangeRequested
648 << varRequest.m_CacheRangeRequested;
647 << varRequest.m_CacheRangeRequested;
649 varHandler->m_State = VariableRequestHandlerState::PENDING;
648 varHandler->m_State = VariableRequestHandlerState::PENDING;
650 varHandler->m_PendingVarRequest = varRequest;
649 varHandler->m_PendingVarRequest = varRequest;
651 break;
650 break;
652 }
651 }
653 case VariableRequestHandlerState::PENDING: {
652 case VariableRequestHandlerState::PENDING: {
654 qCCritical(LOG_VariableController()) << tr("Process Request PENDING")
653 qCDebug(LOG_VariableController()) << tr("Process Request PENDING")
655 << varRequest.m_RangeRequested
654 << varRequest.m_RangeRequested
656 << varRequest.m_CacheRangeRequested;
655 << varRequest.m_CacheRangeRequested;
657 auto variableGroupIdToCancel = varHandler->m_PendingVarRequest.m_VariableGroupId;
656 auto variableGroupIdToCancel = varHandler->m_PendingVarRequest.m_VariableGroupId;
658 varHandler->m_PendingVarRequest = varRequest;
657 varHandler->m_PendingVarRequest = varRequest;
659 cancelVariableRequest(variableGroupIdToCancel);
658 cancelVariableRequest(variableGroupIdToCancel);
660
659
661 break;
660 break;
662 }
661 }
663 default:
662 default:
664 qCCritical(LOG_VariableController())
663 qCCritical(LOG_VariableController())
665 << QObject::tr("Unknown VariableRequestHandlerState");
664 << QObject::tr("Unknown VariableRequestHandlerState");
666 }
665 }
667 }
666 }
668
667
669 std::shared_ptr<Variable>
668 std::shared_ptr<Variable>
670 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
669 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
671 {
670 {
672 std::shared_ptr<Variable> var;
671 std::shared_ptr<Variable> var;
673 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
672 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
674
673
675 auto end = m_VariableToIdentifierMap.cend();
674 auto end = m_VariableToIdentifierMap.cend();
676 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
675 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
677 if (it != end) {
676 if (it != end) {
678 var = it->first;
677 var = it->first;
679 }
678 }
680 else {
679 else {
681 qCCritical(LOG_VariableController())
680 qCCritical(LOG_VariableController())
682 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
681 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
683 }
682 }
684
683
685 return var;
684 return var;
686 }
685 }
687
686
688 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
687 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
689 const QVector<AcquisitionDataPacket> acqDataPacketVector)
688 const QVector<AcquisitionDataPacket> acqDataPacketVector)
690 {
689 {
691 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
690 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
692 << acqDataPacketVector.size();
691 << acqDataPacketVector.size();
693 std::shared_ptr<IDataSeries> dataSeries;
692 std::shared_ptr<IDataSeries> dataSeries;
694 if (!acqDataPacketVector.isEmpty()) {
693 if (!acqDataPacketVector.isEmpty()) {
695 dataSeries = acqDataPacketVector[0].m_DateSeries;
694 dataSeries = acqDataPacketVector[0].m_DateSeries;
696 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
695 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
697 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
696 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
698 }
697 }
699 }
698 }
700 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
699 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
701 << acqDataPacketVector.size();
700 << acqDataPacketVector.size();
702 return dataSeries;
701 return dataSeries;
703 }
702 }
704
703
705 void VariableController::VariableControllerPrivate::registerProvider(
704 void VariableController::VariableControllerPrivate::registerProvider(
706 std::shared_ptr<IDataProvider> provider)
705 std::shared_ptr<IDataProvider> provider)
707 {
706 {
708 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
707 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
709 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
708 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
710 << provider->objectName();
709 << provider->objectName();
711 m_ProviderSet.insert(provider);
710 m_ProviderSet.insert(provider);
712 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
711 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
713 &VariableAcquisitionWorker::onVariableDataAcquired);
712 &VariableAcquisitionWorker::onVariableDataAcquired);
714 connect(provider.get(), &IDataProvider::dataProvidedProgress,
713 connect(provider.get(), &IDataProvider::dataProvidedProgress,
715 m_VariableAcquisitionWorker.get(),
714 m_VariableAcquisitionWorker.get(),
716 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
715 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
717 connect(provider.get(), &IDataProvider::dataProvidedFailed,
716 connect(provider.get(), &IDataProvider::dataProvidedFailed,
718 m_VariableAcquisitionWorker.get(),
717 m_VariableAcquisitionWorker.get(),
719 &VariableAcquisitionWorker::onVariableAcquisitionFailed);
718 &VariableAcquisitionWorker::onVariableAcquisitionFailed);
720 }
719 }
721 else {
720 else {
722 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
721 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
723 }
722 }
724 }
723 }
725
724
726 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
725 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
727 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
726 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
728 {
727 {
729 auto itVarHandler = m_VarIdToVarRequestHandler.find(varId);
728 auto itVarHandler = m_VarIdToVarRequestHandler.find(varId);
730 if (itVarHandler == m_VarIdToVarRequestHandler.cend()) {
729 if (itVarHandler == m_VarIdToVarRequestHandler.cend()) {
731 return QUuid();
730 return QUuid();
732 }
731 }
733
732
734 auto varHandler = itVarHandler->second.get();
733 auto varHandler = itVarHandler->second.get();
735 if (varHandler->m_State == VariableRequestHandlerState::OFF) {
734 if (varHandler->m_State == VariableRequestHandlerState::OFF) {
736 // TODO log impossible case !!!
735 // TODO log impossible case !!!
737 }
736 }
738
737
739 varHandler->m_RunningVarRequest.m_DataSeries = dataSeries;
738 varHandler->m_RunningVarRequest.m_DataSeries = dataSeries;
740 varHandler->m_CanUpdate = true;
739 varHandler->m_CanUpdate = true;
741
740
742 // Element traitΓ©, on a dΓ©jΓ  toutes les donnΓ©es necessaires
741 // Element traitΓ©, on a dΓ©jΓ  toutes les donnΓ©es necessaires
743 auto varGroupId = varHandler->m_RunningVarRequest.m_VariableGroupId;
742 auto varGroupId = varHandler->m_RunningVarRequest.m_VariableGroupId;
744 qCInfo(LOG_VariableController()) << "Variable::acceptVariableRequest" << varGroupId
743 qCDebug(LOG_VariableController()) << "Variable::acceptVariableRequest" << varGroupId
745 << m_VarGroupIdToVarIds.size();
744 << m_VarGroupIdToVarIds.size();
746
745
747 return varHandler->m_RunningVarRequest.m_VariableGroupId;
746 return varHandler->m_RunningVarRequest.m_VariableGroupId;
748 }
747 }
749
748
750 void VariableController::VariableControllerPrivate::updateVariables(QUuid varRequestId)
749 void VariableController::VariableControllerPrivate::updateVariables(QUuid varRequestId)
751 {
750 {
752 qCInfo(LOG_VariableController()) << "VariableControllerPrivate::updateVariables"
751 qCDebug(LOG_VariableController()) << "VariableControllerPrivate::updateVariables"
753 << QThread::currentThread()->objectName() << varRequestId;
752 << QThread::currentThread()->objectName() << varRequestId;
754
753
755 auto varGroupIdToVarIdsIt = m_VarGroupIdToVarIds.find(varRequestId);
754 auto varGroupIdToVarIdsIt = m_VarGroupIdToVarIds.find(varRequestId);
756 if (varGroupIdToVarIdsIt == m_VarGroupIdToVarIds.end()) {
755 if (varGroupIdToVarIdsIt == m_VarGroupIdToVarIds.end()) {
757 // TODO LOG cannot update since varGroupdId isn't here anymore
756 qCWarning(LOG_VariableController())
758 qCInfo(LOG_VariableController()) << "Impossible to updateVariables of unknown variables"
757 << tr("Impossible to updateVariables of unknown variables") << varRequestId;
759 << varRequestId;
760 return;
758 return;
761 }
759 }
762
760
763 auto &varIds = varGroupIdToVarIdsIt->second;
761 auto &varIds = varGroupIdToVarIdsIt->second;
764 auto varIdsEnd = varIds.end();
762 auto varIdsEnd = varIds.end();
765 bool processVariableUpdate = true;
763 bool processVariableUpdate = true;
766 qCInfo(LOG_VariableController())
767 << "VariableControllerPrivate::compute procss for group of size" << varIds.size();
768 for (auto varIdsIt = varIds.begin(); (varIdsIt != varIdsEnd) && processVariableUpdate;
764 for (auto varIdsIt = varIds.begin(); (varIdsIt != varIdsEnd) && processVariableUpdate;
769 ++varIdsIt) {
765 ++varIdsIt) {
770 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
766 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
771 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
767 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
772 processVariableUpdate &= itVarHandler->second->m_CanUpdate;
768 processVariableUpdate &= itVarHandler->second->m_CanUpdate;
773 }
769 }
774 }
770 }
775
771
776 if (processVariableUpdate) {
772 if (processVariableUpdate) {
777 qCInfo(LOG_VariableController()) << "Final update OK for the var request" << varIds.size();
773 qCDebug(LOG_VariableController()) << "Final update OK for the var request" << varIds.size();
778 for (auto varIdsIt = varIds.begin(); varIdsIt != varIdsEnd; ++varIdsIt) {
774 for (auto varIdsIt = varIds.begin(); varIdsIt != varIdsEnd; ++varIdsIt) {
779 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
775 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
780 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
776 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
781 if (auto var = findVariable(*varIdsIt)) {
777 if (auto var = findVariable(*varIdsIt)) {
782 auto &varRequest = itVarHandler->second->m_RunningVarRequest;
778 auto &varRequest = itVarHandler->second->m_RunningVarRequest;
783 var->setRange(varRequest.m_RangeRequested);
779 var->setRange(varRequest.m_RangeRequested);
784 var->setCacheRange(varRequest.m_CacheRangeRequested);
780 var->setCacheRange(varRequest.m_CacheRangeRequested);
785 qCInfo(LOG_VariableController()) << tr("1: onDataProvided")
781 qCDebug(LOG_VariableController()) << tr("1: onDataProvided")
786 << varRequest.m_RangeRequested
782 << varRequest.m_RangeRequested
787 << varRequest.m_CacheRangeRequested;
783 << varRequest.m_CacheRangeRequested;
788 qCInfo(LOG_VariableController()) << tr("2: onDataProvided var points before")
784 qCDebug(LOG_VariableController()) << tr("2: onDataProvided var points before")
789 << var->nbPoints()
785 << var->nbPoints()
790 << varRequest.m_DataSeries->nbPoints();
786 << varRequest.m_DataSeries->nbPoints();
791 var->mergeDataSeries(varRequest.m_DataSeries);
787 var->mergeDataSeries(varRequest.m_DataSeries);
792 qCInfo(LOG_VariableController()) << tr("3: onDataProvided var points after")
788 qCDebug(LOG_VariableController()) << tr("3: onDataProvided var points after")
793 << var->nbPoints();
789 << var->nbPoints();
794
790
795 emit var->updated();
791 emit var->updated();
796 qCCritical(LOG_VariableController()) << tr("Update OK");
792 qCDebug(LOG_VariableController()) << tr("Update OK");
797 }
793 }
798 else {
794 else {
799 qCCritical(LOG_VariableController())
795 qCCritical(LOG_VariableController())
800 << tr("Impossible to update data to a null variable");
796 << tr("Impossible to update data to a null variable");
801 }
797 }
802 }
798 }
803 }
799 }
804 updateVariableRequest(varRequestId);
800 updateVariableRequest(varRequestId);
805
801
806 // cleaning varRequestId
802 // cleaning varRequestId
807 qCInfo(LOG_VariableController()) << tr("m_VarGroupIdToVarIds erase") << varRequestId;
803 qCDebug(LOG_VariableController()) << tr("m_VarGroupIdToVarIds erase") << varRequestId;
808 m_VarGroupIdToVarIds.erase(varRequestId);
804 m_VarGroupIdToVarIds.erase(varRequestId);
809 }
805 }
810 }
806 }
811
807
812
808
813 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
809 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
814 {
810 {
815 auto varGroupIdToVarIdsIt = m_VarGroupIdToVarIds.find(varRequestId);
811 auto varGroupIdToVarIdsIt = m_VarGroupIdToVarIds.find(varRequestId);
816 if (varGroupIdToVarIdsIt == m_VarGroupIdToVarIds.end()) {
812 if (varGroupIdToVarIdsIt == m_VarGroupIdToVarIds.end()) {
817 // TODO LOG cannot update variable request since varGroupdId isn't here anymore
813 // TODO LOG cannot update variable request since varGroupdId isn't here anymore
818 return;
814 return;
819 }
815 }
820
816
821 auto &varIds = varGroupIdToVarIdsIt->second;
817 auto &varIds = varGroupIdToVarIdsIt->second;
822 auto varIdsEnd = varIds.end();
818 auto varIdsEnd = varIds.end();
823 for (auto varIdsIt = varIds.begin(); (varIdsIt != varIdsEnd); ++varIdsIt) {
819 for (auto varIdsIt = varIds.begin(); (varIdsIt != varIdsEnd); ++varIdsIt) {
824 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
820 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
825 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
821 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
826
822
827 auto varHandler = itVarHandler->second.get();
823 auto varHandler = itVarHandler->second.get();
828 varHandler->m_CanUpdate = false;
824 varHandler->m_CanUpdate = false;
829
825
830
826
831 switch (varHandler->m_State) {
827 switch (varHandler->m_State) {
832 case VariableRequestHandlerState::OFF: {
828 case VariableRequestHandlerState::OFF: {
833 qCCritical(LOG_VariableController())
829 qCCritical(LOG_VariableController())
834 << QObject::tr("Impossible to update a variable with handler in OFF state");
830 << QObject::tr("Impossible to update a variable with handler in OFF state");
835 } break;
831 } break;
836 case VariableRequestHandlerState::RUNNING: {
832 case VariableRequestHandlerState::RUNNING: {
837 varHandler->m_State = VariableRequestHandlerState::OFF;
833 varHandler->m_State = VariableRequestHandlerState::OFF;
838 varHandler->m_RunningVarRequest = VariableRequest{};
834 varHandler->m_RunningVarRequest = VariableRequest{};
839 break;
835 break;
840 }
836 }
841 case VariableRequestHandlerState::PENDING: {
837 case VariableRequestHandlerState::PENDING: {
842 varHandler->m_State = VariableRequestHandlerState::RUNNING;
838 varHandler->m_State = VariableRequestHandlerState::RUNNING;
843 varHandler->m_RunningVarRequest = varHandler->m_PendingVarRequest;
839 varHandler->m_RunningVarRequest = varHandler->m_PendingVarRequest;
844 varHandler->m_PendingVarRequest = VariableRequest{};
840 varHandler->m_PendingVarRequest = VariableRequest{};
845 auto var = findVariable(itVarHandler->first);
841 auto var = findVariable(itVarHandler->first);
846 executeVarRequest(var, varHandler->m_RunningVarRequest);
842 executeVarRequest(var, varHandler->m_RunningVarRequest);
847 break;
843 break;
848 }
844 }
849 default:
845 default:
850 qCCritical(LOG_VariableController())
846 qCCritical(LOG_VariableController())
851 << QObject::tr("Unknown VariableRequestHandlerState");
847 << QObject::tr("Unknown VariableRequestHandlerState");
852 }
848 }
853 }
849 }
854 }
850 }
855 }
851 }
856
852
857
853
858 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
854 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
859 {
855 {
856 qCDebug(LOG_VariableController()) << tr("cancelVariableRequest") << varRequestId;
857
860 auto varGroupIdToVarIdsIt = m_VarGroupIdToVarIds.find(varRequestId);
858 auto varGroupIdToVarIdsIt = m_VarGroupIdToVarIds.find(varRequestId);
861 if (varGroupIdToVarIdsIt == m_VarGroupIdToVarIds.end()) {
859 if (varGroupIdToVarIdsIt == m_VarGroupIdToVarIds.end()) {
862 qCCritical(LOG_VariableController())
860 qCCritical(LOG_VariableController())
863 << tr("Impossible to cancelVariableRequest for unknown varGroupdId") << varRequestId;
861 << tr("Impossible to cancelVariableRequest for unknown varGroupdId") << varRequestId;
864 return;
862 return;
865 }
863 }
866
864
867 auto &varIds = varGroupIdToVarIdsIt->second;
865 auto &varIds = varGroupIdToVarIdsIt->second;
868 auto varIdsEnd = varIds.end();
866 auto varIdsEnd = varIds.end();
869 for (auto varIdsIt = varIds.begin(); (varIdsIt != varIdsEnd); ++varIdsIt) {
867 for (auto varIdsIt = varIds.begin(); (varIdsIt != varIdsEnd); ++varIdsIt) {
870 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
868 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
871 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
869 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
872
870
873 auto varHandler = itVarHandler->second.get();
871 auto varHandler = itVarHandler->second.get();
874 varHandler->m_CanUpdate = false;
872 varHandler->m_CanUpdate = false;
875 varHandler->m_VarId = QUuid{};
873 varHandler->m_VarId = QUuid{};
876 switch (varHandler->m_State) {
874 switch (varHandler->m_State) {
877 case VariableRequestHandlerState::OFF: {
875 case VariableRequestHandlerState::OFF: {
878 qCWarning(LOG_VariableController())
876 qCWarning(LOG_VariableController())
879 << QObject::tr("Impossible to cancel a variable with no running request");
877 << QObject::tr("Impossible to cancel a variable with no running request");
880 break;
878 break;
881 }
879 }
882 case VariableRequestHandlerState::RUNNING: {
880 case VariableRequestHandlerState::RUNNING: {
883
881
884 if (varHandler->m_RunningVarRequest.m_VariableGroupId == varRequestId) {
882 if (varHandler->m_RunningVarRequest.m_VariableGroupId == varRequestId) {
885 auto var = findVariable(itVarHandler->first);
883 auto var = findVariable(itVarHandler->first);
886 auto varProvider = m_VariableToProviderMap.at(var);
884 auto varProvider = m_VariableToProviderMap.at(var);
887 if (varProvider != nullptr) {
885 if (varProvider != nullptr) {
888 m_VariableAcquisitionWorker->abortProgressRequested(
886 m_VariableAcquisitionWorker->abortProgressRequested(
889 itVarHandler->first);
887 itVarHandler->first);
890 }
888 }
891 m_VariableModel->setDataProgress(var, 0.0);
889 m_VariableModel->setDataProgress(var, 0.0);
892 varHandler->m_State = VariableRequestHandlerState::OFF;
890 varHandler->m_State = VariableRequestHandlerState::OFF;
893 varHandler->m_RunningVarRequest = VariableRequest{};
891 varHandler->m_RunningVarRequest = VariableRequest{};
894 }
892 }
895 else {
893 else {
896 // TODO: log Impossible to cancel the running variable request beacause its
894 // TODO: log Impossible to cancel the running variable request beacause its
897 // varRequestId isn't not the canceled one
895 // varRequestId isn't not the canceled one
898 }
896 }
899 break;
897 break;
900 }
898 }
901 case VariableRequestHandlerState::PENDING: {
899 case VariableRequestHandlerState::PENDING: {
902 if (varHandler->m_RunningVarRequest.m_VariableGroupId == varRequestId) {
900 if (varHandler->m_RunningVarRequest.m_VariableGroupId == varRequestId) {
903 auto var = findVariable(itVarHandler->first);
901 auto var = findVariable(itVarHandler->first);
904 auto varProvider = m_VariableToProviderMap.at(var);
902 auto varProvider = m_VariableToProviderMap.at(var);
905 if (varProvider != nullptr) {
903 if (varProvider != nullptr) {
906 m_VariableAcquisitionWorker->abortProgressRequested(
904 m_VariableAcquisitionWorker->abortProgressRequested(
907 itVarHandler->first);
905 itVarHandler->first);
908 }
906 }
909 m_VariableModel->setDataProgress(var, 0.0);
907 m_VariableModel->setDataProgress(var, 0.0);
910 varHandler->m_State = VariableRequestHandlerState::RUNNING;
908 varHandler->m_State = VariableRequestHandlerState::RUNNING;
911 varHandler->m_RunningVarRequest = varHandler->m_PendingVarRequest;
909 varHandler->m_RunningVarRequest = varHandler->m_PendingVarRequest;
912 executeVarRequest(var, varHandler->m_RunningVarRequest);
910 executeVarRequest(var, varHandler->m_RunningVarRequest);
913 }
911 }
914 else if (varHandler->m_PendingVarRequest.m_VariableGroupId == varRequestId) {
912 else if (varHandler->m_PendingVarRequest.m_VariableGroupId == varRequestId) {
915 varHandler->m_State = VariableRequestHandlerState::RUNNING;
913 varHandler->m_State = VariableRequestHandlerState::RUNNING;
916 varHandler->m_PendingVarRequest = VariableRequest{};
914 varHandler->m_PendingVarRequest = VariableRequest{};
917 }
915 }
918 else {
916 else {
919 // TODO: log Impossible to cancel the variable request beacause its
917 // TODO: log Impossible to cancel the variable request beacause its
920 // varRequestId isn't not the canceled one
918 // varRequestId isn't not the canceled one
921 }
919 }
922 break;
920 break;
923 }
921 }
924 default:
922 default:
925 qCCritical(LOG_VariableController())
923 qCCritical(LOG_VariableController())
926 << QObject::tr("Unknown VariableRequestHandlerState");
924 << QObject::tr("Unknown VariableRequestHandlerState");
927 }
925 }
928 }
926 }
929 }
927 }
928 qCDebug(LOG_VariableController()) << tr("cancelVariableRequest: erase") << varRequestId;
930 m_VarGroupIdToVarIds.erase(varRequestId);
929 m_VarGroupIdToVarIds.erase(varRequestId);
931 }
930 }
932
931
933 void VariableController::VariableControllerPrivate::executeVarRequest(std::shared_ptr<Variable> var,
932 void VariableController::VariableControllerPrivate::executeVarRequest(std::shared_ptr<Variable> var,
934 VariableRequest &varRequest)
933 VariableRequest &varRequest)
935 {
934 {
936 qCCritical(LOG_VariableController()) << tr("TORM: executeVarRequest");
935 qCDebug(LOG_VariableController()) << tr("TORM: executeVarRequest");
937
936
938 auto varId = m_VariableToIdentifierMap.at(var);
937 auto varId = m_VariableToIdentifierMap.at(var);
939
938
940 auto varCacheRange = var->cacheRange();
939 auto varCacheRange = var->cacheRange();
941 auto varCacheRangeRequested = varRequest.m_CacheRangeRequested;
940 auto varCacheRangeRequested = varRequest.m_CacheRangeRequested;
942 auto notInCacheRangeList
941 auto notInCacheRangeList
943 = Variable::provideNotInCacheRangeList(varCacheRange, varCacheRangeRequested);
942 = Variable::provideNotInCacheRangeList(varCacheRange, varCacheRangeRequested);
944 // auto inCacheRangeList
943 // auto inCacheRangeList
945 // = Variable::provideInCacheRangeList(varCacheRange, varCacheRangeRequested);
944 // = Variable::provideInCacheRangeList(varCacheRange, varCacheRangeRequested);
946
945
947 if (!notInCacheRangeList.empty()) {
946 if (!notInCacheRangeList.empty()) {
948
947
949 auto varProvider = m_VariableToProviderMap.at(var);
948 auto varProvider = m_VariableToProviderMap.at(var);
950 if (varProvider != nullptr) {
949 if (varProvider != nullptr) {
951 qCCritical(LOG_VariableController()) << "executeVarRequest "
950 qCDebug(LOG_VariableController()) << "executeVarRequest " << varRequest.m_RangeRequested
952 << varRequest.m_RangeRequested
951 << varRequest.m_CacheRangeRequested;
953 << varRequest.m_CacheRangeRequested;
954 m_VariableAcquisitionWorker->pushVariableRequest(
952 m_VariableAcquisitionWorker->pushVariableRequest(
955 varRequest.m_VariableGroupId, varId, varRequest.m_RangeRequested,
953 varRequest.m_VariableGroupId, varId, varRequest.m_RangeRequested,
956 varRequest.m_CacheRangeRequested,
954 varRequest.m_CacheRangeRequested,
957 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
955 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
958 varProvider);
956 varProvider);
959 }
957 }
960 else {
958 else {
961 qCCritical(LOG_VariableController())
959 qCCritical(LOG_VariableController())
962 << "Impossible to provide data with a null provider";
960 << "Impossible to provide data with a null provider";
963 }
961 }
964
962
965 // if (!inCacheRangeList.empty()) {
963 // if (!inCacheRangeList.empty()) {
966 // emit q->updateVarDisplaying(var, inCacheRangeList.first());
964 // emit q->updateVarDisplaying(var, inCacheRangeList.first());
967 // }
965 // }
968 }
966 }
969 else {
967 else {
970 acceptVariableRequest(varId,
968 acceptVariableRequest(varId,
971 var->dataSeries()->subDataSeries(varRequest.m_CacheRangeRequested));
969 var->dataSeries()->subDataSeries(varRequest.m_CacheRangeRequested));
972 }
970 }
973 }
971 }
@@ -1,285 +1,282
1 #include "AmdaProvider.h"
1 #include "AmdaProvider.h"
2 #include "AmdaDefs.h"
2 #include "AmdaDefs.h"
3 #include "AmdaResultParser.h"
3 #include "AmdaResultParser.h"
4
4
5 #include <Common/DateUtils.h>
5 #include <Common/DateUtils.h>
6 #include <Data/DataProviderParameters.h>
6 #include <Data/DataProviderParameters.h>
7 #include <Network/NetworkController.h>
7 #include <Network/NetworkController.h>
8 #include <SqpApplication.h>
8 #include <SqpApplication.h>
9 #include <Variable/Variable.h>
9 #include <Variable/Variable.h>
10
10
11 #include <QNetworkAccessManager>
11 #include <QNetworkAccessManager>
12 #include <QNetworkReply>
12 #include <QNetworkReply>
13 #include <QTemporaryFile>
13 #include <QTemporaryFile>
14 #include <QThread>
14 #include <QThread>
15
15
16 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
16 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
17
17
18 namespace {
18 namespace {
19
19
20 /// URL format for a request on AMDA server. The parameters are as follows:
20 /// URL format for a request on AMDA server. The parameters are as follows:
21 /// - %1: start date
21 /// - %1: start date
22 /// - %2: end date
22 /// - %2: end date
23 /// - %3: parameter id
23 /// - %3: parameter id
24 /// AMDA V2: http://amdatest.irap.omp.eu/php/rest/
24 /// AMDA V2: http://amdatest.irap.omp.eu/php/rest/
25 const auto AMDA_URL_FORMAT = QStringLiteral(
25 const auto AMDA_URL_FORMAT = QStringLiteral(
26 "http://amda.irap.omp.eu/php/rest/"
26 "http://amda.irap.omp.eu/php/rest/"
27 "getParameter.php?startTime=%1&stopTime=%2&parameterID=%3&outputFormat=ASCII&"
27 "getParameter.php?startTime=%1&stopTime=%2&parameterID=%3&outputFormat=ASCII&"
28 "timeFormat=ISO8601&gzip=0");
28 "timeFormat=ISO8601&gzip=0");
29
29
30 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
30 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
31 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
31 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
32
32
33 /// Formats a time to a date that can be passed in URL
33 /// Formats a time to a date that can be passed in URL
34 QString dateFormat(double sqpRange) noexcept
34 QString dateFormat(double sqpRange) noexcept
35 {
35 {
36 auto dateTime = DateUtils::dateTime(sqpRange);
36 auto dateTime = DateUtils::dateTime(sqpRange);
37 return dateTime.toString(AMDA_TIME_FORMAT);
37 return dateTime.toString(AMDA_TIME_FORMAT);
38 }
38 }
39
39
40 AmdaResultParser::ValueType valueType(const QString &valueType)
40 AmdaResultParser::ValueType valueType(const QString &valueType)
41 {
41 {
42 if (valueType == QStringLiteral("scalar")) {
42 if (valueType == QStringLiteral("scalar")) {
43 return AmdaResultParser::ValueType::SCALAR;
43 return AmdaResultParser::ValueType::SCALAR;
44 }
44 }
45 else if (valueType == QStringLiteral("vector")) {
45 else if (valueType == QStringLiteral("vector")) {
46 return AmdaResultParser::ValueType::VECTOR;
46 return AmdaResultParser::ValueType::VECTOR;
47 }
47 }
48 else {
48 else {
49 return AmdaResultParser::ValueType::UNKNOWN;
49 return AmdaResultParser::ValueType::UNKNOWN;
50 }
50 }
51 }
51 }
52
52
53 } // namespace
53 } // namespace
54
54
55 AmdaProvider::AmdaProvider()
55 AmdaProvider::AmdaProvider()
56 {
56 {
57 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::AmdaProvider") << QThread::currentThread();
57 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::AmdaProvider") << QThread::currentThread();
58 if (auto app = sqpApp) {
58 if (auto app = sqpApp) {
59 auto &networkController = app->networkController();
59 auto &networkController = app->networkController();
60 connect(this, SIGNAL(requestConstructed(std::shared_ptr<QNetworkRequest>, QUuid,
60 connect(this, SIGNAL(requestConstructed(std::shared_ptr<QNetworkRequest>, QUuid,
61 std::function<void(QNetworkReply *, QUuid)>)),
61 std::function<void(QNetworkReply *, QUuid)>)),
62 &networkController,
62 &networkController,
63 SLOT(onProcessRequested(std::shared_ptr<QNetworkRequest>, QUuid,
63 SLOT(onProcessRequested(std::shared_ptr<QNetworkRequest>, QUuid,
64 std::function<void(QNetworkReply *, QUuid)>)));
64 std::function<void(QNetworkReply *, QUuid)>)));
65
65
66
66
67 connect(&sqpApp->networkController(),
67 connect(&sqpApp->networkController(),
68 SIGNAL(replyDownloadProgress(QUuid, std::shared_ptr<QNetworkRequest>, double)),
68 SIGNAL(replyDownloadProgress(QUuid, std::shared_ptr<QNetworkRequest>, double)),
69 this,
69 this,
70 SLOT(onReplyDownloadProgress(QUuid, std::shared_ptr<QNetworkRequest>, double)));
70 SLOT(onReplyDownloadProgress(QUuid, std::shared_ptr<QNetworkRequest>, double)));
71 }
71 }
72 }
72 }
73
73
74 std::shared_ptr<IDataProvider> AmdaProvider::clone() const
74 std::shared_ptr<IDataProvider> AmdaProvider::clone() const
75 {
75 {
76 // No copy is made in the clone
76 // No copy is made in the clone
77 return std::make_shared<AmdaProvider>();
77 return std::make_shared<AmdaProvider>();
78 }
78 }
79
79
80 void AmdaProvider::requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters)
80 void AmdaProvider::requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters)
81 {
81 {
82 // NOTE: Try to use multithread if possible
82 // NOTE: Try to use multithread if possible
83 const auto times = parameters.m_Times;
83 const auto times = parameters.m_Times;
84 const auto data = parameters.m_Data;
84 const auto data = parameters.m_Data;
85 for (const auto &dateTime : qAsConst(times)) {
85 for (const auto &dateTime : qAsConst(times)) {
86 qCDebug(LOG_AmdaProvider()) << tr("TORM AmdaProvider::requestDataLoading ") << acqIdentifier
86 qCDebug(LOG_AmdaProvider()) << tr("TORM AmdaProvider::requestDataLoading ") << acqIdentifier
87 << dateTime;
87 << dateTime;
88 this->retrieveData(acqIdentifier, dateTime, data);
88 this->retrieveData(acqIdentifier, dateTime, data);
89
89
90
90
91 // TORM when AMDA will support quick asynchrone request
91 // TORM when AMDA will support quick asynchrone request
92 QThread::msleep(1000);
92 QThread::msleep(1000);
93 }
93 }
94 }
94 }
95
95
96 void AmdaProvider::requestDataAborting(QUuid acqIdentifier)
96 void AmdaProvider::requestDataAborting(QUuid acqIdentifier)
97 {
97 {
98 if (auto app = sqpApp) {
98 if (auto app = sqpApp) {
99 auto &networkController = app->networkController();
99 auto &networkController = app->networkController();
100 networkController.onReplyCanceled(acqIdentifier);
100 networkController.onReplyCanceled(acqIdentifier);
101 }
101 }
102 }
102 }
103
103
104 void AmdaProvider::onReplyDownloadProgress(QUuid acqIdentifier,
104 void AmdaProvider::onReplyDownloadProgress(QUuid acqIdentifier,
105 std::shared_ptr<QNetworkRequest> networkRequest,
105 std::shared_ptr<QNetworkRequest> networkRequest,
106 double progress)
106 double progress)
107 {
107 {
108 qCDebug(LOG_AmdaProvider()) << tr("onReplyDownloadProgress") << acqIdentifier
108 qCDebug(LOG_AmdaProvider()) << tr("onReplyDownloadProgress") << acqIdentifier
109 << networkRequest.get() << progress;
109 << networkRequest.get() << progress;
110 auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
110 auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
111 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
111 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
112
112
113 // Update the progression for the current request
113 // Update the progression for the current request
114 auto requestPtr = networkRequest;
114 auto requestPtr = networkRequest;
115 auto findRequest = [requestPtr](const auto &entry) { return requestPtr == entry.first; };
115 auto findRequest = [requestPtr](const auto &entry) { return requestPtr == entry.first; };
116
116
117 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
117 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
118 auto requestProgressMapEnd = requestProgressMap.end();
118 auto requestProgressMapEnd = requestProgressMap.end();
119 auto requestProgressMapIt
119 auto requestProgressMapIt
120 = std::find_if(requestProgressMap.begin(), requestProgressMapEnd, findRequest);
120 = std::find_if(requestProgressMap.begin(), requestProgressMapEnd, findRequest);
121
121
122 if (requestProgressMapIt != requestProgressMapEnd) {
122 if (requestProgressMapIt != requestProgressMapEnd) {
123 requestProgressMapIt->second = progress;
123 requestProgressMapIt->second = progress;
124 }
124 }
125 else {
125 else {
126 // This case can happened when a progression is send after the request has been
126 // This case can happened when a progression is send after the request has been
127 // finished.
127 // finished.
128 // Generaly the case when aborting a request
128 // Generaly the case when aborting a request
129 qCDebug(LOG_AmdaProvider()) << tr("Can't retrieve Request in progress") << acqIdentifier
129 qCDebug(LOG_AmdaProvider()) << tr("Can't retrieve Request in progress") << acqIdentifier
130 << networkRequest.get() << progress;
130 << networkRequest.get() << progress;
131 }
131 }
132
132
133 // Compute the current final progress and notify it
133 // Compute the current final progress and notify it
134 double finalProgress = 0.0;
134 double finalProgress = 0.0;
135
135
136 auto fraq = requestProgressMap.size();
136 auto fraq = requestProgressMap.size();
137
137
138 for (auto requestProgress : requestProgressMap) {
138 for (auto requestProgress : requestProgressMap) {
139 finalProgress += requestProgress.second;
139 finalProgress += requestProgress.second;
140 qCDebug(LOG_AmdaProvider()) << tr("Current final progress without fraq:")
140 qCDebug(LOG_AmdaProvider()) << tr("Current final progress without fraq:")
141 << finalProgress << requestProgress.second;
141 << finalProgress << requestProgress.second;
142 }
142 }
143
143
144 if (fraq > 0) {
144 if (fraq > 0) {
145 finalProgress = finalProgress / fraq;
145 finalProgress = finalProgress / fraq;
146 }
146 }
147
147
148 qCDebug(LOG_AmdaProvider()) << tr("Current final progress: ") << fraq << finalProgress;
148 qCDebug(LOG_AmdaProvider()) << tr("Current final progress: ") << fraq << finalProgress;
149 emit dataProvidedProgress(acqIdentifier, finalProgress);
149 emit dataProvidedProgress(acqIdentifier, finalProgress);
150 }
150 }
151 else {
151 else {
152 // This case can happened when a progression is send after the request has been finished.
152 // This case can happened when a progression is send after the request has been finished.
153 // Generaly the case when aborting a request
153 // Generaly the case when aborting a request
154 emit dataProvidedProgress(acqIdentifier, 100.0);
154 emit dataProvidedProgress(acqIdentifier, 100.0);
155 }
155 }
156 }
156 }
157
157
158 void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVariantHash &data)
158 void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVariantHash &data)
159 {
159 {
160 // Retrieves product ID from data: if the value is invalid, no request is made
160 // Retrieves product ID from data: if the value is invalid, no request is made
161 auto productId = data.value(AMDA_XML_ID_KEY).toString();
161 auto productId = data.value(AMDA_XML_ID_KEY).toString();
162 if (productId.isNull()) {
162 if (productId.isNull()) {
163 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
163 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
164 return;
164 return;
165 }
165 }
166
166
167 // Retrieves the data type that determines whether the expected format for the result file is
167 // Retrieves the data type that determines whether the expected format for the result file is
168 // scalar, vector...
168 // scalar, vector...
169 auto productValueType = valueType(data.value(AMDA_DATA_TYPE_KEY).toString());
169 auto productValueType = valueType(data.value(AMDA_DATA_TYPE_KEY).toString());
170
170
171 // /////////// //
171 // /////////// //
172 // Creates URL //
172 // Creates URL //
173 // /////////// //
173 // /////////// //
174
174
175 auto startDate = dateFormat(dateTime.m_TStart);
175 auto startDate = dateFormat(dateTime.m_TStart);
176 auto endDate = dateFormat(dateTime.m_TEnd);
176 auto endDate = dateFormat(dateTime.m_TEnd);
177
177
178 auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
178 auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
179 qCInfo(LOG_AmdaProvider()) << tr("TORM AmdaProvider::retrieveData url:") << url;
179 qCInfo(LOG_AmdaProvider()) << tr("TORM AmdaProvider::retrieveData url:") << url;
180 auto tempFile = std::make_shared<QTemporaryFile>();
180 auto tempFile = std::make_shared<QTemporaryFile>();
181
181
182 // LAMBDA
182 // LAMBDA
183 auto httpDownloadFinished = [this, dateTime, tempFile,
183 auto httpDownloadFinished = [this, dateTime, tempFile,
184 productValueType](QNetworkReply *reply, QUuid dataId) noexcept {
184 productValueType](QNetworkReply *reply, QUuid dataId) noexcept {
185
185
186 // Don't do anything if the reply was abort
186 // Don't do anything if the reply was abort
187 if (reply->error() == QNetworkReply::NoError) {
187 if (reply->error() == QNetworkReply::NoError) {
188
188
189 if (tempFile) {
189 if (tempFile) {
190 auto replyReadAll = reply->readAll();
190 auto replyReadAll = reply->readAll();
191 if (!replyReadAll.isEmpty()) {
191 if (!replyReadAll.isEmpty()) {
192 tempFile->write(replyReadAll);
192 tempFile->write(replyReadAll);
193 }
193 }
194 tempFile->close();
194 tempFile->close();
195
195
196 // Parse results file
196 // Parse results file
197 if (auto dataSeries
197 if (auto dataSeries
198 = AmdaResultParser::readTxt(tempFile->fileName(), productValueType)) {
198 = AmdaResultParser::readTxt(tempFile->fileName(), productValueType)) {
199 emit dataProvided(dataId, dataSeries, dateTime);
199 emit dataProvided(dataId, dataSeries, dateTime);
200 }
200 }
201 else {
201 else {
202 /// @todo ALX : debug
202 /// @todo ALX : debug
203 emit dataProvidedFailed(dataId);
203 emit dataProvidedFailed(dataId);
204 }
204 }
205 }
205 }
206 qCDebug(LOG_AmdaProvider()) << tr("acquisition requests erase because of finishing")
207 << dataId;
208 m_AcqIdToRequestProgressMap.erase(dataId);
206 m_AcqIdToRequestProgressMap.erase(dataId);
209 }
207 }
210 else {
208 else {
211 qCCritical(LOG_AmdaProvider()) << tr("httpDownloadFinished ERROR");
209 qCCritical(LOG_AmdaProvider()) << tr("httpDownloadFinished ERROR");
212 emit dataProvidedFailed(dataId);
210 emit dataProvidedFailed(dataId);
213 }
211 }
214
212
215 };
213 };
216 auto httpFinishedLambda
214 auto httpFinishedLambda
217 = [this, httpDownloadFinished, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
215 = [this, httpDownloadFinished, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
218
216
219 // Don't do anything if the reply was abort
217 // Don't do anything if the reply was abort
220 if (reply->error() == QNetworkReply::NoError) {
218 if (reply->error() == QNetworkReply::NoError) {
221 // AMDA v2: auto downloadFileUrl = QUrl{QString{reply->readAll()}.trimmed()};
219 // AMDA v2: auto downloadFileUrl = QUrl{QString{reply->readAll()}.trimmed()};
222 auto downloadFileUrl = QUrl{QString{reply->readAll()}};
220 auto downloadFileUrl = QUrl{QString{reply->readAll()}};
223
221
224 qCInfo(LOG_AmdaProvider())
222 qCInfo(LOG_AmdaProvider())
225 << tr("TORM AmdaProvider::retrieveData downloadFileUrl:") << downloadFileUrl;
223 << tr("TORM AmdaProvider::retrieveData downloadFileUrl:") << downloadFileUrl;
226 // Executes request for downloading file //
224 // Executes request for downloading file //
227
225
228 // Creates destination file
226 // Creates destination file
229 if (tempFile->open()) {
227 if (tempFile->open()) {
230 // Executes request and store the request for progression
228 // Executes request and store the request for progression
231 auto request = std::make_shared<QNetworkRequest>(downloadFileUrl);
229 auto request = std::make_shared<QNetworkRequest>(downloadFileUrl);
232 updateRequestProgress(dataId, request, 0.0);
230 updateRequestProgress(dataId, request, 0.0);
233 emit requestConstructed(request, dataId, httpDownloadFinished);
231 emit requestConstructed(request, dataId, httpDownloadFinished);
234 }
232 }
235 else {
233 else {
236 emit dataProvidedFailed(dataId);
234 emit dataProvidedFailed(dataId);
237 }
235 }
238 }
236 }
239 else {
237 else {
240 qCDebug(LOG_AmdaProvider())
241 << tr("acquisition requests erase because of aborting") << dataId;
242 qCCritical(LOG_AmdaProvider()) << tr("httpFinishedLambda ERROR");
238 qCCritical(LOG_AmdaProvider()) << tr("httpFinishedLambda ERROR");
243 m_AcqIdToRequestProgressMap.erase(dataId);
239 m_AcqIdToRequestProgressMap.erase(dataId);
244 emit dataProvidedFailed(dataId);
240 emit dataProvidedFailed(dataId);
245 }
241 }
246 };
242 };
247
243
248 // //////////////// //
244 // //////////////// //
249 // Executes request //
245 // Executes request //
250 // //////////////// //
246 // //////////////// //
251
247
252 auto request = std::make_shared<QNetworkRequest>(url);
248 auto request = std::make_shared<QNetworkRequest>(url);
253 qCDebug(LOG_AmdaProvider()) << tr("First Request creation") << request.get();
249 qCDebug(LOG_AmdaProvider()) << tr("First Request creation") << request.get();
254 updateRequestProgress(token, request, 0.0);
250 updateRequestProgress(token, request, 0.0);
255
251
256 emit requestConstructed(request, token, httpFinishedLambda);
252 emit requestConstructed(request, token, httpFinishedLambda);
257 }
253 }
258
254
259 void AmdaProvider::updateRequestProgress(QUuid acqIdentifier,
255 void AmdaProvider::updateRequestProgress(QUuid acqIdentifier,
260 std::shared_ptr<QNetworkRequest> request, double progress)
256 std::shared_ptr<QNetworkRequest> request, double progress)
261 {
257 {
258 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress request") << request.get();
262 auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
259 auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
263 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
260 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
264 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
261 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
265 auto requestProgressMapIt = requestProgressMap.find(request);
262 auto requestProgressMapIt = requestProgressMap.find(request);
266 if (requestProgressMapIt != requestProgressMap.end()) {
263 if (requestProgressMapIt != requestProgressMap.end()) {
267 requestProgressMapIt->second = progress;
264 requestProgressMapIt->second = progress;
268 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new progress for request")
265 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new progress for request")
269 << acqIdentifier << request.get() << progress;
266 << acqIdentifier << request.get() << progress;
270 }
267 }
271 else {
268 else {
272 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new request") << acqIdentifier
269 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new request") << acqIdentifier
273 << request.get() << progress;
270 << request.get() << progress;
274 acqIdToRequestProgressMapIt->second.insert(std::make_pair(request, progress));
271 acqIdToRequestProgressMapIt->second.insert(std::make_pair(request, progress));
275 }
272 }
276 }
273 }
277 else {
274 else {
278 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new acqIdentifier")
275 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new acqIdentifier")
279 << acqIdentifier << request.get() << progress;
276 << acqIdentifier << request.get() << progress;
280 auto requestProgressMap = std::map<std::shared_ptr<QNetworkRequest>, double>{};
277 auto requestProgressMap = std::map<std::shared_ptr<QNetworkRequest>, double>{};
281 requestProgressMap.insert(std::make_pair(request, progress));
278 requestProgressMap.insert(std::make_pair(request, progress));
282 m_AcqIdToRequestProgressMap.insert(
279 m_AcqIdToRequestProgressMap.insert(
283 std::make_pair(acqIdentifier, std::move(requestProgressMap)));
280 std::make_pair(acqIdentifier, std::move(requestProgressMap)));
284 }
281 }
285 }
282 }
@@ -1,237 +1,240
1 #include "AmdaResultParser.h"
1 #include "AmdaResultParser.h"
2
2
3 #include <Common/DateUtils.h>
3 #include <Common/DateUtils.h>
4 #include <Data/ScalarSeries.h>
4 #include <Data/ScalarSeries.h>
5 #include <Data/VectorSeries.h>
5 #include <Data/VectorSeries.h>
6
6
7 #include <QDateTime>
7 #include <QDateTime>
8 #include <QFile>
8 #include <QFile>
9 #include <QRegularExpression>
9 #include <QRegularExpression>
10
10
11 #include <cmath>
11 #include <cmath>
12
12
13 Q_LOGGING_CATEGORY(LOG_AmdaResultParser, "AmdaResultParser")
13 Q_LOGGING_CATEGORY(LOG_AmdaResultParser, "AmdaResultParser")
14
14
15 namespace {
15 namespace {
16
16
17 /// Message in result file when the file was not found on server
17 /// Message in result file when the file was not found on server
18 const auto FILE_NOT_FOUND_MESSAGE = QStringLiteral("Not Found");
18 const auto FILE_NOT_FOUND_MESSAGE = QStringLiteral("Not Found");
19
19
20 /// Separator between values in a result line
20 /// Separator between values in a result line
21 const auto RESULT_LINE_SEPARATOR = QRegularExpression{QStringLiteral("\\s+")};
21 const auto RESULT_LINE_SEPARATOR = QRegularExpression{QStringLiteral("\\s+")};
22
22
23 // AMDA V2
23 // AMDA V2
24 // /// Regex to find the header of the data in the file. This header indicates the end of comments
24 // /// Regex to find the header of the data in the file. This header indicates the end of comments
25 // in
25 // in
26 // /// the file
26 // /// the file
27 // const auto DATA_HEADER_REGEX = QRegularExpression{QStringLiteral("#\\s*DATA\\s*:")};
27 // const auto DATA_HEADER_REGEX = QRegularExpression{QStringLiteral("#\\s*DATA\\s*:")};
28
28
29 /// Format for dates in result files
29 /// Format for dates in result files
30 const auto DATE_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss.zzz");
30 const auto DATE_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss.zzz");
31
31
32 // AMDA V2
32 // AMDA V2
33 // /// Regex to find unit in a line. Examples of valid lines:
33 // /// Regex to find unit in a line. Examples of valid lines:
34 // /// ... PARAMETER_UNITS : nT ...
34 // /// ... PARAMETER_UNITS : nT ...
35 // /// ... PARAMETER_UNITS:nT ...
35 // /// ... PARAMETER_UNITS:nT ...
36 // /// ... PARAMETER_UNITS: mΒ² ...
36 // /// ... PARAMETER_UNITS: mΒ² ...
37 // /// ... PARAMETER_UNITS : m/s ...
37 // /// ... PARAMETER_UNITS : m/s ...
38 // const auto UNIT_REGEX = QRegularExpression{QStringLiteral("\\s*PARAMETER_UNITS\\s*:\\s*(.+)")};
38 // const auto UNIT_REGEX = QRegularExpression{QStringLiteral("\\s*PARAMETER_UNITS\\s*:\\s*(.+)")};
39
39
40 /// ... - Units : nT - ...
40 /// ... - Units : nT - ...
41 /// ... -Units:nT- ...
41 /// ... -Units:nT- ...
42 /// ... -Units: mΒ²- ...
42 /// ... -Units: mΒ²- ...
43 /// ... - Units : m/s - ...
43 /// ... - Units : m/s - ...
44 const auto UNIT_REGEX = QRegularExpression{QStringLiteral("-\\s*Units\\s*:\\s*(.+?)\\s*-")};
44 const auto UNIT_REGEX = QRegularExpression{QStringLiteral("-\\s*Units\\s*:\\s*(.+?)\\s*-")};
45
45
46 QDateTime dateTimeFromString(const QString &stringDate) noexcept
46 QDateTime dateTimeFromString(const QString &stringDate) noexcept
47 {
47 {
48 #if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
48 #if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
49 return QDateTime::fromString(stringDate, Qt::ISODateWithMs);
49 return QDateTime::fromString(stringDate, Qt::ISODateWithMs);
50 #else
50 #else
51 return QDateTime::fromString(stringDate, DATE_FORMAT);
51 return QDateTime::fromString(stringDate, DATE_FORMAT);
52 #endif
52 #endif
53 }
53 }
54
54
55 /// Converts a string date to a double date
55 /// Converts a string date to a double date
56 /// @return a double that represents the date in seconds, NaN if the string date can't be converted
56 /// @return a double that represents the date in seconds, NaN if the string date can't be converted
57 double doubleDate(const QString &stringDate) noexcept
57 double doubleDate(const QString &stringDate) noexcept
58 {
58 {
59 // Format: yyyy-MM-ddThh:mm:ss.zzz
59 // Format: yyyy-MM-ddThh:mm:ss.zzz
60 auto dateTime = dateTimeFromString(stringDate);
60 auto dateTime = dateTimeFromString(stringDate);
61 dateTime.setTimeSpec(Qt::UTC);
61 dateTime.setTimeSpec(Qt::UTC);
62 return dateTime.isValid() ? DateUtils::secondsSinceEpoch(dateTime)
62 return dateTime.isValid() ? DateUtils::secondsSinceEpoch(dateTime)
63 : std::numeric_limits<double>::quiet_NaN();
63 : std::numeric_limits<double>::quiet_NaN();
64 }
64 }
65
65
66 /// Checks if a line is a comment line
66 /// Checks if a line is a comment line
67 bool isCommentLine(const QString &line)
67 bool isCommentLine(const QString &line)
68 {
68 {
69 return line.startsWith("#");
69 return line.startsWith("#");
70 }
70 }
71
71
72 /// @return the number of lines to be read depending on the type of value passed in parameter
72 /// @return the number of lines to be read depending on the type of value passed in parameter
73 int nbValues(AmdaResultParser::ValueType valueType) noexcept
73 int nbValues(AmdaResultParser::ValueType valueType) noexcept
74 {
74 {
75 switch (valueType) {
75 switch (valueType) {
76 case AmdaResultParser::ValueType::SCALAR:
76 case AmdaResultParser::ValueType::SCALAR:
77 return 1;
77 return 1;
78 case AmdaResultParser::ValueType::VECTOR:
78 case AmdaResultParser::ValueType::VECTOR:
79 return 3;
79 return 3;
80 case AmdaResultParser::ValueType::UNKNOWN:
80 case AmdaResultParser::ValueType::UNKNOWN:
81 // Invalid case
81 // Invalid case
82 break;
82 break;
83 }
83 }
84
84
85 // Invalid cases
85 // Invalid cases
86 qCCritical(LOG_AmdaResultParser())
86 qCCritical(LOG_AmdaResultParser())
87 << QObject::tr("Can't get the number of values to read: unsupported type");
87 << QObject::tr("Can't get the number of values to read: unsupported type");
88 return 0;
88 return 0;
89 }
89 }
90
90
91 /**
91 /**
92 * Reads stream to retrieve x-axis unit
92 * Reads stream to retrieve x-axis unit
93 * @param stream the stream to read
93 * @param stream the stream to read
94 * @return the unit that has been read in the stream, a default unit (time unit with no label) if an
94 * @return the unit that has been read in the stream, a default unit (time unit with no label) if an
95 * error occured during reading
95 * error occured during reading
96 */
96 */
97 Unit readXAxisUnit(QTextStream &stream)
97 Unit readXAxisUnit(QTextStream &stream)
98 {
98 {
99 QString line{};
99 QString line{};
100
100
101 // Searches unit in the comment lines (as long as the reading has not reached the data header)
101 // Searches unit in the comment lines (as long as the reading has not reached the data header)
102 // AMDA V2: while (stream.readLineInto(&line) && !line.contains(DATA_HEADER_REGEX)) {
102 // AMDA V2: while (stream.readLineInto(&line) && !line.contains(DATA_HEADER_REGEX)) {
103 while (stream.readLineInto(&line) && isCommentLine(line)) {
103 while (stream.readLineInto(&line) && isCommentLine(line)) {
104 auto match = UNIT_REGEX.match(line);
104 auto match = UNIT_REGEX.match(line);
105 if (match.hasMatch()) {
105 if (match.hasMatch()) {
106 return Unit{match.captured(1), true};
106 return Unit{match.captured(1), true};
107 }
107 }
108 }
108 }
109
109
110 qCWarning(LOG_AmdaResultParser()) << QObject::tr("The unit could not be found in the file");
110 qCWarning(LOG_AmdaResultParser()) << QObject::tr("The unit could not be found in the file");
111
111
112 // Error cases
112 // Error cases
113 return Unit{{}, true};
113 return Unit{{}, true};
114 }
114 }
115
115
116 /**
116 /**
117 * Reads stream to retrieve results
117 * Reads stream to retrieve results
118 * @param stream the stream to read
118 * @param stream the stream to read
119 * @return the pair of vectors x-axis data/values data that has been read in the stream
119 * @return the pair of vectors x-axis data/values data that has been read in the stream
120 */
120 */
121 std::pair<std::vector<double>, std::vector<double> >
121 std::pair<std::vector<double>, std::vector<double> >
122 readResults(QTextStream &stream, AmdaResultParser::ValueType valueType)
122 readResults(QTextStream &stream, AmdaResultParser::ValueType valueType)
123 {
123 {
124 auto expectedNbValues = nbValues(valueType) + 1;
124 auto expectedNbValues = nbValues(valueType) + 1;
125
125
126 auto xData = std::vector<double>{};
126 auto xData = std::vector<double>{};
127 auto valuesData = std::vector<double>{};
127 auto valuesData = std::vector<double>{};
128
128
129 QString line{};
129 QString line{};
130
130
131 // Skip comment lines
131 // Skip comment lines
132 while (stream.readLineInto(&line) && isCommentLine(line)) {
132 while (stream.readLineInto(&line) && isCommentLine(line)) {
133 }
133 }
134
134
135 if (!stream.atEnd()) {
135 if (!stream.atEnd()) {
136 do {
136 do {
137 auto lineData = line.split(RESULT_LINE_SEPARATOR, QString::SkipEmptyParts);
137 auto lineData = line.split(RESULT_LINE_SEPARATOR, QString::SkipEmptyParts);
138 if (lineData.size() == expectedNbValues) {
138 if (lineData.size() == expectedNbValues) {
139 // X : the data is converted from date to double (in secs)
139 // X : the data is converted from date to double (in secs)
140 auto x = doubleDate(lineData.at(0));
140 auto x = doubleDate(lineData.at(0));
141
141
142 // Adds result only if x is valid. Then, if value is invalid, it is set to NaN
142 // Adds result only if x is valid. Then, if value is invalid, it is set to NaN
143 if (!std::isnan(x)) {
143 if (!std::isnan(x)) {
144 xData.push_back(x);
144 xData.push_back(x);
145
145
146 // Values
146 // Values
147 for (auto valueIndex = 1; valueIndex < expectedNbValues; ++valueIndex) {
147 for (auto valueIndex = 1; valueIndex < expectedNbValues; ++valueIndex) {
148 auto column = valueIndex;
148 auto column = valueIndex;
149
149
150 bool valueOk;
150 bool valueOk;
151 auto value = lineData.at(column).toDouble(&valueOk);
151 auto value = lineData.at(column).toDouble(&valueOk);
152
152
153 if (!valueOk) {
153 if (!valueOk) {
154 qCWarning(LOG_AmdaResultParser())
154 qCWarning(LOG_AmdaResultParser())
155 << QObject::tr(
155 << QObject::tr(
156 "Value from (line %1, column %2) is invalid and will be "
156 "Value from (line %1, column %2) is invalid and will be "
157 "converted to NaN")
157 "converted to NaN")
158 .arg(line, column);
158 .arg(line, column);
159 value = std::numeric_limits<double>::quiet_NaN();
159 value = std::numeric_limits<double>::quiet_NaN();
160 }
160 }
161 valuesData.push_back(value);
161 valuesData.push_back(value);
162 }
162 }
163 }
163 }
164 else {
164 else {
165 qCWarning(LOG_AmdaResultParser())
165 qCWarning(LOG_AmdaResultParser())
166 << QObject::tr("Can't retrieve results from line %1: x is invalid")
166 << QObject::tr("Can't retrieve results from line %1: x is invalid")
167 .arg(line);
167 .arg(line);
168 }
168 }
169 }
169 }
170 else {
170 else {
171 qCWarning(LOG_AmdaResultParser())
171 qCWarning(LOG_AmdaResultParser())
172 << QObject::tr("Can't retrieve results from line %1: invalid line").arg(line);
172 << QObject::tr("Can't retrieve results from line %1: invalid line").arg(line);
173 }
173 }
174 } while (stream.readLineInto(&line));
174 } while (stream.readLineInto(&line));
175 }
175 }
176
176
177 return std::make_pair(std::move(xData), std::move(valuesData));
177 return std::make_pair(std::move(xData), std::move(valuesData));
178 }
178 }
179
179
180 } // namespace
180 } // namespace
181
181
182 std::shared_ptr<IDataSeries> AmdaResultParser::readTxt(const QString &filePath,
182 std::shared_ptr<IDataSeries> AmdaResultParser::readTxt(const QString &filePath,
183 ValueType valueType) noexcept
183 ValueType valueType) noexcept
184 {
184 {
185 if (valueType == ValueType::UNKNOWN) {
185 if (valueType == ValueType::UNKNOWN) {
186 qCCritical(LOG_AmdaResultParser())
186 qCCritical(LOG_AmdaResultParser())
187 << QObject::tr("Can't retrieve AMDA data: the type of values to be read is unknown");
187 << QObject::tr("Can't retrieve AMDA data: the type of values to be read is unknown");
188 return nullptr;
188 return nullptr;
189 }
189 }
190
190
191 QFile file{filePath};
191 QFile file{filePath};
192
192
193 if (!file.open(QFile::ReadOnly | QIODevice::Text)) {
193 if (!file.open(QFile::ReadOnly | QIODevice::Text)) {
194 qCCritical(LOG_AmdaResultParser())
194 qCCritical(LOG_AmdaResultParser())
195 << QObject::tr("Can't retrieve AMDA data from file %1: %2")
195 << QObject::tr("Can't retrieve AMDA data from file %1: %2")
196 .arg(filePath, file.errorString());
196 .arg(filePath, file.errorString());
197 return nullptr;
197 return nullptr;
198 }
198 }
199
199
200 QTextStream stream{&file};
200 QTextStream stream{&file};
201
201
202 // Checks if the file was found on the server
202 // Checks if the file was found on the server
203 auto firstLine = stream.readLine();
203 auto firstLine = stream.readLine();
204 if (firstLine.compare(FILE_NOT_FOUND_MESSAGE) == 0) {
204 if (firstLine.compare(FILE_NOT_FOUND_MESSAGE) == 0) {
205 qCCritical(LOG_AmdaResultParser())
205 qCCritical(LOG_AmdaResultParser())
206 << QObject::tr("Can't retrieve AMDA data from file %1: file was not found on server")
206 << QObject::tr("Can't retrieve AMDA data from file %1: file was not found on server")
207 .arg(filePath);
207 .arg(filePath);
208 return nullptr;
208 return nullptr;
209 }
209 }
210
210
211 // Reads x-axis unit
211 // Reads x-axis unit
212 stream.seek(0); // returns to the beginning of the file
212 stream.seek(0); // returns to the beginning of the file
213 auto xAxisUnit = readXAxisUnit(stream);
213 auto xAxisUnit = readXAxisUnit(stream);
214 if (xAxisUnit.m_Name.isEmpty()) {
215 return nullptr;
216 }
214
217
215 // Reads results
218 // Reads results
216 // AMDA V2: remove line
219 // AMDA V2: remove line
217 stream.seek(0); // returns to the beginning of the file
220 stream.seek(0); // returns to the beginning of the file
218 auto results = readResults(stream, valueType);
221 auto results = readResults(stream, valueType);
219
222
220 // Creates data series
223 // Creates data series
221 switch (valueType) {
224 switch (valueType) {
222 case ValueType::SCALAR:
225 case ValueType::SCALAR:
223 return std::make_shared<ScalarSeries>(std::move(results.first),
226 return std::make_shared<ScalarSeries>(std::move(results.first),
224 std::move(results.second), xAxisUnit, Unit{});
227 std::move(results.second), xAxisUnit, Unit{});
225 case ValueType::VECTOR:
228 case ValueType::VECTOR:
226 return std::make_shared<VectorSeries>(std::move(results.first),
229 return std::make_shared<VectorSeries>(std::move(results.first),
227 std::move(results.second), xAxisUnit, Unit{});
230 std::move(results.second), xAxisUnit, Unit{});
228 case ValueType::UNKNOWN:
231 case ValueType::UNKNOWN:
229 // Invalid case
232 // Invalid case
230 break;
233 break;
231 }
234 }
232
235
233 // Invalid cases
236 // Invalid cases
234 qCCritical(LOG_AmdaResultParser())
237 qCCritical(LOG_AmdaResultParser())
235 << QObject::tr("Can't create data series: unsupported value type");
238 << QObject::tr("Can't create data series: unsupported value type");
236 return nullptr;
239 return nullptr;
237 }
240 }
General Comments 3
Under Review
author

Auto status change to "Under Review"

Approved
author

Merge lasted acquisition developpement on main Sciqlop branch

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