##// END OF EJS Templates
Sets variable name
Alexandre Leroux -
r686:0d7fa2ed1e86
parent child
Show More
@@ -1,74 +1,75
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 QString name() const noexcept;
31 QString name() const noexcept;
32 void setName(const QString &name) noexcept;
32 SqpRange range() const noexcept;
33 SqpRange range() const noexcept;
33 void setRange(const SqpRange &range) noexcept;
34 void setRange(const SqpRange &range) noexcept;
34 SqpRange cacheRange() const noexcept;
35 SqpRange cacheRange() const noexcept;
35 void setCacheRange(const SqpRange &cacheRange) noexcept;
36 void setCacheRange(const SqpRange &cacheRange) noexcept;
36
37
37 /// Returns the real range of the variable, i.e. the min and max x-axis values of the data
38 /// Returns the real range of the variable, i.e. the min and max x-axis values of the data
38 /// series between the range of the variable. The real range is updated each time the variable
39 /// series between the range of the variable. The real range is updated each time the variable
39 /// range or the data series changed
40 /// range or the data series changed
40 /// @return the real range, invalid range if the data series is null or empty
41 /// @return the real range, invalid range if the data series is null or empty
41 /// @sa setDataSeries()
42 /// @sa setDataSeries()
42 /// @sa setRange()
43 /// @sa setRange()
43 SqpRange realRange() const noexcept;
44 SqpRange realRange() const noexcept;
44
45
45 /// @return the data of the variable, nullptr if there is no data
46 /// @return the data of the variable, nullptr if there is no data
46 std::shared_ptr<IDataSeries> dataSeries() const noexcept;
47 std::shared_ptr<IDataSeries> dataSeries() const noexcept;
47
48
48 QVariantHash metadata() const noexcept;
49 QVariantHash metadata() const noexcept;
49
50
50 bool contains(const SqpRange &range) const noexcept;
51 bool contains(const SqpRange &range) const noexcept;
51 bool intersect(const SqpRange &range) const noexcept;
52 bool intersect(const SqpRange &range) const noexcept;
52 bool isInside(const SqpRange &range) const noexcept;
53 bool isInside(const SqpRange &range) const noexcept;
53
54
54 bool cacheContains(const SqpRange &range) const noexcept;
55 bool cacheContains(const SqpRange &range) const noexcept;
55 bool cacheIntersect(const SqpRange &range) const noexcept;
56 bool cacheIntersect(const SqpRange &range) const noexcept;
56 bool cacheIsInside(const SqpRange &range) const noexcept;
57 bool cacheIsInside(const SqpRange &range) const noexcept;
57
58
58 QVector<SqpRange> provideNotInCacheRangeList(const SqpRange &range) const noexcept;
59 QVector<SqpRange> provideNotInCacheRangeList(const SqpRange &range) const noexcept;
59 QVector<SqpRange> provideInCacheRangeList(const SqpRange &range) const noexcept;
60 QVector<SqpRange> provideInCacheRangeList(const SqpRange &range) const noexcept;
60 void mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept;
61 void mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept;
61
62
62 signals:
63 signals:
63 void updated();
64 void updated();
64
65
65 private:
66 private:
66 class VariablePrivate;
67 class VariablePrivate;
67 spimpl::unique_impl_ptr<VariablePrivate> impl;
68 spimpl::unique_impl_ptr<VariablePrivate> impl;
68 };
69 };
69
70
70 // Required for using shared_ptr in signals/slots
71 // Required for using shared_ptr in signals/slots
71 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_REGISTRY, std::shared_ptr<Variable>)
72 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_REGISTRY, std::shared_ptr<Variable>)
72 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_VECTOR_REGISTRY, QVector<std::shared_ptr<Variable> >)
73 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_VECTOR_REGISTRY, QVector<std::shared_ptr<Variable> >)
73
74
74 #endif // SCIQLOP_VARIABLE_H
75 #endif // SCIQLOP_VARIABLE_H
@@ -1,270 +1,277
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 void lockRead() { m_Lock.lockForRead(); }
23 void lockRead() { m_Lock.lockForRead(); }
24 void lockWrite() { m_Lock.lockForWrite(); }
24 void lockWrite() { m_Lock.lockForWrite(); }
25 void unlock() { m_Lock.unlock(); }
25 void unlock() { m_Lock.unlock(); }
26
26
27 void purgeDataSeries()
27 void purgeDataSeries()
28 {
28 {
29 if (m_DataSeries) {
29 if (m_DataSeries) {
30 m_DataSeries->purge(m_CacheRange.m_TStart, m_CacheRange.m_TEnd);
30 m_DataSeries->purge(m_CacheRange.m_TStart, m_CacheRange.m_TEnd);
31 }
31 }
32 updateRealRange();
32 updateRealRange();
33 }
33 }
34
34
35 /// Updates real range according to current variable range and data series
35 /// Updates real range according to current variable range and data series
36 void updateRealRange()
36 void updateRealRange()
37 {
37 {
38 if (m_DataSeries) {
38 if (m_DataSeries) {
39 m_DataSeries->lockRead();
39 m_DataSeries->lockRead();
40 auto end = m_DataSeries->cend();
40 auto end = m_DataSeries->cend();
41 auto minXAxisIt = m_DataSeries->minXAxisData(m_Range.m_TStart);
41 auto minXAxisIt = m_DataSeries->minXAxisData(m_Range.m_TStart);
42 auto maxXAxisIt = m_DataSeries->maxXAxisData(m_Range.m_TEnd);
42 auto maxXAxisIt = m_DataSeries->maxXAxisData(m_Range.m_TEnd);
43
43
44 m_RealRange = (minXAxisIt != end && maxXAxisIt != end)
44 m_RealRange = (minXAxisIt != end && maxXAxisIt != end)
45 ? SqpRange{minXAxisIt->x(), maxXAxisIt->x()}
45 ? SqpRange{minXAxisIt->x(), maxXAxisIt->x()}
46 : INVALID_RANGE;
46 : INVALID_RANGE;
47 m_DataSeries->unlock();
47 m_DataSeries->unlock();
48 }
48 }
49 else {
49 else {
50 m_RealRange = INVALID_RANGE;
50 m_RealRange = INVALID_RANGE;
51 }
51 }
52 }
52 }
53
53
54 QString m_Name;
54 QString m_Name;
55
55
56 SqpRange m_Range;
56 SqpRange m_Range;
57 SqpRange m_CacheRange;
57 SqpRange m_CacheRange;
58 QVariantHash m_Metadata;
58 QVariantHash m_Metadata;
59 std::shared_ptr<IDataSeries> m_DataSeries;
59 std::shared_ptr<IDataSeries> m_DataSeries;
60 SqpRange m_RealRange;
60 SqpRange m_RealRange;
61
61
62 QReadWriteLock m_Lock;
62 QReadWriteLock m_Lock;
63 };
63 };
64
64
65 Variable::Variable(const QString &name, const SqpRange &dateTime, const QVariantHash &metadata)
65 Variable::Variable(const QString &name, const SqpRange &dateTime, const QVariantHash &metadata)
66 : impl{spimpl::make_unique_impl<VariablePrivate>(name, dateTime, metadata)}
66 : impl{spimpl::make_unique_impl<VariablePrivate>(name, dateTime, metadata)}
67 {
67 {
68 }
68 }
69
69
70 QString Variable::name() const noexcept
70 QString Variable::name() const noexcept
71 {
71 {
72 impl->lockRead();
72 impl->lockRead();
73 auto name = impl->m_Name;
73 auto name = impl->m_Name;
74 impl->unlock();
74 impl->unlock();
75 return name;
75 return name;
76 }
76 }
77
77
78 void Variable::setName(const QString &name) noexcept
79 {
80 impl->lockWrite();
81 impl->m_Name = name;
82 impl->unlock();
83 }
84
78 SqpRange Variable::range() const noexcept
85 SqpRange Variable::range() const noexcept
79 {
86 {
80 impl->lockRead();
87 impl->lockRead();
81 auto range = impl->m_Range;
88 auto range = impl->m_Range;
82 impl->unlock();
89 impl->unlock();
83 return range;
90 return range;
84 }
91 }
85
92
86 void Variable::setRange(const SqpRange &range) noexcept
93 void Variable::setRange(const SqpRange &range) noexcept
87 {
94 {
88 impl->lockWrite();
95 impl->lockWrite();
89 impl->m_Range = range;
96 impl->m_Range = range;
90 impl->updateRealRange();
97 impl->updateRealRange();
91 impl->unlock();
98 impl->unlock();
92 }
99 }
93
100
94 SqpRange Variable::cacheRange() const noexcept
101 SqpRange Variable::cacheRange() const noexcept
95 {
102 {
96 impl->lockRead();
103 impl->lockRead();
97 auto cacheRange = impl->m_CacheRange;
104 auto cacheRange = impl->m_CacheRange;
98 impl->unlock();
105 impl->unlock();
99 return cacheRange;
106 return cacheRange;
100 }
107 }
101
108
102 void Variable::setCacheRange(const SqpRange &cacheRange) noexcept
109 void Variable::setCacheRange(const SqpRange &cacheRange) noexcept
103 {
110 {
104 impl->lockWrite();
111 impl->lockWrite();
105 if (cacheRange != impl->m_CacheRange) {
112 if (cacheRange != impl->m_CacheRange) {
106 impl->m_CacheRange = cacheRange;
113 impl->m_CacheRange = cacheRange;
107 impl->purgeDataSeries();
114 impl->purgeDataSeries();
108 }
115 }
109 impl->unlock();
116 impl->unlock();
110 }
117 }
111
118
112 SqpRange Variable::realRange() const noexcept
119 SqpRange Variable::realRange() const noexcept
113 {
120 {
114 return impl->m_RealRange;
121 return impl->m_RealRange;
115 }
122 }
116
123
117 void Variable::mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
124 void Variable::mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
118 {
125 {
119 qCDebug(LOG_Variable()) << "TORM Variable::mergeDataSeries"
126 qCDebug(LOG_Variable()) << "TORM Variable::mergeDataSeries"
120 << QThread::currentThread()->objectName();
127 << QThread::currentThread()->objectName();
121 if (!dataSeries) {
128 if (!dataSeries) {
122 /// @todo ALX : log
129 /// @todo ALX : log
123 return;
130 return;
124 }
131 }
125
132
126 // Add or merge the data
133 // Add or merge the data
127 impl->lockWrite();
134 impl->lockWrite();
128 if (!impl->m_DataSeries) {
135 if (!impl->m_DataSeries) {
129 impl->m_DataSeries = dataSeries->clone();
136 impl->m_DataSeries = dataSeries->clone();
130 }
137 }
131 else {
138 else {
132 impl->m_DataSeries->merge(dataSeries.get());
139 impl->m_DataSeries->merge(dataSeries.get());
133 }
140 }
134 impl->purgeDataSeries();
141 impl->purgeDataSeries();
135 impl->unlock();
142 impl->unlock();
136 }
143 }
137
144
138 std::shared_ptr<IDataSeries> Variable::dataSeries() const noexcept
145 std::shared_ptr<IDataSeries> Variable::dataSeries() const noexcept
139 {
146 {
140 impl->lockRead();
147 impl->lockRead();
141 auto dataSeries = impl->m_DataSeries;
148 auto dataSeries = impl->m_DataSeries;
142 impl->unlock();
149 impl->unlock();
143
150
144 return dataSeries;
151 return dataSeries;
145 }
152 }
146
153
147 QVariantHash Variable::metadata() const noexcept
154 QVariantHash Variable::metadata() const noexcept
148 {
155 {
149 impl->lockRead();
156 impl->lockRead();
150 auto metadata = impl->m_Metadata;
157 auto metadata = impl->m_Metadata;
151 impl->unlock();
158 impl->unlock();
152 return metadata;
159 return metadata;
153 }
160 }
154
161
155 bool Variable::contains(const SqpRange &range) const noexcept
162 bool Variable::contains(const SqpRange &range) const noexcept
156 {
163 {
157 impl->lockRead();
164 impl->lockRead();
158 auto res = impl->m_Range.contains(range);
165 auto res = impl->m_Range.contains(range);
159 impl->unlock();
166 impl->unlock();
160 return res;
167 return res;
161 }
168 }
162
169
163 bool Variable::intersect(const SqpRange &range) const noexcept
170 bool Variable::intersect(const SqpRange &range) const noexcept
164 {
171 {
165
172
166 impl->lockRead();
173 impl->lockRead();
167 auto res = impl->m_Range.intersect(range);
174 auto res = impl->m_Range.intersect(range);
168 impl->unlock();
175 impl->unlock();
169 return res;
176 return res;
170 }
177 }
171
178
172 bool Variable::isInside(const SqpRange &range) const noexcept
179 bool Variable::isInside(const SqpRange &range) const noexcept
173 {
180 {
174 impl->lockRead();
181 impl->lockRead();
175 auto res = range.contains(SqpRange{impl->m_Range.m_TStart, impl->m_Range.m_TEnd});
182 auto res = range.contains(SqpRange{impl->m_Range.m_TStart, impl->m_Range.m_TEnd});
176 impl->unlock();
183 impl->unlock();
177 return res;
184 return res;
178 }
185 }
179
186
180 bool Variable::cacheContains(const SqpRange &range) const noexcept
187 bool Variable::cacheContains(const SqpRange &range) const noexcept
181 {
188 {
182 impl->lockRead();
189 impl->lockRead();
183 auto res = impl->m_CacheRange.contains(range);
190 auto res = impl->m_CacheRange.contains(range);
184 impl->unlock();
191 impl->unlock();
185 return res;
192 return res;
186 }
193 }
187
194
188 bool Variable::cacheIntersect(const SqpRange &range) const noexcept
195 bool Variable::cacheIntersect(const SqpRange &range) const noexcept
189 {
196 {
190 impl->lockRead();
197 impl->lockRead();
191 auto res = impl->m_CacheRange.intersect(range);
198 auto res = impl->m_CacheRange.intersect(range);
192 impl->unlock();
199 impl->unlock();
193 return res;
200 return res;
194 }
201 }
195
202
196 bool Variable::cacheIsInside(const SqpRange &range) const noexcept
203 bool Variable::cacheIsInside(const SqpRange &range) const noexcept
197 {
204 {
198 impl->lockRead();
205 impl->lockRead();
199 auto res = range.contains(SqpRange{impl->m_CacheRange.m_TStart, impl->m_CacheRange.m_TEnd});
206 auto res = range.contains(SqpRange{impl->m_CacheRange.m_TStart, impl->m_CacheRange.m_TEnd});
200 impl->unlock();
207 impl->unlock();
201 return res;
208 return res;
202 }
209 }
203
210
204
211
205 QVector<SqpRange> Variable::provideNotInCacheRangeList(const SqpRange &range) const noexcept
212 QVector<SqpRange> Variable::provideNotInCacheRangeList(const SqpRange &range) const noexcept
206 {
213 {
207 // This code assume that cach in contigue. Can return 0, 1 or 2 SqpRange
214 // This code assume that cach in contigue. Can return 0, 1 or 2 SqpRange
208
215
209 auto notInCache = QVector<SqpRange>{};
216 auto notInCache = QVector<SqpRange>{};
210
217
211 if (!this->cacheContains(range)) {
218 if (!this->cacheContains(range)) {
212 if (range.m_TEnd <= impl->m_CacheRange.m_TStart
219 if (range.m_TEnd <= impl->m_CacheRange.m_TStart
213 || range.m_TStart >= impl->m_CacheRange.m_TEnd) {
220 || range.m_TStart >= impl->m_CacheRange.m_TEnd) {
214 notInCache << range;
221 notInCache << range;
215 }
222 }
216 else if (range.m_TStart < impl->m_CacheRange.m_TStart
223 else if (range.m_TStart < impl->m_CacheRange.m_TStart
217 && range.m_TEnd <= impl->m_CacheRange.m_TEnd) {
224 && range.m_TEnd <= impl->m_CacheRange.m_TEnd) {
218 notInCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TStart};
225 notInCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TStart};
219 }
226 }
220 else if (range.m_TStart < impl->m_CacheRange.m_TStart
227 else if (range.m_TStart < impl->m_CacheRange.m_TStart
221 && range.m_TEnd > impl->m_CacheRange.m_TEnd) {
228 && range.m_TEnd > impl->m_CacheRange.m_TEnd) {
222 notInCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TStart}
229 notInCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TStart}
223 << SqpRange{impl->m_CacheRange.m_TEnd, range.m_TEnd};
230 << SqpRange{impl->m_CacheRange.m_TEnd, range.m_TEnd};
224 }
231 }
225 else if (range.m_TStart < impl->m_CacheRange.m_TEnd) {
232 else if (range.m_TStart < impl->m_CacheRange.m_TEnd) {
226 notInCache << SqpRange{impl->m_CacheRange.m_TEnd, range.m_TEnd};
233 notInCache << SqpRange{impl->m_CacheRange.m_TEnd, range.m_TEnd};
227 }
234 }
228 else {
235 else {
229 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
236 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
230 << QThread::currentThread();
237 << QThread::currentThread();
231 }
238 }
232 }
239 }
233
240
234 return notInCache;
241 return notInCache;
235 }
242 }
236
243
237 QVector<SqpRange> Variable::provideInCacheRangeList(const SqpRange &range) const noexcept
244 QVector<SqpRange> Variable::provideInCacheRangeList(const SqpRange &range) const noexcept
238 {
245 {
239 // This code assume that cach in contigue. Can return 0 or 1 SqpRange
246 // This code assume that cach in contigue. Can return 0 or 1 SqpRange
240
247
241 auto inCache = QVector<SqpRange>{};
248 auto inCache = QVector<SqpRange>{};
242
249
243
250
244 if (this->intersect(range)) {
251 if (this->intersect(range)) {
245 if (range.m_TStart <= impl->m_CacheRange.m_TStart
252 if (range.m_TStart <= impl->m_CacheRange.m_TStart
246 && range.m_TEnd >= impl->m_CacheRange.m_TStart
253 && range.m_TEnd >= impl->m_CacheRange.m_TStart
247 && range.m_TEnd < impl->m_CacheRange.m_TEnd) {
254 && range.m_TEnd < impl->m_CacheRange.m_TEnd) {
248 inCache << SqpRange{impl->m_CacheRange.m_TStart, range.m_TEnd};
255 inCache << SqpRange{impl->m_CacheRange.m_TStart, range.m_TEnd};
249 }
256 }
250
257
251 else if (range.m_TStart >= impl->m_CacheRange.m_TStart
258 else if (range.m_TStart >= impl->m_CacheRange.m_TStart
252 && range.m_TEnd <= impl->m_CacheRange.m_TEnd) {
259 && range.m_TEnd <= impl->m_CacheRange.m_TEnd) {
253 inCache << range;
260 inCache << range;
254 }
261 }
255 else if (range.m_TStart > impl->m_CacheRange.m_TStart
262 else if (range.m_TStart > impl->m_CacheRange.m_TStart
256 && range.m_TEnd > impl->m_CacheRange.m_TEnd) {
263 && range.m_TEnd > impl->m_CacheRange.m_TEnd) {
257 inCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TEnd};
264 inCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TEnd};
258 }
265 }
259 else if (range.m_TStart <= impl->m_CacheRange.m_TStart
266 else if (range.m_TStart <= impl->m_CacheRange.m_TStart
260 && range.m_TEnd >= impl->m_CacheRange.m_TEnd) {
267 && range.m_TEnd >= impl->m_CacheRange.m_TEnd) {
261 inCache << impl->m_CacheRange;
268 inCache << impl->m_CacheRange;
262 }
269 }
263 else {
270 else {
264 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
271 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
265 << QThread::currentThread();
272 << QThread::currentThread();
266 }
273 }
267 }
274 }
268
275
269 return inCache;
276 return inCache;
270 }
277 }
General Comments 0
You need to be logged in to leave comments. Login now