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