##// END OF EJS Templates
Added DateTimeRange unit Tests...
jeandet -
r6:d9ddd9092db4
parent child
Show More
@@ -0,0 +1,106
1 #include <QObject>
2 #include <QtTest>
3 #include <QUuid>
4 #include <limits>
5
6
7 #include <Data/DateTimeRange.h>
8 #include <Common/Numeric.h>
9
10 Q_DECLARE_METATYPE(Seconds<double>);
11
12 DateTimeRange computeZoom(QDateTime start, QDateTime stop, double zoom)
13 {
14 double start_epoch = start.toMSecsSinceEpoch();
15 double stop_epoch = stop.toMSecsSinceEpoch();
16 auto delta = stop_epoch - start_epoch;
17 auto dt_ms = (zoom-1.)*(double(delta))/2.;
18 return DateTimeRange{(start_epoch - dt_ms)/1000., (stop_epoch + dt_ms)/1000.};
19 }
20
21 class TestDateTimeRange: public QObject {
22 Q_OBJECT
23
24 private slots:
25 void testRangeDelta_data()
26 {
27 QTest::addColumn<QDateTime>("tstart");
28 QTest::addColumn<QDateTime>("tend");
29 QTest::addColumn<double>("expected");
30 auto now = QDateTime::currentDateTime();
31 auto yesterday = QDateTime::currentDateTime().addDays(-1);
32 QTest::newRow("No delta") << now << now << 0.;
33 QTest::newRow("One day delta") << yesterday << now << 60.*60.*24.;
34 QTest::newRow("Minus one day delta") << now << yesterday << -60.*60.*24.;
35 }
36
37 void testRangeDelta()
38 {
39 QFETCH(QDateTime,tstart);
40 QFETCH(QDateTime,tend);
41 QFETCH(double,expected);
42 auto range = DateTimeRange::fromDateTime(tstart, tend);
43 double delta = range.delta();
44 // Since it is built from QDateTime don't expect better resolution
45 QVERIFY((delta-expected) <= 0.002);
46 }
47
48 void testRangeShift_data()
49 {
50 QTest::addColumn<DateTimeRange>("initial");
51 QTest::addColumn<Seconds<double>>("shift");
52 QTest::addColumn<DateTimeRange>("expected");
53 auto now = QDateTime::currentDateTime();
54 auto yestd = QDateTime::currentDateTime().addDays(-1);
55 auto range = DateTimeRange::fromDateTime(yestd, now);
56 QTest::newRow("No shift") << range << Seconds<double>{0.} << range;
57
58 QTest::newRow("One milisecond left") << range << Seconds<double>{-.001} <<
59 DateTimeRange::fromDateTime(yestd.addMSecs(-1.), now.addMSecs(-1.));
60 QTest::newRow("One milisecond right") << range << Seconds<double>{.001} <<
61 DateTimeRange::fromDateTime(yestd.addMSecs(1.), now.addMSecs(1.));
62 QTest::newRow("One second left") << range << Seconds<double>{-1.} <<
63 DateTimeRange::fromDateTime(yestd.addSecs(-1.), now.addSecs(-1.));
64 QTest::newRow("One second right") << range << Seconds<double>{1.} <<
65 DateTimeRange::fromDateTime(yestd.addSecs(1.), now.addSecs(1.));
66 QTest::newRow("One year left") << range << Seconds<double>{-365.*24.*60.*60.} <<
67 DateTimeRange::fromDateTime(yestd.addYears(-1.), now.addYears(-1.));
68 QTest::newRow("One year right") << range << Seconds<double>{365.*24.*60.*60.} <<
69 DateTimeRange::fromDateTime(yestd.addYears(1.), now.addYears(1.));
70 }
71 void testRangeShift()
72 {
73 QFETCH(DateTimeRange,initial);
74 QFETCH(Seconds<double>,shift);
75 QFETCH(DateTimeRange,expected);
76 QCOMPARE(initial+shift, expected);
77 }
78
79 void testRangeZoom_data()
80 {
81 QTest::addColumn<DateTimeRange>("initial");
82 QTest::addColumn<double>("zoom");
83 QTest::addColumn<DateTimeRange>("expected");
84 auto now = QDateTime::currentDateTime();
85 auto yestd = QDateTime::currentDateTime().addDays(-1);
86 auto range = DateTimeRange::fromDateTime(yestd, now);
87 QTest::newRow("No zoom") << range << 1. << range;
88
89 QTest::newRow("Zoom IN 0.001") << range << 1.001 <<
90 computeZoom(yestd, now, 1.001);
91 QTest::newRow("Zoom OUT 0.001") << range << 0.999 <<
92 computeZoom(yestd, now, 0.999);
93 }
94 void testRangeZoom()
95 {
96 QFETCH(DateTimeRange,initial);
97 QFETCH(double,zoom);
98 QFETCH(DateTimeRange,expected);
99 QCOMPARE(initial*zoom, expected);
100 }
101
102 };
103 QTEST_MAIN(TestDateTimeRange)
104
105
106 #include "TestDateTimeRange.moc"
@@ -1,18 +1,26
1 #ifndef NUMERIC_H
2 #define NUMERIC_H
1 3 #include <cmath>
2 4 #include <limits>
3 5 #include <type_traits>
4 6 #include <algorithm>
5 7
8 namespace SciQLop::numeric {
9
6 10 /*
7 11 taken from here https://en.cppreference.com/w/cpp/types/numeric_limits/epsilon
8 12 */
9 13 template<class T>
10 14 typename std::enable_if<!std::numeric_limits<T>::is_integer, bool>::type
11 15 almost_equal(T x, T y, int ulp)
12 16 {
13 17 // the machine epsilon has to be scaled to the magnitude of the values used
14 18 // and multiplied by the desired precision in ULPs (units in the last place)
15 19 return std::abs(x-y) <= std::numeric_limits<T>::epsilon() * std::abs(x+y) * ulp
16 20 // unless the result is subnormal
17 21 || std::abs(x-y) < std::numeric_limits<T>::min();
18 22 }
23
24 }
25
26 #endif
@@ -1,159 +1,164
1 1 #ifndef SCIQLOP_SQPRANGE_H
2 2 #define SCIQLOP_SQPRANGE_H
3 3
4 #include <cmath>
4 5 #include <QObject>
5 6
6 7 #include <QDebug>
7 8
9 #include <opaque/numeric_typedef.hpp>
8 10 #include <Common/DateUtils.h>
9 11 #include <Common/MetaTypes.h>
10 #include <opaque/numeric_typedef.hpp>
11
12 #include <cmath>
12 #include <Common/Numeric.h>
13 13
14 14
15 15 template <typename T>
16 16 struct Seconds : opaque::numeric_typedef<T, Seconds<T>> ,
17 17 opaque::binop::multipliable <Seconds<T>, true , Seconds<T>, T, T>,
18 18 opaque::binop::dividable <Seconds<T>, true , Seconds<T>, T, T>,
19 19 opaque::binop::addable <Seconds<T>, true , Seconds<T>, T, T>,
20 20 opaque::binop::subtractable <Seconds<T>, true , Seconds<T>, T, T>
21 21
22 22 {
23 23 using base = opaque::numeric_typedef<T, Seconds<T>>;
24 24 using base::base;
25 operator T () const {return this->value;}
25 26 };
26 27
27 28 /**
28 29 * @brief The SqpRange struct holds the information of time parameters
29 30 */
30 31 struct DateTimeRange {
31 32 /// Creates SqpRange from dates and times
32 33 static DateTimeRange fromDateTime(const QDate &startDate, const QTime &startTime,
33 34 const QDate &endDate, const QTime &endTime)
34 35 {
35 36 return {DateUtils::secondsSinceEpoch(QDateTime{startDate, startTime, Qt::UTC}),
36 37 DateUtils::secondsSinceEpoch(QDateTime{endDate, endTime, Qt::UTC})};
37 38 }
38 39
40 static DateTimeRange fromDateTime(const QDateTime &start, const QDateTime &end)
41 {
42 return {DateUtils::secondsSinceEpoch(start),
43 DateUtils::secondsSinceEpoch(end)};
44 }
45
39 46 /// Start time (UTC)
40 47 double m_TStart;
41 48 /// End time (UTC)
42 49 double m_TEnd;
43 50
44 51 Seconds<double> delta()const {return Seconds<double>{this->m_TEnd - this->m_TStart};}
45 52
46 53 bool contains(const DateTimeRange &dateTime) const noexcept
47 54 {
48 55 return (m_TStart <= dateTime.m_TStart && m_TEnd >= dateTime.m_TEnd);
49 56 }
50 57
51 58 bool intersect(const DateTimeRange &dateTime) const noexcept
52 59 {
53 60 return (m_TEnd >= dateTime.m_TStart && m_TStart <= dateTime.m_TEnd);
54 61 }
55 62
56 63 bool operator==(const DateTimeRange &other) const
57 64 {
58 auto equals = [](const auto &v1, const auto &v2) {
59 return (std::isnan(v1) && std::isnan(v2)) || v1 == v2;
60 };
61
62 return equals(m_TStart, other.m_TStart) && equals(m_TEnd, other.m_TEnd);
65 return SciQLop::numeric::almost_equal(m_TStart, other.m_TStart, 1.) &&
66 SciQLop::numeric::almost_equal(m_TEnd, other.m_TEnd, 1.);
63 67 }
68
64 69 bool operator!=(const DateTimeRange &other) const { return !(*this == other); }
65 70
66 71 void grow(double factor)
67 72 {
68 73 double grow_v{delta()*(factor - 1.)/2.};
69 74 m_TStart -= grow_v;
70 75 m_TEnd += grow_v;
71 76 }
72 77
73 78 void shrink(double factor)
74 79 {
75 80 double shrink_v{this->delta()*(1. - factor)/2.};
76 81 m_TStart += shrink_v;
77 82 m_TEnd -= shrink_v;
78 83 }
79 84
80 85 DateTimeRange& operator*=(double k)
81 86 {
82 87 this->grow(k);
83 88 return *this;
84 89 }
85 90
86 91 DateTimeRange& operator/=(double k)
87 92 {
88 93 this->shrink(k);
89 94 return *this;
90 95 }
91 96
92 97 };
93 98
94 99 template <class T>
95 100 DateTimeRange& operator+=(DateTimeRange&r, Seconds<T> offset)
96 101 {
97 102 shift(r,offset);
98 103 return r;
99 104 }
100 105
101 106 template <class T>
102 107 DateTimeRange& operator-=(DateTimeRange&r, Seconds<T> offset)
103 108 {
104 109 shift(r,-offset);
105 110 }
106 111
107 112 template <class T>
108 113 void shift(DateTimeRange& r, Seconds<T> offset)
109 114 {
110 115 r.m_TEnd+=static_cast<double>(offset);
111 116 r.m_TStart+=static_cast<double>(offset);
112 117 }
113 118
114 119 inline DateTimeRange operator*(const DateTimeRange& r, double k)
115 120 {
116 121 DateTimeRange result{r};
117 122 result.grow(k);
118 123 return result;
119 124 }
120 125
121 126 inline DateTimeRange operator/(const DateTimeRange& r, double k)
122 127 {
123 128 DateTimeRange result{r};
124 129 result.shrink(k);
125 130 return result;
126 131 }
127 132
128 133 template<class T>
129 134 DateTimeRange operator+(const DateTimeRange& r, Seconds<T> offset)
130 135 {
131 136 DateTimeRange result{r};
132 137 shift(result,offset);
133 138 return result;
134 139 }
135 140
136 141 template<class T>
137 142 DateTimeRange operator-(const DateTimeRange& r, Seconds<T> offset)
138 143 {
139 144 DateTimeRange result{r};
140 145 shift(result,-offset);
141 146 return result;
142 147 }
143 148
144 149 const auto INVALID_RANGE
145 150 = DateTimeRange{std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN()};
146 151
147 152 inline QDebug operator<<(QDebug d, DateTimeRange obj)
148 153 {
149 154 auto tendDateTimeStart = DateUtils::dateTime(obj.m_TStart);
150 155 auto tendDateTimeEnd = DateUtils::dateTime(obj.m_TEnd);
151 156
152 157 d << "ts: " << tendDateTimeStart << " te: " << tendDateTimeEnd;
153 158 return d;
154 159 }
155 160
156 161 // Required for using shared_ptr in signals/slots
157 162 SCIQLOP_REGISTER_META_TYPE(SQPRANGE_REGISTRY, DateTimeRange)
158 163
159 164 #endif // SCIQLOP_SQPRANGE_H
@@ -1,1103 +1,1103
1 1 #include <Variable/Variable.h>
2 2 #include <Variable/VariableAcquisitionWorker.h>
3 3 #include <Variable/VariableCacheStrategy.h>
4 4 #include <Variable/VariableCacheStrategyFactory.h>
5 5 #include <Variable/VariableController.h>
6 6 #include <Variable/VariableModel.h>
7 7 #include <Variable/VariableSynchronizationGroup.h>
8 8
9 9 #include <Data/DataProviderParameters.h>
10 10 #include <Data/IDataProvider.h>
11 11 #include <Data/IDataSeries.h>
12 12 #include <Data/VariableRequest.h>
13 13 #include <Time/TimeController.h>
14 14
15 15 #include <Common/Numeric.h>
16 16
17 17 #include <QDataStream>
18 18 #include <QMutex>
19 19 #include <QThread>
20 20 #include <QUuid>
21 21 #include <QtCore/QItemSelectionModel>
22 22
23 23 #include <deque>
24 24 #include <set>
25 25 #include <unordered_map>
26 26
27 27 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
28 28
29 29 namespace {
30 30
31 31 DateTimeRange computeSynchroRangeRequested(const DateTimeRange &varRange, const DateTimeRange &graphRange,
32 32 const DateTimeRange &oldGraphRange)
33 33 {
34 34 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
35 35
36 36 auto varRangeRequested = varRange;
37 37 switch (zoomType) {
38 38 case AcquisitionZoomType::ZoomIn: {
39 39 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
40 40 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
41 41 varRangeRequested.m_TStart += deltaLeft;
42 42 varRangeRequested.m_TEnd -= deltaRight;
43 43 break;
44 44 }
45 45
46 46 case AcquisitionZoomType::ZoomOut: {
47 47 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
48 48 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
49 49 varRangeRequested.m_TStart -= deltaLeft;
50 50 varRangeRequested.m_TEnd += deltaRight;
51 51 break;
52 52 }
53 53 case AcquisitionZoomType::PanRight: {
54 54 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
55 55 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
56 56 varRangeRequested.m_TStart += deltaLeft;
57 57 varRangeRequested.m_TEnd += deltaRight;
58 58 break;
59 59 }
60 60 case AcquisitionZoomType::PanLeft: {
61 61 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
62 62 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
63 63 varRangeRequested.m_TStart -= deltaLeft;
64 64 varRangeRequested.m_TEnd -= deltaRight;
65 65 break;
66 66 }
67 67 case AcquisitionZoomType::Unknown: {
68 68 qCCritical(LOG_VariableController())
69 69 << VariableController::tr("Impossible to synchronize: zoom type unknown");
70 70 break;
71 71 }
72 72 default:
73 73 qCCritical(LOG_VariableController()) << VariableController::tr(
74 74 "Impossible to synchronize: zoom type not take into account");
75 75 // No action
76 76 break;
77 77 }
78 78
79 79 return varRangeRequested;
80 80 }
81 81 }
82 82
83 83 enum class VariableRequestHandlerState { OFF, RUNNING, PENDING };
84 84
85 85 struct VariableRequestHandler {
86 86
87 87 VariableRequestHandler()
88 88 {
89 89 m_CanUpdate = false;
90 90 m_State = VariableRequestHandlerState::OFF;
91 91 }
92 92
93 93 QUuid m_VarId;
94 94 VariableRequest m_RunningVarRequest;
95 95 VariableRequest m_PendingVarRequest;
96 96 VariableRequestHandlerState m_State;
97 97 bool m_CanUpdate;
98 98 };
99 99
100 100 struct VariableController::VariableControllerPrivate {
101 101 explicit VariableControllerPrivate(VariableController *parent)
102 102 : m_WorkingMutex{},
103 103 m_VariableModel{new VariableModel{parent}},
104 104 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
105 105 // m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
106 106 m_VariableCacheStrategy{VariableCacheStrategyFactory::createCacheStrategy(
107 107 CacheStrategy::SingleThreshold)},
108 108 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
109 109 q{parent}
110 110 {
111 111
112 112 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
113 113 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
114 114 }
115 115
116 116
117 117 virtual ~VariableControllerPrivate()
118 118 {
119 119 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
120 120 m_VariableAcquisitionWorkerThread.quit();
121 121 m_VariableAcquisitionWorkerThread.wait();
122 122 }
123 123
124 124
125 125 void processRequest(std::shared_ptr<Variable> var, const DateTimeRange &rangeRequested,
126 126 QUuid varRequestId);
127 127
128 128 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
129 129 std::shared_ptr<IDataSeries>
130 130 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
131 131
132 132 void registerProvider(std::shared_ptr<IDataProvider> provider);
133 133
134 134 void storeVariableRequest(QUuid varId, QUuid varRequestId, const VariableRequest &varRequest);
135 135 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries);
136 136 void updateVariables(QUuid varRequestId);
137 137 void updateVariableRequest(QUuid varRequestId);
138 138 void cancelVariableRequest(QUuid varRequestId);
139 139 void executeVarRequest(std::shared_ptr<Variable> var, VariableRequest &varRequest);
140 140 bool hasPendingDownloads();
141 141 template <typename VariableIterator>
142 142 void desynchronize(VariableIterator variableIt, const QUuid &syncGroupId);
143 143
144 144 QMutex m_WorkingMutex;
145 145 /// Variable model. The VariableController has the ownership
146 146 VariableModel *m_VariableModel;
147 147 QItemSelectionModel *m_VariableSelectionModel;
148 148
149 149
150 150 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
151 151 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
152 152 QThread m_VariableAcquisitionWorkerThread;
153 153
154 154 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
155 155 m_VariableToProviderMap;
156 156 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
157 157 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
158 158 m_GroupIdToVariableSynchronizationGroupMap;
159 159 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
160 160 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
161 161
162 162 std::map<QUuid, std::list<QUuid> > m_VarGroupIdToVarIds;
163 163 std::map<QUuid, std::unique_ptr<VariableRequestHandler> > m_VarIdToVarRequestHandler;
164 164
165 165 VariableController *q;
166 166 };
167 167
168 168
169 169 VariableController::VariableController(QObject *parent)
170 170 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
171 171 {
172 172 qCDebug(LOG_VariableController()) << tr("VariableController construction")
173 173 << QThread::currentThread();
174 174
175 175 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
176 176 &VariableController::onAbortProgressRequested);
177 177
178 178 connect(impl->m_VariableAcquisitionWorker.get(),
179 179 &VariableAcquisitionWorker::variableCanceledRequested, this,
180 180 &VariableController::onAbortAcquisitionRequested);
181 181
182 182 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
183 183 &VariableController::onDataProvided);
184 184 connect(impl->m_VariableAcquisitionWorker.get(),
185 185 &VariableAcquisitionWorker::variableRequestInProgress, this,
186 186 &VariableController::onVariableRetrieveDataInProgress);
187 187
188 188
189 189 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
190 190 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
191 191 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
192 192 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
193 193
194 194 connect(impl->m_VariableModel, &VariableModel::requestVariableRangeUpdate, this,
195 195 &VariableController::onUpdateDateTime);
196 196
197 197 impl->m_VariableAcquisitionWorkerThread.start();
198 198 }
199 199
200 200 VariableController::~VariableController()
201 201 {
202 202 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
203 203 << QThread::currentThread();
204 204 this->waitForFinish();
205 205 }
206 206
207 207 VariableModel *VariableController::variableModel() noexcept
208 208 {
209 209 return impl->m_VariableModel;
210 210 }
211 211
212 212 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
213 213 {
214 214 return impl->m_VariableSelectionModel;
215 215 }
216 216
217 217 std::shared_ptr<Variable>
218 218 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
219 219 {
220 220 if (impl->m_VariableModel->containsVariable(variable)) {
221 221 // Clones variable
222 222 auto duplicate = variable->clone();
223 223
224 224 // Adds clone to model
225 225 impl->m_VariableModel->addVariable(duplicate);
226 226
227 227 // Generates clone identifier
228 228 impl->m_VariableToIdentifierMap[duplicate] = QUuid::createUuid();
229 229
230 230 // Registers provider
231 231 auto variableProvider = impl->m_VariableToProviderMap.at(variable);
232 232 auto duplicateProvider = variableProvider != nullptr ? variableProvider->clone() : nullptr;
233 233
234 234 impl->m_VariableToProviderMap[duplicate] = duplicateProvider;
235 235 if (duplicateProvider) {
236 236 impl->registerProvider(duplicateProvider);
237 237 }
238 238
239 239 return duplicate;
240 240 }
241 241 else {
242 242 qCCritical(LOG_VariableController())
243 243 << tr("Can't create duplicate of variable %1: variable not registered in the model")
244 244 .arg(variable->name());
245 245 return nullptr;
246 246 }
247 247 }
248 248
249 249 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
250 250 {
251 251 if (!variable) {
252 252 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
253 253 return;
254 254 }
255 255
256 256 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
257 257 // make some treatments before the deletion
258 258 emit variableAboutToBeDeleted(variable);
259 259
260 260 auto variableIt = impl->m_VariableToIdentifierMap.find(variable);
261 261 Q_ASSERT(variableIt != impl->m_VariableToIdentifierMap.cend());
262 262
263 263 auto variableId = variableIt->second;
264 264
265 265 // Removes variable's handler
266 266 impl->m_VarIdToVarRequestHandler.erase(variableId);
267 267
268 268 // Desynchronizes variable (if the variable is in a sync group)
269 269 auto syncGroupIt = impl->m_VariableIdGroupIdMap.find(variableId);
270 270 if (syncGroupIt != impl->m_VariableIdGroupIdMap.cend()) {
271 271 impl->desynchronize(variableIt, syncGroupIt->second);
272 272 }
273 273
274 274 // Deletes identifier
275 275 impl->m_VariableToIdentifierMap.erase(variableIt);
276 276
277 277 // Deletes provider
278 278 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
279 279 qCDebug(LOG_VariableController())
280 280 << tr("Number of providers deleted for variable %1: %2")
281 281 .arg(variable->name(), QString::number(nbProvidersDeleted));
282 282
283 283
284 284 // Deletes from model
285 285 impl->m_VariableModel->deleteVariable(variable);
286 286 }
287 287
288 288 void VariableController::deleteVariables(
289 289 const QVector<std::shared_ptr<Variable> > &variables) noexcept
290 290 {
291 291 for (auto variable : qAsConst(variables)) {
292 292 deleteVariable(variable);
293 293 }
294 294 }
295 295
296 296 QByteArray
297 297 VariableController::mimeDataForVariables(const QList<std::shared_ptr<Variable> > &variables) const
298 298 {
299 299 auto encodedData = QByteArray{};
300 300
301 301 QVariantList ids;
302 302 for (auto &var : variables) {
303 303 auto itVar = impl->m_VariableToIdentifierMap.find(var);
304 304 if (itVar == impl->m_VariableToIdentifierMap.cend()) {
305 305 qCCritical(LOG_VariableController())
306 306 << tr("Impossible to find the data for an unknown variable.");
307 307 }
308 308
309 309 ids << itVar->second.toByteArray();
310 310 }
311 311
312 312 QDataStream stream{&encodedData, QIODevice::WriteOnly};
313 313 stream << ids;
314 314
315 315 return encodedData;
316 316 }
317 317
318 318 QList<std::shared_ptr<Variable> >
319 319 VariableController::variablesForMimeData(const QByteArray &mimeData) const
320 320 {
321 321 auto variables = QList<std::shared_ptr<Variable> >{};
322 322 QDataStream stream{mimeData};
323 323
324 324 QVariantList ids;
325 325 stream >> ids;
326 326
327 327 for (auto id : ids) {
328 328 auto uuid = QUuid{id.toByteArray()};
329 329 auto var = impl->findVariable(uuid);
330 330 variables << var;
331 331 }
332 332
333 333 return variables;
334 334 }
335 335
336 336 std::shared_ptr<Variable>
337 337 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
338 338 std::shared_ptr<IDataProvider> provider, const DateTimeRange& range) noexcept
339 339 {
340 340 // if (!impl->m_TimeController) {
341 341 // qCCritical(LOG_VariableController())
342 342 // << tr("Impossible to create variable: The time controller is null");
343 343 // return nullptr;
344 344 // }
345 345
346 346 // auto range = impl->m_TimeController->dateTime();
347 347
348 348 if (auto newVariable = impl->m_VariableModel->createVariable(name, metadata)) {
349 349 auto varId = QUuid::createUuid();
350 350
351 351 // Create the handler
352 352 auto varRequestHandler = std::make_unique<VariableRequestHandler>();
353 353 varRequestHandler->m_VarId = varId;
354 354
355 355 impl->m_VarIdToVarRequestHandler.insert(
356 356 std::make_pair(varId, std::move(varRequestHandler)));
357 357
358 358 // store the provider
359 359 impl->registerProvider(provider);
360 360
361 361 // Associate the provider
362 362 impl->m_VariableToProviderMap[newVariable] = provider;
363 363 impl->m_VariableToIdentifierMap[newVariable] = varId;
364 364
365 365 this->onRequestDataLoading(QVector<std::shared_ptr<Variable> >{newVariable}, range, false);
366 366
367 367 // auto varRequestId = QUuid::createUuid();
368 368 // qCInfo(LOG_VariableController()) << "createVariable: " << varId << varRequestId;
369 369 // impl->processRequest(newVariable, range, varRequestId);
370 370 // impl->updateVariableRequest(varRequestId);
371 371
372 372 emit variableAdded(newVariable);
373 373
374 374 return newVariable;
375 375 }
376 376
377 377 qCCritical(LOG_VariableController()) << tr("Impossible to create variable");
378 378 return nullptr;
379 379 }
380 380
381 381 void VariableController::onDateTimeOnSelection(const DateTimeRange &dateTime)
382 382 {
383 383 // NOTE: Even if acquisition request is aborting, the graphe range will be changed
384 384 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
385 385 << QThread::currentThread()->objectName();
386 386 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
387 387
388 388 // NOTE we only permit the time modification for one variable
389 389 // DEPRECATED
390 390 // auto variables = QVector<std::shared_ptr<Variable> >{};
391 391 // for (const auto &selectedRow : qAsConst(selectedRows)) {
392 392 // if (auto selectedVariable =
393 393 // impl->m_VariableModel->variable(selectedRow.row())) {
394 394 // variables << selectedVariable;
395 395
396 396 // // notify that rescale operation has to be done
397 397 // emit rangeChanged(selectedVariable, dateTime);
398 398 // }
399 399 // }
400 400 // if (!variables.isEmpty()) {
401 401 // this->onRequestDataLoading(variables, dateTime, synchro);
402 402 // }
403 403 if (selectedRows.size() == 1) {
404 404
405 405 if (auto selectedVariable
406 406 = impl->m_VariableModel->variable(qAsConst(selectedRows).first().row())) {
407 407
408 408 onUpdateDateTime(selectedVariable, dateTime);
409 409 }
410 410 }
411 411 else if (selectedRows.size() > 1) {
412 412 qCCritical(LOG_VariableController())
413 413 << tr("Impossible to set time for more than 1 variable in the same time");
414 414 }
415 415 else {
416 416 qCWarning(LOG_VariableController())
417 417 << tr("There is no variable selected to set the time one");
418 418 }
419 419 }
420 420
421 421 void VariableController::onUpdateDateTime(std::shared_ptr<Variable> variable,
422 422 const DateTimeRange &dateTime)
423 423 {
424 424 auto itVar = impl->m_VariableToIdentifierMap.find(variable);
425 425 if (itVar == impl->m_VariableToIdentifierMap.cend()) {
426 426 qCCritical(LOG_VariableController())
427 427 << tr("Impossible to onDateTimeOnSelection request for unknown variable");
428 428 return;
429 429 }
430 430
431 431 // notify that rescale operation has to be done
432 432 emit rangeChanged(variable, dateTime);
433 433
434 434 auto synchro
435 435 = impl->m_VariableIdGroupIdMap.find(itVar->second) != impl->m_VariableIdGroupIdMap.cend();
436 436
437 437 this->onRequestDataLoading(QVector<std::shared_ptr<Variable> >{variable}, dateTime, synchro);
438 438 }
439 439
440 440 void VariableController::onDataProvided(QUuid vIdentifier, const DateTimeRange &rangeRequested,
441 441 const DateTimeRange &cacheRangeRequested,
442 442 QVector<AcquisitionDataPacket> dataAcquired)
443 443 {
444 444 qCDebug(LOG_VariableController()) << tr("onDataProvided") << QThread::currentThread();
445 445 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
446 446 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
447 447 if (!varRequestId.isNull()) {
448 448 impl->updateVariables(varRequestId);
449 449 }
450 450 }
451 451
452 452 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
453 453 {
454 454 qCDebug(LOG_VariableController())
455 455 << "TORM: variableController::onVariableRetrieveDataInProgress"
456 456 << QThread::currentThread()->objectName() << progress;
457 457 if (auto var = impl->findVariable(identifier)) {
458 458 impl->m_VariableModel->setDataProgress(var, progress);
459 459 }
460 460 else {
461 461 qCCritical(LOG_VariableController())
462 462 << tr("Impossible to notify progression of a null variable");
463 463 }
464 464 }
465 465
466 466 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
467 467 {
468 468 qCDebug(LOG_VariableController()) << "TORM: variableController::onAbortProgressRequested"
469 469 << QThread::currentThread()->objectName() << variable->name();
470 470
471 471 auto itVar = impl->m_VariableToIdentifierMap.find(variable);
472 472 if (itVar == impl->m_VariableToIdentifierMap.cend()) {
473 473 qCCritical(LOG_VariableController())
474 474 << tr("Impossible to onAbortProgressRequested request for unknown variable");
475 475 return;
476 476 }
477 477
478 478 auto varId = itVar->second;
479 479
480 480 auto itVarHandler = impl->m_VarIdToVarRequestHandler.find(varId);
481 481 if (itVarHandler == impl->m_VarIdToVarRequestHandler.cend()) {
482 482 qCCritical(LOG_VariableController())
483 483 << tr("Impossible to onAbortProgressRequested for variable with unknown handler");
484 484 return;
485 485 }
486 486
487 487 auto varHandler = itVarHandler->second.get();
488 488
489 489 // case where a variable has a running request
490 490 if (varHandler->m_State != VariableRequestHandlerState::OFF) {
491 491 impl->cancelVariableRequest(varHandler->m_RunningVarRequest.m_VariableGroupId);
492 492 }
493 493 }
494 494
495 495 void VariableController::onAbortAcquisitionRequested(QUuid vIdentifier)
496 496 {
497 497 qCDebug(LOG_VariableController()) << "TORM: variableController::onAbortAcquisitionRequested"
498 498 << QThread::currentThread()->objectName() << vIdentifier;
499 499
500 500 if (auto var = impl->findVariable(vIdentifier)) {
501 501 this->onAbortProgressRequested(var);
502 502 }
503 503 else {
504 504 qCCritical(LOG_VariableController())
505 505 << tr("Impossible to abort Acquisition Requestof a null variable");
506 506 }
507 507 }
508 508
509 509 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
510 510 {
511 511 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
512 512 << QThread::currentThread()->objectName()
513 513 << synchronizationGroupId;
514 514 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
515 515 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
516 516 std::make_pair(synchronizationGroupId, vSynchroGroup));
517 517 }
518 518
519 519 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
520 520 {
521 521 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
522 522 }
523 523
524 524 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
525 525 QUuid synchronizationGroupId)
526 526
527 527 {
528 528 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
529 529 << synchronizationGroupId;
530 530 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
531 531 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
532 532 auto groupIdToVSGIt
533 533 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
534 534 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
535 535 impl->m_VariableIdGroupIdMap.insert(
536 536 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
537 537 groupIdToVSGIt->second->addVariable(varToVarIdIt->second);
538 538 }
539 539 else {
540 540 qCCritical(LOG_VariableController())
541 541 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
542 542 << variable->name();
543 543 }
544 544 }
545 545 else {
546 546 qCCritical(LOG_VariableController())
547 547 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
548 548 }
549 549 }
550 550
551 551 void VariableController::desynchronize(std::shared_ptr<Variable> variable,
552 552 QUuid synchronizationGroupId)
553 553 {
554 554 // Gets variable id
555 555 auto variableIt = impl->m_VariableToIdentifierMap.find(variable);
556 556 if (variableIt == impl->m_VariableToIdentifierMap.cend()) {
557 557 qCCritical(LOG_VariableController())
558 558 << tr("Can't desynchronize variable %1: variable identifier not found")
559 559 .arg(variable->name());
560 560 return;
561 561 }
562 562
563 563 impl->desynchronize(variableIt, synchronizationGroupId);
564 564 }
565 565
566 566 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
567 567 const DateTimeRange &range, bool synchronise)
568 568 {
569 569 // variables is assumed synchronized
570 570 // TODO: Asser variables synchronization
571 571 // we want to load data of the variable for the dateTime.
572 572 if (variables.isEmpty()) {
573 573 return;
574 574 }
575 575
576 576 auto varRequestId = QUuid::createUuid();
577 577 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
578 578 << QThread::currentThread()->objectName() << varRequestId
579 579 << range << synchronise;
580 580
581 581 if (!synchronise) {
582 582 auto varIds = std::list<QUuid>{};
583 583 for (const auto &var : variables) {
584 584 auto vId = impl->m_VariableToIdentifierMap.at(var);
585 585 varIds.push_back(vId);
586 586 }
587 587 impl->m_VarGroupIdToVarIds.insert(std::make_pair(varRequestId, varIds));
588 588 for (const auto &var : variables) {
589 589 qCDebug(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId
590 590 << varIds.size();
591 591 impl->processRequest(var, range, varRequestId);
592 592 }
593 593 }
594 594 else {
595 595 auto vId = impl->m_VariableToIdentifierMap.at(variables.first());
596 596 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
597 597 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
598 598 auto groupId = varIdToGroupIdIt->second;
599 599
600 600 auto vSynchronizationGroup
601 601 = impl->m_GroupIdToVariableSynchronizationGroupMap.at(groupId);
602 602 auto vSyncIds = vSynchronizationGroup->getIds();
603 603
604 604 auto varIds = std::list<QUuid>{};
605 605 for (auto vId : vSyncIds) {
606 606 varIds.push_back(vId);
607 607 }
608 608 impl->m_VarGroupIdToVarIds.insert(std::make_pair(varRequestId, varIds));
609 609
610 610 for (auto vId : vSyncIds) {
611 611 auto var = impl->findVariable(vId);
612 612
613 613 // Don't process already processed var
614 614 if (var != nullptr) {
615 615 qCDebug(LOG_VariableController()) << "processRequest synchro for" << var->name()
616 616 << varRequestId;
617 617 auto vSyncRangeRequested
618 618 = variables.contains(var)
619 619 ? range
620 620 : computeSynchroRangeRequested(var->range(), range,
621 621 variables.first()->range());
622 622 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
623 623 impl->processRequest(var, vSyncRangeRequested, varRequestId);
624 624 }
625 625 else {
626 626 qCCritical(LOG_VariableController())
627 627
628 628 << tr("Impossible to synchronize a null variable");
629 629 }
630 630 }
631 631 }
632 632 }
633 633
634 634 impl->updateVariables(varRequestId);
635 635 }
636 636
637 637
638 638 void VariableController::initialize()
639 639 {
640 640 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
641 641 impl->m_WorkingMutex.lock();
642 642 qCDebug(LOG_VariableController()) << tr("VariableController init END");
643 643 }
644 644
645 645 void VariableController::finalize()
646 646 {
647 647 impl->m_WorkingMutex.unlock();
648 648 }
649 649
650 650 void VariableController::waitForFinish()
651 651 {
652 652 QMutexLocker locker{&impl->m_WorkingMutex};
653 653 }
654 654
655 655 bool VariableController::hasPendingDownloads()
656 656 {
657 657 return impl->hasPendingDownloads();
658 658 }
659 659
660 660 AcquisitionZoomType VariableController::getZoomType(const DateTimeRange &range, const DateTimeRange &oldRange)
661 661 {
662 if (almost_equal(static_cast<double>(range.delta()), static_cast<double>(oldRange.delta()), 1)) // same delta -> must be a pan or nothing
662 if (SciQLop::numeric::almost_equal<double>(range.delta(), oldRange.delta(), 1)) // same delta -> must be a pan or nothing
663 663 {
664 664 if(range.m_TStart > oldRange.m_TStart)
665 665 return AcquisitionZoomType::PanRight;
666 666 if(range.m_TStart < oldRange.m_TStart)
667 667 return AcquisitionZoomType::PanLeft;
668 668 }
669 669 else // different delta -> must be a zoom
670 670 {
671 671 if(range.m_TStart > oldRange.m_TStart)
672 672 return AcquisitionZoomType::ZoomIn;
673 673 if(range.m_TStart < oldRange.m_TStart)
674 674 return AcquisitionZoomType::ZoomOut;
675 675 }
676 676 return AcquisitionZoomType::Unknown;
677 677 }
678 678
679 679 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
680 680 const DateTimeRange &rangeRequested,
681 681 QUuid varRequestId)
682 682 {
683 683 auto itVar = m_VariableToIdentifierMap.find(var);
684 684 if (itVar == m_VariableToIdentifierMap.cend()) {
685 685 qCCritical(LOG_VariableController())
686 686 << tr("Impossible to process request for unknown variable");
687 687 return;
688 688 }
689 689
690 690 auto varId = itVar->second;
691 691
692 692 auto itVarHandler = m_VarIdToVarRequestHandler.find(varId);
693 693 if (itVarHandler == m_VarIdToVarRequestHandler.cend()) {
694 694 qCCritical(LOG_VariableController())
695 695 << tr("Impossible to process request for variable with unknown handler");
696 696 return;
697 697 }
698 698
699 699 auto oldRange = var->range();
700 700
701 701 auto varHandler = itVarHandler->second.get();
702 702
703 703 if (varHandler->m_State != VariableRequestHandlerState::OFF) {
704 704 oldRange = varHandler->m_RunningVarRequest.m_RangeRequested;
705 705 }
706 706
707 707 auto varRequest = VariableRequest{};
708 708 varRequest.m_VariableGroupId = varRequestId;
709 709 auto varStrategyRangesRequested
710 710 = m_VariableCacheStrategy->computeRange(oldRange, rangeRequested);
711 711 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
712 712 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
713 713
714 714 switch (varHandler->m_State) {
715 715 case VariableRequestHandlerState::OFF: {
716 716 qCDebug(LOG_VariableController()) << tr("Process Request OFF")
717 717 << varRequest.m_RangeRequested
718 718 << varRequest.m_CacheRangeRequested;
719 719 varHandler->m_RunningVarRequest = varRequest;
720 720 varHandler->m_State = VariableRequestHandlerState::RUNNING;
721 721 executeVarRequest(var, varRequest);
722 722 break;
723 723 }
724 724 case VariableRequestHandlerState::RUNNING: {
725 725 qCDebug(LOG_VariableController()) << tr("Process Request RUNNING")
726 726 << varRequest.m_RangeRequested
727 727 << varRequest.m_CacheRangeRequested;
728 728 varHandler->m_State = VariableRequestHandlerState::PENDING;
729 729 varHandler->m_PendingVarRequest = varRequest;
730 730 break;
731 731 }
732 732 case VariableRequestHandlerState::PENDING: {
733 733 qCDebug(LOG_VariableController()) << tr("Process Request PENDING")
734 734 << varRequest.m_RangeRequested
735 735 << varRequest.m_CacheRangeRequested;
736 736 auto variableGroupIdToCancel = varHandler->m_PendingVarRequest.m_VariableGroupId;
737 737 cancelVariableRequest(variableGroupIdToCancel);
738 738 // Cancel variable can make state downgrade
739 739 varHandler->m_State = VariableRequestHandlerState::PENDING;
740 740 varHandler->m_PendingVarRequest = varRequest;
741 741
742 742 break;
743 743 }
744 744 default:
745 745 qCCritical(LOG_VariableController())
746 746 << QObject::tr("Unknown VariableRequestHandlerState");
747 747 }
748 748 }
749 749
750 750 std::shared_ptr<Variable>
751 751 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
752 752 {
753 753 std::shared_ptr<Variable> var;
754 754 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
755 755
756 756 auto end = m_VariableToIdentifierMap.cend();
757 757 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
758 758 if (it != end) {
759 759 var = it->first;
760 760 }
761 761 else {
762 762 qCCritical(LOG_VariableController())
763 763 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
764 764 }
765 765
766 766 return var;
767 767 }
768 768
769 769 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
770 770 const QVector<AcquisitionDataPacket> acqDataPacketVector)
771 771 {
772 772 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
773 773 << acqDataPacketVector.size();
774 774 std::shared_ptr<IDataSeries> dataSeries;
775 775 if (!acqDataPacketVector.isEmpty()) {
776 776 dataSeries = acqDataPacketVector[0].m_DateSeries;
777 777 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
778 778 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
779 779 }
780 780 }
781 781 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
782 782 << acqDataPacketVector.size();
783 783 return dataSeries;
784 784 }
785 785
786 786 void VariableController::VariableControllerPrivate::registerProvider(
787 787 std::shared_ptr<IDataProvider> provider)
788 788 {
789 789 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
790 790 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
791 791 << provider->objectName();
792 792 m_ProviderSet.insert(provider);
793 793 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
794 794 &VariableAcquisitionWorker::onVariableDataAcquired);
795 795 connect(provider.get(), &IDataProvider::dataProvidedProgress,
796 796 m_VariableAcquisitionWorker.get(),
797 797 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
798 798 connect(provider.get(), &IDataProvider::dataProvidedFailed,
799 799 m_VariableAcquisitionWorker.get(),
800 800 &VariableAcquisitionWorker::onVariableAcquisitionFailed);
801 801 }
802 802 else {
803 803 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
804 804 }
805 805 }
806 806
807 807 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
808 808 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
809 809 {
810 810 auto itVarHandler = m_VarIdToVarRequestHandler.find(varId);
811 811 if (itVarHandler == m_VarIdToVarRequestHandler.cend()) {
812 812 return QUuid();
813 813 }
814 814
815 815 auto varHandler = itVarHandler->second.get();
816 816 if (varHandler->m_State == VariableRequestHandlerState::OFF) {
817 817 qCCritical(LOG_VariableController())
818 818 << tr("acceptVariableRequest impossible on a variable with OFF state");
819 819 }
820 820
821 821 varHandler->m_RunningVarRequest.m_DataSeries = dataSeries;
822 822 varHandler->m_CanUpdate = true;
823 823
824 824 // Element traitΓ©, on a dΓ©jΓ  toutes les donnΓ©es necessaires
825 825 auto varGroupId = varHandler->m_RunningVarRequest.m_VariableGroupId;
826 826 qCDebug(LOG_VariableController()) << "Variable::acceptVariableRequest" << varGroupId
827 827 << m_VarGroupIdToVarIds.size();
828 828
829 829 return varHandler->m_RunningVarRequest.m_VariableGroupId;
830 830 }
831 831
832 832 void VariableController::VariableControllerPrivate::updateVariables(QUuid varRequestId)
833 833 {
834 834 qCDebug(LOG_VariableController()) << "VariableControllerPrivate::updateVariables"
835 835 << QThread::currentThread()->objectName() << varRequestId;
836 836
837 837 auto varGroupIdToVarIdsIt = m_VarGroupIdToVarIds.find(varRequestId);
838 838 if (varGroupIdToVarIdsIt == m_VarGroupIdToVarIds.end()) {
839 839 qCWarning(LOG_VariableController())
840 840 << tr("Impossible to updateVariables of unknown variables") << varRequestId;
841 841 return;
842 842 }
843 843
844 844 auto &varIds = varGroupIdToVarIdsIt->second;
845 845 auto varIdsEnd = varIds.end();
846 846 bool processVariableUpdate = true;
847 847 qCDebug(LOG_VariableController()) << "VariableControllerPrivate::updateVariables"
848 848 << varRequestId << varIds.size();
849 849 for (auto varIdsIt = varIds.begin(); (varIdsIt != varIdsEnd) && processVariableUpdate;
850 850 ++varIdsIt) {
851 851 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
852 852 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
853 853 processVariableUpdate &= itVarHandler->second->m_CanUpdate;
854 854 }
855 855 }
856 856
857 857 if (processVariableUpdate) {
858 858 qCDebug(LOG_VariableController()) << "Final update OK for the var request" << varIds.size();
859 859 for (auto varIdsIt = varIds.begin(); varIdsIt != varIdsEnd; ++varIdsIt) {
860 860 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
861 861 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
862 862 if (auto var = findVariable(*varIdsIt)) {
863 863 auto &varRequest = itVarHandler->second->m_RunningVarRequest;
864 864 var->setRange(varRequest.m_RangeRequested);
865 865 var->setCacheRange(varRequest.m_CacheRangeRequested);
866 866 qCDebug(LOG_VariableController()) << tr("1: onDataProvided")
867 867 << varRequest.m_RangeRequested
868 868 << varRequest.m_CacheRangeRequested;
869 869 qCDebug(LOG_VariableController()) << tr("2: onDataProvided var points before")
870 870 << var->nbPoints()
871 871 << varRequest.m_DataSeries->nbPoints();
872 872 var->mergeDataSeries(varRequest.m_DataSeries);
873 873 qCDebug(LOG_VariableController()) << tr("3: onDataProvided var points after")
874 874 << var->nbPoints();
875 875
876 876 emit var->updated();
877 877 qCDebug(LOG_VariableController()) << tr("Update OK");
878 878 }
879 879 else {
880 880 qCCritical(LOG_VariableController())
881 881 << tr("Impossible to update data to a null variable");
882 882 }
883 883 }
884 884 }
885 885 updateVariableRequest(varRequestId);
886 886
887 887 // cleaning varRequestId
888 888 qCDebug(LOG_VariableController()) << tr("m_VarGroupIdToVarIds erase") << varRequestId;
889 889 m_VarGroupIdToVarIds.erase(varRequestId);
890 890 if (m_VarGroupIdToVarIds.empty()) {
891 891 emit q->acquisitionFinished();
892 892 }
893 893 }
894 894 }
895 895
896 896
897 897 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
898 898 {
899 899 auto varGroupIdToVarIdsIt = m_VarGroupIdToVarIds.find(varRequestId);
900 900 if (varGroupIdToVarIdsIt == m_VarGroupIdToVarIds.end()) {
901 901 qCCritical(LOG_VariableController()) << QObject::tr(
902 902 "Impossible to updateVariableRequest since varGroupdId isn't here anymore");
903 903
904 904 return;
905 905 }
906 906
907 907 auto &varIds = varGroupIdToVarIdsIt->second;
908 908 auto varIdsEnd = varIds.end();
909 909 for (auto varIdsIt = varIds.begin(); (varIdsIt != varIdsEnd); ++varIdsIt) {
910 910 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
911 911 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
912 912
913 913 auto varHandler = itVarHandler->second.get();
914 914 varHandler->m_CanUpdate = false;
915 915
916 916
917 917 switch (varHandler->m_State) {
918 918 case VariableRequestHandlerState::OFF: {
919 919 qCCritical(LOG_VariableController())
920 920 << QObject::tr("Impossible to update a variable with handler in OFF state");
921 921 } break;
922 922 case VariableRequestHandlerState::RUNNING: {
923 923 varHandler->m_State = VariableRequestHandlerState::OFF;
924 924 varHandler->m_RunningVarRequest = VariableRequest{};
925 925 break;
926 926 }
927 927 case VariableRequestHandlerState::PENDING: {
928 928 varHandler->m_State = VariableRequestHandlerState::RUNNING;
929 929 varHandler->m_RunningVarRequest = varHandler->m_PendingVarRequest;
930 930 varHandler->m_PendingVarRequest = VariableRequest{};
931 931 auto var = findVariable(itVarHandler->first);
932 932 executeVarRequest(var, varHandler->m_RunningVarRequest);
933 933 updateVariables(varHandler->m_RunningVarRequest.m_VariableGroupId);
934 934 break;
935 935 }
936 936 default:
937 937 qCCritical(LOG_VariableController())
938 938 << QObject::tr("Unknown VariableRequestHandlerState");
939 939 }
940 940 }
941 941 }
942 942 }
943 943
944 944
945 945 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
946 946 {
947 947 qCDebug(LOG_VariableController()) << tr("cancelVariableRequest") << varRequestId;
948 948
949 949 auto varGroupIdToVarIdsIt = m_VarGroupIdToVarIds.find(varRequestId);
950 950 if (varGroupIdToVarIdsIt == m_VarGroupIdToVarIds.end()) {
951 951 qCCritical(LOG_VariableController())
952 952 << tr("Impossible to cancelVariableRequest for unknown varGroupdId") << varRequestId;
953 953 return;
954 954 }
955 955
956 956 auto &varIds = varGroupIdToVarIdsIt->second;
957 957 auto varIdsEnd = varIds.end();
958 958 for (auto varIdsIt = varIds.begin(); (varIdsIt != varIdsEnd); ++varIdsIt) {
959 959 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
960 960 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
961 961
962 962 auto varHandler = itVarHandler->second.get();
963 963 varHandler->m_VarId = QUuid{};
964 964 switch (varHandler->m_State) {
965 965 case VariableRequestHandlerState::OFF: {
966 966 qCWarning(LOG_VariableController())
967 967 << QObject::tr("Impossible to cancel a variable with no running request");
968 968 break;
969 969 }
970 970 case VariableRequestHandlerState::RUNNING: {
971 971
972 972 if (varHandler->m_RunningVarRequest.m_VariableGroupId == varRequestId) {
973 973 auto var = findVariable(itVarHandler->first);
974 974 auto varProvider = m_VariableToProviderMap.at(var);
975 975 if (varProvider != nullptr) {
976 976 m_VariableAcquisitionWorker->abortProgressRequested(
977 977 itVarHandler->first);
978 978 }
979 979 m_VariableModel->setDataProgress(var, 0.0);
980 980 varHandler->m_CanUpdate = false;
981 981 varHandler->m_State = VariableRequestHandlerState::OFF;
982 982 varHandler->m_RunningVarRequest = VariableRequest{};
983 983 }
984 984 else {
985 985 // TODO: log Impossible to cancel the running variable request beacause its
986 986 // varRequestId isn't not the canceled one
987 987 }
988 988 break;
989 989 }
990 990 case VariableRequestHandlerState::PENDING: {
991 991 if (varHandler->m_RunningVarRequest.m_VariableGroupId == varRequestId) {
992 992 auto var = findVariable(itVarHandler->first);
993 993 auto varProvider = m_VariableToProviderMap.at(var);
994 994 if (varProvider != nullptr) {
995 995 m_VariableAcquisitionWorker->abortProgressRequested(
996 996 itVarHandler->first);
997 997 }
998 998 m_VariableModel->setDataProgress(var, 0.0);
999 999 varHandler->m_CanUpdate = false;
1000 1000 varHandler->m_State = VariableRequestHandlerState::RUNNING;
1001 1001 varHandler->m_RunningVarRequest = varHandler->m_PendingVarRequest;
1002 1002 varHandler->m_PendingVarRequest = VariableRequest{};
1003 1003 executeVarRequest(var, varHandler->m_RunningVarRequest);
1004 1004 }
1005 1005 else if (varHandler->m_PendingVarRequest.m_VariableGroupId == varRequestId) {
1006 1006 varHandler->m_State = VariableRequestHandlerState::RUNNING;
1007 1007 varHandler->m_PendingVarRequest = VariableRequest{};
1008 1008 }
1009 1009 else {
1010 1010 // TODO: log Impossible to cancel the variable request beacause its
1011 1011 // varRequestId isn't not the canceled one
1012 1012 }
1013 1013 break;
1014 1014 }
1015 1015 default:
1016 1016 qCCritical(LOG_VariableController())
1017 1017 << QObject::tr("Unknown VariableRequestHandlerState");
1018 1018 }
1019 1019 }
1020 1020 }
1021 1021 qCDebug(LOG_VariableController()) << tr("cancelVariableRequest: erase") << varRequestId;
1022 1022 m_VarGroupIdToVarIds.erase(varRequestId);
1023 1023 if (m_VarGroupIdToVarIds.empty()) {
1024 1024 emit q->acquisitionFinished();
1025 1025 }
1026 1026 }
1027 1027
1028 1028 void VariableController::VariableControllerPrivate::executeVarRequest(std::shared_ptr<Variable> var,
1029 1029 VariableRequest &varRequest)
1030 1030 {
1031 1031 qCDebug(LOG_VariableController()) << tr("TORM: executeVarRequest");
1032 1032
1033 1033 auto varIdIt = m_VariableToIdentifierMap.find(var);
1034 1034 if (varIdIt == m_VariableToIdentifierMap.cend()) {
1035 1035 qCWarning(LOG_VariableController()) << tr(
1036 1036 "Can't execute request of a variable that is not registered (may has been deleted)");
1037 1037 return;
1038 1038 }
1039 1039
1040 1040 auto varId = varIdIt->second;
1041 1041
1042 1042 auto varCacheRange = var->cacheRange();
1043 1043 auto varCacheRangeRequested = varRequest.m_CacheRangeRequested;
1044 1044 auto notInCacheRangeList
1045 1045 = Variable::provideNotInCacheRangeList(varCacheRange, varCacheRangeRequested);
1046 1046 auto inCacheRangeList
1047 1047 = Variable::provideInCacheRangeList(varCacheRange, varCacheRangeRequested);
1048 1048
1049 1049 if (!notInCacheRangeList.empty()) {
1050 1050
1051 1051 auto varProvider = m_VariableToProviderMap.at(var);
1052 1052 if (varProvider != nullptr) {
1053 1053 qCDebug(LOG_VariableController()) << "executeVarRequest " << varRequest.m_RangeRequested
1054 1054 << varRequest.m_CacheRangeRequested;
1055 1055 m_VariableAcquisitionWorker->pushVariableRequest(
1056 1056 varRequest.m_VariableGroupId, varId, varRequest.m_RangeRequested,
1057 1057 varRequest.m_CacheRangeRequested,
1058 1058 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
1059 1059 varProvider);
1060 1060 }
1061 1061 else {
1062 1062 qCCritical(LOG_VariableController())
1063 1063 << "Impossible to provide data with a null provider";
1064 1064 }
1065 1065
1066 1066 if (!inCacheRangeList.empty()) {
1067 1067 emit q->updateVarDisplaying(var, inCacheRangeList.first());
1068 1068 }
1069 1069 }
1070 1070 else {
1071 1071 acceptVariableRequest(varId,
1072 1072 var->dataSeries()->subDataSeries(varRequest.m_CacheRangeRequested));
1073 1073 }
1074 1074 }
1075 1075
1076 1076 bool VariableController::VariableControllerPrivate::hasPendingDownloads()
1077 1077 {
1078 1078 return !m_VarGroupIdToVarIds.empty();
1079 1079 }
1080 1080
1081 1081 template <typename VariableIterator>
1082 1082 void VariableController::VariableControllerPrivate::desynchronize(VariableIterator variableIt,
1083 1083 const QUuid &syncGroupId)
1084 1084 {
1085 1085 const auto &variable = variableIt->first;
1086 1086 const auto &variableId = variableIt->second;
1087 1087
1088 1088 // Gets synchronization group
1089 1089 auto groupIt = m_GroupIdToVariableSynchronizationGroupMap.find(syncGroupId);
1090 1090 if (groupIt == m_GroupIdToVariableSynchronizationGroupMap.cend()) {
1091 1091 qCCritical(LOG_VariableController())
1092 1092 << tr("Can't desynchronize variable %1: unknown synchronization group")
1093 1093 .arg(variable->name());
1094 1094 return;
1095 1095 }
1096 1096
1097 1097 // Removes variable from synchronization group
1098 1098 auto synchronizationGroup = groupIt->second;
1099 1099 synchronizationGroup->removeVariable(variableId);
1100 1100
1101 1101 // Removes link between variable and synchronization group
1102 1102 m_VariableIdGroupIdMap.erase(variableId);
1103 1103 }
@@ -1,83 +1,86
1 1 #include "Variable/VariableController2.h"
2 #include "Variable/VariableSynchronizationGroup2.h"
2 3 #include <Common/containers.h>
3 4 #include <Common/debug.h>
4 5 #include <Data/DataProviderParameters.h>
5 6
6 7 class VariableController2::VariableController2Private
7 8 {
8 9 std::set<std::shared_ptr<Variable>> _variables;
9 10 QMap<QUuid,std::shared_ptr<IDataProvider>> _providers;
11 QMap<QUuid,std::shared_ptr<VariableSynchronizationGroup2>> _synchronizationGroups;
10 12 public:
11 13 VariableController2Private(QObject* parent=Q_NULLPTR)
12 14 {
13 15 Q_UNUSED(parent);
14 16 }
15 17
16 18 ~VariableController2Private() = default;
17 19
18 20 std::shared_ptr<Variable> createVariable(const QString &name, const QVariantHash &metadata, std::shared_ptr<IDataProvider> provider, const DateTimeRange &range)
19 21 {
20 22 auto newVar = std::make_shared<Variable>(name,metadata);
21 23 this->_variables.insert(newVar);
22 24 this->_providers[newVar->ID()] = provider;
25 this->_synchronizationGroups[newVar->ID()] = std::make_shared<VariableSynchronizationGroup2>(newVar->ID());
23 26 return newVar;
24 27 }
25 28
26 29 void deleteVariable(std::shared_ptr<Variable> variable)
27 30 {
28 31 if(this->_providers.contains(variable->ID()))
29 32 this->_providers.remove(variable->ID());
30 33 if(SciQLop::containers::contains(this->_variables, variable))
31 34 this->_variables.erase(variable);
32 35 }
33 36
34 37 void changeRange(std::shared_ptr<Variable> variable, DateTimeRange r)
35 38 {
36 39 if(_providers.contains(variable->ID()))
37 40 {
38 41 auto provider = _providers[variable->ID()];
39 42 auto data = provider->getData(DataProviderParameters{{r},variable->metadata()});
40 43 variable->mergeDataSeries(data);
41 44 }
42 45 else
43 46 {
44 47 SCIQLOP_ERROR("No provider found for given variable");
45 48 }
46 49 }
47 50
48 51
49 52 const std::set<std::shared_ptr<Variable>>& variables()
50 53 {
51 54 return _variables;
52 55 }
53 56
54 57 };
55 58
56 59 VariableController2::VariableController2()
57 60 :impl{spimpl::make_unique_impl<VariableController2Private>()}
58 61 {}
59 62
60 63 std::shared_ptr<Variable> VariableController2::createVariable(const QString &name, const QVariantHash &metadata, std::shared_ptr<IDataProvider> provider, const DateTimeRange &range)
61 64 {
62 65 auto var = impl->createVariable(name, metadata, provider, range);
63 66 emit variableAdded(var);
64 67 impl->changeRange(var,range);
65 68 return var;
66 69 }
67 70
68 71 void VariableController2::deleteVariable(std::shared_ptr<Variable> variable)
69 72 {
70 73 impl->deleteVariable(variable);
71 74 emit variableDeleted(variable);
72 75 }
73 76
74 77 void VariableController2::changeRange(std::shared_ptr<Variable> variable, DateTimeRange r)
75 78 {
76 79 impl->changeRange(variable, r);
77 80 }
78 81
79 82 const std::set<std::shared_ptr<Variable> > &VariableController2::variables()
80 83 {
81 84 return impl->variables();
82 85 }
83 86
@@ -1,126 +1,126
1 1 #include <pybind11/pybind11.h>
2 2 #include <pybind11/operators.h>
3 3 #include <pybind11/embed.h>
4 4 #include <pybind11/numpy.h>
5 5 #include <pybind11/chrono.h>
6 6 #include <pybind11/functional.h>
7 7
8 8 #include <string>
9 9 #include <sstream>
10 10
11 11 #include "pywrappers_common.h"
12 12 #include "CoreWrappers.h"
13 13
14 14 #include <Data/DataSeriesType.h>
15 15 #include <Data/ScalarSeries.h>
16 16 #include <Data/VectorSeries.h>
17 17 #include <Data/Unit.h>
18 18 #include <Data/IDataProvider.h>
19 19
20 20 #include <Variable/VariableController.h>
21 21
22 22 #include <Time/TimeController.h>
23 23
24 24 #include <Network/Downloader.h>
25 25
26 26
27 27
28 28 namespace py = pybind11;
29 29 using namespace std::chrono;
30 30
31 31 PYBIND11_MODULE(pysciqlopcore,m){
32 32
33 33 py::enum_<DataSeriesType>(m, "DataSeriesType")
34 34 .value("SCALAR", DataSeriesType::SCALAR)
35 35 .value("SPECTROGRAM", DataSeriesType::SPECTROGRAM)
36 36 .value("UNKNOWN", DataSeriesType::UNKNOWN)
37 37 .export_values();
38 38
39 39 py::class_<Unit>(m, "Unit")
40 40 .def_readwrite("name", &Unit::m_Name)
41 41 .def_readwrite("time_unit", &Unit::m_TimeUnit)
42 42 .def(py::self == py::self)
43 43 .def(py::self != py::self)
44 44 .def("__repr__",__repr__<Unit>);
45 45
46 46 py::class_<Response>(m,"Response")
47 47 .def("status_code", &Response::status_code);
48 48
49 49 py::class_<Downloader>(m,"Downloader")
50 50 .def_static("get", Downloader::get)
51 51 .def_static("getAsync", Downloader::getAsync)
52 52 .def_static("downloadFinished", Downloader::downloadFinished);
53 53
54 54 py::class_<DataSeriesIteratorValue>(m,"DataSeriesIteratorValue")
55 55 .def_property_readonly("x", &DataSeriesIteratorValue::x)
56 56 .def("value", py::overload_cast<>(&DataSeriesIteratorValue::value, py::const_))
57 57 .def("value", py::overload_cast<int>(&DataSeriesIteratorValue::value, py::const_));
58 58
59 59 py::class_<IDataSeries, std::shared_ptr<IDataSeries>>(m, "IDataSeries")
60 60 .def("nbPoints", &IDataSeries::nbPoints)
61 61 .def_property_readonly("xAxisUnit", &IDataSeries::xAxisUnit)
62 62 .def_property_readonly("yAxisUnit", &IDataSeries::yAxisUnit)
63 63 .def_property_readonly("valuesUnit", &IDataSeries::valuesUnit)
64 64 .def("__getitem__", [](IDataSeries& serie, int key) {
65 65 return *(serie.begin()+key);
66 66 }, py::is_operator())
67 67 .def("__len__", &IDataSeries::nbPoints)
68 68 .def("__iter__", [](IDataSeries& serie) {
69 69 return py::make_iterator(serie.begin(), serie.end());
70 70 }, py::keep_alive<0, 1>())
71 71 .def("__repr__",__repr__<IDataSeries>);
72 72
73 73 py::class_<ScalarSeries, std::shared_ptr<ScalarSeries>, IDataSeries>(m, "ScalarSeries")
74 74 .def("nbPoints", &ScalarSeries::nbPoints);
75 75
76 76 py::class_<VectorSeries, std::shared_ptr<VectorSeries>, IDataSeries>(m, "VectorSeries")
77 77 .def("nbPoints", &VectorSeries::nbPoints);
78 78
79 79
80 80 py::class_<IDataProvider, std::shared_ptr<IDataProvider>>(m, "IDataProvider");
81 81
82 82
83 83 py::class_<Variable,std::shared_ptr<Variable>>(m, "Variable")
84 84 .def(py::init<const QString&>())
85 85 .def_property("name", &Variable::name, &Variable::setName)
86 86 .def_property("range", &Variable::range, &Variable::setRange)
87 87 .def_property("cacheRange", &Variable::cacheRange, &Variable::setCacheRange)
88 88 .def_property_readonly("nbPoints", &Variable::nbPoints)
89 89 .def_property_readonly("dataSeries", &Variable::dataSeries)
90 90 .def("__len__", [](Variable& variable) {
91 91 auto rng = variable.dataSeries()->xAxisRange(variable.range().m_TStart,variable.range().m_TEnd);
92 92 return std::distance(rng.first,rng.second);
93 93 })
94 94 .def("__iter__", [](Variable& variable) {
95 95 auto rng = variable.dataSeries()->xAxisRange(variable.range().m_TStart,variable.range().m_TEnd);
96 96 return py::make_iterator(rng.first, rng.second);
97 97 }, py::keep_alive<0, 1>())
98 98 .def("__getitem__", [](Variable& variable, int key) {
99 99 //insane and slow!
100 100 auto rng = variable.dataSeries()->xAxisRange(variable.range().m_TStart,variable.range().m_TEnd);
101 101 if(key<0)
102 102 return *(rng.second+key);
103 103 else
104 104 return *(rng.first+key);
105 105 })
106 106 .def("__repr__",__repr__<Variable>);
107 107
108 108
109 109 py::class_<DateTimeRange>(m,"SqpRange")
110 .def("fromDateTime", &DateTimeRange::fromDateTime, py::return_value_policy::move)
110 //.def("fromDateTime", &DateTimeRange::fromDateTime, py::return_value_policy::move)
111 111 .def(py::init([](double start, double stop){return DateTimeRange{start, stop};}))
112 112 .def(py::init([](system_clock::time_point start, system_clock::time_point stop)
113 113 {
114 114 double start_ = 0.001 * duration_cast<milliseconds>(start.time_since_epoch()).count();
115 115 double stop_ = 0.001 * duration_cast<milliseconds>(stop.time_since_epoch()).count();
116 116 return DateTimeRange{start_, stop_};
117 117 }))
118 118 .def_property_readonly("start", [](const DateTimeRange& range){
119 119 return system_clock::from_time_t(range.m_TStart);
120 120 })
121 121 .def_property_readonly("stop", [](const DateTimeRange& range){
122 122 return system_clock::from_time_t(range.m_TEnd);
123 123 })
124 124 .def("__repr__", __repr__<DateTimeRange>);
125 125
126 126 }
@@ -1,46 +1,48
1 1 add_definitions(-DCORE_TESTS_RESOURCES_DIR="${CMAKE_CURRENT_LIST_DIR}/../tests-resources")
2 2
3 3 FILE (GLOB_RECURSE TestUtilsSources
4 4 TestUtils/TestProviders.h
5 5 TestUtils/TestProviders.cpp
6 6 )
7 7
8 8 add_library(TestUtils ${TestUtilsSources})
9 9 target_link_libraries(TestUtils sciqlopcore Qt5::Test)
10 10
11 11 declare_test(TestStringUtils TestStringUtils Common/TestStringUtils.cpp "sciqlopcore;Qt5::Test")
12 12
13 13 declare_test(TestContainers TestContainers Common/TestContainers.cpp "sciqlopcore;Qt5::Test")
14 14 declare_test(TestSyncGroup TestSyncGroup Variable/TestSyncGroup.cpp "sciqlopcore;Qt5::Test")
15 15
16 declare_test(TestDateTimeRange TestDateTimeRange Data/TestDateTimeRange.cpp "sciqlopcore;Qt5::Test")
17
16 18
17 19 declare_test(TestDataSeriesUtils TestDataSeriesUtils Data/TestDataSeriesUtils.cpp "sciqlopcore;Qt5::Test")
18 20 declare_test(TestOptionalAxis TestOptionalAxis Data/TestOptionalAxis.cpp "sciqlopcore;Qt5::Test")
19 21 declare_test(TestSpectrogramSeries TestSpectrogramSeries
20 22 "Data/TestSpectrogramSeries.cpp;Data/DataSeriesBuilders.h;Data/DataSeriesBuilders.cpp;Data/DataSeriesTestsUtils.h;Data/DataSeriesTestsUtils.cpp"
21 23 "sciqlopcore;Qt5::Test")
22 24 declare_test(TestOneDimArrayData TestOneDimArrayData Data/TestOneDimArrayData.cpp "sciqlopcore;Qt5::Test")
23 25 declare_test(TestScalarSeries TestScalarSeries
24 26 "Data/TestScalarSeries.cpp;Data/DataSeriesBuilders.h;Data/DataSeriesBuilders.cpp;Data/DataSeriesTestsUtils.h;Data/DataSeriesTestsUtils.cpp"
25 27 "sciqlopcore;Qt5::Test")
26 28 declare_test(TestTwoDimArrayData TestTwoDimArrayData Data/TestTwoDimArrayData.cpp "sciqlopcore;Qt5::Test")
27 29 declare_test(TestVectorSeries TestVectorSeries
28 30 "Data/TestVectorSeries.cpp;Data/DataSeriesBuilders.h;Data/DataSeriesBuilders.cpp;Data/DataSeriesTestsUtils.h;Data/DataSeriesTestsUtils.cpp"
29 31 "sciqlopcore;Qt5::Test")
30 32
31 33 declare_test(TestDataSourceController TestDataSourceController
32 34 "DataSource/TestDataSourceController.cpp;DataSource/DataSourceItemBuilder.cpp"
33 35 "sciqlopcore;Qt5::Test")
34 36 declare_test(TestDataSourceItem TestDataSourceItem
35 37 "DataSource/TestDataSourceItem.cpp;DataSource/DataSourceItemBuilder.cpp"
36 38 "sciqlopcore;Qt5::Test")
37 39
38 40 declare_test(TestVariable TestVariable Variable/TestVariable.cpp "sciqlopcore;Qt5::Test")
39 41 declare_test(TestVariableCacheController TestVariableCacheController Variable/TestVariableCacheController.cpp "sciqlopcore;Qt5::Test")
40 42 declare_test(TestVariableController TestVariableController Variable/TestVariableController.cpp "sciqlopcore;Qt5::Test")
41 43 declare_test(TestVariableSync TestVariableSync Variable/TestVariableSync.cpp "sciqlopcore;Qt5::Test")
42 44
43 45 declare_test(TestDownloader TestDownloader Network/TestDownloader.cpp "sciqlopcore;Qt5::Test")
44 46
45 47
46 48 declare_test(TestVariableController2 TestVariableController2 Variable/TestVariableController2.cpp "sciqlopcore;TestUtils;Qt5::Test")
General Comments 0
You need to be logged in to leave comments. Login now