##// END OF EJS Templates
Fixed untimely update of the range to be displayed in the variable widget
Alexandre Leroux -
r611:aff19a50babf
parent child
Show More
@@ -26,8 +26,21 struct SqpRange {
26 {
26 {
27 return (m_TEnd >= dateTime.m_TStart && m_TStart <= dateTime.m_TEnd);
27 return (m_TEnd >= dateTime.m_TStart && m_TStart <= dateTime.m_TEnd);
28 }
28 }
29
30 bool operator==(const SqpRange &other) const
31 {
32 auto equals = [](const auto &v1, const auto &v2) {
33 return (std::isnan(v1) && std::isnan(v2)) || v1 == v2;
34 };
35
36 return equals(m_TStart, other.m_TStart) && equals(m_TEnd, other.m_TEnd);
37 }
38 bool operator!=(const SqpRange &other) const { return !(*this == other); }
29 };
39 };
30
40
41 const auto INVALID_RANGE
42 = SqpRange{std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN()};
43
31 inline QDebug operator<<(QDebug d, SqpRange obj)
44 inline QDebug operator<<(QDebug d, SqpRange obj)
32 {
45 {
33 auto tendDateTimeStart = DateUtils::dateTime(obj.m_TStart);
46 auto tendDateTimeStart = DateUtils::dateTime(obj.m_TStart);
@@ -3,6 +3,7
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Data/DataSeriesIterator.h>
6 #include <Data/SqpRange.h>
7 #include <Data/SqpRange.h>
7
8
8 #include <QLoggingCategory>
9 #include <QLoggingCategory>
@@ -33,6 +34,14 public:
33 SqpRange cacheRange() const noexcept;
34 SqpRange cacheRange() const noexcept;
34 void setCacheRange(const SqpRange &cacheRange) noexcept;
35 void setCacheRange(const SqpRange &cacheRange) noexcept;
35
36
37 /// Returns the real range of the variable, i.e. the min and max x-axis values of the data
38 /// series between the range of the variable. The real range is updated each time the variable
39 /// range or the data series changed
40 /// @return the real range, invalid range if the data series is null or empty
41 /// @sa setDataSeries()
42 /// @sa setRange()
43 SqpRange realRange() const noexcept;
44
36 /// @return the data of the variable, nullptr if there is no data
45 /// @return the data of the variable, nullptr if there is no data
37 std::shared_ptr<IDataSeries> dataSeries() const noexcept;
46 std::shared_ptr<IDataSeries> dataSeries() const noexcept;
38
47
@@ -12,7 +12,11 Q_LOGGING_CATEGORY(LOG_Variable, "Variable")
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},
16 m_Range{dateTime},
17 m_Metadata{metadata},
18 m_DataSeries{nullptr},
19 m_RealRange{INVALID_RANGE}
16 {
20 {
17 }
21 }
18
22
@@ -20,12 +24,32 struct Variable::VariablePrivate {
20 void lockWrite() { m_Lock.lockForWrite(); }
24 void lockWrite() { m_Lock.lockForWrite(); }
21 void unlock() { m_Lock.unlock(); }
25 void unlock() { m_Lock.unlock(); }
22
26
27 /// Updates real range according to current variable range and data series
28 void updateRealRange()
29 {
30 if (m_DataSeries) {
31 m_DataSeries->lockRead();
32 auto end = m_DataSeries->cend();
33 auto minXAxisIt = m_DataSeries->minXAxisData(m_Range.m_TStart);
34 auto maxXAxisIt = m_DataSeries->maxXAxisData(m_Range.m_TEnd);
35
36 m_RealRange = (minXAxisIt != end && maxXAxisIt != end)
37 ? SqpRange{minXAxisIt->x(), maxXAxisIt->x()}
38 : INVALID_RANGE;
39 m_DataSeries->unlock();
40 }
41 else {
42 m_RealRange = INVALID_RANGE;
43 }
44 }
45
23 QString m_Name;
46 QString m_Name;
24
47
25 SqpRange m_Range;
48 SqpRange m_Range;
26 SqpRange m_CacheRange;
49 SqpRange m_CacheRange;
27 QVariantHash m_Metadata;
50 QVariantHash m_Metadata;
28 std::shared_ptr<IDataSeries> m_DataSeries;
51 std::shared_ptr<IDataSeries> m_DataSeries;
52 SqpRange m_RealRange;
29
53
30 QReadWriteLock m_Lock;
54 QReadWriteLock m_Lock;
31 };
55 };
@@ -55,6 +79,7 void Variable::setRange(const SqpRange &range) noexcept
55 {
79 {
56 impl->lockWrite();
80 impl->lockWrite();
57 impl->m_Range = range;
81 impl->m_Range = range;
82 impl->updateRealRange();
58 impl->unlock();
83 impl->unlock();
59 }
84 }
60
85
@@ -73,6 +98,11 void Variable::setCacheRange(const SqpRange &cacheRange) noexcept
73 impl->unlock();
98 impl->unlock();
74 }
99 }
75
100
101 SqpRange Variable::realRange() const noexcept
102 {
103 return impl->m_RealRange;
104 }
105
76 void Variable::setDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
106 void Variable::setDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
77 {
107 {
78 qCDebug(LOG_Variable()) << "TORM Variable::setDataSeries"
108 qCDebug(LOG_Variable()) << "TORM Variable::setDataSeries"
@@ -83,6 +113,7 void Variable::setDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
83 }
113 }
84 impl->lockWrite();
114 impl->lockWrite();
85 impl->m_DataSeries = dataSeries->clone();
115 impl->m_DataSeries = dataSeries->clone();
116 impl->updateRealRange();
86 impl->unlock();
117 impl->unlock();
87 }
118 }
88
119
@@ -153,35 +153,21 QVariant VariableModel::data(const QModelIndex &index, int role) const
153
153
154 if (role == Qt::DisplayRole) {
154 if (role == Qt::DisplayRole) {
155 if (auto variable = impl->m_Variables.at(index.row()).get()) {
155 if (auto variable = impl->m_Variables.at(index.row()).get()) {
156 /// Lambda function that builds the variant to return for a time value
157 /// @param getValueFun function used to get for a data series the iterator on the entry
158 /// that contains the time value to display
159 auto dateTimeVariant = [variable](const auto &getValueFun) {
160 if (auto dataSeries = variable->dataSeries()) {
161 dataSeries->lockRead();
162 auto it = getValueFun(*dataSeries);
163 auto resVariant = (it != dataSeries->cend())
164 ? DateUtils::dateTime(it->x()).toString(DATETIME_FORMAT)
165 : QVariant{};
166 dataSeries->unlock();
167 return resVariant;
168 }
169 else {
170 return QVariant{};
171 }
172 };
173
174 switch (index.column()) {
156 switch (index.column()) {
175 case NAME_COLUMN:
157 case NAME_COLUMN:
176 return variable->name();
158 return variable->name();
177 case TSTART_COLUMN:
159 case TSTART_COLUMN: {
178 // Shows the min value of the data series above the range tstart
160 auto range = variable->realRange();
179 return dateTimeVariant([min = variable->range().m_TStart](
161 return range != INVALID_RANGE
180 const auto &dataSeries) { return dataSeries.minXAxisData(min); });
162 ? DateUtils::dateTime(range.m_TStart).toString(DATETIME_FORMAT)
181 case TEND_COLUMN:
163 : QVariant{};
182 // Shows the max value of the data series under the range tend
164 }
183 return dateTimeVariant([max = variable->range().m_TEnd](
165 case TEND_COLUMN: {
184 const auto &dataSeries) { return dataSeries.maxXAxisData(max); });
166 auto range = variable->realRange();
167 return range != INVALID_RANGE
168 ? DateUtils::dateTime(range.m_TEnd).toString(DATETIME_FORMAT)
169 : QVariant{};
170 }
185 case UNIT_COLUMN:
171 case UNIT_COLUMN:
186 return variable->metadata().value(QStringLiteral("units"));
172 return variable->metadata().value(QStringLiteral("units"));
187 case MISSION_COLUMN:
173 case MISSION_COLUMN:
General Comments 0
You need to be logged in to leave comments. Login now