##// END OF EJS Templates
Merge branch 'feature/fixAcquisitionSynchroBug' into develop
perrinel -
r824:60a224a1b89a merge
parent child
Show More
@@ -1,83 +1,89
1 #ifndef SCIQLOP_VARIABLE_H
1 #ifndef SCIQLOP_VARIABLE_H
2 #define SCIQLOP_VARIABLE_H
2 #define SCIQLOP_VARIABLE_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Data/DataSeriesIterator.h>
6 #include <Data/DataSeriesIterator.h>
7 #include <Data/SqpRange.h>
7 #include <Data/SqpRange.h>
8
8
9 #include <QLoggingCategory>
9 #include <QLoggingCategory>
10 #include <QObject>
10 #include <QObject>
11
11
12 #include <Common/MetaTypes.h>
12 #include <Common/MetaTypes.h>
13 #include <Common/spimpl.h>
13 #include <Common/spimpl.h>
14
14
15 Q_DECLARE_LOGGING_CATEGORY(LOG_Variable)
15 Q_DECLARE_LOGGING_CATEGORY(LOG_Variable)
16
16
17 class IDataSeries;
17 class IDataSeries;
18 class QString;
18 class QString;
19
19
20 /**
20 /**
21 * @brief The Variable class represents a variable in SciQlop.
21 * @brief The Variable class represents a variable in SciQlop.
22 */
22 */
23 class SCIQLOP_CORE_EXPORT Variable : public QObject {
23 class SCIQLOP_CORE_EXPORT Variable : public QObject {
24
24
25 Q_OBJECT
25 Q_OBJECT
26
26
27 public:
27 public:
28 explicit Variable(const QString &name, const QVariantHash &metadata = {});
28 explicit Variable(const QString &name, const QVariantHash &metadata = {});
29
29
30 /// Copy ctor
30 /// Copy ctor
31 explicit Variable(const Variable &other);
31 explicit Variable(const Variable &other);
32
32
33 std::shared_ptr<Variable> clone() const;
33 std::shared_ptr<Variable> clone() const;
34
34
35 QString name() const noexcept;
35 QString name() const noexcept;
36 void setName(const QString &name) noexcept;
36 void setName(const QString &name) noexcept;
37 SqpRange range() const noexcept;
37 SqpRange range() const noexcept;
38 void setRange(const SqpRange &range) noexcept;
38 void setRange(const SqpRange &range) noexcept;
39 SqpRange cacheRange() const noexcept;
39 SqpRange cacheRange() const noexcept;
40 void setCacheRange(const SqpRange &cacheRange) noexcept;
40 void setCacheRange(const SqpRange &cacheRange) noexcept;
41
41
42 /// @return the number of points hold by the variable. The number of points is updated each time
42 /// @return the number of points hold by the variable. The number of points is updated each time
43 /// the data series changes
43 /// the data series changes
44 int nbPoints() const noexcept;
44 int nbPoints() const noexcept;
45
45
46 /// Returns the real range of the variable, i.e. the min and max x-axis values of the data
46 /// Returns the real range of the variable, i.e. the min and max x-axis values of the data
47 /// series between the range of the variable. The real range is updated each time the variable
47 /// series between the range of the variable. The real range is updated each time the variable
48 /// range or the data series changed
48 /// range or the data series changed
49 /// @return the real range, invalid range if the data series is null or empty
49 /// @return the real range, invalid range if the data series is null or empty
50 /// @sa setDataSeries()
50 /// @sa setDataSeries()
51 /// @sa setRange()
51 /// @sa setRange()
52 SqpRange realRange() const noexcept;
52 SqpRange realRange() const noexcept;
53
53
54 /// @return the data of the variable, nullptr if there is no data
54 /// @return the data of the variable, nullptr if there is no data
55 std::shared_ptr<IDataSeries> dataSeries() const noexcept;
55 std::shared_ptr<IDataSeries> dataSeries() const noexcept;
56
56
57 QVariantHash metadata() const noexcept;
57 QVariantHash metadata() const noexcept;
58
58
59 bool contains(const SqpRange &range) const noexcept;
59 bool contains(const SqpRange &range) const noexcept;
60 bool intersect(const SqpRange &range) const noexcept;
60 bool intersect(const SqpRange &range) const noexcept;
61 bool isInside(const SqpRange &range) const noexcept;
61 bool isInside(const SqpRange &range) const noexcept;
62
62
63 bool cacheContains(const SqpRange &range) const noexcept;
63 bool cacheContains(const SqpRange &range) const noexcept;
64 bool cacheIntersect(const SqpRange &range) const noexcept;
64 bool cacheIntersect(const SqpRange &range) const noexcept;
65 bool cacheIsInside(const SqpRange &range) const noexcept;
65 bool cacheIsInside(const SqpRange &range) const noexcept;
66
66
67 QVector<SqpRange> provideNotInCacheRangeList(const SqpRange &range) const noexcept;
67 QVector<SqpRange> provideNotInCacheRangeList(const SqpRange &range) const noexcept;
68 QVector<SqpRange> provideInCacheRangeList(const SqpRange &range) const noexcept;
68 QVector<SqpRange> provideInCacheRangeList(const SqpRange &range) const noexcept;
69 void mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept;
69 void mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept;
70
70
71 static QVector<SqpRange> provideNotInCacheRangeList(const SqpRange &oldRange,
72 const SqpRange &nextRange);
73
74 static QVector<SqpRange> provideInCacheRangeList(const SqpRange &oldRange,
75 const SqpRange &nextRange);
76
71 signals:
77 signals:
72 void updated();
78 void updated();
73
79
74 private:
80 private:
75 class VariablePrivate;
81 class VariablePrivate;
76 spimpl::unique_impl_ptr<VariablePrivate> impl;
82 spimpl::unique_impl_ptr<VariablePrivate> impl;
77 };
83 };
78
84
79 // Required for using shared_ptr in signals/slots
85 // Required for using shared_ptr in signals/slots
80 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_REGISTRY, std::shared_ptr<Variable>)
86 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_REGISTRY, std::shared_ptr<Variable>)
81 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_VECTOR_REGISTRY, QVector<std::shared_ptr<Variable> >)
87 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_VECTOR_REGISTRY, QVector<std::shared_ptr<Variable> >)
82
88
83 #endif // SCIQLOP_VARIABLE_H
89 #endif // SCIQLOP_VARIABLE_H
@@ -1,315 +1,388
1 #include "Variable/Variable.h"
1 #include "Variable/Variable.h"
2
2
3 #include <Data/IDataSeries.h>
3 #include <Data/IDataSeries.h>
4 #include <Data/SqpRange.h>
4 #include <Data/SqpRange.h>
5
5
6 #include <QMutex>
6 #include <QMutex>
7 #include <QReadWriteLock>
7 #include <QReadWriteLock>
8 #include <QThread>
8 #include <QThread>
9
9
10 Q_LOGGING_CATEGORY(LOG_Variable, "Variable")
10 Q_LOGGING_CATEGORY(LOG_Variable, "Variable")
11
11
12 struct Variable::VariablePrivate {
12 struct Variable::VariablePrivate {
13 explicit VariablePrivate(const QString &name, const QVariantHash &metadata)
13 explicit VariablePrivate(const QString &name, const QVariantHash &metadata)
14 : m_Name{name},
14 : m_Name{name},
15 m_Range{INVALID_RANGE},
15 m_Range{INVALID_RANGE},
16 m_CacheRange{INVALID_RANGE},
16 m_CacheRange{INVALID_RANGE},
17 m_Metadata{metadata},
17 m_Metadata{metadata},
18 m_DataSeries{nullptr},
18 m_DataSeries{nullptr},
19 m_RealRange{INVALID_RANGE},
19 m_RealRange{INVALID_RANGE},
20 m_NbPoints{0}
20 m_NbPoints{0}
21 {
21 {
22 }
22 }
23
23
24 VariablePrivate(const VariablePrivate &other)
24 VariablePrivate(const VariablePrivate &other)
25 : m_Name{other.m_Name},
25 : m_Name{other.m_Name},
26 m_Range{other.m_Range},
26 m_Range{other.m_Range},
27 m_CacheRange{other.m_CacheRange},
27 m_CacheRange{other.m_CacheRange},
28 m_Metadata{other.m_Metadata},
28 m_Metadata{other.m_Metadata},
29 m_DataSeries{other.m_DataSeries != nullptr ? other.m_DataSeries->clone() : nullptr},
29 m_DataSeries{other.m_DataSeries != nullptr ? other.m_DataSeries->clone() : nullptr},
30 m_RealRange{other.m_RealRange},
30 m_RealRange{other.m_RealRange},
31 m_NbPoints{other.m_NbPoints}
31 m_NbPoints{other.m_NbPoints}
32 {
32 {
33 }
33 }
34
34
35 void lockRead() { m_Lock.lockForRead(); }
35 void lockRead() { m_Lock.lockForRead(); }
36 void lockWrite() { m_Lock.lockForWrite(); }
36 void lockWrite() { m_Lock.lockForWrite(); }
37 void unlock() { m_Lock.unlock(); }
37 void unlock() { m_Lock.unlock(); }
38
38
39 void purgeDataSeries()
39 void purgeDataSeries()
40 {
40 {
41 if (m_DataSeries) {
41 if (m_DataSeries) {
42 m_DataSeries->purge(m_CacheRange.m_TStart, m_CacheRange.m_TEnd);
42 m_DataSeries->purge(m_CacheRange.m_TStart, m_CacheRange.m_TEnd);
43 }
43 }
44 updateRealRange();
44 updateRealRange();
45 updateNbPoints();
45 updateNbPoints();
46 }
46 }
47
47
48 void updateNbPoints() { m_NbPoints = m_DataSeries ? m_DataSeries->nbPoints() : 0; }
48 void updateNbPoints() { m_NbPoints = m_DataSeries ? m_DataSeries->nbPoints() : 0; }
49
49
50 /// Updates real range according to current variable range and data series
50 /// Updates real range according to current variable range and data series
51 void updateRealRange()
51 void updateRealRange()
52 {
52 {
53 if (m_DataSeries) {
53 if (m_DataSeries) {
54 m_DataSeries->lockRead();
54 m_DataSeries->lockRead();
55 auto end = m_DataSeries->cend();
55 auto end = m_DataSeries->cend();
56 auto minXAxisIt = m_DataSeries->minXAxisData(m_Range.m_TStart);
56 auto minXAxisIt = m_DataSeries->minXAxisData(m_Range.m_TStart);
57 auto maxXAxisIt = m_DataSeries->maxXAxisData(m_Range.m_TEnd);
57 auto maxXAxisIt = m_DataSeries->maxXAxisData(m_Range.m_TEnd);
58
58
59 m_RealRange
59 m_RealRange
60 = (minXAxisIt != end && maxXAxisIt != end && minXAxisIt->x() <= maxXAxisIt->x())
60 = (minXAxisIt != end && maxXAxisIt != end && minXAxisIt->x() <= maxXAxisIt->x())
61 ? SqpRange{minXAxisIt->x(), maxXAxisIt->x()}
61 ? SqpRange{minXAxisIt->x(), maxXAxisIt->x()}
62 : INVALID_RANGE;
62 : INVALID_RANGE;
63 m_DataSeries->unlock();
63 m_DataSeries->unlock();
64 }
64 }
65 else {
65 else {
66 m_RealRange = INVALID_RANGE;
66 m_RealRange = INVALID_RANGE;
67 }
67 }
68 }
68 }
69
69
70 QString m_Name;
70 QString m_Name;
71
71
72 SqpRange m_Range;
72 SqpRange m_Range;
73 SqpRange m_CacheRange;
73 SqpRange m_CacheRange;
74 QVariantHash m_Metadata;
74 QVariantHash m_Metadata;
75 std::shared_ptr<IDataSeries> m_DataSeries;
75 std::shared_ptr<IDataSeries> m_DataSeries;
76 SqpRange m_RealRange;
76 SqpRange m_RealRange;
77 int m_NbPoints;
77 int m_NbPoints;
78
78
79 QReadWriteLock m_Lock;
79 QReadWriteLock m_Lock;
80 };
80 };
81
81
82 Variable::Variable(const QString &name, const QVariantHash &metadata)
82 Variable::Variable(const QString &name, const QVariantHash &metadata)
83 : impl{spimpl::make_unique_impl<VariablePrivate>(name, metadata)}
83 : impl{spimpl::make_unique_impl<VariablePrivate>(name, metadata)}
84 {
84 {
85 }
85 }
86
86
87 Variable::Variable(const Variable &other)
87 Variable::Variable(const Variable &other)
88 : impl{spimpl::make_unique_impl<VariablePrivate>(*other.impl)}
88 : impl{spimpl::make_unique_impl<VariablePrivate>(*other.impl)}
89 {
89 {
90 }
90 }
91
91
92 std::shared_ptr<Variable> Variable::clone() const
92 std::shared_ptr<Variable> Variable::clone() const
93 {
93 {
94 return std::make_shared<Variable>(*this);
94 return std::make_shared<Variable>(*this);
95 }
95 }
96
96
97 QString Variable::name() const noexcept
97 QString Variable::name() const noexcept
98 {
98 {
99 impl->lockRead();
99 impl->lockRead();
100 auto name = impl->m_Name;
100 auto name = impl->m_Name;
101 impl->unlock();
101 impl->unlock();
102 return name;
102 return name;
103 }
103 }
104
104
105 void Variable::setName(const QString &name) noexcept
105 void Variable::setName(const QString &name) noexcept
106 {
106 {
107 impl->lockWrite();
107 impl->lockWrite();
108 impl->m_Name = name;
108 impl->m_Name = name;
109 impl->unlock();
109 impl->unlock();
110 }
110 }
111
111
112 SqpRange Variable::range() const noexcept
112 SqpRange Variable::range() const noexcept
113 {
113 {
114 impl->lockRead();
114 impl->lockRead();
115 auto range = impl->m_Range;
115 auto range = impl->m_Range;
116 impl->unlock();
116 impl->unlock();
117 return range;
117 return range;
118 }
118 }
119
119
120 void Variable::setRange(const SqpRange &range) noexcept
120 void Variable::setRange(const SqpRange &range) noexcept
121 {
121 {
122 impl->lockWrite();
122 impl->lockWrite();
123 impl->m_Range = range;
123 impl->m_Range = range;
124 impl->updateRealRange();
124 impl->updateRealRange();
125 impl->unlock();
125 impl->unlock();
126 }
126 }
127
127
128 SqpRange Variable::cacheRange() const noexcept
128 SqpRange Variable::cacheRange() const noexcept
129 {
129 {
130 impl->lockRead();
130 impl->lockRead();
131 auto cacheRange = impl->m_CacheRange;
131 auto cacheRange = impl->m_CacheRange;
132 impl->unlock();
132 impl->unlock();
133 return cacheRange;
133 return cacheRange;
134 }
134 }
135
135
136 void Variable::setCacheRange(const SqpRange &cacheRange) noexcept
136 void Variable::setCacheRange(const SqpRange &cacheRange) noexcept
137 {
137 {
138 impl->lockWrite();
138 impl->lockWrite();
139 if (cacheRange != impl->m_CacheRange) {
139 if (cacheRange != impl->m_CacheRange) {
140 impl->m_CacheRange = cacheRange;
140 impl->m_CacheRange = cacheRange;
141 impl->purgeDataSeries();
142 }
141 }
143 impl->unlock();
142 impl->unlock();
144 }
143 }
145
144
146 int Variable::nbPoints() const noexcept
145 int Variable::nbPoints() const noexcept
147 {
146 {
148 return impl->m_NbPoints;
147 return impl->m_NbPoints;
149 }
148 }
150
149
151 SqpRange Variable::realRange() const noexcept
150 SqpRange Variable::realRange() const noexcept
152 {
151 {
153 return impl->m_RealRange;
152 return impl->m_RealRange;
154 }
153 }
155
154
156 void Variable::mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
155 void Variable::mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
157 {
156 {
158 qCDebug(LOG_Variable()) << "TORM Variable::mergeDataSeries"
157 qCDebug(LOG_Variable()) << "TORM Variable::mergeDataSeries"
159 << QThread::currentThread()->objectName();
158 << QThread::currentThread()->objectName();
160 if (!dataSeries) {
159 if (!dataSeries) {
161 /// @todo ALX : log
160 /// @todo ALX : log
162 return;
161 return;
163 }
162 }
164
163
165 // Add or merge the data
164 // Add or merge the data
166 impl->lockWrite();
165 impl->lockWrite();
167 if (!impl->m_DataSeries) {
166 if (!impl->m_DataSeries) {
168 impl->m_DataSeries = dataSeries->clone();
167 impl->m_DataSeries = dataSeries->clone();
169 }
168 }
170 else {
169 else {
171 impl->m_DataSeries->merge(dataSeries.get());
170 impl->m_DataSeries->merge(dataSeries.get());
172 }
171 }
173 impl->purgeDataSeries();
172 impl->purgeDataSeries();
174 impl->unlock();
173 impl->unlock();
175 }
174 }
176
175
176
177 std::shared_ptr<IDataSeries> Variable::dataSeries() const noexcept
177 std::shared_ptr<IDataSeries> Variable::dataSeries() const noexcept
178 {
178 {
179 impl->lockRead();
179 impl->lockRead();
180 auto dataSeries = impl->m_DataSeries;
180 auto dataSeries = impl->m_DataSeries;
181 impl->unlock();
181 impl->unlock();
182
182
183 return dataSeries;
183 return dataSeries;
184 }
184 }
185
185
186 QVariantHash Variable::metadata() const noexcept
186 QVariantHash Variable::metadata() const noexcept
187 {
187 {
188 impl->lockRead();
188 impl->lockRead();
189 auto metadata = impl->m_Metadata;
189 auto metadata = impl->m_Metadata;
190 impl->unlock();
190 impl->unlock();
191 return metadata;
191 return metadata;
192 }
192 }
193
193
194 bool Variable::contains(const SqpRange &range) const noexcept
194 bool Variable::contains(const SqpRange &range) const noexcept
195 {
195 {
196 impl->lockRead();
196 impl->lockRead();
197 auto res = impl->m_Range.contains(range);
197 auto res = impl->m_Range.contains(range);
198 impl->unlock();
198 impl->unlock();
199 return res;
199 return res;
200 }
200 }
201
201
202 bool Variable::intersect(const SqpRange &range) const noexcept
202 bool Variable::intersect(const SqpRange &range) const noexcept
203 {
203 {
204
204
205 impl->lockRead();
205 impl->lockRead();
206 auto res = impl->m_Range.intersect(range);
206 auto res = impl->m_Range.intersect(range);
207 impl->unlock();
207 impl->unlock();
208 return res;
208 return res;
209 }
209 }
210
210
211 bool Variable::isInside(const SqpRange &range) const noexcept
211 bool Variable::isInside(const SqpRange &range) const noexcept
212 {
212 {
213 impl->lockRead();
213 impl->lockRead();
214 auto res = range.contains(SqpRange{impl->m_Range.m_TStart, impl->m_Range.m_TEnd});
214 auto res = range.contains(SqpRange{impl->m_Range.m_TStart, impl->m_Range.m_TEnd});
215 impl->unlock();
215 impl->unlock();
216 return res;
216 return res;
217 }
217 }
218
218
219 bool Variable::cacheContains(const SqpRange &range) const noexcept
219 bool Variable::cacheContains(const SqpRange &range) const noexcept
220 {
220 {
221 impl->lockRead();
221 impl->lockRead();
222 auto res = impl->m_CacheRange.contains(range);
222 auto res = impl->m_CacheRange.contains(range);
223 impl->unlock();
223 impl->unlock();
224 return res;
224 return res;
225 }
225 }
226
226
227 bool Variable::cacheIntersect(const SqpRange &range) const noexcept
227 bool Variable::cacheIntersect(const SqpRange &range) const noexcept
228 {
228 {
229 impl->lockRead();
229 impl->lockRead();
230 auto res = impl->m_CacheRange.intersect(range);
230 auto res = impl->m_CacheRange.intersect(range);
231 impl->unlock();
231 impl->unlock();
232 return res;
232 return res;
233 }
233 }
234
234
235 bool Variable::cacheIsInside(const SqpRange &range) const noexcept
235 bool Variable::cacheIsInside(const SqpRange &range) const noexcept
236 {
236 {
237 impl->lockRead();
237 impl->lockRead();
238 auto res = range.contains(SqpRange{impl->m_CacheRange.m_TStart, impl->m_CacheRange.m_TEnd});
238 auto res = range.contains(SqpRange{impl->m_CacheRange.m_TStart, impl->m_CacheRange.m_TEnd});
239 impl->unlock();
239 impl->unlock();
240 return res;
240 return res;
241 }
241 }
242
242
243
243
244 QVector<SqpRange> Variable::provideNotInCacheRangeList(const SqpRange &range) const noexcept
244 QVector<SqpRange> Variable::provideNotInCacheRangeList(const SqpRange &range) const noexcept
245 {
245 {
246 // This code assume that cach in contigue. Can return 0, 1 or 2 SqpRange
246 // This code assume that cach in contigue. Can return 0, 1 or 2 SqpRange
247 auto notInCache = QVector<SqpRange>{};
247 auto notInCache = QVector<SqpRange>{};
248 if (impl->m_CacheRange != INVALID_RANGE) {
248 if (impl->m_CacheRange != INVALID_RANGE) {
249
249
250 if (!this->cacheContains(range)) {
250 if (!this->cacheContains(range)) {
251 if (range.m_TEnd <= impl->m_CacheRange.m_TStart
251 if (range.m_TEnd <= impl->m_CacheRange.m_TStart
252 || range.m_TStart >= impl->m_CacheRange.m_TEnd) {
252 || range.m_TStart >= impl->m_CacheRange.m_TEnd) {
253 notInCache << range;
253 notInCache << range;
254 }
254 }
255 else if (range.m_TStart < impl->m_CacheRange.m_TStart
255 else if (range.m_TStart < impl->m_CacheRange.m_TStart
256 && range.m_TEnd <= impl->m_CacheRange.m_TEnd) {
256 && range.m_TEnd <= impl->m_CacheRange.m_TEnd) {
257 notInCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TStart};
257 notInCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TStart};
258 }
258 }
259 else if (range.m_TStart < impl->m_CacheRange.m_TStart
259 else if (range.m_TStart < impl->m_CacheRange.m_TStart
260 && range.m_TEnd > impl->m_CacheRange.m_TEnd) {
260 && range.m_TEnd > impl->m_CacheRange.m_TEnd) {
261 notInCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TStart}
261 notInCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TStart}
262 << SqpRange{impl->m_CacheRange.m_TEnd, range.m_TEnd};
262 << SqpRange{impl->m_CacheRange.m_TEnd, range.m_TEnd};
263 }
263 }
264 else if (range.m_TStart < impl->m_CacheRange.m_TEnd) {
264 else if (range.m_TStart < impl->m_CacheRange.m_TEnd) {
265 notInCache << SqpRange{impl->m_CacheRange.m_TEnd, range.m_TEnd};
265 notInCache << SqpRange{impl->m_CacheRange.m_TEnd, range.m_TEnd};
266 }
266 }
267 else {
267 else {
268 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
268 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
269 << QThread::currentThread();
269 << QThread::currentThread();
270 }
270 }
271 }
271 }
272 }
272 }
273 else {
273 else {
274 notInCache << range;
274 notInCache << range;
275 }
275 }
276
276
277 return notInCache;
277 return notInCache;
278 }
278 }
279
279
280 QVector<SqpRange> Variable::provideInCacheRangeList(const SqpRange &range) const noexcept
280 QVector<SqpRange> Variable::provideInCacheRangeList(const SqpRange &range) const noexcept
281 {
281 {
282 // This code assume that cach in contigue. Can return 0 or 1 SqpRange
282 // This code assume that cach in contigue. Can return 0 or 1 SqpRange
283
283
284 auto inCache = QVector<SqpRange>{};
284 auto inCache = QVector<SqpRange>{};
285
285
286 if (impl->m_CacheRange != INVALID_RANGE) {
286 if (impl->m_CacheRange != INVALID_RANGE) {
287
287
288 if (this->intersect(range)) {
288 if (this->cacheIntersect(range)) {
289 if (range.m_TStart <= impl->m_CacheRange.m_TStart
289 if (range.m_TStart <= impl->m_CacheRange.m_TStart
290 && range.m_TEnd >= impl->m_CacheRange.m_TStart
290 && range.m_TEnd >= impl->m_CacheRange.m_TStart
291 && range.m_TEnd < impl->m_CacheRange.m_TEnd) {
291 && range.m_TEnd < impl->m_CacheRange.m_TEnd) {
292 inCache << SqpRange{impl->m_CacheRange.m_TStart, range.m_TEnd};
292 inCache << SqpRange{impl->m_CacheRange.m_TStart, range.m_TEnd};
293 }
293 }
294
294
295 else if (range.m_TStart >= impl->m_CacheRange.m_TStart
295 else if (range.m_TStart >= impl->m_CacheRange.m_TStart
296 && range.m_TEnd <= impl->m_CacheRange.m_TEnd) {
296 && range.m_TEnd <= impl->m_CacheRange.m_TEnd) {
297 inCache << range;
297 inCache << range;
298 }
298 }
299 else if (range.m_TStart > impl->m_CacheRange.m_TStart
299 else if (range.m_TStart > impl->m_CacheRange.m_TStart
300 && range.m_TEnd > impl->m_CacheRange.m_TEnd) {
300 && range.m_TEnd > impl->m_CacheRange.m_TEnd) {
301 inCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TEnd};
301 inCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TEnd};
302 }
302 }
303 else if (range.m_TStart <= impl->m_CacheRange.m_TStart
303 else if (range.m_TStart <= impl->m_CacheRange.m_TStart
304 && range.m_TEnd >= impl->m_CacheRange.m_TEnd) {
304 && range.m_TEnd >= impl->m_CacheRange.m_TEnd) {
305 inCache << impl->m_CacheRange;
305 inCache << impl->m_CacheRange;
306 }
306 }
307 else {
307 else {
308 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
308 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
309 << QThread::currentThread();
309 << QThread::currentThread();
310 }
310 }
311 }
311 }
312 }
312 }
313
313
314 return inCache;
314 return inCache;
315 }
315 }
316
317
318 QVector<SqpRange> Variable::provideNotInCacheRangeList(const SqpRange &oldRange,
319 const SqpRange &nextRange)
320 {
321
322 // This code assume that cach in contigue. Can return 0, 1 or 2 SqpRange
323 auto notInCache = QVector<SqpRange>{};
324 if (oldRange != INVALID_RANGE) {
325
326 if (!oldRange.contains(nextRange)) {
327 if (nextRange.m_TEnd <= oldRange.m_TStart || nextRange.m_TStart >= oldRange.m_TEnd) {
328 notInCache << nextRange;
329 }
330 else if (nextRange.m_TStart < oldRange.m_TStart
331 && nextRange.m_TEnd <= oldRange.m_TEnd) {
332 notInCache << SqpRange{nextRange.m_TStart, oldRange.m_TStart};
333 }
334 else if (nextRange.m_TStart < oldRange.m_TStart && nextRange.m_TEnd > oldRange.m_TEnd) {
335 notInCache << SqpRange{nextRange.m_TStart, oldRange.m_TStart}
336 << SqpRange{oldRange.m_TEnd, nextRange.m_TEnd};
337 }
338 else if (nextRange.m_TStart < oldRange.m_TEnd) {
339 notInCache << SqpRange{oldRange.m_TEnd, nextRange.m_TEnd};
340 }
341 else {
342 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
343 << QThread::currentThread();
344 }
345 }
346 }
347 else {
348 notInCache << nextRange;
349 }
350
351 return notInCache;
352 }
353
354 QVector<SqpRange> Variable::provideInCacheRangeList(const SqpRange &oldRange,
355 const SqpRange &nextRange)
356 {
357 // This code assume that cach is contigue. Can return 0 or 1 SqpRange
358
359 auto inCache = QVector<SqpRange>{};
360
361 if (oldRange != INVALID_RANGE) {
362
363 if (oldRange.intersect(nextRange)) {
364 if (nextRange.m_TStart <= oldRange.m_TStart && nextRange.m_TEnd >= oldRange.m_TStart
365 && nextRange.m_TEnd < oldRange.m_TEnd) {
366 inCache << SqpRange{oldRange.m_TStart, nextRange.m_TEnd};
367 }
368
369 else if (nextRange.m_TStart >= oldRange.m_TStart
370 && nextRange.m_TEnd <= oldRange.m_TEnd) {
371 inCache << nextRange;
372 }
373 else if (nextRange.m_TStart > oldRange.m_TStart && nextRange.m_TEnd > oldRange.m_TEnd) {
374 inCache << SqpRange{nextRange.m_TStart, oldRange.m_TEnd};
375 }
376 else if (nextRange.m_TStart <= oldRange.m_TStart
377 && nextRange.m_TEnd >= oldRange.m_TEnd) {
378 inCache << oldRange;
379 }
380 else {
381 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
382 << QThread::currentThread();
383 }
384 }
385 }
386
387 return inCache;
388 }
@@ -1,322 +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
36 void cancelVarRequest(QUuid varRequestId);
37 void removeAcqRequest(QUuid acqRequestId);
38
35 QMutex m_WorkingMutex;
39 QMutex m_WorkingMutex;
36 QReadWriteLock m_Lock;
40 QReadWriteLock m_Lock;
37
41
38 std::map<QUuid, QVector<AcquisitionDataPacket> > m_AcqIdentifierToAcqDataPacketVectorMap;
42 std::map<QUuid, QVector<AcquisitionDataPacket> > m_AcqIdentifierToAcqDataPacketVectorMap;
39 std::map<QUuid, AcquisitionRequest> m_AcqIdentifierToAcqRequestMap;
43 std::map<QUuid, AcquisitionRequest> m_AcqIdentifierToAcqRequestMap;
40 std::map<QUuid, std::pair<QUuid, QUuid> > m_VIdentifierToCurrrentAcqIdNextIdPairMap;
44 std::map<QUuid, std::pair<QUuid, QUuid> > m_VIdentifierToCurrrentAcqIdNextIdPairMap;
41 VariableAcquisitionWorker *q;
45 VariableAcquisitionWorker *q;
42 };
46 };
43
47
44
48
45 VariableAcquisitionWorker::VariableAcquisitionWorker(QObject *parent)
49 VariableAcquisitionWorker::VariableAcquisitionWorker(QObject *parent)
46 : QObject{parent}, impl{spimpl::make_unique_impl<VariableAcquisitionWorkerPrivate>(this)}
50 : QObject{parent}, impl{spimpl::make_unique_impl<VariableAcquisitionWorkerPrivate>(this)}
47 {
51 {
48 }
52 }
49
53
50 VariableAcquisitionWorker::~VariableAcquisitionWorker()
54 VariableAcquisitionWorker::~VariableAcquisitionWorker()
51 {
55 {
52 qCInfo(LOG_VariableAcquisitionWorker()) << tr("VariableAcquisitionWorker destruction")
56 qCInfo(LOG_VariableAcquisitionWorker()) << tr("VariableAcquisitionWorker destruction")
53 << QThread::currentThread();
57 << QThread::currentThread();
54 this->waitForFinish();
58 this->waitForFinish();
55 }
59 }
56
60
57
61
58 QUuid VariableAcquisitionWorker::pushVariableRequest(QUuid varRequestId, QUuid vIdentifier,
62 QUuid VariableAcquisitionWorker::pushVariableRequest(QUuid varRequestId, QUuid vIdentifier,
59 SqpRange rangeRequested,
63 SqpRange rangeRequested,
60 SqpRange cacheRangeRequested,
64 SqpRange cacheRangeRequested,
61 DataProviderParameters parameters,
65 DataProviderParameters parameters,
62 std::shared_ptr<IDataProvider> provider)
66 std::shared_ptr<IDataProvider> provider)
63 {
67 {
64 qCDebug(LOG_VariableAcquisitionWorker())
68 qCDebug(LOG_VariableAcquisitionWorker())
65 << tr("TORM VariableAcquisitionWorker::pushVariableRequest ") << cacheRangeRequested;
69 << tr("TORM VariableAcquisitionWorker::pushVariableRequest ") << cacheRangeRequested;
66 auto varRequestIdCanceled = QUuid();
70 auto varRequestIdCanceled = QUuid();
67
71
68 // Request creation
72 // Request creation
69 auto acqRequest = AcquisitionRequest{};
73 auto acqRequest = AcquisitionRequest{};
70 qCInfo(LOG_VariableAcquisitionWorker()) << tr("TpushVariableRequest ") << vIdentifier;
74 qCDebug(LOG_VariableAcquisitionWorker()) << tr("PushVariableRequest ") << vIdentifier
75 << varRequestId;
71 acqRequest.m_VarRequestId = varRequestId;
76 acqRequest.m_VarRequestId = varRequestId;
72 acqRequest.m_vIdentifier = vIdentifier;
77 acqRequest.m_vIdentifier = vIdentifier;
73 acqRequest.m_DataProviderParameters = parameters;
78 acqRequest.m_DataProviderParameters = parameters;
74 acqRequest.m_RangeRequested = rangeRequested;
79 acqRequest.m_RangeRequested = rangeRequested;
75 acqRequest.m_CacheRangeRequested = cacheRangeRequested;
80 acqRequest.m_CacheRangeRequested = cacheRangeRequested;
76 acqRequest.m_Size = parameters.m_Times.size();
81 acqRequest.m_Size = parameters.m_Times.size();
77 acqRequest.m_Provider = provider;
82 acqRequest.m_Provider = provider;
78
83
79
84
80 // Register request
85 // Register request
81 impl->lockWrite();
86 impl->lockWrite();
82 impl->m_AcqIdentifierToAcqRequestMap.insert(
87 impl->m_AcqIdentifierToAcqRequestMap.insert(
83 std::make_pair(acqRequest.m_AcqIdentifier, acqRequest));
88 std::make_pair(acqRequest.m_AcqIdentifier, acqRequest));
84
89
85 auto it = impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
90 auto it = impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
86 if (it != impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
91 if (it != impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
87 // A current request already exists, we can replace the next one
92 // A current request already exists, we can replace the next one
88 auto nextAcqId = it->second.second;
93 auto oldAcqId = it->second.second;
89 auto acqIdentifierToAcqRequestMapIt = impl->m_AcqIdentifierToAcqRequestMap.find(nextAcqId);
94 auto acqIdentifierToAcqRequestMapIt = impl->m_AcqIdentifierToAcqRequestMap.find(oldAcqId);
90 if (acqIdentifierToAcqRequestMapIt != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
95 if (acqIdentifierToAcqRequestMapIt != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
91 auto request = acqIdentifierToAcqRequestMapIt->second;
96 auto oldAcqRequest = acqIdentifierToAcqRequestMapIt->second;
92 varRequestIdCanceled = request.m_VarRequestId;
97 varRequestIdCanceled = oldAcqRequest.m_VarRequestId;
93 }
98 }
94
99
95 it->second.second = acqRequest.m_AcqIdentifier;
100 it->second.second = acqRequest.m_AcqIdentifier;
96 impl->unlock();
101 impl->unlock();
102
103 // remove old acqIdentifier from the worker
104 impl->cancelVarRequest(varRequestIdCanceled);
105 // impl->m_AcqIdentifierToAcqRequestMap.erase(oldAcqId);
97 }
106 }
98 else {
107 else {
99 // First request for the variable, it must be stored and executed
108 // First request for the variable, it must be stored and executed
100 impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.insert(
109 impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.insert(
101 std::make_pair(vIdentifier, std::make_pair(acqRequest.m_AcqIdentifier, QUuid())));
110 std::make_pair(vIdentifier, std::make_pair(acqRequest.m_AcqIdentifier, QUuid())));
102 impl->unlock();
111 impl->unlock();
103
112
104 QMetaObject::invokeMethod(this, "onExecuteRequest", Qt::QueuedConnection,
113 QMetaObject::invokeMethod(this, "onExecuteRequest", Qt::QueuedConnection,
105 Q_ARG(QUuid, acqRequest.m_AcqIdentifier));
114 Q_ARG(QUuid, acqRequest.m_AcqIdentifier));
106 }
115 }
107
116
108 return varRequestIdCanceled;
117 return varRequestIdCanceled;
109 }
118 }
110
119
111 void VariableAcquisitionWorker::abortProgressRequested(QUuid vIdentifier)
120 void VariableAcquisitionWorker::abortProgressRequested(QUuid vIdentifier)
112 {
121 {
113 impl->lockRead();
122 impl->lockRead();
114
123
115 auto it = impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
124 auto it = impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
116 if (it != impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
125 if (it != impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
117 auto currentAcqId = it->second.first;
126 auto currentAcqId = it->second.first;
118
127
119 auto it = impl->m_AcqIdentifierToAcqRequestMap.find(currentAcqId);
128 auto it = impl->m_AcqIdentifierToAcqRequestMap.find(currentAcqId);
120 if (it != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
129 if (it != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
121 auto request = it->second;
130 auto request = it->second;
122 impl->unlock();
131 impl->unlock();
123
132
124 // Remove the current request from the worker
133 // Remove the current request from the worker
125
126 impl->lockWrite();
127 impl->updateToNextRequest(vIdentifier);
134 impl->updateToNextRequest(vIdentifier);
128 impl->unlock();
129
135
130 // notify the request aborting to the provider
136 // notify the request aborting to the provider
131 request.m_Provider->requestDataAborting(currentAcqId);
137 request.m_Provider->requestDataAborting(currentAcqId);
132 }
138 }
133 else {
139 else {
134 impl->unlock();
140 impl->unlock();
135 qCWarning(LOG_VariableAcquisitionWorker())
141 qCWarning(LOG_VariableAcquisitionWorker())
136 << tr("Impossible to abort an unknown acquisition request") << currentAcqId;
142 << tr("Impossible to abort an unknown acquisition request") << currentAcqId;
137 }
143 }
138 }
144 }
139 else {
145 else {
140 impl->unlock();
146 impl->unlock();
141 }
147 }
142 }
148 }
143
149
144 void VariableAcquisitionWorker::onVariableRetrieveDataInProgress(QUuid acqIdentifier,
150 void VariableAcquisitionWorker::onVariableRetrieveDataInProgress(QUuid acqIdentifier,
145 double progress)
151 double progress)
146 {
152 {
147 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM: onVariableRetrieveDataInProgress ")
153 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM: onVariableRetrieveDataInProgress ")
148 << acqIdentifier << progress;
154 << acqIdentifier << progress;
149 impl->lockRead();
155 impl->lockRead();
150 auto aIdToARit = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier);
156 auto aIdToARit = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier);
151 if (aIdToARit != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
157 if (aIdToARit != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
152 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;
153
159
154 auto currentPartProgress
160 auto currentPartProgress
155 = std::isnan(progress) ? 0.0 : (progress * currentPartSize) / 100.0;
161 = std::isnan(progress) ? 0.0 : (progress * currentPartSize) / 100.0;
156 auto currentAlreadyProgress = aIdToARit->second.m_Progression * currentPartSize;
162 auto currentAlreadyProgress = aIdToARit->second.m_Progression * currentPartSize;
157
163
158 auto finalProgression = currentAlreadyProgress + currentPartProgress;
164 auto finalProgression = currentAlreadyProgress + currentPartProgress;
159 emit variableRequestInProgress(aIdToARit->second.m_vIdentifier, finalProgression);
165 emit variableRequestInProgress(aIdToARit->second.m_vIdentifier, finalProgression);
160 qCDebug(LOG_VariableAcquisitionWorker())
166 qCDebug(LOG_VariableAcquisitionWorker())
161 << tr("TORM: onVariableRetrieveDataInProgress ")
167 << tr("TORM: onVariableRetrieveDataInProgress ")
162 << QThread::currentThread()->objectName() << aIdToARit->second.m_vIdentifier
168 << QThread::currentThread()->objectName() << aIdToARit->second.m_vIdentifier
163 << currentPartSize << currentAlreadyProgress << currentPartProgress << finalProgression;
169 << currentPartSize << currentAlreadyProgress << currentPartProgress << finalProgression;
164 if (finalProgression == 100.0) {
170 if (finalProgression == 100.0) {
165 emit variableRequestInProgress(aIdToARit->second.m_vIdentifier, 0.0);
171 emit variableRequestInProgress(aIdToARit->second.m_vIdentifier, 0.0);
166 }
172 }
167 }
173 }
168 impl->unlock();
174 impl->unlock();
169 }
175 }
170
176
171 void VariableAcquisitionWorker::onVariableAcquisitionFailed(QUuid acqIdentifier)
177 void VariableAcquisitionWorker::onVariableAcquisitionFailed(QUuid acqIdentifier)
172 {
178 {
173 qCDebug(LOG_VariableAcquisitionWorker()) << tr("onVariableAcquisitionFailed")
179 qCDebug(LOG_VariableAcquisitionWorker()) << tr("onVariableAcquisitionFailed")
174 << QThread::currentThread();
180 << QThread::currentThread();
175 impl->lockRead();
181 impl->lockRead();
176 auto it = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier);
182 auto it = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier);
177 if (it != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
183 if (it != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
178 auto request = it->second;
184 auto request = it->second;
179 impl->unlock();
185 impl->unlock();
180 qCInfo(LOG_VariableAcquisitionWorker()) << tr("onVariableAcquisitionFailed")
186 qCInfo(LOG_VariableAcquisitionWorker()) << tr("onVariableAcquisitionFailed")
181 << acqIdentifier << request.m_vIdentifier
187 << acqIdentifier << request.m_vIdentifier
182 << QThread::currentThread();
188 << QThread::currentThread();
183 emit variableCanceledRequested(request.m_vIdentifier);
189 emit variableCanceledRequested(request.m_vIdentifier);
184 }
190 }
185 else {
191 else {
186 impl->unlock();
192 impl->unlock();
187 // TODO log no acqIdentifier recognized
193 // TODO log no acqIdentifier recognized
188 }
194 }
189 }
195 }
190
196
191 void VariableAcquisitionWorker::onVariableDataAcquired(QUuid acqIdentifier,
197 void VariableAcquisitionWorker::onVariableDataAcquired(QUuid acqIdentifier,
192 std::shared_ptr<IDataSeries> dataSeries,
198 std::shared_ptr<IDataSeries> dataSeries,
193 SqpRange dataRangeAcquired)
199 SqpRange dataRangeAcquired)
194 {
200 {
195 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM: onVariableDataAcquired on range ")
201 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM: onVariableDataAcquired on range ")
196 << acqIdentifier << dataRangeAcquired;
202 << acqIdentifier << dataRangeAcquired;
197 impl->lockWrite();
203 impl->lockWrite();
198 auto aIdToARit = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier);
204 auto aIdToARit = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier);
199 if (aIdToARit != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
205 if (aIdToARit != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
200 // Store the result
206 // Store the result
201 auto dataPacket = AcquisitionDataPacket{};
207 auto dataPacket = AcquisitionDataPacket{};
202 dataPacket.m_Range = dataRangeAcquired;
208 dataPacket.m_Range = dataRangeAcquired;
203 dataPacket.m_DateSeries = dataSeries;
209 dataPacket.m_DateSeries = dataSeries;
204
210
205 auto aIdToADPVit = impl->m_AcqIdentifierToAcqDataPacketVectorMap.find(acqIdentifier);
211 auto aIdToADPVit = impl->m_AcqIdentifierToAcqDataPacketVectorMap.find(acqIdentifier);
206 if (aIdToADPVit != impl->m_AcqIdentifierToAcqDataPacketVectorMap.cend()) {
212 if (aIdToADPVit != impl->m_AcqIdentifierToAcqDataPacketVectorMap.cend()) {
207 // A current request result already exists, we can update it
213 // A current request result already exists, we can update it
208 aIdToADPVit->second.push_back(dataPacket);
214 aIdToADPVit->second.push_back(dataPacket);
209 }
215 }
210 else {
216 else {
211 // First request result for the variable, it must be stored
217 // First request result for the variable, it must be stored
212 impl->m_AcqIdentifierToAcqDataPacketVectorMap.insert(
218 impl->m_AcqIdentifierToAcqDataPacketVectorMap.insert(
213 std::make_pair(acqIdentifier, QVector<AcquisitionDataPacket>() << dataPacket));
219 std::make_pair(acqIdentifier, QVector<AcquisitionDataPacket>() << dataPacket));
214 }
220 }
215
221
216
222
217 // Decrement the counter of the request
223 // Decrement the counter of the request
218 auto &acqRequest = aIdToARit->second;
224 auto &acqRequest = aIdToARit->second;
219 acqRequest.m_Progression = acqRequest.m_Progression + 1;
225 acqRequest.m_Progression = acqRequest.m_Progression + 1;
220
226
221 // 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
222 // removed the finished request
228 // removed the finished request
223 if (acqRequest.m_Size == acqRequest.m_Progression) {
229 if (acqRequest.m_Size == acqRequest.m_Progression) {
230 auto varId = acqRequest.m_vIdentifier;
231 auto rangeRequested = acqRequest.m_RangeRequested;
232 auto cacheRangeRequested = acqRequest.m_CacheRangeRequested;
224 // Return the data
233 // Return the data
225 aIdToADPVit = impl->m_AcqIdentifierToAcqDataPacketVectorMap.find(acqIdentifier);
234 aIdToADPVit = impl->m_AcqIdentifierToAcqDataPacketVectorMap.find(acqIdentifier);
226 if (aIdToADPVit != impl->m_AcqIdentifierToAcqDataPacketVectorMap.cend()) {
235 if (aIdToADPVit != impl->m_AcqIdentifierToAcqDataPacketVectorMap.cend()) {
227 emit dataProvided(acqRequest.m_vIdentifier, acqRequest.m_RangeRequested,
236 emit dataProvided(varId, rangeRequested, cacheRangeRequested, aIdToADPVit->second);
228 acqRequest.m_CacheRangeRequested, aIdToADPVit->second);
229 }
237 }
238 impl->unlock();
230
239
231 // Update to the next request
240 // Update to the next request
232 impl->updateToNextRequest(acqRequest.m_vIdentifier);
241 impl->updateToNextRequest(acqRequest.m_vIdentifier);
233 }
242 }
243 else {
244 impl->unlock();
245 }
234 }
246 }
235 else {
247 else {
248 impl->unlock();
236 qCWarning(LOG_VariableAcquisitionWorker())
249 qCWarning(LOG_VariableAcquisitionWorker())
237 << tr("Impossible to retrieve AcquisitionRequest for the incoming data.");
250 << tr("Impossible to retrieve AcquisitionRequest for the incoming data.");
238 }
251 }
239 impl->unlock();
240 }
252 }
241
253
242 void VariableAcquisitionWorker::onExecuteRequest(QUuid acqIdentifier)
254 void VariableAcquisitionWorker::onExecuteRequest(QUuid acqIdentifier)
243 {
255 {
244 qCDebug(LOG_VariableAcquisitionWorker()) << tr("onExecuteRequest") << QThread::currentThread();
256 qCDebug(LOG_VariableAcquisitionWorker()) << tr("onExecuteRequest") << QThread::currentThread();
245 impl->lockRead();
257 impl->lockRead();
246 auto it = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier);
258 auto it = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier);
247 if (it != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
259 if (it != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
248 auto request = it->second;
260 auto request = it->second;
249 impl->unlock();
261 impl->unlock();
250 emit variableRequestInProgress(request.m_vIdentifier, 0.1);
262 emit variableRequestInProgress(request.m_vIdentifier, 0.1);
251 request.m_Provider->requestDataLoading(acqIdentifier, request.m_DataProviderParameters);
263 request.m_Provider->requestDataLoading(acqIdentifier, request.m_DataProviderParameters);
252 }
264 }
253 else {
265 else {
254 impl->unlock();
266 impl->unlock();
255 // TODO log no acqIdentifier recognized
267 // TODO log no acqIdentifier recognized
256 }
268 }
257 }
269 }
258
270
259 void VariableAcquisitionWorker::initialize()
271 void VariableAcquisitionWorker::initialize()
260 {
272 {
261 qCDebug(LOG_VariableAcquisitionWorker()) << tr("VariableAcquisitionWorker init")
273 qCDebug(LOG_VariableAcquisitionWorker()) << tr("VariableAcquisitionWorker init")
262 << QThread::currentThread();
274 << QThread::currentThread();
263 impl->m_WorkingMutex.lock();
275 impl->m_WorkingMutex.lock();
264 qCDebug(LOG_VariableAcquisitionWorker()) << tr("VariableAcquisitionWorker init END");
276 qCDebug(LOG_VariableAcquisitionWorker()) << tr("VariableAcquisitionWorker init END");
265 }
277 }
266
278
267 void VariableAcquisitionWorker::finalize()
279 void VariableAcquisitionWorker::finalize()
268 {
280 {
269 impl->m_WorkingMutex.unlock();
281 impl->m_WorkingMutex.unlock();
270 }
282 }
271
283
272 void VariableAcquisitionWorker::waitForFinish()
284 void VariableAcquisitionWorker::waitForFinish()
273 {
285 {
274 QMutexLocker locker{&impl->m_WorkingMutex};
286 QMutexLocker locker{&impl->m_WorkingMutex};
275 }
287 }
276
288
277 void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::removeVariableRequest(
289 void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::removeVariableRequest(
278 QUuid vIdentifier)
290 QUuid vIdentifier)
279 {
291 {
280 lockWrite();
292 lockWrite();
281 auto it = m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
293 auto it = m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
282
294
283 if (it != m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
295 if (it != m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
284 // A current request already exists, we can replace the next one
296 // A current request already exists, we can replace the next one
285
297
286 m_AcqIdentifierToAcqRequestMap.erase(it->second.first);
298 m_AcqIdentifierToAcqRequestMap.erase(it->second.first);
287 m_AcqIdentifierToAcqDataPacketVectorMap.erase(it->second.first);
299 m_AcqIdentifierToAcqDataPacketVectorMap.erase(it->second.first);
288
300
289 m_AcqIdentifierToAcqRequestMap.erase(it->second.second);
301 m_AcqIdentifierToAcqRequestMap.erase(it->second.second);
290 m_AcqIdentifierToAcqDataPacketVectorMap.erase(it->second.second);
302 m_AcqIdentifierToAcqDataPacketVectorMap.erase(it->second.second);
291 }
303 }
292 m_VIdentifierToCurrrentAcqIdNextIdPairMap.erase(vIdentifier);
304 m_VIdentifierToCurrrentAcqIdNextIdPairMap.erase(vIdentifier);
293 unlock();
305 unlock();
294 }
306 }
295
307
296 void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::updateToNextRequest(
308 void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::updateToNextRequest(
297 QUuid vIdentifier)
309 QUuid vIdentifier)
298 {
310 {
311 lockRead();
299 auto it = m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
312 auto it = m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
300 if (it != m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
313 if (it != m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
301 if (it->second.second.isNull()) {
314 if (it->second.second.isNull()) {
315 unlock();
302 // There is no next request, we can remove the variable request
316 // There is no next request, we can remove the variable request
303 removeVariableRequest(vIdentifier);
317 removeVariableRequest(vIdentifier);
304 }
318 }
305 else {
319 else {
306 auto acqIdentifierToRemove = it->second.first;
320 auto acqIdentifierToRemove = it->second.first;
307 // Move the next request to the current request
321 // Move the next request to the current request
308 it->second.first = it->second.second;
322 auto nextRequestId = it->second.second;
323 it->second.first = nextRequestId;
309 it->second.second = QUuid();
324 it->second.second = QUuid();
325 unlock();
310 // Remove AcquisitionRequest and results;
326 // Remove AcquisitionRequest and results;
327 lockWrite();
311 m_AcqIdentifierToAcqRequestMap.erase(acqIdentifierToRemove);
328 m_AcqIdentifierToAcqRequestMap.erase(acqIdentifierToRemove);
312 m_AcqIdentifierToAcqDataPacketVectorMap.erase(acqIdentifierToRemove);
329 m_AcqIdentifierToAcqDataPacketVectorMap.erase(acqIdentifierToRemove);
330 unlock();
313 // Execute the current request
331 // Execute the current request
314 QMetaObject::invokeMethod(q, "onExecuteRequest", Qt::QueuedConnection,
332 QMetaObject::invokeMethod(q, "onExecuteRequest", Qt::QueuedConnection,
315 Q_ARG(QUuid, it->second.first));
333 Q_ARG(QUuid, nextRequestId));
316 }
334 }
317 }
335 }
318 else {
336 else {
337 unlock();
319 qCCritical(LOG_VariableAcquisitionWorker())
338 qCCritical(LOG_VariableAcquisitionWorker())
320 << tr("Impossible to execute the acquisition on an unfound variable ");
339 << tr("Impossible to execute the acquisition on an unfound variable ");
321 }
340 }
322 }
341 }
342
343 void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::cancelVarRequest(
344 QUuid varRequestId)
345 {
346 qCDebug(LOG_VariableAcquisitionWorker())
347 << "VariableAcquisitionWorkerPrivate::cancelVarRequest 0";
348 lockRead();
349 // get all AcqIdentifier in link with varRequestId
350 QVector<QUuid> acqIdsToRm;
351 auto cend = m_AcqIdentifierToAcqRequestMap.cend();
352 for (auto it = m_AcqIdentifierToAcqRequestMap.cbegin(); it != cend; ++it) {
353 if (it->second.m_VarRequestId == varRequestId) {
354 acqIdsToRm << it->first;
355 }
356 }
357 unlock();
358 // run aborting or removing of acqIdsToRm
359
360 for (auto acqId : acqIdsToRm) {
361 removeAcqRequest(acqId);
362 }
363 qCDebug(LOG_VariableAcquisitionWorker())
364 << "VariableAcquisitionWorkerPrivate::cancelVarRequest end";
365 }
366
367 void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::removeAcqRequest(
368 QUuid acqRequestId)
369 {
370 qCDebug(LOG_VariableAcquisitionWorker())
371 << "VariableAcquisitionWorkerPrivate::removeAcqRequest";
372 QUuid vIdentifier;
373 std::shared_ptr<IDataProvider> provider;
374 lockRead();
375 auto acqIt = m_AcqIdentifierToAcqRequestMap.find(acqRequestId);
376 if (acqIt != m_AcqIdentifierToAcqRequestMap.cend()) {
377 vIdentifier = acqIt->second.m_vIdentifier;
378 provider = acqIt->second.m_Provider;
379
380 auto it = m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
381 if (it != m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
382 if (it->second.first == acqRequestId) {
383 // acqRequest is currently running -> let's aborting it
384 unlock();
385
386 // Remove the current request from the worker
387 updateToNextRequest(vIdentifier);
388
389 // notify the request aborting to the provider
390 provider->requestDataAborting(acqRequestId);
391 }
392 else if (it->second.second == acqRequestId) {
393 it->second.second = QUuid();
394 unlock();
395 }
396 else {
397 unlock();
398 }
399 }
400 else {
401 unlock();
402 }
403 }
404 else {
405 unlock();
406 }
407
408 lockWrite();
409
410 m_AcqIdentifierToAcqDataPacketVectorMap.erase(acqRequestId);
411 m_AcqIdentifierToAcqRequestMap.erase(acqRequestId);
412
413 unlock();
414 qCDebug(LOG_VariableAcquisitionWorker())
415 << "VariableAcquisitionWorkerPrivate::removeAcqRequest END";
416 }
@@ -1,897 +1,889
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 struct VariableController::VariableControllerPrivate {
80 struct VariableController::VariableControllerPrivate {
81 explicit VariableControllerPrivate(VariableController *parent)
81 explicit VariableControllerPrivate(VariableController *parent)
82 : m_WorkingMutex{},
82 : m_WorkingMutex{},
83 m_VariableModel{new VariableModel{parent}},
83 m_VariableModel{new VariableModel{parent}},
84 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
84 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
85 // m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
85 // m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
86 m_VariableCacheStrategy{VariableCacheStrategyFactory::createCacheStrategy(
86 m_VariableCacheStrategy{VariableCacheStrategyFactory::createCacheStrategy(
87 CacheStrategy::SingleThreshold)},
87 CacheStrategy::SingleThreshold)},
88 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
88 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
89 q{parent}
89 q{parent}
90 {
90 {
91
91
92 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
92 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
93 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
93 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
94 }
94 }
95
95
96
96
97 virtual ~VariableControllerPrivate()
97 virtual ~VariableControllerPrivate()
98 {
98 {
99 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
99 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
100 m_VariableAcquisitionWorkerThread.quit();
100 m_VariableAcquisitionWorkerThread.quit();
101 m_VariableAcquisitionWorkerThread.wait();
101 m_VariableAcquisitionWorkerThread.wait();
102 }
102 }
103
103
104
104
105 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested,
105 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested,
106 QUuid varRequestId);
106 QUuid varRequestId);
107
107
108 QVector<SqpRange> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
109 const SqpRange &dateTime);
110
111 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
108 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
112 std::shared_ptr<IDataSeries>
109 std::shared_ptr<IDataSeries>
113 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
110 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
114
111
115 void registerProvider(std::shared_ptr<IDataProvider> provider);
112 void registerProvider(std::shared_ptr<IDataProvider> provider);
116
113
117 void storeVariableRequest(QUuid varId, QUuid varRequestId, const VariableRequest &varRequest);
114 void storeVariableRequest(QUuid varId, QUuid varRequestId, const VariableRequest &varRequest);
118 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries);
115 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries);
119 void updateVariableRequest(QUuid varRequestId);
116 void updateVariableRequest(QUuid varRequestId);
120 void cancelVariableRequest(QUuid varRequestId);
117 void cancelVariableRequest(QUuid varRequestId);
121
118
122 SqpRange getLastRequestedRange(QUuid varId);
119 SqpRange getLastRequestedRange(QUuid varId);
123
120
124 QMutex m_WorkingMutex;
121 QMutex m_WorkingMutex;
125 /// Variable model. The VariableController has the ownership
122 /// Variable model. The VariableController has the ownership
126 VariableModel *m_VariableModel;
123 VariableModel *m_VariableModel;
127 QItemSelectionModel *m_VariableSelectionModel;
124 QItemSelectionModel *m_VariableSelectionModel;
128
125
129
126
130 TimeController *m_TimeController{nullptr};
127 TimeController *m_TimeController{nullptr};
131 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
128 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
132 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
129 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
133 QThread m_VariableAcquisitionWorkerThread;
130 QThread m_VariableAcquisitionWorkerThread;
134
131
135 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
132 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
136 m_VariableToProviderMap;
133 m_VariableToProviderMap;
137 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
134 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
138 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
135 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
139 m_GroupIdToVariableSynchronizationGroupMap;
136 m_GroupIdToVariableSynchronizationGroupMap;
140 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
137 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
141 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
138 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
142
139
143 std::map<QUuid, std::map<QUuid, VariableRequest> > m_VarRequestIdToVarIdVarRequestMap;
140 std::map<QUuid, std::map<QUuid, VariableRequest> > m_VarRequestIdToVarIdVarRequestMap;
144
141
145 std::map<QUuid, std::deque<QUuid> > m_VarIdToVarRequestIdQueueMap;
142 std::map<QUuid, std::deque<QUuid> > m_VarIdToVarRequestIdQueueMap;
146
143
147
144
148 VariableController *q;
145 VariableController *q;
149 };
146 };
150
147
151
148
152 VariableController::VariableController(QObject *parent)
149 VariableController::VariableController(QObject *parent)
153 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
150 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
154 {
151 {
155 qCDebug(LOG_VariableController()) << tr("VariableController construction")
152 qCDebug(LOG_VariableController()) << tr("VariableController construction")
156 << QThread::currentThread();
153 << QThread::currentThread();
157
154
158 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
155 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
159 &VariableController::onAbortProgressRequested);
156 &VariableController::onAbortProgressRequested);
160
157
161 connect(impl->m_VariableAcquisitionWorker.get(),
158 connect(impl->m_VariableAcquisitionWorker.get(),
162 &VariableAcquisitionWorker::variableCanceledRequested, this,
159 &VariableAcquisitionWorker::variableCanceledRequested, this,
163 &VariableController::onAbortAcquisitionRequested);
160 &VariableController::onAbortAcquisitionRequested);
164
161
165 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
162 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
166 &VariableController::onDataProvided);
163 &VariableController::onDataProvided);
167 connect(impl->m_VariableAcquisitionWorker.get(),
164 connect(impl->m_VariableAcquisitionWorker.get(),
168 &VariableAcquisitionWorker::variableRequestInProgress, this,
165 &VariableAcquisitionWorker::variableRequestInProgress, this,
169 &VariableController::onVariableRetrieveDataInProgress);
166 &VariableController::onVariableRetrieveDataInProgress);
170
167
171
168
172 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
169 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
173 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
170 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
174 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
171 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
175 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
172 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
176
173
177
174
178 impl->m_VariableAcquisitionWorkerThread.start();
175 impl->m_VariableAcquisitionWorkerThread.start();
179 }
176 }
180
177
181 VariableController::~VariableController()
178 VariableController::~VariableController()
182 {
179 {
183 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
180 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
184 << QThread::currentThread();
181 << QThread::currentThread();
185 this->waitForFinish();
182 this->waitForFinish();
186 }
183 }
187
184
188 VariableModel *VariableController::variableModel() noexcept
185 VariableModel *VariableController::variableModel() noexcept
189 {
186 {
190 return impl->m_VariableModel;
187 return impl->m_VariableModel;
191 }
188 }
192
189
193 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
190 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
194 {
191 {
195 return impl->m_VariableSelectionModel;
192 return impl->m_VariableSelectionModel;
196 }
193 }
197
194
198 void VariableController::setTimeController(TimeController *timeController) noexcept
195 void VariableController::setTimeController(TimeController *timeController) noexcept
199 {
196 {
200 impl->m_TimeController = timeController;
197 impl->m_TimeController = timeController;
201 }
198 }
202
199
203 std::shared_ptr<Variable>
200 std::shared_ptr<Variable>
204 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
201 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
205 {
202 {
206 if (impl->m_VariableModel->containsVariable(variable)) {
203 if (impl->m_VariableModel->containsVariable(variable)) {
207 // Clones variable
204 // Clones variable
208 auto duplicate = variable->clone();
205 auto duplicate = variable->clone();
209
206
210 // Adds clone to model
207 // Adds clone to model
211 impl->m_VariableModel->addVariable(duplicate);
208 impl->m_VariableModel->addVariable(duplicate);
212
209
213 // Generates clone identifier
210 // Generates clone identifier
214 impl->m_VariableToIdentifierMap[duplicate] = QUuid::createUuid();
211 impl->m_VariableToIdentifierMap[duplicate] = QUuid::createUuid();
215
212
216 // Registers provider
213 // Registers provider
217 auto variableProvider = impl->m_VariableToProviderMap.at(variable);
214 auto variableProvider = impl->m_VariableToProviderMap.at(variable);
218 auto duplicateProvider = variableProvider != nullptr ? variableProvider->clone() : nullptr;
215 auto duplicateProvider = variableProvider != nullptr ? variableProvider->clone() : nullptr;
219
216
220 impl->m_VariableToProviderMap[duplicate] = duplicateProvider;
217 impl->m_VariableToProviderMap[duplicate] = duplicateProvider;
221 if (duplicateProvider) {
218 if (duplicateProvider) {
222 impl->registerProvider(duplicateProvider);
219 impl->registerProvider(duplicateProvider);
223 }
220 }
224
221
225 return duplicate;
222 return duplicate;
226 }
223 }
227 else {
224 else {
228 qCCritical(LOG_VariableController())
225 qCCritical(LOG_VariableController())
229 << tr("Can't create duplicate of variable %1: variable not registered in the model")
226 << tr("Can't create duplicate of variable %1: variable not registered in the model")
230 .arg(variable->name());
227 .arg(variable->name());
231 return nullptr;
228 return nullptr;
232 }
229 }
233 }
230 }
234
231
235 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
232 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
236 {
233 {
237 if (!variable) {
234 if (!variable) {
238 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
235 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
239 return;
236 return;
240 }
237 }
241
238
242 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
239 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
243 // make some treatments before the deletion
240 // make some treatments before the deletion
244 emit variableAboutToBeDeleted(variable);
241 emit variableAboutToBeDeleted(variable);
245
242
246 // Deletes identifier
243 // Deletes identifier
247 impl->m_VariableToIdentifierMap.erase(variable);
244 impl->m_VariableToIdentifierMap.erase(variable);
248
245
249 // Deletes provider
246 // Deletes provider
250 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
247 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
251 qCDebug(LOG_VariableController())
248 qCDebug(LOG_VariableController())
252 << tr("Number of providers deleted for variable %1: %2")
249 << tr("Number of providers deleted for variable %1: %2")
253 .arg(variable->name(), QString::number(nbProvidersDeleted));
250 .arg(variable->name(), QString::number(nbProvidersDeleted));
254
251
255
252
256 // Deletes from model
253 // Deletes from model
257 impl->m_VariableModel->deleteVariable(variable);
254 impl->m_VariableModel->deleteVariable(variable);
258 }
255 }
259
256
260 void VariableController::deleteVariables(
257 void VariableController::deleteVariables(
261 const QVector<std::shared_ptr<Variable> > &variables) noexcept
258 const QVector<std::shared_ptr<Variable> > &variables) noexcept
262 {
259 {
263 for (auto variable : qAsConst(variables)) {
260 for (auto variable : qAsConst(variables)) {
264 deleteVariable(variable);
261 deleteVariable(variable);
265 }
262 }
266 }
263 }
267
264
268 std::shared_ptr<Variable>
265 std::shared_ptr<Variable>
269 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
266 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
270 std::shared_ptr<IDataProvider> provider) noexcept
267 std::shared_ptr<IDataProvider> provider) noexcept
271 {
268 {
272 if (!impl->m_TimeController) {
269 if (!impl->m_TimeController) {
273 qCCritical(LOG_VariableController())
270 qCCritical(LOG_VariableController())
274 << tr("Impossible to create variable: The time controller is null");
271 << tr("Impossible to create variable: The time controller is null");
275 return nullptr;
272 return nullptr;
276 }
273 }
277
274
278 auto range = impl->m_TimeController->dateTime();
275 auto range = impl->m_TimeController->dateTime();
279
276
280 if (auto newVariable = impl->m_VariableModel->createVariable(name, metadata)) {
277 if (auto newVariable = impl->m_VariableModel->createVariable(name, metadata)) {
281 auto identifier = QUuid::createUuid();
278 auto identifier = QUuid::createUuid();
282
279
283 // store the provider
280 // store the provider
284 impl->registerProvider(provider);
281 impl->registerProvider(provider);
285
282
286 // Associate the provider
283 // Associate the provider
287 impl->m_VariableToProviderMap[newVariable] = provider;
284 impl->m_VariableToProviderMap[newVariable] = provider;
288 qCInfo(LOG_VariableController()) << "createVariable: " << identifier;
285 qCInfo(LOG_VariableController()) << "createVariable: " << identifier;
289 impl->m_VariableToIdentifierMap[newVariable] = identifier;
286 impl->m_VariableToIdentifierMap[newVariable] = identifier;
290
287
291
288
292 auto varRequestId = QUuid::createUuid();
289 auto varRequestId = QUuid::createUuid();
293 impl->processRequest(newVariable, range, varRequestId);
290 impl->processRequest(newVariable, range, varRequestId);
294 impl->updateVariableRequest(varRequestId);
291 impl->updateVariableRequest(varRequestId);
295
292
296 return newVariable;
293 return newVariable;
297 }
294 }
298 }
295 }
299
296
300 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
297 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
301 {
298 {
302 // NOTE: Even if acquisition request is aborting, the graphe range will be changed
299 // NOTE: Even if acquisition request is aborting, the graphe range will be changed
303 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
300 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
304 << QThread::currentThread()->objectName();
301 << QThread::currentThread()->objectName();
305 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
302 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
306 auto variables = QVector<std::shared_ptr<Variable> >{};
303 auto variables = QVector<std::shared_ptr<Variable> >{};
307
304
308 for (const auto &selectedRow : qAsConst(selectedRows)) {
305 for (const auto &selectedRow : qAsConst(selectedRows)) {
309 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
306 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
310 variables << selectedVariable;
307 variables << selectedVariable;
311
308
312 // notify that rescale operation has to be done
309 // notify that rescale operation has to be done
313 emit rangeChanged(selectedVariable, dateTime);
310 emit rangeChanged(selectedVariable, dateTime);
314 }
311 }
315 }
312 }
316
313
317 if (!variables.isEmpty()) {
314 if (!variables.isEmpty()) {
318 this->onRequestDataLoading(variables, dateTime, true);
315 this->onRequestDataLoading(variables, dateTime, true);
319 }
316 }
320 }
317 }
321
318
322 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
319 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
323 const SqpRange &cacheRangeRequested,
320 const SqpRange &cacheRangeRequested,
324 QVector<AcquisitionDataPacket> dataAcquired)
321 QVector<AcquisitionDataPacket> dataAcquired)
325 {
322 {
326 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
323 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
327 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
324 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
328 if (!varRequestId.isNull()) {
325 if (!varRequestId.isNull()) {
329 impl->updateVariableRequest(varRequestId);
326 impl->updateVariableRequest(varRequestId);
330 }
327 }
331 }
328 }
332
329
333 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
330 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
334 {
331 {
335 qCDebug(LOG_VariableController())
332 qCDebug(LOG_VariableController())
336 << "TORM: variableController::onVariableRetrieveDataInProgress"
333 << "TORM: variableController::onVariableRetrieveDataInProgress"
337 << QThread::currentThread()->objectName() << progress;
334 << QThread::currentThread()->objectName() << progress;
338 if (auto var = impl->findVariable(identifier)) {
335 if (auto var = impl->findVariable(identifier)) {
339 impl->m_VariableModel->setDataProgress(var, progress);
336 impl->m_VariableModel->setDataProgress(var, progress);
340 }
337 }
341 else {
338 else {
342 qCCritical(LOG_VariableController())
339 qCCritical(LOG_VariableController())
343 << tr("Impossible to notify progression of a null variable");
340 << tr("Impossible to notify progression of a null variable");
344 }
341 }
345 }
342 }
346
343
347 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
344 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
348 {
345 {
349 auto it = impl->m_VariableToIdentifierMap.find(variable);
346 auto it = impl->m_VariableToIdentifierMap.find(variable);
350 if (it != impl->m_VariableToIdentifierMap.cend()) {
347 if (it != impl->m_VariableToIdentifierMap.cend()) {
351 impl->m_VariableAcquisitionWorker->abortProgressRequested(it->second);
348 impl->m_VariableAcquisitionWorker->abortProgressRequested(it->second);
352
349
353 QUuid varRequestId;
350 QUuid varRequestId;
354 auto varIdToVarRequestIdQueueMapIt = impl->m_VarIdToVarRequestIdQueueMap.find(it->second);
351 auto varIdToVarRequestIdQueueMapIt = impl->m_VarIdToVarRequestIdQueueMap.find(it->second);
355 if (varIdToVarRequestIdQueueMapIt != impl->m_VarIdToVarRequestIdQueueMap.cend()) {
352 if (varIdToVarRequestIdQueueMapIt != impl->m_VarIdToVarRequestIdQueueMap.cend()) {
356 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
353 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
357 varRequestId = varRequestIdQueue.front();
354 varRequestId = varRequestIdQueue.front();
358 impl->cancelVariableRequest(varRequestId);
355 impl->cancelVariableRequest(varRequestId);
359
356
360 // Finish the progression for the request
357 // Finish the progression for the request
361 impl->m_VariableModel->setDataProgress(variable, 0.0);
358 impl->m_VariableModel->setDataProgress(variable, 0.0);
362 }
359 }
363 else {
360 else {
364 qCWarning(LOG_VariableController())
361 qCWarning(LOG_VariableController())
365 << tr("Aborting progression of inexistant variable request detected !!!")
362 << tr("Aborting progression of inexistant variable request detected !!!")
366 << QThread::currentThread()->objectName();
363 << QThread::currentThread()->objectName();
367 }
364 }
368 }
365 }
369 else {
366 else {
370 qCWarning(LOG_VariableController())
367 qCWarning(LOG_VariableController())
371 << tr("Aborting progression of inexistant variable detected !!!")
368 << tr("Aborting progression of inexistant variable detected !!!")
372 << QThread::currentThread()->objectName();
369 << QThread::currentThread()->objectName();
373 }
370 }
374 }
371 }
375
372
376 void VariableController::onAbortAcquisitionRequested(QUuid vIdentifier)
373 void VariableController::onAbortAcquisitionRequested(QUuid vIdentifier)
377 {
374 {
378 qCDebug(LOG_VariableController()) << "TORM: variableController::onAbortAcquisitionRequested"
375 qCDebug(LOG_VariableController()) << "TORM: variableController::onAbortAcquisitionRequested"
379 << QThread::currentThread()->objectName() << vIdentifier;
376 << QThread::currentThread()->objectName() << vIdentifier;
380
377
381 if (auto var = impl->findVariable(vIdentifier)) {
378 if (auto var = impl->findVariable(vIdentifier)) {
382 this->onAbortProgressRequested(var);
379 this->onAbortProgressRequested(var);
383 }
380 }
384 else {
381 else {
385 qCCritical(LOG_VariableController())
382 qCCritical(LOG_VariableController())
386 << tr("Impossible to abort Acquisition Requestof a null variable");
383 << tr("Impossible to abort Acquisition Requestof a null variable");
387 }
384 }
388 }
385 }
389
386
390 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
387 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
391 {
388 {
392 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
389 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
393 << QThread::currentThread()->objectName()
390 << QThread::currentThread()->objectName()
394 << synchronizationGroupId;
391 << synchronizationGroupId;
395 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
392 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
396 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
393 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
397 std::make_pair(synchronizationGroupId, vSynchroGroup));
394 std::make_pair(synchronizationGroupId, vSynchroGroup));
398 }
395 }
399
396
400 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
397 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
401 {
398 {
402 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
399 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
403 }
400 }
404
401
405 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
402 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
406 QUuid synchronizationGroupId)
403 QUuid synchronizationGroupId)
407
404
408 {
405 {
409 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
406 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
410 << synchronizationGroupId;
407 << synchronizationGroupId;
411 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
408 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
412 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
409 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
413 auto groupIdToVSGIt
410 auto groupIdToVSGIt
414 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
411 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
415 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
412 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
416 impl->m_VariableIdGroupIdMap.insert(
413 impl->m_VariableIdGroupIdMap.insert(
417 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
414 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
418 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
415 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
419 }
416 }
420 else {
417 else {
421 qCCritical(LOG_VariableController())
418 qCCritical(LOG_VariableController())
422 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
419 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
423 << variable->name();
420 << variable->name();
424 }
421 }
425 }
422 }
426 else {
423 else {
427 qCCritical(LOG_VariableController())
424 qCCritical(LOG_VariableController())
428 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
425 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
429 }
426 }
430 }
427 }
431
428
432 void VariableController::desynchronize(std::shared_ptr<Variable> variable,
429 void VariableController::desynchronize(std::shared_ptr<Variable> variable,
433 QUuid synchronizationGroupId)
430 QUuid synchronizationGroupId)
434 {
431 {
435 // Gets variable id
432 // Gets variable id
436 auto variableIt = impl->m_VariableToIdentifierMap.find(variable);
433 auto variableIt = impl->m_VariableToIdentifierMap.find(variable);
437 if (variableIt == impl->m_VariableToIdentifierMap.cend()) {
434 if (variableIt == impl->m_VariableToIdentifierMap.cend()) {
438 qCCritical(LOG_VariableController())
435 qCCritical(LOG_VariableController())
439 << tr("Can't desynchronize variable %1: variable identifier not found")
436 << tr("Can't desynchronize variable %1: variable identifier not found")
440 .arg(variable->name());
437 .arg(variable->name());
441 return;
438 return;
442 }
439 }
443
440
444 // Gets synchronization group
441 // Gets synchronization group
445 auto groupIt = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
442 auto groupIt = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
446 if (groupIt == impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
443 if (groupIt == impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
447 qCCritical(LOG_VariableController())
444 qCCritical(LOG_VariableController())
448 << tr("Can't desynchronize variable %1: unknown synchronization group")
445 << tr("Can't desynchronize variable %1: unknown synchronization group")
449 .arg(variable->name());
446 .arg(variable->name());
450 return;
447 return;
451 }
448 }
452
449
453 auto variableId = variableIt->second;
450 auto variableId = variableIt->second;
454
451
455 // Removes variable from synchronization group
452 // Removes variable from synchronization group
456 auto synchronizationGroup = groupIt->second;
453 auto synchronizationGroup = groupIt->second;
457 synchronizationGroup->removeVariableId(variableId);
454 synchronizationGroup->removeVariableId(variableId);
458
455
459 // Removes link between variable and synchronization group
456 // Removes link between variable and synchronization group
460 impl->m_VariableIdGroupIdMap.erase(variableId);
457 impl->m_VariableIdGroupIdMap.erase(variableId);
461 }
458 }
462
459
463 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
460 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
464 const SqpRange &range, bool synchronise)
461 const SqpRange &range, bool synchronise)
465 {
462 {
466 // NOTE: oldRange isn't really necessary since oldRange == variable->range().
463 // NOTE: oldRange isn't really necessary since oldRange == variable->range().
467
464
468 // we want to load data of the variable for the dateTime.
465 // we want to load data of the variable for the dateTime.
469 // First we check if the cache contains some of them.
466 // First we check if the cache contains some of them.
470 // For the other, we ask the provider to give them.
467 // For the other, we ask the provider to give them.
471
468
472 auto varRequestId = QUuid::createUuid();
469 auto varRequestId = QUuid::createUuid();
473 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
470 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
474 << QThread::currentThread()->objectName() << varRequestId;
471 << QThread::currentThread()->objectName() << varRequestId;
475
472
476 for (const auto &var : variables) {
473 for (const auto &var : variables) {
477 qCDebug(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId;
474 qCDebug(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId;
478 impl->processRequest(var, range, varRequestId);
475 impl->processRequest(var, range, varRequestId);
479 }
476 }
480
477
481 if (synchronise) {
478 if (synchronise) {
482 // Get the group ids
479 // Get the group ids
483 qCDebug(LOG_VariableController())
480 qCDebug(LOG_VariableController())
484 << "TORM VariableController::onRequestDataLoading for synchro var ENABLE";
481 << "TORM VariableController::onRequestDataLoading for synchro var ENABLE";
485 auto groupIds = std::set<QUuid>{};
482 auto groupIds = std::set<QUuid>{};
486 auto groupIdToOldRangeMap = std::map<QUuid, SqpRange>{};
483 auto groupIdToOldRangeMap = std::map<QUuid, SqpRange>{};
487 for (const auto &var : variables) {
484 for (const auto &var : variables) {
488 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(var);
485 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(var);
489 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
486 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
490 auto vId = varToVarIdIt->second;
487 auto vId = varToVarIdIt->second;
491 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
488 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
492 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
489 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
493 auto gId = varIdToGroupIdIt->second;
490 auto gId = varIdToGroupIdIt->second;
494 groupIdToOldRangeMap.insert(std::make_pair(gId, var->range()));
491 groupIdToOldRangeMap.insert(std::make_pair(gId, var->range()));
495 if (groupIds.find(gId) == groupIds.cend()) {
492 if (groupIds.find(gId) == groupIds.cend()) {
496 qCDebug(LOG_VariableController()) << "Synchro detect group " << gId;
493 qCDebug(LOG_VariableController()) << "Synchro detect group " << gId;
497 groupIds.insert(gId);
494 groupIds.insert(gId);
498 }
495 }
499 }
496 }
500 }
497 }
501 }
498 }
502
499
503 // We assume here all group ids exist
500 // We assume here all group ids exist
504 for (const auto &gId : groupIds) {
501 for (const auto &gId : groupIds) {
505 auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId);
502 auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId);
506 auto vSyncIds = vSynchronizationGroup->getIds();
503 auto vSyncIds = vSynchronizationGroup->getIds();
507 qCDebug(LOG_VariableController()) << "Var in synchro group ";
504 qCDebug(LOG_VariableController()) << "Var in synchro group ";
508 for (auto vId : vSyncIds) {
505 for (auto vId : vSyncIds) {
509 auto var = impl->findVariable(vId);
506 auto var = impl->findVariable(vId);
510
507
511 // Don't process already processed var
508 // Don't process already processed var
512 if (!variables.contains(var)) {
509 if (!variables.contains(var)) {
513 if (var != nullptr) {
510 if (var != nullptr) {
514 qCDebug(LOG_VariableController()) << "processRequest synchro for"
511 qCDebug(LOG_VariableController()) << "processRequest synchro for"
515 << var->name();
512 << var->name();
516 auto vSyncRangeRequested = computeSynchroRangeRequested(
513 auto vSyncRangeRequested = computeSynchroRangeRequested(
517 var->range(), range, groupIdToOldRangeMap.at(gId));
514 var->range(), range, groupIdToOldRangeMap.at(gId));
518 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
515 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
519 impl->processRequest(var, vSyncRangeRequested, varRequestId);
516 impl->processRequest(var, vSyncRangeRequested, varRequestId);
520 }
517 }
521 else {
518 else {
522 qCCritical(LOG_VariableController())
519 qCCritical(LOG_VariableController())
523
520
524 << tr("Impossible to synchronize a null variable");
521 << tr("Impossible to synchronize a null variable");
525 }
522 }
526 }
523 }
527 }
524 }
528 }
525 }
529 }
526 }
530
527
531 impl->updateVariableRequest(varRequestId);
528 impl->updateVariableRequest(varRequestId);
532 }
529 }
533
530
534
531
535 void VariableController::initialize()
532 void VariableController::initialize()
536 {
533 {
537 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
534 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
538 impl->m_WorkingMutex.lock();
535 impl->m_WorkingMutex.lock();
539 qCDebug(LOG_VariableController()) << tr("VariableController init END");
536 qCDebug(LOG_VariableController()) << tr("VariableController init END");
540 }
537 }
541
538
542 void VariableController::finalize()
539 void VariableController::finalize()
543 {
540 {
544 impl->m_WorkingMutex.unlock();
541 impl->m_WorkingMutex.unlock();
545 }
542 }
546
543
547 void VariableController::waitForFinish()
544 void VariableController::waitForFinish()
548 {
545 {
549 QMutexLocker locker{&impl->m_WorkingMutex};
546 QMutexLocker locker{&impl->m_WorkingMutex};
550 }
547 }
551
548
552 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
549 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
553 {
550 {
554 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
551 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
555 auto zoomType = AcquisitionZoomType::Unknown;
552 auto zoomType = AcquisitionZoomType::Unknown;
556 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
553 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
557 qCCritical(LOG_VariableController()) << "zoomtype: ZoomOut";
554 qCDebug(LOG_VariableController()) << "zoomtype: ZoomOut";
558 zoomType = AcquisitionZoomType::ZoomOut;
555 zoomType = AcquisitionZoomType::ZoomOut;
559 }
556 }
560 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
557 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
561 qCCritical(LOG_VariableController()) << "zoomtype: PanRight";
558 qCDebug(LOG_VariableController()) << "zoomtype: PanRight";
562 zoomType = AcquisitionZoomType::PanRight;
559 zoomType = AcquisitionZoomType::PanRight;
563 }
560 }
564 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
561 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
565 qCCritical(LOG_VariableController()) << "zoomtype: PanLeft";
562 qCDebug(LOG_VariableController()) << "zoomtype: PanLeft";
566 zoomType = AcquisitionZoomType::PanLeft;
563 zoomType = AcquisitionZoomType::PanLeft;
567 }
564 }
568 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
565 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
569 qCCritical(LOG_VariableController()) << "zoomtype: ZoomIn";
566 qCDebug(LOG_VariableController()) << "zoomtype: ZoomIn";
570 zoomType = AcquisitionZoomType::ZoomIn;
567 zoomType = AcquisitionZoomType::ZoomIn;
571 }
568 }
572 else {
569 else {
573 qCCritical(LOG_VariableController()) << "getZoomType: Unknown type detected";
570 qCDebug(LOG_VariableController()) << "getZoomType: Unknown type detected";
574 }
571 }
575 return zoomType;
572 return zoomType;
576 }
573 }
577
574
578 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
575 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
579 const SqpRange &rangeRequested,
576 const SqpRange &rangeRequested,
580 QUuid varRequestId)
577 QUuid varRequestId)
581 {
578 {
582 auto varRequest = VariableRequest{};
579 auto varRequest = VariableRequest{};
583
580
584 auto it = m_VariableToIdentifierMap.find(var);
581 auto it = m_VariableToIdentifierMap.find(var);
585 if (it != m_VariableToIdentifierMap.cend()) {
582 if (it != m_VariableToIdentifierMap.cend()) {
586
583
587 auto varId = it->second;
584 auto varId = it->second;
588
585
589 auto oldRange = getLastRequestedRange(varId);
586 auto oldRange = getLastRequestedRange(varId);
590
587
591 // check for update oldRange to the last request range.
588 // check for update oldRange to the last request range.
592 if (oldRange == INVALID_RANGE) {
589 if (oldRange == INVALID_RANGE) {
593 oldRange = var->range();
590 oldRange = var->range();
594 }
591 }
595
592
596 auto varStrategyRangesRequested
593 auto varStrategyRangesRequested
597 = m_VariableCacheStrategy->computeRange(oldRange, rangeRequested);
594 = m_VariableCacheStrategy->computeRange(oldRange, rangeRequested);
598
595
599 auto notInCacheRangeList = QVector<SqpRange>{varStrategyRangesRequested.second};
596 auto notInCacheRangeList
600 auto inCacheRangeList = QVector<SqpRange>{};
597 = Variable::provideNotInCacheRangeList(oldRange, varStrategyRangesRequested.second);
601 if (m_VarIdToVarRequestIdQueueMap.find(varId) == m_VarIdToVarRequestIdQueueMap.cend()) {
598 auto inCacheRangeList
602 notInCacheRangeList
599 = Variable::provideInCacheRangeList(oldRange, varStrategyRangesRequested.second);
603 = var->provideNotInCacheRangeList(varStrategyRangesRequested.second);
604 inCacheRangeList = var->provideInCacheRangeList(varStrategyRangesRequested.second);
605 }
606
600
607 if (!notInCacheRangeList.empty()) {
601 if (!notInCacheRangeList.empty()) {
608 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
602 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
609 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
603 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
610
604
611 // store VarRequest
605 // store VarRequest
612 storeVariableRequest(varId, varRequestId, varRequest);
606 storeVariableRequest(varId, varRequestId, varRequest);
613
607
614 auto varProvider = m_VariableToProviderMap.at(var);
608 auto varProvider = m_VariableToProviderMap.at(var);
615 if (varProvider != nullptr) {
609 if (varProvider != nullptr) {
616 auto varRequestIdCanceled = m_VariableAcquisitionWorker->pushVariableRequest(
610 auto varRequestIdCanceled = m_VariableAcquisitionWorker->pushVariableRequest(
617 varRequestId, varId, varStrategyRangesRequested.first,
611 varRequestId, varId, varStrategyRangesRequested.first,
618 varStrategyRangesRequested.second,
612 varStrategyRangesRequested.second,
619 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
613 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
620 varProvider);
614 varProvider);
621
615
622 if (!varRequestIdCanceled.isNull()) {
616 if (!varRequestIdCanceled.isNull()) {
623 qCDebug(LOG_VariableAcquisitionWorker()) << tr("vsarRequestIdCanceled: ")
617 qCInfo(LOG_VariableAcquisitionWorker()) << tr("varRequestIdCanceled: ")
624 << varRequestIdCanceled;
618 << varRequestIdCanceled;
625 cancelVariableRequest(varRequestIdCanceled);
619 cancelVariableRequest(varRequestIdCanceled);
626 }
620 }
627 }
621 }
628 else {
622 else {
629 qCCritical(LOG_VariableController())
623 qCCritical(LOG_VariableController())
630 << "Impossible to provide data with a null provider";
624 << "Impossible to provide data with a null provider";
631 }
625 }
632
626
633 if (!inCacheRangeList.empty()) {
627 if (!inCacheRangeList.empty()) {
634 emit q->updateVarDisplaying(var, inCacheRangeList.first());
628 emit q->updateVarDisplaying(var, inCacheRangeList.first());
635 }
629 }
636 }
630 }
637 else {
631 else {
638 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
632 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
639 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
633 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
640 // store VarRequest
634 // store VarRequest
641 storeVariableRequest(varId, varRequestId, varRequest);
635 storeVariableRequest(varId, varRequestId, varRequest);
642 acceptVariableRequest(
636 acceptVariableRequest(
643 varId, var->dataSeries()->subDataSeries(varStrategyRangesRequested.second));
637 varId, var->dataSeries()->subDataSeries(varStrategyRangesRequested.second));
644 }
638 }
645 }
639 }
646 }
640 }
647
641
648 std::shared_ptr<Variable>
642 std::shared_ptr<Variable>
649 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
643 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
650 {
644 {
651 std::shared_ptr<Variable> var;
645 std::shared_ptr<Variable> var;
652 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
646 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
653
647
654 auto end = m_VariableToIdentifierMap.cend();
648 auto end = m_VariableToIdentifierMap.cend();
655 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
649 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
656 if (it != end) {
650 if (it != end) {
657 var = it->first;
651 var = it->first;
658 }
652 }
659 else {
653 else {
660 qCCritical(LOG_VariableController())
654 qCCritical(LOG_VariableController())
661 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
655 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
662 }
656 }
663
657
664 return var;
658 return var;
665 }
659 }
666
660
667 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
661 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
668 const QVector<AcquisitionDataPacket> acqDataPacketVector)
662 const QVector<AcquisitionDataPacket> acqDataPacketVector)
669 {
663 {
670 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
664 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
671 << acqDataPacketVector.size();
665 << acqDataPacketVector.size();
672 std::shared_ptr<IDataSeries> dataSeries;
666 std::shared_ptr<IDataSeries> dataSeries;
673 if (!acqDataPacketVector.isEmpty()) {
667 if (!acqDataPacketVector.isEmpty()) {
674 dataSeries = acqDataPacketVector[0].m_DateSeries;
668 dataSeries = acqDataPacketVector[0].m_DateSeries;
675 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
669 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
676 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
670 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
677 }
671 }
678 }
672 }
679 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
673 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
680 << acqDataPacketVector.size();
674 << acqDataPacketVector.size();
681 return dataSeries;
675 return dataSeries;
682 }
676 }
683
677
684 void VariableController::VariableControllerPrivate::registerProvider(
678 void VariableController::VariableControllerPrivate::registerProvider(
685 std::shared_ptr<IDataProvider> provider)
679 std::shared_ptr<IDataProvider> provider)
686 {
680 {
687 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
681 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
688 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
682 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
689 << provider->objectName();
683 << provider->objectName();
690 m_ProviderSet.insert(provider);
684 m_ProviderSet.insert(provider);
691 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
685 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
692 &VariableAcquisitionWorker::onVariableDataAcquired);
686 &VariableAcquisitionWorker::onVariableDataAcquired);
693 connect(provider.get(), &IDataProvider::dataProvidedProgress,
687 connect(provider.get(), &IDataProvider::dataProvidedProgress,
694 m_VariableAcquisitionWorker.get(),
688 m_VariableAcquisitionWorker.get(),
695 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
689 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
696 connect(provider.get(), &IDataProvider::dataProvidedFailed,
690 connect(provider.get(), &IDataProvider::dataProvidedFailed,
697 m_VariableAcquisitionWorker.get(),
691 m_VariableAcquisitionWorker.get(),
698 &VariableAcquisitionWorker::onVariableAcquisitionFailed);
692 &VariableAcquisitionWorker::onVariableAcquisitionFailed);
699 }
693 }
700 else {
694 else {
701 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
695 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
702 }
696 }
703 }
697 }
704
698
705 void VariableController::VariableControllerPrivate::storeVariableRequest(
699 void VariableController::VariableControllerPrivate::storeVariableRequest(
706 QUuid varId, QUuid varRequestId, const VariableRequest &varRequest)
700 QUuid varId, QUuid varRequestId, const VariableRequest &varRequest)
707 {
701 {
708 // First request for the variable. we can create an entry for it
702 // First request for the variable. we can create an entry for it
709 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
703 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
710 if (varIdToVarRequestIdQueueMapIt == m_VarIdToVarRequestIdQueueMap.cend()) {
704 if (varIdToVarRequestIdQueueMapIt == m_VarIdToVarRequestIdQueueMap.cend()) {
711 auto varRequestIdQueue = std::deque<QUuid>{};
705 auto varRequestIdQueue = std::deque<QUuid>{};
712 qCDebug(LOG_VariableController()) << tr("Store REQUEST in QUEUE");
706 qCDebug(LOG_VariableController()) << tr("Store REQUEST in QUEUE");
713 varRequestIdQueue.push_back(varRequestId);
707 varRequestIdQueue.push_back(varRequestId);
714 m_VarIdToVarRequestIdQueueMap.insert(std::make_pair(varId, std::move(varRequestIdQueue)));
708 m_VarIdToVarRequestIdQueueMap.insert(std::make_pair(varId, std::move(varRequestIdQueue)));
715 }
709 }
716 else {
710 else {
717 qCDebug(LOG_VariableController()) << tr("Store REQUEST in EXISTING QUEUE");
711 qCDebug(LOG_VariableController()) << tr("Store REQUEST in EXISTING QUEUE");
718 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
712 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
719 varRequestIdQueue.push_back(varRequestId);
713 varRequestIdQueue.push_back(varRequestId);
720 }
714 }
721
715
722 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
716 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
723 if (varRequestIdToVarIdVarRequestMapIt == m_VarRequestIdToVarIdVarRequestMap.cend()) {
717 if (varRequestIdToVarIdVarRequestMapIt == m_VarRequestIdToVarIdVarRequestMap.cend()) {
724 auto varIdToVarRequestMap = std::map<QUuid, VariableRequest>{};
718 auto varIdToVarRequestMap = std::map<QUuid, VariableRequest>{};
725 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
719 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
726 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in MAP");
720 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in MAP");
727 m_VarRequestIdToVarIdVarRequestMap.insert(
721 m_VarRequestIdToVarIdVarRequestMap.insert(
728 std::make_pair(varRequestId, std::move(varIdToVarRequestMap)));
722 std::make_pair(varRequestId, std::move(varIdToVarRequestMap)));
729 }
723 }
730 else {
724 else {
731 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
725 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
732 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in EXISTING MAP");
726 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in EXISTING MAP");
733 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
727 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
734 }
728 }
735 }
729 }
736
730
737 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
731 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
738 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
732 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
739 {
733 {
740 QUuid varRequestId;
734 QUuid varRequestId;
741 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
735 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
742 if (varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.cend()) {
736 if (varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.cend()) {
743 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
737 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
744 varRequestId = varRequestIdQueue.front();
738 varRequestId = varRequestIdQueue.front();
745 auto varRequestIdToVarIdVarRequestMapIt
739 auto varRequestIdToVarIdVarRequestMapIt
746 = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
740 = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
747 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
741 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
748 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
742 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
749 auto varIdToVarRequestMapIt = varIdToVarRequestMap.find(varId);
743 auto varIdToVarRequestMapIt = varIdToVarRequestMap.find(varId);
750 if (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) {
744 if (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) {
751 qCDebug(LOG_VariableController()) << tr("acceptVariableRequest");
745 qCDebug(LOG_VariableController()) << tr("acceptVariableRequest");
752 auto &varRequest = varIdToVarRequestMapIt->second;
746 auto &varRequest = varIdToVarRequestMapIt->second;
753 varRequest.m_DataSeries = dataSeries;
747 varRequest.m_DataSeries = dataSeries;
754 varRequest.m_CanUpdate = true;
748 varRequest.m_CanUpdate = true;
755 }
749 }
756 else {
750 else {
757 qCDebug(LOG_VariableController())
751 qCDebug(LOG_VariableController())
758 << tr("Impossible to acceptVariableRequest of a unknown variable id attached "
752 << tr("Impossible to acceptVariableRequest of a unknown variable id attached "
759 "to a variableRequestId")
753 "to a variableRequestId")
760 << varRequestId << varId;
754 << varRequestId << varId;
761 }
755 }
762 }
756 }
763 else {
757 else {
764 qCCritical(LOG_VariableController())
758 qCCritical(LOG_VariableController())
765 << tr("Impossible to acceptVariableRequest of a unknown variableRequestId")
759 << tr("Impossible to acceptVariableRequest of a unknown variableRequestId")
766 << varRequestId;
760 << varRequestId;
767 }
761 }
768
762
769 varRequestIdQueue.pop_front();
763 varRequestIdQueue.pop_front();
770 if (varRequestIdQueue.empty()) {
764 if (varRequestIdQueue.empty()) {
771 qCDebug(LOG_VariableController())
765 qCDebug(LOG_VariableController())
772 << tr("TORM Erase REQUEST because it has been accepted") << varId;
766 << tr("TORM Erase REQUEST because it has been accepted") << varId;
773 m_VarIdToVarRequestIdQueueMap.erase(varId);
767 m_VarIdToVarRequestIdQueueMap.erase(varId);
774 }
768 }
775 }
769 }
776 else {
770 else {
777 qCCritical(LOG_VariableController())
771 qCCritical(LOG_VariableController())
778 << tr("Impossible to acceptVariableRequest of a unknown variable id") << varId;
772 << tr("Impossible to acceptVariableRequest of a unknown variable id") << varId;
779 }
773 }
780
774
781 return varRequestId;
775 return varRequestId;
782 }
776 }
783
777
784 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
778 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
785 {
779 {
786
780
787 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
781 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
788 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
782 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
789 bool processVariableUpdate = true;
783 bool processVariableUpdate = true;
790 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
784 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
791 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
785 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
792 (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) && processVariableUpdate;
786 (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) && processVariableUpdate;
793 ++varIdToVarRequestMapIt) {
787 ++varIdToVarRequestMapIt) {
794 processVariableUpdate &= varIdToVarRequestMapIt->second.m_CanUpdate;
788 processVariableUpdate &= varIdToVarRequestMapIt->second.m_CanUpdate;
795 qCDebug(LOG_VariableController()) << tr("updateVariableRequest")
789 qCDebug(LOG_VariableController()) << tr("updateVariableRequest")
796 << processVariableUpdate;
790 << processVariableUpdate;
797 }
791 }
798
792
799 if (processVariableUpdate) {
793 if (processVariableUpdate) {
800 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
794 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
801 varIdToVarRequestMapIt != varIdToVarRequestMap.cend(); ++varIdToVarRequestMapIt) {
795 varIdToVarRequestMapIt != varIdToVarRequestMap.cend(); ++varIdToVarRequestMapIt) {
802 if (auto var = findVariable(varIdToVarRequestMapIt->first)) {
796 if (auto var = findVariable(varIdToVarRequestMapIt->first)) {
803 auto &varRequest = varIdToVarRequestMapIt->second;
797 auto &varRequest = varIdToVarRequestMapIt->second;
804 var->setRange(varRequest.m_RangeRequested);
798 var->setRange(varRequest.m_RangeRequested);
805 var->setCacheRange(varRequest.m_CacheRangeRequested);
799 var->setCacheRange(varRequest.m_CacheRangeRequested);
806 qCDebug(LOG_VariableController()) << tr("1: onDataProvided")
800 qCDebug(LOG_VariableController()) << tr("1: onDataProvided")
807 << varRequest.m_RangeRequested;
801 << varRequest.m_RangeRequested
808 qCDebug(LOG_VariableController()) << tr("2: onDataProvided")
809 << varRequest.m_CacheRangeRequested;
802 << varRequest.m_CacheRangeRequested;
803 qCDebug(LOG_VariableController()) << tr("2: onDataProvided var points before")
804 << var->nbPoints()
805 << varRequest.m_DataSeries->nbPoints();
810 var->mergeDataSeries(varRequest.m_DataSeries);
806 var->mergeDataSeries(varRequest.m_DataSeries);
811 qCDebug(LOG_VariableController()) << tr("3: onDataProvided");
807 qCDebug(LOG_VariableController()) << tr("3: onDataProvided var points after")
808 << var->nbPoints();
812
809
813 /// @todo MPL: confirm
814 // Variable update is notified only if there is no pending request for it
815 // if
816 // (m_VarIdToVarRequestIdQueueMap.count(varIdToVarRequestMapIt->first)
817 // == 0) {
818 emit var->updated();
810 emit var->updated();
819 // }
820 }
811 }
821 else {
812 else {
822 qCCritical(LOG_VariableController())
813 qCCritical(LOG_VariableController())
823 << tr("Impossible to update data to a null variable");
814 << tr("Impossible to update data to a null variable");
824 }
815 }
825 }
816 }
826
827 // cleaning varRequestId
817 // cleaning varRequestId
828 qCDebug(LOG_VariableController()) << tr("0: erase REQUEST in MAP ?")
818 qCDebug(LOG_VariableController()) << tr("0: erase REQUEST in MAP ?")
829 << m_VarRequestIdToVarIdVarRequestMap.size();
819 << m_VarRequestIdToVarIdVarRequestMap.size();
830 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
820 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
831 qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in MAP ?")
821 qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in MAP ?")
832 << m_VarRequestIdToVarIdVarRequestMap.size();
822 << m_VarRequestIdToVarIdVarRequestMap.size();
833 }
823 }
834 }
824 }
835 else {
825 else {
836 qCCritical(LOG_VariableController())
826 qCCritical(LOG_VariableController())
837 << tr("Cannot updateVariableRequest for a unknow varRequestId") << varRequestId;
827 << tr("Cannot updateVariableRequest for a unknow varRequestId") << varRequestId;
838 }
828 }
839 }
829 }
840
830
841 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
831 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
842 {
832 {
843 // cleaning varRequestId
833 // cleaning varRequestId
844 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
834 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
845
835
846 for (auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.begin();
836 for (auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.begin();
847 varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.end();) {
837 varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.end();) {
848 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
838 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
849 varRequestIdQueue.erase(
839 varRequestIdQueue.erase(
850 std::remove(varRequestIdQueue.begin(), varRequestIdQueue.end(), varRequestId),
840 std::remove(varRequestIdQueue.begin(), varRequestIdQueue.end(), varRequestId),
851 varRequestIdQueue.end());
841 varRequestIdQueue.end());
852 if (varRequestIdQueue.empty()) {
842 if (varRequestIdQueue.empty()) {
853 varIdToVarRequestIdQueueMapIt
843 varIdToVarRequestIdQueueMapIt
854 = m_VarIdToVarRequestIdQueueMap.erase(varIdToVarRequestIdQueueMapIt);
844 = m_VarIdToVarRequestIdQueueMap.erase(varIdToVarRequestIdQueueMapIt);
845
846 // Recompute if there is any next request based on the removed request.
855 }
847 }
856 else {
848 else {
857 ++varIdToVarRequestIdQueueMapIt;
849 ++varIdToVarRequestIdQueueMapIt;
858 }
850 }
859 }
851 }
860 }
852 }
861
853
862 SqpRange VariableController::VariableControllerPrivate::getLastRequestedRange(QUuid varId)
854 SqpRange VariableController::VariableControllerPrivate::getLastRequestedRange(QUuid varId)
863 {
855 {
864 auto lastRangeRequested = SqpRange{INVALID_RANGE};
856 auto lastRangeRequested = SqpRange{INVALID_RANGE};
865 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
857 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
866 if (varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.cend()) {
858 if (varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.cend()) {
867 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
859 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
868 auto varRequestId = varRequestIdQueue.back();
860 auto varRequestId = varRequestIdQueue.back();
869 auto varRequestIdToVarIdVarRequestMapIt
861 auto varRequestIdToVarIdVarRequestMapIt
870 = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
862 = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
871 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
863 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
872 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
864 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
873 auto varIdToVarRequestMapIt = varIdToVarRequestMap.find(varId);
865 auto varIdToVarRequestMapIt = varIdToVarRequestMap.find(varId);
874 if (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) {
866 if (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) {
875 auto &varRequest = varIdToVarRequestMapIt->second;
867 auto &varRequest = varIdToVarRequestMapIt->second;
876 lastRangeRequested = varRequest.m_RangeRequested;
868 lastRangeRequested = varRequest.m_RangeRequested;
877 }
869 }
878 else {
870 else {
879 qCDebug(LOG_VariableController())
871 qCDebug(LOG_VariableController())
880 << tr("Impossible to getLastRequestedRange of a unknown variable id attached "
872 << tr("Impossible to getLastRequestedRange of a unknown variable id attached "
881 "to a variableRequestId")
873 "to a variableRequestId")
882 << varRequestId << varId;
874 << varRequestId << varId;
883 }
875 }
884 }
876 }
885 else {
877 else {
886 qCCritical(LOG_VariableController())
878 qCCritical(LOG_VariableController())
887 << tr("Impossible to getLastRequestedRange of a unknown variableRequestId")
879 << tr("Impossible to getLastRequestedRange of a unknown variableRequestId")
888 << varRequestId;
880 << varRequestId;
889 }
881 }
890 }
882 }
891 else {
883 else {
892 qDebug(LOG_VariableController())
884 qDebug(LOG_VariableController())
893 << tr("Impossible to getLastRequestedRange of a unknown variable id") << varId;
885 << tr("Impossible to getLastRequestedRange of a unknown variable id") << varId;
894 }
886 }
895
887
896 return lastRangeRequested;
888 return lastRangeRequested;
897 }
889 }
@@ -1,213 +1,211
1 #include "CosinusProvider.h"
1 #include "CosinusProvider.h"
2 #include "MockDefs.h"
2 #include "MockDefs.h"
3
3
4 #include <Data/DataProviderParameters.h>
4 #include <Data/DataProviderParameters.h>
5 #include <Data/ScalarSeries.h>
5 #include <Data/ScalarSeries.h>
6 #include <Data/VectorSeries.h>
6 #include <Data/VectorSeries.h>
7
7
8 #include <cmath>
8 #include <cmath>
9
9
10 #include <QFuture>
10 #include <QFuture>
11 #include <QThread>
11 #include <QThread>
12 #include <QtConcurrent/QtConcurrent>
12 #include <QtConcurrent/QtConcurrent>
13
13
14 Q_LOGGING_CATEGORY(LOG_CosinusProvider, "CosinusProvider")
14 Q_LOGGING_CATEGORY(LOG_CosinusProvider, "CosinusProvider")
15
15
16 namespace {
16 namespace {
17
17
18 /// Abstract cosinus type
18 /// Abstract cosinus type
19 struct ICosinusType {
19 struct ICosinusType {
20 virtual ~ICosinusType() = default;
20 virtual ~ICosinusType() = default;
21 /// @return the number of components generated for the type
21 /// @return the number of components generated for the type
22 virtual int componentCount() const = 0;
22 virtual int componentCount() const = 0;
23 /// @return the data series created for the type
23 /// @return the data series created for the type
24 virtual std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData,
24 virtual std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData,
25 std::vector<double> valuesData,
25 std::vector<double> valuesData,
26 Unit xAxisUnit,
26 Unit xAxisUnit,
27 Unit valuesUnit) const = 0;
27 Unit valuesUnit) const = 0;
28 };
28 };
29
29
30 struct ScalarCosinus : public ICosinusType {
30 struct ScalarCosinus : public ICosinusType {
31 int componentCount() const override { return 1; }
31 int componentCount() const override { return 1; }
32
32
33 std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData,
33 std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData,
34 std::vector<double> valuesData, Unit xAxisUnit,
34 std::vector<double> valuesData, Unit xAxisUnit,
35 Unit valuesUnit) const override
35 Unit valuesUnit) const override
36 {
36 {
37 return std::make_shared<ScalarSeries>(std::move(xAxisData), std::move(valuesData),
37 return std::make_shared<ScalarSeries>(std::move(xAxisData), std::move(valuesData),
38 xAxisUnit, valuesUnit);
38 xAxisUnit, valuesUnit);
39 }
39 }
40 };
40 };
41 struct VectorCosinus : public ICosinusType {
41 struct VectorCosinus : public ICosinusType {
42 int componentCount() const override { return 3; }
42 int componentCount() const override { return 3; }
43
43
44 std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData,
44 std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData,
45 std::vector<double> valuesData, Unit xAxisUnit,
45 std::vector<double> valuesData, Unit xAxisUnit,
46 Unit valuesUnit) const override
46 Unit valuesUnit) const override
47 {
47 {
48 return std::make_shared<VectorSeries>(std::move(xAxisData), std::move(valuesData),
48 return std::make_shared<VectorSeries>(std::move(xAxisData), std::move(valuesData),
49 xAxisUnit, valuesUnit);
49 xAxisUnit, valuesUnit);
50 }
50 }
51 };
51 };
52
52
53 /// Converts string to cosinus type
53 /// Converts string to cosinus type
54 /// @return the cosinus type if the string could be converted, nullptr otherwise
54 /// @return the cosinus type if the string could be converted, nullptr otherwise
55 std::unique_ptr<ICosinusType> cosinusType(const QString &type) noexcept
55 std::unique_ptr<ICosinusType> cosinusType(const QString &type) noexcept
56 {
56 {
57 if (type.compare(QStringLiteral("scalar"), Qt::CaseInsensitive) == 0) {
57 if (type.compare(QStringLiteral("scalar"), Qt::CaseInsensitive) == 0) {
58 return std::make_unique<ScalarCosinus>();
58 return std::make_unique<ScalarCosinus>();
59 }
59 }
60 else if (type.compare(QStringLiteral("vector"), Qt::CaseInsensitive) == 0) {
60 else if (type.compare(QStringLiteral("vector"), Qt::CaseInsensitive) == 0) {
61 return std::make_unique<VectorCosinus>();
61 return std::make_unique<VectorCosinus>();
62 }
62 }
63 else {
63 else {
64 return nullptr;
64 return nullptr;
65 }
65 }
66 }
66 }
67
67
68 } // namespace
68 } // namespace
69
69
70 std::shared_ptr<IDataProvider> CosinusProvider::clone() const
70 std::shared_ptr<IDataProvider> CosinusProvider::clone() const
71 {
71 {
72 // No copy is made in clone
72 // No copy is made in clone
73 return std::make_shared<CosinusProvider>();
73 return std::make_shared<CosinusProvider>();
74 }
74 }
75
75
76 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(QUuid acqIdentifier,
76 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(QUuid acqIdentifier,
77 const SqpRange &dataRangeRequested,
77 const SqpRange &dataRangeRequested,
78 const QVariantHash &data)
78 const QVariantHash &data)
79 {
79 {
80 // TODO: Add Mutex
80 // TODO: Add Mutex
81 auto dataIndex = 0;
81 auto dataIndex = 0;
82
82
83 // Retrieves cosinus type
83 // Retrieves cosinus type
84 auto typeVariant = data.value(COSINUS_TYPE_KEY, COSINUS_TYPE_DEFAULT_VALUE);
84 auto typeVariant = data.value(COSINUS_TYPE_KEY, COSINUS_TYPE_DEFAULT_VALUE);
85 if (!typeVariant.canConvert<QString>()) {
85 if (!typeVariant.canConvert<QString>()) {
86 qCCritical(LOG_CosinusProvider()) << tr("Can't retrieve data: invalid type");
86 qCCritical(LOG_CosinusProvider()) << tr("Can't retrieve data: invalid type");
87 return nullptr;
87 return nullptr;
88 }
88 }
89
89
90 auto type = cosinusType(typeVariant.toString());
90 auto type = cosinusType(typeVariant.toString());
91 if (!type) {
91 if (!type) {
92 qCCritical(LOG_CosinusProvider()) << tr("Can't retrieve data: unknown type");
92 qCCritical(LOG_CosinusProvider()) << tr("Can't retrieve data: unknown type");
93 return nullptr;
93 return nullptr;
94 }
94 }
95
95
96 // Retrieves frequency
96 // Retrieves frequency
97 auto freqVariant = data.value(COSINUS_FREQUENCY_KEY, COSINUS_FREQUENCY_DEFAULT_VALUE);
97 auto freqVariant = data.value(COSINUS_FREQUENCY_KEY, COSINUS_FREQUENCY_DEFAULT_VALUE);
98 if (!freqVariant.canConvert<double>()) {
98 if (!freqVariant.canConvert<double>()) {
99 qCCritical(LOG_CosinusProvider()) << tr("Can't retrieve data: invalid frequency");
99 qCCritical(LOG_CosinusProvider()) << tr("Can't retrieve data: invalid frequency");
100 return nullptr;
100 return nullptr;
101 }
101 }
102
102
103 // Gets the timerange from the parameters
103 // Gets the timerange from the parameters
104 double freq = freqVariant.toDouble();
104 double freq = freqVariant.toDouble();
105 double start = std::ceil(dataRangeRequested.m_TStart * freq);
105 double start = std::ceil(dataRangeRequested.m_TStart * freq);
106 double end = std::floor(dataRangeRequested.m_TEnd * freq);
106 double end = std::floor(dataRangeRequested.m_TEnd * freq);
107
107
108 // We assure that timerange is valid
108 // We assure that timerange is valid
109 if (end < start) {
109 if (end < start) {
110 std::swap(start, end);
110 std::swap(start, end);
111 }
111 }
112
112
113 // Generates scalar series containing cosinus values (one value per second, end value is
113 // Generates scalar series containing cosinus values (one value per second, end value is
114 // included)
114 // included)
115 auto dataCount = end - start + 1;
115 auto dataCount = end - start + 1;
116
116
117 // Number of components (depending on the cosinus type)
117 // Number of components (depending on the cosinus type)
118 auto componentCount = type->componentCount();
118 auto componentCount = type->componentCount();
119
119
120 auto xAxisData = std::vector<double>{};
120 auto xAxisData = std::vector<double>{};
121 xAxisData.resize(dataCount);
121 xAxisData.resize(dataCount);
122
122
123 auto valuesData = std::vector<double>{};
123 auto valuesData = std::vector<double>{};
124 valuesData.resize(dataCount * componentCount);
124 valuesData.resize(dataCount * componentCount);
125
125
126 int progress = 0;
126 int progress = 0;
127 auto progressEnd = dataCount;
127 auto progressEnd = dataCount;
128 for (auto time = start; time <= end; ++time, ++dataIndex) {
128 for (auto time = start; time <= end; ++time, ++dataIndex) {
129 auto it = m_VariableToEnableProvider.find(acqIdentifier);
129 auto it = m_VariableToEnableProvider.find(acqIdentifier);
130 if (it != m_VariableToEnableProvider.end() && it.value()) {
130 if (it != m_VariableToEnableProvider.end() && it.value()) {
131 const auto timeOnFreq = time / freq;
131 const auto timeOnFreq = time / freq;
132
132
133 xAxisData[dataIndex] = timeOnFreq;
133 xAxisData[dataIndex] = timeOnFreq;
134
134
135 // Generates all components' values
135 // Generates all components' values
136 // Example: for a vector, values will be : cos(x), cos(x)/2, cos(x)/3
136 // Example: for a vector, values will be : cos(x), cos(x)/2, cos(x)/3
137 auto value = std::cos(timeOnFreq);
137 auto value = std::cos(timeOnFreq);
138 for (auto i = 0; i < componentCount; ++i) {
138 for (auto i = 0; i < componentCount; ++i) {
139 valuesData[componentCount * dataIndex + i] = value / (i + 1);
139 valuesData[componentCount * dataIndex + i] = value / (i + 1);
140 }
140 }
141
141
142 // progression
142 // progression
143 int currentProgress = (time - start) * 100.0 / progressEnd;
143 int currentProgress = (time - start) * 100.0 / progressEnd;
144 if (currentProgress != progress) {
144 if (currentProgress != progress) {
145 progress = currentProgress;
145 progress = currentProgress;
146
146
147 emit dataProvidedProgress(acqIdentifier, progress);
147 emit dataProvidedProgress(acqIdentifier, progress);
148 qCDebug(LOG_CosinusProvider()) << "TORM: CosinusProvider::retrieveData"
148 qCDebug(LOG_CosinusProvider()) << "TORM: CosinusProvider::retrieveData"
149 << QThread::currentThread()->objectName()
149 << QThread::currentThread()->objectName()
150 << progress;
150 << progress;
151 // NOTE: Try to use multithread if possible
151 // NOTE: Try to use multithread if possible
152 }
152 }
153 }
153 }
154 else {
154 else {
155 if (!it.value()) {
155 if (!it.value()) {
156 qCDebug(LOG_CosinusProvider())
156 qCDebug(LOG_CosinusProvider())
157 << "CosinusProvider::retrieveData: ARRET De l'acquisition detectΓ©"
157 << "CosinusProvider::retrieveData: ARRET De l'acquisition detectΓ©"
158 << end - time;
158 << end - time;
159 }
159 }
160 }
160 }
161 }
161 }
162 if (progress != 100) {
162 if (progress != 100) {
163 // We can close progression beacause all data has been retrieved
163 // We can close progression beacause all data has been retrieved
164 emit dataProvidedProgress(acqIdentifier, 100);
164 emit dataProvidedProgress(acqIdentifier, 100);
165 }
165 }
166 return type->createDataSeries(std::move(xAxisData), std::move(valuesData),
166 return type->createDataSeries(std::move(xAxisData), std::move(valuesData),
167 Unit{QStringLiteral("t"), true}, Unit{});
167 Unit{QStringLiteral("t"), true}, Unit{});
168 }
168 }
169
169
170 void CosinusProvider::requestDataLoading(QUuid acqIdentifier,
170 void CosinusProvider::requestDataLoading(QUuid acqIdentifier,
171 const DataProviderParameters &parameters)
171 const DataProviderParameters &parameters)
172 {
172 {
173 // TODO: Add Mutex
173 // TODO: Add Mutex
174 m_VariableToEnableProvider[acqIdentifier] = true;
174 m_VariableToEnableProvider[acqIdentifier] = true;
175 qCDebug(LOG_CosinusProvider()) << "TORM: CosinusProvider::requestDataLoading"
175 qCDebug(LOG_CosinusProvider()) << "TORM: CosinusProvider::requestDataLoading"
176 << QThread::currentThread()->objectName();
176 << QThread::currentThread()->objectName();
177 // NOTE: Try to use multithread if possible
177 // NOTE: Try to use multithread if possible
178 const auto times = parameters.m_Times;
178 const auto times = parameters.m_Times;
179
179
180 for (const auto &dateTime : qAsConst(times)) {
180 for (const auto &dateTime : qAsConst(times)) {
181 if (m_VariableToEnableProvider[acqIdentifier]) {
181 if (m_VariableToEnableProvider[acqIdentifier]) {
182 auto scalarSeries = this->retrieveData(acqIdentifier, dateTime, parameters.m_Data);
182 auto scalarSeries = this->retrieveData(acqIdentifier, dateTime, parameters.m_Data);
183 qCDebug(LOG_CosinusProvider()) << "TORM: CosinusProvider::dataProvided";
184 emit dataProvided(acqIdentifier, scalarSeries, dateTime);
183 emit dataProvided(acqIdentifier, scalarSeries, dateTime);
185 }
184 }
186 }
185 }
187 }
186 }
188
187
189 void CosinusProvider::requestDataAborting(QUuid acqIdentifier)
188 void CosinusProvider::requestDataAborting(QUuid acqIdentifier)
190 {
189 {
191 // TODO: Add Mutex
192 qCDebug(LOG_CosinusProvider()) << "CosinusProvider::requestDataAborting" << acqIdentifier
190 qCDebug(LOG_CosinusProvider()) << "CosinusProvider::requestDataAborting" << acqIdentifier
193 << QThread::currentThread()->objectName();
191 << QThread::currentThread()->objectName();
194 auto it = m_VariableToEnableProvider.find(acqIdentifier);
192 auto it = m_VariableToEnableProvider.find(acqIdentifier);
195 if (it != m_VariableToEnableProvider.end()) {
193 if (it != m_VariableToEnableProvider.end()) {
196 it.value() = false;
194 it.value() = false;
197 }
195 }
198 else {
196 else {
199 qCWarning(LOG_CosinusProvider())
197 qCDebug(LOG_CosinusProvider())
200 << tr("Aborting progression of inexistant identifier detected !!!");
198 << tr("Aborting progression of inexistant identifier detected !!!");
201 }
199 }
202 }
200 }
203
201
204 std::shared_ptr<IDataSeries> CosinusProvider::provideDataSeries(const SqpRange &dataRangeRequested,
202 std::shared_ptr<IDataSeries> CosinusProvider::provideDataSeries(const SqpRange &dataRangeRequested,
205 const QVariantHash &data)
203 const QVariantHash &data)
206 {
204 {
207 auto uid = QUuid::createUuid();
205 auto uid = QUuid::createUuid();
208 m_VariableToEnableProvider[uid] = true;
206 m_VariableToEnableProvider[uid] = true;
209 auto dataSeries = this->retrieveData(uid, dataRangeRequested, data);
207 auto dataSeries = this->retrieveData(uid, dataRangeRequested, data);
210
208
211 m_VariableToEnableProvider.remove(uid);
209 m_VariableToEnableProvider.remove(uid);
212 return dataSeries;
210 return dataSeries;
213 }
211 }
General Comments 3
Under Review
author

Auto status change to "Under Review"

Approved
author

Status change > Approved

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