##// END OF EJS Templates
Renames subData() to subDataSeries()...
Alexandre Leroux -
r554:5d1bac48fb3a
parent child
Show More
@@ -1,72 +1,73
1 #ifndef SCIQLOP_IDATASERIES_H
1 #ifndef SCIQLOP_IDATASERIES_H
2 #define SCIQLOP_IDATASERIES_H
2 #define SCIQLOP_IDATASERIES_H
3
3
4 #include <Common/MetaTypes.h>
4 #include <Common/MetaTypes.h>
5 #include <Data/SqpRange.h>
5 #include <Data/SqpRange.h>
6
6
7 #include <memory>
7 #include <memory>
8
8
9 #include <QString>
9 #include <QString>
10
10
11 template <int Dim>
11 template <int Dim>
12 class ArrayData;
12 class ArrayData;
13
13
14 struct Unit {
14 struct Unit {
15 explicit Unit(const QString &name = {}, bool timeUnit = false)
15 explicit Unit(const QString &name = {}, bool timeUnit = false)
16 : m_Name{name}, m_TimeUnit{timeUnit}
16 : m_Name{name}, m_TimeUnit{timeUnit}
17 {
17 {
18 }
18 }
19
19
20 inline bool operator==(const Unit &other) const
20 inline bool operator==(const Unit &other) const
21 {
21 {
22 return std::tie(m_Name, m_TimeUnit) == std::tie(other.m_Name, other.m_TimeUnit);
22 return std::tie(m_Name, m_TimeUnit) == std::tie(other.m_Name, other.m_TimeUnit);
23 }
23 }
24 inline bool operator!=(const Unit &other) const { return !(*this == other); }
24 inline bool operator!=(const Unit &other) const { return !(*this == other); }
25
25
26 QString m_Name; ///< Unit name
26 QString m_Name; ///< Unit name
27 bool m_TimeUnit; ///< The unit is a unit of time (UTC)
27 bool m_TimeUnit; ///< The unit is a unit of time (UTC)
28 };
28 };
29
29
30 /**
30 /**
31 * @brief The IDataSeries aims to declare a data series.
31 * @brief The IDataSeries aims to declare a data series.
32 *
32 *
33 * A data series is an entity that contains at least :
33 * A data series is an entity that contains at least :
34 * - one dataset representing the x-axis
34 * - one dataset representing the x-axis
35 * - one dataset representing the values
35 * - one dataset representing the values
36 *
36 *
37 * Each dataset is represented by an ArrayData, and is associated with a unit.
37 * Each dataset is represented by an ArrayData, and is associated with a unit.
38 *
38 *
39 * An ArrayData can be unidimensional or two-dimensional, depending on the implementation of the
39 * An ArrayData can be unidimensional or two-dimensional, depending on the implementation of the
40 * IDataSeries. The x-axis dataset is always unidimensional.
40 * IDataSeries. The x-axis dataset is always unidimensional.
41 *
41 *
42 * @sa ArrayData
42 * @sa ArrayData
43 */
43 */
44 class IDataSeries {
44 class IDataSeries {
45 public:
45 public:
46 virtual ~IDataSeries() noexcept = default;
46 virtual ~IDataSeries() noexcept = default;
47
47
48 /// Returns the x-axis dataset
48 /// Returns the x-axis dataset
49 virtual std::shared_ptr<ArrayData<1> > xAxisData() = 0;
49 virtual std::shared_ptr<ArrayData<1> > xAxisData() = 0;
50
50
51 /// Returns the x-axis dataset (as const)
51 /// Returns the x-axis dataset (as const)
52 virtual const std::shared_ptr<ArrayData<1> > xAxisData() const = 0;
52 virtual const std::shared_ptr<ArrayData<1> > xAxisData() const = 0;
53
53
54 virtual Unit xAxisUnit() const = 0;
54 virtual Unit xAxisUnit() const = 0;
55
55
56 virtual Unit valuesUnit() const = 0;
56 virtual Unit valuesUnit() const = 0;
57
57
58 virtual void merge(IDataSeries *dataSeries) = 0;
58 virtual void merge(IDataSeries *dataSeries) = 0;
59 virtual std::shared_ptr<IDataSeries> subData(const SqpRange &range) = 0;
59 /// @todo Review the name and signature of this method
60 virtual std::shared_ptr<IDataSeries> subDataSeries(const SqpRange &range) = 0;
60
61
61 virtual std::unique_ptr<IDataSeries> clone() const = 0;
62 virtual std::unique_ptr<IDataSeries> clone() const = 0;
62 virtual SqpRange range() const = 0;
63 virtual SqpRange range() const = 0;
63
64
64 virtual void lockRead() = 0;
65 virtual void lockRead() = 0;
65 virtual void lockWrite() = 0;
66 virtual void lockWrite() = 0;
66 virtual void unlock() = 0;
67 virtual void unlock() = 0;
67 };
68 };
68
69
69 // Required for using shared_ptr in signals/slots
70 // Required for using shared_ptr in signals/slots
70 SCIQLOP_REGISTER_META_TYPE(IDATASERIES_PTR_REGISTRY, std::shared_ptr<IDataSeries>)
71 SCIQLOP_REGISTER_META_TYPE(IDATASERIES_PTR_REGISTRY, std::shared_ptr<IDataSeries>)
71
72
72 #endif // SCIQLOP_IDATASERIES_H
73 #endif // SCIQLOP_IDATASERIES_H
@@ -1,27 +1,27
1 #ifndef SCIQLOP_SCALARSERIES_H
1 #ifndef SCIQLOP_SCALARSERIES_H
2 #define SCIQLOP_SCALARSERIES_H
2 #define SCIQLOP_SCALARSERIES_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Data/DataSeries.h>
6 #include <Data/DataSeries.h>
7
7
8 /**
8 /**
9 * @brief The ScalarSeries class is the implementation for a data series representing a scalar.
9 * @brief The ScalarSeries class is the implementation for a data series representing a scalar.
10 */
10 */
11 class SCIQLOP_CORE_EXPORT ScalarSeries : public DataSeries<1> {
11 class SCIQLOP_CORE_EXPORT ScalarSeries : public DataSeries<1> {
12 public:
12 public:
13 /**
13 /**
14 * Ctor with two vectors. The vectors must have the same size, otherwise a ScalarSeries with no
14 * Ctor with two vectors. The vectors must have the same size, otherwise a ScalarSeries with no
15 * values will be created.
15 * values will be created.
16 * @param xAxisData x-axis data
16 * @param xAxisData x-axis data
17 * @param valuesData values data
17 * @param valuesData values data
18 */
18 */
19 explicit ScalarSeries(QVector<double> xAxisData, QVector<double> valuesData,
19 explicit ScalarSeries(QVector<double> xAxisData, QVector<double> valuesData,
20 const Unit &xAxisUnit, const Unit &valuesUnit);
20 const Unit &xAxisUnit, const Unit &valuesUnit);
21
21
22 std::unique_ptr<IDataSeries> clone() const override;
22 std::unique_ptr<IDataSeries> clone() const override;
23
23
24 std::shared_ptr<IDataSeries> subData(const SqpRange &range) override;
24 std::shared_ptr<IDataSeries> subDataSeries(const SqpRange &range) override;
25 };
25 };
26
26
27 #endif // SCIQLOP_SCALARSERIES_H
27 #endif // SCIQLOP_SCALARSERIES_H
@@ -1,41 +1,41
1 #include <Data/ScalarSeries.h>
1 #include <Data/ScalarSeries.h>
2
2
3 ScalarSeries::ScalarSeries(QVector<double> xAxisData, QVector<double> valuesData,
3 ScalarSeries::ScalarSeries(QVector<double> xAxisData, QVector<double> valuesData,
4 const Unit &xAxisUnit, const Unit &valuesUnit)
4 const Unit &xAxisUnit, const Unit &valuesUnit)
5 : DataSeries{std::make_shared<ArrayData<1> >(std::move(xAxisData)), xAxisUnit,
5 : DataSeries{std::make_shared<ArrayData<1> >(std::move(xAxisData)), xAxisUnit,
6 std::make_shared<ArrayData<1> >(std::move(valuesData)), valuesUnit}
6 std::make_shared<ArrayData<1> >(std::move(valuesData)), valuesUnit}
7 {
7 {
8 }
8 }
9
9
10 std::unique_ptr<IDataSeries> ScalarSeries::clone() const
10 std::unique_ptr<IDataSeries> ScalarSeries::clone() const
11 {
11 {
12 return std::make_unique<ScalarSeries>(*this);
12 return std::make_unique<ScalarSeries>(*this);
13 }
13 }
14
14
15 std::shared_ptr<IDataSeries> ScalarSeries::subData(const SqpRange &range)
15 std::shared_ptr<IDataSeries> ScalarSeries::subDataSeries(const SqpRange &range)
16 {
16 {
17 auto subXAxisData = QVector<double>();
17 auto subXAxisData = QVector<double>();
18 auto subValuesData = QVector<double>();
18 auto subValuesData = QVector<double>();
19 this->lockRead();
19 this->lockRead();
20 {
20 {
21 const auto &currentXData = this->xAxisData()->cdata();
21 const auto &currentXData = this->xAxisData()->cdata();
22 const auto &currentValuesData = this->valuesData()->cdata();
22 const auto &currentValuesData = this->valuesData()->cdata();
23
23
24 auto xDataBegin = currentXData.cbegin();
24 auto xDataBegin = currentXData.cbegin();
25 auto xDataEnd = currentXData.cend();
25 auto xDataEnd = currentXData.cend();
26
26
27 auto lowerIt = std::lower_bound(xDataBegin, xDataEnd, range.m_TStart);
27 auto lowerIt = std::lower_bound(xDataBegin, xDataEnd, range.m_TStart);
28 auto upperIt = std::upper_bound(xDataBegin, xDataEnd, range.m_TEnd);
28 auto upperIt = std::upper_bound(xDataBegin, xDataEnd, range.m_TEnd);
29 auto distance = std::distance(xDataBegin, lowerIt);
29 auto distance = std::distance(xDataBegin, lowerIt);
30
30
31 auto valuesDataIt = currentValuesData.cbegin() + distance;
31 auto valuesDataIt = currentValuesData.cbegin() + distance;
32 for (auto xAxisDataIt = lowerIt; xAxisDataIt != upperIt; ++xAxisDataIt, ++valuesDataIt) {
32 for (auto xAxisDataIt = lowerIt; xAxisDataIt != upperIt; ++xAxisDataIt, ++valuesDataIt) {
33 subXAxisData.append(*xAxisDataIt);
33 subXAxisData.append(*xAxisDataIt);
34 subValuesData.append(*valuesDataIt);
34 subValuesData.append(*valuesDataIt);
35 }
35 }
36 }
36 }
37 this->unlock();
37 this->unlock();
38
38
39 return std::make_shared<ScalarSeries>(subXAxisData, subValuesData, this->xAxisUnit(),
39 return std::make_shared<ScalarSeries>(subXAxisData, subValuesData, this->xAxisUnit(),
40 this->valuesUnit());
40 this->valuesUnit());
41 }
41 }
@@ -1,211 +1,211
1 #include "Variable/Variable.h"
1 #include "Variable/Variable.h"
2
2
3 #include <Data/IDataSeries.h>
3 #include <Data/IDataSeries.h>
4 #include <Data/SqpRange.h>
4 #include <Data/SqpRange.h>
5
5
6 #include <QMutex>
6 #include <QMutex>
7 #include <QReadWriteLock>
7 #include <QReadWriteLock>
8 #include <QThread>
8 #include <QThread>
9
9
10 Q_LOGGING_CATEGORY(LOG_Variable, "Variable")
10 Q_LOGGING_CATEGORY(LOG_Variable, "Variable")
11
11
12 struct Variable::VariablePrivate {
12 struct Variable::VariablePrivate {
13 explicit VariablePrivate(const QString &name, const SqpRange &dateTime,
13 explicit VariablePrivate(const QString &name, const SqpRange &dateTime,
14 const QVariantHash &metadata)
14 const QVariantHash &metadata)
15 : m_Name{name}, m_Range{dateTime}, m_Metadata{metadata}, m_DataSeries{nullptr}
15 : m_Name{name}, m_Range{dateTime}, m_Metadata{metadata}, m_DataSeries{nullptr}
16 {
16 {
17 }
17 }
18
18
19 void lockRead() { m_Lock.lockForRead(); }
19 void lockRead() { m_Lock.lockForRead(); }
20 void lockWrite() { m_Lock.lockForWrite(); }
20 void lockWrite() { m_Lock.lockForWrite(); }
21 void unlock() { m_Lock.unlock(); }
21 void unlock() { m_Lock.unlock(); }
22
22
23 QString m_Name;
23 QString m_Name;
24
24
25 SqpRange m_Range;
25 SqpRange m_Range;
26 SqpRange m_CacheRange;
26 SqpRange m_CacheRange;
27 QVariantHash m_Metadata;
27 QVariantHash m_Metadata;
28 std::shared_ptr<IDataSeries> m_DataSeries;
28 std::shared_ptr<IDataSeries> m_DataSeries;
29
29
30 QReadWriteLock m_Lock;
30 QReadWriteLock m_Lock;
31 };
31 };
32
32
33 Variable::Variable(const QString &name, const SqpRange &dateTime, const QVariantHash &metadata)
33 Variable::Variable(const QString &name, const SqpRange &dateTime, const QVariantHash &metadata)
34 : impl{spimpl::make_unique_impl<VariablePrivate>(name, dateTime, metadata)}
34 : impl{spimpl::make_unique_impl<VariablePrivate>(name, dateTime, metadata)}
35 {
35 {
36 }
36 }
37
37
38 QString Variable::name() const noexcept
38 QString Variable::name() const noexcept
39 {
39 {
40 impl->lockRead();
40 impl->lockRead();
41 auto name = impl->m_Name;
41 auto name = impl->m_Name;
42 impl->unlock();
42 impl->unlock();
43 return name;
43 return name;
44 }
44 }
45
45
46 SqpRange Variable::range() const noexcept
46 SqpRange Variable::range() const noexcept
47 {
47 {
48 impl->lockRead();
48 impl->lockRead();
49 auto range = impl->m_Range;
49 auto range = impl->m_Range;
50 impl->unlock();
50 impl->unlock();
51 return range;
51 return range;
52 }
52 }
53
53
54 void Variable::setRange(const SqpRange &range) noexcept
54 void Variable::setRange(const SqpRange &range) noexcept
55 {
55 {
56 impl->lockWrite();
56 impl->lockWrite();
57 impl->m_Range = range;
57 impl->m_Range = range;
58 impl->unlock();
58 impl->unlock();
59 }
59 }
60
60
61 SqpRange Variable::cacheRange() const noexcept
61 SqpRange Variable::cacheRange() const noexcept
62 {
62 {
63 impl->lockRead();
63 impl->lockRead();
64 auto cacheRange = impl->m_CacheRange;
64 auto cacheRange = impl->m_CacheRange;
65 impl->unlock();
65 impl->unlock();
66 return cacheRange;
66 return cacheRange;
67 }
67 }
68
68
69 void Variable::setCacheRange(const SqpRange &cacheRange) noexcept
69 void Variable::setCacheRange(const SqpRange &cacheRange) noexcept
70 {
70 {
71 impl->lockWrite();
71 impl->lockWrite();
72 impl->m_CacheRange = cacheRange;
72 impl->m_CacheRange = cacheRange;
73 impl->unlock();
73 impl->unlock();
74 }
74 }
75
75
76 void Variable::setDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
76 void Variable::setDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
77 {
77 {
78 qCDebug(LOG_Variable()) << "TORM Variable::setDataSeries"
78 qCDebug(LOG_Variable()) << "TORM Variable::setDataSeries"
79 << QThread::currentThread()->objectName();
79 << QThread::currentThread()->objectName();
80 if (!dataSeries) {
80 if (!dataSeries) {
81 /// @todo ALX : log
81 /// @todo ALX : log
82 return;
82 return;
83 }
83 }
84 impl->lockWrite();
84 impl->lockWrite();
85 impl->m_DataSeries = dataSeries->clone();
85 impl->m_DataSeries = dataSeries->clone();
86 impl->unlock();
86 impl->unlock();
87 }
87 }
88
88
89 void Variable::mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
89 void Variable::mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
90 {
90 {
91 qCDebug(LOG_Variable()) << "TORM Variable::mergeDataSeries"
91 qCDebug(LOG_Variable()) << "TORM Variable::mergeDataSeries"
92 << QThread::currentThread()->objectName();
92 << QThread::currentThread()->objectName();
93 if (!dataSeries) {
93 if (!dataSeries) {
94 /// @todo ALX : log
94 /// @todo ALX : log
95 return;
95 return;
96 }
96 }
97
97
98 // Add or merge the data
98 // Add or merge the data
99 // Inits the data series of the variable
99 // Inits the data series of the variable
100 impl->lockWrite();
100 impl->lockWrite();
101 if (!impl->m_DataSeries) {
101 if (!impl->m_DataSeries) {
102 impl->m_DataSeries = dataSeries->clone();
102 impl->m_DataSeries = dataSeries->clone();
103 }
103 }
104 else {
104 else {
105 impl->m_DataSeries->merge(dataSeries.get());
105 impl->m_DataSeries->merge(dataSeries.get());
106 }
106 }
107 impl->unlock();
107 impl->unlock();
108
108
109 // sub the data
109 // sub the data
110 auto subData = this->dataSeries()->subData(this->cacheRange());
110 auto subData = this->dataSeries()->subDataSeries(this->cacheRange());
111 qCDebug(LOG_Variable()) << "TORM: Variable::mergeDataSeries sub" << subData->range();
111 qCDebug(LOG_Variable()) << "TORM: Variable::mergeDataSeries sub" << subData->range();
112 this->setDataSeries(subData);
112 this->setDataSeries(subData);
113 qCDebug(LOG_Variable()) << "TORM: Variable::mergeDataSeries set" << this->dataSeries()->range();
113 qCDebug(LOG_Variable()) << "TORM: Variable::mergeDataSeries set" << this->dataSeries()->range();
114 }
114 }
115
115
116 std::shared_ptr<IDataSeries> Variable::dataSeries() const noexcept
116 std::shared_ptr<IDataSeries> Variable::dataSeries() const noexcept
117 {
117 {
118 impl->lockRead();
118 impl->lockRead();
119 auto dataSeries = impl->m_DataSeries;
119 auto dataSeries = impl->m_DataSeries;
120 impl->unlock();
120 impl->unlock();
121
121
122 return dataSeries;
122 return dataSeries;
123 }
123 }
124
124
125 QVariantHash Variable::metadata() const noexcept
125 QVariantHash Variable::metadata() const noexcept
126 {
126 {
127 impl->lockRead();
127 impl->lockRead();
128 auto metadata = impl->m_Metadata;
128 auto metadata = impl->m_Metadata;
129 impl->unlock();
129 impl->unlock();
130 return metadata;
130 return metadata;
131 }
131 }
132
132
133 bool Variable::contains(const SqpRange &range) const noexcept
133 bool Variable::contains(const SqpRange &range) const noexcept
134 {
134 {
135 impl->lockRead();
135 impl->lockRead();
136 auto res = impl->m_Range.contains(range);
136 auto res = impl->m_Range.contains(range);
137 impl->unlock();
137 impl->unlock();
138 return res;
138 return res;
139 }
139 }
140
140
141 bool Variable::intersect(const SqpRange &range) const noexcept
141 bool Variable::intersect(const SqpRange &range) const noexcept
142 {
142 {
143
143
144 impl->lockRead();
144 impl->lockRead();
145 auto res = impl->m_Range.intersect(range);
145 auto res = impl->m_Range.intersect(range);
146 impl->unlock();
146 impl->unlock();
147 return res;
147 return res;
148 }
148 }
149
149
150 bool Variable::isInside(const SqpRange &range) const noexcept
150 bool Variable::isInside(const SqpRange &range) const noexcept
151 {
151 {
152 impl->lockRead();
152 impl->lockRead();
153 auto res = range.contains(SqpRange{impl->m_Range.m_TStart, impl->m_Range.m_TEnd});
153 auto res = range.contains(SqpRange{impl->m_Range.m_TStart, impl->m_Range.m_TEnd});
154 impl->unlock();
154 impl->unlock();
155 return res;
155 return res;
156 }
156 }
157
157
158 bool Variable::cacheContains(const SqpRange &range) const noexcept
158 bool Variable::cacheContains(const SqpRange &range) const noexcept
159 {
159 {
160 impl->lockRead();
160 impl->lockRead();
161 auto res = impl->m_CacheRange.contains(range);
161 auto res = impl->m_CacheRange.contains(range);
162 impl->unlock();
162 impl->unlock();
163 return res;
163 return res;
164 }
164 }
165
165
166 bool Variable::cacheIntersect(const SqpRange &range) const noexcept
166 bool Variable::cacheIntersect(const SqpRange &range) const noexcept
167 {
167 {
168 impl->lockRead();
168 impl->lockRead();
169 auto res = impl->m_CacheRange.intersect(range);
169 auto res = impl->m_CacheRange.intersect(range);
170 impl->unlock();
170 impl->unlock();
171 return res;
171 return res;
172 }
172 }
173
173
174 bool Variable::cacheIsInside(const SqpRange &range) const noexcept
174 bool Variable::cacheIsInside(const SqpRange &range) const noexcept
175 {
175 {
176 impl->lockRead();
176 impl->lockRead();
177 auto res = range.contains(SqpRange{impl->m_CacheRange.m_TStart, impl->m_CacheRange.m_TEnd});
177 auto res = range.contains(SqpRange{impl->m_CacheRange.m_TStart, impl->m_CacheRange.m_TEnd});
178 impl->unlock();
178 impl->unlock();
179 return res;
179 return res;
180 }
180 }
181
181
182
182
183 QVector<SqpRange> Variable::provideNotInCacheRangeList(const SqpRange &range) const noexcept
183 QVector<SqpRange> Variable::provideNotInCacheRangeList(const SqpRange &range) const noexcept
184 {
184 {
185 auto notInCache = QVector<SqpRange>{};
185 auto notInCache = QVector<SqpRange>{};
186
186
187 if (!this->cacheContains(range)) {
187 if (!this->cacheContains(range)) {
188 if (range.m_TEnd <= impl->m_CacheRange.m_TStart
188 if (range.m_TEnd <= impl->m_CacheRange.m_TStart
189 || range.m_TStart >= impl->m_CacheRange.m_TEnd) {
189 || range.m_TStart >= impl->m_CacheRange.m_TEnd) {
190 notInCache << range;
190 notInCache << range;
191 }
191 }
192 else if (range.m_TStart < impl->m_CacheRange.m_TStart
192 else if (range.m_TStart < impl->m_CacheRange.m_TStart
193 && range.m_TEnd <= impl->m_CacheRange.m_TEnd) {
193 && range.m_TEnd <= impl->m_CacheRange.m_TEnd) {
194 notInCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TStart};
194 notInCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TStart};
195 }
195 }
196 else if (range.m_TStart < impl->m_CacheRange.m_TStart
196 else if (range.m_TStart < impl->m_CacheRange.m_TStart
197 && range.m_TEnd > impl->m_CacheRange.m_TEnd) {
197 && range.m_TEnd > impl->m_CacheRange.m_TEnd) {
198 notInCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TStart}
198 notInCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TStart}
199 << SqpRange{impl->m_CacheRange.m_TEnd, range.m_TEnd};
199 << SqpRange{impl->m_CacheRange.m_TEnd, range.m_TEnd};
200 }
200 }
201 else if (range.m_TStart < impl->m_CacheRange.m_TEnd) {
201 else if (range.m_TStart < impl->m_CacheRange.m_TEnd) {
202 notInCache << SqpRange{impl->m_CacheRange.m_TEnd, range.m_TEnd};
202 notInCache << SqpRange{impl->m_CacheRange.m_TEnd, range.m_TEnd};
203 }
203 }
204 else {
204 else {
205 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
205 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
206 << QThread::currentThread();
206 << QThread::currentThread();
207 }
207 }
208 }
208 }
209
209
210 return notInCache;
210 return notInCache;
211 }
211 }
@@ -1,541 +1,541
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableAcquisitionWorker.h>
2 #include <Variable/VariableAcquisitionWorker.h>
3 #include <Variable/VariableCacheController.h>
3 #include <Variable/VariableCacheController.h>
4 #include <Variable/VariableCacheStrategy.h>
4 #include <Variable/VariableCacheStrategy.h>
5 #include <Variable/VariableController.h>
5 #include <Variable/VariableController.h>
6 #include <Variable/VariableModel.h>
6 #include <Variable/VariableModel.h>
7 #include <Variable/VariableSynchronizationGroup.h>
7 #include <Variable/VariableSynchronizationGroup.h>
8
8
9 #include <Data/DataProviderParameters.h>
9 #include <Data/DataProviderParameters.h>
10 #include <Data/IDataProvider.h>
10 #include <Data/IDataProvider.h>
11 #include <Data/IDataSeries.h>
11 #include <Data/IDataSeries.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 <set>
19 #include <set>
20 #include <unordered_map>
20 #include <unordered_map>
21
21
22 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
22 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
23
23
24 namespace {
24 namespace {
25
25
26 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
26 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
27 const SqpRange &oldGraphRange)
27 const SqpRange &oldGraphRange)
28 {
28 {
29 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
29 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
30
30
31 auto varRangeRequested = varRange;
31 auto varRangeRequested = varRange;
32 switch (zoomType) {
32 switch (zoomType) {
33 case AcquisitionZoomType::ZoomIn: {
33 case AcquisitionZoomType::ZoomIn: {
34 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
34 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
35 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
35 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
36 varRangeRequested.m_TStart += deltaLeft;
36 varRangeRequested.m_TStart += deltaLeft;
37 varRangeRequested.m_TEnd -= deltaRight;
37 varRangeRequested.m_TEnd -= deltaRight;
38 break;
38 break;
39 }
39 }
40
40
41 case AcquisitionZoomType::ZoomOut: {
41 case AcquisitionZoomType::ZoomOut: {
42 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
42 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
43 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
43 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
44 varRangeRequested.m_TStart -= deltaLeft;
44 varRangeRequested.m_TStart -= deltaLeft;
45 varRangeRequested.m_TEnd += deltaRight;
45 varRangeRequested.m_TEnd += deltaRight;
46 break;
46 break;
47 }
47 }
48 case AcquisitionZoomType::PanRight: {
48 case AcquisitionZoomType::PanRight: {
49 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
49 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
50 varRangeRequested.m_TStart += deltaRight;
50 varRangeRequested.m_TStart += deltaRight;
51 varRangeRequested.m_TEnd += deltaRight;
51 varRangeRequested.m_TEnd += deltaRight;
52 break;
52 break;
53 }
53 }
54 case AcquisitionZoomType::PanLeft: {
54 case AcquisitionZoomType::PanLeft: {
55 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
55 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
56 varRangeRequested.m_TStart -= deltaLeft;
56 varRangeRequested.m_TStart -= deltaLeft;
57 varRangeRequested.m_TEnd -= deltaLeft;
57 varRangeRequested.m_TEnd -= deltaLeft;
58 break;
58 break;
59 }
59 }
60 case AcquisitionZoomType::Unknown: {
60 case AcquisitionZoomType::Unknown: {
61 qCCritical(LOG_VariableController())
61 qCCritical(LOG_VariableController())
62 << VariableController::tr("Impossible to synchronize: zoom type unknown");
62 << VariableController::tr("Impossible to synchronize: zoom type unknown");
63 break;
63 break;
64 }
64 }
65 default:
65 default:
66 qCCritical(LOG_VariableController()) << VariableController::tr(
66 qCCritical(LOG_VariableController()) << VariableController::tr(
67 "Impossible to synchronize: zoom type not take into account");
67 "Impossible to synchronize: zoom type not take into account");
68 // No action
68 // No action
69 break;
69 break;
70 }
70 }
71
71
72 return varRangeRequested;
72 return varRangeRequested;
73 }
73 }
74 }
74 }
75
75
76 struct VariableController::VariableControllerPrivate {
76 struct VariableController::VariableControllerPrivate {
77 explicit VariableControllerPrivate(VariableController *parent)
77 explicit VariableControllerPrivate(VariableController *parent)
78 : m_WorkingMutex{},
78 : m_WorkingMutex{},
79 m_VariableModel{new VariableModel{parent}},
79 m_VariableModel{new VariableModel{parent}},
80 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
80 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
81 m_VariableCacheController{std::make_unique<VariableCacheController>()},
81 m_VariableCacheController{std::make_unique<VariableCacheController>()},
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 {
84 {
85
85
86 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
86 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
87 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
87 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
88 }
88 }
89
89
90
90
91 virtual ~VariableControllerPrivate()
91 virtual ~VariableControllerPrivate()
92 {
92 {
93 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
93 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
94 m_VariableAcquisitionWorkerThread.quit();
94 m_VariableAcquisitionWorkerThread.quit();
95 m_VariableAcquisitionWorkerThread.wait();
95 m_VariableAcquisitionWorkerThread.wait();
96 }
96 }
97
97
98
98
99 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested);
99 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested);
100
100
101 QVector<SqpRange> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
101 QVector<SqpRange> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
102 const SqpRange &dateTime);
102 const SqpRange &dateTime);
103
103
104 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
104 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
105 std::shared_ptr<IDataSeries>
105 std::shared_ptr<IDataSeries>
106 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
106 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
107
107
108 void registerProvider(std::shared_ptr<IDataProvider> provider);
108 void registerProvider(std::shared_ptr<IDataProvider> provider);
109
109
110 QMutex m_WorkingMutex;
110 QMutex m_WorkingMutex;
111 /// Variable model. The VariableController has the ownership
111 /// Variable model. The VariableController has the ownership
112 VariableModel *m_VariableModel;
112 VariableModel *m_VariableModel;
113 QItemSelectionModel *m_VariableSelectionModel;
113 QItemSelectionModel *m_VariableSelectionModel;
114
114
115
115
116 TimeController *m_TimeController{nullptr};
116 TimeController *m_TimeController{nullptr};
117 std::unique_ptr<VariableCacheController> m_VariableCacheController;
117 std::unique_ptr<VariableCacheController> m_VariableCacheController;
118 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
118 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
119 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
119 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
120 QThread m_VariableAcquisitionWorkerThread;
120 QThread m_VariableAcquisitionWorkerThread;
121
121
122 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
122 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
123 m_VariableToProviderMap;
123 m_VariableToProviderMap;
124 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
124 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
125 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
125 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
126 m_GroupIdToVariableSynchronizationGroupMap;
126 m_GroupIdToVariableSynchronizationGroupMap;
127 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
127 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
128 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
128 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
129 };
129 };
130
130
131
131
132 VariableController::VariableController(QObject *parent)
132 VariableController::VariableController(QObject *parent)
133 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
133 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
134 {
134 {
135 qCDebug(LOG_VariableController()) << tr("VariableController construction")
135 qCDebug(LOG_VariableController()) << tr("VariableController construction")
136 << QThread::currentThread();
136 << QThread::currentThread();
137
137
138 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
138 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
139 &VariableController::onAbortProgressRequested);
139 &VariableController::onAbortProgressRequested);
140
140
141 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
141 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
142 &VariableController::onDataProvided);
142 &VariableController::onDataProvided);
143 connect(impl->m_VariableAcquisitionWorker.get(),
143 connect(impl->m_VariableAcquisitionWorker.get(),
144 &VariableAcquisitionWorker::variableRequestInProgress, this,
144 &VariableAcquisitionWorker::variableRequestInProgress, this,
145 &VariableController::onVariableRetrieveDataInProgress);
145 &VariableController::onVariableRetrieveDataInProgress);
146
146
147 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
147 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
148 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
148 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
149 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
149 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
150 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
150 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
151
151
152
152
153 impl->m_VariableAcquisitionWorkerThread.start();
153 impl->m_VariableAcquisitionWorkerThread.start();
154 }
154 }
155
155
156 VariableController::~VariableController()
156 VariableController::~VariableController()
157 {
157 {
158 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
158 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
159 << QThread::currentThread();
159 << QThread::currentThread();
160 this->waitForFinish();
160 this->waitForFinish();
161 }
161 }
162
162
163 VariableModel *VariableController::variableModel() noexcept
163 VariableModel *VariableController::variableModel() noexcept
164 {
164 {
165 return impl->m_VariableModel;
165 return impl->m_VariableModel;
166 }
166 }
167
167
168 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
168 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
169 {
169 {
170 return impl->m_VariableSelectionModel;
170 return impl->m_VariableSelectionModel;
171 }
171 }
172
172
173 void VariableController::setTimeController(TimeController *timeController) noexcept
173 void VariableController::setTimeController(TimeController *timeController) noexcept
174 {
174 {
175 impl->m_TimeController = timeController;
175 impl->m_TimeController = timeController;
176 }
176 }
177
177
178 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
178 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
179 {
179 {
180 if (!variable) {
180 if (!variable) {
181 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
181 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
182 return;
182 return;
183 }
183 }
184
184
185 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
185 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
186 // make some treatments before the deletion
186 // make some treatments before the deletion
187 emit variableAboutToBeDeleted(variable);
187 emit variableAboutToBeDeleted(variable);
188
188
189 // Deletes identifier
189 // Deletes identifier
190 impl->m_VariableToIdentifierMap.erase(variable);
190 impl->m_VariableToIdentifierMap.erase(variable);
191
191
192 // Deletes provider
192 // Deletes provider
193 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
193 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
194 qCDebug(LOG_VariableController())
194 qCDebug(LOG_VariableController())
195 << tr("Number of providers deleted for variable %1: %2")
195 << tr("Number of providers deleted for variable %1: %2")
196 .arg(variable->name(), QString::number(nbProvidersDeleted));
196 .arg(variable->name(), QString::number(nbProvidersDeleted));
197
197
198 // Clears cache
198 // Clears cache
199 impl->m_VariableCacheController->clear(variable);
199 impl->m_VariableCacheController->clear(variable);
200
200
201 // Deletes from model
201 // Deletes from model
202 impl->m_VariableModel->deleteVariable(variable);
202 impl->m_VariableModel->deleteVariable(variable);
203 }
203 }
204
204
205 void VariableController::deleteVariables(
205 void VariableController::deleteVariables(
206 const QVector<std::shared_ptr<Variable> > &variables) noexcept
206 const QVector<std::shared_ptr<Variable> > &variables) noexcept
207 {
207 {
208 for (auto variable : qAsConst(variables)) {
208 for (auto variable : qAsConst(variables)) {
209 deleteVariable(variable);
209 deleteVariable(variable);
210 }
210 }
211 }
211 }
212
212
213 void VariableController::abortProgress(std::shared_ptr<Variable> variable)
213 void VariableController::abortProgress(std::shared_ptr<Variable> variable)
214 {
214 {
215 }
215 }
216
216
217 void VariableController::createVariable(const QString &name, const QVariantHash &metadata,
217 void VariableController::createVariable(const QString &name, const QVariantHash &metadata,
218 std::shared_ptr<IDataProvider> provider) noexcept
218 std::shared_ptr<IDataProvider> provider) noexcept
219 {
219 {
220
220
221 if (!impl->m_TimeController) {
221 if (!impl->m_TimeController) {
222 qCCritical(LOG_VariableController())
222 qCCritical(LOG_VariableController())
223 << tr("Impossible to create variable: The time controller is null");
223 << tr("Impossible to create variable: The time controller is null");
224 return;
224 return;
225 }
225 }
226
226
227 auto range = impl->m_TimeController->dateTime();
227 auto range = impl->m_TimeController->dateTime();
228
228
229 if (auto newVariable = impl->m_VariableModel->createVariable(name, range, metadata)) {
229 if (auto newVariable = impl->m_VariableModel->createVariable(name, range, metadata)) {
230 auto identifier = QUuid::createUuid();
230 auto identifier = QUuid::createUuid();
231
231
232 // store the provider
232 // store the provider
233 impl->registerProvider(provider);
233 impl->registerProvider(provider);
234
234
235 // Associate the provider
235 // Associate the provider
236 impl->m_VariableToProviderMap[newVariable] = provider;
236 impl->m_VariableToProviderMap[newVariable] = provider;
237 impl->m_VariableToIdentifierMap[newVariable] = identifier;
237 impl->m_VariableToIdentifierMap[newVariable] = identifier;
238
238
239
239
240 impl->processRequest(newVariable, range);
240 impl->processRequest(newVariable, range);
241 }
241 }
242 }
242 }
243
243
244 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
244 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
245 {
245 {
246 // TODO check synchronisation
246 // TODO check synchronisation
247 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
247 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
248 << QThread::currentThread()->objectName();
248 << QThread::currentThread()->objectName();
249 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
249 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
250
250
251 for (const auto &selectedRow : qAsConst(selectedRows)) {
251 for (const auto &selectedRow : qAsConst(selectedRows)) {
252 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
252 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
253 selectedVariable->setRange(dateTime);
253 selectedVariable->setRange(dateTime);
254 impl->processRequest(selectedVariable, dateTime);
254 impl->processRequest(selectedVariable, dateTime);
255
255
256 // notify that rescale operation has to be done
256 // notify that rescale operation has to be done
257 emit rangeChanged(selectedVariable, dateTime);
257 emit rangeChanged(selectedVariable, dateTime);
258 }
258 }
259 }
259 }
260 }
260 }
261
261
262 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
262 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
263 const SqpRange &cacheRangeRequested,
263 const SqpRange &cacheRangeRequested,
264 QVector<AcquisitionDataPacket> dataAcquired)
264 QVector<AcquisitionDataPacket> dataAcquired)
265 {
265 {
266 if (auto var = impl->findVariable(vIdentifier)) {
266 if (auto var = impl->findVariable(vIdentifier)) {
267 var->setRange(rangeRequested);
267 var->setRange(rangeRequested);
268 var->setCacheRange(cacheRangeRequested);
268 var->setCacheRange(cacheRangeRequested);
269 qCDebug(LOG_VariableController()) << tr("1: onDataProvided") << rangeRequested;
269 qCDebug(LOG_VariableController()) << tr("1: onDataProvided") << rangeRequested;
270 qCDebug(LOG_VariableController()) << tr("2: onDataProvided") << cacheRangeRequested;
270 qCDebug(LOG_VariableController()) << tr("2: onDataProvided") << cacheRangeRequested;
271
271
272 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
272 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
273 qCDebug(LOG_VariableController()) << tr("3: onDataProvided")
273 qCDebug(LOG_VariableController()) << tr("3: onDataProvided")
274 << retrievedDataSeries->range();
274 << retrievedDataSeries->range();
275 var->mergeDataSeries(retrievedDataSeries);
275 var->mergeDataSeries(retrievedDataSeries);
276 qCDebug(LOG_VariableController()) << tr("4: onDataProvided");
276 qCDebug(LOG_VariableController()) << tr("4: onDataProvided");
277 emit var->updated();
277 emit var->updated();
278 }
278 }
279 else {
279 else {
280 qCCritical(LOG_VariableController()) << tr("Impossible to provide data to a null variable");
280 qCCritical(LOG_VariableController()) << tr("Impossible to provide data to a null variable");
281 }
281 }
282 }
282 }
283
283
284 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
284 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
285 {
285 {
286 if (auto var = impl->findVariable(identifier)) {
286 if (auto var = impl->findVariable(identifier)) {
287 impl->m_VariableModel->setDataProgress(var, progress);
287 impl->m_VariableModel->setDataProgress(var, progress);
288 }
288 }
289 else {
289 else {
290 qCCritical(LOG_VariableController())
290 qCCritical(LOG_VariableController())
291 << tr("Impossible to notify progression of a null variable");
291 << tr("Impossible to notify progression of a null variable");
292 }
292 }
293 }
293 }
294
294
295 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
295 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
296 {
296 {
297 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
297 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
298 << QThread::currentThread()->objectName();
298 << QThread::currentThread()->objectName();
299
299
300 auto it = impl->m_VariableToIdentifierMap.find(variable);
300 auto it = impl->m_VariableToIdentifierMap.find(variable);
301 if (it != impl->m_VariableToIdentifierMap.cend()) {
301 if (it != impl->m_VariableToIdentifierMap.cend()) {
302 impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
302 impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
303 }
303 }
304 else {
304 else {
305 qCWarning(LOG_VariableController())
305 qCWarning(LOG_VariableController())
306 << tr("Aborting progression of inexistant variable detected !!!")
306 << tr("Aborting progression of inexistant variable detected !!!")
307 << QThread::currentThread()->objectName();
307 << QThread::currentThread()->objectName();
308 }
308 }
309 }
309 }
310
310
311 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
311 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
312 {
312 {
313 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
313 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
314 << QThread::currentThread()->objectName()
314 << QThread::currentThread()->objectName()
315 << synchronizationGroupId;
315 << synchronizationGroupId;
316 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
316 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
317 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
317 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
318 std::make_pair(synchronizationGroupId, vSynchroGroup));
318 std::make_pair(synchronizationGroupId, vSynchroGroup));
319 }
319 }
320
320
321 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
321 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
322 {
322 {
323 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
323 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
324 }
324 }
325
325
326 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
326 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
327 QUuid synchronizationGroupId)
327 QUuid synchronizationGroupId)
328
328
329 {
329 {
330 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
330 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
331 << synchronizationGroupId;
331 << synchronizationGroupId;
332 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
332 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
333 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
333 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
334 auto groupIdToVSGIt
334 auto groupIdToVSGIt
335 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
335 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
336 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
336 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
337 impl->m_VariableIdGroupIdMap.insert(
337 impl->m_VariableIdGroupIdMap.insert(
338 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
338 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
339 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
339 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
340 }
340 }
341 else {
341 else {
342 qCCritical(LOG_VariableController())
342 qCCritical(LOG_VariableController())
343 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
343 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
344 << variable->name();
344 << variable->name();
345 }
345 }
346 }
346 }
347 else {
347 else {
348 qCCritical(LOG_VariableController())
348 qCCritical(LOG_VariableController())
349 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
349 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
350 }
350 }
351 }
351 }
352
352
353
353
354 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
354 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
355 const SqpRange &range, const SqpRange &oldRange,
355 const SqpRange &range, const SqpRange &oldRange,
356 bool synchronise)
356 bool synchronise)
357 {
357 {
358 // NOTE: oldRange isn't really necessary since oldRange == variable->range().
358 // NOTE: oldRange isn't really necessary since oldRange == variable->range().
359
359
360 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
360 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
361 << QThread::currentThread()->objectName();
361 << QThread::currentThread()->objectName();
362 // we want to load data of the variable for the dateTime.
362 // we want to load data of the variable for the dateTime.
363 // First we check if the cache contains some of them.
363 // First we check if the cache contains some of them.
364 // For the other, we ask the provider to give them.
364 // For the other, we ask the provider to give them.
365
365
366 for (const auto &var : variables) {
366 for (const auto &var : variables) {
367 qCDebug(LOG_VariableController()) << "processRequest for" << var->name();
367 qCDebug(LOG_VariableController()) << "processRequest for" << var->name();
368 impl->processRequest(var, range);
368 impl->processRequest(var, range);
369 }
369 }
370
370
371 if (synchronise) {
371 if (synchronise) {
372 // Get the group ids
372 // Get the group ids
373 qCDebug(LOG_VariableController())
373 qCDebug(LOG_VariableController())
374 << "TORM VariableController::onRequestDataLoading for synchro var ENABLE";
374 << "TORM VariableController::onRequestDataLoading for synchro var ENABLE";
375 auto groupIds = std::set<QUuid>();
375 auto groupIds = std::set<QUuid>();
376 for (const auto &var : variables) {
376 for (const auto &var : variables) {
377 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(var);
377 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(var);
378 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
378 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
379 auto vId = varToVarIdIt->second;
379 auto vId = varToVarIdIt->second;
380 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
380 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
381 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
381 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
382 auto gId = varIdToGroupIdIt->second;
382 auto gId = varIdToGroupIdIt->second;
383 if (groupIds.find(gId) == groupIds.cend()) {
383 if (groupIds.find(gId) == groupIds.cend()) {
384 qCDebug(LOG_VariableController()) << "Synchro detect group " << gId;
384 qCDebug(LOG_VariableController()) << "Synchro detect group " << gId;
385 groupIds.insert(gId);
385 groupIds.insert(gId);
386 }
386 }
387 }
387 }
388 }
388 }
389 }
389 }
390
390
391 // We assume here all group ids exist
391 // We assume here all group ids exist
392 for (const auto &gId : groupIds) {
392 for (const auto &gId : groupIds) {
393 auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId);
393 auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId);
394 auto vSyncIds = vSynchronizationGroup->getIds();
394 auto vSyncIds = vSynchronizationGroup->getIds();
395 qCDebug(LOG_VariableController()) << "Var in synchro group ";
395 qCDebug(LOG_VariableController()) << "Var in synchro group ";
396 for (auto vId : vSyncIds) {
396 for (auto vId : vSyncIds) {
397 auto var = impl->findVariable(vId);
397 auto var = impl->findVariable(vId);
398
398
399 // Don't process already processed var
399 // Don't process already processed var
400 if (!variables.contains(var)) {
400 if (!variables.contains(var)) {
401 if (var != nullptr) {
401 if (var != nullptr) {
402 qCDebug(LOG_VariableController()) << "processRequest synchro for"
402 qCDebug(LOG_VariableController()) << "processRequest synchro for"
403 << var->name();
403 << var->name();
404 auto vSyncRangeRequested
404 auto vSyncRangeRequested
405 = computeSynchroRangeRequested(var->range(), range, oldRange);
405 = computeSynchroRangeRequested(var->range(), range, oldRange);
406 impl->processRequest(var, vSyncRangeRequested);
406 impl->processRequest(var, vSyncRangeRequested);
407 }
407 }
408 else {
408 else {
409 qCCritical(LOG_VariableController())
409 qCCritical(LOG_VariableController())
410
410
411 << tr("Impossible to synchronize a null variable");
411 << tr("Impossible to synchronize a null variable");
412 }
412 }
413 }
413 }
414 }
414 }
415 }
415 }
416 }
416 }
417 }
417 }
418
418
419
419
420 void VariableController::initialize()
420 void VariableController::initialize()
421 {
421 {
422 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
422 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
423 impl->m_WorkingMutex.lock();
423 impl->m_WorkingMutex.lock();
424 qCDebug(LOG_VariableController()) << tr("VariableController init END");
424 qCDebug(LOG_VariableController()) << tr("VariableController init END");
425 }
425 }
426
426
427 void VariableController::finalize()
427 void VariableController::finalize()
428 {
428 {
429 impl->m_WorkingMutex.unlock();
429 impl->m_WorkingMutex.unlock();
430 }
430 }
431
431
432 void VariableController::waitForFinish()
432 void VariableController::waitForFinish()
433 {
433 {
434 QMutexLocker locker{&impl->m_WorkingMutex};
434 QMutexLocker locker{&impl->m_WorkingMutex};
435 }
435 }
436
436
437 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
437 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
438 {
438 {
439 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
439 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
440 auto zoomType = AcquisitionZoomType::Unknown;
440 auto zoomType = AcquisitionZoomType::Unknown;
441 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
441 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
442 zoomType = AcquisitionZoomType::ZoomOut;
442 zoomType = AcquisitionZoomType::ZoomOut;
443 }
443 }
444 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
444 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
445 zoomType = AcquisitionZoomType::PanRight;
445 zoomType = AcquisitionZoomType::PanRight;
446 }
446 }
447 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
447 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
448 zoomType = AcquisitionZoomType::PanLeft;
448 zoomType = AcquisitionZoomType::PanLeft;
449 }
449 }
450 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
450 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
451 zoomType = AcquisitionZoomType::ZoomIn;
451 zoomType = AcquisitionZoomType::ZoomIn;
452 }
452 }
453 else {
453 else {
454 qCCritical(LOG_VariableController()) << "getZoomType: Unknown type detected";
454 qCCritical(LOG_VariableController()) << "getZoomType: Unknown type detected";
455 }
455 }
456 return zoomType;
456 return zoomType;
457 }
457 }
458
458
459 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
459 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
460 const SqpRange &rangeRequested)
460 const SqpRange &rangeRequested)
461 {
461 {
462
462
463 auto varRangesRequested
463 auto varRangesRequested
464 = m_VariableCacheStrategy->computeCacheRange(var->range(), rangeRequested);
464 = m_VariableCacheStrategy->computeCacheRange(var->range(), rangeRequested);
465 auto notInCacheRangeList = var->provideNotInCacheRangeList(varRangesRequested.second);
465 auto notInCacheRangeList = var->provideNotInCacheRangeList(varRangesRequested.second);
466
466
467 if (!notInCacheRangeList.empty()) {
467 if (!notInCacheRangeList.empty()) {
468 auto identifier = m_VariableToIdentifierMap.at(var);
468 auto identifier = m_VariableToIdentifierMap.at(var);
469 auto varProvider = m_VariableToProviderMap.at(var);
469 auto varProvider = m_VariableToProviderMap.at(var);
470 if (varProvider != nullptr) {
470 if (varProvider != nullptr) {
471 m_VariableAcquisitionWorker->pushVariableRequest(
471 m_VariableAcquisitionWorker->pushVariableRequest(
472 identifier, varRangesRequested.first, varRangesRequested.second,
472 identifier, varRangesRequested.first, varRangesRequested.second,
473 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
473 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
474 varProvider);
474 varProvider);
475 }
475 }
476 else {
476 else {
477 qCCritical(LOG_VariableController())
477 qCCritical(LOG_VariableController())
478 << "Impossible to provide data with a null provider";
478 << "Impossible to provide data with a null provider";
479 }
479 }
480 }
480 }
481 else {
481 else {
482 var->setRange(rangeRequested);
482 var->setRange(rangeRequested);
483 var->setCacheRange(varRangesRequested.second);
483 var->setCacheRange(varRangesRequested.second);
484 var->setDataSeries(var->dataSeries()->subData(varRangesRequested.second));
484 var->setDataSeries(var->dataSeries()->subDataSeries(varRangesRequested.second));
485 emit var->updated();
485 emit var->updated();
486 }
486 }
487 }
487 }
488
488
489 std::shared_ptr<Variable>
489 std::shared_ptr<Variable>
490 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
490 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
491 {
491 {
492 std::shared_ptr<Variable> var;
492 std::shared_ptr<Variable> var;
493 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
493 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
494
494
495 auto end = m_VariableToIdentifierMap.cend();
495 auto end = m_VariableToIdentifierMap.cend();
496 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
496 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
497 if (it != end) {
497 if (it != end) {
498 var = it->first;
498 var = it->first;
499 }
499 }
500 else {
500 else {
501 qCCritical(LOG_VariableController())
501 qCCritical(LOG_VariableController())
502 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
502 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
503 }
503 }
504
504
505 return var;
505 return var;
506 }
506 }
507
507
508 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
508 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
509 const QVector<AcquisitionDataPacket> acqDataPacketVector)
509 const QVector<AcquisitionDataPacket> acqDataPacketVector)
510 {
510 {
511 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
511 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
512 << acqDataPacketVector.size();
512 << acqDataPacketVector.size();
513 std::shared_ptr<IDataSeries> dataSeries;
513 std::shared_ptr<IDataSeries> dataSeries;
514 if (!acqDataPacketVector.isEmpty()) {
514 if (!acqDataPacketVector.isEmpty()) {
515 dataSeries = acqDataPacketVector[0].m_DateSeries;
515 dataSeries = acqDataPacketVector[0].m_DateSeries;
516 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
516 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
517 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
517 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
518 }
518 }
519 }
519 }
520 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
520 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
521 << acqDataPacketVector.size();
521 << acqDataPacketVector.size();
522 return dataSeries;
522 return dataSeries;
523 }
523 }
524
524
525 void VariableController::VariableControllerPrivate::registerProvider(
525 void VariableController::VariableControllerPrivate::registerProvider(
526 std::shared_ptr<IDataProvider> provider)
526 std::shared_ptr<IDataProvider> provider)
527 {
527 {
528 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
528 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
529 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
529 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
530 << provider->objectName();
530 << provider->objectName();
531 m_ProviderSet.insert(provider);
531 m_ProviderSet.insert(provider);
532 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
532 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
533 &VariableAcquisitionWorker::onVariableDataAcquired);
533 &VariableAcquisitionWorker::onVariableDataAcquired);
534 connect(provider.get(), &IDataProvider::dataProvidedProgress,
534 connect(provider.get(), &IDataProvider::dataProvidedProgress,
535 m_VariableAcquisitionWorker.get(),
535 m_VariableAcquisitionWorker.get(),
536 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
536 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
537 }
537 }
538 else {
538 else {
539 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
539 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
540 }
540 }
541 }
541 }
General Comments 0
You need to be logged in to leave comments. Login now