##// END OF EJS Templates
Switched to cpp_utils package...
jeandet -
r94:29637e951955
parent child
Show More
@@ -1,225 +1,225
1 #ifndef SCIQLOP_DATETIMERANGE_H
1 #ifndef SCIQLOP_DATETIMERANGE_H
2 #define SCIQLOP_DATETIMERANGE_H
2 #define SCIQLOP_DATETIMERANGE_H
3
3
4 #include <Common/DateUtils.h>
4 #include <Common/DateUtils.h>
5 #include <Common/MetaTypes.h>
5 #include <Common/MetaTypes.h>
6 #include <Common/Numeric.h>
6 #include <Numeric.h>
7 #include <QDebug>
7 #include <QDebug>
8 #include <QObject>
8 #include <QObject>
9 #include <cmath>
9 #include <cmath>
10 #include <opaque/numeric_typedef.hpp>
10 #include <opaque/numeric_typedef.hpp>
11
11
12 template<typename T>
12 template<typename T>
13 struct Seconds
13 struct Seconds
14 : opaque::numeric_typedef<T, Seconds<T>>,
14 : opaque::numeric_typedef<T, Seconds<T>>,
15 opaque::binop::multipliable<Seconds<T>, true, Seconds<T>, T, T>,
15 opaque::binop::multipliable<Seconds<T>, true, Seconds<T>, T, T>,
16 opaque::binop::dividable<Seconds<T>, true, Seconds<T>, T, T>,
16 opaque::binop::dividable<Seconds<T>, true, Seconds<T>, T, T>,
17 opaque::binop::addable<Seconds<T>, true, Seconds<T>, T, T>,
17 opaque::binop::addable<Seconds<T>, true, Seconds<T>, T, T>,
18 opaque::binop::subtractable<Seconds<T>, true, Seconds<T>, T, T>
18 opaque::binop::subtractable<Seconds<T>, true, Seconds<T>, T, T>
19
19
20 {
20 {
21 using base = opaque::numeric_typedef<T, Seconds<T>>;
21 using base = opaque::numeric_typedef<T, Seconds<T>>;
22 using base::base;
22 using base::base;
23 operator T() const { return this->value; }
23 operator T() const { return this->value; }
24 };
24 };
25
25
26 struct InvalidDateTimeRangeTransformation
26 struct InvalidDateTimeRangeTransformation
27 {};
27 {};
28
28
29 struct DateTimeRangeTransformation
29 struct DateTimeRangeTransformation
30 {
30 {
31 double zoom;
31 double zoom;
32 Seconds<double> shift;
32 Seconds<double> shift;
33 bool operator==(const DateTimeRangeTransformation& other) const
33 bool operator==(const DateTimeRangeTransformation& other) const
34 {
34 {
35 return SciQLop::numeric::almost_equal(zoom, other.zoom, 1) &&
35 return cpp_utils::numeric::almost_equal(zoom, other.zoom, 1) &&
36 SciQLop::numeric::almost_equal<double>(shift, other.shift, 1);
36 cpp_utils::numeric::almost_equal<double>(shift, other.shift, 1);
37 }
37 }
38 DateTimeRangeTransformation
38 DateTimeRangeTransformation
39 merge(const DateTimeRangeTransformation& other) const
39 merge(const DateTimeRangeTransformation& other) const
40 {
40 {
41 return DateTimeRangeTransformation{zoom * other.zoom, shift + other.shift};
41 return DateTimeRangeTransformation{zoom * other.zoom, shift + other.shift};
42 }
42 }
43 };
43 };
44
44
45 /**
45 /**
46 * @brief The SqpRange struct holds the information of time parameters
46 * @brief The SqpRange struct holds the information of time parameters
47 */
47 */
48 struct DateTimeRange
48 struct DateTimeRange
49 {
49 {
50 DateTimeRange() : m_TStart(std::nan("")), m_TEnd(std::nan("")) {}
50 DateTimeRange() : m_TStart(std::nan("")), m_TEnd(std::nan("")) {}
51 DateTimeRange(double TStart, double TEnd) : m_TStart(TStart), m_TEnd(TEnd) {}
51 DateTimeRange(double TStart, double TEnd) : m_TStart(TStart), m_TEnd(TEnd) {}
52 DateTimeRange(const std::pair<double, double>& range)
52 DateTimeRange(const std::pair<double, double>& range)
53 : m_TStart(range.first), m_TEnd(range.second)
53 : m_TStart(range.first), m_TEnd(range.second)
54 {}
54 {}
55 /// Creates SqpRange from dates and times
55 /// Creates SqpRange from dates and times
56 static DateTimeRange fromDateTime(const QDate& startDate,
56 static DateTimeRange fromDateTime(const QDate& startDate,
57 const QTime& startTime,
57 const QTime& startTime,
58 const QDate& endDate, const QTime& endTime)
58 const QDate& endDate, const QTime& endTime)
59 {
59 {
60 return {
60 return {
61 DateUtils::secondsSinceEpoch(QDateTime{startDate, startTime, Qt::UTC}),
61 DateUtils::secondsSinceEpoch(QDateTime{startDate, startTime, Qt::UTC}),
62 DateUtils::secondsSinceEpoch(QDateTime{endDate, endTime, Qt::UTC})};
62 DateUtils::secondsSinceEpoch(QDateTime{endDate, endTime, Qt::UTC})};
63 }
63 }
64
64
65 static DateTimeRange fromDateTime(const QDateTime& start,
65 static DateTimeRange fromDateTime(const QDateTime& start,
66 const QDateTime& end)
66 const QDateTime& end)
67 {
67 {
68 return {DateUtils::secondsSinceEpoch(start),
68 return {DateUtils::secondsSinceEpoch(start),
69 DateUtils::secondsSinceEpoch(end)};
69 DateUtils::secondsSinceEpoch(end)};
70 }
70 }
71
71
72 /// Start time (UTC)
72 /// Start time (UTC)
73 double m_TStart;
73 double m_TStart;
74 /// End time (UTC)
74 /// End time (UTC)
75 double m_TEnd;
75 double m_TEnd;
76
76
77 Seconds<double> delta() const noexcept
77 Seconds<double> delta() const noexcept
78 {
78 {
79 return Seconds<double>{this->m_TEnd - this->m_TStart};
79 return Seconds<double>{this->m_TEnd - this->m_TStart};
80 }
80 }
81
81
82 bool contains(const DateTimeRange& dateTime) const noexcept
82 bool contains(const DateTimeRange& dateTime) const noexcept
83 {
83 {
84 return (m_TStart <= dateTime.m_TStart && m_TEnd >= dateTime.m_TEnd);
84 return (m_TStart <= dateTime.m_TStart && m_TEnd >= dateTime.m_TEnd);
85 }
85 }
86
86
87 Seconds<double> center() const noexcept
87 Seconds<double> center() const noexcept
88 {
88 {
89 return Seconds<double>((m_TStart + m_TEnd) / 2.);
89 return Seconds<double>((m_TStart + m_TEnd) / 2.);
90 }
90 }
91
91
92 bool intersect(const DateTimeRange& dateTime) const noexcept
92 bool intersect(const DateTimeRange& dateTime) const noexcept
93 {
93 {
94 return (m_TEnd >= dateTime.m_TStart && m_TStart <= dateTime.m_TEnd);
94 return (m_TEnd >= dateTime.m_TStart && m_TStart <= dateTime.m_TEnd);
95 }
95 }
96
96
97 inline DateTimeRange transform(const DateTimeRangeTransformation& tr) const
97 inline DateTimeRange transform(const DateTimeRangeTransformation& tr) const
98 noexcept;
98 noexcept;
99
99
100 bool operator==(const DateTimeRange& other) const
100 bool operator==(const DateTimeRange& other) const
101 {
101 {
102 return SciQLop::numeric::almost_equal(m_TStart, other.m_TStart, 1) &&
102 return cpp_utils::numeric::almost_equal(m_TStart, other.m_TStart, 1) &&
103 SciQLop::numeric::almost_equal(m_TEnd, other.m_TEnd, 1);
103 cpp_utils::numeric::almost_equal(m_TEnd, other.m_TEnd, 1);
104 }
104 }
105
105
106 bool operator!=(const DateTimeRange& other) const
106 bool operator!=(const DateTimeRange& other) const
107 {
107 {
108 return !(*this == other);
108 return !(*this == other);
109 }
109 }
110
110
111 void grow(double factor) noexcept
111 void grow(double factor) noexcept
112 {
112 {
113 double grow_v{delta() * (factor - 1.) / 2.};
113 double grow_v{delta() * (factor - 1.) / 2.};
114 m_TStart -= grow_v;
114 m_TStart -= grow_v;
115 m_TEnd += grow_v;
115 m_TEnd += grow_v;
116 }
116 }
117
117
118 void shrink(double factor) noexcept
118 void shrink(double factor) noexcept
119 {
119 {
120 double shrink_v{this->delta() * (1. - factor) / 2.};
120 double shrink_v{this->delta() * (1. - factor) / 2.};
121 m_TStart += shrink_v;
121 m_TStart += shrink_v;
122 m_TEnd -= shrink_v;
122 m_TEnd -= shrink_v;
123 }
123 }
124
124
125 DateTimeRange& operator*=(double k)
125 DateTimeRange& operator*=(double k)
126 {
126 {
127 this->grow(k);
127 this->grow(k);
128 return *this;
128 return *this;
129 }
129 }
130
130
131 DateTimeRange& operator/=(double k)
131 DateTimeRange& operator/=(double k)
132 {
132 {
133 this->shrink(k);
133 this->shrink(k);
134 return *this;
134 return *this;
135 }
135 }
136
136
137 // compute set difference
137 // compute set difference
138 std::vector<DateTimeRange> operator-(const DateTimeRange& other) const
138 std::vector<DateTimeRange> operator-(const DateTimeRange& other) const
139 {
139 {
140 std::vector<DateTimeRange> result;
140 std::vector<DateTimeRange> result;
141 if(std::isnan(other.m_TStart) || std::isnan(other.m_TEnd) ||
141 if(std::isnan(other.m_TStart) || std::isnan(other.m_TEnd) ||
142 !this->intersect(other))
142 !this->intersect(other))
143 { result.emplace_back(m_TStart, m_TEnd); }
143 { result.emplace_back(m_TStart, m_TEnd); }
144 else
144 else
145 {
145 {
146 if(this->m_TStart < other.m_TStart)
146 if(this->m_TStart < other.m_TStart)
147 { result.emplace_back(this->m_TStart, other.m_TStart); }
147 { result.emplace_back(this->m_TStart, other.m_TStart); }
148 if(this->m_TEnd > other.m_TEnd)
148 if(this->m_TEnd > other.m_TEnd)
149 { result.emplace_back(other.m_TEnd, this->m_TEnd); }
149 { result.emplace_back(other.m_TEnd, this->m_TEnd); }
150 }
150 }
151 return result;
151 return result;
152 }
152 }
153 };
153 };
154
154
155 template<class T> DateTimeRange& operator+=(DateTimeRange& r, Seconds<T> offset)
155 template<class T> DateTimeRange& operator+=(DateTimeRange& r, Seconds<T> offset)
156 {
156 {
157 shift(r, offset);
157 shift(r, offset);
158 return r;
158 return r;
159 }
159 }
160
160
161 template<class T> DateTimeRange& operator-=(DateTimeRange& r, Seconds<T> offset)
161 template<class T> DateTimeRange& operator-=(DateTimeRange& r, Seconds<T> offset)
162 {
162 {
163 shift(r, -offset);
163 shift(r, -offset);
164 return r;
164 return r;
165 }
165 }
166
166
167 template<class T> void shift(DateTimeRange& r, Seconds<T> offset)
167 template<class T> void shift(DateTimeRange& r, Seconds<T> offset)
168 {
168 {
169 r.m_TEnd += static_cast<double>(offset);
169 r.m_TEnd += static_cast<double>(offset);
170 r.m_TStart += static_cast<double>(offset);
170 r.m_TStart += static_cast<double>(offset);
171 }
171 }
172
172
173 inline DateTimeRange operator*(const DateTimeRange& r, double k)
173 inline DateTimeRange operator*(const DateTimeRange& r, double k)
174 {
174 {
175 DateTimeRange result{r};
175 DateTimeRange result{r};
176 result.grow(k);
176 result.grow(k);
177 return result;
177 return result;
178 }
178 }
179
179
180 inline DateTimeRange operator/(const DateTimeRange& r, double k)
180 inline DateTimeRange operator/(const DateTimeRange& r, double k)
181 {
181 {
182 DateTimeRange result{r};
182 DateTimeRange result{r};
183 result.shrink(k);
183 result.shrink(k);
184 return result;
184 return result;
185 }
185 }
186
186
187 template<class T>
187 template<class T>
188 DateTimeRange operator+(const DateTimeRange& r, Seconds<T> offset)
188 DateTimeRange operator+(const DateTimeRange& r, Seconds<T> offset)
189 {
189 {
190 DateTimeRange result{r};
190 DateTimeRange result{r};
191 shift(result, offset);
191 shift(result, offset);
192 return result;
192 return result;
193 }
193 }
194
194
195 template<class T>
195 template<class T>
196 DateTimeRange operator-(const DateTimeRange& r, Seconds<T> offset)
196 DateTimeRange operator-(const DateTimeRange& r, Seconds<T> offset)
197 {
197 {
198 DateTimeRange result{r};
198 DateTimeRange result{r};
199 shift(result, -offset);
199 shift(result, -offset);
200 return result;
200 return result;
201 }
201 }
202
202
203 const auto INVALID_RANGE =
203 const auto INVALID_RANGE =
204 DateTimeRange{std::numeric_limits<double>::quiet_NaN(),
204 DateTimeRange{std::numeric_limits<double>::quiet_NaN(),
205 std::numeric_limits<double>::quiet_NaN()};
205 std::numeric_limits<double>::quiet_NaN()};
206
206
207 inline QDebug operator<<(QDebug d, DateTimeRange obj)
207 inline QDebug operator<<(QDebug d, DateTimeRange obj)
208 {
208 {
209 auto tendDateTimeStart = DateUtils::dateTime(obj.m_TStart);
209 auto tendDateTimeStart = DateUtils::dateTime(obj.m_TStart);
210 auto tendDateTimeEnd = DateUtils::dateTime(obj.m_TEnd);
210 auto tendDateTimeEnd = DateUtils::dateTime(obj.m_TEnd);
211
211
212 d << "ts: " << tendDateTimeStart << " te: " << tendDateTimeEnd;
212 d << "ts: " << tendDateTimeStart << " te: " << tendDateTimeEnd;
213 return d;
213 return d;
214 }
214 }
215
215
216 DateTimeRange
216 DateTimeRange
217 DateTimeRange::transform(const DateTimeRangeTransformation& tr) const noexcept
217 DateTimeRange::transform(const DateTimeRangeTransformation& tr) const noexcept
218 {
218 {
219 return DateTimeRange{*this} * tr.zoom + tr.shift;
219 return DateTimeRange{*this} * tr.zoom + tr.shift;
220 }
220 }
221
221
222 // Required for using shared_ptr in signals/slots
222 // Required for using shared_ptr in signals/slots
223 SCIQLOP_REGISTER_META_TYPE(SQPRANGE_REGISTRY, DateTimeRange)
223 SCIQLOP_REGISTER_META_TYPE(SQPRANGE_REGISTRY, DateTimeRange)
224
224
225 #endif // SCIQLOP_DATETIMERANGE_H
225 #endif // SCIQLOP_DATETIMERANGE_H
@@ -1,86 +1,86
1 #ifndef SCIQLOP_DATETIMERANGEHELPER_H
1 #ifndef SCIQLOP_DATETIMERANGEHELPER_H
2 #define SCIQLOP_DATETIMERANGEHELPER_H
2 #define SCIQLOP_DATETIMERANGEHELPER_H
3
3
4 #include <optional>
4 #include <optional>
5
5
6 #include <cmath>
6 #include <cmath>
7 #include <variant>
7 #include <variant>
8 #include <QObject>
8 #include <QObject>
9
9
10 #include <QDebug>
10 #include <QDebug>
11
11
12 #include <opaque/numeric_typedef.hpp>
12 #include <opaque/numeric_typedef.hpp>
13 #include <Common/DateUtils.h>
13 #include <Common/DateUtils.h>
14 #include <Common/MetaTypes.h>
14 #include <Common/MetaTypes.h>
15 #include <Common/Numeric.h>
15 #include <Numeric.h>
16 #include <Data/DateTimeRange.h>
16 #include <Data/DateTimeRange.h>
17
17
18 enum class TransformationType { ZoomOut, ZoomIn, PanRight, PanLeft, Unknown };
18 enum class TransformationType { ZoomOut, ZoomIn, PanRight, PanLeft, Unknown };
19
19
20 namespace DateTimeRangeHelper {
20 namespace DateTimeRangeHelper {
21
21
22
22
23 inline bool isnan(const DateTimeRange& range)
23 inline bool isnan(const DateTimeRange& range)
24 {
24 {
25 return std::isnan(range.m_TStart) && std::isnan(range.m_TEnd);
25 return std::isnan(range.m_TStart) && std::isnan(range.m_TEnd);
26 }
26 }
27
27
28 inline bool hasnan(const DateTimeRange& range)
28 inline bool hasnan(const DateTimeRange& range)
29 {
29 {
30 return std::isnan(range.m_TStart) || std::isnan(range.m_TEnd);
30 return std::isnan(range.m_TStart) || std::isnan(range.m_TEnd);
31 }
31 }
32
32
33 inline bool isPureShift(const DateTimeRange& range1, const DateTimeRange& range2)
33 inline bool isPureShift(const DateTimeRange& range1, const DateTimeRange& range2)
34 {
34 {
35 return SciQLop::numeric::almost_equal<double>(range1.delta(), range2.delta(), 1)
35 return cpp_utils::numeric::almost_equal<double>(range1.delta(), range2.delta(), 1)
36 && !SciQLop::numeric::almost_equal(range1.m_TStart, range2.m_TStart, 1);
36 && !cpp_utils::numeric::almost_equal(range1.m_TStart, range2.m_TStart, 1);
37 }
37 }
38
38
39 inline bool isPureZoom(const DateTimeRange& range1, const DateTimeRange& range2)
39 inline bool isPureZoom(const DateTimeRange& range1, const DateTimeRange& range2)
40 {
40 {
41 return !SciQLop::numeric::almost_equal<double>(range1.delta(),range2.delta(),1)&&
41 return !cpp_utils::numeric::almost_equal<double>(range1.delta(),range2.delta(),1)&&
42 SciQLop::numeric::almost_equal<double>(range1.center(), range2.center(),1);
42 cpp_utils::numeric::almost_equal<double>(range1.center(), range2.center(),1);
43 }
43 }
44
44
45
45
46 /**
46 /**
47 * @brief computeTransformation such as range2 = zoom*range1 + shift
47 * @brief computeTransformation such as range2 = zoom*range1 + shift
48 * @param range1
48 * @param range1
49 * @param range2
49 * @param range2
50 * @return trnaformation applied to range1 to get range2 or an object of type
50 * @return trnaformation applied to range1 to get range2 or an object of type
51 * InvalidDateTimeRangeTransformation if the transformation has NaN or forbiden values
51 * InvalidDateTimeRangeTransformation if the transformation has NaN or forbiden values
52 */
52 */
53 inline std::optional<DateTimeRangeTransformation>
53 inline std::optional<DateTimeRangeTransformation>
54 computeTransformation(const DateTimeRange& range1, const DateTimeRange& range2)
54 computeTransformation(const DateTimeRange& range1, const DateTimeRange& range2)
55 {
55 {
56 std::optional<DateTimeRangeTransformation> transformation;
56 std::optional<DateTimeRangeTransformation> transformation;
57 double zoom = range2.delta()/range1.delta();
57 double zoom = range2.delta()/range1.delta();
58 Seconds<double> shift = range2.center() - (range1*zoom).center();
58 Seconds<double> shift = range2.center() - (range1*zoom).center();
59 bool zoomValid = zoom!=0. && !std::isnan(zoom) && !std::isinf(zoom);
59 bool zoomValid = zoom!=0. && !std::isnan(zoom) && !std::isinf(zoom);
60 bool shiftValid = !std::isnan(shift.value) && !std::isinf(shift.value);
60 bool shiftValid = !std::isnan(shift.value) && !std::isinf(shift.value);
61 if(zoomValid && shiftValid)
61 if(zoomValid && shiftValid)
62 transformation = DateTimeRangeTransformation{zoom, shift};
62 transformation = DateTimeRangeTransformation{zoom, shift};
63 return transformation;
63 return transformation;
64 }
64 }
65
65
66 inline TransformationType getTransformationType(const DateTimeRange& range1, const DateTimeRange& range2)
66 inline TransformationType getTransformationType(const DateTimeRange& range1, const DateTimeRange& range2)
67 {
67 {
68 auto transformation = computeTransformation (range1,range2);
68 auto transformation = computeTransformation (range1,range2);
69 if(transformation.has_value ())
69 if(transformation.has_value ())
70 {
70 {
71 if(SciQLop::numeric::almost_equal(transformation->zoom,1.))
71 if(cpp_utils::numeric::almost_equal(transformation->zoom,1.))
72 {
72 {
73 if(transformation->shift > 0.)
73 if(transformation->shift > 0.)
74 return TransformationType::PanRight;
74 return TransformationType::PanRight;
75 return TransformationType::PanLeft;
75 return TransformationType::PanLeft;
76 }
76 }
77 if(transformation->zoom > 0.)
77 if(transformation->zoom > 0.)
78 return TransformationType::ZoomOut;
78 return TransformationType::ZoomOut;
79 return TransformationType::ZoomIn;
79 return TransformationType::ZoomIn;
80 }
80 }
81 return TransformationType::Unknown;
81 return TransformationType::Unknown;
82 }
82 }
83
83
84 }
84 }
85
85
86 #endif // SCIQLOP_DATETIMERANGEHELPER_H
86 #endif // SCIQLOP_DATETIMERANGEHELPER_H
@@ -1,60 +1,60
1 #ifndef SCIQLOP_IDATAPROVIDER_H
1 #ifndef SCIQLOP_IDATAPROVIDER_H
2 #define SCIQLOP_IDATAPROVIDER_H
2 #define SCIQLOP_IDATAPROVIDER_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Common/MetaTypes.h>
6 #include <Common/MetaTypes.h>
7 #include <Common/deprecate.h>
7 #include <deprecate.h>
8 #include <Data/DateTimeRange.h>
8 #include <Data/DateTimeRange.h>
9 #include <QObject>
9 #include <QObject>
10 #include <QUuid>
10 #include <QUuid>
11 #include <TimeSeries.h>
11 #include <TimeSeries.h>
12 #include <functional>
12 #include <functional>
13 #include <memory>
13 #include <memory>
14
14
15 class DataProviderParameters;
15 class DataProviderParameters;
16 class IDataSeries;
16 class IDataSeries;
17 DEPRECATE(class QNetworkReply; class QNetworkRequest;)
17 DEPRECATE(class QNetworkReply; class QNetworkRequest;)
18
18
19 /**
19 /**
20 * @brief The IDataProvider interface aims to declare a data provider.
20 * @brief The IDataProvider interface aims to declare a data provider.
21 *
21 *
22 * A data provider is an entity that generates data and returns it according to
22 * A data provider is an entity that generates data and returns it according to
23 * various parameters (time interval, product to retrieve the data, etc.) Since
23 * various parameters (time interval, product to retrieve the data, etc.) Since
24 * its client mihgt use it from different threads it has to be either stateless
24 * its client mihgt use it from different threads it has to be either stateless
25 * and/or thread safe
25 * and/or thread safe
26 *
26 *
27 * @sa IDataSeries
27 * @sa IDataSeries
28 */
28 */
29 class SCIQLOP_CORE_EXPORT IDataProvider : public QObject
29 class SCIQLOP_CORE_EXPORT IDataProvider : public QObject
30 {
30 {
31 Q_OBJECT
31 Q_OBJECT
32
32
33 QUuid _id=QUuid::createUuid();
33 QUuid _id=QUuid::createUuid();
34
34
35 public:
35 public:
36 virtual ~IDataProvider() noexcept = default;
36 virtual ~IDataProvider() noexcept = default;
37 // virtual std::shared_ptr<IDataProvider> clone() const = 0;
37 // virtual std::shared_ptr<IDataProvider> clone() const = 0;
38
38
39 // Synchronous call -> asyncGetData may be written for asynchronous get
39 // Synchronous call -> asyncGetData may be written for asynchronous get
40 virtual TimeSeries::ITimeSerie*
40 virtual TimeSeries::ITimeSerie*
41 getData(const DataProviderParameters& parameters) = 0;
41 getData(const DataProviderParameters& parameters) = 0;
42
42
43 QUuid id() const { return _id; }
43 QUuid id() const { return _id; }
44 QString name()
44 QString name()
45 {
45 {
46 return QString("%1-%2").arg(this->metaObject()->className()).arg(id().toString());
46 return QString("%1-%2").arg(this->metaObject()->className()).arg(id().toString());
47 }
47 }
48
48
49 signals:
49 signals:
50
50
51 void progress(QUuid requestID, double progress);
51 void progress(QUuid requestID, double progress);
52 };
52 };
53
53
54 // Required for using shared_ptr in signals/slots
54 // Required for using shared_ptr in signals/slots
55 SCIQLOP_REGISTER_META_TYPE(IDATAPROVIDER_PTR_REGISTRY,
55 SCIQLOP_REGISTER_META_TYPE(IDATAPROVIDER_PTR_REGISTRY,
56 std::shared_ptr<IDataProvider>)
56 std::shared_ptr<IDataProvider>)
57 SCIQLOP_REGISTER_META_TYPE(IDATAPROVIDER_FUNCTION_REGISTRY,
57 SCIQLOP_REGISTER_META_TYPE(IDATAPROVIDER_FUNCTION_REGISTRY,
58 std::function<void(QNetworkReply*, QUuid)>)
58 std::function<void(QNetworkReply*, QUuid)>)
59
59
60 #endif // SCIQLOP_IDATAPROVIDER_H
60 #endif // SCIQLOP_IDATAPROVIDER_H
@@ -1,189 +1,189
1 #ifndef SCIQLOP_DATASOURCEITEM_H
1 #ifndef SCIQLOP_DATASOURCEITEM_H
2 #define SCIQLOP_DATASOURCEITEM_H
2 #define SCIQLOP_DATASOURCEITEM_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Common/spimpl.h>
6 #include <Common/spimpl.h>
7 #include <Common/trees.h>
7 #include <trees/algorithms.hpp>
8 #include <QVariant>
8 #include <QVariant>
9 #include <QVector>
9 #include <QVector>
10 #include <iostream>
10 #include <iostream>
11 #include <iomanip>
11 #include <iomanip>
12
12
13 class DataSourceItemAction;
13 class DataSourceItemAction;
14
14
15 /**
15 /**
16 * Possible types of an item
16 * Possible types of an item
17 */
17 */
18 enum class DataSourceItemType
18 enum class DataSourceItemType
19 {
19 {
20 NODE,
20 NODE,
21 PRODUCT,
21 PRODUCT,
22 COMPONENT
22 COMPONENT
23 };
23 };
24
24
25
25
26
26
27 /**
27 /**
28 * @brief The DataSourceItem class aims to represent a structure element of a
28 * @brief The DataSourceItem class aims to represent a structure element of a
29 * data source. A data source has a tree structure that is made up of a main
29 * data source. A data source has a tree structure that is made up of a main
30 * DataSourceItem object (root) containing other DataSourceItem objects
30 * DataSourceItem object (root) containing other DataSourceItem objects
31 * (children). For each DataSourceItem can be associated a set of data
31 * (children). For each DataSourceItem can be associated a set of data
32 * representing it.
32 * representing it.
33 */
33 */
34 class SCIQLOP_CORE_EXPORT DataSourceItem
34 class SCIQLOP_CORE_EXPORT DataSourceItem
35 {
35 {
36
36
37 public:
37 public:
38 using iterator_type = decltype (std::begin(std::declval<std::vector<std::unique_ptr<DataSourceItem>>>()));
38 using iterator_type = decltype (std::begin(std::declval<std::vector<std::unique_ptr<DataSourceItem>>>()));
39 using const_iterator_type = decltype (std::cbegin(std::declval<std::vector<std::unique_ptr<DataSourceItem>>>()));
39 using const_iterator_type = decltype (std::cbegin(std::declval<std::vector<std::unique_ptr<DataSourceItem>>>()));
40 /// Key associated with the name of the item
40 /// Key associated with the name of the item
41 static const QString NAME_DATA_KEY;
41 static const QString NAME_DATA_KEY;
42 /// Key associated with the plugin of the item
42 /// Key associated with the plugin of the item
43 static const QString PLUGIN_DATA_KEY;
43 static const QString PLUGIN_DATA_KEY;
44 /// Key associated with a unique id of the plugin
44 /// Key associated with a unique id of the plugin
45 static const QString ID_DATA_KEY;
45 static const QString ID_DATA_KEY;
46
46
47 explicit DataSourceItem(DataSourceItemType type, const QString& name);
47 explicit DataSourceItem(DataSourceItemType type, const QString& name);
48 explicit DataSourceItem(DataSourceItemType type, QVariantHash data = {});
48 explicit DataSourceItem(DataSourceItemType type, QVariantHash data = {});
49
49
50 std::unique_ptr<DataSourceItem> clone() const;
50 std::unique_ptr<DataSourceItem> clone() const;
51
51
52 /// @return the actions of the item as a vector
52 /// @return the actions of the item as a vector
53 QVector<DataSourceItemAction*> actions() const noexcept;
53 QVector<DataSourceItemAction*> actions() const noexcept;
54
54
55 /**
55 /**
56 * Adds an action to the item. The item takes ownership of the action, and the
56 * Adds an action to the item. The item takes ownership of the action, and the
57 * action is automatically associated to the item
57 * action is automatically associated to the item
58 * @param action the action to add
58 * @param action the action to add
59 */
59 */
60 void addAction(std::unique_ptr<DataSourceItemAction> action) noexcept;
60 void addAction(std::unique_ptr<DataSourceItemAction> action) noexcept;
61
61
62 /**
62 /**
63 * Adds a child to the item. The item takes ownership of the child.
63 * Adds a child to the item. The item takes ownership of the child.
64 * @param child the child to add
64 * @param child the child to add
65 */
65 */
66 void appendChild(std::unique_ptr<DataSourceItem> child) noexcept;
66 void appendChild(std::unique_ptr<DataSourceItem> child) noexcept;
67
67
68 /**
68 /**
69 * Returns the item's child associated to an index
69 * Returns the item's child associated to an index
70 * @param childIndex the index to search
70 * @param childIndex the index to search
71 * @return a pointer to the child if index is valid, nullptr otherwise
71 * @return a pointer to the child if index is valid, nullptr otherwise
72 */
72 */
73 DataSourceItem* child(int childIndex) const noexcept;
73 DataSourceItem* child(int childIndex) const noexcept;
74
74
75 int childCount() const noexcept;
75 int childCount() const noexcept;
76
76
77 /**
77 /**
78 * Get the data associated to a key
78 * Get the data associated to a key
79 * @param key the key to search
79 * @param key the key to search
80 * @return the data found if key is valid, default QVariant otherwise
80 * @return the data found if key is valid, default QVariant otherwise
81 */
81 */
82 QVariant data(const QString& key) const noexcept;
82 QVariant data(const QString& key) const noexcept;
83
83
84 /// Gets all data
84 /// Gets all data
85 QVariantHash data() const noexcept;
85 QVariantHash data() const noexcept;
86
86
87 /**
87 /**
88 * Merge in the item the source item passed as parameter.
88 * Merge in the item the source item passed as parameter.
89 *
89 *
90 * The merge is done by adding as child of the item the complete tree
90 * The merge is done by adding as child of the item the complete tree
91 * represented by the source item. If a part of the tree already exists in the
91 * represented by the source item. If a part of the tree already exists in the
92 * item (based on the name of the nodes), it is merged by completing the
92 * item (based on the name of the nodes), it is merged by completing the
93 * existing tree by items "leaves" (products, components or nodes with no
93 * existing tree by items "leaves" (products, components or nodes with no
94 * child).
94 * child).
95 *
95 *
96 * For example, with item representing the tree:
96 * For example, with item representing the tree:
97 * R (root node)
97 * R (root node)
98 * - N1 (node)
98 * - N1 (node)
99 * -- N11 (node)
99 * -- N11 (node)
100 * --- P1 (product)
100 * --- P1 (product)
101 * --- P2 (product)
101 * --- P2 (product)
102 * - N2 (node)
102 * - N2 (node)
103 *
103 *
104 * and the source item representing the tree:
104 * and the source item representing the tree:
105 * N1 (root node)
105 * N1 (root node)
106 * - N11 (node)
106 * - N11 (node)
107 * -- P3 (product)
107 * -- P3 (product)
108 * - N12 (node)
108 * - N12 (node)
109 *
109 *
110 * The leaves of the source item to merge into the item are N1/N11/P3 and
110 * The leaves of the source item to merge into the item are N1/N11/P3 and
111 * N1/N12 => we therefore have the following merge result:
111 * N1/N12 => we therefore have the following merge result:
112 * R
112 * R
113 * - N1
113 * - N1
114 * -- N11
114 * -- N11
115 * --- P1
115 * --- P1
116 * --- P2
116 * --- P2
117 * --- P3 (added leaf)
117 * --- P3 (added leaf)
118 * -- N12 (added leaf)
118 * -- N12 (added leaf)
119 *
119 *
120 * @param item the source item
120 * @param item the source item
121 * @remarks No control is performed on products or components that are merged
121 * @remarks No control is performed on products or components that are merged
122 * into the same tree part (two products or components may have the same name)
122 * into the same tree part (two products or components may have the same name)
123 * @remarks the merge is made by copy (source item is not changed and still
123 * @remarks the merge is made by copy (source item is not changed and still
124 * exists after the operation)
124 * exists after the operation)
125 */
125 */
126 void merge(const DataSourceItem& item);
126 void merge(const DataSourceItem& item);
127
127
128 bool isRoot() const noexcept;
128 bool isRoot() const noexcept;
129
129
130 QString name() const noexcept;
130 QString name() const noexcept;
131
131
132 /**
132 /**
133 * Get the item's parent
133 * Get the item's parent
134 * @return a pointer to the parent if it exists, nullptr if the item is a root
134 * @return a pointer to the parent if it exists, nullptr if the item is a root
135 */
135 */
136 DataSourceItem* parentItem() const noexcept;
136 DataSourceItem* parentItem() const noexcept;
137
137
138 /**
138 /**
139 * Gets the item's root
139 * Gets the item's root
140 * @return the top parent, the item itself if it's the root item
140 * @return the top parent, the item itself if it's the root item
141 */
141 */
142 const DataSourceItem& rootItem() const noexcept;
142 const DataSourceItem& rootItem() const noexcept;
143
143
144 /**
144 /**
145 * Sets or appends a value to a key
145 * Sets or appends a value to a key
146 * @param key the key
146 * @param key the key
147 * @param value the value
147 * @param value the value
148 * @param append if true, the value is added to the values already existing
148 * @param append if true, the value is added to the values already existing
149 * for the key, otherwise it replaces the existing values
149 * for the key, otherwise it replaces the existing values
150 */
150 */
151 void setData(const QString& key, const QVariant& value,
151 void setData(const QString& key, const QVariant& value,
152 bool append = false) noexcept;
152 bool append = false) noexcept;
153
153
154 DataSourceItemType type() const noexcept;
154 DataSourceItemType type() const noexcept;
155
155
156 /**
156 /**
157 * @brief Searches the first child matching the specified data.
157 * @brief Searches the first child matching the specified data.
158 * @param data The data to search.
158 * @param data The data to search.
159 * @param recursive So the search recursively.
159 * @param recursive So the search recursively.
160 * @return the item matching the data or nullptr if it was not found.
160 * @return the item matching the data or nullptr if it was not found.
161 */
161 */
162 DataSourceItem* findItem(const QVariantHash& data, bool recursive);
162 DataSourceItem* findItem(const QVariantHash& data, bool recursive);
163
163
164 DataSourceItem* findItem(const QString& name);
164 DataSourceItem* findItem(const QString& name);
165
165
166 /**
166 /**
167 * @brief Searches the first child matching the specified \p ID_DATA_KEY in
167 * @brief Searches the first child matching the specified \p ID_DATA_KEY in
168 * its metadata.
168 * its metadata.
169 * @param id The id to search.
169 * @param id The id to search.
170 * @param recursive So the search recursively.
170 * @param recursive So the search recursively.
171 * @return the item matching the data or nullptr if it was not found.
171 * @return the item matching the data or nullptr if it was not found.
172 */
172 */
173 DataSourceItem* findItem(const QString& datasourceIdKey, bool recursive);
173 DataSourceItem* findItem(const QString& datasourceIdKey, bool recursive);
174
174
175 bool operator==(const DataSourceItem& other);
175 bool operator==(const DataSourceItem& other);
176 bool operator!=(const DataSourceItem& other);
176 bool operator!=(const DataSourceItem& other);
177
177
178 iterator_type begin() noexcept;
178 iterator_type begin() noexcept;
179 iterator_type end() noexcept;
179 iterator_type end() noexcept;
180 const_iterator_type begin()const noexcept;
180 const_iterator_type begin()const noexcept;
181 const_iterator_type end()const noexcept;
181 const_iterator_type end()const noexcept;
182 const_iterator_type cbegin()const noexcept;
182 const_iterator_type cbegin()const noexcept;
183 const_iterator_type cend()const noexcept;
183 const_iterator_type cend()const noexcept;
184 private:
184 private:
185 class DataSourceItemPrivate;
185 class DataSourceItemPrivate;
186 spimpl::unique_impl_ptr<DataSourceItemPrivate> impl;
186 spimpl::unique_impl_ptr<DataSourceItemPrivate> impl;
187 };
187 };
188
188
189 #endif // SCIQLOP_DATASOURCEITEMMODEL_H
189 #endif // SCIQLOP_DATASOURCEITEMMODEL_H
@@ -1,98 +1,98
1 #ifndef SCIQLOP_VARIABLE2_H
1 #ifndef SCIQLOP_VARIABLE2_H
2 #define SCIQLOP_VARIABLE2_H
2 #define SCIQLOP_VARIABLE2_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Common/MetaTypes.h>
6 #include <Common/MetaTypes.h>
7 #include <Common/deprecate.h>
7 #include <deprecate.h>
8 #include <Common/spimpl.h>
8 #include <Common/spimpl.h>
9 #include <Data/DataSeriesType.h>
9 #include <Data/DataSeriesType.h>
10 #include <Data/DateTimeRange.h>
10 #include <Data/DateTimeRange.h>
11 #include <Data/MultiComponentTimeSerie.h>
11 #include <Data/MultiComponentTimeSerie.h>
12 #include <Data/ScalarTimeSerie.h>
12 #include <Data/ScalarTimeSerie.h>
13 #include <Data/SpectrogramTimeSerie.h>
13 #include <Data/SpectrogramTimeSerie.h>
14 #include <Data/VectorTimeSerie.h>
14 #include <Data/VectorTimeSerie.h>
15 #include <QDataStream>
15 #include <QDataStream>
16 #include <QObject>
16 #include <QObject>
17 #include <QReadWriteLock>
17 #include <QReadWriteLock>
18 #include <QUuid>
18 #include <QUuid>
19 #include <TimeSeries.h>
19 #include <TimeSeries.h>
20 #include <optional>
20 #include <optional>
21
21
22 class SCIQLOP_CORE_EXPORT Variable2 : public QObject
22 class SCIQLOP_CORE_EXPORT Variable2 : public QObject
23 {
23 {
24 Q_OBJECT
24 Q_OBJECT
25
25
26 public:
26 public:
27 explicit Variable2(const QString& name, const QVariantHash& metadata = {});
27 explicit Variable2(const QString& name, const QVariantHash& metadata = {});
28
28
29 /// Copy ctor
29 /// Copy ctor
30 explicit Variable2(const Variable2& other);
30 explicit Variable2(const Variable2& other);
31
31
32 std::shared_ptr<Variable2> clone() const;
32 std::shared_ptr<Variable2> clone() const;
33
33
34 QString name();
34 QString name();
35 void setName(const QString& name);
35 void setName(const QString& name);
36 DateTimeRange range();
36 DateTimeRange range();
37 void setRange(const DateTimeRange& range);
37 void setRange(const DateTimeRange& range);
38 std::optional<DateTimeRange> realRange();
38 std::optional<DateTimeRange> realRange();
39
39
40 std::size_t nbPoints();
40 std::size_t nbPoints();
41
41
42 /// @return the data of the variable, nullptr if there is no data
42 /// @return the data of the variable, nullptr if there is no data
43 std::shared_ptr<TimeSeries::ITimeSerie> data();
43 std::shared_ptr<TimeSeries::ITimeSerie> data();
44
44
45 /// @return the type of data that the variable holds
45 /// @return the type of data that the variable holds
46 DataSeriesType type();
46 DataSeriesType type();
47
47
48 QVariantHash metadata() const noexcept;
48 QVariantHash metadata() const noexcept;
49
49
50 // void setData(const std::vector<AnyTimeSerie*>& dataSeries,
50 // void setData(const std::vector<AnyTimeSerie*>& dataSeries,
51 // const DateTimeRange& range, bool notify = true);
51 // const DateTimeRange& range, bool notify = true);
52
52
53 void setData(const std::vector<TimeSeries::ITimeSerie*>& dataSeries,
53 void setData(const std::vector<TimeSeries::ITimeSerie*>& dataSeries,
54 const DateTimeRange& range, bool notify = true);
54 const DateTimeRange& range, bool notify = true);
55
55
56 static QByteArray
56 static QByteArray
57 mimeData(const std::vector<std::shared_ptr<Variable2>>& variables)
57 mimeData(const std::vector<std::shared_ptr<Variable2>>& variables)
58 {
58 {
59 auto encodedData = QByteArray{};
59 auto encodedData = QByteArray{};
60 QDataStream stream{&encodedData, QIODevice::WriteOnly};
60 QDataStream stream{&encodedData, QIODevice::WriteOnly};
61 for(auto& var : variables)
61 for(auto& var : variables)
62 {
62 {
63 stream << var->ID().toByteArray();
63 stream << var->ID().toByteArray();
64 }
64 }
65 return encodedData;
65 return encodedData;
66 }
66 }
67
67
68 static std::vector<QUuid> IDs(QByteArray mimeData)
68 static std::vector<QUuid> IDs(QByteArray mimeData)
69 {
69 {
70 std::vector<QUuid> variables;
70 std::vector<QUuid> variables;
71 QDataStream stream{mimeData};
71 QDataStream stream{mimeData};
72
72
73 QVariantList ids;
73 QVariantList ids;
74 stream >> ids;
74 stream >> ids;
75 std::transform(std::cbegin(ids), std::cend(ids),
75 std::transform(std::cbegin(ids), std::cend(ids),
76 std::back_inserter(variables),
76 std::back_inserter(variables),
77 [](const auto& id) { return id.toByteArray(); });
77 [](const auto& id) { return id.toByteArray(); });
78 return variables;
78 return variables;
79 }
79 }
80
80
81 operator QUuid() { return _uuid; }
81 operator QUuid() { return _uuid; }
82 QUuid ID() { return _uuid; }
82 QUuid ID() { return _uuid; }
83 signals:
83 signals:
84 void updated(QUuid ID);
84 void updated(QUuid ID);
85
85
86 private:
86 private:
87 struct VariablePrivate;
87 struct VariablePrivate;
88 spimpl::unique_impl_ptr<VariablePrivate> impl;
88 spimpl::unique_impl_ptr<VariablePrivate> impl;
89 QUuid _uuid;
89 QUuid _uuid;
90 QReadWriteLock m_lock;
90 QReadWriteLock m_lock;
91 };
91 };
92
92
93 // Required for using shared_ptr in signals/slots
93 // Required for using shared_ptr in signals/slots
94 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_REGISTRY, std::shared_ptr<Variable2>)
94 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_REGISTRY, std::shared_ptr<Variable2>)
95 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_VECTOR_REGISTRY,
95 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_VECTOR_REGISTRY,
96 QVector<std::shared_ptr<Variable2>>)
96 QVector<std::shared_ptr<Variable2>>)
97
97
98 #endif // SCIQLOP_VARIABLE2_H
98 #endif // SCIQLOP_VARIABLE2_H
@@ -1,80 +1,80
1 #ifndef SCIQLOP_VARIABLESYNCHRONIZATIONGROUP2_H
1 #ifndef SCIQLOP_VARIABLESYNCHRONIZATIONGROUP2_H
2 #define SCIQLOP_VARIABLESYNCHRONIZATIONGROUP2_H
2 #define SCIQLOP_VARIABLESYNCHRONIZATIONGROUP2_H
3
3
4 #include <QUuid>
4 #include <QUuid>
5 #include <set>
5 #include <set>
6
6
7 #include "CoreGlobal.h"
7 #include "CoreGlobal.h"
8 #include <Common/spimpl.h>
8 #include <Common/spimpl.h>
9 #include <Common/containers.h>
9 #include <containers/algorithms.hpp>
10
10
11 /**
11 /**
12 * @brief The VariableSynchronizationGroup2 class holds a list of Variables uuid which are synchronized
12 * @brief The VariableSynchronizationGroup2 class holds a list of Variables uuid which are synchronized
13 * @note This class is part of SciQLop internals, as a normal user you shouldn't have to care about it
13 * @note This class is part of SciQLop internals, as a normal user you shouldn't have to care about it
14 */
14 */
15 class SCIQLOP_CORE_EXPORT VariableSynchronizationGroup2
15 class SCIQLOP_CORE_EXPORT VariableSynchronizationGroup2
16 {
16 {
17
17
18 public:
18 public:
19 explicit VariableSynchronizationGroup2()=default;
19 explicit VariableSynchronizationGroup2()=default;
20 /**
20 /**
21 * @brief VariableSynchronizationGroup2 is a convenience ctor to build a group with a default variable
21 * @brief VariableSynchronizationGroup2 is a convenience ctor to build a group with a default variable
22 * @param variable
22 * @param variable
23 */
23 */
24 explicit VariableSynchronizationGroup2(QUuid variable)
24 explicit VariableSynchronizationGroup2(QUuid variable)
25 :_variables{{variable}}
25 :_variables{{variable}}
26 {}
26 {}
27
27
28 /**
28 /**
29 * @brief addVariable adds the given variable to the group, does nothing if the varaible is alredy in the group
29 * @brief addVariable adds the given variable to the group, does nothing if the varaible is alredy in the group
30 * @param variable
30 * @param variable
31 * @sa removeVariable
31 * @sa removeVariable
32 */
32 */
33 void addVariable(QUuid variable) noexcept
33 void addVariable(QUuid variable) noexcept
34 {
34 {
35 this->_variables.insert(variable);
35 this->_variables.insert(variable);
36 }
36 }
37
37
38 /**
38 /**
39 * @brief removeVariable removes the given variable from the group, does nothing if the varaible is not in the group
39 * @brief removeVariable removes the given variable from the group, does nothing if the varaible is not in the group
40 * @param variable
40 * @param variable
41 * @sa addVariable
41 * @sa addVariable
42 */
42 */
43 void removeVariable(QUuid variable) noexcept
43 void removeVariable(QUuid variable) noexcept
44 {
44 {
45 this->_variables.erase(variable);
45 this->_variables.erase(variable);
46 }
46 }
47
47
48 /**
48 /**
49 * @brief contains checks if the given variable is in the group
49 * @brief contains checks if the given variable is in the group
50 * @param variable
50 * @param variable
51 * @return true if the variable is in the group
51 * @return true if the variable is in the group
52 */
52 */
53 bool contains(QUuid variable) const noexcept
53 bool contains(QUuid variable) const noexcept
54 {
54 {
55 return SciQLop::containers::contains(this->_variables,variable);
55 return cpp_utils::containers::contains(this->_variables,variable);
56 }
56 }
57
57
58 /**
58 /**
59 * @brief variables
59 * @brief variables
60 * @return the list of synchronized variables in this group as a std::set
60 * @return the list of synchronized variables in this group as a std::set
61 */
61 */
62 const std::set<QUuid> &variables() const noexcept
62 const std::set<QUuid> &variables() const noexcept
63 {
63 {
64 return this->_variables;
64 return this->_variables;
65 }
65 }
66
66
67 inline bool isEmpty()
67 inline bool isEmpty()
68 {
68 {
69 return _variables.size()==0;
69 return _variables.size()==0;
70 }
70 }
71
71
72 inline QUuid ID(){return _ID;}
72 inline QUuid ID(){return _ID;}
73
73
74 operator QUuid() {return _ID;}
74 operator QUuid() {return _ID;}
75 private:
75 private:
76 std::set<QUuid> _variables;
76 std::set<QUuid> _variables;
77 QUuid _ID = QUuid::createUuid();
77 QUuid _ID = QUuid::createUuid();
78 };
78 };
79
79
80 #endif // SCIQLOP_VARIABLESYNCHRONIZATIONGROUP2_H
80 #endif // SCIQLOP_VARIABLESYNCHRONIZATIONGROUP2_H
@@ -1,149 +1,149
1 #pragma once
1 #pragma once
2 #include "Variable/VariableSynchronizationGroup2.h"
2 #include "Variable/VariableSynchronizationGroup2.h"
3
3
4 #include <Common/containers.h>
4 #include <containers/algorithms.hpp>
5 #include <Common/debug.h>
5 #include <Common/debug.h>
6 #include <Data/DataProviderParameters.h>
6 #include <Data/DataProviderParameters.h>
7 #include <Data/DateTimeRange.h>
7 #include <Data/DateTimeRange.h>
8 #include <Data/DateTimeRangeHelper.h>
8 #include <Data/DateTimeRangeHelper.h>
9 #include <Data/IDataProvider.h>
9 #include <Data/IDataProvider.h>
10 #include <QObject>
10 #include <QObject>
11 #include <QReadWriteLock>
11 #include <QReadWriteLock>
12 #include <QRunnable>
12 #include <QRunnable>
13 #include <QThreadPool>
13 #include <QThreadPool>
14 #include <TimeSeries.h>
14 #include <TimeSeries.h>
15 #include <Variable/Variable2.h>
15 #include <Variable/Variable2.h>
16
16
17 struct VCTransaction
17 struct VCTransaction
18 {
18 {
19 VCTransaction(QUuid refVar, DateTimeRange range, int varCount)
19 VCTransaction(QUuid refVar, DateTimeRange range, int varCount)
20 : refVar{refVar}, range{range}, _remainingVars{varCount}
20 : refVar{refVar}, range{range}, _remainingVars{varCount}
21 {}
21 {}
22
22
23 QUuid refVar;
23 QUuid refVar;
24 DateTimeRange range;
24 DateTimeRange range;
25 bool ready()
25 bool ready()
26 {
26 {
27 QReadLocker lock{&_lock};
27 QReadLocker lock{&_lock};
28 return _remainingVars == 0;
28 return _remainingVars == 0;
29 }
29 }
30
30
31 bool done()
31 bool done()
32 {
32 {
33 QWriteLocker lock{&_lock};
33 QWriteLocker lock{&_lock};
34 _remainingVars -= 1;
34 _remainingVars -= 1;
35 return _remainingVars == 0;
35 return _remainingVars == 0;
36 }
36 }
37
37
38 private:
38 private:
39 QReadWriteLock _lock;
39 QReadWriteLock _lock;
40 int _remainingVars;
40 int _remainingVars;
41 };
41 };
42
42
43 class TransactionExe : public QObject, public QRunnable
43 class TransactionExe : public QObject, public QRunnable
44 {
44 {
45 Q_OBJECT
45 Q_OBJECT
46 std::shared_ptr<Variable2> _variable;
46 std::shared_ptr<Variable2> _variable;
47 std::shared_ptr<IDataProvider> _provider;
47 std::shared_ptr<IDataProvider> _provider;
48 std::vector<DateTimeRange> _ranges;
48 std::vector<DateTimeRange> _ranges;
49 DateTimeRange _range;
49 DateTimeRange _range;
50 bool _overwrite;
50 bool _overwrite;
51
51
52 public:
52 public:
53 TransactionExe(const std::shared_ptr<Variable2>& variable,
53 TransactionExe(const std::shared_ptr<Variable2>& variable,
54 const std::shared_ptr<IDataProvider>& provider,
54 const std::shared_ptr<IDataProvider>& provider,
55 const std::vector<DateTimeRange>& ranges, DateTimeRange range,
55 const std::vector<DateTimeRange>& ranges, DateTimeRange range,
56 bool overwrite = true)
56 bool overwrite = true)
57 : _variable{variable}, _provider{provider}, _ranges{ranges},
57 : _variable{variable}, _provider{provider}, _ranges{ranges},
58 _range{range}, _overwrite{overwrite}
58 _range{range}, _overwrite{overwrite}
59 {
59 {
60 setAutoDelete(true);
60 setAutoDelete(true);
61 }
61 }
62 void run() override
62 void run() override
63 {
63 {
64 std::vector<TimeSeries::ITimeSerie*> data;
64 std::vector<TimeSeries::ITimeSerie*> data;
65 for(auto range : _ranges)
65 for(auto range : _ranges)
66 {
66 {
67 auto ds = _provider->getData(
67 auto ds = _provider->getData(
68 DataProviderParameters{{range}, _variable->metadata()});
68 DataProviderParameters{{range}, _variable->metadata()});
69 if(ds and ds->size()) data.push_back(ds); // skip empty dataSeries
69 if(ds and ds->size()) data.push_back(ds); // skip empty dataSeries
70 }
70 }
71 if(_overwrite)
71 if(_overwrite)
72 _variable->setData(data, _range, true);
72 _variable->setData(data, _range, true);
73 else
73 else
74 {
74 {
75 data.push_back(_variable->data().get());
75 data.push_back(_variable->data().get());
76 _variable->setData(data, _range, true);
76 _variable->setData(data, _range, true);
77 }
77 }
78 std::for_each(std::begin(data), std::end(data),
78 std::for_each(std::begin(data), std::end(data),
79 [](TimeSeries::ITimeSerie* ts) { delete ts; });
79 [](TimeSeries::ITimeSerie* ts) { delete ts; });
80 emit transactionComplete();
80 emit transactionComplete();
81 }
81 }
82 signals:
82 signals:
83 void transactionComplete();
83 void transactionComplete();
84 };
84 };
85
85
86 class VCTransactionsQueues
86 class VCTransactionsQueues
87 {
87 {
88 QReadWriteLock _mutex{QReadWriteLock::Recursive};
88 QReadWriteLock _mutex{QReadWriteLock::Recursive};
89 std::map<QUuid, std::optional<std::shared_ptr<VCTransaction>>>
89 std::map<QUuid, std::optional<std::shared_ptr<VCTransaction>>>
90 _nextTransactions;
90 _nextTransactions;
91 std::map<QUuid, std::optional<std::shared_ptr<VCTransaction>>>
91 std::map<QUuid, std::optional<std::shared_ptr<VCTransaction>>>
92 _pendingTransactions;
92 _pendingTransactions;
93
93
94 public:
94 public:
95 void addEntry(QUuid id)
95 void addEntry(QUuid id)
96 {
96 {
97 QWriteLocker lock{&_mutex};
97 QWriteLocker lock{&_mutex};
98 _nextTransactions[id] = std::nullopt;
98 _nextTransactions[id] = std::nullopt;
99 _pendingTransactions[id] = std::nullopt;
99 _pendingTransactions[id] = std::nullopt;
100 }
100 }
101
101
102 void removeEntry(QUuid id)
102 void removeEntry(QUuid id)
103 {
103 {
104 QWriteLocker lock{&_mutex};
104 QWriteLocker lock{&_mutex};
105 _nextTransactions.erase(id);
105 _nextTransactions.erase(id);
106 _pendingTransactions.erase(id);
106 _pendingTransactions.erase(id);
107 }
107 }
108
108
109 std::map<QUuid, std::optional<std::shared_ptr<VCTransaction>>>
109 std::map<QUuid, std::optional<std::shared_ptr<VCTransaction>>>
110 pendingTransactions()
110 pendingTransactions()
111 {
111 {
112 QReadLocker lock{&_mutex};
112 QReadLocker lock{&_mutex};
113 return _pendingTransactions;
113 return _pendingTransactions;
114 }
114 }
115
115
116 std::map<QUuid, std::optional<std::shared_ptr<VCTransaction>>>
116 std::map<QUuid, std::optional<std::shared_ptr<VCTransaction>>>
117 nextTransactions()
117 nextTransactions()
118 {
118 {
119 QReadLocker lock{&_mutex};
119 QReadLocker lock{&_mutex};
120 return _nextTransactions;
120 return _nextTransactions;
121 }
121 }
122
122
123 std::optional<std::shared_ptr<VCTransaction>> start(QUuid id)
123 std::optional<std::shared_ptr<VCTransaction>> start(QUuid id)
124 {
124 {
125 QWriteLocker lock{&_mutex};
125 QWriteLocker lock{&_mutex};
126 _pendingTransactions[id] = _nextTransactions[id];
126 _pendingTransactions[id] = _nextTransactions[id];
127 _nextTransactions[id] = std::nullopt;
127 _nextTransactions[id] = std::nullopt;
128 return _pendingTransactions[id];
128 return _pendingTransactions[id];
129 }
129 }
130
130
131 void enqueue(QUuid id, std::shared_ptr<VCTransaction> transaction)
131 void enqueue(QUuid id, std::shared_ptr<VCTransaction> transaction)
132 {
132 {
133 QWriteLocker lock{&_mutex};
133 QWriteLocker lock{&_mutex};
134 _nextTransactions[id] = transaction;
134 _nextTransactions[id] = transaction;
135 }
135 }
136
136
137 void complete(QUuid id)
137 void complete(QUuid id)
138 {
138 {
139 QWriteLocker lock{&_mutex};
139 QWriteLocker lock{&_mutex};
140 _pendingTransactions[id] = std::nullopt;
140 _pendingTransactions[id] = std::nullopt;
141 }
141 }
142
142
143 bool active(QUuid id)
143 bool active(QUuid id)
144 {
144 {
145 QReadLocker lock{&_mutex};
145 QReadLocker lock{&_mutex};
146 return _nextTransactions[id].has_value() ||
146 return _nextTransactions[id].has_value() ||
147 _pendingTransactions[id].has_value();
147 _pendingTransactions[id].has_value();
148 }
148 }
149 };
149 };
@@ -1,111 +1,106
1
1
2 catalogicpp_dep = dependency('catalogicpp', required : true, fallback:['catalogicpp','catalogicpp_dep'])
2 catalogicpp_dep = dependency('catalogicpp', required : true, fallback:['catalogicpp','catalogicpp_dep'])
3 pybind11_dep = dependency('pybind11', required : true, fallback:['pybind11','pybind11_dep'])
3 pybind11_dep = dependency('pybind11', required : true, fallback:['pybind11','pybind11_dep'])
4 timeseries_dep = dependency('TimeSeries', required : true, fallback:['TimeSeries','time_series_dep'])
4 timeseries_dep = dependency('TimeSeries', required : true, fallback:['TimeSeries','time_series_dep'])
5 cpp_utils_dep = dependency('cpp_utils', fallback:['cpp_utils','cpp_utils_dep'])
5
6
6 core_moc_headers = [
7 core_moc_headers = [
7 './include/Common/containers.h',
8 './include/Common/StringUtils.h',
9 './include/Common/Numeric.h',
10 './include/Common/spimpl.h',
8 './include/Common/spimpl.h',
11 './include/Common/DateUtils.h',
9 './include/Common/DateUtils.h',
12 './include/Common/MimeTypesDef.h',
10 './include/Common/MimeTypesDef.h',
13 './include/Common/SignalWaiter.h',
11 './include/Common/SignalWaiter.h',
14 './include/Common/deprecate.h',
15 './include/Common/debug.h',
12 './include/Common/debug.h',
16 './include/Common/MetaTypes.h',
13 './include/Common/MetaTypes.h',
17 './include/Common/cpp_utils.h',
18 './include/Common/SortUtils.h',
14 './include/Common/SortUtils.h',
19 './include/Data/DateTimeRangeHelper.h',
15 './include/Data/DateTimeRangeHelper.h',
20 './include/Data/ScalarTimeSerie.h',
16 './include/Data/ScalarTimeSerie.h',
21 './include/Data/DateTimeRange.h',
17 './include/Data/DateTimeRange.h',
22 './include/Data/DataProviderParameters.h',
18 './include/Data/DataProviderParameters.h',
23 './include/Data/TimeSeriesUtils.h',
19 './include/Data/TimeSeriesUtils.h',
24 './include/Data/VectorTimeSerie.h',
20 './include/Data/VectorTimeSerie.h',
25 './include/Data/SqpIterator.h',
21 './include/Data/SqpIterator.h',
26 './include/Data/IDataProvider.h',
22 './include/Data/IDataProvider.h',
27 './include/Data/SpectrogramTimeSerie.h',
23 './include/Data/SpectrogramTimeSerie.h',
28 './include/Data/MultiComponentTimeSerie.h',
24 './include/Data/MultiComponentTimeSerie.h',
29 './include/Data/DataSeriesType.h',
25 './include/Data/DataSeriesType.h',
30 './include/CoreGlobal.h',
26 './include/CoreGlobal.h',
31 './include/Network/NetworkController.h',
27 './include/Network/NetworkController.h',
32 './include/Network/Response.h',
28 './include/Network/Response.h',
33 './include/Network/Downloader.h',
29 './include/Network/Downloader.h',
34 './include/Settings/SqpSettingsDefs.h',
30 './include/Settings/SqpSettingsDefs.h',
35 './include/Settings/ISqpSettingsBindable.h',
31 './include/Settings/ISqpSettingsBindable.h',
36 './include/DataSource/DataSourceController.h',
32 './include/DataSource/DataSourceController.h',
37 './include/DataSource/DataSourceItem.h',
33 './include/DataSource/DataSourceItem.h',
38 './include/DataSource/DataSourceItemAction.h',
34 './include/DataSource/DataSourceItemAction.h',
39 './include/DataSource/DataSourceItemMergeHelper.h',
35 './include/DataSource/DataSourceItemMergeHelper.h',
40 './include/Time/TimeController.h',
36 './include/Time/TimeController.h',
41 './include/PluginManager/PluginManager.h',
37 './include/PluginManager/PluginManager.h',
42 './include/Version.h',
38 './include/Version.h',
43 './include/Catalogue/CatalogueController.h',
39 './include/Catalogue/CatalogueController.h',
44 './include/Plugin/IPlugin.h',
40 './include/Plugin/IPlugin.h',
45 './include/Variable/VariableModel2.h',
41 './include/Variable/VariableModel2.h',
46 './include/Variable/VariableController2.h',
42 './include/Variable/VariableController2.h',
47 './include/Variable/Variable2.h',
43 './include/Variable/Variable2.h',
48 './include/Variable/VariableSynchronizationGroup2.h',
44 './include/Variable/VariableSynchronizationGroup2.h',
49 './include/Variable/private/VCTransaction.h']
45 './include/Variable/private/VCTransaction.h']
50
46
51
47
52
48
53 core_moc_sources = ['src/Network/Downloader.cpp']
49 core_moc_sources = ['src/Network/Downloader.cpp']
54
50
55
51
56 core_moc_files = qt5.preprocess(moc_headers : core_moc_headers, moc_sources: core_moc_sources)
52 core_moc_files = qt5.preprocess(moc_headers : core_moc_headers, moc_sources: core_moc_sources)
57
53
58 core_sources = ['./src/Common/MimeTypesDef.cpp',
54 core_sources = ['./src/Common/MimeTypesDef.cpp',
59 './src/Common/SignalWaiter.cpp',
55 './src/Common/SignalWaiter.cpp',
60 './src/Common/DateUtils.cpp',
56 './src/Common/DateUtils.cpp',
61 './src/Common/StringUtils.cpp',
62 './src/Network/Downloader.cpp',
57 './src/Network/Downloader.cpp',
63 './src/Network/NetworkController.cpp',
58 './src/Network/NetworkController.cpp',
64 './src/Settings/SqpSettingsDefs.cpp',
59 './src/Settings/SqpSettingsDefs.cpp',
65 './src/DataSource/DataSourceItemAction.cpp',
60 './src/DataSource/DataSourceItemAction.cpp',
66 './src/DataSource/DataSourceItemMergeHelper.cpp',
61 './src/DataSource/DataSourceItemMergeHelper.cpp',
67 './src/DataSource/DataSourceItem.cpp',
62 './src/DataSource/DataSourceItem.cpp',
68 './src/DataSource/DataSourceController.cpp',
63 './src/DataSource/DataSourceController.cpp',
69 './src/Time/TimeController.cpp',
64 './src/Time/TimeController.cpp',
70 './src/PluginManager/PluginManager.cpp',
65 './src/PluginManager/PluginManager.cpp',
71 './src/Version.cpp',
66 './src/Version.cpp',
72 './src/Catalogue/CatalogueController.cpp',
67 './src/Catalogue/CatalogueController.cpp',
73 './src/Variable/VariableSynchronizationGroup2.cpp',
68 './src/Variable/VariableSynchronizationGroup2.cpp',
74 './src/Variable/Variable2.cpp',
69 './src/Variable/Variable2.cpp',
75 './src/Variable/VariableController2.cpp',
70 './src/Variable/VariableController2.cpp',
76 './src/Variable/VariableModel2.cpp']
71 './src/Variable/VariableModel2.cpp']
77
72
78
73
79 core_inc = include_directories(['include', 'include/Plugin'])
74 core_inc = include_directories(['include', 'include/Plugin'])
80
75
81 sciqlop_core_lib = library('sciqlopcore',
76 sciqlop_core_lib = library('sciqlopcore',
82 core_sources,
77 core_sources,
83 core_moc_files,
78 core_moc_files,
84 cpp_args : '-DCORE_LIB',
79 cpp_args : '-DCORE_LIB',
85 include_directories : core_inc,
80 include_directories : core_inc,
86 dependencies : [qt5core, qt5network, catalogicpp_dep, pybind11_dep, timeseries_dep],
81 dependencies : [qt5core, qt5network, catalogicpp_dep, pybind11_dep, timeseries_dep, cpp_utils_dep],
87 install : true
82 install : true
88 )
83 )
89
84
90
85
91 sciqlop_core = declare_dependency(link_with : sciqlop_core_lib,
86 sciqlop_core = declare_dependency(link_with : sciqlop_core_lib,
92 include_directories : core_inc,
87 include_directories : core_inc,
93 dependencies : [qt5core, qt5network, catalogicpp_dep, pybind11_dep, timeseries_dep])
88 dependencies : [qt5core, qt5network, catalogicpp_dep, pybind11_dep, timeseries_dep, cpp_utils_dep])
94
89
95 pymod = import('python')
90 pymod = import('python')
96 python3 = pymod.find_installation('python3')
91 python3 = pymod.find_installation('python3')
97
92
98 pysciqlopcore_srcs = [
93 pysciqlopcore_srcs = [
99 './src/pybind11_wrappers/CatalogWrappers.cpp',
94 './src/pybind11_wrappers/CatalogWrappers.cpp',
100 './src/pybind11_wrappers/QtWrappers.cpp',
95 './src/pybind11_wrappers/QtWrappers.cpp',
101 './src/pybind11_wrappers/CoreWrappers.cpp'
96 './src/pybind11_wrappers/CoreWrappers.cpp'
102 ]
97 ]
103
98
104 python3.extension_module('pysciqlopcore', './src/pybind11_wrappers/CoreWrappers.cpp',
99 python3.extension_module('pysciqlopcore', './src/pybind11_wrappers/CoreWrappers.cpp',
105 dependencies: [sciqlop_core],
100 dependencies: [sciqlop_core],
106 install: true
101 install: true
107 )
102 )
108
103
109
104
110 subdir('tests')
105 subdir('tests')
111
106
@@ -1,800 +1,800
1 #include <Catalogue/CatalogueController.h>
1 #include <Catalogue/CatalogueController.h>
2 #include <CatalogueIO.hpp>
2 #include <CatalogueIO.hpp>
3 #include <Common/containers.h>
3 #include <containers/algorithms.hpp>
4 #include <Common/debug.h>
4 #include <Common/debug.h>
5 #include <QDataStream>
5 #include <QDataStream>
6 #include <QDir>
6 #include <QDir>
7 #include <QMutex>
7 #include <QMutex>
8 #include <QStandardPaths>
8 #include <QStandardPaths>
9 #include <QThread>
9 #include <QThread>
10
10
11 using namespace SciQLop::containers;
11 using namespace cpp_utils::containers;
12
12
13 // class CatalogueController::CatalogueControllerPrivate
13 // class CatalogueController::CatalogueControllerPrivate
14 //{
14 //{
15
15
16 // public:
16 // public:
17 // explicit CatalogueControllerPrivate(CatalogueController* parent) : m_Q {
17 // explicit CatalogueControllerPrivate(CatalogueController* parent) : m_Q {
18 // parent } {}
18 // parent } {}
19
19
20 // CatalogueDao m_CatalogueDao;
20 // CatalogueDao m_CatalogueDao;
21
21
22 // QStringList m_RepositoryList;
22 // QStringList m_RepositoryList;
23 // CatalogueController* m_Q;
23 // CatalogueController* m_Q;
24
24
25 // QSet<QString> m_KeysWithChanges;
25 // QSet<QString> m_KeysWithChanges;
26
26
27 // QString eventUniqueKey(const std::shared_ptr<DBEvent>& event) const;
27 // QString eventUniqueKey(const std::shared_ptr<DBEvent>& event) const;
28 // QString catalogueUniqueKey(const std::shared_ptr<DBCatalogue>& catalogue)
28 // QString catalogueUniqueKey(const std::shared_ptr<DBCatalogue>& catalogue)
29 // const;
29 // const;
30
30
31 // void copyDBtoDB(const QString& dbFrom, const QString& dbTo);
31 // void copyDBtoDB(const QString& dbFrom, const QString& dbTo);
32 // QString toWorkRepository(QString repository);
32 // QString toWorkRepository(QString repository);
33 // QString toSyncRepository(QString repository);
33 // QString toSyncRepository(QString repository);
34 // void savAllDB();
34 // void savAllDB();
35
35
36 // void saveEvent(std::shared_ptr<DBEvent> event, bool persist = true);
36 // void saveEvent(std::shared_ptr<DBEvent> event, bool persist = true);
37 // void saveCatalogue(std::shared_ptr<DBCatalogue> catalogue, bool persist =
37 // void saveCatalogue(std::shared_ptr<DBCatalogue> catalogue, bool persist =
38 // true);
38 // true);
39
39
40 // std::shared_ptr<IRequestPredicate> createFinder(
40 // std::shared_ptr<IRequestPredicate> createFinder(
41 // const QUuid& uniqId, const QString& repository, DBType type);
41 // const QUuid& uniqId, const QString& repository, DBType type);
42 //};
42 //};
43
43
44 CatalogueController::CatalogueController(QObject* parent)
44 CatalogueController::CatalogueController(QObject* parent)
45 //: impl { spimpl::make_unique_impl<CatalogueControllerPrivate>(this) }
45 //: impl { spimpl::make_unique_impl<CatalogueControllerPrivate>(this) }
46 {}
46 {}
47
47
48 CatalogueController::~CatalogueController() {}
48 CatalogueController::~CatalogueController() {}
49
49
50 QStringList CatalogueController::repositories() const
50 QStringList CatalogueController::repositories() const
51 {
51 {
52 QStringList repos;
52 QStringList repos;
53 std::transform(std::begin(_currentRepos), std::end(_currentRepos),
53 std::transform(std::begin(_currentRepos), std::end(_currentRepos),
54 std::back_inserter(repos),
54 std::back_inserter(repos),
55 [](auto& pair) { return pair.first; });
55 [](auto& pair) { return pair.first; });
56 return repos;
56 return repos;
57 }
57 }
58
58
59 void CatalogueController::loadRepository(const QString& path,
59 void CatalogueController::loadRepository(const QString& path,
60 const QString& name)
60 const QString& name)
61 {
61 {
62 if(QFile::exists(path))
62 if(QFile::exists(path))
63 {
63 {
64 auto repo = CatalogiCpp::load_repository<time_t>(path.toStdString());
64 auto repo = CatalogiCpp::load_repository<time_t>(path.toStdString());
65 _lastSavedRepos[name] = repo;
65 _lastSavedRepos[name] = repo;
66 _currentRepos[name] = repo;
66 _currentRepos[name] = repo;
67 }
67 }
68 }
68 }
69
69
70 void CatalogueController::saveRepository(const QString& path,
70 void CatalogueController::saveRepository(const QString& path,
71 const QString& name)
71 const QString& name)
72 {
72 {
73 if(contains(_currentRepos, name))
73 if(contains(_currentRepos, name))
74 {
74 {
75 CatalogiCpp::save_repository(_currentRepos[name], path.toStdString());
75 CatalogiCpp::save_repository(_currentRepos[name], path.toStdString());
76 _lastSavedRepos[name] = _currentRepos[name];
76 _lastSavedRepos[name] = _currentRepos[name];
77 }
77 }
78 }
78 }
79
79
80 std::vector<CatalogueController::Event_ptr> CatalogueController::events()
80 std::vector<CatalogueController::Event_ptr> CatalogueController::events()
81 {
81 {
82 std::vector<CatalogueController::Event_ptr> e_list;
82 std::vector<CatalogueController::Event_ptr> e_list;
83 for(auto& [_, repo] : _currentRepos)
83 for(auto& [_, repo] : _currentRepos)
84 {
84 {
85 for(auto& [_, event] : repo.events())
85 for(auto& [_, event] : repo.events())
86 e_list.push_back(event);
86 e_list.push_back(event);
87 }
87 }
88 return e_list;
88 return e_list;
89 }
89 }
90
90
91 std::vector<CatalogueController::Event_ptr>
91 std::vector<CatalogueController::Event_ptr>
92 CatalogueController::events(const CatalogueController::Catalogue_ptr& catalogue)
92 CatalogueController::events(const CatalogueController::Catalogue_ptr& catalogue)
93 {
93 {
94 std::vector<CatalogueController::Event_ptr> e_list;
94 std::vector<CatalogueController::Event_ptr> e_list;
95 for(auto& [_, event] : catalogue->events())
95 for(auto& [_, event] : catalogue->events())
96 e_list.push_back(event);
96 e_list.push_back(event);
97 return e_list;
97 return e_list;
98 }
98 }
99
99
100 std::vector<std::shared_ptr<CatalogueController::Event_t>>
100 std::vector<std::shared_ptr<CatalogueController::Event_t>>
101 CatalogueController::events(const QString& repository)
101 CatalogueController::events(const QString& repository)
102 {
102 {
103 std::vector<std::shared_ptr<CatalogueController::Event_t>> e_list;
103 std::vector<std::shared_ptr<CatalogueController::Event_t>> e_list;
104 if(contains(_currentRepos, repository))
104 if(contains(_currentRepos, repository))
105 {
105 {
106 auto repo = _currentRepos[repository];
106 auto repo = _currentRepos[repository];
107 for(auto& [_, event] : repo.events())
107 for(auto& [_, event] : repo.events())
108 e_list.push_back(event);
108 e_list.push_back(event);
109 }
109 }
110 return e_list;
110 return e_list;
111 }
111 }
112
112
113 std::vector<CatalogueController::Catalogue_ptr>
113 std::vector<CatalogueController::Catalogue_ptr>
114 CatalogueController::catalogues()
114 CatalogueController::catalogues()
115 {
115 {
116 std::vector<CatalogueController::Catalogue_ptr> c_list;
116 std::vector<CatalogueController::Catalogue_ptr> c_list;
117 for(auto& [_, repo] : _currentRepos)
117 for(auto& [_, repo] : _currentRepos)
118 {
118 {
119 for(auto& [_, catalogue] : repo.catalogues())
119 for(auto& [_, catalogue] : repo.catalogues())
120 c_list.push_back(catalogue);
120 c_list.push_back(catalogue);
121 }
121 }
122 return c_list;
122 return c_list;
123 }
123 }
124
124
125 std::vector<CatalogueController::Catalogue_ptr>
125 std::vector<CatalogueController::Catalogue_ptr>
126 CatalogueController::catalogues(const QString& repository)
126 CatalogueController::catalogues(const QString& repository)
127 {
127 {
128 std::vector<CatalogueController::Catalogue_ptr> c_list;
128 std::vector<CatalogueController::Catalogue_ptr> c_list;
129 if(contains(_currentRepos, repository))
129 if(contains(_currentRepos, repository))
130 {
130 {
131 auto repo = _currentRepos[repository];
131 auto repo = _currentRepos[repository];
132 for(auto& [_, catalogue] : repo.catalogues())
132 for(auto& [_, catalogue] : repo.catalogues())
133 c_list.push_back(catalogue);
133 c_list.push_back(catalogue);
134 }
134 }
135 return c_list;
135 return c_list;
136 }
136 }
137
137
138 bool CatalogueController::hasUnsavedChanges(
138 bool CatalogueController::hasUnsavedChanges(
139 CatalogueController::Event_ptr event)
139 CatalogueController::Event_ptr event)
140 {
140 {
141 if(auto repo = repository(event))
141 if(auto repo = repository(event))
142 {
142 {
143 if(contains(_lastSavedRepos, *repo))
143 if(contains(_lastSavedRepos, *repo))
144 { return *event != *(_lastSavedRepos[*repo].event(event->uuid)); }
144 { return *event != *(_lastSavedRepos[*repo].event(event->uuid)); }
145 }
145 }
146 return true;
146 return true;
147 }
147 }
148
148
149 std::optional<QString>
149 std::optional<QString>
150 CatalogueController::repository(CatalogueController::Event_ptr event)
150 CatalogueController::repository(CatalogueController::Event_ptr event)
151 {
151 {
152 for(auto& [repoName, repo] : _currentRepos)
152 for(auto& [repoName, repo] : _currentRepos)
153 {
153 {
154 if(repo.event(event->uuid)) return repoName;
154 if(repo.event(event->uuid)) return repoName;
155 }
155 }
156 return std::nullopt;
156 return std::nullopt;
157 }
157 }
158
158
159 std::optional<QString>
159 std::optional<QString>
160 CatalogueController::repository(CatalogueController::Catalogue_ptr catalogue)
160 CatalogueController::repository(CatalogueController::Catalogue_ptr catalogue)
161 {
161 {
162 for(auto& [repoName, repo] : _currentRepos)
162 for(auto& [repoName, repo] : _currentRepos)
163 {
163 {
164 if(repo.catalogue(catalogue->uuid)) return repoName;
164 if(repo.catalogue(catalogue->uuid)) return repoName;
165 }
165 }
166 return std::nullopt;
166 return std::nullopt;
167 }
167 }
168
168
169 void CatalogueController::save(CatalogueController::Event_ptr event)
169 void CatalogueController::save(CatalogueController::Event_ptr event)
170 {
170 {
171 auto repo_name = repository(event);
171 auto repo_name = repository(event);
172 if(repo_name && contains(_lastSavedRepos, *repo_name))
172 if(repo_name && contains(_lastSavedRepos, *repo_name))
173 {
173 {
174 auto repo = _lastSavedRepos[*repo_name];
174 auto repo = _lastSavedRepos[*repo_name];
175 if(contains(repo.events(), event->uuid))
175 if(contains(repo.events(), event->uuid))
176 {
176 {
177 auto saved_evemt = _lastSavedRepos[*repo_name].event(event->uuid);
177 auto saved_evemt = _lastSavedRepos[*repo_name].event(event->uuid);
178 *saved_evemt = *event;
178 *saved_evemt = *event;
179 }
179 }
180 else
180 else
181 {
181 {
182 // TODO/Question should we also take care of which catalogue has it?
182 // TODO/Question should we also take care of which catalogue has it?
183 // if an event is created and added to a catalogue, what should we do if
183 // if an event is created and added to a catalogue, what should we do if
184 // the user clicks the event save button?
184 // the user clicks the event save button?
185 // - Only save event value in all events list?
185 // - Only save event value in all events list?
186 // - Also save the fact that this event is added to a catalogue and save
186 // - Also save the fact that this event is added to a catalogue and save
187 // the catalogue?
187 // the catalogue?
188 repo.add(event);
188 repo.add(event);
189 }
189 }
190 }
190 }
191 }
191 }
192
192
193 void CatalogueController::save(CatalogueController::Catalogue_ptr catalogue)
193 void CatalogueController::save(CatalogueController::Catalogue_ptr catalogue)
194 {
194 {
195 auto repo_name = repository(catalogue);
195 auto repo_name = repository(catalogue);
196 if(repo_name && contains(_lastSavedRepos, *repo_name))
196 if(repo_name && contains(_lastSavedRepos, *repo_name))
197 {
197 {
198 auto repo = _lastSavedRepos[*repo_name];
198 auto repo = _lastSavedRepos[*repo_name];
199 if(contains(repo.catalogues(), catalogue->uuid))
199 if(contains(repo.catalogues(), catalogue->uuid))
200 {
200 {
201 auto saved_catalogue = repo.catalogue(catalogue->uuid);
201 auto saved_catalogue = repo.catalogue(catalogue->uuid);
202 *saved_catalogue = *catalogue;
202 *saved_catalogue = *catalogue;
203 }
203 }
204 else
204 else
205 {
205 {
206 repo.add(catalogue);
206 repo.add(catalogue);
207 }
207 }
208 }
208 }
209 }
209 }
210
210
211 void CatalogueController::save(const QString& repository)
211 void CatalogueController::save(const QString& repository)
212 {
212 {
213 if(contains(_currentRepos, repository))
213 if(contains(_currentRepos, repository))
214 { _lastSavedRepos[repository] = _currentRepos[repository]; }
214 { _lastSavedRepos[repository] = _currentRepos[repository]; }
215 else
215 else
216 {
216 {
217 SCIQLOP_ERROR(CatalogueController, "Trying to save an unknown repository");
217 SCIQLOP_ERROR(CatalogueController, "Trying to save an unknown repository");
218 }
218 }
219 }
219 }
220
220
221 void CatalogueController::add(const QString& repository)
221 void CatalogueController::add(const QString& repository)
222 {
222 {
223 if(!contains(_currentRepos, repository))
223 if(!contains(_currentRepos, repository))
224 {
224 {
225 _currentRepos[repository] = Repository_t{};
225 _currentRepos[repository] = Repository_t{};
226 emit repositoryAdded(repository);
226 emit repositoryAdded(repository);
227 }
227 }
228 }
228 }
229
229
230 CatalogueController::Catalogue_ptr
230 CatalogueController::Catalogue_ptr
231 CatalogueController::add(const QString& catalogue, const QString& repository)
231 CatalogueController::add(const QString& catalogue, const QString& repository)
232 {
232 {
233 if(!contains(_currentRepos, repository)) { add(repository); }
233 if(!contains(_currentRepos, repository)) { add(repository); }
234 auto new_catalogue = make_catalogue_ptr();
234 auto new_catalogue = make_catalogue_ptr();
235 new_catalogue->name = catalogue.toStdString();
235 new_catalogue->name = catalogue.toStdString();
236 _currentRepos[repository].add(new_catalogue);
236 _currentRepos[repository].add(new_catalogue);
237 emit catalogueAdded(new_catalogue, repository);
237 emit catalogueAdded(new_catalogue, repository);
238 return new_catalogue;
238 return new_catalogue;
239 }
239 }
240
240
241 void CatalogueController::add(CatalogueController::Event_ptr event,
241 void CatalogueController::add(CatalogueController::Event_ptr event,
242 CatalogueController::Catalogue_ptr catalogue)
242 CatalogueController::Catalogue_ptr catalogue)
243 {
243 {
244 catalogue->add(event);
244 catalogue->add(event);
245 emit this->catalogueChanged(catalogue);
245 emit this->catalogueChanged(catalogue);
246 }
246 }
247
247
248 void CatalogueController::add(CatalogueController::Event_ptr event,
248 void CatalogueController::add(CatalogueController::Event_ptr event,
249 const QString& repository)
249 const QString& repository)
250 {}
250 {}
251
251
252 // void CatalogueController::saveDB(const QString& destinationPath, const
252 // void CatalogueController::saveDB(const QString& destinationPath, const
253 // QString& repositoryName)
253 // QString& repositoryName)
254 //{
254 //{
255 // if (!impl->m_CatalogueDao.saveDB(destinationPath, repositoryName))
255 // if (!impl->m_CatalogueDao.saveDB(destinationPath, repositoryName))
256 // {
256 // {
257 // qCCritical(LOG_CatalogueController())
257 // qCCritical(LOG_CatalogueController())
258 // << tr("Impossible to saveDB %1 from %2 ").arg(repositoryName,
258 // << tr("Impossible to saveDB %1 from %2 ").arg(repositoryName,
259 // destinationPath);
259 // destinationPath);
260 // }
260 // }
261 //}
261 //}
262
262
263 // std::list<std::shared_ptr<DBEvent>> CatalogueController::retrieveEvents(
263 // std::list<std::shared_ptr<DBEvent>> CatalogueController::retrieveEvents(
264 // const QString& repository) const
264 // const QString& repository) const
265 //{
265 //{
266 // QString dbDireName = repository.isEmpty() ? REPOSITORY_DEFAULT :
266 // QString dbDireName = repository.isEmpty() ? REPOSITORY_DEFAULT :
267 // repository;
267 // repository;
268
268
269 // auto eventsShared = std::list<std::shared_ptr<DBEvent>> {};
269 // auto eventsShared = std::list<std::shared_ptr<DBEvent>> {};
270 // auto events =
270 // auto events =
271 // impl->m_CatalogueDao.getEvents(impl->toWorkRepository(dbDireName)); for
271 // impl->m_CatalogueDao.getEvents(impl->toWorkRepository(dbDireName)); for
272 // (auto event : events)
272 // (auto event : events)
273 // {
273 // {
274 // eventsShared.push_back(std::make_shared<DBEvent>(event));
274 // eventsShared.push_back(std::make_shared<DBEvent>(event));
275 // }
275 // }
276 // return eventsShared;
276 // return eventsShared;
277 //}
277 //}
278
278
279 // std::list<std::shared_ptr<DBEvent>> CatalogueController::retrieveAllEvents()
279 // std::list<std::shared_ptr<DBEvent>> CatalogueController::retrieveAllEvents()
280 // const
280 // const
281 //{
281 //{
282 // auto eventsShared = std::list<std::shared_ptr<DBEvent>> {};
282 // auto eventsShared = std::list<std::shared_ptr<DBEvent>> {};
283 // for (auto repository : impl->m_RepositoryList)
283 // for (auto repository : impl->m_RepositoryList)
284 // {
284 // {
285 // eventsShared.splice(eventsShared.end(), retrieveEvents(repository));
285 // eventsShared.splice(eventsShared.end(), retrieveEvents(repository));
286 // }
286 // }
287
287
288 // return eventsShared;
288 // return eventsShared;
289 //}
289 //}
290
290
291 // std::list<std::shared_ptr<DBEvent>>
291 // std::list<std::shared_ptr<DBEvent>>
292 // CatalogueController::retrieveEventsFromCatalogue(
292 // CatalogueController::retrieveEventsFromCatalogue(
293 // std::shared_ptr<DBCatalogue> catalogue) const
293 // std::shared_ptr<DBCatalogue> catalogue) const
294 //{
294 //{
295 // auto eventsShared = std::list<std::shared_ptr<DBEvent>> {};
295 // auto eventsShared = std::list<std::shared_ptr<DBEvent>> {};
296 // auto events = impl->m_CatalogueDao.getCatalogueEvents(*catalogue);
296 // auto events = impl->m_CatalogueDao.getCatalogueEvents(*catalogue);
297 // for (auto event : events)
297 // for (auto event : events)
298 // {
298 // {
299 // eventsShared.push_back(std::make_shared<DBEvent>(event));
299 // eventsShared.push_back(std::make_shared<DBEvent>(event));
300 // }
300 // }
301 // return eventsShared;
301 // return eventsShared;
302 //}
302 //}
303
303
304 // void CatalogueController::updateEvent(std::shared_ptr<DBEvent> event)
304 // void CatalogueController::updateEvent(std::shared_ptr<DBEvent> event)
305 //{
305 //{
306 // event->setRepository(impl->toWorkRepository(event->getRepository()));
306 // event->setRepository(impl->toWorkRepository(event->getRepository()));
307
307
308 // auto uniqueId = impl->eventUniqueKey(event);
308 // auto uniqueId = impl->eventUniqueKey(event);
309 // impl->m_KeysWithChanges.insert(uniqueId);
309 // impl->m_KeysWithChanges.insert(uniqueId);
310
310
311 // impl->m_CatalogueDao.updateEvent(*event);
311 // impl->m_CatalogueDao.updateEvent(*event);
312 //}
312 //}
313
313
314 // void CatalogueController::updateEventProduct(std::shared_ptr<DBEventProduct>
314 // void CatalogueController::updateEventProduct(std::shared_ptr<DBEventProduct>
315 // eventProduct)
315 // eventProduct)
316 //{
316 //{
317 // impl->m_CatalogueDao.updateEventProduct(*eventProduct);
317 // impl->m_CatalogueDao.updateEventProduct(*eventProduct);
318 //}
318 //}
319
319
320 // void CatalogueController::removeEvent(std::shared_ptr<DBEvent> event)
320 // void CatalogueController::removeEvent(std::shared_ptr<DBEvent> event)
321 //{
321 //{
322 // // Remove it from both repository and repository_work
322 // // Remove it from both repository and repository_work
323 // event->setRepository(impl->toWorkRepository(event->getRepository()));
323 // event->setRepository(impl->toWorkRepository(event->getRepository()));
324 // impl->m_CatalogueDao.removeEvent(*event);
324 // impl->m_CatalogueDao.removeEvent(*event);
325 // event->setRepository(impl->toSyncRepository(event->getRepository()));
325 // event->setRepository(impl->toSyncRepository(event->getRepository()));
326 // impl->m_CatalogueDao.removeEvent(*event);
326 // impl->m_CatalogueDao.removeEvent(*event);
327 // impl->savAllDB();
327 // impl->savAllDB();
328 //}
328 //}
329
329
330 // void CatalogueController::addEvent(std::shared_ptr<DBEvent> event)
330 // void CatalogueController::addEvent(std::shared_ptr<DBEvent> event)
331 //{
331 //{
332 // event->setRepository(impl->toWorkRepository(event->getRepository()));
332 // event->setRepository(impl->toWorkRepository(event->getRepository()));
333
333
334 // auto eventTemp = *event;
334 // auto eventTemp = *event;
335 // impl->m_CatalogueDao.addEvent(eventTemp);
335 // impl->m_CatalogueDao.addEvent(eventTemp);
336
336
337 // // Call update is necessary at the creation of add Event if it has some
337 // // Call update is necessary at the creation of add Event if it has some
338 // tags or some event
338 // tags or some event
339 // // products
339 // // products
340 // if (!event->getEventProducts().empty() || !event->getTags().empty())
340 // if (!event->getEventProducts().empty() || !event->getTags().empty())
341 // {
341 // {
342
342
343 // auto eventProductsTemp = eventTemp.getEventProducts();
343 // auto eventProductsTemp = eventTemp.getEventProducts();
344 // auto eventProductTempUpdated = std::list<DBEventProduct> {};
344 // auto eventProductTempUpdated = std::list<DBEventProduct> {};
345 // for (auto eventProductTemp : eventProductsTemp)
345 // for (auto eventProductTemp : eventProductsTemp)
346 // {
346 // {
347 // eventProductTemp.setEvent(eventTemp);
347 // eventProductTemp.setEvent(eventTemp);
348 // eventProductTempUpdated.push_back(eventProductTemp);
348 // eventProductTempUpdated.push_back(eventProductTemp);
349 // }
349 // }
350 // eventTemp.setEventProducts(eventProductTempUpdated);
350 // eventTemp.setEventProducts(eventProductTempUpdated);
351
351
352 // impl->m_CatalogueDao.updateEvent(eventTemp);
352 // impl->m_CatalogueDao.updateEvent(eventTemp);
353 // }
353 // }
354
354
355 // auto workPred = impl->createFinder(event->getUniqId(),
355 // auto workPred = impl->createFinder(event->getUniqId(),
356 // event->getRepository(), DBType::WORK);
356 // event->getRepository(), DBType::WORK);
357
357
358 // auto workEvent = impl->m_CatalogueDao.getEvent(workPred);
358 // auto workEvent = impl->m_CatalogueDao.getEvent(workPred);
359 // *event = workEvent;
359 // *event = workEvent;
360
360
361 // auto uniqueId = impl->eventUniqueKey(event);
361 // auto uniqueId = impl->eventUniqueKey(event);
362 // impl->m_KeysWithChanges.insert(uniqueId);
362 // impl->m_KeysWithChanges.insert(uniqueId);
363 //}
363 //}
364
364
365 // void CatalogueController::saveEvent(std::shared_ptr<DBEvent> event)
365 // void CatalogueController::saveEvent(std::shared_ptr<DBEvent> event)
366 //{
366 //{
367 // impl->saveEvent(event, true);
367 // impl->saveEvent(event, true);
368 // impl->m_KeysWithChanges.remove(impl->eventUniqueKey(event));
368 // impl->m_KeysWithChanges.remove(impl->eventUniqueKey(event));
369 //}
369 //}
370
370
371 // void CatalogueController::discardEvent(std::shared_ptr<DBEvent> event, bool&
371 // void CatalogueController::discardEvent(std::shared_ptr<DBEvent> event, bool&
372 // removed)
372 // removed)
373 //{
373 //{
374 // auto syncPred = impl->createFinder(event->getUniqId(),
374 // auto syncPred = impl->createFinder(event->getUniqId(),
375 // event->getRepository(), DBType::SYNC); auto workPred =
375 // event->getRepository(), DBType::SYNC); auto workPred =
376 // impl->createFinder(event->getUniqId(), event->getRepository(),
376 // impl->createFinder(event->getUniqId(), event->getRepository(),
377 // DBType::WORK);
377 // DBType::WORK);
378
378
379 // auto syncEvent = impl->m_CatalogueDao.getEvent(syncPred);
379 // auto syncEvent = impl->m_CatalogueDao.getEvent(syncPred);
380 // if (!syncEvent.getUniqId().isNull())
380 // if (!syncEvent.getUniqId().isNull())
381 // {
381 // {
382 // removed = false;
382 // removed = false;
383 // impl->m_CatalogueDao.copyEvent(
383 // impl->m_CatalogueDao.copyEvent(
384 // syncEvent, impl->toWorkRepository(event->getRepository()), true);
384 // syncEvent, impl->toWorkRepository(event->getRepository()), true);
385
385
386 // auto workEvent = impl->m_CatalogueDao.getEvent(workPred);
386 // auto workEvent = impl->m_CatalogueDao.getEvent(workPred);
387 // *event = workEvent;
387 // *event = workEvent;
388 // impl->m_KeysWithChanges.remove(impl->eventUniqueKey(event));
388 // impl->m_KeysWithChanges.remove(impl->eventUniqueKey(event));
389 // }
389 // }
390 // else
390 // else
391 // {
391 // {
392 // removed = true;
392 // removed = true;
393 // // Since the element wasn't in sync repository. Discard it means
393 // // Since the element wasn't in sync repository. Discard it means
394 // remove it
394 // remove it
395 // event->setRepository(impl->toWorkRepository(event->getRepository()));
395 // event->setRepository(impl->toWorkRepository(event->getRepository()));
396 // impl->m_CatalogueDao.removeEvent(*event);
396 // impl->m_CatalogueDao.removeEvent(*event);
397 // }
397 // }
398 //}
398 //}
399
399
400 // bool CatalogueController::eventHasChanges(std::shared_ptr<DBEvent> event)
400 // bool CatalogueController::eventHasChanges(std::shared_ptr<DBEvent> event)
401 // const
401 // const
402 //{
402 //{
403 // return impl->m_KeysWithChanges.contains(impl->eventUniqueKey(event));
403 // return impl->m_KeysWithChanges.contains(impl->eventUniqueKey(event));
404 //}
404 //}
405
405
406 // std::list<std::shared_ptr<DBCatalogue>>
406 // std::list<std::shared_ptr<DBCatalogue>>
407 // CatalogueController::retrieveCatalogues(
407 // CatalogueController::retrieveCatalogues(
408 // const QString& repository) const
408 // const QString& repository) const
409 //{
409 //{
410 // QString dbDireName = repository.isEmpty() ? REPOSITORY_DEFAULT :
410 // QString dbDireName = repository.isEmpty() ? REPOSITORY_DEFAULT :
411 // repository;
411 // repository;
412
412
413 // auto cataloguesShared = std::list<std::shared_ptr<DBCatalogue>> {};
413 // auto cataloguesShared = std::list<std::shared_ptr<DBCatalogue>> {};
414 // auto catalogues =
414 // auto catalogues =
415 // impl->m_CatalogueDao.getCatalogues(impl->toWorkRepository(dbDireName));
415 // impl->m_CatalogueDao.getCatalogues(impl->toWorkRepository(dbDireName));
416 // for (auto catalogue : catalogues)
416 // for (auto catalogue : catalogues)
417 // {
417 // {
418 // cataloguesShared.push_back(std::make_shared<DBCatalogue>(catalogue));
418 // cataloguesShared.push_back(std::make_shared<DBCatalogue>(catalogue));
419 // }
419 // }
420 // return cataloguesShared;
420 // return cataloguesShared;
421 //}
421 //}
422
422
423 // void CatalogueController::addCatalogue(std::shared_ptr<DBCatalogue>
423 // void CatalogueController::addCatalogue(std::shared_ptr<DBCatalogue>
424 // catalogue)
424 // catalogue)
425 //{
425 //{
426 // catalogue->setRepository(impl->toWorkRepository(catalogue->getRepository()));
426 // catalogue->setRepository(impl->toWorkRepository(catalogue->getRepository()));
427
427
428 // auto catalogueTemp = *catalogue;
428 // auto catalogueTemp = *catalogue;
429 // impl->m_CatalogueDao.addCatalogue(catalogueTemp);
429 // impl->m_CatalogueDao.addCatalogue(catalogueTemp);
430
430
431 // auto workPred
431 // auto workPred
432 // = impl->createFinder(catalogue->getUniqId(),
432 // = impl->createFinder(catalogue->getUniqId(),
433 // catalogue->getRepository(), DBType::WORK);
433 // catalogue->getRepository(), DBType::WORK);
434
434
435 // auto workCatalogue = impl->m_CatalogueDao.getCatalogue(workPred);
435 // auto workCatalogue = impl->m_CatalogueDao.getCatalogue(workPred);
436 // *catalogue = workCatalogue;
436 // *catalogue = workCatalogue;
437
437
438 // auto uniqueId = impl->catalogueUniqueKey(catalogue);
438 // auto uniqueId = impl->catalogueUniqueKey(catalogue);
439 // impl->m_KeysWithChanges.insert(uniqueId);
439 // impl->m_KeysWithChanges.insert(uniqueId);
440 //}
440 //}
441
441
442 // void CatalogueController::updateCatalogue(std::shared_ptr<DBCatalogue>
442 // void CatalogueController::updateCatalogue(std::shared_ptr<DBCatalogue>
443 // catalogue)
443 // catalogue)
444 //{
444 //{
445 // catalogue->setRepository(impl->toWorkRepository(catalogue->getRepository()));
445 // catalogue->setRepository(impl->toWorkRepository(catalogue->getRepository()));
446
446
447 // auto uniqueId = impl->catalogueUniqueKey(catalogue);
447 // auto uniqueId = impl->catalogueUniqueKey(catalogue);
448 // impl->m_KeysWithChanges.insert(uniqueId);
448 // impl->m_KeysWithChanges.insert(uniqueId);
449
449
450 // impl->m_CatalogueDao.updateCatalogue(*catalogue);
450 // impl->m_CatalogueDao.updateCatalogue(*catalogue);
451 //}
451 //}
452
452
453 // void CatalogueController::removeCatalogue(std::shared_ptr<DBCatalogue>
453 // void CatalogueController::removeCatalogue(std::shared_ptr<DBCatalogue>
454 // catalogue)
454 // catalogue)
455 //{
455 //{
456 // // Remove it from both repository and repository_work
456 // // Remove it from both repository and repository_work
457 // catalogue->setRepository(impl->toWorkRepository(catalogue->getRepository()));
457 // catalogue->setRepository(impl->toWorkRepository(catalogue->getRepository()));
458 // impl->m_CatalogueDao.removeCatalogue(*catalogue);
458 // impl->m_CatalogueDao.removeCatalogue(*catalogue);
459 // catalogue->setRepository(impl->toSyncRepository(catalogue->getRepository()));
459 // catalogue->setRepository(impl->toSyncRepository(catalogue->getRepository()));
460 // impl->m_CatalogueDao.removeCatalogue(*catalogue);
460 // impl->m_CatalogueDao.removeCatalogue(*catalogue);
461 // impl->savAllDB();
461 // impl->savAllDB();
462 //}
462 //}
463
463
464 // void CatalogueController::saveCatalogue(std::shared_ptr<DBCatalogue>
464 // void CatalogueController::saveCatalogue(std::shared_ptr<DBCatalogue>
465 // catalogue)
465 // catalogue)
466 //{
466 //{
467 // impl->saveCatalogue(catalogue, true);
467 // impl->saveCatalogue(catalogue, true);
468 // impl->m_KeysWithChanges.remove(impl->catalogueUniqueKey(catalogue));
468 // impl->m_KeysWithChanges.remove(impl->catalogueUniqueKey(catalogue));
469
469
470 // // remove key of events of the catalogue
470 // // remove key of events of the catalogue
471 // if (catalogue->getType() == CatalogueType::STATIC)
471 // if (catalogue->getType() == CatalogueType::STATIC)
472 // {
472 // {
473 // auto events = this->retrieveEventsFromCatalogue(catalogue);
473 // auto events = this->retrieveEventsFromCatalogue(catalogue);
474 // for (auto event : events)
474 // for (auto event : events)
475 // {
475 // {
476 // impl->m_KeysWithChanges.remove(impl->eventUniqueKey(event));
476 // impl->m_KeysWithChanges.remove(impl->eventUniqueKey(event));
477 // }
477 // }
478 // }
478 // }
479 //}
479 //}
480
480
481 // void CatalogueController::discardCatalogue(std::shared_ptr<DBCatalogue>
481 // void CatalogueController::discardCatalogue(std::shared_ptr<DBCatalogue>
482 // catalogue, bool& removed)
482 // catalogue, bool& removed)
483 //{
483 //{
484 // auto syncPred
484 // auto syncPred
485 // = impl->createFinder(catalogue->getUniqId(),
485 // = impl->createFinder(catalogue->getUniqId(),
486 // catalogue->getRepository(), DBType::SYNC);
486 // catalogue->getRepository(), DBType::SYNC);
487 // auto workPred
487 // auto workPred
488 // = impl->createFinder(catalogue->getUniqId(),
488 // = impl->createFinder(catalogue->getUniqId(),
489 // catalogue->getRepository(), DBType::WORK);
489 // catalogue->getRepository(), DBType::WORK);
490
490
491 // auto syncCatalogue = impl->m_CatalogueDao.getCatalogue(syncPred);
491 // auto syncCatalogue = impl->m_CatalogueDao.getCatalogue(syncPred);
492 // if (!syncCatalogue.getUniqId().isNull())
492 // if (!syncCatalogue.getUniqId().isNull())
493 // {
493 // {
494 // removed = false;
494 // removed = false;
495 // impl->m_CatalogueDao.copyCatalogue(
495 // impl->m_CatalogueDao.copyCatalogue(
496 // syncCatalogue, impl->toWorkRepository(catalogue->getRepository()),
496 // syncCatalogue, impl->toWorkRepository(catalogue->getRepository()),
497 // true);
497 // true);
498
498
499 // auto workCatalogue = impl->m_CatalogueDao.getCatalogue(workPred);
499 // auto workCatalogue = impl->m_CatalogueDao.getCatalogue(workPred);
500 // *catalogue = workCatalogue;
500 // *catalogue = workCatalogue;
501 // impl->m_KeysWithChanges.remove(impl->catalogueUniqueKey(catalogue));
501 // impl->m_KeysWithChanges.remove(impl->catalogueUniqueKey(catalogue));
502 // }
502 // }
503 // else
503 // else
504 // {
504 // {
505 // removed = true;
505 // removed = true;
506 // // Since the element wasn't in sync repository. Discard it means
506 // // Since the element wasn't in sync repository. Discard it means
507 // remove it
507 // remove it
508 // catalogue->setRepository(impl->toWorkRepository(catalogue->getRepository()));
508 // catalogue->setRepository(impl->toWorkRepository(catalogue->getRepository()));
509 // impl->m_CatalogueDao.removeCatalogue(*catalogue);
509 // impl->m_CatalogueDao.removeCatalogue(*catalogue);
510 // }
510 // }
511 //}
511 //}
512
512
513 // void CatalogueController::saveAll()
513 // void CatalogueController::saveAll()
514 //{
514 //{
515 // for (auto repository : impl->m_RepositoryList)
515 // for (auto repository : impl->m_RepositoryList)
516 // {
516 // {
517 // // Save Event
517 // // Save Event
518 // auto events = this->retrieveEvents(repository);
518 // auto events = this->retrieveEvents(repository);
519 // for (auto event : events)
519 // for (auto event : events)
520 // {
520 // {
521 // impl->saveEvent(event, false);
521 // impl->saveEvent(event, false);
522 // }
522 // }
523
523
524 // // Save Catalogue
524 // // Save Catalogue
525 // auto catalogues = this->retrieveCatalogues(repository);
525 // auto catalogues = this->retrieveCatalogues(repository);
526 // for (auto catalogue : catalogues)
526 // for (auto catalogue : catalogues)
527 // {
527 // {
528 // impl->saveCatalogue(catalogue, false);
528 // impl->saveCatalogue(catalogue, false);
529 // }
529 // }
530 // }
530 // }
531
531
532 // impl->savAllDB();
532 // impl->savAllDB();
533 // impl->m_KeysWithChanges.clear();
533 // impl->m_KeysWithChanges.clear();
534 //}
534 //}
535
535
536 // bool CatalogueController::hasChanges() const
536 // bool CatalogueController::hasChanges() const
537 //{
537 //{
538 // return !impl->m_KeysWithChanges.isEmpty();
538 // return !impl->m_KeysWithChanges.isEmpty();
539 //}
539 //}
540
540
541 // QByteArray CatalogueController::mimeDataForEvents(
541 // QByteArray CatalogueController::mimeDataForEvents(
542 // const QVector<std::shared_ptr<DBEvent>>& events) const
542 // const QVector<std::shared_ptr<DBEvent>>& events) const
543 //{
543 //{
544 // auto encodedData = QByteArray {};
544 // auto encodedData = QByteArray {};
545
545
546 // QMap<QString, QVariantList> idsPerRepository;
546 // QMap<QString, QVariantList> idsPerRepository;
547 // for (auto event : events)
547 // for (auto event : events)
548 // {
548 // {
549 // idsPerRepository[event->getRepository()] << event->getUniqId();
549 // idsPerRepository[event->getRepository()] << event->getUniqId();
550 // }
550 // }
551
551
552 // QDataStream stream { &encodedData, QIODevice::WriteOnly };
552 // QDataStream stream { &encodedData, QIODevice::WriteOnly };
553 // stream << idsPerRepository;
553 // stream << idsPerRepository;
554
554
555 // return encodedData;
555 // return encodedData;
556 //}
556 //}
557
557
558 // QVector<std::shared_ptr<DBEvent>> CatalogueController::eventsForMimeData(
558 // QVector<std::shared_ptr<DBEvent>> CatalogueController::eventsForMimeData(
559 // const QByteArray& mimeData) const
559 // const QByteArray& mimeData) const
560 //{
560 //{
561 // auto events = QVector<std::shared_ptr<DBEvent>> {};
561 // auto events = QVector<std::shared_ptr<DBEvent>> {};
562 // QDataStream stream { mimeData };
562 // QDataStream stream { mimeData };
563
563
564 // QMap<QString, QVariantList> idsPerRepository;
564 // QMap<QString, QVariantList> idsPerRepository;
565 // stream >> idsPerRepository;
565 // stream >> idsPerRepository;
566
566
567 // for (auto it = idsPerRepository.cbegin(); it != idsPerRepository.cend();
567 // for (auto it = idsPerRepository.cbegin(); it != idsPerRepository.cend();
568 // ++it)
568 // ++it)
569 // {
569 // {
570 // auto repository = it.key();
570 // auto repository = it.key();
571 // auto allRepositoryEvent = retrieveEvents(repository);
571 // auto allRepositoryEvent = retrieveEvents(repository);
572 // for (auto uuid : it.value())
572 // for (auto uuid : it.value())
573 // {
573 // {
574 // for (auto repositoryEvent : allRepositoryEvent)
574 // for (auto repositoryEvent : allRepositoryEvent)
575 // {
575 // {
576 // if (uuid.toUuid() == repositoryEvent->getUniqId())
576 // if (uuid.toUuid() == repositoryEvent->getUniqId())
577 // {
577 // {
578 // events << repositoryEvent;
578 // events << repositoryEvent;
579 // }
579 // }
580 // }
580 // }
581 // }
581 // }
582 // }
582 // }
583
583
584 // return events;
584 // return events;
585 //}
585 //}
586
586
587 // QByteArray CatalogueController::mimeDataForCatalogues(
587 // QByteArray CatalogueController::mimeDataForCatalogues(
588 // const QVector<std::shared_ptr<DBCatalogue>>& catalogues) const
588 // const QVector<std::shared_ptr<DBCatalogue>>& catalogues) const
589 //{
589 //{
590 // auto encodedData = QByteArray {};
590 // auto encodedData = QByteArray {};
591
591
592 // QMap<QString, QVariantList> idsPerRepository;
592 // QMap<QString, QVariantList> idsPerRepository;
593 // for (auto catalogue : catalogues)
593 // for (auto catalogue : catalogues)
594 // {
594 // {
595 // idsPerRepository[catalogue->getRepository()] <<
595 // idsPerRepository[catalogue->getRepository()] <<
596 // catalogue->getUniqId();
596 // catalogue->getUniqId();
597 // }
597 // }
598
598
599 // QDataStream stream { &encodedData, QIODevice::WriteOnly };
599 // QDataStream stream { &encodedData, QIODevice::WriteOnly };
600 // stream << idsPerRepository;
600 // stream << idsPerRepository;
601
601
602 // return encodedData;
602 // return encodedData;
603 //}
603 //}
604
604
605 // QVector<std::shared_ptr<DBCatalogue>>
605 // QVector<std::shared_ptr<DBCatalogue>>
606 // CatalogueController::cataloguesForMimeData(
606 // CatalogueController::cataloguesForMimeData(
607 // const QByteArray& mimeData) const
607 // const QByteArray& mimeData) const
608 //{
608 //{
609 // auto catalogues = QVector<std::shared_ptr<DBCatalogue>> {};
609 // auto catalogues = QVector<std::shared_ptr<DBCatalogue>> {};
610 // QDataStream stream { mimeData };
610 // QDataStream stream { mimeData };
611
611
612 // QMap<QString, QVariantList> idsPerRepository;
612 // QMap<QString, QVariantList> idsPerRepository;
613 // stream >> idsPerRepository;
613 // stream >> idsPerRepository;
614
614
615 // for (auto it = idsPerRepository.cbegin(); it != idsPerRepository.cend();
615 // for (auto it = idsPerRepository.cbegin(); it != idsPerRepository.cend();
616 // ++it)
616 // ++it)
617 // {
617 // {
618 // auto repository = it.key();
618 // auto repository = it.key();
619 // auto allRepositoryCatalogues = retrieveCatalogues(repository);
619 // auto allRepositoryCatalogues = retrieveCatalogues(repository);
620 // for (auto uuid : it.value())
620 // for (auto uuid : it.value())
621 // {
621 // {
622 // for (auto repositoryCatalogues : allRepositoryCatalogues)
622 // for (auto repositoryCatalogues : allRepositoryCatalogues)
623 // {
623 // {
624 // if (uuid.toUuid() == repositoryCatalogues->getUniqId())
624 // if (uuid.toUuid() == repositoryCatalogues->getUniqId())
625 // {
625 // {
626 // catalogues << repositoryCatalogues;
626 // catalogues << repositoryCatalogues;
627 // }
627 // }
628 // }
628 // }
629 // }
629 // }
630 // }
630 // }
631
631
632 // return catalogues;
632 // return catalogues;
633 //}
633 //}
634
634
635 // void CatalogueController::initialize()
635 // void CatalogueController::initialize()
636 //{
636 //{
637 // qCDebug(LOG_CatalogueController())
637 // qCDebug(LOG_CatalogueController())
638 // << tr("CatalogueController init") << QThread::currentThread();
638 // << tr("CatalogueController init") << QThread::currentThread();
639
639
640 // impl->m_CatalogueDao.initialize();
640 // impl->m_CatalogueDao.initialize();
641 // auto defaultRepositoryLocation
641 // auto defaultRepositoryLocation
642 // = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
642 // = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
643
643
644 // QDir defaultRepositoryLocationDir;
644 // QDir defaultRepositoryLocationDir;
645 // if (defaultRepositoryLocationDir.mkpath(defaultRepositoryLocation))
645 // if (defaultRepositoryLocationDir.mkpath(defaultRepositoryLocation))
646 // {
646 // {
647 // defaultRepositoryLocationDir.cd(defaultRepositoryLocation);
647 // defaultRepositoryLocationDir.cd(defaultRepositoryLocation);
648 // auto defaultRepository =
648 // auto defaultRepository =
649 // defaultRepositoryLocationDir.absoluteFilePath(REPOSITORY_DEFAULT);
649 // defaultRepositoryLocationDir.absoluteFilePath(REPOSITORY_DEFAULT);
650
650
651 // qCInfo(LOG_CatalogueController())
651 // qCInfo(LOG_CatalogueController())
652 // << tr("Persistant data loading from: ") << defaultRepository;
652 // << tr("Persistant data loading from: ") << defaultRepository;
653
653
654 // QDir dbDir(defaultRepository);
654 // QDir dbDir(defaultRepository);
655 // impl->m_RepositoryList << REPOSITORY_DEFAULT;
655 // impl->m_RepositoryList << REPOSITORY_DEFAULT;
656 // if (dbDir.exists())
656 // if (dbDir.exists())
657 // {
657 // {
658 // auto dirName = dbDir.dirName();
658 // auto dirName = dbDir.dirName();
659
659
660 // if (impl->m_CatalogueDao.addDB(defaultRepository, dirName))
660 // if (impl->m_CatalogueDao.addDB(defaultRepository, dirName))
661 // {
661 // {
662 // impl->copyDBtoDB(dirName, impl->toWorkRepository(dirName));
662 // impl->copyDBtoDB(dirName, impl->toWorkRepository(dirName));
663 // }
663 // }
664 // }
664 // }
665 // else
665 // else
666 // {
666 // {
667 // qCInfo(LOG_CatalogueController())
667 // qCInfo(LOG_CatalogueController())
668 // << tr("Initialisation of Default repository detected") <<
668 // << tr("Initialisation of Default repository detected") <<
669 // defaultRepository;
669 // defaultRepository;
670 // }
670 // }
671 // }
671 // }
672 // else
672 // else
673 // {
673 // {
674 // qCWarning(LOG_CatalogueController())
674 // qCWarning(LOG_CatalogueController())
675 // << tr("Cannot load the persistent default repository from ")
675 // << tr("Cannot load the persistent default repository from ")
676 // << defaultRepositoryLocation;
676 // << defaultRepositoryLocation;
677 // }
677 // }
678
678
679 // qCDebug(LOG_CatalogueController()) << tr("CatalogueController init END");
679 // qCDebug(LOG_CatalogueController()) << tr("CatalogueController init END");
680 //}
680 //}
681
681
682 // QString CatalogueController::CatalogueControllerPrivate::eventUniqueKey(
682 // QString CatalogueController::CatalogueControllerPrivate::eventUniqueKey(
683 // const std::shared_ptr<DBEvent>& event) const
683 // const std::shared_ptr<DBEvent>& event) const
684 //{
684 //{
685 // return event->getUniqId().toString().append(event->getRepository());
685 // return event->getUniqId().toString().append(event->getRepository());
686 //}
686 //}
687
687
688 // QString CatalogueController::CatalogueControllerPrivate::catalogueUniqueKey(
688 // QString CatalogueController::CatalogueControllerPrivate::catalogueUniqueKey(
689 // const std::shared_ptr<DBCatalogue>& catalogue) const
689 // const std::shared_ptr<DBCatalogue>& catalogue) const
690 //{
690 //{
691 // return
691 // return
692 // catalogue->getUniqId().toString().append(catalogue->getRepository());
692 // catalogue->getUniqId().toString().append(catalogue->getRepository());
693 //}
693 //}
694
694
695 // void CatalogueController::CatalogueControllerPrivate::copyDBtoDB(
695 // void CatalogueController::CatalogueControllerPrivate::copyDBtoDB(
696 // const QString& dbFrom, const QString& dbTo)
696 // const QString& dbFrom, const QString& dbTo)
697 //{
697 //{
698 // // auto cataloguesShared = std::list<std::shared_ptr<DBCatalogue> >{};
698 // // auto cataloguesShared = std::list<std::shared_ptr<DBCatalogue> >{};
699 // auto catalogues = m_CatalogueDao.getCatalogues(dbFrom);
699 // auto catalogues = m_CatalogueDao.getCatalogues(dbFrom);
700 // auto events = m_CatalogueDao.getEvents(dbFrom);
700 // auto events = m_CatalogueDao.getEvents(dbFrom);
701 // for (auto catalogue : catalogues)
701 // for (auto catalogue : catalogues)
702 // {
702 // {
703 // m_CatalogueDao.copyCatalogue(catalogue, dbTo, true);
703 // m_CatalogueDao.copyCatalogue(catalogue, dbTo, true);
704 // }
704 // }
705
705
706 // for (auto event : events)
706 // for (auto event : events)
707 // {
707 // {
708 // m_CatalogueDao.copyEvent(event, dbTo, true);
708 // m_CatalogueDao.copyEvent(event, dbTo, true);
709 // }
709 // }
710 //}
710 //}
711
711
712 // QString
712 // QString
713 // CatalogueController::CatalogueControllerPrivate::toWorkRepository(QString
713 // CatalogueController::CatalogueControllerPrivate::toWorkRepository(QString
714 // repository)
714 // repository)
715 //{
715 //{
716 // auto syncRepository = toSyncRepository(repository);
716 // auto syncRepository = toSyncRepository(repository);
717
717
718 // return QString("%1%2").arg(syncRepository, REPOSITORY_WORK_SUFFIX);
718 // return QString("%1%2").arg(syncRepository, REPOSITORY_WORK_SUFFIX);
719 //}
719 //}
720
720
721 // QString
721 // QString
722 // CatalogueController::CatalogueControllerPrivate::toSyncRepository(QString
722 // CatalogueController::CatalogueControllerPrivate::toSyncRepository(QString
723 // repository)
723 // repository)
724 //{
724 //{
725 // auto syncRepository = repository;
725 // auto syncRepository = repository;
726 // if (repository.endsWith(REPOSITORY_WORK_SUFFIX))
726 // if (repository.endsWith(REPOSITORY_WORK_SUFFIX))
727 // {
727 // {
728 // syncRepository.remove(REPOSITORY_WORK_SUFFIX);
728 // syncRepository.remove(REPOSITORY_WORK_SUFFIX);
729 // }
729 // }
730 // else if (repository.endsWith(REPOSITORY_TRASH_SUFFIX))
730 // else if (repository.endsWith(REPOSITORY_TRASH_SUFFIX))
731 // {
731 // {
732 // syncRepository.remove(REPOSITORY_TRASH_SUFFIX);
732 // syncRepository.remove(REPOSITORY_TRASH_SUFFIX);
733 // }
733 // }
734 // return syncRepository;
734 // return syncRepository;
735 //}
735 //}
736
736
737 // void CatalogueController::CatalogueControllerPrivate::savAllDB()
737 // void CatalogueController::CatalogueControllerPrivate::savAllDB()
738 //{
738 //{
739 // for (auto repository : m_RepositoryList)
739 // for (auto repository : m_RepositoryList)
740 // {
740 // {
741 // auto defaultRepositoryLocation
741 // auto defaultRepositoryLocation
742 // =
742 // =
743 // QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
743 // QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
744 // m_CatalogueDao.saveDB(defaultRepositoryLocation, repository);
744 // m_CatalogueDao.saveDB(defaultRepositoryLocation, repository);
745 // }
745 // }
746 //}
746 //}
747
747
748 // void CatalogueController::CatalogueControllerPrivate::saveEvent(
748 // void CatalogueController::CatalogueControllerPrivate::saveEvent(
749 // std::shared_ptr<DBEvent> event, bool persist)
749 // std::shared_ptr<DBEvent> event, bool persist)
750 //{
750 //{
751 // m_CatalogueDao.copyEvent(*event, toSyncRepository(event->getRepository()),
751 // m_CatalogueDao.copyEvent(*event, toSyncRepository(event->getRepository()),
752 // true); if (persist)
752 // true); if (persist)
753 // {
753 // {
754 // savAllDB();
754 // savAllDB();
755 // }
755 // }
756 //}
756 //}
757
757
758 // void CatalogueController::CatalogueControllerPrivate::saveCatalogue(
758 // void CatalogueController::CatalogueControllerPrivate::saveCatalogue(
759 // std::shared_ptr<DBCatalogue> catalogue, bool persist)
759 // std::shared_ptr<DBCatalogue> catalogue, bool persist)
760 //{
760 //{
761 // m_CatalogueDao.copyCatalogue(*catalogue,
761 // m_CatalogueDao.copyCatalogue(*catalogue,
762 // toSyncRepository(catalogue->getRepository()), true); if (persist)
762 // toSyncRepository(catalogue->getRepository()), true); if (persist)
763 // {
763 // {
764 // savAllDB();
764 // savAllDB();
765 // }
765 // }
766 //}
766 //}
767
767
768 // std::shared_ptr<IRequestPredicate>
768 // std::shared_ptr<IRequestPredicate>
769 // CatalogueController::CatalogueControllerPrivate::createFinder(
769 // CatalogueController::CatalogueControllerPrivate::createFinder(
770 // const QUuid& uniqId, const QString& repository, DBType type)
770 // const QUuid& uniqId, const QString& repository, DBType type)
771 //{
771 //{
772 // // update catalogue parameter
772 // // update catalogue parameter
773 // auto uniqIdPredicate = std::make_shared<ComparaisonPredicate>(
773 // auto uniqIdPredicate = std::make_shared<ComparaisonPredicate>(
774 // QString { "uniqId" }, uniqId, ComparaisonOperation::EQUALEQUAL);
774 // QString { "uniqId" }, uniqId, ComparaisonOperation::EQUALEQUAL);
775
775
776 // auto repositoryType = repository;
776 // auto repositoryType = repository;
777 // switch (type)
777 // switch (type)
778 // {
778 // {
779 // case DBType::SYNC:
779 // case DBType::SYNC:
780 // repositoryType = toSyncRepository(repositoryType);
780 // repositoryType = toSyncRepository(repositoryType);
781 // break;
781 // break;
782 // case DBType::WORK:
782 // case DBType::WORK:
783 // repositoryType = toWorkRepository(repositoryType);
783 // repositoryType = toWorkRepository(repositoryType);
784 // break;
784 // break;
785 // case DBType::TRASH:
785 // case DBType::TRASH:
786 // default:
786 // default:
787 // break;
787 // break;
788 // }
788 // }
789
789
790 // auto repositoryPredicate = std::make_shared<ComparaisonPredicate>(
790 // auto repositoryPredicate = std::make_shared<ComparaisonPredicate>(
791 // QString { "repository" }, repositoryType,
791 // QString { "repository" }, repositoryType,
792 // ComparaisonOperation::EQUALEQUAL);
792 // ComparaisonOperation::EQUALEQUAL);
793
793
794 // auto finderPred =
794 // auto finderPred =
795 // std::make_shared<CompoundPredicate>(CompoundOperation::AND);
795 // std::make_shared<CompoundPredicate>(CompoundOperation::AND);
796 // finderPred->AddRequestPredicate(uniqIdPredicate);
796 // finderPred->AddRequestPredicate(uniqIdPredicate);
797 // finderPred->AddRequestPredicate(repositoryPredicate);
797 // finderPred->AddRequestPredicate(repositoryPredicate);
798
798
799 // return finderPred;
799 // return finderPred;
800 //}
800 //}
@@ -1,298 +1,298
1 #include "DataSource/DataSourceController.h"
1 #include "DataSource/DataSourceController.h"
2
2
3 #include "DataSource/DataSourceItem.h"
3 #include "DataSource/DataSourceItem.h"
4 #include "DataSource/DataSourceItemAction.h"
4 #include "DataSource/DataSourceItemAction.h"
5
5
6 #include <Common/containers.h>
6 #include <containers/algorithms.hpp>
7 #include <Data/IDataProvider.h>
7 #include <Data/IDataProvider.h>
8 #include <QDataStream>
8 #include <QDataStream>
9 #include <QDir>
9 #include <QDir>
10 #include <QMutex>
10 #include <QMutex>
11 #include <QStandardPaths>
11 #include <QStandardPaths>
12 #include <QThread>
12 #include <QThread>
13
13
14 Q_LOGGING_CATEGORY(LOG_DataSourceController, "DataSourceController")
14 Q_LOGGING_CATEGORY(LOG_DataSourceController, "DataSourceController")
15
15
16 std::unique_ptr<DataSourceItem> make_folder_item(const QString& name)
16 std::unique_ptr<DataSourceItem> make_folder_item(const QString& name)
17 {
17 {
18 return std::make_unique<DataSourceItem>(DataSourceItemType::NODE, name);
18 return std::make_unique<DataSourceItem>(DataSourceItemType::NODE, name);
19 }
19 }
20
20
21 template<typename T>
21 template<typename T>
22 DataSourceItem* make_path_items(const T& path_list_begin,
22 DataSourceItem* make_path_items(const T& path_list_begin,
23 const T& path_list_end, DataSourceItem* root)
23 const T& path_list_end, DataSourceItem* root)
24 {
24 {
25 std::for_each(path_list_begin, path_list_end,
25 std::for_each(path_list_begin, path_list_end,
26 [&root](const auto& folder_name) mutable {
26 [&root](const auto& folder_name) mutable {
27 auto folder_ptr = root->findItem(folder_name);
27 auto folder_ptr = root->findItem(folder_name);
28 if(folder_ptr == nullptr)
28 if(folder_ptr == nullptr)
29 {
29 {
30 auto folder = make_folder_item(folder_name);
30 auto folder = make_folder_item(folder_name);
31 folder_ptr = folder.get();
31 folder_ptr = folder.get();
32 root->appendChild(std::move(folder));
32 root->appendChild(std::move(folder));
33 }
33 }
34 root = folder_ptr;
34 root = folder_ptr;
35 });
35 });
36 return root;
36 return root;
37 }
37 }
38
38
39 std::unique_ptr<DataSourceItem>
39 std::unique_ptr<DataSourceItem>
40 make_product_item(const QVariantHash& metaData, const QUuid& dataSourceUid,
40 make_product_item(const QVariantHash& metaData, const QUuid& dataSourceUid,
41 const QString& DATA_SOURCE_NAME, DataSourceController* dc)
41 const QString& DATA_SOURCE_NAME, DataSourceController* dc)
42 {
42 {
43 auto result =
43 auto result =
44 std::make_unique<DataSourceItem>(DataSourceItemType::PRODUCT, metaData);
44 std::make_unique<DataSourceItem>(DataSourceItemType::PRODUCT, metaData);
45
45
46 // Adds plugin name to product metadata
46 // Adds plugin name to product metadata
47 result->setData(DataSourceItem::PLUGIN_DATA_KEY, DATA_SOURCE_NAME);
47 result->setData(DataSourceItem::PLUGIN_DATA_KEY, DATA_SOURCE_NAME);
48 result->setData(DataSourceItem::ID_DATA_KEY,
48 result->setData(DataSourceItem::ID_DATA_KEY,
49 metaData.value(DataSourceItem::NAME_DATA_KEY));
49 metaData.value(DataSourceItem::NAME_DATA_KEY));
50
50
51 auto productName = metaData.value(DataSourceItem::NAME_DATA_KEY).toString();
51 auto productName = metaData.value(DataSourceItem::NAME_DATA_KEY).toString();
52
52
53 // Add action to load product from DataSourceController
53 // Add action to load product from DataSourceController
54 result->addAction(std::make_unique<DataSourceItemAction>(
54 result->addAction(std::make_unique<DataSourceItemAction>(
55 QObject::tr("Load %1 product").arg(productName),
55 QObject::tr("Load %1 product").arg(productName),
56 [productName, dataSourceUid, dc](DataSourceItem& item) {
56 [productName, dataSourceUid, dc](DataSourceItem& item) {
57 if(dc) { dc->loadProductItem(dataSourceUid, item); }
57 if(dc) { dc->loadProductItem(dataSourceUid, item); }
58 }));
58 }));
59
59
60 return result;
60 return result;
61 }
61 }
62
62
63 class DataSourceController::DataSourceControllerPrivate
63 class DataSourceController::DataSourceControllerPrivate
64 {
64 {
65 public:
65 public:
66 QMutex m_WorkingMutex;
66 QMutex m_WorkingMutex;
67 /// Data sources registered
67 /// Data sources registered
68 QHash<QUuid, QString> m_DataSources;
68 QHash<QUuid, QString> m_DataSources;
69 /// Data sources structures
69 /// Data sources structures
70 std::map<QUuid, std::unique_ptr<DataSourceItem>> m_DataSourceItems;
70 std::map<QUuid, std::unique_ptr<DataSourceItem>> m_DataSourceItems;
71 /// Data providers registered
71 /// Data providers registered
72 /// @remarks Data providers are stored as shared_ptr as they can be sent to a
72 /// @remarks Data providers are stored as shared_ptr as they can be sent to a
73 /// variable and continue to live without necessarily the data source
73 /// variable and continue to live without necessarily the data source
74 /// controller
74 /// controller
75 std::map<QUuid, std::shared_ptr<IDataProvider>> m_DataProviders;
75 std::map<QUuid, std::shared_ptr<IDataProvider>> m_DataProviders;
76
76
77 // Search for the first datasource item matching the specified data
77 // Search for the first datasource item matching the specified data
78 DataSourceItem* findDataSourceItem(const QVariantHash& data)
78 DataSourceItem* findDataSourceItem(const QVariantHash& data)
79 {
79 {
80 DataSourceItem* sourceItem = nullptr;
80 DataSourceItem* sourceItem = nullptr;
81 for(const auto& item : m_DataSourceItems)
81 for(const auto& item : m_DataSourceItems)
82 {
82 {
83 sourceItem = item.second->findItem(data, true);
83 sourceItem = item.second->findItem(data, true);
84 if(sourceItem) { break; }
84 if(sourceItem) { break; }
85 }
85 }
86
86
87 return sourceItem;
87 return sourceItem;
88 }
88 }
89
89
90 // Search for the first datasource item matching the specified ID_DATA_KEY
90 // Search for the first datasource item matching the specified ID_DATA_KEY
91 DataSourceItem* findDataSourceItem(const QString& datasourceIdKey)
91 DataSourceItem* findDataSourceItem(const QString& datasourceIdKey)
92 {
92 {
93 DataSourceItem* sourceItem = nullptr;
93 DataSourceItem* sourceItem = nullptr;
94 for(const auto& item : m_DataSourceItems)
94 for(const auto& item : m_DataSourceItems)
95 {
95 {
96 sourceItem = item.second->findItem(datasourceIdKey, true);
96 sourceItem = item.second->findItem(datasourceIdKey, true);
97 if(sourceItem) { break; }
97 if(sourceItem) { break; }
98 }
98 }
99
99
100 return sourceItem;
100 return sourceItem;
101 }
101 }
102 };
102 };
103
103
104 DataSourceController::DataSourceController(QObject* parent)
104 DataSourceController::DataSourceController(QObject* parent)
105 : impl{spimpl::make_unique_impl<DataSourceControllerPrivate>()}
105 : impl{spimpl::make_unique_impl<DataSourceControllerPrivate>()}
106 {
106 {
107 qCDebug(LOG_DataSourceController())
107 qCDebug(LOG_DataSourceController())
108 << tr("DataSourceController construction") << QThread::currentThread();
108 << tr("DataSourceController construction") << QThread::currentThread();
109 }
109 }
110
110
111 DataSourceController::~DataSourceController()
111 DataSourceController::~DataSourceController()
112 {
112 {
113 qCDebug(LOG_DataSourceController())
113 qCDebug(LOG_DataSourceController())
114 << tr("DataSourceController destruction") << QThread::currentThread();
114 << tr("DataSourceController destruction") << QThread::currentThread();
115 this->waitForFinish();
115 this->waitForFinish();
116 }
116 }
117
117
118 QUuid DataSourceController::registerDataSource(
118 QUuid DataSourceController::registerDataSource(
119 const QString& dataSourceName) noexcept
119 const QString& dataSourceName) noexcept
120 {
120 {
121 auto dataSourceUid = QUuid::createUuid();
121 auto dataSourceUid = QUuid::createUuid();
122 impl->m_DataSources.insert(dataSourceUid, dataSourceName);
122 impl->m_DataSources.insert(dataSourceUid, dataSourceName);
123
123
124 return dataSourceUid;
124 return dataSourceUid;
125 }
125 }
126
126
127 void DataSourceController::registerProvider(IDataProvider *provider) noexcept
127 void DataSourceController::registerProvider(IDataProvider *provider) noexcept
128 {
128 {
129 impl->m_DataSources.insert(provider->id(), provider->name());
129 impl->m_DataSources.insert(provider->id(), provider->name());
130 impl->m_DataProviders.insert({provider->id(), std::unique_ptr<IDataProvider>{provider}});
130 impl->m_DataProviders.insert({provider->id(), std::unique_ptr<IDataProvider>{provider}});
131 // TODO rethink this, I don't get why we have to do this crap
131 // TODO rethink this, I don't get why we have to do this crap
132 // why do we need a root node for each provider
132 // why do we need a root node for each provider
133 setDataSourceItem(provider->id(),make_folder_item(provider->name()));
133 setDataSourceItem(provider->id(),make_folder_item(provider->name()));
134 }
134 }
135
135
136 void DataSourceController::setDataSourceItem(
136 void DataSourceController::setDataSourceItem(
137 const QUuid& dataSourceUid,
137 const QUuid& dataSourceUid,
138 std::unique_ptr<DataSourceItem> dataSourceItem) noexcept
138 std::unique_ptr<DataSourceItem> dataSourceItem) noexcept
139 {
139 {
140 if(!dataSourceItem)
140 if(!dataSourceItem)
141 {
141 {
142 qCWarning(LOG_DataSourceController())
142 qCWarning(LOG_DataSourceController())
143 << tr("Data source item can't be registered (null item)");
143 << tr("Data source item can't be registered (null item)");
144 return;
144 return;
145 }
145 }
146
146
147 if(impl->m_DataSources.contains(dataSourceUid))
147 if(impl->m_DataSources.contains(dataSourceUid))
148 {
148 {
149 // The data provider is implicitly converted to a shared_ptr
149 // The data provider is implicitly converted to a shared_ptr
150 impl->m_DataSourceItems.insert(
150 impl->m_DataSourceItems.insert(
151 std::make_pair(dataSourceUid, std::move(dataSourceItem)));
151 std::make_pair(dataSourceUid, std::move(dataSourceItem)));
152
152
153 // Retrieves the data source item to emit the signal with it
153 // Retrieves the data source item to emit the signal with it
154 auto it = impl->m_DataSourceItems.find(dataSourceUid);
154 auto it = impl->m_DataSourceItems.find(dataSourceUid);
155 if(it != impl->m_DataSourceItems.end())
155 if(it != impl->m_DataSourceItems.end())
156 { emit dataSourceItemSet(it->second.get()); }
156 { emit dataSourceItemSet(it->second.get()); }
157 }
157 }
158 else
158 else
159 {
159 {
160 qCWarning(LOG_DataSourceController())
160 qCWarning(LOG_DataSourceController())
161 << tr("Can't set data source item for uid %1 : no "
161 << tr("Can't set data source item for uid %1 : no "
162 "data source has been registered with the uid")
162 "data source has been registered with the uid")
163 .arg(dataSourceUid.toString());
163 .arg(dataSourceUid.toString());
164 }
164 }
165 }
165 }
166
166
167
167
168
168
169 void DataSourceController::setDataSourceItem(const QUuid& dataSourceUid, const QString& path,
169 void DataSourceController::setDataSourceItem(const QUuid& dataSourceUid, const QString& path,
170 const QMap<QString, QString> &metaData) noexcept
170 const QMap<QString, QString> &metaData) noexcept
171 {
171 {
172 if(auto it = impl->m_DataSourceItems.find(dataSourceUid);
172 if(auto it = impl->m_DataSourceItems.find(dataSourceUid);
173 it != impl->m_DataSourceItems.end())
173 it != impl->m_DataSourceItems.end())
174 {
174 {
175 auto path_list = path.split('/', QString::SkipEmptyParts);
175 auto path_list = path.split('/', QString::SkipEmptyParts);
176 auto name = *(std::cend(path_list) - 1);
176 auto name = *(std::cend(path_list) - 1);
177 auto path_item = make_path_items(
177 auto path_item = make_path_items(
178 std::cbegin(path_list), std::cend(path_list) - 1, it->second.get());
178 std::cbegin(path_list), std::cend(path_list) - 1, it->second.get());
179 QVariantHash meta_data{{DataSourceItem::NAME_DATA_KEY, name}};
179 QVariantHash meta_data{{DataSourceItem::NAME_DATA_KEY, name}};
180 for(auto& key : metaData.keys())
180 for(auto& key : metaData.keys())
181 {
181 {
182 meta_data[key] = metaData[key];
182 meta_data[key] = metaData[key];
183 }
183 }
184 path_item->appendChild(
184 path_item->appendChild(
185 make_product_item(meta_data, dataSourceUid, "test", this));
185 make_product_item(meta_data, dataSourceUid, "test", this));
186 emit dataSourceItemSet(it->second.get());
186 emit dataSourceItemSet(it->second.get());
187 }
187 }
188 }
188 }
189
189
190 void DataSourceController::setDataProvider(
190 void DataSourceController::setDataProvider(
191 const QUuid& dataSourceUid,
191 const QUuid& dataSourceUid,
192 std::unique_ptr<IDataProvider> dataProvider) noexcept
192 std::unique_ptr<IDataProvider> dataProvider) noexcept
193 {
193 {
194 if(impl->m_DataSources.contains(dataSourceUid))
194 if(impl->m_DataSources.contains(dataSourceUid))
195 {
195 {
196 impl->m_DataProviders.insert(
196 impl->m_DataProviders.insert(
197 std::make_pair(dataSourceUid, std::move(dataProvider)));
197 std::make_pair(dataSourceUid, std::move(dataProvider)));
198 }
198 }
199 else
199 else
200 {
200 {
201 qCWarning(LOG_DataSourceController())
201 qCWarning(LOG_DataSourceController())
202 << tr("Can't set data provider for uid %1 : no data "
202 << tr("Can't set data provider for uid %1 : no data "
203 "source has been registered with the uid")
203 "source has been registered with the uid")
204 .arg(dataSourceUid.toString());
204 .arg(dataSourceUid.toString());
205 }
205 }
206 }
206 }
207
207
208 void DataSourceController::loadProductItem(
208 void DataSourceController::loadProductItem(
209 const QUuid& dataSourceUid, const DataSourceItem& productItem) noexcept
209 const QUuid& dataSourceUid, const DataSourceItem& productItem) noexcept
210 {
210 {
211 if(productItem.type() == DataSourceItemType::PRODUCT ||
211 if(productItem.type() == DataSourceItemType::PRODUCT ||
212 productItem.type() == DataSourceItemType::COMPONENT)
212 productItem.type() == DataSourceItemType::COMPONENT)
213 {
213 {
214 /// Retrieves the data provider of the data source (if any)
214 /// Retrieves the data provider of the data source (if any)
215 auto it = impl->m_DataProviders.find(dataSourceUid);
215 auto it = impl->m_DataProviders.find(dataSourceUid);
216 auto dataProvider =
216 auto dataProvider =
217 (it != impl->m_DataProviders.end()) ? it->second : nullptr;
217 (it != impl->m_DataProviders.end()) ? it->second : nullptr;
218
218
219 emit createVariable(productItem.name(), productItem.data(), dataProvider);
219 emit createVariable(productItem.name(), productItem.data(), dataProvider);
220 }
220 }
221 else
221 else
222 {
222 {
223 qCWarning(LOG_DataSourceController())
223 qCWarning(LOG_DataSourceController())
224 << tr("Can't load an item that is not a product");
224 << tr("Can't load an item that is not a product");
225 }
225 }
226 }
226 }
227
227
228 QByteArray
228 QByteArray
229 DataSourceController::mimeDataForProductsData(const QVariantList& productsData)
229 DataSourceController::mimeDataForProductsData(const QVariantList& productsData)
230 {
230 {
231 QByteArray encodedData;
231 QByteArray encodedData;
232 QDataStream stream{&encodedData, QIODevice::WriteOnly};
232 QDataStream stream{&encodedData, QIODevice::WriteOnly};
233
233
234 stream << productsData;
234 stream << productsData;
235
235
236 return encodedData;
236 return encodedData;
237 }
237 }
238
238
239 QVariantList
239 QVariantList
240 DataSourceController::productsDataForMimeData(const QByteArray& mimeData)
240 DataSourceController::productsDataForMimeData(const QByteArray& mimeData)
241 {
241 {
242 QDataStream stream{mimeData};
242 QDataStream stream{mimeData};
243
243
244 QVariantList productList;
244 QVariantList productList;
245 stream >> productList;
245 stream >> productList;
246
246
247 return productList;
247 return productList;
248 }
248 }
249
249
250 void DataSourceController::initialize()
250 void DataSourceController::initialize()
251 {
251 {
252 qCDebug(LOG_DataSourceController())
252 qCDebug(LOG_DataSourceController())
253 << tr("DataSourceController init") << QThread::currentThread();
253 << tr("DataSourceController init") << QThread::currentThread();
254 impl->m_WorkingMutex.lock();
254 impl->m_WorkingMutex.lock();
255 qCDebug(LOG_DataSourceController()) << tr("DataSourceController init END");
255 qCDebug(LOG_DataSourceController()) << tr("DataSourceController init END");
256 }
256 }
257
257
258 void DataSourceController::finalize() { impl->m_WorkingMutex.unlock(); }
258 void DataSourceController::finalize() { impl->m_WorkingMutex.unlock(); }
259
259
260 void DataSourceController::requestVariableFromProductIdKey(
260 void DataSourceController::requestVariableFromProductIdKey(
261 const QString& datasourceIdKey)
261 const QString& datasourceIdKey)
262 {
262 {
263 auto sourceItem = impl->findDataSourceItem(datasourceIdKey);
263 auto sourceItem = impl->findDataSourceItem(datasourceIdKey);
264
264
265 if(sourceItem)
265 if(sourceItem)
266 {
266 {
267 auto sourceName = sourceItem->rootItem().name();
267 auto sourceName = sourceItem->rootItem().name();
268 auto sourceId = impl->m_DataSources.key(sourceName);
268 auto sourceId = impl->m_DataSources.key(sourceName);
269 loadProductItem(sourceId, *sourceItem);
269 loadProductItem(sourceId, *sourceItem);
270 }
270 }
271 else
271 else
272 {
272 {
273 qCWarning(LOG_DataSourceController())
273 qCWarning(LOG_DataSourceController())
274 << tr("requestVariable, product data not found");
274 << tr("requestVariable, product data not found");
275 }
275 }
276 }
276 }
277
277
278 void DataSourceController::requestVariable(const QVariantHash& productData)
278 void DataSourceController::requestVariable(const QVariantHash& productData)
279 {
279 {
280 auto sourceItem = impl->findDataSourceItem(productData);
280 auto sourceItem = impl->findDataSourceItem(productData);
281
281
282 if(sourceItem)
282 if(sourceItem)
283 {
283 {
284 auto sourceName = sourceItem->rootItem().name();
284 auto sourceName = sourceItem->rootItem().name();
285 auto sourceId = impl->m_DataSources.key(sourceName);
285 auto sourceId = impl->m_DataSources.key(sourceName);
286 loadProductItem(sourceId, *sourceItem);
286 loadProductItem(sourceId, *sourceItem);
287 }
287 }
288 else
288 else
289 {
289 {
290 qCWarning(LOG_DataSourceController())
290 qCWarning(LOG_DataSourceController())
291 << tr("requestVariable, product data not found");
291 << tr("requestVariable, product data not found");
292 }
292 }
293 }
293 }
294
294
295 void DataSourceController::waitForFinish()
295 void DataSourceController::waitForFinish()
296 {
296 {
297 QMutexLocker locker{&impl->m_WorkingMutex};
297 QMutexLocker locker{&impl->m_WorkingMutex};
298 }
298 }
@@ -1,448 +1,448
1 #include "Variable/VariableController2.h"
1 #include "Variable/VariableController2.h"
2
2
3 #include "Variable/VariableSynchronizationGroup2.h"
3 #include "Variable/VariableSynchronizationGroup2.h"
4
4
5 #include <Common/containers.h>
5 #include <containers/algorithms.hpp>
6 #include <Common/debug.h>
6 #include <Common/debug.h>
7 #include <Data/DataProviderParameters.h>
7 #include <Data/DataProviderParameters.h>
8 #include <Data/DateTimeRange.h>
8 #include <Data/DateTimeRange.h>
9 #include <Data/DateTimeRangeHelper.h>
9 #include <Data/DateTimeRangeHelper.h>
10 #include <QCoreApplication>
10 #include <QCoreApplication>
11 #include <QDataStream>
11 #include <QDataStream>
12 #include <QObject>
12 #include <QObject>
13 #include <QQueue>
13 #include <QQueue>
14 #include <QRunnable>
14 #include <QRunnable>
15 #include <QThreadPool>
15 #include <QThreadPool>
16 #include <Variable/private/VCTransaction.h>
16 #include <Variable/private/VCTransaction.h>
17
17
18 class VariableController2::VariableController2Private
18 class VariableController2::VariableController2Private
19 {
19 {
20 struct threadSafeVaraiblesMaps
20 struct threadSafeVaraiblesMaps
21 {
21 {
22 inline void
22 inline void
23 addVariable(const std::shared_ptr<Variable2>& variable,
23 addVariable(const std::shared_ptr<Variable2>& variable,
24 const std::shared_ptr<IDataProvider>& provider,
24 const std::shared_ptr<IDataProvider>& provider,
25 const std::shared_ptr<VariableSynchronizationGroup2>&
25 const std::shared_ptr<VariableSynchronizationGroup2>&
26 synchronizationGroup)
26 synchronizationGroup)
27 {
27 {
28 QWriteLocker lock{&_lock};
28 QWriteLocker lock{&_lock};
29 _variables[*variable] = variable;
29 _variables[*variable] = variable;
30 _providers[*variable] = provider;
30 _providers[*variable] = provider;
31 _synchronizationGroups[*variable] = synchronizationGroup;
31 _synchronizationGroups[*variable] = synchronizationGroup;
32 }
32 }
33
33
34 inline void removeVariable(const std::shared_ptr<Variable2>& variable)
34 inline void removeVariable(const std::shared_ptr<Variable2>& variable)
35 {
35 {
36 QWriteLocker lock{&_lock};
36 QWriteLocker lock{&_lock};
37 _variables.erase(*variable);
37 _variables.erase(*variable);
38 _providers.remove(*variable);
38 _providers.remove(*variable);
39 _synchronizationGroups.remove(*variable);
39 _synchronizationGroups.remove(*variable);
40 }
40 }
41
41
42 inline void
42 inline void
43 synchronize(const std::shared_ptr<Variable2>& variable,
43 synchronize(const std::shared_ptr<Variable2>& variable,
44 const std::optional<std::shared_ptr<Variable2>>& with)
44 const std::optional<std::shared_ptr<Variable2>>& with)
45 {
45 {
46 QWriteLocker lock{&_lock};
46 QWriteLocker lock{&_lock};
47 if(with.has_value())
47 if(with.has_value())
48 {
48 {
49 auto newGroup = _synchronizationGroups[*with.value()];
49 auto newGroup = _synchronizationGroups[*with.value()];
50 newGroup->addVariable(*variable);
50 newGroup->addVariable(*variable);
51 _synchronizationGroups[*variable] = newGroup;
51 _synchronizationGroups[*variable] = newGroup;
52 }
52 }
53 else
53 else
54 {
54 {
55 _synchronizationGroups[*variable] =
55 _synchronizationGroups[*variable] =
56 std::make_shared<VariableSynchronizationGroup2>(*variable);
56 std::make_shared<VariableSynchronizationGroup2>(*variable);
57 }
57 }
58 }
58 }
59
59
60 inline std::shared_ptr<Variable2> variable(QUuid variable)
60 inline std::shared_ptr<Variable2> variable(QUuid variable)
61 {
61 {
62 QReadLocker lock{&_lock};
62 QReadLocker lock{&_lock};
63 auto it = _variables.find(variable);
63 auto it = _variables.find(variable);
64 #if __cplusplus > 201703L
64 #if __cplusplus > 201703L
65 [[unlikely]]
65 [[unlikely]]
66 #endif
66 #endif
67 if(it == _variables.end())
67 if(it == _variables.end())
68 SCIQLOP_ERROR(threadSafeVaraiblesMaps, "Unknown Variable");
68 SCIQLOP_ERROR(threadSafeVaraiblesMaps, "Unknown Variable");
69 return (*it).second;
69 return (*it).second;
70 }
70 }
71
71
72 inline std::shared_ptr<Variable2> variable(int index)
72 inline std::shared_ptr<Variable2> variable(int index)
73 {
73 {
74 QReadLocker lock{&_lock};
74 QReadLocker lock{&_lock};
75 #if __cplusplus > 201703L
75 #if __cplusplus > 201703L
76 [[unlikely]]
76 [[unlikely]]
77 #endif
77 #endif
78 if(!_variables.size() > index)
78 if(!(_variables.size() > static_cast<unsigned int>(index)))
79 SCIQLOP_ERROR(threadSafeVaraiblesMaps, "Index is out of bounds");
79 SCIQLOP_ERROR(threadSafeVaraiblesMaps, "Index is out of bounds");
80 auto it = _variables.cbegin();
80 auto it = _variables.cbegin();
81 while(index != 0)
81 while(index != 0)
82 {
82 {
83 index -= 1;
83 index -= 1;
84 it++;
84 it++;
85 }
85 }
86 return (*(it)).second;
86 return (*(it)).second;
87 }
87 }
88
88
89 inline const std::vector<std::shared_ptr<Variable2>> variables()
89 inline const std::vector<std::shared_ptr<Variable2>> variables()
90 {
90 {
91 std::vector<std::shared_ptr<Variable2>> vars;
91 std::vector<std::shared_ptr<Variable2>> vars;
92 QReadLocker lock{&_lock};
92 QReadLocker lock{&_lock};
93 for(const auto& [id, var] : _variables)
93 for(const auto& [id, var] : _variables)
94 {
94 {
95 vars.push_back(var);
95 vars.push_back(var);
96 }
96 }
97 return vars;
97 return vars;
98 }
98 }
99
99
100 inline std::shared_ptr<IDataProvider> provider(QUuid variable)
100 inline std::shared_ptr<IDataProvider> provider(QUuid variable)
101 {
101 {
102 QReadLocker lock{&_lock};
102 QReadLocker lock{&_lock};
103 #if __cplusplus > 201703L
103 #if __cplusplus > 201703L
104 [[unlikely]]
104 [[unlikely]]
105 #endif
105 #endif
106 if(!_providers.contains(variable))
106 if(!_providers.contains(variable))
107 SCIQLOP_ERROR(threadSafeVaraiblesMaps, "Unknown Variable");
107 SCIQLOP_ERROR(threadSafeVaraiblesMaps, "Unknown Variable");
108 return _providers[variable];
108 return _providers[variable];
109 }
109 }
110
110
111 inline std::shared_ptr<VariableSynchronizationGroup2> group(QUuid variable)
111 inline std::shared_ptr<VariableSynchronizationGroup2> group(QUuid variable)
112 {
112 {
113 QReadLocker lock{&_lock};
113 QReadLocker lock{&_lock};
114 #if __cplusplus > 201703L
114 #if __cplusplus > 201703L
115 [[unlikely]]
115 [[unlikely]]
116 #endif
116 #endif
117 if(!_synchronizationGroups.contains(variable))
117 if(!_synchronizationGroups.contains(variable))
118 SCIQLOP_ERROR(threadSafeVaraiblesMaps, "Unknown Variable");
118 SCIQLOP_ERROR(threadSafeVaraiblesMaps, "Unknown Variable");
119 return _synchronizationGroups[variable];
119 return _synchronizationGroups[variable];
120 }
120 }
121
121
122 inline bool has(const std::shared_ptr<Variable2>& variable)
122 inline bool has(const std::shared_ptr<Variable2>& variable)
123 {
123 {
124 QReadLocker lock{&_lock};
124 QReadLocker lock{&_lock};
125 return _variables.find(*variable) == _variables.end();
125 return _variables.find(*variable) == _variables.end();
126 }
126 }
127
127
128 private:
128 private:
129 std::map<QUuid, std::shared_ptr<Variable2>> _variables;
129 std::map<QUuid, std::shared_ptr<Variable2>> _variables;
130 QMap<QUuid, std::shared_ptr<IDataProvider>> _providers;
130 QMap<QUuid, std::shared_ptr<IDataProvider>> _providers;
131 QMap<QUuid, std::shared_ptr<VariableSynchronizationGroup2>>
131 QMap<QUuid, std::shared_ptr<VariableSynchronizationGroup2>>
132 _synchronizationGroups;
132 _synchronizationGroups;
133 QReadWriteLock _lock{QReadWriteLock::Recursive};
133 QReadWriteLock _lock{QReadWriteLock::Recursive};
134 } _maps;
134 } _maps;
135 std::vector<QUuid> _variablesToRemove;
135 std::vector<QUuid> _variablesToRemove;
136 QThreadPool* _ThreadPool;
136 QThreadPool* _ThreadPool;
137 VCTransactionsQueues _transactions;
137 VCTransactionsQueues _transactions;
138
138
139 void _transactionComplete(QUuid group,
139 void _transactionComplete(QUuid group,
140 std::shared_ptr<VCTransaction> transaction)
140 std::shared_ptr<VCTransaction> transaction)
141 {
141 {
142 if(transaction->done()) { _transactions.complete(group); }
142 if(transaction->done()) { _transactions.complete(group); }
143 this->_processTransactions();
143 this->_processTransactions();
144 }
144 }
145
145
146 void _cleanupVariables()
146 void _cleanupVariables()
147 {
147 {
148 for(auto id : _variablesToRemove)
148 for(auto id : _variablesToRemove)
149 {
149 {
150 auto v = this->variable(id);
150 auto v = this->variable(id);
151 if(!hasPendingTransactions(v))
151 if(!hasPendingTransactions(v))
152 {
152 {
153 _variablesToRemove.erase(std::remove(_variablesToRemove.begin(),
153 _variablesToRemove.erase(std::remove(_variablesToRemove.begin(),
154 _variablesToRemove.end(), id),
154 _variablesToRemove.end(), id),
155 _variablesToRemove.end());
155 _variablesToRemove.end());
156 this->deleteVariable(v);
156 this->deleteVariable(v);
157 }
157 }
158 }
158 }
159 }
159 }
160
160
161 void _processTransactions(bool fragmented = false)
161 void _processTransactions(bool fragmented = false)
162 {
162 {
163 auto nextTransactions = _transactions.nextTransactions();
163 auto nextTransactions = _transactions.nextTransactions();
164 auto pendingTransactions = _transactions.pendingTransactions();
164 auto pendingTransactions = _transactions.pendingTransactions();
165 for(auto [groupID, newTransaction] : nextTransactions)
165 for(auto [groupID, newTransaction] : nextTransactions)
166 {
166 {
167 if(newTransaction.has_value() &&
167 if(newTransaction.has_value() &&
168 !pendingTransactions[groupID].has_value())
168 !pendingTransactions[groupID].has_value())
169 {
169 {
170 _transactions.start(groupID);
170 _transactions.start(groupID);
171 auto refVar = _maps.variable(newTransaction.value()->refVar);
171 auto refVar = _maps.variable(newTransaction.value()->refVar);
172 auto ranges =
172 auto ranges =
173 _computeAllRangesInGroup(refVar, newTransaction.value()->range);
173 _computeAllRangesInGroup(refVar, newTransaction.value()->range);
174 for(auto const& [ID, range] : ranges)
174 for(auto const& [ID, range] : ranges)
175 {
175 {
176 auto provider = _maps.provider(ID);
176 auto provider = _maps.provider(ID);
177 auto variable = _maps.variable(ID);
177 auto variable = _maps.variable(ID);
178 if(fragmented)
178 if(fragmented)
179 {
179 {
180 auto missingRanges = _computeMissingRanges(variable, range);
180 auto missingRanges = _computeMissingRanges(variable, range);
181
181
182 auto exe =
182 auto exe =
183 new TransactionExe(variable, provider, missingRanges, range);
183 new TransactionExe(variable, provider, missingRanges, range);
184 QObject::connect(
184 QObject::connect(
185 exe, &TransactionExe::transactionComplete,
185 exe, &TransactionExe::transactionComplete,
186 [groupID = groupID, transaction = newTransaction.value(),
186 [groupID = groupID, transaction = newTransaction.value(),
187 this]() { this->_transactionComplete(groupID, transaction); });
187 this]() { this->_transactionComplete(groupID, transaction); });
188 _ThreadPool->start(exe);
188 _ThreadPool->start(exe);
189 }
189 }
190 else
190 else
191 {
191 {
192 auto exe = new TransactionExe(variable, provider, {range}, range);
192 auto exe = new TransactionExe(variable, provider, {range}, range);
193 QObject::connect(
193 QObject::connect(
194 exe, &TransactionExe::transactionComplete,
194 exe, &TransactionExe::transactionComplete,
195 [groupID = groupID, transaction = newTransaction.value(),
195 [groupID = groupID, transaction = newTransaction.value(),
196 this]() { this->_transactionComplete(groupID, transaction); });
196 this]() { this->_transactionComplete(groupID, transaction); });
197 _ThreadPool->start(exe);
197 _ThreadPool->start(exe);
198 }
198 }
199 }
199 }
200 }
200 }
201 }
201 }
202 // after each transaction update we get a new distribution of idle and
202 // after each transaction update we get a new distribution of idle and
203 // working variables so we can delete variables which are waiting to be
203 // working variables so we can delete variables which are waiting to be
204 // deleted if they are now idle
204 // deleted if they are now idle
205 _cleanupVariables();
205 _cleanupVariables();
206 }
206 }
207
207
208 std::map<QUuid, DateTimeRange>
208 std::map<QUuid, DateTimeRange>
209 _computeAllRangesInGroup(const std::shared_ptr<Variable2>& refVar,
209 _computeAllRangesInGroup(const std::shared_ptr<Variable2>& refVar,
210 DateTimeRange r)
210 DateTimeRange r)
211 {
211 {
212 std::map<QUuid, DateTimeRange> ranges;
212 std::map<QUuid, DateTimeRange> ranges;
213 if(!DateTimeRangeHelper::hasnan(r))
213 if(!DateTimeRangeHelper::hasnan(r))
214 {
214 {
215 auto group = _maps.group(*refVar);
215 auto group = _maps.group(*refVar);
216 if(auto transformation =
216 if(auto transformation =
217 DateTimeRangeHelper::computeTransformation(refVar->range(), r);
217 DateTimeRangeHelper::computeTransformation(refVar->range(), r);
218 transformation.has_value())
218 transformation.has_value())
219 {
219 {
220 for(auto varId : group->variables())
220 for(auto varId : group->variables())
221 {
221 {
222 auto var = _maps.variable(varId);
222 auto var = _maps.variable(varId);
223 auto newRange = var->range().transform(transformation.value());
223 auto newRange = var->range().transform(transformation.value());
224 ranges[varId] = newRange;
224 ranges[varId] = newRange;
225 }
225 }
226 }
226 }
227 else // force new range to all variables -> may be weird if more than one
227 else // force new range to all variables -> may be weird if more than one
228 // var in the group
228 // var in the group
229 // TODO ensure that there is no side effects
229 // TODO ensure that there is no side effects
230 {
230 {
231 for(auto varId : group->variables())
231 for(auto varId : group->variables())
232 {
232 {
233 auto var = _maps.variable(varId);
233 auto var = _maps.variable(varId);
234 ranges[varId] = r;
234 ranges[varId] = r;
235 }
235 }
236 }
236 }
237 }
237 }
238 else
238 else
239 {
239 {
240 SCIQLOP_ERROR(VariableController2Private, "Invalid range containing NaN");
240 SCIQLOP_ERROR(VariableController2Private, "Invalid range containing NaN");
241 }
241 }
242 return ranges;
242 return ranges;
243 }
243 }
244
244
245 std::vector<DateTimeRange>
245 std::vector<DateTimeRange>
246 _computeMissingRanges(const std::shared_ptr<Variable2>& var, DateTimeRange r)
246 _computeMissingRanges(const std::shared_ptr<Variable2>& var, DateTimeRange r)
247 {
247 {
248 return r - var->range();
248 return r - var->range();
249 }
249 }
250
250
251 void _changeRange(QUuid id, DateTimeRange r)
251 void _changeRange(QUuid id, DateTimeRange r)
252 {
252 {
253 _changeRange(_maps.variable(id), r);
253 _changeRange(_maps.variable(id), r);
254 }
254 }
255 void _changeRange(const std::shared_ptr<Variable2>& var, DateTimeRange r)
255 void _changeRange(const std::shared_ptr<Variable2>& var, DateTimeRange r)
256 {
256 {
257 auto provider = _maps.provider(*var);
257 auto provider = _maps.provider(*var);
258 auto missingRanges = _computeMissingRanges(var, r);
258 auto missingRanges = _computeMissingRanges(var, r);
259 std::vector<TimeSeries::ITimeSerie*> data;
259 std::vector<TimeSeries::ITimeSerie*> data;
260 for(auto range : missingRanges)
260 for(auto range : missingRanges)
261 {
261 {
262 data.push_back(
262 data.push_back(
263 provider->getData(DataProviderParameters{{range}, var->metadata()}));
263 provider->getData(DataProviderParameters{{range}, var->metadata()}));
264 }
264 }
265 data.push_back(var->data().get()); // might be smarter
265 data.push_back(var->data().get()); // might be smarter
266 var->setData(data, r, true);
266 var->setData(data, r, true);
267 std::for_each(std::begin(data), std::end(data), [](auto ts) { delete ts; });
267 std::for_each(std::begin(data), std::end(data), [](auto ts) { delete ts; });
268 }
268 }
269
269
270 public:
270 public:
271 VariableController2Private(QObject* parent = Q_NULLPTR)
271 VariableController2Private(QObject* parent = Q_NULLPTR)
272 {
272 {
273 Q_UNUSED(parent);
273 Q_UNUSED(parent);
274 this->_ThreadPool = new QThreadPool();
274 this->_ThreadPool = new QThreadPool();
275 this->_ThreadPool->setMaxThreadCount(32);
275 this->_ThreadPool->setMaxThreadCount(32);
276 }
276 }
277
277
278 /*
278 /*
279 * This dtor has to like this even if this is ugly, because default dtor would
279 * This dtor has to like this even if this is ugly, because default dtor would
280 * rely on declaration order to destruct members and that would always lead to
280 * rely on declaration order to destruct members and that would always lead to
281 * regressions when modifying class members
281 * regressions when modifying class members
282 */
282 */
283 ~VariableController2Private() { delete this->_ThreadPool; }
283 ~VariableController2Private() { delete this->_ThreadPool; }
284
284
285 std::shared_ptr<Variable2>
285 std::shared_ptr<Variable2>
286 createVariable(const QString& name, const QVariantHash& metadata,
286 createVariable(const QString& name, const QVariantHash& metadata,
287 std::shared_ptr<IDataProvider> provider)
287 std::shared_ptr<IDataProvider> provider)
288 {
288 {
289 auto newVar = std::make_shared<Variable2>(name, metadata);
289 auto newVar = std::make_shared<Variable2>(name, metadata);
290 auto group = std::make_shared<VariableSynchronizationGroup2>(newVar->ID());
290 auto group = std::make_shared<VariableSynchronizationGroup2>(newVar->ID());
291 _maps.addVariable(newVar, std::move(provider), group);
291 _maps.addVariable(newVar, std::move(provider), group);
292 this->_transactions.addEntry(*group);
292 this->_transactions.addEntry(*group);
293 return newVar;
293 return newVar;
294 }
294 }
295
295
296 std::shared_ptr<Variable2> variable(QUuid ID) { return _maps.variable(ID); }
296 std::shared_ptr<Variable2> variable(QUuid ID) { return _maps.variable(ID); }
297
297
298 std::shared_ptr<Variable2> variable(int index)
298 std::shared_ptr<Variable2> variable(int index)
299 {
299 {
300 return _maps.variable(index);
300 return _maps.variable(index);
301 }
301 }
302
302
303 std::shared_ptr<Variable2>
303 std::shared_ptr<Variable2>
304 cloneVariable(const std::shared_ptr<Variable2>& variable)
304 cloneVariable(const std::shared_ptr<Variable2>& variable)
305 {
305 {
306 auto newVar = variable->clone();
306 auto newVar = variable->clone();
307 _maps.synchronize(newVar, std::nullopt);
307 _maps.synchronize(newVar, std::nullopt);
308 _maps.addVariable(newVar, _maps.provider(*variable), _maps.group(*newVar));
308 _maps.addVariable(newVar, _maps.provider(*variable), _maps.group(*newVar));
309 this->_transactions.addEntry(*_maps.group(*newVar));
309 this->_transactions.addEntry(*_maps.group(*newVar));
310 return newVar;
310 return newVar;
311 }
311 }
312
312
313 bool hasPendingTransactions(const std::shared_ptr<Variable2>& variable)
313 bool hasPendingTransactions(const std::shared_ptr<Variable2>& variable)
314 {
314 {
315 return _transactions.active(*_maps.group(*variable));
315 return _transactions.active(*_maps.group(*variable));
316 }
316 }
317
317
318 bool hasPendingTransactions()
318 bool hasPendingTransactions()
319 {
319 {
320 bool has = false;
320 bool has = false;
321 for(const auto& var : _maps.variables())
321 for(const auto& var : _maps.variables())
322 {
322 {
323 has |= _transactions.active(*_maps.group(*var));
323 has |= _transactions.active(*_maps.group(*var));
324 }
324 }
325 return has;
325 return has;
326 }
326 }
327
327
328 void deleteVariable(const std::shared_ptr<Variable2>& variable)
328 void deleteVariable(const std::shared_ptr<Variable2>& variable)
329 {
329 {
330 if(!hasPendingTransactions(variable))
330 if(!hasPendingTransactions(variable))
331 _maps.removeVariable(variable);
331 _maps.removeVariable(variable);
332 else
332 else
333 _variablesToRemove.push_back(variable->ID());
333 _variablesToRemove.push_back(variable->ID());
334 }
334 }
335
335
336 void asyncChangeRange(const std::shared_ptr<Variable2>& variable,
336 void asyncChangeRange(const std::shared_ptr<Variable2>& variable,
337 const DateTimeRange& r)
337 const DateTimeRange& r)
338 {
338 {
339 if(!DateTimeRangeHelper::hasnan(r))
339 if(!DateTimeRangeHelper::hasnan(r))
340 {
340 {
341 auto group = _maps.group(*variable);
341 auto group = _maps.group(*variable);
342 // Just overwrite next transaction
342 // Just overwrite next transaction
343 {
343 {
344 _transactions.enqueue(*group,
344 _transactions.enqueue(*group,
345 std::make_shared<VCTransaction>(
345 std::make_shared<VCTransaction>(
346 variable->ID(), r,
346 variable->ID(), r,
347 static_cast<int>(group->variables().size())));
347 static_cast<int>(group->variables().size())));
348 }
348 }
349 _processTransactions();
349 _processTransactions();
350 }
350 }
351 else
351 else
352 {
352 {
353 SCIQLOP_ERROR(VariableController2Private, "Invalid range containing NaN");
353 SCIQLOP_ERROR(VariableController2Private, "Invalid range containing NaN");
354 }
354 }
355 }
355 }
356
356
357 void changeRange(const std::shared_ptr<Variable2>& variable, DateTimeRange r)
357 void changeRange(const std::shared_ptr<Variable2>& variable, DateTimeRange r)
358 {
358 {
359 asyncChangeRange(variable, r);
359 asyncChangeRange(variable, r);
360 while(hasPendingTransactions(variable))
360 while(hasPendingTransactions(variable))
361 {
361 {
362 QCoreApplication::processEvents();
362 QCoreApplication::processEvents();
363 }
363 }
364 }
364 }
365
365
366 inline void synchronize(const std::shared_ptr<Variable2>& var,
366 inline void synchronize(const std::shared_ptr<Variable2>& var,
367 const std::shared_ptr<Variable2>& with)
367 const std::shared_ptr<Variable2>& with)
368 {
368 {
369 _maps.synchronize(var, with);
369 _maps.synchronize(var, with);
370 }
370 }
371
371
372 inline const std::vector<std::shared_ptr<Variable2>> variables()
372 inline const std::vector<std::shared_ptr<Variable2>> variables()
373 {
373 {
374 return _maps.variables();
374 return _maps.variables();
375 }
375 }
376 };
376 };
377
377
378 VariableController2::VariableController2()
378 VariableController2::VariableController2()
379 : impl{spimpl::make_unique_impl<VariableController2Private>()}
379 : impl{spimpl::make_unique_impl<VariableController2Private>()}
380 {}
380 {}
381
381
382 std::shared_ptr<Variable2> VariableController2::createVariable(
382 std::shared_ptr<Variable2> VariableController2::createVariable(
383 const QString& name, const QVariantHash& metadata,
383 const QString& name, const QVariantHash& metadata,
384 const std::shared_ptr<IDataProvider>& provider, const DateTimeRange& range)
384 const std::shared_ptr<IDataProvider>& provider, const DateTimeRange& range)
385 {
385 {
386 auto var = impl->createVariable(name, metadata, provider);
386 auto var = impl->createVariable(name, metadata, provider);
387 var->setRange(range); // even with no data this is it's range
387 var->setRange(range); // even with no data this is it's range
388 if(!DateTimeRangeHelper::hasnan(range))
388 if(!DateTimeRangeHelper::hasnan(range))
389 impl->asyncChangeRange(var, range);
389 impl->asyncChangeRange(var, range);
390 else
390 else
391 SCIQLOP_ERROR(VariableController2, "Creating a variable with default "
391 SCIQLOP_ERROR(VariableController2, "Creating a variable with default "
392 "constructed DateTimeRange is an error");
392 "constructed DateTimeRange is an error");
393 emit variableAdded(var);
393 emit variableAdded(var);
394 return var;
394 return var;
395 }
395 }
396
396
397 std::shared_ptr<Variable2>
397 std::shared_ptr<Variable2>
398 VariableController2::cloneVariable(const std::shared_ptr<Variable2>& variable)
398 VariableController2::cloneVariable(const std::shared_ptr<Variable2>& variable)
399 {
399 {
400 return impl->cloneVariable(variable);
400 return impl->cloneVariable(variable);
401 }
401 }
402
402
403 void VariableController2::deleteVariable(
403 void VariableController2::deleteVariable(
404 const std::shared_ptr<Variable2>& variable)
404 const std::shared_ptr<Variable2>& variable)
405 {
405 {
406 impl->deleteVariable(variable);
406 impl->deleteVariable(variable);
407 emit variableDeleted(variable);
407 emit variableDeleted(variable);
408 }
408 }
409
409
410 void VariableController2::changeRange(
410 void VariableController2::changeRange(
411 const std::shared_ptr<Variable2>& variable, const DateTimeRange& r)
411 const std::shared_ptr<Variable2>& variable, const DateTimeRange& r)
412 {
412 {
413 impl->changeRange(variable, r);
413 impl->changeRange(variable, r);
414 }
414 }
415
415
416 void VariableController2::asyncChangeRange(
416 void VariableController2::asyncChangeRange(
417 const std::shared_ptr<Variable2>& variable, const DateTimeRange& r)
417 const std::shared_ptr<Variable2>& variable, const DateTimeRange& r)
418 {
418 {
419 impl->asyncChangeRange(variable, r);
419 impl->asyncChangeRange(variable, r);
420 }
420 }
421
421
422 const std::vector<std::shared_ptr<Variable2>> VariableController2::variables()
422 const std::vector<std::shared_ptr<Variable2>> VariableController2::variables()
423 {
423 {
424 return impl->variables();
424 return impl->variables();
425 }
425 }
426
426
427 bool VariableController2::isReady(const std::shared_ptr<Variable2>& variable)
427 bool VariableController2::isReady(const std::shared_ptr<Variable2>& variable)
428 {
428 {
429 return !impl->hasPendingTransactions(variable);
429 return !impl->hasPendingTransactions(variable);
430 }
430 }
431
431
432 bool VariableController2::isReady() { return !impl->hasPendingTransactions(); }
432 bool VariableController2::isReady() { return !impl->hasPendingTransactions(); }
433
433
434 void VariableController2::synchronize(const std::shared_ptr<Variable2>& var,
434 void VariableController2::synchronize(const std::shared_ptr<Variable2>& var,
435 const std::shared_ptr<Variable2>& with)
435 const std::shared_ptr<Variable2>& with)
436 {
436 {
437 impl->synchronize(var, with);
437 impl->synchronize(var, with);
438 }
438 }
439
439
440 const std::vector<std::shared_ptr<Variable2>>
440 const std::vector<std::shared_ptr<Variable2>>
441 VariableController2::variables(const std::vector<QUuid>& ids)
441 VariableController2::variables(const std::vector<QUuid>& ids)
442 {
442 {
443 std::vector<std::shared_ptr<Variable2>> variables;
443 std::vector<std::shared_ptr<Variable2>> variables;
444 std::transform(std::cbegin(ids), std::cend(ids),
444 std::transform(std::cbegin(ids), std::cend(ids),
445 std::back_inserter(variables),
445 std::back_inserter(variables),
446 [this](const auto& id) { return impl->variable(id); });
446 [this](const auto& id) { return impl->variable(id); });
447 return variables;
447 return variables;
448 }
448 }
@@ -1,278 +1,279
1 #include <Common/DateUtils.h>
1 #include <Common/DateUtils.h>
2 #include <Common/MimeTypesDef.h>
2 #include <Common/MimeTypesDef.h>
3 #include <Common/StringUtils.h>
3 #include <cpp_utils_qt/cpp_utils_qt.hpp>
4 #include <Common/containers.h>
4 #include <strings/algorithms.hpp>
5 #include <containers/algorithms.hpp>
5 #include <DataSource/DataSourceController.h>
6 #include <DataSource/DataSourceController.h>
6 #include <QMimeData>
7 #include <QMimeData>
7 #include <QSize>
8 #include <QSize>
8 #include <QTimer>
9 #include <QTimer>
9 #include <Time/TimeController.h>
10 #include <Time/TimeController.h>
10 #include <Variable/Variable2.h>
11 #include <Variable/Variable2.h>
11 #include <Variable/VariableController2.h>
12 #include <Variable/VariableController2.h>
12 #include <Variable/VariableModel2.h>
13 #include <Variable/VariableModel2.h>
13 #include <unordered_map>
14 #include <unordered_map>
14
15
15 namespace
16 namespace
16 {
17 {
17 // Column indexes
18 // Column indexes
18 const auto NAME_COLUMN = 0;
19 const auto NAME_COLUMN = 0;
19 const auto TSTART_COLUMN = 1;
20 const auto TSTART_COLUMN = 1;
20 const auto TEND_COLUMN = 2;
21 const auto TEND_COLUMN = 2;
21 const auto NBPOINTS_COLUMN = 3;
22 const auto NBPOINTS_COLUMN = 3;
22 const auto UNIT_COLUMN = 4;
23 const auto UNIT_COLUMN = 4;
23 const auto MISSION_COLUMN = 5;
24 const auto MISSION_COLUMN = 5;
24 const auto PLUGIN_COLUMN = 6;
25 const auto PLUGIN_COLUMN = 6;
25 const auto NB_COLUMNS = 7;
26 const auto NB_COLUMNS = 7;
26
27
27 // Column properties
28 // Column properties
28 const auto DEFAULT_HEIGHT = 25;
29 const auto DEFAULT_HEIGHT = 25;
29 const auto DEFAULT_WIDTH = 100;
30 const auto DEFAULT_WIDTH = 100;
30
31
31 struct ColumnProperties
32 struct ColumnProperties
32 {
33 {
33 ColumnProperties(const QString& name = {}, int width = DEFAULT_WIDTH,
34 ColumnProperties(const QString& name = {}, int width = DEFAULT_WIDTH,
34 int height = DEFAULT_HEIGHT)
35 int height = DEFAULT_HEIGHT)
35 : m_Name{name}, m_Width{width}, m_Height{height}
36 : m_Name{name}, m_Width{width}, m_Height{height}
36 {}
37 {}
37
38
38 QString m_Name;
39 QString m_Name;
39 int m_Width;
40 int m_Width;
40 int m_Height;
41 int m_Height;
41 };
42 };
42
43
43 const auto COLUMN_PROPERTIES = QHash<int, ColumnProperties>{
44 const auto COLUMN_PROPERTIES = QHash<int, ColumnProperties>{
44 {NAME_COLUMN, {QObject::tr("Name")}},
45 {NAME_COLUMN, {QObject::tr("Name")}},
45 {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
46 {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
46 {TEND_COLUMN, {QObject::tr("tEnd"), 180}},
47 {TEND_COLUMN, {QObject::tr("tEnd"), 180}},
47 {NBPOINTS_COLUMN, {QObject::tr("Nb points")}},
48 {NBPOINTS_COLUMN, {QObject::tr("Nb points")}},
48 {UNIT_COLUMN, {QObject::tr("Unit")}},
49 {UNIT_COLUMN, {QObject::tr("Unit")}},
49 {MISSION_COLUMN, {QObject::tr("Mission")}},
50 {MISSION_COLUMN, {QObject::tr("Mission")}},
50 {PLUGIN_COLUMN, {QObject::tr("Plugin")}}};
51 {PLUGIN_COLUMN, {QObject::tr("Plugin")}}};
51
52
52 QString uniqueName(const QString& defaultName,
53 QString uniqueName(const QString& defaultName,
53 const std::vector<std::shared_ptr<Variable2>>& variables)
54 const std::vector<std::shared_ptr<Variable2>>& variables)
54 {
55 {
55 auto forbiddenNames = std::vector<QString>(variables.size());
56 auto forbiddenNames = std::vector<QString>(variables.size());
56 std::transform(variables.cbegin(), variables.cend(), forbiddenNames.begin(),
57 std::transform(variables.cbegin(), variables.cend(), forbiddenNames.begin(),
57 [](const auto& variable) { return variable->name(); });
58 [](const auto& variable) { return variable->name(); });
58 auto uniqueName = StringUtils::uniqueName(defaultName, forbiddenNames);
59 auto uniqueName = cpp_utils::strings::make_unique_name(defaultName, forbiddenNames);
59 Q_ASSERT(!uniqueName.isEmpty());
60 Q_ASSERT(!uniqueName.isEmpty());
60
61
61 return uniqueName;
62 return uniqueName;
62 }
63 }
63
64
64 } // namespace
65 } // namespace
65
66
66 VariableModel2::VariableModel2(QObject* parent) : QAbstractTableModel{parent} {}
67 VariableModel2::VariableModel2(QObject* parent) : QAbstractTableModel{parent} {}
67
68
68 int VariableModel2::columnCount(const QModelIndex& parent) const
69 int VariableModel2::columnCount(const QModelIndex& parent) const
69 {
70 {
70 Q_UNUSED(parent);
71 Q_UNUSED(parent);
71
72
72 return NB_COLUMNS;
73 return NB_COLUMNS;
73 }
74 }
74
75
75 int VariableModel2::rowCount(const QModelIndex& parent) const
76 int VariableModel2::rowCount(const QModelIndex& parent) const
76 {
77 {
77 Q_UNUSED(parent);
78 Q_UNUSED(parent);
78 return _variables.size();
79 return _variables.size();
79 }
80 }
80
81
81 QVariant VariableModel2::data(const QModelIndex& index, int role) const
82 QVariant VariableModel2::data(const QModelIndex& index, int role) const
82 {
83 {
83 if(!index.isValid()) { return QVariant{}; }
84 if(!index.isValid()) { return QVariant{}; }
84
85
85 if(index.row() < 0 || index.row() >= rowCount()) { return QVariant{}; }
86 if(index.row() < 0 || index.row() >= rowCount()) { return QVariant{}; }
86
87
87 if(role == Qt::DisplayRole)
88 if(role == Qt::DisplayRole)
88 {
89 {
89 if(auto variable = _variables[index.row()])
90 if(auto variable = _variables[index.row()])
90 {
91 {
91 switch(index.column())
92 switch(index.column())
92 {
93 {
93 case NAME_COLUMN: return variable->name();
94 case NAME_COLUMN: return variable->name();
94 case TSTART_COLUMN:
95 case TSTART_COLUMN:
95 {
96 {
96 if(auto range = variable->realRange(); range.has_value())
97 if(auto range = variable->realRange(); range.has_value())
97 return DateUtils::dateTime(range.value().m_TStart)
98 return DateUtils::dateTime(range.value().m_TStart)
98 .toString(DATETIME_FORMAT);
99 .toString(DATETIME_FORMAT);
99 return QVariant{};
100 return QVariant{};
100 }
101 }
101 case TEND_COLUMN:
102 case TEND_COLUMN:
102 {
103 {
103 if(auto range = variable->realRange(); range.has_value())
104 if(auto range = variable->realRange(); range.has_value())
104 return DateUtils::dateTime(range.value().m_TEnd)
105 return DateUtils::dateTime(range.value().m_TEnd)
105 .toString(DATETIME_FORMAT);
106 .toString(DATETIME_FORMAT);
106 return QVariant{};
107 return QVariant{};
107 }
108 }
108 case NBPOINTS_COLUMN: return int(variable->nbPoints());
109 case NBPOINTS_COLUMN: return int(variable->nbPoints());
109 case UNIT_COLUMN:
110 case UNIT_COLUMN:
110 return variable->metadata().value(QStringLiteral("units"));
111 return variable->metadata().value(QStringLiteral("units"));
111 case MISSION_COLUMN:
112 case MISSION_COLUMN:
112 return variable->metadata().value(QStringLiteral("mission"));
113 return variable->metadata().value(QStringLiteral("mission"));
113 case PLUGIN_COLUMN:
114 case PLUGIN_COLUMN:
114 return variable->metadata().value(QStringLiteral("plugin"));
115 return variable->metadata().value(QStringLiteral("plugin"));
115 default:
116 default:
116 // No action
117 // No action
117 break;
118 break;
118 }
119 }
119 }
120 }
120 }
121 }
121 else if(role == VariableRoles::ProgressRole)
122 else if(role == VariableRoles::ProgressRole)
122 {
123 {
123 return QVariant{};
124 return QVariant{};
124 }
125 }
125
126
126 return QVariant{};
127 return QVariant{};
127 }
128 }
128
129
129 QVariant VariableModel2::headerData(int section, Qt::Orientation orientation,
130 QVariant VariableModel2::headerData(int section, Qt::Orientation orientation,
130 int role) const
131 int role) const
131 {
132 {
132 if(role != Qt::DisplayRole && role != Qt::SizeHintRole) { return QVariant{}; }
133 if(role != Qt::DisplayRole && role != Qt::SizeHintRole) { return QVariant{}; }
133
134
134 if(orientation == Qt::Horizontal)
135 if(orientation == Qt::Horizontal)
135 {
136 {
136 auto propertiesIt = COLUMN_PROPERTIES.find(section);
137 auto propertiesIt = COLUMN_PROPERTIES.find(section);
137 if(propertiesIt != COLUMN_PROPERTIES.cend())
138 if(propertiesIt != COLUMN_PROPERTIES.cend())
138 {
139 {
139 // Role is either DisplayRole or SizeHintRole
140 // Role is either DisplayRole or SizeHintRole
140 return (role == Qt::DisplayRole)
141 return (role == Qt::DisplayRole)
141 ? QVariant{propertiesIt->m_Name}
142 ? QVariant{propertiesIt->m_Name}
142 : QVariant{
143 : QVariant{
143 QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
144 QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
144 }
145 }
145 }
146 }
146
147
147 return QVariant{};
148 return QVariant{};
148 }
149 }
149
150
150 Qt::ItemFlags VariableModel2::flags(const QModelIndex& index) const
151 Qt::ItemFlags VariableModel2::flags(const QModelIndex& index) const
151 {
152 {
152 return QAbstractTableModel::flags(index) | Qt::ItemIsDragEnabled |
153 return QAbstractTableModel::flags(index) | Qt::ItemIsDragEnabled |
153 Qt::ItemIsDropEnabled;
154 Qt::ItemIsDropEnabled;
154 }
155 }
155
156
156 Qt::DropActions VariableModel2::supportedDropActions() const
157 Qt::DropActions VariableModel2::supportedDropActions() const
157 {
158 {
158 return Qt::CopyAction | Qt::MoveAction;
159 return Qt::CopyAction | Qt::MoveAction;
159 }
160 }
160
161
161 Qt::DropActions VariableModel2::supportedDragActions() const
162 Qt::DropActions VariableModel2::supportedDragActions() const
162 {
163 {
163 return Qt::CopyAction | Qt::MoveAction;
164 return Qt::CopyAction | Qt::MoveAction;
164 }
165 }
165
166
166 QStringList VariableModel2::mimeTypes() const
167 QStringList VariableModel2::mimeTypes() const
167 {
168 {
168 return {MIME_TYPE_VARIABLE_LIST, MIME_TYPE_TIME_RANGE};
169 return {MIME_TYPE_VARIABLE_LIST, MIME_TYPE_TIME_RANGE};
169 }
170 }
170
171
171 QMimeData* VariableModel2::mimeData(const QModelIndexList& indexes) const
172 QMimeData* VariableModel2::mimeData(const QModelIndexList& indexes) const
172 {
173 {
173 auto mimeData = new QMimeData;
174 auto mimeData = new QMimeData;
174 std::vector<std::shared_ptr<Variable2>> variables;
175 std::vector<std::shared_ptr<Variable2>> variables;
175
176
176 DateTimeRange firstTimeRange;
177 DateTimeRange firstTimeRange;
177 for(const auto& index : indexes)
178 for(const auto& index : indexes)
178 {
179 {
179 if(index.column() == 0)
180 if(index.column() == 0)
180 { // only the first column
181 { // only the first column
181 auto variable = _variables[index.row()];
182 auto variable = _variables[index.row()];
182 if(variable.get() && index.isValid())
183 if(variable.get() && index.isValid())
183 {
184 {
184 if(variables.size() == 0)
185 if(variables.size() == 0)
185 {
186 {
186 // Gets the range of the first variable
187 // Gets the range of the first variable
187 firstTimeRange = variable->range();
188 firstTimeRange = variable->range();
188 }
189 }
189 variables.push_back(variable);
190 variables.push_back(variable);
190 }
191 }
191 }
192 }
192 }
193 }
193
194
194 auto variablesEncodedData = Variable2::mimeData(variables);
195 auto variablesEncodedData = Variable2::mimeData(variables);
195 mimeData->setData(MIME_TYPE_VARIABLE_LIST, variablesEncodedData);
196 mimeData->setData(MIME_TYPE_VARIABLE_LIST, variablesEncodedData);
196
197
197 if(variables.size() == 1)
198 if(variables.size() == 1)
198 {
199 {
199 // No time range MIME data if multiple variables are dragged
200 // No time range MIME data if multiple variables are dragged
200 auto timeEncodedData = TimeController::mimeDataForTimeRange(firstTimeRange);
201 auto timeEncodedData = TimeController::mimeDataForTimeRange(firstTimeRange);
201 mimeData->setData(MIME_TYPE_TIME_RANGE, timeEncodedData);
202 mimeData->setData(MIME_TYPE_TIME_RANGE, timeEncodedData);
202 }
203 }
203
204
204 return mimeData;
205 return mimeData;
205 }
206 }
206
207
207 bool VariableModel2::canDropMimeData(const QMimeData* data,
208 bool VariableModel2::canDropMimeData(const QMimeData* data,
208 Qt::DropAction action, int row, int column,
209 Qt::DropAction action, int row, int column,
209 const QModelIndex& parent) const
210 const QModelIndex& parent) const
210 {
211 {
211 Q_UNUSED(column);
212 Q_UNUSED(column);
212 // drop of a product
213 // drop of a product
213 return data->hasFormat(MIME_TYPE_PRODUCT_LIST) ||
214 return data->hasFormat(MIME_TYPE_PRODUCT_LIST) ||
214 (data->hasFormat(MIME_TYPE_TIME_RANGE) && parent.isValid() &&
215 (data->hasFormat(MIME_TYPE_TIME_RANGE) && parent.isValid() &&
215 !data->hasFormat(MIME_TYPE_VARIABLE_LIST));
216 !data->hasFormat(MIME_TYPE_VARIABLE_LIST));
216 }
217 }
217
218
218 bool VariableModel2::dropMimeData(const QMimeData* data, Qt::DropAction action,
219 bool VariableModel2::dropMimeData(const QMimeData* data, Qt::DropAction action,
219 int row, int column,
220 int row, int column,
220 const QModelIndex& parent)
221 const QModelIndex& parent)
221 {
222 {
222 auto dropDone = false;
223 auto dropDone = false;
223
224
224 if(data->hasFormat(MIME_TYPE_PRODUCT_LIST))
225 if(data->hasFormat(MIME_TYPE_PRODUCT_LIST))
225 {
226 {
226 auto productList = DataSourceController::productsDataForMimeData(
227 auto productList = DataSourceController::productsDataForMimeData(
227 data->data(MIME_TYPE_PRODUCT_LIST));
228 data->data(MIME_TYPE_PRODUCT_LIST));
228
229
229 for(auto metaData : productList)
230 for(auto metaData : productList)
230 {
231 {
231 emit createVariable(metaData.toHash());
232 emit createVariable(metaData.toHash());
232 }
233 }
233
234
234 dropDone = true;
235 dropDone = true;
235 }
236 }
236 else if(data->hasFormat(MIME_TYPE_TIME_RANGE) && parent.isValid())
237 else if(data->hasFormat(MIME_TYPE_TIME_RANGE) && parent.isValid())
237 {
238 {
238 auto variable = _variables[parent.row()];
239 auto variable = _variables[parent.row()];
239 auto range =
240 auto range =
240 TimeController::timeRangeForMimeData(data->data(MIME_TYPE_TIME_RANGE));
241 TimeController::timeRangeForMimeData(data->data(MIME_TYPE_TIME_RANGE));
241
242
242 emit asyncChangeRange(variable, range);
243 emit asyncChangeRange(variable, range);
243
244
244 dropDone = true;
245 dropDone = true;
245 }
246 }
246
247
247 return dropDone;
248 return dropDone;
248 }
249 }
249
250
250 void VariableModel2::variableUpdated(QUuid id) noexcept
251 void VariableModel2::variableUpdated(QUuid id) noexcept
251 {
252 {
252 emit dataChanged(QModelIndex(), QModelIndex());
253 emit dataChanged(QModelIndex(), QModelIndex());
253 }
254 }
254
255
255 void VariableModel2::variableAdded(const std::shared_ptr<Variable2>& variable)
256 void VariableModel2::variableAdded(const std::shared_ptr<Variable2>& variable)
256 {
257 {
257 if(!SciQLop::containers::contains(_variables, variable))
258 if(!cpp_utils::containers::contains(_variables, variable))
258 {
259 {
259 beginInsertRows(QModelIndex(), this->_variables.size(),
260 beginInsertRows(QModelIndex(), this->_variables.size(),
260 this->_variables.size());
261 this->_variables.size());
261 this->_variables.push_back(variable);
262 this->_variables.push_back(variable);
262 endInsertRows();
263 endInsertRows();
263 connect(variable.get(), &Variable2::updated, this,
264 connect(variable.get(), &Variable2::updated, this,
264 &VariableModel2::variableUpdated);
265 &VariableModel2::variableUpdated);
265 }
266 }
266 }
267 }
267
268
268 void VariableModel2::variableDeleted(const std::shared_ptr<Variable2>& variable)
269 void VariableModel2::variableDeleted(const std::shared_ptr<Variable2>& variable)
269 {
270 {
270 auto it = std::find(_variables.begin(), _variables.end(), variable);
271 auto it = std::find(_variables.begin(), _variables.end(), variable);
271 if(it != _variables.end())
272 if(it != _variables.end())
272 {
273 {
273 auto index = std::distance(_variables.begin(), it);
274 auto index = std::distance(_variables.begin(), it);
274 beginRemoveRows(QModelIndex(), index, index);
275 beginRemoveRows(QModelIndex(), index, index);
275 _variables.erase(it);
276 _variables.erase(it);
276 endRemoveRows();
277 endRemoveRows();
277 }
278 }
278 }
279 }
@@ -1,248 +1,248
1 #include <Common/Numeric.h>
1 #include <Numeric.h>
2 #include <Data/DateTimeRange.h>
2 #include <Data/DateTimeRange.h>
3 #include <Data/DateTimeRangeHelper.h>
3 #include <Data/DateTimeRangeHelper.h>
4 #include <QObject>
4 #include <QObject>
5 #include <QUuid>
5 #include <QUuid>
6 #include <QtTest>
6 #include <QtTest>
7 #include <limits>
7 #include <limits>
8
8
9 Q_DECLARE_METATYPE(Seconds<double>);
9 Q_DECLARE_METATYPE(Seconds<double>);
10 Q_DECLARE_METATYPE(DateTimeRangeTransformation);
10 Q_DECLARE_METATYPE(DateTimeRangeTransformation);
11
11
12 DateTimeRange computeZoom(QDateTime start, QDateTime stop, double zoom)
12 DateTimeRange computeZoom(QDateTime start, QDateTime stop, double zoom)
13 {
13 {
14 double start_epoch = start.toMSecsSinceEpoch();
14 double start_epoch = start.toMSecsSinceEpoch();
15 double stop_epoch = stop.toMSecsSinceEpoch();
15 double stop_epoch = stop.toMSecsSinceEpoch();
16 auto delta = stop_epoch - start_epoch;
16 auto delta = stop_epoch - start_epoch;
17 auto dt_ms = (zoom - 1.) * (double(delta)) / 2.;
17 auto dt_ms = (zoom - 1.) * (double(delta)) / 2.;
18 return DateTimeRange{(start_epoch - dt_ms) / 1000.,
18 return DateTimeRange{(start_epoch - dt_ms) / 1000.,
19 (stop_epoch + dt_ms) / 1000.};
19 (stop_epoch + dt_ms) / 1000.};
20 }
20 }
21
21
22 class TestDateTimeRange : public QObject
22 class TestDateTimeRange : public QObject
23 {
23 {
24 Q_OBJECT
24 Q_OBJECT
25
25
26 private slots:
26 private slots:
27 void testRangeDelta_data()
27 void testRangeDelta_data()
28 {
28 {
29 QTest::addColumn<QDateTime>("tstart");
29 QTest::addColumn<QDateTime>("tstart");
30 QTest::addColumn<QDateTime>("tend");
30 QTest::addColumn<QDateTime>("tend");
31 QTest::addColumn<double>("expected");
31 QTest::addColumn<double>("expected");
32 auto now = QDateTime::currentDateTime();
32 auto now = QDateTime::currentDateTime();
33 auto yesterday = QDateTime::currentDateTime().addDays(-1);
33 auto yesterday = QDateTime::currentDateTime().addDays(-1);
34 QTest::newRow("No delta") << now << now << 0.;
34 QTest::newRow("No delta") << now << now << 0.;
35 QTest::newRow("One day delta") << yesterday << now << 60. * 60. * 24.;
35 QTest::newRow("One day delta") << yesterday << now << 60. * 60. * 24.;
36 QTest::newRow("Minus one day delta")
36 QTest::newRow("Minus one day delta")
37 << now << yesterday << -60. * 60. * 24.;
37 << now << yesterday << -60. * 60. * 24.;
38 }
38 }
39
39
40 void testRangeDelta()
40 void testRangeDelta()
41 {
41 {
42 QFETCH(QDateTime, tstart);
42 QFETCH(QDateTime, tstart);
43 QFETCH(QDateTime, tend);
43 QFETCH(QDateTime, tend);
44 QFETCH(double, expected);
44 QFETCH(double, expected);
45 auto range = DateTimeRange::fromDateTime(tstart, tend);
45 auto range = DateTimeRange::fromDateTime(tstart, tend);
46 double delta = range.delta();
46 double delta = range.delta();
47 // Since it is built from QDateTime don't expect better resolution
47 // Since it is built from QDateTime don't expect better resolution
48 QVERIFY((delta - expected) <= 0.002);
48 QVERIFY((delta - expected) <= 0.002);
49 }
49 }
50
50
51 void testRangeShift_data()
51 void testRangeShift_data()
52 {
52 {
53 QTest::addColumn<DateTimeRange>("initial");
53 QTest::addColumn<DateTimeRange>("initial");
54 QTest::addColumn<Seconds<double>>("shift");
54 QTest::addColumn<Seconds<double>>("shift");
55 QTest::addColumn<DateTimeRange>("expected");
55 QTest::addColumn<DateTimeRange>("expected");
56 auto now = QDateTime::currentDateTime();
56 auto now = QDateTime::currentDateTime();
57 auto yestd = QDateTime::currentDateTime().addDays(-1);
57 auto yestd = QDateTime::currentDateTime().addDays(-1);
58 auto range = DateTimeRange::fromDateTime(yestd, now);
58 auto range = DateTimeRange::fromDateTime(yestd, now);
59 QTest::newRow("No shift") << range << Seconds<double>{0.} << range;
59 QTest::newRow("No shift") << range << Seconds<double>{0.} << range;
60
60
61 QTest::newRow("One milisecond left")
61 QTest::newRow("One milisecond left")
62 << range << Seconds<double>{-.001}
62 << range << Seconds<double>{-.001}
63 << DateTimeRange::fromDateTime(yestd.addMSecs(-1.), now.addMSecs(-1.));
63 << DateTimeRange::fromDateTime(yestd.addMSecs(-1.), now.addMSecs(-1.));
64 QTest::newRow("One milisecond right")
64 QTest::newRow("One milisecond right")
65 << range << Seconds<double>{.001}
65 << range << Seconds<double>{.001}
66 << DateTimeRange::fromDateTime(yestd.addMSecs(1.), now.addMSecs(1.));
66 << DateTimeRange::fromDateTime(yestd.addMSecs(1.), now.addMSecs(1.));
67 QTest::newRow("One second left")
67 QTest::newRow("One second left")
68 << range << Seconds<double>{-1.}
68 << range << Seconds<double>{-1.}
69 << DateTimeRange::fromDateTime(yestd.addSecs(-1.), now.addSecs(-1.));
69 << DateTimeRange::fromDateTime(yestd.addSecs(-1.), now.addSecs(-1.));
70 QTest::newRow("One second right")
70 QTest::newRow("One second right")
71 << range << Seconds<double>{1.}
71 << range << Seconds<double>{1.}
72 << DateTimeRange::fromDateTime(yestd.addSecs(1.), now.addSecs(1.));
72 << DateTimeRange::fromDateTime(yestd.addSecs(1.), now.addSecs(1.));
73 QTest::newRow("One year left")
73 QTest::newRow("One year left")
74 << range << Seconds<double>{-365. * 24. * 60. * 60.}
74 << range << Seconds<double>{-365. * 24. * 60. * 60.}
75 << DateTimeRange::fromDateTime(yestd.addSecs(-365 * 24 * 60 * 60),
75 << DateTimeRange::fromDateTime(yestd.addSecs(-365 * 24 * 60 * 60),
76 now.addSecs(-365 * 24 * 60 * 60));
76 now.addSecs(-365 * 24 * 60 * 60));
77 QTest::newRow("One year right")
77 QTest::newRow("One year right")
78 << range << Seconds<double>{365. * 24. * 60. * 60.}
78 << range << Seconds<double>{365. * 24. * 60. * 60.}
79 << DateTimeRange::fromDateTime(yestd.addSecs(365 * 24 * 60 * 60),
79 << DateTimeRange::fromDateTime(yestd.addSecs(365 * 24 * 60 * 60),
80 now.addSecs(365 * 24 * 60 * 60));
80 now.addSecs(365 * 24 * 60 * 60));
81 }
81 }
82
82
83 void testRangeShift()
83 void testRangeShift()
84 {
84 {
85 QFETCH(DateTimeRange, initial);
85 QFETCH(DateTimeRange, initial);
86 QFETCH(Seconds<double>, shift);
86 QFETCH(Seconds<double>, shift);
87 QFETCH(DateTimeRange, expected);
87 QFETCH(DateTimeRange, expected);
88 QCOMPARE(initial + shift, expected);
88 QCOMPARE(initial + shift, expected);
89 }
89 }
90
90
91 void testRangeZoom_data()
91 void testRangeZoom_data()
92 {
92 {
93 QTest::addColumn<DateTimeRange>("initial");
93 QTest::addColumn<DateTimeRange>("initial");
94 QTest::addColumn<double>("zoom");
94 QTest::addColumn<double>("zoom");
95 QTest::addColumn<DateTimeRange>("expected");
95 QTest::addColumn<DateTimeRange>("expected");
96 auto now = QDateTime::currentDateTime();
96 auto now = QDateTime::currentDateTime();
97 auto yestd = QDateTime::currentDateTime().addDays(-1);
97 auto yestd = QDateTime::currentDateTime().addDays(-1);
98 auto range = DateTimeRange::fromDateTime(yestd, now);
98 auto range = DateTimeRange::fromDateTime(yestd, now);
99 QTest::newRow("No zoom") << range << 1. << range;
99 QTest::newRow("No zoom") << range << 1. << range;
100
100
101 QTest::newRow("Zoom IN 0.001")
101 QTest::newRow("Zoom IN 0.001")
102 << range << 1.001 << computeZoom(yestd, now, 1.001);
102 << range << 1.001 << computeZoom(yestd, now, 1.001);
103 QTest::newRow("Zoom OUT 0.001")
103 QTest::newRow("Zoom OUT 0.001")
104 << range << 0.999 << computeZoom(yestd, now, 0.999);
104 << range << 0.999 << computeZoom(yestd, now, 0.999);
105 }
105 }
106 void testRangeZoom()
106 void testRangeZoom()
107 {
107 {
108 QFETCH(DateTimeRange, initial);
108 QFETCH(DateTimeRange, initial);
109 QFETCH(double, zoom);
109 QFETCH(double, zoom);
110 QFETCH(DateTimeRange, expected);
110 QFETCH(DateTimeRange, expected);
111 QCOMPARE(initial * zoom, expected);
111 QCOMPARE(initial * zoom, expected);
112 }
112 }
113
113
114 void testRangeContains_data()
114 void testRangeContains_data()
115 {
115 {
116 QTest::addColumn<DateTimeRange>("range");
116 QTest::addColumn<DateTimeRange>("range");
117 QTest::addColumn<DateTimeRange>("range2");
117 QTest::addColumn<DateTimeRange>("range2");
118 QTest::addColumn<bool>("contains");
118 QTest::addColumn<bool>("contains");
119 auto now = QDateTime::currentDateTime();
119 auto now = QDateTime::currentDateTime();
120 auto yestd = QDateTime::currentDateTime().addDays(-1);
120 auto yestd = QDateTime::currentDateTime().addDays(-1);
121 auto range = DateTimeRange::fromDateTime(yestd, now);
121 auto range = DateTimeRange::fromDateTime(yestd, now);
122 QTest::newRow("Same range") << range << range << true;
122 QTest::newRow("Same range") << range << range << true;
123 QTest::newRow("Smaller range") << range << range * 0.8 << true;
123 QTest::newRow("Smaller range") << range << range * 0.8 << true;
124 QTest::newRow("Bigger range") << range << range * 1.2 << false;
124 QTest::newRow("Bigger range") << range << range * 1.2 << false;
125 QTest::newRow("Shifted range with overlap")
125 QTest::newRow("Shifted range with overlap")
126 << range << range + Seconds<double>{1000.} << false;
126 << range << range + Seconds<double>{1000.} << false;
127 QTest::newRow("Shifted range without overlap")
127 QTest::newRow("Shifted range without overlap")
128 << range << range + Seconds<double>{24. * 60. * 60. * 10} << false;
128 << range << range + Seconds<double>{24. * 60. * 60. * 10} << false;
129 }
129 }
130
130
131 void testRangeContains()
131 void testRangeContains()
132 {
132 {
133 QFETCH(DateTimeRange, range);
133 QFETCH(DateTimeRange, range);
134 QFETCH(DateTimeRange, range2);
134 QFETCH(DateTimeRange, range2);
135 QFETCH(bool, contains);
135 QFETCH(bool, contains);
136 QCOMPARE(range.contains(range2), contains);
136 QCOMPARE(range.contains(range2), contains);
137 }
137 }
138
138
139 void testRangeIntersect_data()
139 void testRangeIntersect_data()
140 {
140 {
141 QTest::addColumn<DateTimeRange>("range");
141 QTest::addColumn<DateTimeRange>("range");
142 QTest::addColumn<DateTimeRange>("range2");
142 QTest::addColumn<DateTimeRange>("range2");
143 QTest::addColumn<bool>("contains");
143 QTest::addColumn<bool>("contains");
144 auto now = QDateTime::currentDateTime();
144 auto now = QDateTime::currentDateTime();
145 auto yestd = QDateTime::currentDateTime().addDays(-1);
145 auto yestd = QDateTime::currentDateTime().addDays(-1);
146 auto tomorrow = QDateTime::currentDateTime().addDays(1);
146 auto tomorrow = QDateTime::currentDateTime().addDays(1);
147 auto range = DateTimeRange::fromDateTime(yestd, now);
147 auto range = DateTimeRange::fromDateTime(yestd, now);
148 auto range2 = DateTimeRange::fromDateTime(now, tomorrow);
148 auto range2 = DateTimeRange::fromDateTime(now, tomorrow);
149 QTest::newRow("Same range") << range << range << true;
149 QTest::newRow("Same range") << range << range << true;
150 QTest::newRow("Smaller range") << range << range * 0.8 << true;
150 QTest::newRow("Smaller range") << range << range * 0.8 << true;
151 QTest::newRow("Bigger range") << range << range * 1.2 << true;
151 QTest::newRow("Bigger range") << range << range * 1.2 << true;
152 QTest::newRow("Shifted range with overlap")
152 QTest::newRow("Shifted range with overlap")
153 << range << range + Seconds<double>{1000.} << true;
153 << range << range + Seconds<double>{1000.} << true;
154 QTest::newRow("Shifted range with overlaping boundary")
154 QTest::newRow("Shifted range with overlaping boundary")
155 << range << range2 << true;
155 << range << range2 << true;
156 QTest::newRow("Shifted range .1 seonds outside")
156 QTest::newRow("Shifted range .1 seonds outside")
157 << range << range2 + Seconds<double>{.1} << false;
157 << range << range2 + Seconds<double>{.1} << false;
158 QTest::newRow("Shifted range without overlap")
158 QTest::newRow("Shifted range without overlap")
159 << range << range + Seconds<double>{24. * 60. * 60. * 10} << false;
159 << range << range + Seconds<double>{24. * 60. * 60. * 10} << false;
160 }
160 }
161
161
162 void testRangeIntersect()
162 void testRangeIntersect()
163 {
163 {
164 QFETCH(DateTimeRange, range);
164 QFETCH(DateTimeRange, range);
165 QFETCH(DateTimeRange, range2);
165 QFETCH(DateTimeRange, range2);
166 QFETCH(bool, contains);
166 QFETCH(bool, contains);
167 QCOMPARE(range.intersect(range2), contains);
167 QCOMPARE(range.intersect(range2), contains);
168 }
168 }
169
169
170 void testRangeTransformations_data()
170 void testRangeTransformations_data()
171 {
171 {
172 QTest::addColumn<DateTimeRange>("range1");
172 QTest::addColumn<DateTimeRange>("range1");
173 QTest::addColumn<DateTimeRange>("range2");
173 QTest::addColumn<DateTimeRange>("range2");
174 QTest::addColumn<DateTimeRangeTransformation>("transformation");
174 QTest::addColumn<DateTimeRangeTransformation>("transformation");
175 auto now = QDateTime::currentDateTime();
175 auto now = QDateTime::currentDateTime();
176 auto yestd = QDateTime::currentDateTime().addDays(-1);
176 auto yestd = QDateTime::currentDateTime().addDays(-1);
177 auto range = DateTimeRange::fromDateTime(yestd, now);
177 auto range = DateTimeRange::fromDateTime(yestd, now);
178
178
179 QTest::newRow("Same range")
179 QTest::newRow("Same range")
180 << range << range
180 << range << range
181 << DateTimeRangeTransformation{1., Seconds<double>{0.}};
181 << DateTimeRangeTransformation{1., Seconds<double>{0.}};
182
182
183 QTest::newRow("Transformatio 1.1x + 10s")
183 QTest::newRow("Transformatio 1.1x + 10s")
184 << range << range * 1.1 + Seconds<double>{10.}
184 << range << range * 1.1 + Seconds<double>{10.}
185 << DateTimeRangeTransformation{1.1, Seconds<double>{10.}};
185 << DateTimeRangeTransformation{1.1, Seconds<double>{10.}};
186
186
187 QTest::newRow("Transformatio 1.x + 10s")
187 QTest::newRow("Transformatio 1.x + 10s")
188 << range << range * 1. + Seconds<double>{10.}
188 << range << range * 1. + Seconds<double>{10.}
189 << DateTimeRangeTransformation{1., Seconds<double>{10.}};
189 << DateTimeRangeTransformation{1., Seconds<double>{10.}};
190
190
191 QTest::newRow("Transformatio 1.1x + 0s")
191 QTest::newRow("Transformatio 1.1x + 0s")
192 << range << range * 1.1 + Seconds<double>{0.}
192 << range << range * 1.1 + Seconds<double>{0.}
193 << DateTimeRangeTransformation{1.1, Seconds<double>{0.}};
193 << DateTimeRangeTransformation{1.1, Seconds<double>{0.}};
194
194
195 QTest::newRow("Transformatio 0.9x - 10s")
195 QTest::newRow("Transformatio 0.9x - 10s")
196 << range << range * 0.9 + Seconds<double>{-10.}
196 << range << range * 0.9 + Seconds<double>{-10.}
197 << DateTimeRangeTransformation{0.9, Seconds<double>{-10.}};
197 << DateTimeRangeTransformation{0.9, Seconds<double>{-10.}};
198 }
198 }
199 void testRangeTransformations()
199 void testRangeTransformations()
200 {
200 {
201 QFETCH(DateTimeRange, range1);
201 QFETCH(DateTimeRange, range1);
202 QFETCH(DateTimeRange, range2);
202 QFETCH(DateTimeRange, range2);
203 QFETCH(DateTimeRangeTransformation, transformation);
203 QFETCH(DateTimeRangeTransformation, transformation);
204 auto computed_tr =
204 auto computed_tr =
205 DateTimeRangeHelper::computeTransformation(range1, range2).value();
205 DateTimeRangeHelper::computeTransformation(range1, range2).value();
206 QCOMPARE(computed_tr, transformation);
206 QCOMPARE(computed_tr, transformation);
207 QCOMPARE(range1.transform(transformation), range2);
207 QCOMPARE(range1.transform(transformation), range2);
208 QCOMPARE(range1.transform(computed_tr), range2);
208 QCOMPARE(range1.transform(computed_tr), range2);
209 }
209 }
210
210
211 void testRangeDiff_data()
211 void testRangeDiff_data()
212 {
212 {
213 QTest::addColumn<DateTimeRange>("source");
213 QTest::addColumn<DateTimeRange>("source");
214 QTest::addColumn<DateTimeRange>("destination");
214 QTest::addColumn<DateTimeRange>("destination");
215 QTest::addColumn<int>("count");
215 QTest::addColumn<int>("count");
216 auto now = QDateTime::currentDateTime();
216 auto now = QDateTime::currentDateTime();
217 auto yestd = QDateTime::currentDateTime().addDays(-1);
217 auto yestd = QDateTime::currentDateTime().addDays(-1);
218 auto range = DateTimeRange::fromDateTime(yestd, now);
218 auto range = DateTimeRange::fromDateTime(yestd, now);
219 QTest::newRow("Same range") << range << range << 0;
219 QTest::newRow("Same range") << range << range << 0;
220 QTest::newRow("No missing data (zoom in)") << range << range * 0.9 << 0;
220 QTest::newRow("No missing data (zoom in)") << range << range * 0.9 << 0;
221 QTest::newRow("Missing data on both sides (zoom out)")
221 QTest::newRow("Missing data on both sides (zoom out)")
222 << range << range * 2. << 2;
222 << range << range * 2. << 2;
223 QTest::newRow("Missing data on left side (pan left)")
223 QTest::newRow("Missing data on left side (pan left)")
224 << range << range - Seconds<double>{1000.} << 1;
224 << range << range - Seconds<double>{1000.} << 1;
225 QTest::newRow("Missing data on right side (pan right)")
225 QTest::newRow("Missing data on right side (pan right)")
226 << range << range + Seconds<double>{1000.} << 1;
226 << range << range + Seconds<double>{1000.} << 1;
227 QTest::newRow("Missing data on right side no intersect (big pan right)")
227 QTest::newRow("Missing data on right side no intersect (big pan right)")
228 << range << range + Seconds<double>{24. * 60. * 60. * 2} << 1;
228 << range << range + Seconds<double>{24. * 60. * 60. * 2} << 1;
229 QTest::newRow("Missing data on left side no intersect (big pan left)")
229 QTest::newRow("Missing data on left side no intersect (big pan left)")
230 << range << range - Seconds<double>{24. * 60. * 60. * 2} << 1;
230 << range << range - Seconds<double>{24. * 60. * 60. * 2} << 1;
231 }
231 }
232
232
233 void testRangeDiff()
233 void testRangeDiff()
234 {
234 {
235 QFETCH(DateTimeRange, source);
235 QFETCH(DateTimeRange, source);
236 QFETCH(DateTimeRange, destination);
236 QFETCH(DateTimeRange, destination);
237 QFETCH(int, count);
237 QFETCH(int, count);
238 auto diff = destination - source;
238 auto diff = destination - source;
239 QCOMPARE(diff.size(), count);
239 QCOMPARE(diff.size(), count);
240 for(const auto& range : diff)
240 for(const auto& range : diff)
241 {
241 {
242 QVERIFY(range.delta().value > 0.);
242 QVERIFY(range.delta().value > 0.);
243 }
243 }
244 }
244 }
245 };
245 };
246 QTEST_MAIN(TestDateTimeRange)
246 QTEST_MAIN(TestDateTimeRange)
247
247
248 #include "TestDateTimeRange.moc"
248 #include "TestDateTimeRange.moc"
@@ -1,157 +1,157
1 #include <Common/containers.h>
1 #include <containers/algorithms.hpp>
2 #include <Data/DataProviderParameters.h>
2 #include <Data/DataProviderParameters.h>
3 #include <Data/DateTimeRange.h>
3 #include <Data/DateTimeRange.h>
4 #include <Data/IDataProvider.h>
4 #include <Data/IDataProvider.h>
5 #include <QObject>
5 #include <QObject>
6 #include <QtTest>
6 #include <QtTest>
7 #include <TestUtils/TestProviders.h>
7 #include <TestUtils/TestProviders.h>
8 #include <Variable/VariableController2.h>
8 #include <Variable/VariableController2.h>
9 #include <algorithm>
9 #include <algorithm>
10 #include <cmath>
10 #include <cmath>
11 #include <numeric>
11 #include <numeric>
12
12
13 #define TEST_VC2_FIXTURE(slope) \
13 #define TEST_VC2_FIXTURE(slope) \
14 VariableController2 vc; \
14 VariableController2 vc; \
15 auto provider = std::make_shared<SimpleRange<slope>>();
15 auto provider = std::make_shared<SimpleRange<slope>>();
16
16
17 #define TEST_VC2_CREATE_DEFAULT_VAR(name) \
17 #define TEST_VC2_CREATE_DEFAULT_VAR(name) \
18 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00), \
18 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00), \
19 QDate(2018, 8, 7), QTime(16, 00)); \
19 QDate(2018, 8, 7), QTime(16, 00)); \
20 auto name = vc.createVariable("name", {}, provider, range); \
20 auto name = vc.createVariable("name", {}, provider, range); \
21 while(!vc.isReady(name)) \
21 while(!vc.isReady(name)) \
22 QCoreApplication::processEvents();
22 QCoreApplication::processEvents();
23
23
24 Q_DECLARE_METATYPE(DateTimeRangeTransformation);
24 Q_DECLARE_METATYPE(DateTimeRangeTransformation);
25
25
26 class TestVariableController2 : public QObject
26 class TestVariableController2 : public QObject
27 {
27 {
28 Q_OBJECT
28 Q_OBJECT
29 public:
29 public:
30 explicit TestVariableController2(QObject* parent = nullptr) : QObject(parent)
30 explicit TestVariableController2(QObject* parent = nullptr) : QObject(parent)
31 {}
31 {}
32 signals:
32 signals:
33
33
34 private slots:
34 private slots:
35 void initTestCase() {}
35 void initTestCase() {}
36 void cleanupTestCase() {}
36 void cleanupTestCase() {}
37
37
38 void testCreateVariable()
38 void testCreateVariable()
39 {
39 {
40 TEST_VC2_FIXTURE(2);
40 TEST_VC2_FIXTURE(2);
41 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00),
41 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00),
42 QDate(2018, 8, 7), QTime(16, 00));
42 QDate(2018, 8, 7), QTime(16, 00));
43 bool callbackCalled = false;
43 bool callbackCalled = false;
44 connect(&vc, &VariableController2::variableAdded,
44 connect(&vc, &VariableController2::variableAdded,
45 [&callbackCalled](std::shared_ptr<Variable2>) {
45 [&callbackCalled](std::shared_ptr<Variable2>) {
46 callbackCalled = true;
46 callbackCalled = true;
47 });
47 });
48 QVERIFY(!callbackCalled);
48 QVERIFY(!callbackCalled);
49 auto var1 = vc.createVariable("var1", {}, provider, range);
49 auto var1 = vc.createVariable("var1", {}, provider, range);
50 QVERIFY(SciQLop::containers::contains(vc.variables(), var1));
50 QVERIFY(cpp_utils::containers::contains(vc.variables(), var1));
51 QVERIFY(callbackCalled);
51 QVERIFY(callbackCalled);
52 }
52 }
53
53
54 void testDeleteVariable()
54 void testDeleteVariable()
55 {
55 {
56 TEST_VC2_FIXTURE(1);
56 TEST_VC2_FIXTURE(1);
57 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00),
57 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00),
58 QDate(2018, 8, 7), QTime(16, 00));
58 QDate(2018, 8, 7), QTime(16, 00));
59 bool callbackCalled = false;
59 bool callbackCalled = false;
60 connect(&vc, &VariableController2::variableDeleted,
60 connect(&vc, &VariableController2::variableDeleted,
61 [&callbackCalled](std::shared_ptr<Variable2>) {
61 [&callbackCalled](std::shared_ptr<Variable2>) {
62 callbackCalled = true;
62 callbackCalled = true;
63 });
63 });
64 auto var1 = vc.createVariable("var1", {}, provider, range);
64 auto var1 = vc.createVariable("var1", {}, provider, range);
65 while(!vc.isReady(var1))
65 while(!vc.isReady(var1))
66 QCoreApplication::processEvents();
66 QCoreApplication::processEvents();
67 QVERIFY(SciQLop::containers::contains(vc.variables(), var1));
67 QVERIFY(cpp_utils::containers::contains(vc.variables(), var1));
68 QVERIFY(!callbackCalled);
68 QVERIFY(!callbackCalled);
69 vc.deleteVariable(var1);
69 vc.deleteVariable(var1);
70 QVERIFY(!SciQLop::containers::contains(vc.variables(), var1));
70 QVERIFY(!cpp_utils::containers::contains(vc.variables(), var1));
71 QVERIFY(callbackCalled);
71 QVERIFY(callbackCalled);
72 }
72 }
73
73
74 void testGetData()
74 void testGetData()
75 {
75 {
76 TEST_VC2_FIXTURE(10);
76 TEST_VC2_FIXTURE(10);
77 TEST_VC2_CREATE_DEFAULT_VAR(var1);
77 TEST_VC2_CREATE_DEFAULT_VAR(var1);
78 check_variable_state<RangeType<10>>(var1, range);
78 check_variable_state<RangeType<10>>(var1, range);
79 }
79 }
80
80
81 void testZoom_data()
81 void testZoom_data()
82 {
82 {
83 QTest::addColumn<double>("zoom");
83 QTest::addColumn<double>("zoom");
84 QTest::newRow("Zoom IN 10x") << .1;
84 QTest::newRow("Zoom IN 10x") << .1;
85 QTest::newRow("Zoom OUT 10x") << 10.;
85 QTest::newRow("Zoom OUT 10x") << 10.;
86 QTest::newRow("Zoom IN 1x") << 1.;
86 QTest::newRow("Zoom IN 1x") << 1.;
87 }
87 }
88 void testZoom()
88 void testZoom()
89 {
89 {
90 TEST_VC2_FIXTURE(100);
90 TEST_VC2_FIXTURE(100);
91 TEST_VC2_CREATE_DEFAULT_VAR(var1);
91 TEST_VC2_CREATE_DEFAULT_VAR(var1);
92 check_variable_state<RangeType<100>>(var1, range);
92 check_variable_state<RangeType<100>>(var1, range);
93
93
94 QFETCH(double, zoom);
94 QFETCH(double, zoom);
95 range *= zoom;
95 range *= zoom;
96 vc.changeRange(var1, range);
96 vc.changeRange(var1, range);
97 check_variable_state<RangeType<100>>(var1, range);
97 check_variable_state<RangeType<100>>(var1, range);
98 }
98 }
99
99
100 void testPan_data()
100 void testPan_data()
101 {
101 {
102 QTest::addColumn<double>("pan");
102 QTest::addColumn<double>("pan");
103 QTest::newRow("Right 1000 seconds") << 1000.;
103 QTest::newRow("Right 1000 seconds") << 1000.;
104 QTest::newRow("Left 1000 seconds") << -1000.;
104 QTest::newRow("Left 1000 seconds") << -1000.;
105 QTest::newRow("Right 0.1 seconds") << .1;
105 QTest::newRow("Right 0.1 seconds") << .1;
106 QTest::newRow("Left 0.1 seconds") << -.1;
106 QTest::newRow("Left 0.1 seconds") << -.1;
107 }
107 }
108 void testPan()
108 void testPan()
109 {
109 {
110 TEST_VC2_FIXTURE(10);
110 TEST_VC2_FIXTURE(10);
111 TEST_VC2_CREATE_DEFAULT_VAR(var1);
111 TEST_VC2_CREATE_DEFAULT_VAR(var1);
112 check_variable_state<RangeType<10>>(var1, range);
112 check_variable_state<RangeType<10>>(var1, range);
113
113
114 QFETCH(double, pan);
114 QFETCH(double, pan);
115
115
116 range += Seconds<double>{pan};
116 range += Seconds<double>{pan};
117 vc.changeRange(var1, range);
117 vc.changeRange(var1, range);
118 check_variable_state<RangeType<10>>(var1, range);
118 check_variable_state<RangeType<10>>(var1, range);
119 }
119 }
120
120
121 void testCache_data()
121 void testCache_data()
122 {
122 {
123 QTest::addColumn<DateTimeRangeTransformation>("transformation");
123 QTest::addColumn<DateTimeRangeTransformation>("transformation");
124 QTest::addColumn<int>("expectedIncrement");
124 QTest::addColumn<int>("expectedIncrement");
125 QTest::newRow("zoom in")
125 QTest::newRow("zoom in")
126 << DateTimeRangeTransformation{0.8, Seconds<double>(0.)} << 0;
126 << DateTimeRangeTransformation{0.8, Seconds<double>(0.)} << 0;
127 QTest::newRow("tiny zoom out")
127 QTest::newRow("tiny zoom out")
128 << DateTimeRangeTransformation{1.01, Seconds<double>(0.)} << 0;
128 << DateTimeRangeTransformation{1.01, Seconds<double>(0.)} << 0;
129 QTest::newRow("just under cache zoom out")
129 QTest::newRow("just under cache zoom out")
130 << DateTimeRangeTransformation{2.0 / 1.1, Seconds<double>(0.)} << 0;
130 << DateTimeRangeTransformation{2.0 / 1.1, Seconds<double>(0.)} << 0;
131 QTest::newRow("just over cache zoom out")
131 QTest::newRow("just over cache zoom out")
132 << DateTimeRangeTransformation{2.001 / 1.1, Seconds<double>(0.)} << 2;
132 << DateTimeRangeTransformation{2.001 / 1.1, Seconds<double>(0.)} << 2;
133 QTest::newRow("tiny pan left")
133 QTest::newRow("tiny pan left")
134 << DateTimeRangeTransformation{1., Seconds<double>(-100.)} << 0;
134 << DateTimeRangeTransformation{1., Seconds<double>(-100.)} << 0;
135 QTest::newRow("tiny pan right")
135 QTest::newRow("tiny pan right")
136 << DateTimeRangeTransformation{1., Seconds<double>(100.)} << 0;
136 << DateTimeRangeTransformation{1., Seconds<double>(100.)} << 0;
137 }
137 }
138 void testCache()
138 void testCache()
139 {
139 {
140 QSKIP("The cache is disabled for now");
140 QSKIP("The cache is disabled for now");
141 TEST_VC2_FIXTURE(10);
141 TEST_VC2_FIXTURE(10);
142 TEST_VC2_CREATE_DEFAULT_VAR(var1);
142 TEST_VC2_CREATE_DEFAULT_VAR(var1);
143 check_variable_state<RangeType<10>>(var1, range);
143 check_variable_state<RangeType<10>>(var1, range);
144
144
145 QFETCH(DateTimeRangeTransformation, transformation);
145 QFETCH(DateTimeRangeTransformation, transformation);
146 QFETCH(int, expectedIncrement);
146 QFETCH(int, expectedIncrement);
147 auto initialCount = provider->callCounter;
147 auto initialCount = provider->callCounter;
148 range = range.transform(transformation);
148 range = range.transform(transformation);
149 vc.changeRange(var1, range);
149 vc.changeRange(var1, range);
150 check_variable_state<RangeType<10>>(var1, range);
150 check_variable_state<RangeType<10>>(var1, range);
151 QCOMPARE(provider->callCounter - initialCount, expectedIncrement);
151 QCOMPARE(provider->callCounter - initialCount, expectedIncrement);
152 }
152 }
153 };
153 };
154
154
155 QTEST_MAIN(TestVariableController2)
155 QTEST_MAIN(TestVariableController2)
156
156
157 #include "TestVariableController2.moc"
157 #include "TestVariableController2.moc"
@@ -1,64 +1,64
1 #include <Common/containers.h>
1 #include <containers/algorithms.hpp>
2 #include <Data/DataProviderParameters.h>
2 #include <Data/DataProviderParameters.h>
3 #include <Data/DateTimeRange.h>
3 #include <Data/DateTimeRange.h>
4 #include <Data/IDataProvider.h>
4 #include <Data/IDataProvider.h>
5 #include <Data/ScalarTimeSerie.h>
5 #include <Data/ScalarTimeSerie.h>
6 #include <QObject>
6 #include <QObject>
7 #include <QtTest>
7 #include <QtTest>
8 #include <TestUtils/TestProviders.h>
8 #include <TestUtils/TestProviders.h>
9 #include <Variable/VariableController2.h>
9 #include <Variable/VariableController2.h>
10 #include <algorithm>
10 #include <algorithm>
11 #include <cmath>
11 #include <cmath>
12 #include <numeric>
12 #include <numeric>
13
13
14 #define TEST_VC2_FIXTURE(slope) \
14 #define TEST_VC2_FIXTURE(slope) \
15 VariableController2 vc; \
15 VariableController2 vc; \
16 auto provider = std::make_shared<SimpleRange<slope>>();
16 auto provider = std::make_shared<SimpleRange<slope>>();
17
17
18 #define TEST_VC2_CREATE_DEFAULT_VARS(name1, name2, name3) \
18 #define TEST_VC2_CREATE_DEFAULT_VARS(name1, name2, name3) \
19 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00), \
19 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00), \
20 QDate(2018, 8, 7), QTime(16, 00)); \
20 QDate(2018, 8, 7), QTime(16, 00)); \
21 auto name1 = vc.createVariable("name1", {}, provider, range); \
21 auto name1 = vc.createVariable("name1", {}, provider, range); \
22 auto name2 = vc.createVariable("name1", {}, provider, range); \
22 auto name2 = vc.createVariable("name1", {}, provider, range); \
23 auto name3 = vc.createVariable("name1", {}, provider, range); \
23 auto name3 = vc.createVariable("name1", {}, provider, range); \
24 vc.synchronize(name1, name2);
24 vc.synchronize(name1, name2);
25
25
26 class TestVariableController2Async : public QObject
26 class TestVariableController2Async : public QObject
27 {
27 {
28 Q_OBJECT
28 Q_OBJECT
29 public:
29 public:
30 explicit TestVariableController2Async(QObject* parent = nullptr)
30 explicit TestVariableController2Async(QObject* parent = nullptr)
31 : QObject(parent)
31 : QObject(parent)
32 {}
32 {}
33 signals:
33 signals:
34
34
35 private slots:
35 private slots:
36 void initTestCase() {}
36 void initTestCase() {}
37 void cleanupTestCase() {}
37 void cleanupTestCase() {}
38
38
39 void testSimplePan()
39 void testSimplePan()
40 {
40 {
41 TEST_VC2_FIXTURE(2);
41 TEST_VC2_FIXTURE(2);
42 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00),
42 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00),
43 QDate(2018, 8, 7), QTime(16, 00));
43 QDate(2018, 8, 7), QTime(16, 00));
44 int variableUpdated = 0;
44 int variableUpdated = 0;
45 auto var1 = vc.createVariable("var1", {}, provider, range);
45 auto var1 = vc.createVariable("var1", {}, provider, range);
46 auto var2 = vc.createVariable("var2", {}, provider, range);
46 auto var2 = vc.createVariable("var2", {}, provider, range);
47 auto var3 = vc.createVariable("var3", {}, provider, range);
47 auto var3 = vc.createVariable("var3", {}, provider, range);
48 connect(&(*var2), &Variable2::updated,
48 connect(&(*var2), &Variable2::updated,
49 [&variableUpdated]() { variableUpdated += 1; });
49 [&variableUpdated]() { variableUpdated += 1; });
50 vc.synchronize(var1, var2);
50 vc.synchronize(var1, var2);
51 vc.asyncChangeRange(var1, range + Seconds<double>{10000.});
51 vc.asyncChangeRange(var1, range + Seconds<double>{10000.});
52 vc.asyncChangeRange(var1, range + Seconds<double>{50000.});
52 vc.asyncChangeRange(var1, range + Seconds<double>{50000.});
53 vc.asyncChangeRange(var1, range + Seconds<double>{100000.});
53 vc.asyncChangeRange(var1, range + Seconds<double>{100000.});
54 vc.asyncChangeRange(var1, range + Seconds<double>{150000.});
54 vc.asyncChangeRange(var1, range + Seconds<double>{150000.});
55 while(!vc.isReady(var1) || !vc.isReady(var2))
55 while(!vc.isReady(var1) || !vc.isReady(var2))
56 {
56 {
57 QCoreApplication::processEvents();
57 QCoreApplication::processEvents();
58 }
58 }
59 }
59 }
60 };
60 };
61
61
62 QTEST_MAIN(TestVariableController2Async)
62 QTEST_MAIN(TestVariableController2Async)
63
63
64 #include "TestVariableController2Async.moc"
64 #include "TestVariableController2Async.moc"
@@ -1,138 +1,138
1 #include <Common/containers.h>
1 #include <containers/algorithms.hpp>
2 #include <Data/DataProviderParameters.h>
2 #include <Data/DataProviderParameters.h>
3 #include <Data/DateTimeRange.h>
3 #include <Data/DateTimeRange.h>
4 #include <Data/IDataProvider.h>
4 #include <Data/IDataProvider.h>
5 #include <Data/ScalarTimeSerie.h>
5 #include <Data/ScalarTimeSerie.h>
6 #include <QObject>
6 #include <QObject>
7 #include <QtTest>
7 #include <QtTest>
8 #include <TestUtils/TestProviders.h>
8 #include <TestUtils/TestProviders.h>
9 #include <Variable/VariableController2.h>
9 #include <Variable/VariableController2.h>
10 #include <algorithm>
10 #include <algorithm>
11 #include <cmath>
11 #include <cmath>
12 #include <numeric>
12 #include <numeric>
13
13
14 #define TEST_VC2_FIXTURE(slope) \
14 #define TEST_VC2_FIXTURE(slope) \
15 VariableController2 vc; \
15 VariableController2 vc; \
16 auto provider = std::make_shared<SimpleRange<slope>>();
16 auto provider = std::make_shared<SimpleRange<slope>>();
17
17
18 #define TEST_VC2_CREATE_DEFAULT_VARS(name1, name2, name3) \
18 #define TEST_VC2_CREATE_DEFAULT_VARS(name1, name2, name3) \
19 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00), \
19 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00), \
20 QDate(2018, 8, 7), QTime(16, 00)); \
20 QDate(2018, 8, 7), QTime(16, 00)); \
21 auto name1 = vc.createVariable("name1", {}, provider, range); \
21 auto name1 = vc.createVariable("name1", {}, provider, range); \
22 while(!vc.isReady(name1)) \
22 while(!vc.isReady(name1)) \
23 QCoreApplication::processEvents(); \
23 QCoreApplication::processEvents(); \
24 auto name2 = vc.cloneVariable(name1); \
24 auto name2 = vc.cloneVariable(name1); \
25 auto name3 = vc.cloneVariable(name2); \
25 auto name3 = vc.cloneVariable(name2); \
26 vc.synchronize(name1, name2); \
26 vc.synchronize(name1, name2); \
27 while(!vc.isReady(name1)) \
27 while(!vc.isReady(name1)) \
28 QCoreApplication::processEvents();
28 QCoreApplication::processEvents();
29
29
30 class TestVariableController2WithSync : public QObject
30 class TestVariableController2WithSync : public QObject
31 {
31 {
32 Q_OBJECT
32 Q_OBJECT
33 public:
33 public:
34 explicit TestVariableController2WithSync(QObject* parent = nullptr)
34 explicit TestVariableController2WithSync(QObject* parent = nullptr)
35 : QObject(parent)
35 : QObject(parent)
36 {}
36 {}
37 signals:
37 signals:
38
38
39 private slots:
39 private slots:
40 void initTestCase() {}
40 void initTestCase() {}
41 void cleanupTestCase() {}
41 void cleanupTestCase() {}
42
42
43 void testCreateVariable()
43 void testCreateVariable()
44 {
44 {
45 TEST_VC2_FIXTURE(2);
45 TEST_VC2_FIXTURE(2);
46 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00),
46 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00),
47 QDate(2018, 8, 7), QTime(16, 00));
47 QDate(2018, 8, 7), QTime(16, 00));
48 bool callbackCalled = false;
48 bool callbackCalled = false;
49 connect(&vc, &VariableController2::variableAdded,
49 connect(&vc, &VariableController2::variableAdded,
50 [&callbackCalled](std::shared_ptr<Variable2>) {
50 [&callbackCalled](std::shared_ptr<Variable2>) {
51 callbackCalled = true;
51 callbackCalled = true;
52 });
52 });
53 QVERIFY(!callbackCalled);
53 QVERIFY(!callbackCalled);
54 auto var1 = vc.createVariable("var1", {}, provider, range);
54 auto var1 = vc.createVariable("var1", {}, provider, range);
55 QVERIFY(SciQLop::containers::contains(vc.variables(), var1));
55 QVERIFY(cpp_utils::containers::contains(vc.variables(), var1));
56 QVERIFY(callbackCalled);
56 QVERIFY(callbackCalled);
57 }
57 }
58
58
59 void testDeleteVariable()
59 void testDeleteVariable()
60 {
60 {
61 TEST_VC2_FIXTURE(1);
61 TEST_VC2_FIXTURE(1);
62 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00),
62 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00),
63 QDate(2018, 8, 7), QTime(16, 00));
63 QDate(2018, 8, 7), QTime(16, 00));
64 bool callbackCalled = false;
64 bool callbackCalled = false;
65 connect(&vc, &VariableController2::variableDeleted,
65 connect(&vc, &VariableController2::variableDeleted,
66 [&callbackCalled](std::shared_ptr<Variable2>) {
66 [&callbackCalled](std::shared_ptr<Variable2>) {
67 callbackCalled = true;
67 callbackCalled = true;
68 });
68 });
69 auto var1 = vc.createVariable("var1", {}, provider, range);
69 auto var1 = vc.createVariable("var1", {}, provider, range);
70 QVERIFY(SciQLop::containers::contains(vc.variables(), var1));
70 QVERIFY(cpp_utils::containers::contains(vc.variables(), var1));
71 QVERIFY(!callbackCalled);
71 QVERIFY(!callbackCalled);
72 while(!vc.isReady(var1))
72 while(!vc.isReady(var1))
73 {
73 {
74 qApp->processEvents();
74 qApp->processEvents();
75 }
75 }
76 vc.deleteVariable(var1);
76 vc.deleteVariable(var1);
77 QVERIFY(!SciQLop::containers::contains(vc.variables(), var1));
77 QVERIFY(!cpp_utils::containers::contains(vc.variables(), var1));
78 QVERIFY(callbackCalled);
78 QVERIFY(callbackCalled);
79 }
79 }
80
80
81 void testGetData()
81 void testGetData()
82 {
82 {
83 TEST_VC2_FIXTURE(10);
83 TEST_VC2_FIXTURE(10);
84 TEST_VC2_CREATE_DEFAULT_VARS(var1, var2, var3);
84 TEST_VC2_CREATE_DEFAULT_VARS(var1, var2, var3);
85 check_variable_state<RangeType<10>>(var1, range);
85 check_variable_state<RangeType<10>>(var1, range);
86 auto newRange = var2->range() * 1.5 + Seconds<double>{1000.};
86 auto newRange = var2->range() * 1.5 + Seconds<double>{1000.};
87 vc.changeRange(var2, newRange);
87 vc.changeRange(var2, newRange);
88 check_variable_state<RangeType<10>>(var1, newRange);
88 check_variable_state<RangeType<10>>(var1, newRange);
89 check_variable_state<RangeType<10>>(var2, newRange);
89 check_variable_state<RangeType<10>>(var2, newRange);
90 check_variable_state<RangeType<10>>(var3, range);
90 check_variable_state<RangeType<10>>(var3, range);
91 }
91 }
92
92
93 void testZoom_data()
93 void testZoom_data()
94 {
94 {
95 QTest::addColumn<double>("zoom");
95 QTest::addColumn<double>("zoom");
96 QTest::newRow("Zoom IN 10x") << .1;
96 QTest::newRow("Zoom IN 10x") << .1;
97 QTest::newRow("Zoom OUT 10x") << 10.;
97 QTest::newRow("Zoom OUT 10x") << 10.;
98 QTest::newRow("Zoom IN 1x") << 1.;
98 QTest::newRow("Zoom IN 1x") << 1.;
99 }
99 }
100 void testZoom()
100 void testZoom()
101 {
101 {
102 TEST_VC2_FIXTURE(100);
102 TEST_VC2_FIXTURE(100);
103 TEST_VC2_CREATE_DEFAULT_VARS(var1, var2, var3);
103 TEST_VC2_CREATE_DEFAULT_VARS(var1, var2, var3);
104 check_variable_state<RangeType<100>>(var1, range);
104 check_variable_state<RangeType<100>>(var1, range);
105
105
106 QFETCH(double, zoom);
106 QFETCH(double, zoom);
107 range *= zoom;
107 range *= zoom;
108 vc.changeRange(var1, range);
108 vc.changeRange(var1, range);
109 check_variable_state<RangeType<100>>(var1, range);
109 check_variable_state<RangeType<100>>(var1, range);
110 check_variable_state<RangeType<100>>(var2, range);
110 check_variable_state<RangeType<100>>(var2, range);
111 }
111 }
112
112
113 void testPan_data()
113 void testPan_data()
114 {
114 {
115 QTest::addColumn<double>("pan");
115 QTest::addColumn<double>("pan");
116 QTest::newRow("Right 1000 seconds") << 1000.;
116 QTest::newRow("Right 1000 seconds") << 1000.;
117 QTest::newRow("Left 1000 seconds") << -1000.;
117 QTest::newRow("Left 1000 seconds") << -1000.;
118 QTest::newRow("Right 0.1 seconds") << .1;
118 QTest::newRow("Right 0.1 seconds") << .1;
119 QTest::newRow("Left 0.1 seconds") << -.1;
119 QTest::newRow("Left 0.1 seconds") << -.1;
120 }
120 }
121 void testPan()
121 void testPan()
122 {
122 {
123 TEST_VC2_FIXTURE(10);
123 TEST_VC2_FIXTURE(10);
124 TEST_VC2_CREATE_DEFAULT_VARS(var1, var2, var3);
124 TEST_VC2_CREATE_DEFAULT_VARS(var1, var2, var3);
125 check_variable_state<RangeType<10>>(var1, range);
125 check_variable_state<RangeType<10>>(var1, range);
126
126
127 QFETCH(double, pan);
127 QFETCH(double, pan);
128
128
129 range += Seconds<double>{pan};
129 range += Seconds<double>{pan};
130 vc.changeRange(var1, range);
130 vc.changeRange(var1, range);
131 check_variable_state<RangeType<10>>(var1, range);
131 check_variable_state<RangeType<10>>(var1, range);
132 check_variable_state<RangeType<10>>(var2, range);
132 check_variable_state<RangeType<10>>(var2, range);
133 }
133 }
134 };
134 };
135
135
136 QTEST_MAIN(TestVariableController2WithSync)
136 QTEST_MAIN(TestVariableController2WithSync)
137
137
138 #include "TestVariableController2WithSync.moc"
138 #include "TestVariableController2WithSync.moc"
@@ -1,83 +1,73
1 TestUtils = library('TestUtils', 'TestUtils/TestProviders.h', 'TestUtils/TestProviders.cpp',
1 TestUtils = library('TestUtils', 'TestUtils/TestProviders.h', 'TestUtils/TestProviders.cpp',
2 dependencies : [sciqlop_core, qt5test]
2 dependencies : [sciqlop_core, qt5test]
3 )
3 )
4
4
5
5
6 TestUtils_dep = declare_dependency(link_with : TestUtils,
6 TestUtils_dep = declare_dependency(link_with : TestUtils,
7 dependencies : [sciqlop_core, qt5test])
7 dependencies : [sciqlop_core, qt5test])
8
8
9
9
10
10
11 tests = [
11 tests = [
12 {
12 {
13 'name':'TestStringUtils',
14 'sources': ['Common/TestStringUtils.cpp'],
15 'deps': [sciqlop_core, qt5test]
16 },
17 {
18 'name':'TestContainers',
19 'sources': ['Common/TestContainers.cpp'],
20 'deps': [sciqlop_core, qt5test]
21 },
22 {
23 'name':'TestSyncGroup',
13 'name':'TestSyncGroup',
24 'sources': ['Variable/TestSyncGroup.cpp'],
14 'sources': ['Variable/TestSyncGroup.cpp'],
25 'deps': [sciqlop_core, qt5test]
15 'deps': [sciqlop_core, qt5test]
26 },
16 },
27 {
17 {
28 'name':'TestDateTimeRange',
18 'name':'TestDateTimeRange',
29 'sources': ['Data/TestDateTimeRange.cpp'],
19 'sources': ['Data/TestDateTimeRange.cpp'],
30 'deps': [sciqlop_core, qt5test]
20 'deps': [sciqlop_core, qt5test]
31 },
21 },
32 {
22 {
33 'name':'TestDataSourceController',
23 'name':'TestDataSourceController',
34 'sources': [
24 'sources': [
35 'DataSource/TestDataSourceController.cpp',
25 'DataSource/TestDataSourceController.cpp',
36 'DataSource/DataSourceItemBuilder.cpp'
26 'DataSource/DataSourceItemBuilder.cpp'
37 ],
27 ],
38 'deps': [sciqlop_core, qt5test]
28 'deps': [sciqlop_core, qt5test]
39 },
29 },
40 {
30 {
41 'name':'TestDataSourceItem',
31 'name':'TestDataSourceItem',
42 'sources': [
32 'sources': [
43 'DataSource/TestDataSourceItem.cpp',
33 'DataSource/TestDataSourceItem.cpp',
44 'DataSource/DataSourceItemBuilder.cpp'
34 'DataSource/DataSourceItemBuilder.cpp'
45 ],
35 ],
46 'deps': [sciqlop_core, qt5test]
36 'deps': [sciqlop_core, qt5test]
47 },
37 },
48 {
38 {
49 'name':'TestVariable',
39 'name':'TestVariable',
50 'sources': ['Variable/TestVariable.cpp'],
40 'sources': ['Variable/TestVariable.cpp'],
51 'deps': [sciqlop_core, qt5test]
41 'deps': [sciqlop_core, qt5test]
52 },
42 },
53 {
43 {
54 'name':'TestDownloader',
44 'name':'TestDownloader',
55 'sources': ['Network/TestDownloader.cpp'],
45 'sources': ['Network/TestDownloader.cpp'],
56 'deps': [sciqlop_core, qt5test, qt5Concurrent]
46 'deps': [sciqlop_core, qt5test, qt5Concurrent]
57 },
47 },
58 {
48 {
59 'name':'TestVariableController2',
49 'name':'TestVariableController2',
60 'sources': ['Variable/TestVariableController2.cpp'],
50 'sources': ['Variable/TestVariableController2.cpp'],
61 'deps': [sciqlop_core, qt5test, qt5Concurrent, TestUtils_dep]
51 'deps': [sciqlop_core, qt5test, qt5Concurrent, TestUtils_dep]
62 },
52 },
63 {
53 {
64 'name':'TestVariableController2Async',
54 'name':'TestVariableController2Async',
65 'sources': ['Variable/TestVariableController2Async.cpp'],
55 'sources': ['Variable/TestVariableController2Async.cpp'],
66 'deps': [sciqlop_core, qt5test, qt5Concurrent, TestUtils_dep]
56 'deps': [sciqlop_core, qt5test, qt5Concurrent, TestUtils_dep]
67 },
57 },
68 {
58 {
69 'name':'TestVariableController2WithSync',
59 'name':'TestVariableController2WithSync',
70 'sources': ['Variable/TestVariableController2WithSync.cpp'],
60 'sources': ['Variable/TestVariableController2WithSync.cpp'],
71 'deps': [sciqlop_core, qt5test, qt5Concurrent, TestUtils_dep]
61 'deps': [sciqlop_core, qt5test, qt5Concurrent, TestUtils_dep]
72 }
62 }
73 ]
63 ]
74
64
75 foreach unit_test : tests
65 foreach unit_test : tests
76 test_moc_files = qt5.preprocess(moc_sources : unit_test['sources'])
66 test_moc_files = qt5.preprocess(moc_sources : unit_test['sources'])
77 test_exe = executable(unit_test['name'],unit_test['sources'] , test_moc_files,
67 test_exe = executable(unit_test['name'],unit_test['sources'] , test_moc_files,
78 dependencies : unit_test['deps'],
68 dependencies : unit_test['deps'],
79 cpp_args : ['-DCORE_TESTS_RESOURCES_DIR="'+meson.current_source_dir()+'/../tests-resources"']
69 cpp_args : ['-DCORE_TESTS_RESOURCES_DIR="'+meson.current_source_dir()+'/../tests-resources"']
80 )
70 )
81 test('Test-' + unit_test['name'], test_exe, args: ['-teamcity', '-o', '@0@.teamcity.txt'.format(unit_test['name'])])
71 test('Test-' + unit_test['name'], test_exe, args: ['-teamcity', '-o', '@0@.teamcity.txt'.format(unit_test['name'])])
82 endforeach
72 endforeach
83
73
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now