##// END OF EJS Templates
Fix bug when creating two variables crash the app. ...
perrinel -
r756:a7f60f6512e6
parent child
Show More
@@ -1,84 +1,83
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 QVariantHash &metadata = {});
29 const QVariantHash &metadata = {});
30
29
31 /// Copy ctor
30 /// Copy ctor
32 explicit Variable(const Variable &other);
31 explicit Variable(const Variable &other);
33
32
34 std::shared_ptr<Variable> clone() const;
33 std::shared_ptr<Variable> clone() const;
35
34
36 QString name() const noexcept;
35 QString name() const noexcept;
37 void setName(const QString &name) noexcept;
36 void setName(const QString &name) noexcept;
38 SqpRange range() const noexcept;
37 SqpRange range() const noexcept;
39 void setRange(const SqpRange &range) noexcept;
38 void setRange(const SqpRange &range) noexcept;
40 SqpRange cacheRange() const noexcept;
39 SqpRange cacheRange() const noexcept;
41 void setCacheRange(const SqpRange &cacheRange) noexcept;
40 void setCacheRange(const SqpRange &cacheRange) noexcept;
42
41
43 /// @return the number of points hold by the variable. The number of points is updated each time
42 /// @return the number of points hold by the variable. The number of points is updated each time
44 /// the data series changes
43 /// the data series changes
45 int nbPoints() const noexcept;
44 int nbPoints() const noexcept;
46
45
47 /// Returns the real range of the variable, i.e. the min and max x-axis values of the data
46 /// Returns the real range of the variable, i.e. the min and max x-axis values of the data
48 /// series between the range of the variable. The real range is updated each time the variable
47 /// series between the range of the variable. The real range is updated each time the variable
49 /// range or the data series changed
48 /// range or the data series changed
50 /// @return the real range, invalid range if the data series is null or empty
49 /// @return the real range, invalid range if the data series is null or empty
51 /// @sa setDataSeries()
50 /// @sa setDataSeries()
52 /// @sa setRange()
51 /// @sa setRange()
53 SqpRange realRange() const noexcept;
52 SqpRange realRange() const noexcept;
54
53
55 /// @return the data of the variable, nullptr if there is no data
54 /// @return the data of the variable, nullptr if there is no data
56 std::shared_ptr<IDataSeries> dataSeries() const noexcept;
55 std::shared_ptr<IDataSeries> dataSeries() const noexcept;
57
56
58 QVariantHash metadata() const noexcept;
57 QVariantHash metadata() const noexcept;
59
58
60 bool contains(const SqpRange &range) const noexcept;
59 bool contains(const SqpRange &range) const noexcept;
61 bool intersect(const SqpRange &range) const noexcept;
60 bool intersect(const SqpRange &range) const noexcept;
62 bool isInside(const SqpRange &range) const noexcept;
61 bool isInside(const SqpRange &range) const noexcept;
63
62
64 bool cacheContains(const SqpRange &range) const noexcept;
63 bool cacheContains(const SqpRange &range) const noexcept;
65 bool cacheIntersect(const SqpRange &range) const noexcept;
64 bool cacheIntersect(const SqpRange &range) const noexcept;
66 bool cacheIsInside(const SqpRange &range) const noexcept;
65 bool cacheIsInside(const SqpRange &range) const noexcept;
67
66
68 QVector<SqpRange> provideNotInCacheRangeList(const SqpRange &range) const noexcept;
67 QVector<SqpRange> provideNotInCacheRangeList(const SqpRange &range) const noexcept;
69 QVector<SqpRange> provideInCacheRangeList(const SqpRange &range) const noexcept;
68 QVector<SqpRange> provideInCacheRangeList(const SqpRange &range) const noexcept;
70 void mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept;
69 void mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept;
71
70
72 signals:
71 signals:
73 void updated();
72 void updated();
74
73
75 private:
74 private:
76 class VariablePrivate;
75 class VariablePrivate;
77 spimpl::unique_impl_ptr<VariablePrivate> impl;
76 spimpl::unique_impl_ptr<VariablePrivate> impl;
78 };
77 };
79
78
80 // Required for using shared_ptr in signals/slots
79 // Required for using shared_ptr in signals/slots
81 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_REGISTRY, std::shared_ptr<Variable>)
80 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_REGISTRY, std::shared_ptr<Variable>)
82 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_VECTOR_REGISTRY, QVector<std::shared_ptr<Variable> >)
81 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_VECTOR_REGISTRY, QVector<std::shared_ptr<Variable> >)
83
82
84 #endif // SCIQLOP_VARIABLE_H
83 #endif // SCIQLOP_VARIABLE_H
@@ -1,96 +1,95
1 #ifndef SCIQLOP_VARIABLEMODEL_H
1 #ifndef SCIQLOP_VARIABLEMODEL_H
2 #define SCIQLOP_VARIABLEMODEL_H
2 #define SCIQLOP_VARIABLEMODEL_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Data/SqpRange.h>
6 #include <Data/SqpRange.h>
7
7
8 #include <QAbstractTableModel>
8 #include <QAbstractTableModel>
9 #include <QLoggingCategory>
9 #include <QLoggingCategory>
10
10
11 #include <Common/MetaTypes.h>
11 #include <Common/MetaTypes.h>
12 #include <Common/spimpl.h>
12 #include <Common/spimpl.h>
13
13
14 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableModel)
14 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableModel)
15
15
16 enum VariableRoles { ProgressRole = Qt::UserRole };
16 enum VariableRoles { ProgressRole = Qt::UserRole };
17
17
18
18
19 class IDataSeries;
19 class IDataSeries;
20 class Variable;
20 class Variable;
21
21
22 /**
22 /**
23 * @brief The VariableModel class aims to hold the variables that have been created in SciQlop
23 * @brief The VariableModel class aims to hold the variables that have been created in SciQlop
24 */
24 */
25 class SCIQLOP_CORE_EXPORT VariableModel : public QAbstractTableModel {
25 class SCIQLOP_CORE_EXPORT VariableModel : public QAbstractTableModel {
26 Q_OBJECT
26 Q_OBJECT
27 public:
27 public:
28 explicit VariableModel(QObject *parent = nullptr);
28 explicit VariableModel(QObject *parent = nullptr);
29
29
30 /**
30 /**
31 * Adds an existing variable in the model.
31 * Adds an existing variable in the model.
32 * @param variable the variable to add.
32 * @param variable the variable to add.
33 * @remarks the variable's name is modified to avoid name duplicates
33 * @remarks the variable's name is modified to avoid name duplicates
34 * @remarks this method does nothing if the variable already exists in the model
34 * @remarks this method does nothing if the variable already exists in the model
35 */
35 */
36 void addVariable(std::shared_ptr<Variable> variable) noexcept;
36 void addVariable(std::shared_ptr<Variable> variable) noexcept;
37
37
38 /**
38 /**
39 * Checks that a variable is contained in the model
39 * Checks that a variable is contained in the model
40 * @param variable the variable to check
40 * @param variable the variable to check
41 * @return true if the variable is in the model, false otherwise
41 * @return true if the variable is in the model, false otherwise
42 */
42 */
43 bool containsVariable(std::shared_ptr<Variable> variable) const noexcept;
43 bool containsVariable(std::shared_ptr<Variable> variable) const noexcept;
44
44
45 /**
45 /**
46 * Creates a new variable in the model
46 * Creates a new variable in the model
47 * @param name the name of the new variable
47 * @param name the name of the new variable
48 * @param dateTime the dateTime of the new variable
49 * @param metadata the metadata associated to the new variable
48 * @param metadata the metadata associated to the new variable
50 * @return the pointer to the new variable
49 * @return the pointer to the new variable
51 */
50 */
52 std::shared_ptr<Variable> createVariable(const QString &name, const SqpRange &dateTime,
51 std::shared_ptr<Variable> createVariable(const QString &name,
53 const QVariantHash &metadata) noexcept;
52 const QVariantHash &metadata) noexcept;
54
53
55 /**
54 /**
56 * Deletes a variable from the model, if it exists
55 * Deletes a variable from the model, if it exists
57 * @param variable the variable to delete
56 * @param variable the variable to delete
58 */
57 */
59 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
58 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
60
59
61
60
62 std::shared_ptr<Variable> variable(int index) const;
61 std::shared_ptr<Variable> variable(int index) const;
63 std::vector<std::shared_ptr<Variable> > variables() const;
62 std::vector<std::shared_ptr<Variable> > variables() const;
64
63
65 void setDataProgress(std::shared_ptr<Variable> variable, double progress);
64 void setDataProgress(std::shared_ptr<Variable> variable, double progress);
66
65
67
66
68 // /////////////////////////// //
67 // /////////////////////////// //
69 // QAbstractTableModel methods //
68 // QAbstractTableModel methods //
70 // /////////////////////////// //
69 // /////////////////////////// //
71
70
72 virtual int columnCount(const QModelIndex &parent = QModelIndex{}) const override;
71 virtual int columnCount(const QModelIndex &parent = QModelIndex{}) const override;
73 virtual int rowCount(const QModelIndex &parent = QModelIndex{}) const override;
72 virtual int rowCount(const QModelIndex &parent = QModelIndex{}) const override;
74 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
73 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
75 virtual QVariant headerData(int section, Qt::Orientation orientation,
74 virtual QVariant headerData(int section, Qt::Orientation orientation,
76 int role = Qt::DisplayRole) const override;
75 int role = Qt::DisplayRole) const override;
77
76
78
77
79 void abortProgress(const QModelIndex &index);
78 void abortProgress(const QModelIndex &index);
80
79
81 signals:
80 signals:
82 void abortProgessRequested(std::shared_ptr<Variable> variable);
81 void abortProgessRequested(std::shared_ptr<Variable> variable);
83
82
84 private:
83 private:
85 class VariableModelPrivate;
84 class VariableModelPrivate;
86 spimpl::unique_impl_ptr<VariableModelPrivate> impl;
85 spimpl::unique_impl_ptr<VariableModelPrivate> impl;
87
86
88 private slots:
87 private slots:
89 /// Slot called when data of a variable has been updated
88 /// Slot called when data of a variable has been updated
90 void onVariableUpdated() noexcept;
89 void onVariableUpdated() noexcept;
91 };
90 };
92
91
93 // Registers QVector<int> metatype so it can be used in VariableModel::dataChanged() signal
92 // Registers QVector<int> metatype so it can be used in VariableModel::dataChanged() signal
94 SCIQLOP_REGISTER_META_TYPE(QVECTOR_INT_REGISTRY, QVector<int>)
93 SCIQLOP_REGISTER_META_TYPE(QVECTOR_INT_REGISTRY, QVector<int>)
95
94
96 #endif // SCIQLOP_VARIABLEMODEL_H
95 #endif // SCIQLOP_VARIABLEMODEL_H
@@ -1,307 +1,315
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 QVariantHash &metadata)
14 const QVariantHash &metadata)
15 : m_Name{name},
14 : m_Name{name},
16 m_Range{dateTime},
15 m_Range{INVALID_RANGE},
16 m_CacheRange{INVALID_RANGE},
17 m_Metadata{metadata},
17 m_Metadata{metadata},
18 m_DataSeries{nullptr},
18 m_DataSeries{nullptr},
19 m_RealRange{INVALID_RANGE},
19 m_RealRange{INVALID_RANGE},
20 m_NbPoints{0}
20 m_NbPoints{0}
21 {
21 {
22 }
22 }
23
23
24 VariablePrivate(const VariablePrivate &other)
24 VariablePrivate(const VariablePrivate &other)
25 : m_Name{other.m_Name},
25 : m_Name{other.m_Name},
26 m_Range{other.m_Range},
26 m_Range{other.m_Range},
27 m_CacheRange{other.m_CacheRange},
27 m_Metadata{other.m_Metadata},
28 m_Metadata{other.m_Metadata},
28 m_DataSeries{other.m_DataSeries != nullptr ? other.m_DataSeries->clone() : nullptr},
29 m_DataSeries{other.m_DataSeries != nullptr ? other.m_DataSeries->clone() : nullptr},
29 m_RealRange{other.m_RealRange},
30 m_RealRange{other.m_RealRange},
30 m_NbPoints{other.m_NbPoints}
31 m_NbPoints{other.m_NbPoints}
31 {
32 {
32 }
33 }
33
34
34 void lockRead() { m_Lock.lockForRead(); }
35 void lockRead() { m_Lock.lockForRead(); }
35 void lockWrite() { m_Lock.lockForWrite(); }
36 void lockWrite() { m_Lock.lockForWrite(); }
36 void unlock() { m_Lock.unlock(); }
37 void unlock() { m_Lock.unlock(); }
37
38
38 void purgeDataSeries()
39 void purgeDataSeries()
39 {
40 {
40 if (m_DataSeries) {
41 if (m_DataSeries) {
41 m_DataSeries->purge(m_CacheRange.m_TStart, m_CacheRange.m_TEnd);
42 m_DataSeries->purge(m_CacheRange.m_TStart, m_CacheRange.m_TEnd);
42 }
43 }
43 updateRealRange();
44 updateRealRange();
44 updateNbPoints();
45 updateNbPoints();
45 }
46 }
46
47
47 void updateNbPoints() { m_NbPoints = m_DataSeries ? m_DataSeries->nbPoints() : 0; }
48 void updateNbPoints() { m_NbPoints = m_DataSeries ? m_DataSeries->nbPoints() : 0; }
48
49
49 /// Updates real range according to current variable range and data series
50 /// Updates real range according to current variable range and data series
50 void updateRealRange()
51 void updateRealRange()
51 {
52 {
52 if (m_DataSeries) {
53 if (m_DataSeries) {
53 m_DataSeries->lockRead();
54 m_DataSeries->lockRead();
54 auto end = m_DataSeries->cend();
55 auto end = m_DataSeries->cend();
55 auto minXAxisIt = m_DataSeries->minXAxisData(m_Range.m_TStart);
56 auto minXAxisIt = m_DataSeries->minXAxisData(m_Range.m_TStart);
56 auto maxXAxisIt = m_DataSeries->maxXAxisData(m_Range.m_TEnd);
57 auto maxXAxisIt = m_DataSeries->maxXAxisData(m_Range.m_TEnd);
57
58
58 m_RealRange = (minXAxisIt != end && maxXAxisIt != end)
59 m_RealRange
60 = (minXAxisIt != end && maxXAxisIt != end && minXAxisIt->x() <= maxXAxisIt->x())
59 ? SqpRange{minXAxisIt->x(), maxXAxisIt->x()}
61 ? SqpRange{minXAxisIt->x(), maxXAxisIt->x()}
60 : INVALID_RANGE;
62 : INVALID_RANGE;
61 m_DataSeries->unlock();
63 m_DataSeries->unlock();
62 }
64 }
63 else {
65 else {
64 m_RealRange = INVALID_RANGE;
66 m_RealRange = INVALID_RANGE;
65 }
67 }
66 }
68 }
67
69
68 QString m_Name;
70 QString m_Name;
69
71
70 SqpRange m_Range;
72 SqpRange m_Range;
71 SqpRange m_CacheRange;
73 SqpRange m_CacheRange;
72 QVariantHash m_Metadata;
74 QVariantHash m_Metadata;
73 std::shared_ptr<IDataSeries> m_DataSeries;
75 std::shared_ptr<IDataSeries> m_DataSeries;
74 SqpRange m_RealRange;
76 SqpRange m_RealRange;
75 int m_NbPoints;
77 int m_NbPoints;
76
78
77 QReadWriteLock m_Lock;
79 QReadWriteLock m_Lock;
78 };
80 };
79
81
80 Variable::Variable(const QString &name, const SqpRange &dateTime, const QVariantHash &metadata)
82 Variable::Variable(const QString &name, const QVariantHash &metadata)
81 : impl{spimpl::make_unique_impl<VariablePrivate>(name, dateTime, metadata)}
83 : impl{spimpl::make_unique_impl<VariablePrivate>(name, metadata)}
82 {
84 {
83 }
85 }
84
86
85 Variable::Variable(const Variable &other)
87 Variable::Variable(const Variable &other)
86 : impl{spimpl::make_unique_impl<VariablePrivate>(*other.impl)}
88 : impl{spimpl::make_unique_impl<VariablePrivate>(*other.impl)}
87 {
89 {
88 }
90 }
89
91
90 std::shared_ptr<Variable> Variable::clone() const
92 std::shared_ptr<Variable> Variable::clone() const
91 {
93 {
92 return std::make_shared<Variable>(*this);
94 return std::make_shared<Variable>(*this);
93 }
95 }
94
96
95 QString Variable::name() const noexcept
97 QString Variable::name() const noexcept
96 {
98 {
97 impl->lockRead();
99 impl->lockRead();
98 auto name = impl->m_Name;
100 auto name = impl->m_Name;
99 impl->unlock();
101 impl->unlock();
100 return name;
102 return name;
101 }
103 }
102
104
103 void Variable::setName(const QString &name) noexcept
105 void Variable::setName(const QString &name) noexcept
104 {
106 {
105 impl->lockWrite();
107 impl->lockWrite();
106 impl->m_Name = name;
108 impl->m_Name = name;
107 impl->unlock();
109 impl->unlock();
108 }
110 }
109
111
110 SqpRange Variable::range() const noexcept
112 SqpRange Variable::range() const noexcept
111 {
113 {
112 impl->lockRead();
114 impl->lockRead();
113 auto range = impl->m_Range;
115 auto range = impl->m_Range;
114 impl->unlock();
116 impl->unlock();
115 return range;
117 return range;
116 }
118 }
117
119
118 void Variable::setRange(const SqpRange &range) noexcept
120 void Variable::setRange(const SqpRange &range) noexcept
119 {
121 {
120 impl->lockWrite();
122 impl->lockWrite();
121 impl->m_Range = range;
123 impl->m_Range = range;
122 impl->updateRealRange();
124 impl->updateRealRange();
123 impl->unlock();
125 impl->unlock();
124 }
126 }
125
127
126 SqpRange Variable::cacheRange() const noexcept
128 SqpRange Variable::cacheRange() const noexcept
127 {
129 {
128 impl->lockRead();
130 impl->lockRead();
129 auto cacheRange = impl->m_CacheRange;
131 auto cacheRange = impl->m_CacheRange;
130 impl->unlock();
132 impl->unlock();
131 return cacheRange;
133 return cacheRange;
132 }
134 }
133
135
134 void Variable::setCacheRange(const SqpRange &cacheRange) noexcept
136 void Variable::setCacheRange(const SqpRange &cacheRange) noexcept
135 {
137 {
136 impl->lockWrite();
138 impl->lockWrite();
137 if (cacheRange != impl->m_CacheRange) {
139 if (cacheRange != impl->m_CacheRange) {
138 impl->m_CacheRange = cacheRange;
140 impl->m_CacheRange = cacheRange;
139 impl->purgeDataSeries();
141 impl->purgeDataSeries();
140 }
142 }
141 impl->unlock();
143 impl->unlock();
142 }
144 }
143
145
144 int Variable::nbPoints() const noexcept
146 int Variable::nbPoints() const noexcept
145 {
147 {
146 return impl->m_NbPoints;
148 return impl->m_NbPoints;
147 }
149 }
148
150
149 SqpRange Variable::realRange() const noexcept
151 SqpRange Variable::realRange() const noexcept
150 {
152 {
151 return impl->m_RealRange;
153 return impl->m_RealRange;
152 }
154 }
153
155
154 void Variable::mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
156 void Variable::mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
155 {
157 {
156 qCDebug(LOG_Variable()) << "TORM Variable::mergeDataSeries"
158 qCDebug(LOG_Variable()) << "TORM Variable::mergeDataSeries"
157 << QThread::currentThread()->objectName();
159 << QThread::currentThread()->objectName();
158 if (!dataSeries) {
160 if (!dataSeries) {
159 /// @todo ALX : log
161 /// @todo ALX : log
160 return;
162 return;
161 }
163 }
162
164
163 // Add or merge the data
165 // Add or merge the data
164 impl->lockWrite();
166 impl->lockWrite();
165 if (!impl->m_DataSeries) {
167 if (!impl->m_DataSeries) {
166 impl->m_DataSeries = dataSeries->clone();
168 impl->m_DataSeries = dataSeries->clone();
167 }
169 }
168 else {
170 else {
169 impl->m_DataSeries->merge(dataSeries.get());
171 impl->m_DataSeries->merge(dataSeries.get());
170 }
172 }
171 impl->purgeDataSeries();
173 impl->purgeDataSeries();
172 impl->unlock();
174 impl->unlock();
173 }
175 }
174
176
175 std::shared_ptr<IDataSeries> Variable::dataSeries() const noexcept
177 std::shared_ptr<IDataSeries> Variable::dataSeries() const noexcept
176 {
178 {
177 impl->lockRead();
179 impl->lockRead();
178 auto dataSeries = impl->m_DataSeries;
180 auto dataSeries = impl->m_DataSeries;
179 impl->unlock();
181 impl->unlock();
180
182
181 return dataSeries;
183 return dataSeries;
182 }
184 }
183
185
184 QVariantHash Variable::metadata() const noexcept
186 QVariantHash Variable::metadata() const noexcept
185 {
187 {
186 impl->lockRead();
188 impl->lockRead();
187 auto metadata = impl->m_Metadata;
189 auto metadata = impl->m_Metadata;
188 impl->unlock();
190 impl->unlock();
189 return metadata;
191 return metadata;
190 }
192 }
191
193
192 bool Variable::contains(const SqpRange &range) const noexcept
194 bool Variable::contains(const SqpRange &range) const noexcept
193 {
195 {
194 impl->lockRead();
196 impl->lockRead();
195 auto res = impl->m_Range.contains(range);
197 auto res = impl->m_Range.contains(range);
196 impl->unlock();
198 impl->unlock();
197 return res;
199 return res;
198 }
200 }
199
201
200 bool Variable::intersect(const SqpRange &range) const noexcept
202 bool Variable::intersect(const SqpRange &range) const noexcept
201 {
203 {
202
204
203 impl->lockRead();
205 impl->lockRead();
204 auto res = impl->m_Range.intersect(range);
206 auto res = impl->m_Range.intersect(range);
205 impl->unlock();
207 impl->unlock();
206 return res;
208 return res;
207 }
209 }
208
210
209 bool Variable::isInside(const SqpRange &range) const noexcept
211 bool Variable::isInside(const SqpRange &range) const noexcept
210 {
212 {
211 impl->lockRead();
213 impl->lockRead();
212 auto res = range.contains(SqpRange{impl->m_Range.m_TStart, impl->m_Range.m_TEnd});
214 auto res = range.contains(SqpRange{impl->m_Range.m_TStart, impl->m_Range.m_TEnd});
213 impl->unlock();
215 impl->unlock();
214 return res;
216 return res;
215 }
217 }
216
218
217 bool Variable::cacheContains(const SqpRange &range) const noexcept
219 bool Variable::cacheContains(const SqpRange &range) const noexcept
218 {
220 {
219 impl->lockRead();
221 impl->lockRead();
220 auto res = impl->m_CacheRange.contains(range);
222 auto res = impl->m_CacheRange.contains(range);
221 impl->unlock();
223 impl->unlock();
222 return res;
224 return res;
223 }
225 }
224
226
225 bool Variable::cacheIntersect(const SqpRange &range) const noexcept
227 bool Variable::cacheIntersect(const SqpRange &range) const noexcept
226 {
228 {
227 impl->lockRead();
229 impl->lockRead();
228 auto res = impl->m_CacheRange.intersect(range);
230 auto res = impl->m_CacheRange.intersect(range);
229 impl->unlock();
231 impl->unlock();
230 return res;
232 return res;
231 }
233 }
232
234
233 bool Variable::cacheIsInside(const SqpRange &range) const noexcept
235 bool Variable::cacheIsInside(const SqpRange &range) const noexcept
234 {
236 {
235 impl->lockRead();
237 impl->lockRead();
236 auto res = range.contains(SqpRange{impl->m_CacheRange.m_TStart, impl->m_CacheRange.m_TEnd});
238 auto res = range.contains(SqpRange{impl->m_CacheRange.m_TStart, impl->m_CacheRange.m_TEnd});
237 impl->unlock();
239 impl->unlock();
238 return res;
240 return res;
239 }
241 }
240
242
241
243
242 QVector<SqpRange> Variable::provideNotInCacheRangeList(const SqpRange &range) const noexcept
244 QVector<SqpRange> Variable::provideNotInCacheRangeList(const SqpRange &range) const noexcept
243 {
245 {
244 // This code assume that cach in contigue. Can return 0, 1 or 2 SqpRange
246 // This code assume that cach in contigue. Can return 0, 1 or 2 SqpRange
245
246 auto notInCache = QVector<SqpRange>{};
247 auto notInCache = QVector<SqpRange>{};
248 if (impl->m_CacheRange != INVALID_RANGE) {
247
249
248 if (!this->cacheContains(range)) {
250 if (!this->cacheContains(range)) {
249 if (range.m_TEnd <= impl->m_CacheRange.m_TStart
251 if (range.m_TEnd <= impl->m_CacheRange.m_TStart
250 || range.m_TStart >= impl->m_CacheRange.m_TEnd) {
252 || range.m_TStart >= impl->m_CacheRange.m_TEnd) {
251 notInCache << range;
253 notInCache << range;
252 }
254 }
253 else if (range.m_TStart < impl->m_CacheRange.m_TStart
255 else if (range.m_TStart < impl->m_CacheRange.m_TStart
254 && range.m_TEnd <= impl->m_CacheRange.m_TEnd) {
256 && range.m_TEnd <= impl->m_CacheRange.m_TEnd) {
255 notInCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TStart};
257 notInCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TStart};
256 }
258 }
257 else if (range.m_TStart < impl->m_CacheRange.m_TStart
259 else if (range.m_TStart < impl->m_CacheRange.m_TStart
258 && range.m_TEnd > impl->m_CacheRange.m_TEnd) {
260 && range.m_TEnd > impl->m_CacheRange.m_TEnd) {
259 notInCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TStart}
261 notInCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TStart}
260 << SqpRange{impl->m_CacheRange.m_TEnd, range.m_TEnd};
262 << SqpRange{impl->m_CacheRange.m_TEnd, range.m_TEnd};
261 }
263 }
262 else if (range.m_TStart < impl->m_CacheRange.m_TEnd) {
264 else if (range.m_TStart < impl->m_CacheRange.m_TEnd) {
263 notInCache << SqpRange{impl->m_CacheRange.m_TEnd, range.m_TEnd};
265 notInCache << SqpRange{impl->m_CacheRange.m_TEnd, range.m_TEnd};
264 }
266 }
265 else {
267 else {
266 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
268 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
267 << QThread::currentThread();
269 << QThread::currentThread();
268 }
270 }
269 }
271 }
272 }
273 else {
274 notInCache << range;
275 }
270
276
271 return notInCache;
277 return notInCache;
272 }
278 }
273
279
274 QVector<SqpRange> Variable::provideInCacheRangeList(const SqpRange &range) const noexcept
280 QVector<SqpRange> Variable::provideInCacheRangeList(const SqpRange &range) const noexcept
275 {
281 {
276 // This code assume that cach in contigue. Can return 0 or 1 SqpRange
282 // This code assume that cach in contigue. Can return 0 or 1 SqpRange
277
283
278 auto inCache = QVector<SqpRange>{};
284 auto inCache = QVector<SqpRange>{};
279
285
286 if (impl->m_CacheRange != INVALID_RANGE) {
280
287
281 if (this->intersect(range)) {
288 if (this->intersect(range)) {
282 if (range.m_TStart <= impl->m_CacheRange.m_TStart
289 if (range.m_TStart <= impl->m_CacheRange.m_TStart
283 && range.m_TEnd >= impl->m_CacheRange.m_TStart
290 && range.m_TEnd >= impl->m_CacheRange.m_TStart
284 && range.m_TEnd < impl->m_CacheRange.m_TEnd) {
291 && range.m_TEnd < impl->m_CacheRange.m_TEnd) {
285 inCache << SqpRange{impl->m_CacheRange.m_TStart, range.m_TEnd};
292 inCache << SqpRange{impl->m_CacheRange.m_TStart, range.m_TEnd};
286 }
293 }
287
294
288 else if (range.m_TStart >= impl->m_CacheRange.m_TStart
295 else if (range.m_TStart >= impl->m_CacheRange.m_TStart
289 && range.m_TEnd <= impl->m_CacheRange.m_TEnd) {
296 && range.m_TEnd <= impl->m_CacheRange.m_TEnd) {
290 inCache << range;
297 inCache << range;
291 }
298 }
292 else if (range.m_TStart > impl->m_CacheRange.m_TStart
299 else if (range.m_TStart > impl->m_CacheRange.m_TStart
293 && range.m_TEnd > impl->m_CacheRange.m_TEnd) {
300 && range.m_TEnd > impl->m_CacheRange.m_TEnd) {
294 inCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TEnd};
301 inCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TEnd};
295 }
302 }
296 else if (range.m_TStart <= impl->m_CacheRange.m_TStart
303 else if (range.m_TStart <= impl->m_CacheRange.m_TStart
297 && range.m_TEnd >= impl->m_CacheRange.m_TEnd) {
304 && range.m_TEnd >= impl->m_CacheRange.m_TEnd) {
298 inCache << impl->m_CacheRange;
305 inCache << impl->m_CacheRange;
299 }
306 }
300 else {
307 else {
301 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
308 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
302 << QThread::currentThread();
309 << QThread::currentThread();
303 }
310 }
304 }
311 }
312 }
305
313
306 return inCache;
314 return inCache;
307 }
315 }
@@ -1,814 +1,813
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableAcquisitionWorker.h>
2 #include <Variable/VariableAcquisitionWorker.h>
3 #include <Variable/VariableCacheStrategy.h>
3 #include <Variable/VariableCacheStrategy.h>
4 #include <Variable/VariableController.h>
4 #include <Variable/VariableController.h>
5 #include <Variable/VariableModel.h>
5 #include <Variable/VariableModel.h>
6 #include <Variable/VariableSynchronizationGroup.h>
6 #include <Variable/VariableSynchronizationGroup.h>
7
7
8 #include <Data/DataProviderParameters.h>
8 #include <Data/DataProviderParameters.h>
9 #include <Data/IDataProvider.h>
9 #include <Data/IDataProvider.h>
10 #include <Data/IDataSeries.h>
10 #include <Data/IDataSeries.h>
11 #include <Data/VariableRequest.h>
11 #include <Data/VariableRequest.h>
12 #include <Time/TimeController.h>
12 #include <Time/TimeController.h>
13
13
14 #include <QMutex>
14 #include <QMutex>
15 #include <QThread>
15 #include <QThread>
16 #include <QUuid>
16 #include <QUuid>
17 #include <QtCore/QItemSelectionModel>
17 #include <QtCore/QItemSelectionModel>
18
18
19 #include <deque>
19 #include <deque>
20 #include <set>
20 #include <set>
21 #include <unordered_map>
21 #include <unordered_map>
22
22
23 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
23 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
24
24
25 namespace {
25 namespace {
26
26
27 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
27 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
28 const SqpRange &oldGraphRange)
28 const SqpRange &oldGraphRange)
29 {
29 {
30 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
30 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
31
31
32 auto varRangeRequested = varRange;
32 auto varRangeRequested = varRange;
33 switch (zoomType) {
33 switch (zoomType) {
34 case AcquisitionZoomType::ZoomIn: {
34 case AcquisitionZoomType::ZoomIn: {
35 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
35 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
36 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
36 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
37 varRangeRequested.m_TStart += deltaLeft;
37 varRangeRequested.m_TStart += deltaLeft;
38 varRangeRequested.m_TEnd -= deltaRight;
38 varRangeRequested.m_TEnd -= deltaRight;
39 break;
39 break;
40 }
40 }
41
41
42 case AcquisitionZoomType::ZoomOut: {
42 case AcquisitionZoomType::ZoomOut: {
43 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
43 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
44 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
44 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
45 varRangeRequested.m_TStart -= deltaLeft;
45 varRangeRequested.m_TStart -= deltaLeft;
46 varRangeRequested.m_TEnd += deltaRight;
46 varRangeRequested.m_TEnd += deltaRight;
47 break;
47 break;
48 }
48 }
49 case AcquisitionZoomType::PanRight: {
49 case AcquisitionZoomType::PanRight: {
50 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
50 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
51 varRangeRequested.m_TStart += deltaRight;
51 varRangeRequested.m_TStart += deltaRight;
52 varRangeRequested.m_TEnd += deltaRight;
52 varRangeRequested.m_TEnd += deltaRight;
53 break;
53 break;
54 }
54 }
55 case AcquisitionZoomType::PanLeft: {
55 case AcquisitionZoomType::PanLeft: {
56 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
56 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
57 varRangeRequested.m_TStart -= deltaLeft;
57 varRangeRequested.m_TStart -= deltaLeft;
58 varRangeRequested.m_TEnd -= deltaLeft;
58 varRangeRequested.m_TEnd -= deltaLeft;
59 break;
59 break;
60 }
60 }
61 case AcquisitionZoomType::Unknown: {
61 case AcquisitionZoomType::Unknown: {
62 qCCritical(LOG_VariableController())
62 qCCritical(LOG_VariableController())
63 << VariableController::tr("Impossible to synchronize: zoom type unknown");
63 << VariableController::tr("Impossible to synchronize: zoom type unknown");
64 break;
64 break;
65 }
65 }
66 default:
66 default:
67 qCCritical(LOG_VariableController()) << VariableController::tr(
67 qCCritical(LOG_VariableController()) << VariableController::tr(
68 "Impossible to synchronize: zoom type not take into account");
68 "Impossible to synchronize: zoom type not take into account");
69 // No action
69 // No action
70 break;
70 break;
71 }
71 }
72
72
73 return varRangeRequested;
73 return varRangeRequested;
74 }
74 }
75 }
75 }
76
76
77 struct VariableController::VariableControllerPrivate {
77 struct VariableController::VariableControllerPrivate {
78 explicit VariableControllerPrivate(VariableController *parent)
78 explicit VariableControllerPrivate(VariableController *parent)
79 : m_WorkingMutex{},
79 : m_WorkingMutex{},
80 m_VariableModel{new VariableModel{parent}},
80 m_VariableModel{new VariableModel{parent}},
81 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
81 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
82 m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
82 m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
83 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
83 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
84 q{parent}
84 q{parent}
85 {
85 {
86
86
87 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
87 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
88 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
88 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
89 }
89 }
90
90
91
91
92 virtual ~VariableControllerPrivate()
92 virtual ~VariableControllerPrivate()
93 {
93 {
94 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
94 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
95 m_VariableAcquisitionWorkerThread.quit();
95 m_VariableAcquisitionWorkerThread.quit();
96 m_VariableAcquisitionWorkerThread.wait();
96 m_VariableAcquisitionWorkerThread.wait();
97 }
97 }
98
98
99
99
100 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested,
100 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested,
101 QUuid varRequestId);
101 QUuid varRequestId);
102
102
103 QVector<SqpRange> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
103 QVector<SqpRange> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
104 const SqpRange &dateTime);
104 const SqpRange &dateTime);
105
105
106 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
106 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
107 std::shared_ptr<IDataSeries>
107 std::shared_ptr<IDataSeries>
108 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
108 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
109
109
110 void registerProvider(std::shared_ptr<IDataProvider> provider);
110 void registerProvider(std::shared_ptr<IDataProvider> provider);
111
111
112 void storeVariableRequest(QUuid varId, QUuid varRequestId, const VariableRequest &varRequest);
112 void storeVariableRequest(QUuid varId, QUuid varRequestId, const VariableRequest &varRequest);
113 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries);
113 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries);
114 void updateVariableRequest(QUuid varRequestId);
114 void updateVariableRequest(QUuid varRequestId);
115 void cancelVariableRequest(QUuid varRequestId);
115 void cancelVariableRequest(QUuid varRequestId);
116
116
117 QMutex m_WorkingMutex;
117 QMutex m_WorkingMutex;
118 /// Variable model. The VariableController has the ownership
118 /// Variable model. The VariableController has the ownership
119 VariableModel *m_VariableModel;
119 VariableModel *m_VariableModel;
120 QItemSelectionModel *m_VariableSelectionModel;
120 QItemSelectionModel *m_VariableSelectionModel;
121
121
122
122
123 TimeController *m_TimeController{nullptr};
123 TimeController *m_TimeController{nullptr};
124 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
124 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
125 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
125 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
126 QThread m_VariableAcquisitionWorkerThread;
126 QThread m_VariableAcquisitionWorkerThread;
127
127
128 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
128 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
129 m_VariableToProviderMap;
129 m_VariableToProviderMap;
130 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
130 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
131 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
131 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
132 m_GroupIdToVariableSynchronizationGroupMap;
132 m_GroupIdToVariableSynchronizationGroupMap;
133 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
133 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
134 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
134 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
135
135
136 std::map<QUuid, std::map<QUuid, VariableRequest> > m_VarRequestIdToVarIdVarRequestMap;
136 std::map<QUuid, std::map<QUuid, VariableRequest> > m_VarRequestIdToVarIdVarRequestMap;
137
137
138 std::map<QUuid, std::deque<QUuid> > m_VarIdToVarRequestIdQueueMap;
138 std::map<QUuid, std::deque<QUuid> > m_VarIdToVarRequestIdQueueMap;
139
139
140
140
141 VariableController *q;
141 VariableController *q;
142 };
142 };
143
143
144
144
145 VariableController::VariableController(QObject *parent)
145 VariableController::VariableController(QObject *parent)
146 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
146 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
147 {
147 {
148 qCDebug(LOG_VariableController()) << tr("VariableController construction")
148 qCDebug(LOG_VariableController()) << tr("VariableController construction")
149 << QThread::currentThread();
149 << QThread::currentThread();
150
150
151 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
151 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
152 &VariableController::onAbortProgressRequested);
152 &VariableController::onAbortProgressRequested);
153
153
154 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
154 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
155 &VariableController::onDataProvided);
155 &VariableController::onDataProvided);
156 connect(impl->m_VariableAcquisitionWorker.get(),
156 connect(impl->m_VariableAcquisitionWorker.get(),
157 &VariableAcquisitionWorker::variableRequestInProgress, this,
157 &VariableAcquisitionWorker::variableRequestInProgress, this,
158 &VariableController::onVariableRetrieveDataInProgress);
158 &VariableController::onVariableRetrieveDataInProgress);
159
159
160 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
160 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
161 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
161 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
162 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
162 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
163 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
163 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
164
164
165
165
166 impl->m_VariableAcquisitionWorkerThread.start();
166 impl->m_VariableAcquisitionWorkerThread.start();
167 }
167 }
168
168
169 VariableController::~VariableController()
169 VariableController::~VariableController()
170 {
170 {
171 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
171 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
172 << QThread::currentThread();
172 << QThread::currentThread();
173 this->waitForFinish();
173 this->waitForFinish();
174 }
174 }
175
175
176 VariableModel *VariableController::variableModel() noexcept
176 VariableModel *VariableController::variableModel() noexcept
177 {
177 {
178 return impl->m_VariableModel;
178 return impl->m_VariableModel;
179 }
179 }
180
180
181 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
181 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
182 {
182 {
183 return impl->m_VariableSelectionModel;
183 return impl->m_VariableSelectionModel;
184 }
184 }
185
185
186 void VariableController::setTimeController(TimeController *timeController) noexcept
186 void VariableController::setTimeController(TimeController *timeController) noexcept
187 {
187 {
188 impl->m_TimeController = timeController;
188 impl->m_TimeController = timeController;
189 }
189 }
190
190
191 std::shared_ptr<Variable>
191 std::shared_ptr<Variable>
192 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
192 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
193 {
193 {
194 if (impl->m_VariableModel->containsVariable(variable)) {
194 if (impl->m_VariableModel->containsVariable(variable)) {
195 // Clones variable
195 // Clones variable
196 auto duplicate = variable->clone();
196 auto duplicate = variable->clone();
197
197
198 // Adds clone to model
198 // Adds clone to model
199 impl->m_VariableModel->addVariable(duplicate);
199 impl->m_VariableModel->addVariable(duplicate);
200
200
201 // Generates clone identifier
201 // Generates clone identifier
202 impl->m_VariableToIdentifierMap[duplicate] = QUuid::createUuid();
202 impl->m_VariableToIdentifierMap[duplicate] = QUuid::createUuid();
203
203
204 // Registers provider
204 // Registers provider
205 auto variableProvider = impl->m_VariableToProviderMap.at(variable);
205 auto variableProvider = impl->m_VariableToProviderMap.at(variable);
206 auto duplicateProvider = variableProvider != nullptr ? variableProvider->clone() : nullptr;
206 auto duplicateProvider = variableProvider != nullptr ? variableProvider->clone() : nullptr;
207
207
208 impl->m_VariableToProviderMap[duplicate] = duplicateProvider;
208 impl->m_VariableToProviderMap[duplicate] = duplicateProvider;
209 if (duplicateProvider) {
209 if (duplicateProvider) {
210 impl->registerProvider(duplicateProvider);
210 impl->registerProvider(duplicateProvider);
211 }
211 }
212
212
213 return duplicate;
213 return duplicate;
214 }
214 }
215 else {
215 else {
216 qCCritical(LOG_VariableController())
216 qCCritical(LOG_VariableController())
217 << tr("Can't create duplicate of variable %1: variable not registered in the model")
217 << tr("Can't create duplicate of variable %1: variable not registered in the model")
218 .arg(variable->name());
218 .arg(variable->name());
219 return nullptr;
219 return nullptr;
220 }
220 }
221 }
221 }
222
222
223 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
223 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
224 {
224 {
225 if (!variable) {
225 if (!variable) {
226 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
226 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
227 return;
227 return;
228 }
228 }
229
229
230 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
230 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
231 // make some treatments before the deletion
231 // make some treatments before the deletion
232 emit variableAboutToBeDeleted(variable);
232 emit variableAboutToBeDeleted(variable);
233
233
234 // Deletes identifier
234 // Deletes identifier
235 impl->m_VariableToIdentifierMap.erase(variable);
235 impl->m_VariableToIdentifierMap.erase(variable);
236
236
237 // Deletes provider
237 // Deletes provider
238 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
238 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
239 qCDebug(LOG_VariableController())
239 qCDebug(LOG_VariableController())
240 << tr("Number of providers deleted for variable %1: %2")
240 << tr("Number of providers deleted for variable %1: %2")
241 .arg(variable->name(), QString::number(nbProvidersDeleted));
241 .arg(variable->name(), QString::number(nbProvidersDeleted));
242
242
243
243
244 // Deletes from model
244 // Deletes from model
245 impl->m_VariableModel->deleteVariable(variable);
245 impl->m_VariableModel->deleteVariable(variable);
246 }
246 }
247
247
248 void VariableController::deleteVariables(
248 void VariableController::deleteVariables(
249 const QVector<std::shared_ptr<Variable> > &variables) noexcept
249 const QVector<std::shared_ptr<Variable> > &variables) noexcept
250 {
250 {
251 for (auto variable : qAsConst(variables)) {
251 for (auto variable : qAsConst(variables)) {
252 deleteVariable(variable);
252 deleteVariable(variable);
253 }
253 }
254 }
254 }
255
255
256 std::shared_ptr<Variable>
256 std::shared_ptr<Variable>
257 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
257 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
258 std::shared_ptr<IDataProvider> provider) noexcept
258 std::shared_ptr<IDataProvider> provider) noexcept
259 {
259 {
260 if (!impl->m_TimeController) {
260 if (!impl->m_TimeController) {
261 qCCritical(LOG_VariableController())
261 qCCritical(LOG_VariableController())
262 << tr("Impossible to create variable: The time controller is null");
262 << tr("Impossible to create variable: The time controller is null");
263 return nullptr;
263 return nullptr;
264 }
264 }
265
265
266 auto range = impl->m_TimeController->dateTime();
266 auto range = impl->m_TimeController->dateTime();
267
267
268 if (auto newVariable = impl->m_VariableModel->createVariable(name, range, metadata)) {
268 if (auto newVariable = impl->m_VariableModel->createVariable(name, metadata)) {
269 auto identifier = QUuid::createUuid();
269 auto identifier = QUuid::createUuid();
270
270
271 // store the provider
271 // store the provider
272 impl->registerProvider(provider);
272 impl->registerProvider(provider);
273
273
274 // Associate the provider
274 // Associate the provider
275 impl->m_VariableToProviderMap[newVariable] = provider;
275 impl->m_VariableToProviderMap[newVariable] = provider;
276 impl->m_VariableToIdentifierMap[newVariable] = identifier;
276 impl->m_VariableToIdentifierMap[newVariable] = identifier;
277
277
278
278
279 auto varRequestId = QUuid::createUuid();
279 auto varRequestId = QUuid::createUuid();
280 impl->processRequest(newVariable, range, varRequestId);
280 impl->processRequest(newVariable, range, varRequestId);
281 impl->updateVariableRequest(varRequestId);
281 impl->updateVariableRequest(varRequestId);
282
282
283 return newVariable;
283 return newVariable;
284 }
284 }
285 }
285 }
286
286
287 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
287 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
288 {
288 {
289 // TODO check synchronisation and Rescale
289 // TODO check synchronisation and Rescale
290 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
290 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
291 << QThread::currentThread()->objectName();
291 << QThread::currentThread()->objectName();
292 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
292 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
293 auto varRequestId = QUuid::createUuid();
293 auto varRequestId = QUuid::createUuid();
294
294
295 for (const auto &selectedRow : qAsConst(selectedRows)) {
295 for (const auto &selectedRow : qAsConst(selectedRows)) {
296 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
296 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
297 selectedVariable->setRange(dateTime);
297 selectedVariable->setRange(dateTime);
298 impl->processRequest(selectedVariable, dateTime, varRequestId);
298 impl->processRequest(selectedVariable, dateTime, varRequestId);
299
299
300 // notify that rescale operation has to be done
300 // notify that rescale operation has to be done
301 emit rangeChanged(selectedVariable, dateTime);
301 emit rangeChanged(selectedVariable, dateTime);
302 }
302 }
303 }
303 }
304 impl->updateVariableRequest(varRequestId);
304 impl->updateVariableRequest(varRequestId);
305 }
305 }
306
306
307 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
307 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
308 const SqpRange &cacheRangeRequested,
308 const SqpRange &cacheRangeRequested,
309 QVector<AcquisitionDataPacket> dataAcquired)
309 QVector<AcquisitionDataPacket> dataAcquired)
310 {
310 {
311 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
311 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
312 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
312 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
313 if (!varRequestId.isNull()) {
313 if (!varRequestId.isNull()) {
314 impl->updateVariableRequest(varRequestId);
314 impl->updateVariableRequest(varRequestId);
315 }
315 }
316 }
316 }
317
317
318 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
318 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
319 {
319 {
320 qCDebug(LOG_VariableController())
320 qCDebug(LOG_VariableController())
321 << "TORM: variableController::onVariableRetrieveDataInProgress"
321 << "TORM: variableController::onVariableRetrieveDataInProgress"
322 << QThread::currentThread()->objectName() << progress;
322 << QThread::currentThread()->objectName() << progress;
323 if (auto var = impl->findVariable(identifier)) {
323 if (auto var = impl->findVariable(identifier)) {
324 impl->m_VariableModel->setDataProgress(var, progress);
324 impl->m_VariableModel->setDataProgress(var, progress);
325 }
325 }
326 else {
326 else {
327 qCCritical(LOG_VariableController())
327 qCCritical(LOG_VariableController())
328 << tr("Impossible to notify progression of a null variable");
328 << tr("Impossible to notify progression of a null variable");
329 }
329 }
330 }
330 }
331
331
332 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
332 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
333 {
333 {
334 auto it = impl->m_VariableToIdentifierMap.find(variable);
334 auto it = impl->m_VariableToIdentifierMap.find(variable);
335 if (it != impl->m_VariableToIdentifierMap.cend()) {
335 if (it != impl->m_VariableToIdentifierMap.cend()) {
336 impl->m_VariableAcquisitionWorker->abortProgressRequested(it->second);
336 impl->m_VariableAcquisitionWorker->abortProgressRequested(it->second);
337
337
338 QUuid varRequestId;
338 QUuid varRequestId;
339 auto varIdToVarRequestIdQueueMapIt = impl->m_VarIdToVarRequestIdQueueMap.find(it->second);
339 auto varIdToVarRequestIdQueueMapIt = impl->m_VarIdToVarRequestIdQueueMap.find(it->second);
340 if (varIdToVarRequestIdQueueMapIt != impl->m_VarIdToVarRequestIdQueueMap.cend()) {
340 if (varIdToVarRequestIdQueueMapIt != impl->m_VarIdToVarRequestIdQueueMap.cend()) {
341 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
341 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
342 varRequestId = varRequestIdQueue.front();
342 varRequestId = varRequestIdQueue.front();
343 impl->cancelVariableRequest(varRequestId);
343 impl->cancelVariableRequest(varRequestId);
344
344
345 // Finish the progression for the request
345 // Finish the progression for the request
346 impl->m_VariableModel->setDataProgress(variable, 0.0);
346 impl->m_VariableModel->setDataProgress(variable, 0.0);
347 }
347 }
348 else {
348 else {
349 qCWarning(LOG_VariableController())
349 qCWarning(LOG_VariableController())
350 << tr("Aborting progression of inexistant variable request detected !!!")
350 << tr("Aborting progression of inexistant variable request detected !!!")
351 << QThread::currentThread()->objectName();
351 << QThread::currentThread()->objectName();
352 }
352 }
353 }
353 }
354 else {
354 else {
355 qCWarning(LOG_VariableController())
355 qCWarning(LOG_VariableController())
356 << tr("Aborting progression of inexistant variable detected !!!")
356 << tr("Aborting progression of inexistant variable detected !!!")
357 << QThread::currentThread()->objectName();
357 << QThread::currentThread()->objectName();
358 }
358 }
359 }
359 }
360
360
361 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
361 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
362 {
362 {
363 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
363 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
364 << QThread::currentThread()->objectName()
364 << QThread::currentThread()->objectName()
365 << synchronizationGroupId;
365 << synchronizationGroupId;
366 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
366 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
367 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
367 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
368 std::make_pair(synchronizationGroupId, vSynchroGroup));
368 std::make_pair(synchronizationGroupId, vSynchroGroup));
369 }
369 }
370
370
371 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
371 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
372 {
372 {
373 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
373 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
374 }
374 }
375
375
376 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
376 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
377 QUuid synchronizationGroupId)
377 QUuid synchronizationGroupId)
378
378
379 {
379 {
380 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
380 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
381 << synchronizationGroupId;
381 << synchronizationGroupId;
382 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
382 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
383 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
383 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
384 auto groupIdToVSGIt
384 auto groupIdToVSGIt
385 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
385 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
386 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
386 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
387 impl->m_VariableIdGroupIdMap.insert(
387 impl->m_VariableIdGroupIdMap.insert(
388 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
388 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
389 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
389 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
390 }
390 }
391 else {
391 else {
392 qCCritical(LOG_VariableController())
392 qCCritical(LOG_VariableController())
393 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
393 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
394 << variable->name();
394 << variable->name();
395 }
395 }
396 }
396 }
397 else {
397 else {
398 qCCritical(LOG_VariableController())
398 qCCritical(LOG_VariableController())
399 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
399 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
400 }
400 }
401 }
401 }
402
402
403 void VariableController::desynchronize(std::shared_ptr<Variable> variable,
403 void VariableController::desynchronize(std::shared_ptr<Variable> variable,
404 QUuid synchronizationGroupId)
404 QUuid synchronizationGroupId)
405 {
405 {
406 // Gets variable id
406 // Gets variable id
407 auto variableIt = impl->m_VariableToIdentifierMap.find(variable);
407 auto variableIt = impl->m_VariableToIdentifierMap.find(variable);
408 if (variableIt == impl->m_VariableToIdentifierMap.cend()) {
408 if (variableIt == impl->m_VariableToIdentifierMap.cend()) {
409 qCCritical(LOG_VariableController())
409 qCCritical(LOG_VariableController())
410 << tr("Can't desynchronize variable %1: variable identifier not found")
410 << tr("Can't desynchronize variable %1: variable identifier not found")
411 .arg(variable->name());
411 .arg(variable->name());
412 return;
412 return;
413 }
413 }
414
414
415 // Gets synchronization group
415 // Gets synchronization group
416 auto groupIt = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
416 auto groupIt = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
417 if (groupIt == impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
417 if (groupIt == impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
418 qCCritical(LOG_VariableController())
418 qCCritical(LOG_VariableController())
419 << tr("Can't desynchronize variable %1: unknown synchronization group")
419 << tr("Can't desynchronize variable %1: unknown synchronization group")
420 .arg(variable->name());
420 .arg(variable->name());
421 return;
421 return;
422 }
422 }
423
423
424 auto variableId = variableIt->second;
424 auto variableId = variableIt->second;
425
425
426 // Removes variable from synchronization group
426 // Removes variable from synchronization group
427 auto synchronizationGroup = groupIt->second;
427 auto synchronizationGroup = groupIt->second;
428 synchronizationGroup->removeVariableId(variableId);
428 synchronizationGroup->removeVariableId(variableId);
429
429
430 // Removes link between variable and synchronization group
430 // Removes link between variable and synchronization group
431 impl->m_VariableIdGroupIdMap.erase(variableId);
431 impl->m_VariableIdGroupIdMap.erase(variableId);
432 }
432 }
433
433
434 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
434 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
435 const SqpRange &range, const SqpRange &oldRange,
435 const SqpRange &range, const SqpRange &oldRange,
436 bool synchronise)
436 bool synchronise)
437 {
437 {
438 // NOTE: oldRange isn't really necessary since oldRange == variable->range().
438 // NOTE: oldRange isn't really necessary since oldRange == variable->range().
439
439
440 // we want to load data of the variable for the dateTime.
440 // we want to load data of the variable for the dateTime.
441 // First we check if the cache contains some of them.
441 // First we check if the cache contains some of them.
442 // For the other, we ask the provider to give them.
442 // For the other, we ask the provider to give them.
443
443
444 auto varRequestId = QUuid::createUuid();
444 auto varRequestId = QUuid::createUuid();
445 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
445 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
446 << QThread::currentThread()->objectName() << varRequestId;
446 << QThread::currentThread()->objectName() << varRequestId;
447
447
448 for (const auto &var : variables) {
448 for (const auto &var : variables) {
449 qCDebug(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId;
449 qCDebug(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId;
450 impl->processRequest(var, range, varRequestId);
450 impl->processRequest(var, range, varRequestId);
451 }
451 }
452
452
453 if (synchronise) {
453 if (synchronise) {
454 // Get the group ids
454 // Get the group ids
455 qCDebug(LOG_VariableController())
455 qCDebug(LOG_VariableController())
456 << "TORM VariableController::onRequestDataLoading for synchro var ENABLE";
456 << "TORM VariableController::onRequestDataLoading for synchro var ENABLE";
457 auto groupIds = std::set<QUuid>{};
457 auto groupIds = std::set<QUuid>{};
458 auto groupIdToOldRangeMap = std::map<QUuid, SqpRange>{};
458 auto groupIdToOldRangeMap = std::map<QUuid, SqpRange>{};
459 for (const auto &var : variables) {
459 for (const auto &var : variables) {
460 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(var);
460 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(var);
461 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
461 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
462 auto vId = varToVarIdIt->second;
462 auto vId = varToVarIdIt->second;
463 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
463 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
464 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
464 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
465 auto gId = varIdToGroupIdIt->second;
465 auto gId = varIdToGroupIdIt->second;
466 groupIdToOldRangeMap.insert(std::make_pair(gId, var->range()));
466 groupIdToOldRangeMap.insert(std::make_pair(gId, var->range()));
467 if (groupIds.find(gId) == groupIds.cend()) {
467 if (groupIds.find(gId) == groupIds.cend()) {
468 qCDebug(LOG_VariableController()) << "Synchro detect group " << gId;
468 qCDebug(LOG_VariableController()) << "Synchro detect group " << gId;
469 groupIds.insert(gId);
469 groupIds.insert(gId);
470 }
470 }
471 }
471 }
472 }
472 }
473 }
473 }
474
474
475 // We assume here all group ids exist
475 // We assume here all group ids exist
476 for (const auto &gId : groupIds) {
476 for (const auto &gId : groupIds) {
477 auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId);
477 auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId);
478 auto vSyncIds = vSynchronizationGroup->getIds();
478 auto vSyncIds = vSynchronizationGroup->getIds();
479 qCDebug(LOG_VariableController()) << "Var in synchro group ";
479 qCDebug(LOG_VariableController()) << "Var in synchro group ";
480 for (auto vId : vSyncIds) {
480 for (auto vId : vSyncIds) {
481 auto var = impl->findVariable(vId);
481 auto var = impl->findVariable(vId);
482
482
483 // Don't process already processed var
483 // Don't process already processed var
484 if (!variables.contains(var)) {
484 if (!variables.contains(var)) {
485 if (var != nullptr) {
485 if (var != nullptr) {
486 qCDebug(LOG_VariableController()) << "processRequest synchro for"
486 qCDebug(LOG_VariableController()) << "processRequest synchro for"
487 << var->name();
487 << var->name();
488 auto vSyncRangeRequested = computeSynchroRangeRequested(
488 auto vSyncRangeRequested = computeSynchroRangeRequested(
489 var->range(), range, groupIdToOldRangeMap.at(gId));
489 var->range(), range, groupIdToOldRangeMap.at(gId));
490 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
490 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
491 impl->processRequest(var, vSyncRangeRequested, varRequestId);
491 impl->processRequest(var, vSyncRangeRequested, varRequestId);
492 }
492 }
493 else {
493 else {
494 qCCritical(LOG_VariableController())
494 qCCritical(LOG_VariableController())
495
495
496 << tr("Impossible to synchronize a null variable");
496 << tr("Impossible to synchronize a null variable");
497 }
497 }
498 }
498 }
499 }
499 }
500 }
500 }
501 }
501 }
502
502
503 impl->updateVariableRequest(varRequestId);
503 impl->updateVariableRequest(varRequestId);
504 }
504 }
505
505
506
506
507 void VariableController::initialize()
507 void VariableController::initialize()
508 {
508 {
509 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
509 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
510 impl->m_WorkingMutex.lock();
510 impl->m_WorkingMutex.lock();
511 qCDebug(LOG_VariableController()) << tr("VariableController init END");
511 qCDebug(LOG_VariableController()) << tr("VariableController init END");
512 }
512 }
513
513
514 void VariableController::finalize()
514 void VariableController::finalize()
515 {
515 {
516 impl->m_WorkingMutex.unlock();
516 impl->m_WorkingMutex.unlock();
517 }
517 }
518
518
519 void VariableController::waitForFinish()
519 void VariableController::waitForFinish()
520 {
520 {
521 QMutexLocker locker{&impl->m_WorkingMutex};
521 QMutexLocker locker{&impl->m_WorkingMutex};
522 }
522 }
523
523
524 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
524 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
525 {
525 {
526 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
526 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
527 auto zoomType = AcquisitionZoomType::Unknown;
527 auto zoomType = AcquisitionZoomType::Unknown;
528 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
528 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
529 zoomType = AcquisitionZoomType::ZoomOut;
529 zoomType = AcquisitionZoomType::ZoomOut;
530 }
530 }
531 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
531 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
532 zoomType = AcquisitionZoomType::PanRight;
532 zoomType = AcquisitionZoomType::PanRight;
533 }
533 }
534 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
534 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
535 zoomType = AcquisitionZoomType::PanLeft;
535 zoomType = AcquisitionZoomType::PanLeft;
536 }
536 }
537 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
537 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
538 zoomType = AcquisitionZoomType::ZoomIn;
538 zoomType = AcquisitionZoomType::ZoomIn;
539 }
539 }
540 else {
540 else {
541 qCCritical(LOG_VariableController()) << "getZoomType: Unknown type detected";
541 qCCritical(LOG_VariableController()) << "getZoomType: Unknown type detected";
542 }
542 }
543 return zoomType;
543 return zoomType;
544 }
544 }
545
545
546 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
546 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
547 const SqpRange &rangeRequested,
547 const SqpRange &rangeRequested,
548 QUuid varRequestId)
548 QUuid varRequestId)
549 {
549 {
550
550
551 // TODO: protect at
551 // TODO: protect at
552 auto varRequest = VariableRequest{};
552 auto varRequest = VariableRequest{};
553 auto varId = m_VariableToIdentifierMap.at(var);
553 auto varId = m_VariableToIdentifierMap.at(var);
554
554
555 auto varStrategyRangesRequested
555 auto varStrategyRangesRequested
556 = m_VariableCacheStrategy->computeStrategyRanges(var->range(), rangeRequested);
556 = m_VariableCacheStrategy->computeStrategyRanges(var->range(), rangeRequested);
557 auto notInCacheRangeList = var->provideNotInCacheRangeList(varStrategyRangesRequested.second);
557 auto notInCacheRangeList = var->provideNotInCacheRangeList(varStrategyRangesRequested.second);
558 auto inCacheRangeList = var->provideInCacheRangeList(varStrategyRangesRequested.second);
558 auto inCacheRangeList = var->provideInCacheRangeList(varStrategyRangesRequested.second);
559
559
560 if (!notInCacheRangeList.empty()) {
560 if (!notInCacheRangeList.empty()) {
561 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
561 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
562 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
562 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
563
563
564 // store VarRequest
564 // store VarRequest
565 storeVariableRequest(varId, varRequestId, varRequest);
565 storeVariableRequest(varId, varRequestId, varRequest);
566
566
567 auto varProvider = m_VariableToProviderMap.at(var);
567 auto varProvider = m_VariableToProviderMap.at(var);
568 if (varProvider != nullptr) {
568 if (varProvider != nullptr) {
569 auto varRequestIdCanceled = m_VariableAcquisitionWorker->pushVariableRequest(
569 auto varRequestIdCanceled = m_VariableAcquisitionWorker->pushVariableRequest(
570 varRequestId, varId, varStrategyRangesRequested.first,
570 varRequestId, varId, varStrategyRangesRequested.first,
571 varStrategyRangesRequested.second,
571 varStrategyRangesRequested.second,
572 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
572 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
573 varProvider);
573 varProvider);
574
574
575 if (!varRequestIdCanceled.isNull()) {
575 if (!varRequestIdCanceled.isNull()) {
576 qCDebug(LOG_VariableAcquisitionWorker()) << tr("varRequestIdCanceled: ")
576 qCDebug(LOG_VariableAcquisitionWorker()) << tr("vsarRequestIdCanceled: ")
577 << varRequestIdCanceled;
577 << varRequestIdCanceled;
578 cancelVariableRequest(varRequestIdCanceled);
578 cancelVariableRequest(varRequestIdCanceled);
579 }
579 }
580 }
580 }
581 else {
581 else {
582 qCCritical(LOG_VariableController())
582 qCCritical(LOG_VariableController())
583 << "Impossible to provide data with a null provider";
583 << "Impossible to provide data with a null provider";
584 }
584 }
585
585
586 if (!inCacheRangeList.empty()) {
586 if (!inCacheRangeList.empty()) {
587 emit q->updateVarDisplaying(var, inCacheRangeList.first());
587 emit q->updateVarDisplaying(var, inCacheRangeList.first());
588 }
588 }
589 }
589 }
590 else {
590 else {
591
592 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
591 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
593 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
592 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
594 // store VarRequest
593 // store VarRequest
595 storeVariableRequest(varId, varRequestId, varRequest);
594 storeVariableRequest(varId, varRequestId, varRequest);
596 acceptVariableRequest(varId,
595 acceptVariableRequest(varId,
597 var->dataSeries()->subDataSeries(varStrategyRangesRequested.second));
596 var->dataSeries()->subDataSeries(varStrategyRangesRequested.second));
598 }
597 }
599 }
598 }
600
599
601 std::shared_ptr<Variable>
600 std::shared_ptr<Variable>
602 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
601 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
603 {
602 {
604 std::shared_ptr<Variable> var;
603 std::shared_ptr<Variable> var;
605 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
604 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
606
605
607 auto end = m_VariableToIdentifierMap.cend();
606 auto end = m_VariableToIdentifierMap.cend();
608 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
607 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
609 if (it != end) {
608 if (it != end) {
610 var = it->first;
609 var = it->first;
611 }
610 }
612 else {
611 else {
613 qCCritical(LOG_VariableController())
612 qCCritical(LOG_VariableController())
614 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
613 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
615 }
614 }
616
615
617 return var;
616 return var;
618 }
617 }
619
618
620 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
619 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
621 const QVector<AcquisitionDataPacket> acqDataPacketVector)
620 const QVector<AcquisitionDataPacket> acqDataPacketVector)
622 {
621 {
623 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
622 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
624 << acqDataPacketVector.size();
623 << acqDataPacketVector.size();
625 std::shared_ptr<IDataSeries> dataSeries;
624 std::shared_ptr<IDataSeries> dataSeries;
626 if (!acqDataPacketVector.isEmpty()) {
625 if (!acqDataPacketVector.isEmpty()) {
627 dataSeries = acqDataPacketVector[0].m_DateSeries;
626 dataSeries = acqDataPacketVector[0].m_DateSeries;
628 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
627 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
629 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
628 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
630 }
629 }
631 }
630 }
632 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
631 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
633 << acqDataPacketVector.size();
632 << acqDataPacketVector.size();
634 return dataSeries;
633 return dataSeries;
635 }
634 }
636
635
637 void VariableController::VariableControllerPrivate::registerProvider(
636 void VariableController::VariableControllerPrivate::registerProvider(
638 std::shared_ptr<IDataProvider> provider)
637 std::shared_ptr<IDataProvider> provider)
639 {
638 {
640 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
639 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
641 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
640 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
642 << provider->objectName();
641 << provider->objectName();
643 m_ProviderSet.insert(provider);
642 m_ProviderSet.insert(provider);
644 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
643 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
645 &VariableAcquisitionWorker::onVariableDataAcquired);
644 &VariableAcquisitionWorker::onVariableDataAcquired);
646 connect(provider.get(), &IDataProvider::dataProvidedProgress,
645 connect(provider.get(), &IDataProvider::dataProvidedProgress,
647 m_VariableAcquisitionWorker.get(),
646 m_VariableAcquisitionWorker.get(),
648 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
647 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
649 }
648 }
650 else {
649 else {
651 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
650 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
652 }
651 }
653 }
652 }
654
653
655 void VariableController::VariableControllerPrivate::storeVariableRequest(
654 void VariableController::VariableControllerPrivate::storeVariableRequest(
656 QUuid varId, QUuid varRequestId, const VariableRequest &varRequest)
655 QUuid varId, QUuid varRequestId, const VariableRequest &varRequest)
657 {
656 {
658 // First request for the variable. we can create an entry for it
657 // First request for the variable. we can create an entry for it
659 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
658 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
660 if (varIdToVarRequestIdQueueMapIt == m_VarIdToVarRequestIdQueueMap.cend()) {
659 if (varIdToVarRequestIdQueueMapIt == m_VarIdToVarRequestIdQueueMap.cend()) {
661 auto varRequestIdQueue = std::deque<QUuid>{};
660 auto varRequestIdQueue = std::deque<QUuid>{};
662 qCDebug(LOG_VariableController()) << tr("Store REQUEST in QUEUE");
661 qCDebug(LOG_VariableController()) << tr("Store REQUEST in QUEUE");
663 varRequestIdQueue.push_back(varRequestId);
662 varRequestIdQueue.push_back(varRequestId);
664 m_VarIdToVarRequestIdQueueMap.insert(std::make_pair(varId, std::move(varRequestIdQueue)));
663 m_VarIdToVarRequestIdQueueMap.insert(std::make_pair(varId, std::move(varRequestIdQueue)));
665 }
664 }
666 else {
665 else {
667 qCDebug(LOG_VariableController()) << tr("Store REQUEST in EXISTING QUEUE");
666 qCDebug(LOG_VariableController()) << tr("Store REQUEST in EXISTING QUEUE");
668 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
667 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
669 varRequestIdQueue.push_back(varRequestId);
668 varRequestIdQueue.push_back(varRequestId);
670 }
669 }
671
670
672 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
671 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
673 if (varRequestIdToVarIdVarRequestMapIt == m_VarRequestIdToVarIdVarRequestMap.cend()) {
672 if (varRequestIdToVarIdVarRequestMapIt == m_VarRequestIdToVarIdVarRequestMap.cend()) {
674 auto varIdToVarRequestMap = std::map<QUuid, VariableRequest>{};
673 auto varIdToVarRequestMap = std::map<QUuid, VariableRequest>{};
675 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
674 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
676 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in MAP");
675 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in MAP");
677 m_VarRequestIdToVarIdVarRequestMap.insert(
676 m_VarRequestIdToVarIdVarRequestMap.insert(
678 std::make_pair(varRequestId, std::move(varIdToVarRequestMap)));
677 std::make_pair(varRequestId, std::move(varIdToVarRequestMap)));
679 }
678 }
680 else {
679 else {
681 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
680 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
682 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in EXISTING MAP");
681 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in EXISTING MAP");
683 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
682 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
684 }
683 }
685 }
684 }
686
685
687 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
686 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
688 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
687 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
689 {
688 {
690 QUuid varRequestId;
689 QUuid varRequestId;
691 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
690 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
692 if (varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.cend()) {
691 if (varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.cend()) {
693 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
692 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
694 varRequestId = varRequestIdQueue.front();
693 varRequestId = varRequestIdQueue.front();
695 auto varRequestIdToVarIdVarRequestMapIt
694 auto varRequestIdToVarIdVarRequestMapIt
696 = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
695 = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
697 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
696 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
698 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
697 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
699 auto varIdToVarRequestMapIt = varIdToVarRequestMap.find(varId);
698 auto varIdToVarRequestMapIt = varIdToVarRequestMap.find(varId);
700 if (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) {
699 if (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) {
701 qCDebug(LOG_VariableController()) << tr("acceptVariableRequest");
700 qCDebug(LOG_VariableController()) << tr("acceptVariableRequest");
702 auto &varRequest = varIdToVarRequestMapIt->second;
701 auto &varRequest = varIdToVarRequestMapIt->second;
703 varRequest.m_DataSeries = dataSeries;
702 varRequest.m_DataSeries = dataSeries;
704 varRequest.m_CanUpdate = true;
703 varRequest.m_CanUpdate = true;
705 }
704 }
706 else {
705 else {
707 qCDebug(LOG_VariableController())
706 qCDebug(LOG_VariableController())
708 << tr("Impossible to acceptVariableRequest of a unknown variable id attached "
707 << tr("Impossible to acceptVariableRequest of a unknown variable id attached "
709 "to a variableRequestId")
708 "to a variableRequestId")
710 << varRequestId << varId;
709 << varRequestId << varId;
711 }
710 }
712 }
711 }
713 else {
712 else {
714 qCCritical(LOG_VariableController())
713 qCCritical(LOG_VariableController())
715 << tr("Impossible to acceptVariableRequest of a unknown variableRequestId")
714 << tr("Impossible to acceptVariableRequest of a unknown variableRequestId")
716 << varRequestId;
715 << varRequestId;
717 }
716 }
718
717
719 qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in QUEUE ?")
718 qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in QUEUE ?")
720 << varRequestIdQueue.size();
719 << varRequestIdQueue.size();
721 varRequestIdQueue.pop_front();
720 varRequestIdQueue.pop_front();
722 qCDebug(LOG_VariableController()) << tr("2: erase REQUEST in QUEUE ?")
721 qCDebug(LOG_VariableController()) << tr("2: erase REQUEST in QUEUE ?")
723 << varRequestIdQueue.size();
722 << varRequestIdQueue.size();
724 if (varRequestIdQueue.empty()) {
723 if (varRequestIdQueue.empty()) {
725 m_VarIdToVarRequestIdQueueMap.erase(varId);
724 m_VarIdToVarRequestIdQueueMap.erase(varId);
726 }
725 }
727 }
726 }
728 else {
727 else {
729 qCCritical(LOG_VariableController())
728 qCCritical(LOG_VariableController())
730 << tr("Impossible to acceptVariableRequest of a unknown variable id") << varId;
729 << tr("Impossible to acceptVariableRequest of a unknown variable id") << varId;
731 }
730 }
732
731
733 return varRequestId;
732 return varRequestId;
734 }
733 }
735
734
736 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
735 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
737 {
736 {
738
737
739 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
738 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
740 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
739 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
741 bool processVariableUpdate = true;
740 bool processVariableUpdate = true;
742 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
741 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
743 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
742 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
744 (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) && processVariableUpdate;
743 (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) && processVariableUpdate;
745 ++varIdToVarRequestMapIt) {
744 ++varIdToVarRequestMapIt) {
746 processVariableUpdate &= varIdToVarRequestMapIt->second.m_CanUpdate;
745 processVariableUpdate &= varIdToVarRequestMapIt->second.m_CanUpdate;
747 qCDebug(LOG_VariableController()) << tr("updateVariableRequest")
746 qCDebug(LOG_VariableController()) << tr("updateVariableRequest")
748 << processVariableUpdate;
747 << processVariableUpdate;
749 }
748 }
750
749
751 if (processVariableUpdate) {
750 if (processVariableUpdate) {
752 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
751 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
753 varIdToVarRequestMapIt != varIdToVarRequestMap.cend(); ++varIdToVarRequestMapIt) {
752 varIdToVarRequestMapIt != varIdToVarRequestMap.cend(); ++varIdToVarRequestMapIt) {
754 if (auto var = findVariable(varIdToVarRequestMapIt->first)) {
753 if (auto var = findVariable(varIdToVarRequestMapIt->first)) {
755 auto &varRequest = varIdToVarRequestMapIt->second;
754 auto &varRequest = varIdToVarRequestMapIt->second;
756 var->setRange(varRequest.m_RangeRequested);
755 var->setRange(varRequest.m_RangeRequested);
757 var->setCacheRange(varRequest.m_CacheRangeRequested);
756 var->setCacheRange(varRequest.m_CacheRangeRequested);
758 qCDebug(LOG_VariableController()) << tr("1: onDataProvided")
757 qCDebug(LOG_VariableController()) << tr("1: onDataProvided")
759 << varRequest.m_RangeRequested;
758 << varRequest.m_RangeRequested;
760 qCDebug(LOG_VariableController()) << tr("2: onDataProvided")
759 qCDebug(LOG_VariableController()) << tr("2: onDataProvided")
761 << varRequest.m_CacheRangeRequested;
760 << varRequest.m_CacheRangeRequested;
762 var->mergeDataSeries(varRequest.m_DataSeries);
761 var->mergeDataSeries(varRequest.m_DataSeries);
763 qCDebug(LOG_VariableController()) << tr("3: onDataProvided")
762 qCDebug(LOG_VariableController()) << tr("3: onDataProvided")
764 << varRequest.m_DataSeries->range();
763 << varRequest.m_DataSeries->range();
765 qCDebug(LOG_VariableController()) << tr("4: onDataProvided");
764 qCDebug(LOG_VariableController()) << tr("4: onDataProvided");
766
765
767 /// @todo MPL: confirm
766 /// @todo MPL: confirm
768 // Variable update is notified only if there is no pending request for it
767 // Variable update is notified only if there is no pending request for it
769 // if
768 // if
770 // (m_VarIdToVarRequestIdQueueMap.count(varIdToVarRequestMapIt->first)
769 // (m_VarIdToVarRequestIdQueueMap.count(varIdToVarRequestMapIt->first)
771 // == 0) {
770 // == 0) {
772 emit var->updated();
771 emit var->updated();
773 // }
772 // }
774 }
773 }
775 else {
774 else {
776 qCCritical(LOG_VariableController())
775 qCCritical(LOG_VariableController())
777 << tr("Impossible to update data to a null variable");
776 << tr("Impossible to update data to a null variable");
778 }
777 }
779 }
778 }
780
779
781 // cleaning varRequestId
780 // cleaning varRequestId
782 qCDebug(LOG_VariableController()) << tr("0: erase REQUEST in MAP ?")
781 qCDebug(LOG_VariableController()) << tr("0: erase REQUEST in MAP ?")
783 << m_VarRequestIdToVarIdVarRequestMap.size();
782 << m_VarRequestIdToVarIdVarRequestMap.size();
784 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
783 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
785 qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in MAP ?")
784 qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in MAP ?")
786 << m_VarRequestIdToVarIdVarRequestMap.size();
785 << m_VarRequestIdToVarIdVarRequestMap.size();
787 }
786 }
788 }
787 }
789 else {
788 else {
790 qCCritical(LOG_VariableController())
789 qCCritical(LOG_VariableController())
791 << tr("Cannot updateVariableRequest for a unknow varRequestId") << varRequestId;
790 << tr("Cannot updateVariableRequest for a unknow varRequestId") << varRequestId;
792 }
791 }
793 }
792 }
794
793
795 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
794 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
796 {
795 {
797 // cleaning varRequestId
796 // cleaning varRequestId
798 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
797 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
799
798
800 for (auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.begin();
799 for (auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.begin();
801 varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.end();) {
800 varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.end();) {
802 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
801 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
803 varRequestIdQueue.erase(
802 varRequestIdQueue.erase(
804 std::remove(varRequestIdQueue.begin(), varRequestIdQueue.end(), varRequestId),
803 std::remove(varRequestIdQueue.begin(), varRequestIdQueue.end(), varRequestId),
805 varRequestIdQueue.end());
804 varRequestIdQueue.end());
806 if (varRequestIdQueue.empty()) {
805 if (varRequestIdQueue.empty()) {
807 varIdToVarRequestIdQueueMapIt
806 varIdToVarRequestIdQueueMapIt
808 = m_VarIdToVarRequestIdQueueMap.erase(varIdToVarRequestIdQueueMapIt);
807 = m_VarIdToVarRequestIdQueueMap.erase(varIdToVarRequestIdQueueMapIt);
809 }
808 }
810 else {
809 else {
811 ++varIdToVarRequestIdQueueMapIt;
810 ++varIdToVarRequestIdQueueMapIt;
812 }
811 }
813 }
812 }
814 }
813 }
@@ -1,294 +1,293
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableModel.h>
2 #include <Variable/VariableModel.h>
3
3
4 #include <Common/DateUtils.h>
4 #include <Common/DateUtils.h>
5 #include <Common/StringUtils.h>
5 #include <Common/StringUtils.h>
6
6
7 #include <Data/IDataSeries.h>
7 #include <Data/IDataSeries.h>
8
8
9 #include <QSize>
9 #include <QSize>
10 #include <unordered_map>
10 #include <unordered_map>
11
11
12 Q_LOGGING_CATEGORY(LOG_VariableModel, "VariableModel")
12 Q_LOGGING_CATEGORY(LOG_VariableModel, "VariableModel")
13
13
14 namespace {
14 namespace {
15
15
16 // Column indexes
16 // Column indexes
17 const auto NAME_COLUMN = 0;
17 const auto NAME_COLUMN = 0;
18 const auto TSTART_COLUMN = 1;
18 const auto TSTART_COLUMN = 1;
19 const auto TEND_COLUMN = 2;
19 const auto TEND_COLUMN = 2;
20 const auto NBPOINTS_COLUMN = 3;
20 const auto NBPOINTS_COLUMN = 3;
21 const auto UNIT_COLUMN = 4;
21 const auto UNIT_COLUMN = 4;
22 const auto MISSION_COLUMN = 5;
22 const auto MISSION_COLUMN = 5;
23 const auto PLUGIN_COLUMN = 6;
23 const auto PLUGIN_COLUMN = 6;
24 const auto NB_COLUMNS = 7;
24 const auto NB_COLUMNS = 7;
25
25
26 // Column properties
26 // Column properties
27 const auto DEFAULT_HEIGHT = 25;
27 const auto DEFAULT_HEIGHT = 25;
28 const auto DEFAULT_WIDTH = 100;
28 const auto DEFAULT_WIDTH = 100;
29
29
30 struct ColumnProperties {
30 struct ColumnProperties {
31 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
31 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
32 int height = DEFAULT_HEIGHT)
32 int height = DEFAULT_HEIGHT)
33 : m_Name{name}, m_Width{width}, m_Height{height}
33 : m_Name{name}, m_Width{width}, m_Height{height}
34 {
34 {
35 }
35 }
36
36
37 QString m_Name;
37 QString m_Name;
38 int m_Width;
38 int m_Width;
39 int m_Height;
39 int m_Height;
40 };
40 };
41
41
42 const auto COLUMN_PROPERTIES = QHash<int, ColumnProperties>{
42 const auto COLUMN_PROPERTIES = QHash<int, ColumnProperties>{
43 {NAME_COLUMN, {QObject::tr("Name")}}, {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
43 {NAME_COLUMN, {QObject::tr("Name")}}, {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
44 {TEND_COLUMN, {QObject::tr("tEnd"), 180}}, {NBPOINTS_COLUMN, {QObject::tr("Nb points")}},
44 {TEND_COLUMN, {QObject::tr("tEnd"), 180}}, {NBPOINTS_COLUMN, {QObject::tr("Nb points")}},
45 {UNIT_COLUMN, {QObject::tr("Unit")}}, {MISSION_COLUMN, {QObject::tr("Mission")}},
45 {UNIT_COLUMN, {QObject::tr("Unit")}}, {MISSION_COLUMN, {QObject::tr("Mission")}},
46 {PLUGIN_COLUMN, {QObject::tr("Plugin")}}};
46 {PLUGIN_COLUMN, {QObject::tr("Plugin")}}};
47
47
48 /// Format for datetimes
48 /// Format for datetimes
49 const auto DATETIME_FORMAT = QStringLiteral("dd/MM/yyyy \nhh:mm:ss:zzz");
49 const auto DATETIME_FORMAT = QStringLiteral("dd/MM/yyyy \nhh:mm:ss:zzz");
50
50
51 QString uniqueName(const QString &defaultName,
51 QString uniqueName(const QString &defaultName,
52 const std::vector<std::shared_ptr<Variable> > &variables)
52 const std::vector<std::shared_ptr<Variable> > &variables)
53 {
53 {
54 auto forbiddenNames = std::vector<QString>(variables.size());
54 auto forbiddenNames = std::vector<QString>(variables.size());
55 std::transform(variables.cbegin(), variables.cend(), forbiddenNames.begin(),
55 std::transform(variables.cbegin(), variables.cend(), forbiddenNames.begin(),
56 [](const auto &variable) { return variable->name(); });
56 [](const auto &variable) { return variable->name(); });
57 auto uniqueName = StringUtils::uniqueName(defaultName, forbiddenNames);
57 auto uniqueName = StringUtils::uniqueName(defaultName, forbiddenNames);
58 Q_ASSERT(!uniqueName.isEmpty());
58 Q_ASSERT(!uniqueName.isEmpty());
59
59
60 return uniqueName;
60 return uniqueName;
61 }
61 }
62
62
63 } // namespace
63 } // namespace
64
64
65 struct VariableModel::VariableModelPrivate {
65 struct VariableModel::VariableModelPrivate {
66 /// Variables created in SciQlop
66 /// Variables created in SciQlop
67 std::vector<std::shared_ptr<Variable> > m_Variables;
67 std::vector<std::shared_ptr<Variable> > m_Variables;
68 std::unordered_map<std::shared_ptr<Variable>, double> m_VariableToProgress;
68 std::unordered_map<std::shared_ptr<Variable>, double> m_VariableToProgress;
69
69
70 /// Return the row index of the variable. -1 if it's not found
70 /// Return the row index of the variable. -1 if it's not found
71 int indexOfVariable(Variable *variable) const noexcept;
71 int indexOfVariable(Variable *variable) const noexcept;
72 };
72 };
73
73
74 VariableModel::VariableModel(QObject *parent)
74 VariableModel::VariableModel(QObject *parent)
75 : QAbstractTableModel{parent}, impl{spimpl::make_unique_impl<VariableModelPrivate>()}
75 : QAbstractTableModel{parent}, impl{spimpl::make_unique_impl<VariableModelPrivate>()}
76 {
76 {
77 }
77 }
78
78
79 void VariableModel::addVariable(std::shared_ptr<Variable> variable) noexcept
79 void VariableModel::addVariable(std::shared_ptr<Variable> variable) noexcept
80 {
80 {
81 auto insertIndex = rowCount();
81 auto insertIndex = rowCount();
82 beginInsertRows({}, insertIndex, insertIndex);
82 beginInsertRows({}, insertIndex, insertIndex);
83
83
84 // Generates unique name for the variable
84 // Generates unique name for the variable
85 variable->setName(uniqueName(variable->name(), impl->m_Variables));
85 variable->setName(uniqueName(variable->name(), impl->m_Variables));
86
86
87 impl->m_Variables.push_back(variable);
87 impl->m_Variables.push_back(variable);
88 connect(variable.get(), &Variable::updated, this, &VariableModel::onVariableUpdated);
88 connect(variable.get(), &Variable::updated, this, &VariableModel::onVariableUpdated);
89
89
90 endInsertRows();
90 endInsertRows();
91 }
91 }
92
92
93 bool VariableModel::containsVariable(std::shared_ptr<Variable> variable) const noexcept
93 bool VariableModel::containsVariable(std::shared_ptr<Variable> variable) const noexcept
94 {
94 {
95 auto end = impl->m_Variables.cend();
95 auto end = impl->m_Variables.cend();
96 return std::find(impl->m_Variables.cbegin(), end, variable) != end;
96 return std::find(impl->m_Variables.cbegin(), end, variable) != end;
97 }
97 }
98
98
99 std::shared_ptr<Variable> VariableModel::createVariable(const QString &name,
99 std::shared_ptr<Variable> VariableModel::createVariable(const QString &name,
100 const SqpRange &dateTime,
101 const QVariantHash &metadata) noexcept
100 const QVariantHash &metadata) noexcept
102 {
101 {
103 auto variable = std::make_shared<Variable>(name, dateTime, metadata);
102 auto variable = std::make_shared<Variable>(name, metadata);
104 addVariable(variable);
103 addVariable(variable);
105
104
106 return variable;
105 return variable;
107 }
106 }
108
107
109 void VariableModel::deleteVariable(std::shared_ptr<Variable> variable) noexcept
108 void VariableModel::deleteVariable(std::shared_ptr<Variable> variable) noexcept
110 {
109 {
111 if (!variable) {
110 if (!variable) {
112 qCCritical(LOG_Variable()) << "Can't delete a null variable from the model";
111 qCCritical(LOG_Variable()) << "Can't delete a null variable from the model";
113 return;
112 return;
114 }
113 }
115
114
116 // Finds variable in the model
115 // Finds variable in the model
117 auto begin = impl->m_Variables.cbegin();
116 auto begin = impl->m_Variables.cbegin();
118 auto end = impl->m_Variables.cend();
117 auto end = impl->m_Variables.cend();
119 auto it = std::find(begin, end, variable);
118 auto it = std::find(begin, end, variable);
120 if (it != end) {
119 if (it != end) {
121 auto removeIndex = std::distance(begin, it);
120 auto removeIndex = std::distance(begin, it);
122
121
123 // Deletes variable
122 // Deletes variable
124 beginRemoveRows({}, removeIndex, removeIndex);
123 beginRemoveRows({}, removeIndex, removeIndex);
125 impl->m_Variables.erase(it);
124 impl->m_Variables.erase(it);
126 endRemoveRows();
125 endRemoveRows();
127 }
126 }
128 else {
127 else {
129 qCritical(LOG_VariableModel())
128 qCritical(LOG_VariableModel())
130 << tr("Can't delete variable %1 from the model: the variable is not in the model")
129 << tr("Can't delete variable %1 from the model: the variable is not in the model")
131 .arg(variable->name());
130 .arg(variable->name());
132 }
131 }
133
132
134 // Removes variable from progress map
133 // Removes variable from progress map
135 impl->m_VariableToProgress.erase(variable);
134 impl->m_VariableToProgress.erase(variable);
136 }
135 }
137
136
138
137
139 std::shared_ptr<Variable> VariableModel::variable(int index) const
138 std::shared_ptr<Variable> VariableModel::variable(int index) const
140 {
139 {
141 return (index >= 0 && index < impl->m_Variables.size()) ? impl->m_Variables[index] : nullptr;
140 return (index >= 0 && index < impl->m_Variables.size()) ? impl->m_Variables[index] : nullptr;
142 }
141 }
143
142
144 std::vector<std::shared_ptr<Variable> > VariableModel::variables() const
143 std::vector<std::shared_ptr<Variable> > VariableModel::variables() const
145 {
144 {
146 return impl->m_Variables;
145 return impl->m_Variables;
147 }
146 }
148
147
149 void VariableModel::setDataProgress(std::shared_ptr<Variable> variable, double progress)
148 void VariableModel::setDataProgress(std::shared_ptr<Variable> variable, double progress)
150 {
149 {
151 if (progress > 0.0) {
150 if (progress > 0.0) {
152 impl->m_VariableToProgress[variable] = progress;
151 impl->m_VariableToProgress[variable] = progress;
153 }
152 }
154 else {
153 else {
155 impl->m_VariableToProgress.erase(variable);
154 impl->m_VariableToProgress.erase(variable);
156 }
155 }
157 auto modelIndex = createIndex(impl->indexOfVariable(variable.get()), NAME_COLUMN);
156 auto modelIndex = createIndex(impl->indexOfVariable(variable.get()), NAME_COLUMN);
158
157
159 emit dataChanged(modelIndex, modelIndex);
158 emit dataChanged(modelIndex, modelIndex);
160 }
159 }
161
160
162 int VariableModel::columnCount(const QModelIndex &parent) const
161 int VariableModel::columnCount(const QModelIndex &parent) const
163 {
162 {
164 Q_UNUSED(parent);
163 Q_UNUSED(parent);
165
164
166 return NB_COLUMNS;
165 return NB_COLUMNS;
167 }
166 }
168
167
169 int VariableModel::rowCount(const QModelIndex &parent) const
168 int VariableModel::rowCount(const QModelIndex &parent) const
170 {
169 {
171 Q_UNUSED(parent);
170 Q_UNUSED(parent);
172
171
173 return impl->m_Variables.size();
172 return impl->m_Variables.size();
174 }
173 }
175
174
176 QVariant VariableModel::data(const QModelIndex &index, int role) const
175 QVariant VariableModel::data(const QModelIndex &index, int role) const
177 {
176 {
178 if (!index.isValid()) {
177 if (!index.isValid()) {
179 return QVariant{};
178 return QVariant{};
180 }
179 }
181
180
182 if (index.row() < 0 || index.row() >= rowCount()) {
181 if (index.row() < 0 || index.row() >= rowCount()) {
183 return QVariant{};
182 return QVariant{};
184 }
183 }
185
184
186 if (role == Qt::DisplayRole) {
185 if (role == Qt::DisplayRole) {
187 if (auto variable = impl->m_Variables.at(index.row()).get()) {
186 if (auto variable = impl->m_Variables.at(index.row()).get()) {
188 switch (index.column()) {
187 switch (index.column()) {
189 case NAME_COLUMN:
188 case NAME_COLUMN:
190 return variable->name();
189 return variable->name();
191 case TSTART_COLUMN: {
190 case TSTART_COLUMN: {
192 auto range = variable->realRange();
191 auto range = variable->realRange();
193 return range != INVALID_RANGE
192 return range != INVALID_RANGE
194 ? DateUtils::dateTime(range.m_TStart).toString(DATETIME_FORMAT)
193 ? DateUtils::dateTime(range.m_TStart).toString(DATETIME_FORMAT)
195 : QVariant{};
194 : QVariant{};
196 }
195 }
197 case TEND_COLUMN: {
196 case TEND_COLUMN: {
198 auto range = variable->realRange();
197 auto range = variable->realRange();
199 return range != INVALID_RANGE
198 return range != INVALID_RANGE
200 ? DateUtils::dateTime(range.m_TEnd).toString(DATETIME_FORMAT)
199 ? DateUtils::dateTime(range.m_TEnd).toString(DATETIME_FORMAT)
201 : QVariant{};
200 : QVariant{};
202 }
201 }
203 case NBPOINTS_COLUMN:
202 case NBPOINTS_COLUMN:
204 return variable->nbPoints();
203 return variable->nbPoints();
205 case UNIT_COLUMN:
204 case UNIT_COLUMN:
206 return variable->metadata().value(QStringLiteral("units"));
205 return variable->metadata().value(QStringLiteral("units"));
207 case MISSION_COLUMN:
206 case MISSION_COLUMN:
208 return variable->metadata().value(QStringLiteral("mission"));
207 return variable->metadata().value(QStringLiteral("mission"));
209 case PLUGIN_COLUMN:
208 case PLUGIN_COLUMN:
210 return variable->metadata().value(QStringLiteral("plugin"));
209 return variable->metadata().value(QStringLiteral("plugin"));
211 default:
210 default:
212 // No action
211 // No action
213 break;
212 break;
214 }
213 }
215
214
216 qWarning(LOG_VariableModel())
215 qWarning(LOG_VariableModel())
217 << tr("Can't get data (unknown column %1)").arg(index.column());
216 << tr("Can't get data (unknown column %1)").arg(index.column());
218 }
217 }
219 else {
218 else {
220 qWarning(LOG_VariableModel()) << tr("Can't get data (no variable)");
219 qWarning(LOG_VariableModel()) << tr("Can't get data (no variable)");
221 }
220 }
222 }
221 }
223 else if (role == VariableRoles::ProgressRole) {
222 else if (role == VariableRoles::ProgressRole) {
224 if (auto variable = impl->m_Variables.at(index.row())) {
223 if (auto variable = impl->m_Variables.at(index.row())) {
225
224
226 auto it = impl->m_VariableToProgress.find(variable);
225 auto it = impl->m_VariableToProgress.find(variable);
227 if (it != impl->m_VariableToProgress.cend()) {
226 if (it != impl->m_VariableToProgress.cend()) {
228 return it->second;
227 return it->second;
229 }
228 }
230 }
229 }
231 }
230 }
232
231
233 return QVariant{};
232 return QVariant{};
234 }
233 }
235
234
236 QVariant VariableModel::headerData(int section, Qt::Orientation orientation, int role) const
235 QVariant VariableModel::headerData(int section, Qt::Orientation orientation, int role) const
237 {
236 {
238 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
237 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
239 return QVariant{};
238 return QVariant{};
240 }
239 }
241
240
242 if (orientation == Qt::Horizontal) {
241 if (orientation == Qt::Horizontal) {
243 auto propertiesIt = COLUMN_PROPERTIES.find(section);
242 auto propertiesIt = COLUMN_PROPERTIES.find(section);
244 if (propertiesIt != COLUMN_PROPERTIES.cend()) {
243 if (propertiesIt != COLUMN_PROPERTIES.cend()) {
245 // Role is either DisplayRole or SizeHintRole
244 // Role is either DisplayRole or SizeHintRole
246 return (role == Qt::DisplayRole)
245 return (role == Qt::DisplayRole)
247 ? QVariant{propertiesIt->m_Name}
246 ? QVariant{propertiesIt->m_Name}
248 : QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
247 : QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
249 }
248 }
250 else {
249 else {
251 qWarning(LOG_VariableModel())
250 qWarning(LOG_VariableModel())
252 << tr("Can't get header data (unknown column %1)").arg(section);
251 << tr("Can't get header data (unknown column %1)").arg(section);
253 }
252 }
254 }
253 }
255
254
256 return QVariant{};
255 return QVariant{};
257 }
256 }
258
257
259 void VariableModel::abortProgress(const QModelIndex &index)
258 void VariableModel::abortProgress(const QModelIndex &index)
260 {
259 {
261 if (auto variable = impl->m_Variables.at(index.row())) {
260 if (auto variable = impl->m_Variables.at(index.row())) {
262 emit abortProgessRequested(variable);
261 emit abortProgessRequested(variable);
263 }
262 }
264 }
263 }
265
264
266 void VariableModel::onVariableUpdated() noexcept
265 void VariableModel::onVariableUpdated() noexcept
267 {
266 {
268 // Finds variable that has been updated in the model
267 // Finds variable that has been updated in the model
269 if (auto updatedVariable = dynamic_cast<Variable *>(sender())) {
268 if (auto updatedVariable = dynamic_cast<Variable *>(sender())) {
270 auto updatedVariableIndex = impl->indexOfVariable(updatedVariable);
269 auto updatedVariableIndex = impl->indexOfVariable(updatedVariable);
271
270
272 if (updatedVariableIndex > -1) {
271 if (updatedVariableIndex > -1) {
273 emit dataChanged(createIndex(updatedVariableIndex, 0),
272 emit dataChanged(createIndex(updatedVariableIndex, 0),
274 createIndex(updatedVariableIndex, columnCount() - 1));
273 createIndex(updatedVariableIndex, columnCount() - 1));
275 }
274 }
276 }
275 }
277 }
276 }
278
277
279 int VariableModel::VariableModelPrivate::indexOfVariable(Variable *variable) const noexcept
278 int VariableModel::VariableModelPrivate::indexOfVariable(Variable *variable) const noexcept
280 {
279 {
281 auto begin = std::cbegin(m_Variables);
280 auto begin = std::cbegin(m_Variables);
282 auto end = std::cend(m_Variables);
281 auto end = std::cend(m_Variables);
283 auto it
282 auto it
284 = std::find_if(begin, end, [variable](const auto &var) { return var.get() == variable; });
283 = std::find_if(begin, end, [variable](const auto &var) { return var.get() == variable; });
285
284
286 if (it != end) {
285 if (it != end) {
287 // Gets the index of the variable in the model: we assume here that views have the same
286 // Gets the index of the variable in the model: we assume here that views have the same
288 // order as the model
287 // order as the model
289 return std::distance(begin, it);
288 return std::distance(begin, it);
290 }
289 }
291 else {
290 else {
292 return -1;
291 return -1;
293 }
292 }
294 }
293 }
@@ -1,174 +1,177
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2
2
3 #include <QObject>
3 #include <QObject>
4 #include <QtTest>
4 #include <QtTest>
5
5
6 #include <memory>
6 #include <memory>
7
7
8 class TestVariable : public QObject {
8 class TestVariable : public QObject {
9 Q_OBJECT
9 Q_OBJECT
10
10
11 private slots:
11 private slots:
12 void testNotInCacheRangeList();
12 void testNotInCacheRangeList();
13
13
14 void testInCacheRangeList();
14 void testInCacheRangeList();
15 };
15 };
16
16
17
17
18 void TestVariable::testNotInCacheRangeList()
18 void TestVariable::testNotInCacheRangeList()
19 {
19 {
20 auto varRS = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 20, 0}};
20 auto varRS = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 20, 0}};
21 auto varRE = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 40, 0}};
21 auto varRE = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 40, 0}};
22
22
23 auto sqpR = SqpRange{DateUtils::secondsSinceEpoch(varRS), DateUtils::secondsSinceEpoch(varRE)};
23 auto sqpR = SqpRange{DateUtils::secondsSinceEpoch(varRS), DateUtils::secondsSinceEpoch(varRE)};
24
24
25 auto varCRS = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 0, 0}};
25 auto varCRS = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 0, 0}};
26 auto varCRE = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}};
26 auto varCRE = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}};
27
27 auto sqpCR
28 auto sqpCR
28 = SqpRange{DateUtils::secondsSinceEpoch(varCRS), DateUtils::secondsSinceEpoch(varCRE)};
29 = SqpRange{DateUtils::secondsSinceEpoch(varCRS), DateUtils::secondsSinceEpoch(varCRE)};
29
30
30 Variable var{"Var test", sqpR};
31 Variable var{"Var test"};
32 var.setRange(sqpR);
31 var.setCacheRange(sqpCR);
33 var.setCacheRange(sqpCR);
32
34
33 // 1: [ts,te] < varTS
35 // 1: [ts,te] < varTS
34 auto ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
36 auto ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
35 auto te = QDateTime{QDate{2017, 01, 01}, QTime{2, 1, 0, 0}};
37 auto te = QDateTime{QDate{2017, 01, 01}, QTime{2, 1, 0, 0}};
36 auto sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
38 auto sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
37
39
38 auto notInCach = var.provideNotInCacheRangeList(sqp);
40 auto notInCach = var.provideNotInCacheRangeList(sqp);
39
41
40 QCOMPARE(notInCach.size(), 1);
42 QCOMPARE(notInCach.size(), 1);
41
43
42 auto notInCachRange = notInCach.first();
44 auto notInCachRange = notInCach.first();
43
45
44 QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts));
46 QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts));
45 QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te));
47 QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te));
46
48
47 // 2: ts < varTS < te < varTE
49 // 2: ts < varTS < te < varTE
48 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
50 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
49 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}};
51 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}};
50 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
52 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
51 notInCach = var.provideNotInCacheRangeList(sqp);
53 notInCach = var.provideNotInCacheRangeList(sqp);
52 QCOMPARE(notInCach.size(), 1);
54 QCOMPARE(notInCach.size(), 1);
53 notInCachRange = notInCach.first();
55 notInCachRange = notInCach.first();
54 QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts));
56 QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts));
55 QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(varCRS));
57 QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(varCRS));
56
58
57 // 3: varTS < ts < te < varTE
59 // 3: varTS < ts < te < varTE
58 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 20, 0}};
60 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 20, 0}};
59 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}};
61 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}};
60 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
62 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
61 notInCach = var.provideNotInCacheRangeList(sqp);
63 notInCach = var.provideNotInCacheRangeList(sqp);
62 QCOMPARE(notInCach.size(), 0);
64 QCOMPARE(notInCach.size(), 0);
63
65
64
66
65 // 4: varTS < ts < varTE < te
67 // 4: varTS < ts < varTE < te
66 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 20, 0}};
68 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 20, 0}};
67 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
69 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
68 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
70 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
69 notInCach = var.provideNotInCacheRangeList(sqp);
71 notInCach = var.provideNotInCacheRangeList(sqp);
70 QCOMPARE(notInCach.size(), 1);
72 QCOMPARE(notInCach.size(), 1);
71 notInCachRange = notInCach.first();
73 notInCachRange = notInCach.first();
72 QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(varCRE));
74 QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(varCRE));
73 QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te));
75 QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te));
74
76
75 // 5: varTS < varTE < ts < te
77 // 5: varTS < varTE < ts < te
76 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 20, 0}};
78 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 20, 0}};
77 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
79 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
78 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
80 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
79 notInCach = var.provideNotInCacheRangeList(sqp);
81 notInCach = var.provideNotInCacheRangeList(sqp);
80 QCOMPARE(notInCach.size(), 1);
82 QCOMPARE(notInCach.size(), 1);
81 notInCachRange = notInCach.first();
83 notInCachRange = notInCach.first();
82 QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts));
84 QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts));
83 QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te));
85 QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te));
84
86
85 // 6: ts <varTS < varTE < te
87 // 6: ts <varTS < varTE < te
86 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 1, 0, 0}};
88 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 1, 0, 0}};
87 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
89 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
88 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
90 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
89 notInCach = var.provideNotInCacheRangeList(sqp);
91 notInCach = var.provideNotInCacheRangeList(sqp);
90 QCOMPARE(notInCach.size(), 2);
92 QCOMPARE(notInCach.size(), 2);
91 notInCachRange = notInCach.first();
93 notInCachRange = notInCach.first();
92 QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts));
94 QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts));
93 QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(varCRS));
95 QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(varCRS));
94 notInCachRange = notInCach[1];
96 notInCachRange = notInCach[1];
95 QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(varCRE));
97 QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(varCRE));
96 QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te));
98 QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te));
97 }
99 }
98
100
99
101
100 void TestVariable::testInCacheRangeList()
102 void TestVariable::testInCacheRangeList()
101 {
103 {
102 auto varRS = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 20, 0}};
104 auto varRS = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 20, 0}};
103 auto varRE = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 40, 0}};
105 auto varRE = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 40, 0}};
104
106
105 auto sqpR = SqpRange{DateUtils::secondsSinceEpoch(varRS), DateUtils::secondsSinceEpoch(varRE)};
107 auto sqpR = SqpRange{DateUtils::secondsSinceEpoch(varRS), DateUtils::secondsSinceEpoch(varRE)};
106
108
107 auto varCRS = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 0, 0}};
109 auto varCRS = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 0, 0}};
108 auto varCRE = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}};
110 auto varCRE = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}};
109 auto sqpCR
111 auto sqpCR
110 = SqpRange{DateUtils::secondsSinceEpoch(varCRS), DateUtils::secondsSinceEpoch(varCRE)};
112 = SqpRange{DateUtils::secondsSinceEpoch(varCRS), DateUtils::secondsSinceEpoch(varCRE)};
111
113
112 Variable var{"Var test", sqpR};
114 Variable var{"Var test"};
115 var.setRange(sqpR);
113 var.setCacheRange(sqpCR);
116 var.setCacheRange(sqpCR);
114
117
115 // 1: [ts,te] < varTS
118 // 1: [ts,te] < varTS
116 auto ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
119 auto ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
117 auto te = QDateTime{QDate{2017, 01, 01}, QTime{2, 1, 0, 0}};
120 auto te = QDateTime{QDate{2017, 01, 01}, QTime{2, 1, 0, 0}};
118 auto sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
121 auto sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
119
122
120 auto notInCach = var.provideInCacheRangeList(sqp);
123 auto notInCach = var.provideInCacheRangeList(sqp);
121
124
122 QCOMPARE(notInCach.size(), 0);
125 QCOMPARE(notInCach.size(), 0);
123
126
124 // 2: ts < varTS < te < varTE
127 // 2: ts < varTS < te < varTE
125 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
128 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
126 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}};
129 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}};
127 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
130 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
128 notInCach = var.provideInCacheRangeList(sqp);
131 notInCach = var.provideInCacheRangeList(sqp);
129 QCOMPARE(notInCach.size(), 1);
132 QCOMPARE(notInCach.size(), 1);
130 auto notInCachRange = notInCach.first();
133 auto notInCachRange = notInCach.first();
131 QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(varCRS));
134 QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(varCRS));
132 QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te));
135 QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te));
133
136
134 // 3: varTS < ts < te < varTE
137 // 3: varTS < ts < te < varTE
135 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 20, 0}};
138 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 20, 0}};
136 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}};
139 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}};
137 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
140 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
138 notInCach = var.provideInCacheRangeList(sqp);
141 notInCach = var.provideInCacheRangeList(sqp);
139 QCOMPARE(notInCach.size(), 1);
142 QCOMPARE(notInCach.size(), 1);
140 notInCachRange = notInCach.first();
143 notInCachRange = notInCach.first();
141 QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts));
144 QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts));
142 QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te));
145 QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te));
143
146
144 // 4: varTS < ts < varTE < te
147 // 4: varTS < ts < varTE < te
145 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 20, 0}};
148 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 20, 0}};
146 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
149 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
147 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
150 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
148 notInCach = var.provideInCacheRangeList(sqp);
151 notInCach = var.provideInCacheRangeList(sqp);
149 QCOMPARE(notInCach.size(), 1);
152 QCOMPARE(notInCach.size(), 1);
150 notInCachRange = notInCach.first();
153 notInCachRange = notInCach.first();
151 QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts));
154 QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts));
152 QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(varCRE));
155 QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(varCRE));
153
156
154 // 5: varTS < varTE < ts < te
157 // 5: varTS < varTE < ts < te
155 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 20, 0}};
158 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 20, 0}};
156 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
159 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
157 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
160 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
158 notInCach = var.provideInCacheRangeList(sqp);
161 notInCach = var.provideInCacheRangeList(sqp);
159 QCOMPARE(notInCach.size(), 0);
162 QCOMPARE(notInCach.size(), 0);
160
163
161 // 6: ts <varTS < varTE < te
164 // 6: ts <varTS < varTE < te
162 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 1, 0, 0}};
165 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 1, 0, 0}};
163 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
166 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
164 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
167 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
165 notInCach = var.provideInCacheRangeList(sqp);
168 notInCach = var.provideInCacheRangeList(sqp);
166 QCOMPARE(notInCach.size(), 1);
169 QCOMPARE(notInCach.size(), 1);
167 notInCachRange = notInCach.first();
170 notInCachRange = notInCach.first();
168 QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(varCRS));
171 QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(varCRS));
169 QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(varCRE));
172 QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(varCRE));
170 }
173 }
171
174
172
175
173 QTEST_MAIN(TestVariable)
176 QTEST_MAIN(TestVariable)
174 #include "TestVariable.moc"
177 #include "TestVariable.moc"
@@ -1,331 +1,333
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableCacheController.h>
2 #include <Variable/VariableCacheController.h>
3
3
4 #include <QObject>
4 #include <QObject>
5 #include <QtTest>
5 #include <QtTest>
6
6
7 #include <memory>
7 #include <memory>
8
8
9 class TestVariableCacheController : public QObject {
9 class TestVariableCacheController : public QObject {
10 Q_OBJECT
10 Q_OBJECT
11
11
12 private slots:
12 private slots:
13 void testProvideNotInCacheDateTimeList();
13 void testProvideNotInCacheDateTimeList();
14
14
15 void testAddDateTime();
15 void testAddDateTime();
16 };
16 };
17
17
18
18
19 void TestVariableCacheController::testProvideNotInCacheDateTimeList()
19 void TestVariableCacheController::testProvideNotInCacheDateTimeList()
20 {
20 {
21 VariableCacheController variableCacheController{};
21 VariableCacheController variableCacheController{};
22
22
23 auto ts0 = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 0, 0}};
23 auto ts0 = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 0, 0}};
24 auto te0 = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}};
24 auto te0 = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}};
25 auto sqp0 = SqpRange{DateUtils::secondsSinceEpoch(ts0), DateUtils::secondsSinceEpoch(te0)};
25 auto sqp0 = SqpRange{DateUtils::secondsSinceEpoch(ts0), DateUtils::secondsSinceEpoch(te0)};
26
26
27 auto ts1 = QDateTime{QDate{2017, 01, 01}, QTime{2, 6, 0, 0}};
27 auto ts1 = QDateTime{QDate{2017, 01, 01}, QTime{2, 6, 0, 0}};
28 auto te1 = QDateTime{QDate{2017, 01, 01}, QTime{2, 8, 0, 0}};
28 auto te1 = QDateTime{QDate{2017, 01, 01}, QTime{2, 8, 0, 0}};
29 auto sqp1 = SqpRange{DateUtils::secondsSinceEpoch(ts1), DateUtils::secondsSinceEpoch(te1)};
29 auto sqp1 = SqpRange{DateUtils::secondsSinceEpoch(ts1), DateUtils::secondsSinceEpoch(te1)};
30
30
31 auto ts2 = QDateTime{QDate{2017, 01, 01}, QTime{2, 18, 0, 0}};
31 auto ts2 = QDateTime{QDate{2017, 01, 01}, QTime{2, 18, 0, 0}};
32 auto te2 = QDateTime{QDate{2017, 01, 01}, QTime{2, 20, 0, 0}};
32 auto te2 = QDateTime{QDate{2017, 01, 01}, QTime{2, 20, 0, 0}};
33 auto sqp2 = SqpRange{DateUtils::secondsSinceEpoch(ts2), DateUtils::secondsSinceEpoch(te2)};
33 auto sqp2 = SqpRange{DateUtils::secondsSinceEpoch(ts2), DateUtils::secondsSinceEpoch(te2)};
34
34
35 auto var0 = std::make_shared<Variable>("", sqp0);
35 auto var0 = std::make_shared<Variable>("");
36 var0->setRange(sqp0);
36
37
37 variableCacheController.addDateTime(var0, sqp0);
38 variableCacheController.addDateTime(var0, sqp0);
38 variableCacheController.addDateTime(var0, sqp1);
39 variableCacheController.addDateTime(var0, sqp1);
39 variableCacheController.addDateTime(var0, sqp2);
40 variableCacheController.addDateTime(var0, sqp2);
40
41
41 // first case [ts,te] < ts0
42 // first case [ts,te] < ts0
42 auto ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
43 auto ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
43 auto te = QDateTime{QDate{2017, 01, 01}, QTime{2, 1, 0, 0}};
44 auto te = QDateTime{QDate{2017, 01, 01}, QTime{2, 1, 0, 0}};
44 auto sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
45 auto sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
45
46
46
47
47 auto notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
48 auto notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
48
49
49 QCOMPARE(notInCach.size(), 1);
50 QCOMPARE(notInCach.size(), 1);
50 auto notInCacheSqp = notInCach.first();
51 auto notInCacheSqp = notInCach.first();
51 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(ts));
52 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(ts));
52 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(te));
53 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(te));
53
54
54
55
55 // second case ts < ts0 && ts0 < te <= te0
56 // second case ts < ts0 && ts0 < te <= te0
56 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
57 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
57 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}};
58 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}};
58 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
59 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
59
60
60
61
61 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
62 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
62
63
63 QCOMPARE(notInCach.size(), 1);
64 QCOMPARE(notInCach.size(), 1);
64 notInCacheSqp = notInCach.first();
65 notInCacheSqp = notInCach.first();
65 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(ts));
66 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(ts));
66 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(ts0));
67 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(ts0));
67
68
68 // 3th case ts < ts0 && te0 < te <= ts1
69 // 3th case ts < ts0 && te0 < te <= ts1
69 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
70 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
70 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
71 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
71 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
72 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
72
73
73
74
74 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
75 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
75
76
76 QCOMPARE(notInCach.size(), 2);
77 QCOMPARE(notInCach.size(), 2);
77 notInCacheSqp = notInCach.first();
78 notInCacheSqp = notInCach.first();
78 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(ts));
79 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(ts));
79 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(ts0));
80 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(ts0));
80
81
81 notInCacheSqp = notInCach.at(1);
82 notInCacheSqp = notInCach.at(1);
82 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(te0));
83 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(te0));
83 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(te));
84 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(te));
84
85
85 // 4th case ts < ts0 && ts1 < te <= te1
86 // 4th case ts < ts0 && ts1 < te <= te1
86 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
87 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
87 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 7, 0, 0}};
88 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 7, 0, 0}};
88 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
89 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
89
90
90
91
91 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
92 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
92
93
93 QCOMPARE(notInCach.size(), 2);
94 QCOMPARE(notInCach.size(), 2);
94 notInCacheSqp = notInCach.first();
95 notInCacheSqp = notInCach.first();
95 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(ts));
96 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(ts));
96 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(ts0));
97 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(ts0));
97
98
98 notInCacheSqp = notInCach.at(1);
99 notInCacheSqp = notInCach.at(1);
99 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(te0));
100 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(te0));
100 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(ts1));
101 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(ts1));
101
102
102 // 5th case ts < ts0 && te3 < te
103 // 5th case ts < ts0 && te3 < te
103 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
104 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
104 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 22, 0, 0}};
105 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 22, 0, 0}};
105 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
106 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
106
107
107
108
108 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
109 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
109
110
110 QCOMPARE(notInCach.size(), 4);
111 QCOMPARE(notInCach.size(), 4);
111 notInCacheSqp = notInCach.first();
112 notInCacheSqp = notInCach.first();
112 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(ts));
113 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(ts));
113 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(ts0));
114 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(ts0));
114
115
115 notInCacheSqp = notInCach.at(1);
116 notInCacheSqp = notInCach.at(1);
116 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(te0));
117 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(te0));
117 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(ts1));
118 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(ts1));
118
119
119 notInCacheSqp = notInCach.at(2);
120 notInCacheSqp = notInCach.at(2);
120 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(te1));
121 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(te1));
121 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(ts2));
122 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(ts2));
122
123
123 notInCacheSqp = notInCach.at(3);
124 notInCacheSqp = notInCach.at(3);
124 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(te2));
125 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(te2));
125 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(te));
126 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(te));
126
127
127
128
128 // 6th case ts2 < ts
129 // 6th case ts2 < ts
129 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 45, 0, 0}};
130 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 45, 0, 0}};
130 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 47, 0, 0}};
131 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 47, 0, 0}};
131 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
132 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
132
133
133
134
134 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
135 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
135
136
136 QCOMPARE(notInCach.size(), 1);
137 QCOMPARE(notInCach.size(), 1);
137 notInCacheSqp = notInCach.first();
138 notInCacheSqp = notInCach.first();
138 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(ts));
139 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(ts));
139 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(te));
140 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(te));
140
141
141 // 7th case ts = te0 && te < ts1
142 // 7th case ts = te0 && te < ts1
142 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}};
143 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}};
143 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
144 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
144 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
145 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
145
146
146
147
147 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
148 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
148
149
149 QCOMPARE(notInCach.size(), 1);
150 QCOMPARE(notInCach.size(), 1);
150 notInCacheSqp = notInCach.first();
151 notInCacheSqp = notInCach.first();
151 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(te0));
152 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(te0));
152 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(te));
153 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(te));
153
154
154 // 8th case ts0 < ts < te0 && te < ts1
155 // 8th case ts0 < ts < te0 && te < ts1
155 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}};
156 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}};
156 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
157 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
157 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
158 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
158
159
159
160
160 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
161 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
161
162
162 QCOMPARE(notInCach.size(), 1);
163 QCOMPARE(notInCach.size(), 1);
163 notInCacheSqp = notInCach.first();
164 notInCacheSqp = notInCach.first();
164 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(te0));
165 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(te0));
165 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(te));
166 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(te));
166
167
167 // 9th case ts0 < ts < te0 && ts1 < te < te1
168 // 9th case ts0 < ts < te0 && ts1 < te < te1
168 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}};
169 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}};
169 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 7, 0, 0}};
170 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 7, 0, 0}};
170 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
171 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
171
172
172
173
173 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
174 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
174
175
175 QCOMPARE(notInCach.size(), 1);
176 QCOMPARE(notInCach.size(), 1);
176 notInCacheSqp = notInCach.first();
177 notInCacheSqp = notInCach.first();
177 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(te0));
178 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(te0));
178 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(ts1));
179 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(ts1));
179
180
180 // 10th case te1 < ts < te < ts2
181 // 10th case te1 < ts < te < ts2
181 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 9, 0, 0}};
182 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 9, 0, 0}};
182 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 10, 0, 0}};
183 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 10, 0, 0}};
183 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
184 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
184
185
185
186
186 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
187 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
187
188
188 QCOMPARE(notInCach.size(), 1);
189 QCOMPARE(notInCach.size(), 1);
189 notInCacheSqp = notInCach.first();
190 notInCacheSqp = notInCach.first();
190 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(ts));
191 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(ts));
191 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(te));
192 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(te));
192
193
193 // 11th case te0 < ts < ts1 && te3 < te
194 // 11th case te0 < ts < ts1 && te3 < te
194 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
195 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
195 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 47, 0, 0}};
196 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 47, 0, 0}};
196 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
197 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
197
198
198
199
199 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
200 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
200
201
201 QCOMPARE(notInCach.size(), 3);
202 QCOMPARE(notInCach.size(), 3);
202 notInCacheSqp = notInCach.first();
203 notInCacheSqp = notInCach.first();
203 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(ts));
204 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(ts));
204 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(ts1));
205 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(ts1));
205
206
206 notInCacheSqp = notInCach.at(1);
207 notInCacheSqp = notInCach.at(1);
207 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(te1));
208 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(te1));
208 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(ts2));
209 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(ts2));
209
210
210 notInCacheSqp = notInCach.at(2);
211 notInCacheSqp = notInCach.at(2);
211 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(te2));
212 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(te2));
212 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(te));
213 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(te));
213
214
214 // 12th case te0 < ts < ts1 && te3 < te
215 // 12th case te0 < ts < ts1 && te3 < te
215 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
216 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
216 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 10, 0, 0}};
217 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 10, 0, 0}};
217 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
218 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
218
219
219 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
220 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
220
221
221 QCOMPARE(notInCach.size(), 2);
222 QCOMPARE(notInCach.size(), 2);
222 notInCacheSqp = notInCach.first();
223 notInCacheSqp = notInCach.first();
223 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(ts));
224 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(ts));
224 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(ts1));
225 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(ts1));
225
226
226 notInCacheSqp = notInCach.at(1);
227 notInCacheSqp = notInCach.at(1);
227 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(te1));
228 QCOMPARE(notInCacheSqp.m_TStart, DateUtils::secondsSinceEpoch(te1));
228 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(te));
229 QCOMPARE(notInCacheSqp.m_TEnd, DateUtils::secondsSinceEpoch(te));
229
230
230
231
231 // 12th case ts0 < ts < te0
232 // 12th case ts0 < ts < te0
232 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 10, 0}};
233 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 10, 0}};
233 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 50, 0}};
234 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 50, 0}};
234 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
235 sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)};
235
236
236 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
237 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
237 QCOMPARE(notInCach.size(), 0);
238 QCOMPARE(notInCach.size(), 0);
238 }
239 }
239
240
240
241
241 void TestVariableCacheController::testAddDateTime()
242 void TestVariableCacheController::testAddDateTime()
242 {
243 {
243 VariableCacheController variableCacheController{};
244 VariableCacheController variableCacheController{};
244
245
245 auto ts0 = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 0, 0}};
246 auto ts0 = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 0, 0}};
246 auto te0 = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}};
247 auto te0 = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}};
247 auto sqp0 = SqpRange{DateUtils::secondsSinceEpoch(ts0), DateUtils::secondsSinceEpoch(te0)};
248 auto sqp0 = SqpRange{DateUtils::secondsSinceEpoch(ts0), DateUtils::secondsSinceEpoch(te0)};
248
249
249 auto ts1 = QDateTime{QDate{2017, 01, 01}, QTime{2, 6, 0, 0}};
250 auto ts1 = QDateTime{QDate{2017, 01, 01}, QTime{2, 6, 0, 0}};
250 auto te1 = QDateTime{QDate{2017, 01, 01}, QTime{2, 8, 0, 0}};
251 auto te1 = QDateTime{QDate{2017, 01, 01}, QTime{2, 8, 0, 0}};
251 auto sqp1 = SqpRange{DateUtils::secondsSinceEpoch(ts1), DateUtils::secondsSinceEpoch(te1)};
252 auto sqp1 = SqpRange{DateUtils::secondsSinceEpoch(ts1), DateUtils::secondsSinceEpoch(te1)};
252
253
253 auto ts2 = QDateTime{QDate{2017, 01, 01}, QTime{2, 18, 0, 0}};
254 auto ts2 = QDateTime{QDate{2017, 01, 01}, QTime{2, 18, 0, 0}};
254 auto te2 = QDateTime{QDate{2017, 01, 01}, QTime{2, 20, 0, 0}};
255 auto te2 = QDateTime{QDate{2017, 01, 01}, QTime{2, 20, 0, 0}};
255 auto sqp2 = SqpRange{DateUtils::secondsSinceEpoch(ts2), DateUtils::secondsSinceEpoch(te2)};
256 auto sqp2 = SqpRange{DateUtils::secondsSinceEpoch(ts2), DateUtils::secondsSinceEpoch(te2)};
256
257
257 auto ts01 = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}};
258 auto ts01 = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}};
258 auto te01 = QDateTime{QDate{2017, 01, 01}, QTime{2, 6, 0, 0}};
259 auto te01 = QDateTime{QDate{2017, 01, 01}, QTime{2, 6, 0, 0}};
259 auto sqp01 = SqpRange{DateUtils::secondsSinceEpoch(ts01), DateUtils::secondsSinceEpoch(te01)};
260 auto sqp01 = SqpRange{DateUtils::secondsSinceEpoch(ts01), DateUtils::secondsSinceEpoch(te01)};
260
261
261 auto ts3 = QDateTime{QDate{2017, 01, 01}, QTime{2, 14, 0, 0}};
262 auto ts3 = QDateTime{QDate{2017, 01, 01}, QTime{2, 14, 0, 0}};
262 auto te3 = QDateTime{QDate{2017, 01, 01}, QTime{2, 16, 0, 0}};
263 auto te3 = QDateTime{QDate{2017, 01, 01}, QTime{2, 16, 0, 0}};
263 auto sqp3 = SqpRange{DateUtils::secondsSinceEpoch(ts3), DateUtils::secondsSinceEpoch(te3)};
264 auto sqp3 = SqpRange{DateUtils::secondsSinceEpoch(ts3), DateUtils::secondsSinceEpoch(te3)};
264
265
265 auto ts03 = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}};
266 auto ts03 = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}};
266 auto te03 = QDateTime{QDate{2017, 01, 01}, QTime{2, 22, 0, 0}};
267 auto te03 = QDateTime{QDate{2017, 01, 01}, QTime{2, 22, 0, 0}};
267 auto sqp03 = SqpRange{DateUtils::secondsSinceEpoch(ts03), DateUtils::secondsSinceEpoch(te03)};
268 auto sqp03 = SqpRange{DateUtils::secondsSinceEpoch(ts03), DateUtils::secondsSinceEpoch(te03)};
268
269
269
270
270 auto var0 = std::make_shared<Variable>("", sqp0);
271 auto var0 = std::make_shared<Variable>("");
272 var0->setRange(sqp0);
271
273
272
274
273 // First case: add the first interval to the variable :sqp0
275 // First case: add the first interval to the variable :sqp0
274 variableCacheController.addDateTime(var0, sqp0);
276 variableCacheController.addDateTime(var0, sqp0);
275 auto dateCacheList = variableCacheController.dateCacheList(var0);
277 auto dateCacheList = variableCacheController.dateCacheList(var0);
276 QCOMPARE(dateCacheList.count(), 1);
278 QCOMPARE(dateCacheList.count(), 1);
277 auto dateCache = dateCacheList.at(0);
279 auto dateCache = dateCacheList.at(0);
278 QCOMPARE(dateCache.m_TStart, DateUtils::secondsSinceEpoch(ts0));
280 QCOMPARE(dateCache.m_TStart, DateUtils::secondsSinceEpoch(ts0));
279 QCOMPARE(dateCache.m_TEnd, DateUtils::secondsSinceEpoch(te0));
281 QCOMPARE(dateCache.m_TEnd, DateUtils::secondsSinceEpoch(te0));
280
282
281 // 2nd case: add a second interval : sqp1 > sqp0
283 // 2nd case: add a second interval : sqp1 > sqp0
282 variableCacheController.addDateTime(var0, sqp1);
284 variableCacheController.addDateTime(var0, sqp1);
283 dateCacheList = variableCacheController.dateCacheList(var0);
285 dateCacheList = variableCacheController.dateCacheList(var0);
284 QCOMPARE(dateCacheList.count(), 2);
286 QCOMPARE(dateCacheList.count(), 2);
285 dateCache = dateCacheList.at(0);
287 dateCache = dateCacheList.at(0);
286 QCOMPARE(dateCache.m_TStart, DateUtils::secondsSinceEpoch(ts0));
288 QCOMPARE(dateCache.m_TStart, DateUtils::secondsSinceEpoch(ts0));
287 QCOMPARE(dateCache.m_TEnd, DateUtils::secondsSinceEpoch(te0));
289 QCOMPARE(dateCache.m_TEnd, DateUtils::secondsSinceEpoch(te0));
288
290
289 dateCache = dateCacheList.at(1);
291 dateCache = dateCacheList.at(1);
290 QCOMPARE(dateCache.m_TStart, DateUtils::secondsSinceEpoch(ts1));
292 QCOMPARE(dateCache.m_TStart, DateUtils::secondsSinceEpoch(ts1));
291 QCOMPARE(dateCache.m_TEnd, DateUtils::secondsSinceEpoch(te1));
293 QCOMPARE(dateCache.m_TEnd, DateUtils::secondsSinceEpoch(te1));
292
294
293 // 3th case: merge sqp0 & sqp1 with sqp01
295 // 3th case: merge sqp0 & sqp1 with sqp01
294 variableCacheController.addDateTime(var0, sqp01);
296 variableCacheController.addDateTime(var0, sqp01);
295 dateCacheList = variableCacheController.dateCacheList(var0);
297 dateCacheList = variableCacheController.dateCacheList(var0);
296 QCOMPARE(dateCacheList.count(), 1);
298 QCOMPARE(dateCacheList.count(), 1);
297 dateCache = dateCacheList.at(0);
299 dateCache = dateCacheList.at(0);
298 QCOMPARE(dateCache.m_TStart, DateUtils::secondsSinceEpoch(ts0));
300 QCOMPARE(dateCache.m_TStart, DateUtils::secondsSinceEpoch(ts0));
299 QCOMPARE(dateCache.m_TEnd, DateUtils::secondsSinceEpoch(te1));
301 QCOMPARE(dateCache.m_TEnd, DateUtils::secondsSinceEpoch(te1));
300
302
301
303
302 // 4th case: add a second interval : sqp1 > sqp0
304 // 4th case: add a second interval : sqp1 > sqp0
303 variableCacheController.addDateTime(var0, sqp2);
305 variableCacheController.addDateTime(var0, sqp2);
304 variableCacheController.addDateTime(var0, sqp3);
306 variableCacheController.addDateTime(var0, sqp3);
305 dateCacheList = variableCacheController.dateCacheList(var0);
307 dateCacheList = variableCacheController.dateCacheList(var0);
306 QCOMPARE(dateCacheList.count(), 3);
308 QCOMPARE(dateCacheList.count(), 3);
307 dateCache = dateCacheList.at(0);
309 dateCache = dateCacheList.at(0);
308 QCOMPARE(dateCache.m_TStart, DateUtils::secondsSinceEpoch(ts0));
310 QCOMPARE(dateCache.m_TStart, DateUtils::secondsSinceEpoch(ts0));
309 QCOMPARE(dateCache.m_TEnd, DateUtils::secondsSinceEpoch(te1));
311 QCOMPARE(dateCache.m_TEnd, DateUtils::secondsSinceEpoch(te1));
310
312
311 dateCache = dateCacheList.at(1);
313 dateCache = dateCacheList.at(1);
312 QCOMPARE(dateCache.m_TStart, DateUtils::secondsSinceEpoch(ts3));
314 QCOMPARE(dateCache.m_TStart, DateUtils::secondsSinceEpoch(ts3));
313 QCOMPARE(dateCache.m_TEnd, DateUtils::secondsSinceEpoch(te3));
315 QCOMPARE(dateCache.m_TEnd, DateUtils::secondsSinceEpoch(te3));
314
316
315 dateCache = dateCacheList.at(2);
317 dateCache = dateCacheList.at(2);
316 QCOMPARE(dateCache.m_TStart, DateUtils::secondsSinceEpoch(ts2));
318 QCOMPARE(dateCache.m_TStart, DateUtils::secondsSinceEpoch(ts2));
317 QCOMPARE(dateCache.m_TEnd, DateUtils::secondsSinceEpoch(te2));
319 QCOMPARE(dateCache.m_TEnd, DateUtils::secondsSinceEpoch(te2));
318
320
319
321
320 // 5th case: merge all interval
322 // 5th case: merge all interval
321 variableCacheController.addDateTime(var0, sqp03);
323 variableCacheController.addDateTime(var0, sqp03);
322 dateCacheList = variableCacheController.dateCacheList(var0);
324 dateCacheList = variableCacheController.dateCacheList(var0);
323 QCOMPARE(dateCacheList.count(), 1);
325 QCOMPARE(dateCacheList.count(), 1);
324 dateCache = dateCacheList.at(0);
326 dateCache = dateCacheList.at(0);
325 QCOMPARE(dateCache.m_TStart, DateUtils::secondsSinceEpoch(ts0));
327 QCOMPARE(dateCache.m_TStart, DateUtils::secondsSinceEpoch(ts0));
326 QCOMPARE(dateCache.m_TEnd, DateUtils::secondsSinceEpoch(te03));
328 QCOMPARE(dateCache.m_TEnd, DateUtils::secondsSinceEpoch(te03));
327 }
329 }
328
330
329
331
330 QTEST_MAIN(TestVariableCacheController)
332 QTEST_MAIN(TestVariableCacheController)
331 #include "TestVariableCacheController.moc"
333 #include "TestVariableCacheController.moc"
@@ -1,267 +1,265
1 #include "AmdaProvider.h"
1 #include "AmdaProvider.h"
2 #include "AmdaDefs.h"
2 #include "AmdaDefs.h"
3 #include "AmdaResultParser.h"
3 #include "AmdaResultParser.h"
4
4
5 #include <Common/DateUtils.h>
5 #include <Common/DateUtils.h>
6 #include <Data/DataProviderParameters.h>
6 #include <Data/DataProviderParameters.h>
7 #include <Network/NetworkController.h>
7 #include <Network/NetworkController.h>
8 #include <SqpApplication.h>
8 #include <SqpApplication.h>
9 #include <Variable/Variable.h>
9 #include <Variable/Variable.h>
10
10
11 #include <QNetworkAccessManager>
11 #include <QNetworkAccessManager>
12 #include <QNetworkReply>
12 #include <QNetworkReply>
13 #include <QTemporaryFile>
13 #include <QTemporaryFile>
14 #include <QThread>
14 #include <QThread>
15
15
16 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
16 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
17
17
18 namespace {
18 namespace {
19
19
20 /// URL format for a request on AMDA server. The parameters are as follows:
20 /// URL format for a request on AMDA server. The parameters are as follows:
21 /// - %1: start date
21 /// - %1: start date
22 /// - %2: end date
22 /// - %2: end date
23 /// - %3: parameter id
23 /// - %3: parameter id
24 const auto AMDA_URL_FORMAT = QStringLiteral(
24 const auto AMDA_URL_FORMAT = QStringLiteral(
25 "http://amda.irap.omp.eu/php/rest/"
25 "http://amda.irap.omp.eu/php/rest/"
26 "getParameter.php?startTime=%1&stopTime=%2&parameterID=%3&outputFormat=ASCII&"
26 "getParameter.php?startTime=%1&stopTime=%2&parameterID=%3&outputFormat=ASCII&"
27 "timeFormat=ISO8601&gzip=0");
27 "timeFormat=ISO8601&gzip=0");
28
28
29 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
29 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
30 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
30 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
31
31
32 /// Formats a time to a date that can be passed in URL
32 /// Formats a time to a date that can be passed in URL
33 QString dateFormat(double sqpRange) noexcept
33 QString dateFormat(double sqpRange) noexcept
34 {
34 {
35 auto dateTime = DateUtils::dateTime(sqpRange);
35 auto dateTime = DateUtils::dateTime(sqpRange);
36 return dateTime.toString(AMDA_TIME_FORMAT);
36 return dateTime.toString(AMDA_TIME_FORMAT);
37 }
37 }
38
38
39 AmdaResultParser::ValueType valueType(const QString &valueType)
39 AmdaResultParser::ValueType valueType(const QString &valueType)
40 {
40 {
41 if (valueType == QStringLiteral("scalar")) {
41 if (valueType == QStringLiteral("scalar")) {
42 return AmdaResultParser::ValueType::SCALAR;
42 return AmdaResultParser::ValueType::SCALAR;
43 }
43 }
44 else if (valueType == QStringLiteral("vector")) {
44 else if (valueType == QStringLiteral("vector")) {
45 return AmdaResultParser::ValueType::VECTOR;
45 return AmdaResultParser::ValueType::VECTOR;
46 }
46 }
47 else {
47 else {
48 return AmdaResultParser::ValueType::UNKNOWN;
48 return AmdaResultParser::ValueType::UNKNOWN;
49 }
49 }
50 }
50 }
51
51
52 } // namespace
52 } // namespace
53
53
54 AmdaProvider::AmdaProvider()
54 AmdaProvider::AmdaProvider()
55 {
55 {
56 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::AmdaProvider") << QThread::currentThread();
56 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::AmdaProvider") << QThread::currentThread();
57 if (auto app = sqpApp) {
57 if (auto app = sqpApp) {
58 auto &networkController = app->networkController();
58 auto &networkController = app->networkController();
59 connect(this, SIGNAL(requestConstructed(std::shared_ptr<QNetworkRequest>, QUuid,
59 connect(this, SIGNAL(requestConstructed(std::shared_ptr<QNetworkRequest>, QUuid,
60 std::function<void(QNetworkReply *, QUuid)>)),
60 std::function<void(QNetworkReply *, QUuid)>)),
61 &networkController,
61 &networkController,
62 SLOT(onProcessRequested(std::shared_ptr<QNetworkRequest>, QUuid,
62 SLOT(onProcessRequested(std::shared_ptr<QNetworkRequest>, QUuid,
63 std::function<void(QNetworkReply *, QUuid)>)));
63 std::function<void(QNetworkReply *, QUuid)>)));
64
64
65
65
66 connect(&sqpApp->networkController(),
66 connect(&sqpApp->networkController(),
67 SIGNAL(replyDownloadProgress(QUuid, std::shared_ptr<QNetworkRequest>, double)),
67 SIGNAL(replyDownloadProgress(QUuid, std::shared_ptr<QNetworkRequest>, double)),
68 this,
68 this,
69 SLOT(onReplyDownloadProgress(QUuid, std::shared_ptr<QNetworkRequest>, double)));
69 SLOT(onReplyDownloadProgress(QUuid, std::shared_ptr<QNetworkRequest>, double)));
70 }
70 }
71 }
71 }
72
72
73 std::shared_ptr<IDataProvider> AmdaProvider::clone() const
73 std::shared_ptr<IDataProvider> AmdaProvider::clone() const
74 {
74 {
75 // No copy is made in the clone
75 // No copy is made in the clone
76 return std::make_shared<AmdaProvider>();
76 return std::make_shared<AmdaProvider>();
77 }
77 }
78
78
79 void AmdaProvider::requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters)
79 void AmdaProvider::requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters)
80 {
80 {
81 // NOTE: Try to use multithread if possible
81 // NOTE: Try to use multithread if possible
82 const auto times = parameters.m_Times;
82 const auto times = parameters.m_Times;
83 const auto data = parameters.m_Data;
83 const auto data = parameters.m_Data;
84 for (const auto &dateTime : qAsConst(times)) {
84 for (const auto &dateTime : qAsConst(times)) {
85 this->retrieveData(acqIdentifier, dateTime, data);
85 this->retrieveData(acqIdentifier, dateTime, data);
86
86
87
87
88 // TORM when AMDA will support quick asynchrone request
88 // TORM when AMDA will support quick asynchrone request
89 QThread::msleep(1000);
89 QThread::msleep(1000);
90 }
90 }
91 }
91 }
92
92
93 void AmdaProvider::requestDataAborting(QUuid acqIdentifier)
93 void AmdaProvider::requestDataAborting(QUuid acqIdentifier)
94 {
94 {
95 if (auto app = sqpApp) {
95 if (auto app = sqpApp) {
96 auto &networkController = app->networkController();
96 auto &networkController = app->networkController();
97 networkController.onReplyCanceled(acqIdentifier);
97 networkController.onReplyCanceled(acqIdentifier);
98 }
98 }
99 }
99 }
100
100
101 void AmdaProvider::onReplyDownloadProgress(QUuid acqIdentifier,
101 void AmdaProvider::onReplyDownloadProgress(QUuid acqIdentifier,
102 std::shared_ptr<QNetworkRequest> networkRequest,
102 std::shared_ptr<QNetworkRequest> networkRequest,
103 double progress)
103 double progress)
104 {
104 {
105 qCDebug(LOG_AmdaProvider()) << tr("onReplyDownloadProgress") << acqIdentifier
105 qCDebug(LOG_AmdaProvider()) << tr("onReplyDownloadProgress") << acqIdentifier
106 << networkRequest.get() << progress;
106 << networkRequest.get() << progress;
107 auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
107 auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
108 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
108 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
109
109
110 qCDebug(LOG_AmdaProvider()) << tr("1 onReplyDownloadProgress found") << progress;
111 auto requestPtr = networkRequest;
110 auto requestPtr = networkRequest;
112 auto findRequest = [requestPtr](const auto &entry) { return requestPtr == entry.first; };
111 auto findRequest = [requestPtr](const auto &entry) { return requestPtr == entry.first; };
113
112
114 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
113 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
115 auto requestProgressMapEnd = requestProgressMap.end();
114 auto requestProgressMapEnd = requestProgressMap.end();
116 auto requestProgressMapIt
115 auto requestProgressMapIt
117 = std::find_if(requestProgressMap.begin(), requestProgressMapEnd, findRequest);
116 = std::find_if(requestProgressMap.begin(), requestProgressMapEnd, findRequest);
118
117
119 if (requestProgressMapIt != requestProgressMapEnd) {
118 if (requestProgressMapIt != requestProgressMapEnd) {
120 requestProgressMapIt->second = progress;
119 requestProgressMapIt->second = progress;
121 }
120 }
122 else {
121 else {
123 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve Request in progress")
122 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve Request in progress")
124 << acqIdentifier << networkRequest.get() << progress;
123 << acqIdentifier << networkRequest.get() << progress;
125 }
124 }
126 }
125 }
127
126
128 acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
127 acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
129 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
128 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
130 double finalProgress = 0.0;
129 double finalProgress = 0.0;
131
130
132 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
131 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
133 auto fraq = requestProgressMap.size();
132 auto fraq = requestProgressMap.size();
134
133
135 for (auto requestProgress : requestProgressMap) {
134 for (auto requestProgress : requestProgressMap) {
136 finalProgress += requestProgress.second;
135 finalProgress += requestProgress.second;
137 qCDebug(LOG_AmdaProvider()) << tr("current final progress without freq:")
136 qCDebug(LOG_AmdaProvider()) << tr("current final progress without freq:")
138 << finalProgress << requestProgress.second;
137 << finalProgress << requestProgress.second;
139 }
138 }
140
139
141 if (fraq > 0) {
140 if (fraq > 0) {
142 finalProgress = finalProgress / fraq;
141 finalProgress = finalProgress / fraq;
143 }
142 }
144
143
145 qCDebug(LOG_AmdaProvider()) << tr("2 onReplyDownloadProgress final progress") << fraq
144 qCDebug(LOG_AmdaProvider()) << tr("2 onReplyDownloadProgress final progress") << fraq
146 << finalProgress;
145 << finalProgress;
147 emit dataProvidedProgress(acqIdentifier, finalProgress);
146 emit dataProvidedProgress(acqIdentifier, finalProgress);
148 }
147 }
149 else {
148 else {
150 emit dataProvidedProgress(acqIdentifier, 0.0);
149 emit dataProvidedProgress(acqIdentifier, 0.0);
151 }
150 }
152 }
151 }
153
152
154 void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVariantHash &data)
153 void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVariantHash &data)
155 {
154 {
156 // Retrieves product ID from data: if the value is invalid, no request is made
155 // Retrieves product ID from data: if the value is invalid, no request is made
157 auto productId = data.value(AMDA_XML_ID_KEY).toString();
156 auto productId = data.value(AMDA_XML_ID_KEY).toString();
158 if (productId.isNull()) {
157 if (productId.isNull()) {
159 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
158 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
160 return;
159 return;
161 }
160 }
162 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData") << dateTime;
163
161
164 // Retrieves the data type that determines whether the expected format for the result file is
162 // Retrieves the data type that determines whether the expected format for the result file is
165 // scalar, vector...
163 // scalar, vector...
166 auto productValueType = valueType(data.value(AMDA_DATA_TYPE_KEY).toString());
164 auto productValueType = valueType(data.value(AMDA_DATA_TYPE_KEY).toString());
167
165
168 // /////////// //
166 // /////////// //
169 // Creates URL //
167 // Creates URL //
170 // /////////// //
168 // /////////// //
171
169
172 auto startDate = dateFormat(dateTime.m_TStart);
170 auto startDate = dateFormat(dateTime.m_TStart);
173 auto endDate = dateFormat(dateTime.m_TEnd);
171 auto endDate = dateFormat(dateTime.m_TEnd);
174
172
175 auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
173 auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
176 qCDebug(LOG_AmdaProvider()) << tr("TORM AmdaProvider::retrieveData url:") << url;
174 qCDebug(LOG_AmdaProvider()) << tr("TORM AmdaProvider::retrieveData url:") << url;
177 auto tempFile = std::make_shared<QTemporaryFile>();
175 auto tempFile = std::make_shared<QTemporaryFile>();
178
176
179 // LAMBDA
177 // LAMBDA
180 auto httpDownloadFinished = [this, dateTime, tempFile,
178 auto httpDownloadFinished = [this, dateTime, tempFile,
181 productValueType](QNetworkReply *reply, QUuid dataId) noexcept {
179 productValueType](QNetworkReply *reply, QUuid dataId) noexcept {
182
180
183 // Don't do anything if the reply was abort
181 // Don't do anything if the reply was abort
184 if (reply->error() != QNetworkReply::OperationCanceledError) {
182 if (reply->error() != QNetworkReply::OperationCanceledError) {
185
183
186 if (tempFile) {
184 if (tempFile) {
187 auto replyReadAll = reply->readAll();
185 auto replyReadAll = reply->readAll();
188 if (!replyReadAll.isEmpty()) {
186 if (!replyReadAll.isEmpty()) {
189 tempFile->write(replyReadAll);
187 tempFile->write(replyReadAll);
190 }
188 }
191 tempFile->close();
189 tempFile->close();
192
190
193 // Parse results file
191 // Parse results file
194 if (auto dataSeries
192 if (auto dataSeries
195 = AmdaResultParser::readTxt(tempFile->fileName(), productValueType)) {
193 = AmdaResultParser::readTxt(tempFile->fileName(), productValueType)) {
196 emit dataProvided(dataId, dataSeries, dateTime);
194 emit dataProvided(dataId, dataSeries, dateTime);
197 }
195 }
198 else {
196 else {
199 /// @todo ALX : debug
197 /// @todo ALX : debug
200 }
198 }
201 }
199 }
202 m_AcqIdToRequestProgressMap.erase(dataId);
200 m_AcqIdToRequestProgressMap.erase(dataId);
203 }
201 }
204
202
205 };
203 };
206 auto httpFinishedLambda
204 auto httpFinishedLambda
207 = [this, httpDownloadFinished, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
205 = [this, httpDownloadFinished, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
208
206
209 // Don't do anything if the reply was abort
207 // Don't do anything if the reply was abort
210 if (reply->error() != QNetworkReply::OperationCanceledError) {
208 if (reply->error() != QNetworkReply::OperationCanceledError) {
211 auto downloadFileUrl = QUrl{QString{reply->readAll()}};
209 auto downloadFileUrl = QUrl{QString{reply->readAll()}};
212
210
213 qCInfo(LOG_AmdaProvider())
211 qCDebug(LOG_AmdaProvider())
214 << tr("TORM AmdaProvider::retrieveData downloadFileUrl:") << downloadFileUrl;
212 << tr("TORM AmdaProvider::retrieveData downloadFileUrl:") << downloadFileUrl;
215 // Executes request for downloading file //
213 // Executes request for downloading file //
216
214
217 // Creates destination file
215 // Creates destination file
218 if (tempFile->open()) {
216 if (tempFile->open()) {
219 // Executes request and store the request for progression
217 // Executes request and store the request for progression
220 auto request = std::make_shared<QNetworkRequest>(downloadFileUrl);
218 auto request = std::make_shared<QNetworkRequest>(downloadFileUrl);
221 updateRequestProgress(dataId, request, 0.0);
219 updateRequestProgress(dataId, request, 0.0);
222 emit requestConstructed(request, dataId, httpDownloadFinished);
220 emit requestConstructed(request, dataId, httpDownloadFinished);
223 }
221 }
224 }
222 }
225 else {
223 else {
226 m_AcqIdToRequestProgressMap.erase(dataId);
224 m_AcqIdToRequestProgressMap.erase(dataId);
227 }
225 }
228 };
226 };
229
227
230 // //////////////// //
228 // //////////////// //
231 // Executes request //
229 // Executes request //
232 // //////////////// //
230 // //////////////// //
233
231
234 auto request = std::make_shared<QNetworkRequest>(url);
232 auto request = std::make_shared<QNetworkRequest>(url);
235 qCDebug(LOG_AmdaProvider()) << tr("First Request creation") << request.get();
233 qCDebug(LOG_AmdaProvider()) << tr("First Request creation") << request.get();
236 updateRequestProgress(token, request, 0.0);
234 updateRequestProgress(token, request, 0.0);
237
235
238 emit requestConstructed(request, token, httpFinishedLambda);
236 emit requestConstructed(request, token, httpFinishedLambda);
239 }
237 }
240
238
241 void AmdaProvider::updateRequestProgress(QUuid acqIdentifier,
239 void AmdaProvider::updateRequestProgress(QUuid acqIdentifier,
242 std::shared_ptr<QNetworkRequest> request, double progress)
240 std::shared_ptr<QNetworkRequest> request, double progress)
243 {
241 {
244 auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
242 auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
245 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
243 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
246 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
244 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
247 auto requestProgressMapIt = requestProgressMap.find(request);
245 auto requestProgressMapIt = requestProgressMap.find(request);
248 if (requestProgressMapIt != requestProgressMap.end()) {
246 if (requestProgressMapIt != requestProgressMap.end()) {
249 requestProgressMapIt->second = progress;
247 requestProgressMapIt->second = progress;
250 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new progress for request")
248 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new progress for request")
251 << acqIdentifier << request.get() << progress;
249 << acqIdentifier << request.get() << progress;
252 }
250 }
253 else {
251 else {
254 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new request") << acqIdentifier
252 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new request") << acqIdentifier
255 << request.get() << progress;
253 << request.get() << progress;
256 acqIdToRequestProgressMapIt->second.insert(std::make_pair(request, progress));
254 acqIdToRequestProgressMapIt->second.insert(std::make_pair(request, progress));
257 }
255 }
258 }
256 }
259 else {
257 else {
260 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new acqIdentifier")
258 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new acqIdentifier")
261 << acqIdentifier << request.get() << progress;
259 << acqIdentifier << request.get() << progress;
262 auto requestProgressMap = std::map<std::shared_ptr<QNetworkRequest>, double>{};
260 auto requestProgressMap = std::map<std::shared_ptr<QNetworkRequest>, double>{};
263 requestProgressMap.insert(std::make_pair(request, progress));
261 requestProgressMap.insert(std::make_pair(request, progress));
264 m_AcqIdToRequestProgressMap.insert(
262 m_AcqIdToRequestProgressMap.insert(
265 std::make_pair(acqIdentifier, std::move(requestProgressMap)));
263 std::make_pair(acqIdentifier, std::move(requestProgressMap)));
266 }
264 }
267 }
265 }
@@ -1,197 +1,195
1 #include "AmdaProvider.h"
1 #include "AmdaProvider.h"
2 #include "AmdaResultParser.h"
2 #include "AmdaResultParser.h"
3
3
4 #include "SqpApplication.h"
4 #include "SqpApplication.h"
5 #include <Data/DataSeries.h>
5 #include <Data/DataSeries.h>
6 #include <Data/IDataSeries.h>
6 #include <Data/IDataSeries.h>
7 #include <Data/ScalarSeries.h>
7 #include <Data/ScalarSeries.h>
8 #include <Time/TimeController.h>
8 #include <Time/TimeController.h>
9 #include <Variable/Variable.h>
9 #include <Variable/Variable.h>
10 #include <Variable/VariableController.h>
10 #include <Variable/VariableController.h>
11
11
12 #include <QObject>
12 #include <QObject>
13 #include <QtTest>
13 #include <QtTest>
14
14
15 #include <memory>
15 #include <memory>
16
16
17 // TEST with REF:
17 // TEST with REF:
18 // AmdaData-2012-01-01-12-00-00_2012-01-03-12-00-00
18 // AmdaData-2012-01-01-12-00-00_2012-01-03-12-00-00
19 // imf(0) - Type : Local Parameter @ CDPP/AMDA -
19 // imf(0) - Type : Local Parameter @ CDPP/AMDA -
20 // Name : bx_gse - Units : nT - Size : 1 -
20 // Name : bx_gse - Units : nT - Size : 1 -
21 // Frame : GSE - Mission : ACE -
21 // Frame : GSE - Mission : ACE -
22 // Instrument : MFI - Dataset : mfi_final-prelim
22 // Instrument : MFI - Dataset : mfi_final-prelim
23 // REFERENCE DOWNLOAD FILE =
23 // REFERENCE DOWNLOAD FILE =
24 // http://amda.irap.omp.eu/php/rest/getParameter.php?startTime=2012-01-01T12:00:00&stopTime=2012-01-03T12:00:00&parameterID=imf(0)&outputFormat=ASCII&timeFormat=ISO8601&gzip=0
24 // http://amda.irap.omp.eu/php/rest/getParameter.php?startTime=2012-01-01T12:00:00&stopTime=2012-01-03T12:00:00&parameterID=imf(0)&outputFormat=ASCII&timeFormat=ISO8601&gzip=0
25
25
26 namespace {
26 namespace {
27
27
28 /// Path for the tests
28 /// Path for the tests
29 const auto TESTS_RESOURCES_PATH
29 const auto TESTS_RESOURCES_PATH
30 = QFileInfo{QString{AMDA_TESTS_RESOURCES_DIR}, "TestAmdaAcquisition"}.absoluteFilePath();
30 = QFileInfo{QString{AMDA_TESTS_RESOURCES_DIR}, "TestAmdaAcquisition"}.absoluteFilePath();
31
31
32 const auto TESTS_AMDA_REF_FILE = QString{"AmdaData-2012-01-01-12-00-00_2012-01-03-12-00-00.txt"};
32 const auto TESTS_AMDA_REF_FILE = QString{"AmdaData-2012-01-01-12-00-00_2012-01-03-12-00-00.txt"};
33
33
34 template <typename T>
34 template <typename T>
35 bool compareDataSeries(std::shared_ptr<IDataSeries> candidate, SqpRange candidateCacheRange,
35 bool compareDataSeries(std::shared_ptr<IDataSeries> candidate, SqpRange candidateCacheRange,
36 std::shared_ptr<IDataSeries> reference)
36 std::shared_ptr<IDataSeries> reference)
37 {
37 {
38 auto compareLambda = [](const auto &it1, const auto &it2) {
38 auto compareLambda = [](const auto &it1, const auto &it2) {
39 return (it1.x() == it2.x()) && (it1.value() == it2.value());
39 return (it1.x() == it2.x()) && (it1.value() == it2.value());
40 };
40 };
41
41
42 auto candidateDS = std::dynamic_pointer_cast<T>(candidate);
42 auto candidateDS = std::dynamic_pointer_cast<T>(candidate);
43 auto referenceDS = std::dynamic_pointer_cast<T>(reference);
43 auto referenceDS = std::dynamic_pointer_cast<T>(reference);
44
44
45 if (candidateDS && referenceDS) {
45 if (candidateDS && referenceDS) {
46
46
47 auto itRefs
47 auto itRefs
48 = referenceDS->xAxisRange(candidateCacheRange.m_TStart, candidateCacheRange.m_TEnd);
48 = referenceDS->xAxisRange(candidateCacheRange.m_TStart, candidateCacheRange.m_TEnd);
49 qDebug() << " DISTANCE" << std::distance(candidateDS->cbegin(), candidateDS->cend())
49 qDebug() << " DISTANCE" << std::distance(candidateDS->cbegin(), candidateDS->cend())
50 << std::distance(itRefs.first, itRefs.second);
50 << std::distance(itRefs.first, itRefs.second);
51
51
52 // auto xcValue = candidateDS->valuesData()->data();
52 // auto xcValue = candidateDS->valuesData()->data();
53 // auto dist = std::distance(itRefs.first, itRefs.second);
53 // auto dist = std::distance(itRefs.first, itRefs.second);
54 // auto it = itRefs.first;
54 // auto it = itRefs.first;
55 // for (auto i = 0; i < dist - 1; ++i) {
55 // for (auto i = 0; i < dist - 1; ++i) {
56 // ++it;
56 // ++it;
57 // qInfo() << "END:" << it->value();
57 // qInfo() << "END:" << it->value();
58 // }
58 // }
59 // qDebug() << "END:" << it->value() << xcValue.last();
59 // qDebug() << "END:" << it->value() << xcValue.last();
60
60
61 return std::equal(candidateDS->cbegin(), candidateDS->cend(), itRefs.first, itRefs.second,
61 return std::equal(candidateDS->cbegin(), candidateDS->cend(), itRefs.first, itRefs.second,
62 compareLambda);
62 compareLambda);
63 }
63 }
64 else {
64 else {
65 return false;
65 return false;
66 }
66 }
67 }
67 }
68 }
68 }
69
69
70 class TestAmdaAcquisition : public QObject {
70 class TestAmdaAcquisition : public QObject {
71 Q_OBJECT
71 Q_OBJECT
72
72
73 private slots:
73 private slots:
74 void testAcquisition();
74 void testAcquisition();
75 };
75 };
76
76
77 void TestAmdaAcquisition::testAcquisition()
77 void TestAmdaAcquisition::testAcquisition()
78 {
78 {
79 // READ the ref file:
79 // READ the ref file:
80 auto filePath = QFileInfo{TESTS_RESOURCES_PATH, TESTS_AMDA_REF_FILE}.absoluteFilePath();
80 auto filePath = QFileInfo{TESTS_RESOURCES_PATH, TESTS_AMDA_REF_FILE}.absoluteFilePath();
81 auto results = AmdaResultParser::readTxt(filePath, AmdaResultParser::ValueType::SCALAR);
81 auto results = AmdaResultParser::readTxt(filePath, AmdaResultParser::ValueType::SCALAR);
82
82
83 auto provider = std::make_shared<AmdaProvider>();
83 auto provider = std::make_shared<AmdaProvider>();
84 auto timeController = std::make_unique<TimeController>();
84 auto timeController = std::make_unique<TimeController>();
85
85
86 auto varRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 3, 0, 0}};
86 auto varRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 3, 0, 0}};
87 auto varRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 4, 0, 0}};
87 auto varRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 4, 0, 0}};
88
88
89 auto sqpR = SqpRange{DateUtils::secondsSinceEpoch(varRS), DateUtils::secondsSinceEpoch(varRE)};
89 auto sqpR = SqpRange{DateUtils::secondsSinceEpoch(varRS), DateUtils::secondsSinceEpoch(varRE)};
90
90
91 timeController->onTimeToUpdate(sqpR);
91 timeController->onTimeToUpdate(sqpR);
92
92
93 QVariantHash metaData;
93 QVariantHash metaData;
94 metaData.insert("dataType", "scalar");
94 metaData.insert("dataType", "scalar");
95 metaData.insert("xml:id", "imf(0)");
95 metaData.insert("xml:id", "imf(0)");
96
96
97 VariableController vc;
97 VariableController vc;
98 vc.setTimeController(timeController.get());
98 vc.setTimeController(timeController.get());
99
99
100 auto var = vc.createVariable("bx_gse", metaData, provider);
100 auto var = vc.createVariable("bx_gse", metaData, provider);
101
101
102 // 1 : Variable creation
102 // 1 : Variable creation
103 QCOMPARE(var->range().m_TStart, sqpR.m_TStart);
104 QCOMPARE(var->range().m_TEnd, sqpR.m_TEnd);
105
103
106 qDebug() << " 1: TIMECONTROLLER" << timeController->dateTime();
104 qDebug() << " 1: TIMECONTROLLER" << timeController->dateTime();
107 qDebug() << " 1: RANGE " << var->range();
105 qDebug() << " 1: RANGE " << var->range();
108 qDebug() << " 1: CACHERANGE" << var->cacheRange();
106 qDebug() << " 1: CACHERANGE" << var->cacheRange();
109
107
110 // wait for 10 sec before asking next request toi permit asynchrone process to finish.
108 // wait for 10 sec before asking next request toi permit asynchrone process to finish.
111 auto timeToWaitMs = 10000;
109 auto timeToWaitMs = 10000;
112
110
113 QEventLoop loop;
111 QEventLoop loop;
114 QTimer::singleShot(timeToWaitMs, &loop, &QEventLoop::quit);
112 QTimer::singleShot(timeToWaitMs, &loop, &QEventLoop::quit);
115 loop.exec();
113 loop.exec();
116
114
117 // Tests on acquisition operation
115 // Tests on acquisition operation
118
116
119 int count = 1;
117 int count = 1;
120
118
121 auto requestDataLoading = [&vc, var, timeToWaitMs, results, &count](auto tStart, auto tEnd) {
119 auto requestDataLoading = [&vc, var, timeToWaitMs, results, &count](auto tStart, auto tEnd) {
122 ++count;
120 ++count;
123
121
124 auto nextSqpR
122 auto nextSqpR
125 = SqpRange{DateUtils::secondsSinceEpoch(tStart), DateUtils::secondsSinceEpoch(tEnd)};
123 = SqpRange{DateUtils::secondsSinceEpoch(tStart), DateUtils::secondsSinceEpoch(tEnd)};
126 vc.onRequestDataLoading(QVector<std::shared_ptr<Variable> >{} << var, nextSqpR,
124 vc.onRequestDataLoading(QVector<std::shared_ptr<Variable> >{} << var, nextSqpR,
127 var->range(), true);
125 var->range(), true);
128
126
129 QEventLoop loop;
127 QEventLoop loop;
130 QTimer::singleShot(timeToWaitMs, &loop, &QEventLoop::quit);
128 QTimer::singleShot(timeToWaitMs, &loop, &QEventLoop::quit);
131 loop.exec();
129 loop.exec();
132
130
133 qInfo() << count << "RANGE " << var->range();
131 qInfo() << count << "RANGE " << var->range();
134 qInfo() << count << "CACHERANGE" << var->cacheRange();
132 qInfo() << count << "CACHERANGE" << var->cacheRange();
135
133
136 QCOMPARE(var->range().m_TStart, nextSqpR.m_TStart);
134 QCOMPARE(var->range().m_TStart, nextSqpR.m_TStart);
137 QCOMPARE(var->range().m_TEnd, nextSqpR.m_TEnd);
135 QCOMPARE(var->range().m_TEnd, nextSqpR.m_TEnd);
138
136
139 // Verify dataserie
137 // Verify dataserie
140 QVERIFY(compareDataSeries<ScalarSeries>(var->dataSeries(), var->cacheRange(), results));
138 QVERIFY(compareDataSeries<ScalarSeries>(var->dataSeries(), var->cacheRange(), results));
141
139
142 };
140 };
143
141
144 // 2 : pan (jump) left for one hour
142 // 2 : pan (jump) left for one hour
145 auto nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 1, 0, 0}};
143 auto nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 1, 0, 0}};
146 auto nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 2, 0, 0}};
144 auto nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 2, 0, 0}};
147 requestDataLoading(nextVarRS, nextVarRE);
145 requestDataLoading(nextVarRS, nextVarRE);
148
146
149
147
150 // 3 : pan (jump) right for one hour
148 // 3 : pan (jump) right for one hour
151 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 0, 0}};
149 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 0, 0}};
152 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 6, 0, 0}};
150 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 6, 0, 0}};
153 requestDataLoading(nextVarRS, nextVarRE);
151 requestDataLoading(nextVarRS, nextVarRE);
154
152
155 // 4 : pan (overlay) right for 30 min
153 // 4 : pan (overlay) right for 30 min
156 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 30, 0}};
154 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 30, 0}};
157 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 6, 30, 0}};
155 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 6, 30, 0}};
158 // requestDataLoading(nextVarRS, nextVarRE);
156 // requestDataLoading(nextVarRS, nextVarRE);
159
157
160 // 5 : pan (overlay) left for 30 min
158 // 5 : pan (overlay) left for 30 min
161 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 0, 0}};
159 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 0, 0}};
162 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 6, 0, 0}};
160 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 6, 0, 0}};
163 // requestDataLoading(nextVarRS, nextVarRE);
161 // requestDataLoading(nextVarRS, nextVarRE);
164
162
165 // 6 : pan (overlay) left for 30 min - BIS
163 // 6 : pan (overlay) left for 30 min - BIS
166 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 4, 30, 0}};
164 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 4, 30, 0}};
167 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 30, 0}};
165 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 30, 0}};
168 // requestDataLoading(nextVarRS, nextVarRE);
166 // requestDataLoading(nextVarRS, nextVarRE);
169
167
170 // 7 : Zoom in Inside 20 min range
168 // 7 : Zoom in Inside 20 min range
171 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 4, 50, 0}};
169 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 4, 50, 0}};
172 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 10, 0}};
170 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 10, 0}};
173 // requestDataLoading(nextVarRS, nextVarRE);
171 // requestDataLoading(nextVarRS, nextVarRE);
174
172
175 // 8 : Zoom out Inside 2 hours range
173 // 8 : Zoom out Inside 2 hours range
176 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 4, 0, 0}};
174 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 4, 0, 0}};
177 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 6, 0, 0}};
175 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 6, 0, 0}};
178 // requestDataLoading(nextVarRS, nextVarRE);
176 // requestDataLoading(nextVarRS, nextVarRE);
179
177
180
178
181 // Close the app after 10 sec
179 // Close the app after 10 sec
182 QTimer::singleShot(timeToWaitMs, &loop, &QEventLoop::quit);
180 QTimer::singleShot(timeToWaitMs, &loop, &QEventLoop::quit);
183 loop.exec();
181 loop.exec();
184 }
182 }
185
183
186 int main(int argc, char *argv[])
184 int main(int argc, char *argv[])
187 {
185 {
188 SqpApplication app(argc, argv);
186 SqpApplication app(argc, argv);
189 app.setAttribute(Qt::AA_Use96Dpi, true);
187 app.setAttribute(Qt::AA_Use96Dpi, true);
190 TestAmdaAcquisition tc;
188 TestAmdaAcquisition tc;
191 QTEST_SET_MAIN_SOURCE_PATH
189 QTEST_SET_MAIN_SOURCE_PATH
192 return QTest::qExec(&tc, argc, argv);
190 return QTest::qExec(&tc, argc, argv);
193 }
191 }
194
192
195 // QTEST_MAIN(TestAmdaAcquisition)
193 // QTEST_MAIN(TestAmdaAcquisition)
196
194
197 #include "TestAmdaAcquisition.moc"
195 #include "TestAmdaAcquisition.moc"
General Comments 0
You need to be logged in to leave comments. Login now