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