##// END OF EJS Templates
@@ -0,0 +1,35
1 #ifndef CACHESTRATEGYFACTORY_H
2 #define CACHESTRATEGYFACTORY_H
3
4
5 #include <memory>
6 #include <stdexcept>
7
8 #include "VariableCacheStrategy.h"
9 #include "singlethresholdcachestrategy.h"
10
11
12 enum class CacheStrategy { SingleThreshold, TwoThreashold };
13
14
15 class CacheStrategyFactory {
16
17 using cacheStratPtr = std::unique_ptr<VariableCacheStrategy>;
18
19 public:
20 static cacheStratPtr createCacheStrategy(CacheStrategy specificStrategy)
21 {
22 switch (specificStrategy) {
23 case CacheStrategy::SingleThreshold:
24 return std::unique_ptr<VariableCacheStrategy>{new SingleThresholdCacheStrategy{}};
25
26 case CacheStrategy::TwoThreashold:
27 throw std::runtime_error("cache strategy not implemented yet");
28 }
29
30 throw std::runtime_error("Unknown cache strategy");
31 }
32 };
33
34
35 #endif // CACHESTRATEGYFACTORY_H
@@ -0,0 +1,32
1 #ifndef SINGLETHRESHOLDCACHESTRATEGY_H
2 #define SINGLETHRESHOLDCACHESTRATEGY_H
3
4 #include "Settings/SqpSettingsDefs.h"
5 #include "VariableCacheStrategy.h"
6
7
8 /// This class aims to hande the cache strategy.
9 class SCIQLOP_CORE_EXPORT SingleThresholdCacheStrategy : public VariableCacheStrategy {
10 public:
11 SingleThresholdCacheStrategy() = default;
12
13 std::pair<SqpRange, SqpRange> computeRange(const SqpRange &vRange,
14 const SqpRange &rangeRequested) override
15 {
16
17 auto varRanges = std::pair<SqpRange, SqpRange>{};
18
19 auto toleranceFactor = SqpSettings::toleranceValue(
20 GENERAL_TOLERANCE_AT_UPDATE_KEY, GENERAL_TOLERANCE_AT_UPDATE_DEFAULT_VALUE);
21 auto tolerance = toleranceFactor * (rangeRequested.m_TEnd - rangeRequested.m_TStart);
22
23 varRanges.first = rangeRequested;
24 varRanges.second
25 = SqpRange{rangeRequested.m_TStart - tolerance, rangeRequested.m_TEnd + tolerance};
26
27 return varRanges;
28 }
29 };
30
31
32 #endif // SINGLETHRESHOLDCACHESTRATEGY_H
@@ -1,40 +1,37
1 1 #ifndef SCIQLOP_VARIABLECACHESTRATEGY_H
2 2 #define SCIQLOP_VARIABLECACHESTRATEGY_H
3 3
4 4 #include "CoreGlobal.h"
5 5
6 6 #include <QLoggingCategory>
7 7 #include <QObject>
8 8
9 9 #include <Data/SqpRange.h>
10 10
11 11 #include <QLoggingCategory>
12 12
13 13 #include <Common/spimpl.h>
14 14 #include <utility>
15 15
16 16
17 17 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableCacheStrategy)
18 18
19 19 class Variable;
20 20
21 21 /**
22 22 * Possible types of zoom operation
23 23 */
24 enum class CacheStrategy { FixedTolerance, TwoThreashold };
24 // enum class CacheStrategy { FixedTolerance, TwoThreashold };
25 25
26 /// This class aims to hande the cache strategy.
27 class SCIQLOP_CORE_EXPORT VariableCacheStrategy : public QObject {
28 Q_OBJECT
29 public:
30 explicit VariableCacheStrategy(QObject *parent = 0);
31 26
32 std::pair<SqpRange, SqpRange> computeStrategyRanges(const SqpRange &vRange,
33 const SqpRange &rangeRequested);
27 /// This class aims to hande the cache strategy.
28 class SCIQLOP_CORE_EXPORT VariableCacheStrategy {
34 29
35 private:
36 class VariableCacheStrategyPrivate;
37 spimpl::unique_impl_ptr<VariableCacheStrategyPrivate> impl;
30 public:
31 virtual std::pair<SqpRange, SqpRange> computeRange(const SqpRange &vRange,
32 const SqpRange &rangeRequested)
33 = 0;
38 34 };
39 35
36
40 37 #endif // SCIQLOP_VARIABLECACHESTRATEGY_H
@@ -1,52 +0,0
1 #include "Variable/VariableCacheStrategy.h"
2
3 #include "Settings/SqpSettingsDefs.h"
4
5 #include "Variable/Variable.h"
6 #include "Variable/VariableController.h"
7
8 Q_LOGGING_CATEGORY(LOG_VariableCacheStrategy, "VariableCacheStrategy")
9
10 struct VariableCacheStrategy::VariableCacheStrategyPrivate {
11 VariableCacheStrategyPrivate() : m_CacheStrategy{CacheStrategy::FixedTolerance} {}
12
13 CacheStrategy m_CacheStrategy;
14 };
15
16
17 VariableCacheStrategy::VariableCacheStrategy(QObject *parent)
18 : QObject{parent}, impl{spimpl::make_unique_impl<VariableCacheStrategyPrivate>()}
19 {
20 }
21
22 std::pair<SqpRange, SqpRange>
23 VariableCacheStrategy::computeStrategyRanges(const SqpRange &vRange, const SqpRange &rangeRequested)
24 {
25
26 auto varRanges = std::pair<SqpRange, SqpRange>{};
27
28 auto toleranceFactor = SqpSettings::toleranceValue(GENERAL_TOLERANCE_AT_UPDATE_KEY,
29 GENERAL_TOLERANCE_AT_UPDATE_DEFAULT_VALUE);
30 auto tolerance = toleranceFactor * (rangeRequested.m_TEnd - rangeRequested.m_TStart);
31
32 switch (impl->m_CacheStrategy) {
33 case CacheStrategy::FixedTolerance: {
34 varRanges.first = rangeRequested;
35 varRanges.second
36 = SqpRange{rangeRequested.m_TStart - tolerance, rangeRequested.m_TEnd + tolerance};
37 break;
38 }
39
40 case CacheStrategy::TwoThreashold: {
41 // TODO Implement
42 break;
43 }
44 default:
45 qCCritical(LOG_VariableCacheStrategy())
46 << tr("Impossible to use compute the cache range with an unknow cache strategy");
47 // No action
48 break;
49 }
50
51 return varRanges;
52 }
@@ -1,839 +1,842
1 1 #include <Variable/Variable.h>
2 2 #include <Variable/VariableAcquisitionWorker.h>
3 3 #include <Variable/VariableCacheStrategy.h>
4 4 #include <Variable/VariableController.h>
5 5 #include <Variable/VariableModel.h>
6 6 #include <Variable/VariableSynchronizationGroup.h>
7 #include <Variable/cachestrategyfactory.h>
7 8
8 9 #include <Data/DataProviderParameters.h>
9 10 #include <Data/IDataProvider.h>
10 11 #include <Data/IDataSeries.h>
11 12 #include <Data/VariableRequest.h>
12 13 #include <Time/TimeController.h>
13 14
14 15 #include <QMutex>
15 16 #include <QThread>
16 17 #include <QUuid>
17 18 #include <QtCore/QItemSelectionModel>
18 19
19 20 #include <deque>
20 21 #include <set>
21 22 #include <unordered_map>
22 23
23 24 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
24 25
25 26 namespace {
26 27
27 28 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
28 29 const SqpRange &oldGraphRange)
29 30 {
30 31 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
31 32
32 33 auto varRangeRequested = varRange;
33 34 switch (zoomType) {
34 35 case AcquisitionZoomType::ZoomIn: {
35 36 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
36 37 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
37 38 varRangeRequested.m_TStart += deltaLeft;
38 39 varRangeRequested.m_TEnd -= deltaRight;
39 40 break;
40 41 }
41 42
42 43 case AcquisitionZoomType::ZoomOut: {
43 44 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
44 45 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
45 46 varRangeRequested.m_TStart -= deltaLeft;
46 47 varRangeRequested.m_TEnd += deltaRight;
47 48 break;
48 49 }
49 50 case AcquisitionZoomType::PanRight: {
50 51 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
51 52 varRangeRequested.m_TStart += deltaRight;
52 53 varRangeRequested.m_TEnd += deltaRight;
53 54 break;
54 55 }
55 56 case AcquisitionZoomType::PanLeft: {
56 57 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
57 58 varRangeRequested.m_TStart -= deltaLeft;
58 59 varRangeRequested.m_TEnd -= deltaLeft;
59 60 break;
60 61 }
61 62 case AcquisitionZoomType::Unknown: {
62 63 qCCritical(LOG_VariableController())
63 64 << VariableController::tr("Impossible to synchronize: zoom type unknown");
64 65 break;
65 66 }
66 67 default:
67 68 qCCritical(LOG_VariableController()) << VariableController::tr(
68 69 "Impossible to synchronize: zoom type not take into account");
69 70 // No action
70 71 break;
71 72 }
72 73
73 74 return varRangeRequested;
74 75 }
75 76 }
76 77
77 78 struct VariableController::VariableControllerPrivate {
78 79 explicit VariableControllerPrivate(VariableController *parent)
79 80 : m_WorkingMutex{},
80 81 m_VariableModel{new VariableModel{parent}},
81 82 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
82 m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
83 // m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
84 m_VariableCacheStrategy{
85 CacheStrategyFactory::createCacheStrategy(CacheStrategy::SingleThreshold)},
83 86 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
84 87 q{parent}
85 88 {
86 89
87 90 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
88 91 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
89 92 }
90 93
91 94
92 95 virtual ~VariableControllerPrivate()
93 96 {
94 97 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
95 98 m_VariableAcquisitionWorkerThread.quit();
96 99 m_VariableAcquisitionWorkerThread.wait();
97 100 }
98 101
99 102
100 103 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested,
101 104 QUuid varRequestId);
102 105
103 106 QVector<SqpRange> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
104 107 const SqpRange &dateTime);
105 108
106 109 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
107 110 std::shared_ptr<IDataSeries>
108 111 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
109 112
110 113 void registerProvider(std::shared_ptr<IDataProvider> provider);
111 114
112 115 void storeVariableRequest(QUuid varId, QUuid varRequestId, const VariableRequest &varRequest);
113 116 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries);
114 117 void updateVariableRequest(QUuid varRequestId);
115 118 void cancelVariableRequest(QUuid varRequestId);
116 119
117 120 QMutex m_WorkingMutex;
118 121 /// Variable model. The VariableController has the ownership
119 122 VariableModel *m_VariableModel;
120 123 QItemSelectionModel *m_VariableSelectionModel;
121 124
122 125
123 126 TimeController *m_TimeController{nullptr};
124 127 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
125 128 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
126 129 QThread m_VariableAcquisitionWorkerThread;
127 130
128 131 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
129 132 m_VariableToProviderMap;
130 133 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
131 134 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
132 135 m_GroupIdToVariableSynchronizationGroupMap;
133 136 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
134 137 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
135 138
136 139 std::map<QUuid, std::map<QUuid, VariableRequest> > m_VarRequestIdToVarIdVarRequestMap;
137 140
138 141 std::map<QUuid, std::deque<QUuid> > m_VarIdToVarRequestIdQueueMap;
139 142
140 143
141 144 VariableController *q;
142 145 };
143 146
144 147
145 148 VariableController::VariableController(QObject *parent)
146 149 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
147 150 {
148 qCDebug(LOG_VariableController()) << tr("VariableController construction")
149 << QThread::currentThread();
151 qCDebug(LOG_VariableController())
152 << tr("VariableController construction") << QThread::currentThread();
150 153
151 154 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
152 155 &VariableController::onAbortProgressRequested);
153 156
154 157 connect(impl->m_VariableAcquisitionWorker.get(),
155 158 &VariableAcquisitionWorker::variableCanceledRequested, this,
156 159 &VariableController::onAbortAcquisitionRequested);
157 160
158 161 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
159 162 &VariableController::onDataProvided);
160 163 connect(impl->m_VariableAcquisitionWorker.get(),
161 164 &VariableAcquisitionWorker::variableRequestInProgress, this,
162 165 &VariableController::onVariableRetrieveDataInProgress);
163 166
164 167
165 168 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
166 169 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
167 170 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
168 171 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
169 172
170 173
171 174 impl->m_VariableAcquisitionWorkerThread.start();
172 175 }
173 176
174 177 VariableController::~VariableController()
175 178 {
176 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
177 << QThread::currentThread();
179 qCDebug(LOG_VariableController())
180 << tr("VariableController destruction") << QThread::currentThread();
178 181 this->waitForFinish();
179 182 }
180 183
181 184 VariableModel *VariableController::variableModel() noexcept
182 185 {
183 186 return impl->m_VariableModel;
184 187 }
185 188
186 189 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
187 190 {
188 191 return impl->m_VariableSelectionModel;
189 192 }
190 193
191 194 void VariableController::setTimeController(TimeController *timeController) noexcept
192 195 {
193 196 impl->m_TimeController = timeController;
194 197 }
195 198
196 199 std::shared_ptr<Variable>
197 200 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
198 201 {
199 202 if (impl->m_VariableModel->containsVariable(variable)) {
200 203 // Clones variable
201 204 auto duplicate = variable->clone();
202 205
203 206 // Adds clone to model
204 207 impl->m_VariableModel->addVariable(duplicate);
205 208
206 209 // Generates clone identifier
207 210 impl->m_VariableToIdentifierMap[duplicate] = QUuid::createUuid();
208 211
209 212 // Registers provider
210 213 auto variableProvider = impl->m_VariableToProviderMap.at(variable);
211 214 auto duplicateProvider = variableProvider != nullptr ? variableProvider->clone() : nullptr;
212 215
213 216 impl->m_VariableToProviderMap[duplicate] = duplicateProvider;
214 217 if (duplicateProvider) {
215 218 impl->registerProvider(duplicateProvider);
216 219 }
217 220
218 221 return duplicate;
219 222 }
220 223 else {
221 224 qCCritical(LOG_VariableController())
222 225 << tr("Can't create duplicate of variable %1: variable not registered in the model")
223 226 .arg(variable->name());
224 227 return nullptr;
225 228 }
226 229 }
227 230
228 231 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
229 232 {
230 233 if (!variable) {
231 234 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
232 235 return;
233 236 }
234 237
235 238 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
236 239 // make some treatments before the deletion
237 240 emit variableAboutToBeDeleted(variable);
238 241
239 242 // Deletes identifier
240 243 impl->m_VariableToIdentifierMap.erase(variable);
241 244
242 245 // Deletes provider
243 246 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
244 247 qCDebug(LOG_VariableController())
245 248 << tr("Number of providers deleted for variable %1: %2")
246 249 .arg(variable->name(), QString::number(nbProvidersDeleted));
247 250
248 251
249 252 // Deletes from model
250 253 impl->m_VariableModel->deleteVariable(variable);
251 254 }
252 255
253 256 void VariableController::deleteVariables(
254 257 const QVector<std::shared_ptr<Variable> > &variables) noexcept
255 258 {
256 259 for (auto variable : qAsConst(variables)) {
257 260 deleteVariable(variable);
258 261 }
259 262 }
260 263
261 264 std::shared_ptr<Variable>
262 265 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
263 266 std::shared_ptr<IDataProvider> provider) noexcept
264 267 {
265 268 if (!impl->m_TimeController) {
266 269 qCCritical(LOG_VariableController())
267 270 << tr("Impossible to create variable: The time controller is null");
268 271 return nullptr;
269 272 }
270 273
271 274 auto range = impl->m_TimeController->dateTime();
272 275
273 276 if (auto newVariable = impl->m_VariableModel->createVariable(name, metadata)) {
274 277 auto identifier = QUuid::createUuid();
275 278
276 279 // store the provider
277 280 impl->registerProvider(provider);
278 281
279 282 // Associate the provider
280 283 impl->m_VariableToProviderMap[newVariable] = provider;
281 284 qCInfo(LOG_VariableController()) << "createVariable: " << identifier;
282 285 impl->m_VariableToIdentifierMap[newVariable] = identifier;
283 286
284 287
285 288 auto varRequestId = QUuid::createUuid();
286 289 impl->processRequest(newVariable, range, varRequestId);
287 290 impl->updateVariableRequest(varRequestId);
288 291
289 292 return newVariable;
290 293 }
291 294 }
292 295
293 296 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
294 297 {
295 298 // TODO check synchronisation and Rescale
296 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
297 << QThread::currentThread()->objectName();
299 qCDebug(LOG_VariableController())
300 << "VariableController::onDateTimeOnSelection" << QThread::currentThread()->objectName();
298 301 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
299 302 auto varRequestId = QUuid::createUuid();
300 303
301 304 for (const auto &selectedRow : qAsConst(selectedRows)) {
302 305 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
303 306 selectedVariable->setRange(dateTime);
304 307 impl->processRequest(selectedVariable, dateTime, varRequestId);
305 308
306 309 // notify that rescale operation has to be done
307 310 emit rangeChanged(selectedVariable, dateTime);
308 311 }
309 312 }
310 313 impl->updateVariableRequest(varRequestId);
311 314 }
312 315
313 316 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
314 317 const SqpRange &cacheRangeRequested,
315 318 QVector<AcquisitionDataPacket> dataAcquired)
316 319 {
317 320 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
318 321 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
319 322 if (!varRequestId.isNull()) {
320 323 impl->updateVariableRequest(varRequestId);
321 324 }
322 325 }
323 326
324 327 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
325 328 {
326 329 qCDebug(LOG_VariableController())
327 330 << "TORM: variableController::onVariableRetrieveDataInProgress"
328 331 << QThread::currentThread()->objectName() << progress;
329 332 if (auto var = impl->findVariable(identifier)) {
330 333 impl->m_VariableModel->setDataProgress(var, progress);
331 334 }
332 335 else {
333 336 qCCritical(LOG_VariableController())
334 337 << tr("Impossible to notify progression of a null variable");
335 338 }
336 339 }
337 340
338 341 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
339 342 {
340 343 auto it = impl->m_VariableToIdentifierMap.find(variable);
341 344 if (it != impl->m_VariableToIdentifierMap.cend()) {
342 345 impl->m_VariableAcquisitionWorker->abortProgressRequested(it->second);
343 346
344 347 QUuid varRequestId;
345 348 auto varIdToVarRequestIdQueueMapIt = impl->m_VarIdToVarRequestIdQueueMap.find(it->second);
346 349 if (varIdToVarRequestIdQueueMapIt != impl->m_VarIdToVarRequestIdQueueMap.cend()) {
347 350 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
348 351 varRequestId = varRequestIdQueue.front();
349 352 impl->cancelVariableRequest(varRequestId);
350 353
351 354 // Finish the progression for the request
352 355 impl->m_VariableModel->setDataProgress(variable, 0.0);
353 356 }
354 357 else {
355 358 qCWarning(LOG_VariableController())
356 359 << tr("Aborting progression of inexistant variable request detected !!!")
357 360 << QThread::currentThread()->objectName();
358 361 }
359 362 }
360 363 else {
361 364 qCWarning(LOG_VariableController())
362 365 << tr("Aborting progression of inexistant variable detected !!!")
363 366 << QThread::currentThread()->objectName();
364 367 }
365 368 }
366 369
367 370 void VariableController::onAbortAcquisitionRequested(QUuid vIdentifier)
368 371 {
369 372 qCDebug(LOG_VariableController()) << "TORM: variableController::onAbortAcquisitionRequested"
370 373 << QThread::currentThread()->objectName() << vIdentifier;
371 374
372 375 if (auto var = impl->findVariable(vIdentifier)) {
373 376 this->onAbortProgressRequested(var);
374 377 }
375 378 else {
376 379 qCCritical(LOG_VariableController())
377 380 << tr("Impossible to abort Acquisition Requestof a null variable");
378 381 }
379 382 }
380 383
381 384 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
382 385 {
383 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
384 << QThread::currentThread()->objectName()
385 << synchronizationGroupId;
386 qCDebug(LOG_VariableController())
387 << "TORM: VariableController::onAddSynchronizationGroupId"
388 << QThread::currentThread()->objectName() << synchronizationGroupId;
386 389 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
387 390 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
388 391 std::make_pair(synchronizationGroupId, vSynchroGroup));
389 392 }
390 393
391 394 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
392 395 {
393 396 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
394 397 }
395 398
396 399 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
397 400 QUuid synchronizationGroupId)
398 401
399 402 {
400 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
401 << synchronizationGroupId;
403 qCDebug(LOG_VariableController())
404 << "TORM: VariableController::onAddSynchronized" << synchronizationGroupId;
402 405 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
403 406 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
404 407 auto groupIdToVSGIt
405 408 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
406 409 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
407 410 impl->m_VariableIdGroupIdMap.insert(
408 411 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
409 412 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
410 413 }
411 414 else {
412 415 qCCritical(LOG_VariableController())
413 416 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
414 417 << variable->name();
415 418 }
416 419 }
417 420 else {
418 421 qCCritical(LOG_VariableController())
419 422 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
420 423 }
421 424 }
422 425
423 426 void VariableController::desynchronize(std::shared_ptr<Variable> variable,
424 427 QUuid synchronizationGroupId)
425 428 {
426 429 // Gets variable id
427 430 auto variableIt = impl->m_VariableToIdentifierMap.find(variable);
428 431 if (variableIt == impl->m_VariableToIdentifierMap.cend()) {
429 432 qCCritical(LOG_VariableController())
430 433 << tr("Can't desynchronize variable %1: variable identifier not found")
431 434 .arg(variable->name());
432 435 return;
433 436 }
434 437
435 438 // Gets synchronization group
436 439 auto groupIt = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
437 440 if (groupIt == impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
438 441 qCCritical(LOG_VariableController())
439 442 << tr("Can't desynchronize variable %1: unknown synchronization group")
440 443 .arg(variable->name());
441 444 return;
442 445 }
443 446
444 447 auto variableId = variableIt->second;
445 448
446 449 // Removes variable from synchronization group
447 450 auto synchronizationGroup = groupIt->second;
448 451 synchronizationGroup->removeVariableId(variableId);
449 452
450 453 // Removes link between variable and synchronization group
451 454 impl->m_VariableIdGroupIdMap.erase(variableId);
452 455 }
453 456
454 457 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
455 458 const SqpRange &range, const SqpRange &oldRange,
456 459 bool synchronise)
457 460 {
458 461 // NOTE: oldRange isn't really necessary since oldRange == variable->range().
459 462
460 463 // we want to load data of the variable for the dateTime.
461 464 // First we check if the cache contains some of them.
462 465 // For the other, we ask the provider to give them.
463 466
464 467 auto varRequestId = QUuid::createUuid();
465 468 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
466 469 << QThread::currentThread()->objectName() << varRequestId;
467 470
468 471 for (const auto &var : variables) {
469 472 qCDebug(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId;
470 473 impl->processRequest(var, range, varRequestId);
471 474 }
472 475
473 476 if (synchronise) {
474 477 // Get the group ids
475 478 qCDebug(LOG_VariableController())
476 479 << "TORM VariableController::onRequestDataLoading for synchro var ENABLE";
477 480 auto groupIds = std::set<QUuid>{};
478 481 auto groupIdToOldRangeMap = std::map<QUuid, SqpRange>{};
479 482 for (const auto &var : variables) {
480 483 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(var);
481 484 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
482 485 auto vId = varToVarIdIt->second;
483 486 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
484 487 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
485 488 auto gId = varIdToGroupIdIt->second;
486 489 groupIdToOldRangeMap.insert(std::make_pair(gId, var->range()));
487 490 if (groupIds.find(gId) == groupIds.cend()) {
488 491 qCDebug(LOG_VariableController()) << "Synchro detect group " << gId;
489 492 groupIds.insert(gId);
490 493 }
491 494 }
492 495 }
493 496 }
494 497
495 498 // We assume here all group ids exist
496 499 for (const auto &gId : groupIds) {
497 500 auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId);
498 501 auto vSyncIds = vSynchronizationGroup->getIds();
499 502 qCDebug(LOG_VariableController()) << "Var in synchro group ";
500 503 for (auto vId : vSyncIds) {
501 504 auto var = impl->findVariable(vId);
502 505
503 506 // Don't process already processed var
504 507 if (!variables.contains(var)) {
505 508 if (var != nullptr) {
506 qCDebug(LOG_VariableController()) << "processRequest synchro for"
507 << var->name();
509 qCDebug(LOG_VariableController())
510 << "processRequest synchro for" << var->name();
508 511 auto vSyncRangeRequested = computeSynchroRangeRequested(
509 512 var->range(), range, groupIdToOldRangeMap.at(gId));
510 513 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
511 514 impl->processRequest(var, vSyncRangeRequested, varRequestId);
512 515 }
513 516 else {
514 517 qCCritical(LOG_VariableController())
515 518
516 519 << tr("Impossible to synchronize a null variable");
517 520 }
518 521 }
519 522 }
520 523 }
521 524 }
522 525
523 526 impl->updateVariableRequest(varRequestId);
524 527 }
525 528
526 529
527 530 void VariableController::initialize()
528 531 {
529 532 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
530 533 impl->m_WorkingMutex.lock();
531 534 qCDebug(LOG_VariableController()) << tr("VariableController init END");
532 535 }
533 536
534 537 void VariableController::finalize()
535 538 {
536 539 impl->m_WorkingMutex.unlock();
537 540 }
538 541
539 542 void VariableController::waitForFinish()
540 543 {
541 544 QMutexLocker locker{&impl->m_WorkingMutex};
542 545 }
543 546
544 547 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
545 548 {
546 549 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
547 550 auto zoomType = AcquisitionZoomType::Unknown;
548 551 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
549 552 zoomType = AcquisitionZoomType::ZoomOut;
550 553 }
551 554 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
552 555 zoomType = AcquisitionZoomType::PanRight;
553 556 }
554 557 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
555 558 zoomType = AcquisitionZoomType::PanLeft;
556 559 }
557 560 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
558 561 zoomType = AcquisitionZoomType::ZoomIn;
559 562 }
560 563 else {
561 564 qCCritical(LOG_VariableController()) << "getZoomType: Unknown type detected";
562 565 }
563 566 return zoomType;
564 567 }
565 568
566 569 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
567 570 const SqpRange &rangeRequested,
568 571 QUuid varRequestId)
569 572 {
570 573
571 574 // TODO: protect at
572 575 auto varRequest = VariableRequest{};
573 576 auto varId = m_VariableToIdentifierMap.at(var);
574 577
575 578 auto varStrategyRangesRequested
576 = m_VariableCacheStrategy->computeStrategyRanges(var->range(), rangeRequested);
579 = m_VariableCacheStrategy->computeRange(var->range(), rangeRequested);
577 580
578 581 auto notInCacheRangeList = QVector<SqpRange>{varStrategyRangesRequested.second};
579 582 auto inCacheRangeList = QVector<SqpRange>{};
580 583 if (m_VarIdToVarRequestIdQueueMap.find(varId) == m_VarIdToVarRequestIdQueueMap.cend()) {
581 584 notInCacheRangeList = var->provideNotInCacheRangeList(varStrategyRangesRequested.second);
582 585 inCacheRangeList = var->provideInCacheRangeList(varStrategyRangesRequested.second);
583 586 }
584 587
585 588 if (!notInCacheRangeList.empty()) {
586 589 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
587 590 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
588 591
589 592 // store VarRequest
590 593 storeVariableRequest(varId, varRequestId, varRequest);
591 594
592 595 auto varProvider = m_VariableToProviderMap.at(var);
593 596 if (varProvider != nullptr) {
594 597 auto varRequestIdCanceled = m_VariableAcquisitionWorker->pushVariableRequest(
595 598 varRequestId, varId, varStrategyRangesRequested.first,
596 599 varStrategyRangesRequested.second,
597 600 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
598 601 varProvider);
599 602
600 603 if (!varRequestIdCanceled.isNull()) {
601 qCDebug(LOG_VariableAcquisitionWorker()) << tr("vsarRequestIdCanceled: ")
602 << varRequestIdCanceled;
604 qCDebug(LOG_VariableAcquisitionWorker())
605 << tr("vsarRequestIdCanceled: ") << varRequestIdCanceled;
603 606 cancelVariableRequest(varRequestIdCanceled);
604 607 }
605 608 }
606 609 else {
607 610 qCCritical(LOG_VariableController())
608 611 << "Impossible to provide data with a null provider";
609 612 }
610 613
611 614 if (!inCacheRangeList.empty()) {
612 615 emit q->updateVarDisplaying(var, inCacheRangeList.first());
613 616 }
614 617 }
615 618 else {
616 619 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
617 620 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
618 621 // store VarRequest
619 622 storeVariableRequest(varId, varRequestId, varRequest);
620 623 acceptVariableRequest(varId,
621 624 var->dataSeries()->subDataSeries(varStrategyRangesRequested.second));
622 625 }
623 626 }
624 627
625 628 std::shared_ptr<Variable>
626 629 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
627 630 {
628 631 std::shared_ptr<Variable> var;
629 632 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
630 633
631 634 auto end = m_VariableToIdentifierMap.cend();
632 635 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
633 636 if (it != end) {
634 637 var = it->first;
635 638 }
636 639 else {
637 640 qCCritical(LOG_VariableController())
638 641 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
639 642 }
640 643
641 644 return var;
642 645 }
643 646
644 647 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
645 648 const QVector<AcquisitionDataPacket> acqDataPacketVector)
646 649 {
647 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
648 << acqDataPacketVector.size();
650 qCDebug(LOG_VariableController())
651 << tr("TORM: retrieveDataSeries acqDataPacketVector size") << acqDataPacketVector.size();
649 652 std::shared_ptr<IDataSeries> dataSeries;
650 653 if (!acqDataPacketVector.isEmpty()) {
651 654 dataSeries = acqDataPacketVector[0].m_DateSeries;
652 655 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
653 656 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
654 657 }
655 658 }
656 659 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
657 660 << acqDataPacketVector.size();
658 661 return dataSeries;
659 662 }
660 663
661 664 void VariableController::VariableControllerPrivate::registerProvider(
662 665 std::shared_ptr<IDataProvider> provider)
663 666 {
664 667 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
665 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
666 << provider->objectName();
668 qCDebug(LOG_VariableController())
669 << tr("Registering of a new provider") << provider->objectName();
667 670 m_ProviderSet.insert(provider);
668 671 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
669 672 &VariableAcquisitionWorker::onVariableDataAcquired);
670 673 connect(provider.get(), &IDataProvider::dataProvidedProgress,
671 674 m_VariableAcquisitionWorker.get(),
672 675 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
673 676 connect(provider.get(), &IDataProvider::dataProvidedFailed,
674 677 m_VariableAcquisitionWorker.get(),
675 678 &VariableAcquisitionWorker::onVariableAcquisitionFailed);
676 679 }
677 680 else {
678 681 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
679 682 }
680 683 }
681 684
682 685 void VariableController::VariableControllerPrivate::storeVariableRequest(
683 686 QUuid varId, QUuid varRequestId, const VariableRequest &varRequest)
684 687 {
685 688 // First request for the variable. we can create an entry for it
686 689 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
687 690 if (varIdToVarRequestIdQueueMapIt == m_VarIdToVarRequestIdQueueMap.cend()) {
688 691 auto varRequestIdQueue = std::deque<QUuid>{};
689 692 qCDebug(LOG_VariableController()) << tr("Store REQUEST in QUEUE");
690 693 varRequestIdQueue.push_back(varRequestId);
691 694 m_VarIdToVarRequestIdQueueMap.insert(std::make_pair(varId, std::move(varRequestIdQueue)));
692 695 }
693 696 else {
694 697 qCDebug(LOG_VariableController()) << tr("Store REQUEST in EXISTING QUEUE");
695 698 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
696 699 varRequestIdQueue.push_back(varRequestId);
697 700 }
698 701
699 702 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
700 703 if (varRequestIdToVarIdVarRequestMapIt == m_VarRequestIdToVarIdVarRequestMap.cend()) {
701 704 auto varIdToVarRequestMap = std::map<QUuid, VariableRequest>{};
702 705 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
703 706 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in MAP");
704 707 m_VarRequestIdToVarIdVarRequestMap.insert(
705 708 std::make_pair(varRequestId, std::move(varIdToVarRequestMap)));
706 709 }
707 710 else {
708 711 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
709 712 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in EXISTING MAP");
710 713 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
711 714 }
712 715 }
713 716
714 717 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
715 718 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
716 719 {
717 720 QUuid varRequestId;
718 721 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
719 722 if (varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.cend()) {
720 723 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
721 724 varRequestId = varRequestIdQueue.front();
722 725 auto varRequestIdToVarIdVarRequestMapIt
723 726 = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
724 727 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
725 728 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
726 729 auto varIdToVarRequestMapIt = varIdToVarRequestMap.find(varId);
727 730 if (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) {
728 731 qCDebug(LOG_VariableController()) << tr("acceptVariableRequest");
729 732 auto &varRequest = varIdToVarRequestMapIt->second;
730 733 varRequest.m_DataSeries = dataSeries;
731 734 varRequest.m_CanUpdate = true;
732 735 }
733 736 else {
734 737 qCDebug(LOG_VariableController())
735 738 << tr("Impossible to acceptVariableRequest of a unknown variable id attached "
736 739 "to a variableRequestId")
737 740 << varRequestId << varId;
738 741 }
739 742 }
740 743 else {
741 744 qCCritical(LOG_VariableController())
742 745 << tr("Impossible to acceptVariableRequest of a unknown variableRequestId")
743 746 << varRequestId;
744 747 }
745 748
746 749 varRequestIdQueue.pop_front();
747 750 if (varRequestIdQueue.empty()) {
748 751 qCDebug(LOG_VariableController())
749 752 << tr("TORM Erase REQUEST because it has been accepted") << varId;
750 753 m_VarIdToVarRequestIdQueueMap.erase(varId);
751 754 }
752 755 }
753 756 else {
754 757 qCCritical(LOG_VariableController())
755 758 << tr("Impossible to acceptVariableRequest of a unknown variable id") << varId;
756 759 }
757 760
758 761 return varRequestId;
759 762 }
760 763
761 764 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
762 765 {
763 766
764 767 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
765 768 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
766 769 bool processVariableUpdate = true;
767 770 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
768 771 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
769 772 (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) && processVariableUpdate;
770 773 ++varIdToVarRequestMapIt) {
771 774 processVariableUpdate &= varIdToVarRequestMapIt->second.m_CanUpdate;
772 qCDebug(LOG_VariableController()) << tr("updateVariableRequest")
773 << processVariableUpdate;
775 qCDebug(LOG_VariableController())
776 << tr("updateVariableRequest") << processVariableUpdate;
774 777 }
775 778
776 779 if (processVariableUpdate) {
777 780 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
778 781 varIdToVarRequestMapIt != varIdToVarRequestMap.cend(); ++varIdToVarRequestMapIt) {
779 782 if (auto var = findVariable(varIdToVarRequestMapIt->first)) {
780 783 auto &varRequest = varIdToVarRequestMapIt->second;
781 784 var->setRange(varRequest.m_RangeRequested);
782 785 var->setCacheRange(varRequest.m_CacheRangeRequested);
783 qCDebug(LOG_VariableController()) << tr("1: onDataProvided")
784 << varRequest.m_RangeRequested;
785 qCDebug(LOG_VariableController()) << tr("2: onDataProvided")
786 << varRequest.m_CacheRangeRequested;
786 qCDebug(LOG_VariableController())
787 << tr("1: onDataProvided") << varRequest.m_RangeRequested;
788 qCDebug(LOG_VariableController())
789 << tr("2: onDataProvided") << varRequest.m_CacheRangeRequested;
787 790 var->mergeDataSeries(varRequest.m_DataSeries);
788 qCDebug(LOG_VariableController()) << tr("3: onDataProvided")
789 << varRequest.m_DataSeries->range();
791 qCDebug(LOG_VariableController())
792 << tr("3: onDataProvided") << varRequest.m_DataSeries->range();
790 793 qCDebug(LOG_VariableController()) << tr("4: onDataProvided");
791 794
792 795 /// @todo MPL: confirm
793 796 // Variable update is notified only if there is no pending request for it
794 797 // if
795 798 // (m_VarIdToVarRequestIdQueueMap.count(varIdToVarRequestMapIt->first)
796 799 // == 0) {
797 800 emit var->updated();
798 801 // }
799 802 }
800 803 else {
801 804 qCCritical(LOG_VariableController())
802 805 << tr("Impossible to update data to a null variable");
803 806 }
804 807 }
805 808
806 809 // cleaning varRequestId
807 qCDebug(LOG_VariableController()) << tr("0: erase REQUEST in MAP ?")
808 << m_VarRequestIdToVarIdVarRequestMap.size();
810 qCDebug(LOG_VariableController())
811 << tr("0: erase REQUEST in MAP ?") << m_VarRequestIdToVarIdVarRequestMap.size();
809 812 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
810 qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in MAP ?")
811 << m_VarRequestIdToVarIdVarRequestMap.size();
813 qCDebug(LOG_VariableController())
814 << tr("1: erase REQUEST in MAP ?") << m_VarRequestIdToVarIdVarRequestMap.size();
812 815 }
813 816 }
814 817 else {
815 818 qCCritical(LOG_VariableController())
816 819 << tr("Cannot updateVariableRequest for a unknow varRequestId") << varRequestId;
817 820 }
818 821 }
819 822
820 823 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
821 824 {
822 825 // cleaning varRequestId
823 826 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
824 827
825 828 for (auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.begin();
826 829 varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.end();) {
827 830 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
828 831 varRequestIdQueue.erase(
829 832 std::remove(varRequestIdQueue.begin(), varRequestIdQueue.end(), varRequestId),
830 833 varRequestIdQueue.end());
831 834 if (varRequestIdQueue.empty()) {
832 835 varIdToVarRequestIdQueueMapIt
833 836 = m_VarIdToVarRequestIdQueueMap.erase(varIdToVarRequestIdQueueMapIt);
834 837 }
835 838 else {
836 839 ++varIdToVarRequestIdQueueMapIt;
837 840 }
838 841 }
839 842 }
General Comments 0
You need to be logged in to leave comments. Login now