##// END OF EJS Templates
Basic asynchronous variable update, still a lot to do...
jeandet -
r17:895ab1d87afd
parent child
Show More
@@ -0,0 +1,53
1 #include <QThreadPool>
2 #include <QRunnable>
3 #include <QObject>
4 #include <QReadWriteLock>
5
6 #include "Variable/VariableSynchronizationGroup2.h"
7 #include <Variable/Variable.h>
8 #include <Common/containers.h>
9 #include <Common/debug.h>
10 #include <Data/DataProviderParameters.h>
11 #include <Data/DateTimeRangeHelper.h>
12 #include <Data/DateTimeRange.h>
13 #include <Data/IDataProvider.h>
14
15 struct VCTransaction
16 {
17 VCTransaction(QUuid refVar, DateTimeRange range, int ready)
18 :refVar{refVar},range{range},ready{ready}
19 {}
20 QUuid refVar;
21 DateTimeRange range;
22 int ready;
23 QReadWriteLock lock;
24 };
25
26 class TransactionExe:public QObject,public QRunnable
27 {
28 Q_OBJECT
29 std::shared_ptr<Variable> _variable;
30 std::shared_ptr<IDataProvider> _provider;
31 std::vector<DateTimeRange> _ranges;
32 DateTimeRange _range;
33 DateTimeRange _cacheRange;
34 public:
35 TransactionExe(const std::shared_ptr<Variable>& variable, const std::shared_ptr<IDataProvider>& provider,
36 const std::vector<DateTimeRange>& ranges, DateTimeRange range, DateTimeRange cacheRange)
37 :_variable{variable}, _provider{provider},_ranges{ranges},_range{range},_cacheRange{cacheRange}
38 {
39 setAutoDelete(true);
40 }
41 void run()override
42 {
43 std::vector<IDataSeries*> data;
44 for(auto range:_ranges)
45 {
46 data.push_back(_provider->getData(DataProviderParameters{{range}, _variable->metadata()}));
47 }
48 _variable->updateData(data, _range, _cacheRange, true);
49 emit transactionComplete();
50 }
51 signals:
52 void transactionComplete();
53 };
@@ -0,0 +1,67
1 #include <cmath>
2 #include <algorithm>
3 #include <numeric>
4 #include <QtTest>
5 #include <QObject>
6 #include <Variable/VariableController2.h>
7 #include <Data/DateTimeRange.h>
8 #include <Data/IDataProvider.h>
9 #include <Data/ScalarSeries.h>
10 #include <Data/DataProviderParameters.h>
11 #include <Common/containers.h>
12
13 #include <TestUtils/TestProviders.h>
14
15 #define TEST_VC2_FIXTURE(slope) \
16 VariableController2 vc; \
17 auto provider = std::make_shared<SimpleRange<slope>>();\
18
19 #define TEST_VC2_CREATE_DEFAULT_VARS(name1, name2, name3)\
20 auto range = DateTimeRange::fromDateTime(QDate(2018,8,7),QTime(14,00),\
21 QDate(2018,8,7),QTime(16,00));\
22 auto name1 = vc.createVariable("name1", {}, provider, range);\
23 auto name2 = vc.createVariable("name1", {}, provider, range);\
24 auto name3 = vc.createVariable("name1", {}, provider, range);\
25 vc.synchronize(name1,name2);\
26
27
28 class TestVariableController2Async : public QObject
29 {
30 Q_OBJECT
31 public:
32 explicit TestVariableController2Async(QObject *parent = nullptr) : QObject(parent){}
33 signals:
34
35 private slots:
36 void initTestCase(){}
37 void cleanupTestCase(){}
38
39 void testSimplePan()
40 {
41 TEST_VC2_FIXTURE(2);
42 auto range = DateTimeRange::fromDateTime(QDate(2018,8,7),QTime(14,00),
43 QDate(2018,8,7),QTime(16,00));
44 int variableUpdated=0;
45 auto var1 = vc.createVariable("var1", {}, provider, range);
46 auto var2 = vc.createVariable("var2", {}, provider, range);
47 auto var3 = vc.createVariable("var3", {}, provider, range);
48 connect(&(*var2),&Variable::updated, [&variableUpdated](){variableUpdated+=1;});
49 vc.synchronize(var1,var2);
50 vc.asyncChangeRange(var1,range+Seconds<double>{10000.});
51 vc.asyncChangeRange(var1,range+Seconds<double>{50000.});
52 vc.asyncChangeRange(var1,range+Seconds<double>{100000.});
53 vc.asyncChangeRange(var1,range+Seconds<double>{150000.});
54 while(!vc.isReady(var1) || !vc.isReady(var2))
55 {
56 QCoreApplication::processEvents();
57 }
58 }
59
60
61 };
62
63
64 QTEST_MAIN(TestVariableController2Async)
65
66 #include "TestVariableController2Async.moc"
67
@@ -1,191 +1,192
1 1 cmake_minimum_required(VERSION 3.6)
2 2 project(SciQLOPCore CXX)
3 3
4 4 OPTION (CPPCHECK "Analyzes the source code with cppcheck" OFF)
5 5 OPTION (CLANG_TIDY "Analyzes the source code with Clang Tidy" OFF)
6 6 OPTION (IWYU "Analyzes the source code with Include What You Use" OFF)
7 7
8 8 OPTION (Catalog "builds catalog API" OFF)
9 9
10 10 set(CMAKE_CXX_STANDARD 17)
11 11
12 12 set(CMAKE_AUTOMOC ON)
13 13 #https://gitlab.kitware.com/cmake/cmake/issues/15227
14 14 #set(CMAKE_AUTOUIC ON)
15 15 if(POLICY CMP0071)
16 16 cmake_policy(SET CMP0071 OLD)
17 17 endif()
18 18 set(CMAKE_AUTORCC ON)
19 19 set(CMAKE_INCLUDE_CURRENT_DIR ON)
20 20
21 21 find_package(Qt5 COMPONENTS Core Widgets Network PrintSupport Svg Test REQUIRED)
22 22
23 23 find_package(pybind11 CONFIG QUIET)
24 24 if (NOT pybind11_FOUND)
25 25 execute_process(COMMAND git submodule init external/pybind11 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
26 26 execute_process(COMMAND git submodule update external/pybind11 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
27 27 add_subdirectory(external/pybind11)
28 28 endif()
29 29
30 30 macro(declare_test testname testexe sources libraries)
31 31 add_executable(${testexe} ${sources})
32 32 target_link_libraries(${testexe} ${libraries})
33 33 add_test(NAME ${testname} COMMAND ${testexe})
34 34 endmacro(declare_test)
35 35
36 36 enable_testing()
37 37
38 38 FILE (GLOB_RECURSE core_SRCS
39 39 ./include/DataSource/DataSourceItemMergeHelper.h
40 40 ./include/DataSource/DataSourceItemAction.h
41 41 ./include/DataSource/DataSourceItem.h
42 42 ./include/DataSource/DataSourceController.h
43 43 ./include/Common/SortUtils.h
44 44 ./include/Common/spimpl.h
45 45 ./include/Common/MimeTypesDef.h
46 46 ./include/Common/MetaTypes.h
47 47 ./include/Common/StringUtils.h
48 48 ./include/Common/SignalWaiter.h
49 49 ./include/Common/DateUtils.h
50 50 ./include/Common/Numeric.h
51 51 ./include/Common/deprecate.h
52 52 ./include/Common/containers.h
53 53 ./include/Common/debug.h
54 54 ./include/Plugin/IPlugin.h
55 55 ./include/Data/ArrayDataIterator.h
56 56 ./include/Data/VariableRequest.h
57 57 ./include/Data/VectorSeries.h
58 58 ./include/Data/DateTimeRange.h
59 59 ./include/Data/DateTimeRangeHelper.h
60 60 ./include/Data/ScalarSeries.h
61 61 ./include/Data/DataSeriesMergeHelper.h
62 62 ./include/Data/DataSeries.h
63 63 ./include/Data/AcquisitionDataPacket.h
64 64 ./include/Data/DataSeriesType.h
65 65 ./include/Data/AcquisitionRequest.h
66 66 ./include/Data/SqpIterator.h
67 67 ./include/Data/ArrayData.h
68 68 ./include/Data/DataSeriesIterator.h
69 69 ./include/Data/DataSeriesUtils.h
70 70 ./include/Data/SpectrogramSeries.h
71 71 ./include/Data/Unit.h
72 72 ./include/Data/DataProviderParameters.h
73 73 ./include/Data/OptionalAxis.h
74 74 ./include/Data/IDataProvider.h
75 75 ./include/Data/IDataSeries.h
76 76 ./include/Network/NetworkController.h
77 77 ./include/Network/Downloader.h
78 78 ./include/Version.h
79 79 ./include/CoreGlobal.h
80 80 ./include/Visualization/VisualizationController.h
81 81 ./include/PluginManager/PluginManager.h
82 82 ./include/Variable/VariableModel.h
83 83 ./include/Variable/VariableAcquisitionWorker.h
84 84 ./include/Variable/VariableCacheStrategy.h
85 85 ./include/Variable/VariableSynchronizationGroup.h
86 86 ./include/Variable/VariableSynchronizationGroup2.h
87 87 ./include/Variable/ProportionalCacheStrategy.h
88 88 ./include/Variable/SingleThresholdCacheStrategy.h
89 89 ./include/Variable/VariableCacheStrategyFactory.h
90 90 ./include/Variable/Variable.h
91 91 ./include/Variable/VariableCacheController.h
92 92 ./include/Variable/VariableController.h
93 93 ./include/Variable/VariableController2.h
94 ./include/Variable/private/VCTransaction.h
94 95 ./include/Time/TimeController.h
95 96 ./include/Settings/ISqpSettingsBindable.h
96 97 ./include/Settings/SqpSettingsDefs.h
97 98
98 99 ./src/DataSource/DataSourceItem.cpp
99 100 ./src/DataSource/DataSourceItemAction.cpp
100 101 ./src/DataSource/DataSourceItemMergeHelper.cpp
101 102 ./src/DataSource/DataSourceController.cpp
102 103 ./src/Common/DateUtils.cpp
103 104 ./src/Common/MimeTypesDef.cpp
104 105 ./src/Common/StringUtils.cpp
105 106 ./src/Common/SignalWaiter.cpp
106 107 ./src/Data/ScalarSeries.cpp
107 108 ./src/Data/DataSeriesIterator.cpp
108 109 ./src/Data/OptionalAxis.cpp
109 110 ./src/Data/ArrayDataIterator.cpp
110 111 ./src/Data/SpectrogramSeries.cpp
111 112 ./src/Data/DataSeriesUtils.cpp
112 113 ./src/Data/VectorSeries.cpp
113 114 ./src/Network/NetworkController.cpp
114 115 ./src/Network/Downloader.cpp
115 116 ./src/Visualization/VisualizationController.cpp
116 117 ./src/PluginManager/PluginManager.cpp
117 118 ./src/Variable/VariableController.cpp
118 119 ./src/Variable/VariableController2.cpp
119 120 ./src/Variable/VariableModel.cpp
120 121 ./src/Variable/VariableCacheController.cpp
121 122 ./src/Variable/VariableSynchronizationGroup.cpp
122 123 ./src/Variable/VariableSynchronizationGroup2.cpp
123 124 ./src/Variable/Variable.cpp
124 125 ./src/Variable/VariableAcquisitionWorker.cpp
125 126 ./src/Version.cpp
126 127 ./src/Time/TimeController.cpp
127 128 ./src/Settings/SqpSettingsDefs.cpp
128 129
129 130 )
130 131
131 132
132 133 IF(Catalog)
133 134 FILE (GLOB_RECURSE core_catalog_SRCS
134 135 ./src/Catalogue/CatalogueController.cpp
135 136 ./include/Catalogue/CatalogueController.h
136 137 )
137 138 ELSE()
138 139 FILE (GLOB_RECURSE core_catalog_SRCS
139 140 )
140 141 ENDIF(Catalog)
141 142
142 143 add_definitions(-DCORE_STATIC)
143 144 #add_definitions(-DHIDE_DEPRECATED)
144 145 add_definitions(-DSCIQLOP_CRASH_ON_ERROR)
145 146
146 147 add_library(sciqlopcore ${core_SRCS} ${core_catalog_SRCS})
147 148 SET_TARGET_PROPERTIES(sciqlopcore PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
148 149
149 150 target_include_directories(sciqlopcore PUBLIC
150 151 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
151 152 $<INSTALL_INTERFACE:include/SciQLOP>
152 153 )
153 154
154 155 target_link_libraries(sciqlopcore PUBLIC
155 156 Qt5::Core
156 157 Qt5::Network
157 158 )
158 159
159 160 if(Catalog)
160 161 target_link_libraries(sciqlopcore PUBLIC
161 162 catalogs
162 163 )
163 164 endif()
164 165
165 166
166 167 pybind11_add_module(sciqlopqt src/pybind11_wrappers/QtWrappers.cpp)
167 168 target_link_libraries(sciqlopqt PUBLIC Qt5::Core)
168 169
169 170 pybind11_add_module(pysciqlopcore src/pybind11_wrappers/CoreWrappers.cpp)
170 171 target_link_libraries(pysciqlopcore PUBLIC sciqlopcore)
171 172
172 173 add_library(pysciqlop src/pybind11_wrappers/pywrappers_common.h)
173 174 target_link_libraries(pysciqlop PUBLIC Qt5::Core)
174 175 target_include_directories(pysciqlop PUBLIC
175 176 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/pybind11_wrappers/>
176 177 $<INSTALL_INTERFACE:include/SciQLOP/py_wrappers>
177 178 )
178 179
179 180 SET_PROPERTY(GLOBAL PROPERTY CORE_PYTHON_PATH ${CMAKE_CURRENT_BINARY_DIR})
180 181
181 182
182 183 install(TARGETS sciqlopcore EXPORT SciQLOPCoreConfig
183 184 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
184 185 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
185 186 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
186 187
187 188 install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/SciQLOP)
188 189 install(EXPORT SciQLOPCoreConfig DESTINATION share/SciQLOPCore/cmake)
189 190 export(TARGETS sciqlopcore FILE SciQLOPCoreConfig.cmake)
190 191
191 192 add_subdirectory(tests)
@@ -1,219 +1,224
1 1 #ifndef SCIQLOP_DATETIMERANGE_H
2 2 #define SCIQLOP_DATETIMERANGE_H
3 3
4 4 #include <cmath>
5 5 #include <QObject>
6 6
7 7 #include <QDebug>
8 8
9 9 #include <opaque/numeric_typedef.hpp>
10 10 #include <Common/DateUtils.h>
11 11 #include <Common/MetaTypes.h>
12 12 #include <Common/Numeric.h>
13 13
14 14
15 15 template <typename T>
16 16 struct Seconds : opaque::numeric_typedef<T, Seconds<T>> ,
17 17 opaque::binop::multipliable <Seconds<T>, true , Seconds<T>, T, T>,
18 18 opaque::binop::dividable <Seconds<T>, true , Seconds<T>, T, T>,
19 19 opaque::binop::addable <Seconds<T>, true , Seconds<T>, T, T>,
20 20 opaque::binop::subtractable <Seconds<T>, true , Seconds<T>, T, T>
21 21
22 22 {
23 23 using base = opaque::numeric_typedef<T, Seconds<T>>;
24 24 using base::base;
25 25 operator T () const {return this->value;}
26 26 };
27 27
28 28 struct InvalidDateTimeRangeTransformation{};
29 29
30 30 struct DateTimeRangeTransformation
31 31 {
32 32 double zoom;
33 33 Seconds<double> shift;
34 34 bool operator==(const DateTimeRangeTransformation& other) const
35 35 {
36 36 return SciQLop::numeric::almost_equal(zoom, other.zoom, 1) &&
37 37 SciQLop::numeric::almost_equal<double>(shift, other.shift, 1);
38 38 }
39 DateTimeRangeTransformation merge(const DateTimeRangeTransformation& other) const
40 {
41 return DateTimeRangeTransformation{zoom*other.zoom,shift+other.shift};
42 }
39 43 };
40 44
41 45 /**
42 46 * @brief The SqpRange struct holds the information of time parameters
43 47 */
44 48 struct DateTimeRange {
45 49 DateTimeRange()
46 50 :m_TStart(std::nan("")), m_TEnd(std::nan(""))
47 51 {}
48 52 DateTimeRange(double TStart, double TEnd)
49 53 :m_TStart(TStart), m_TEnd(TEnd)
50 54 {}
51 55 /// Creates SqpRange from dates and times
52 56 static DateTimeRange fromDateTime(const QDate &startDate, const QTime &startTime,
53 57 const QDate &endDate, const QTime &endTime)
54 58 {
55 59 return {DateUtils::secondsSinceEpoch(QDateTime{startDate, startTime, Qt::UTC}),
56 60 DateUtils::secondsSinceEpoch(QDateTime{endDate, endTime, Qt::UTC})};
57 61 }
58 62
59 63 static DateTimeRange fromDateTime(const QDateTime &start, const QDateTime &end)
60 64 {
61 65 return {DateUtils::secondsSinceEpoch(start),
62 66 DateUtils::secondsSinceEpoch(end)};
63 67 }
64 68
65 69 /// Start time (UTC)
66 70 double m_TStart;
67 71 /// End time (UTC)
68 72 double m_TEnd;
69 73
70 74 Seconds<double> delta()const noexcept{return Seconds<double>{this->m_TEnd - this->m_TStart};}
71 75
72 76 bool contains(const DateTimeRange &dateTime) const noexcept
73 77 {
74 78 return (m_TStart <= dateTime.m_TStart && m_TEnd >= dateTime.m_TEnd);
75 79 }
76 80
77 81 Seconds<double> center() const noexcept
78 82 {
79 83 return Seconds<double>((m_TStart + m_TEnd) / 2.);
80 84 }
81 85
82 86 bool intersect(const DateTimeRange &dateTime) const noexcept
83 87 {
84 88 return (m_TEnd >= dateTime.m_TStart && m_TStart <= dateTime.m_TEnd);
85 89 }
86 90
87 91 inline DateTimeRange transform(const DateTimeRangeTransformation& tr)const noexcept;
88 92
89 93 bool operator==(const DateTimeRange &other) const
90 94 {
91 95 return SciQLop::numeric::almost_equal(m_TStart, other.m_TStart, 1) &&
92 96 SciQLop::numeric::almost_equal(m_TEnd, other.m_TEnd, 1);
93 97 }
94 98
95 99 bool operator!=(const DateTimeRange &other) const { return !(*this == other); }
96 100
97 101 void grow(double factor)noexcept
98 102 {
99 103 double grow_v{delta()*(factor - 1.)/2.};
100 104 m_TStart -= grow_v;
101 105 m_TEnd += grow_v;
102 106 }
103 107
104 108 void shrink(double factor)noexcept
105 109 {
106 110 double shrink_v{this->delta()*(1. - factor)/2.};
107 111 m_TStart += shrink_v;
108 112 m_TEnd -= shrink_v;
109 113 }
110 114
111 115 DateTimeRange& operator*=(double k)
112 116 {
113 117 this->grow(k);
114 118 return *this;
115 119 }
116 120
117 121 DateTimeRange& operator/=(double k)
118 122 {
119 123 this->shrink(k);
120 124 return *this;
121 125 }
122 126
123 127 // compute set difference
124 128 std::vector<DateTimeRange> operator-(const DateTimeRange& other)const
125 129 {
126 130 std::vector<DateTimeRange> result;
127 131 if(std::isnan(other.m_TStart)||std::isnan(other.m_TEnd)||!this->intersect(other))
128 132 {
129 133 result.emplace_back(m_TStart, m_TEnd);
130 134 }
131 135 else
132 136 {
133 137 if(this->m_TStart<other.m_TStart)
134 138 {
135 139 result.emplace_back(this->m_TStart, other.m_TStart);
136 140 }
137 141 if(this->m_TEnd>other.m_TEnd)
138 142 {
139 143 result.emplace_back(this->m_TEnd, other.m_TEnd);
140 144 }
141 145 }
142 146 return result;
143 147 }
144 148
145 149 };
146 150
147 151 template <class T>
148 152 DateTimeRange& operator+=(DateTimeRange&r, Seconds<T> offset)
149 153 {
150 154 shift(r,offset);
151 155 return r;
152 156 }
153 157
154 158 template <class T>
155 159 DateTimeRange& operator-=(DateTimeRange&r, Seconds<T> offset)
156 160 {
157 161 shift(r,-offset);
162 return r;
158 163 }
159 164
160 165 template <class T>
161 166 void shift(DateTimeRange& r, Seconds<T> offset)
162 167 {
163 168 r.m_TEnd+=static_cast<double>(offset);
164 169 r.m_TStart+=static_cast<double>(offset);
165 170 }
166 171
167 172 inline DateTimeRange operator*(const DateTimeRange& r, double k)
168 173 {
169 174 DateTimeRange result{r};
170 175 result.grow(k);
171 176 return result;
172 177 }
173 178
174 179 inline DateTimeRange operator/(const DateTimeRange& r, double k)
175 180 {
176 181 DateTimeRange result{r};
177 182 result.shrink(k);
178 183 return result;
179 184 }
180 185
181 186 template<class T>
182 187 DateTimeRange operator+(const DateTimeRange& r, Seconds<T> offset)
183 188 {
184 189 DateTimeRange result{r};
185 190 shift(result,offset);
186 191 return result;
187 192 }
188 193
189 194 template<class T>
190 195 DateTimeRange operator-(const DateTimeRange& r, Seconds<T> offset)
191 196 {
192 197 DateTimeRange result{r};
193 198 shift(result,-offset);
194 199 return result;
195 200 }
196 201
197 202 const auto INVALID_RANGE
198 203 = DateTimeRange{std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN()};
199 204
200 205 inline QDebug operator<<(QDebug d, DateTimeRange obj)
201 206 {
202 207 auto tendDateTimeStart = DateUtils::dateTime(obj.m_TStart);
203 208 auto tendDateTimeEnd = DateUtils::dateTime(obj.m_TEnd);
204 209
205 210 d << "ts: " << tendDateTimeStart << " te: " << tendDateTimeEnd;
206 211 return d;
207 212 }
208 213
209 214
210 215
211 216 DateTimeRange DateTimeRange::transform(const DateTimeRangeTransformation &tr) const noexcept
212 217 {
213 218 return DateTimeRange{*this} * tr.zoom + tr.shift;
214 219 }
215 220
216 221 // Required for using shared_ptr in signals/slots
217 222 SCIQLOP_REGISTER_META_TYPE(SQPRANGE_REGISTRY, DateTimeRange)
218 223
219 224 #endif // SCIQLOP_DATETIMERANGE_H
@@ -1,112 +1,108
1 1 #ifndef SCIQLOP_VARIABLE_H
2 2 #define SCIQLOP_VARIABLE_H
3 3
4 4 #include <QLoggingCategory>
5 5 #include <QObject>
6 6 #include <QUuid>
7 7 #include <QReadWriteLock>
8 8
9 9 #include "CoreGlobal.h"
10 10 #include <Data/DataSeriesIterator.h>
11 11 #include <Data/DataSeriesType.h>
12 12 #include <Data/DateTimeRange.h>
13 13
14 14
15 15 #include <Common/deprecate.h>
16 16 #include <Common/MetaTypes.h>
17 17 #include <Common/spimpl.h>
18 18
19 19 Q_DECLARE_LOGGING_CATEGORY(LOG_Variable)
20 20
21 21 class IDataSeries;
22 22 class QString;
23 23
24 24 /**
25 25 * @brief The Variable class represents a variable in SciQlop.
26 26 */
27 27 class SCIQLOP_CORE_EXPORT Variable : public QObject {
28 28
29 29 Q_OBJECT
30 30
31 31 public:
32 32 explicit Variable(const QString &name, const QVariantHash &metadata = {});
33 33
34 34 /// Copy ctor
35 35 explicit Variable(const Variable &other);
36 36
37 37 std::shared_ptr<Variable> clone() const;
38 38
39 39 QString name() const noexcept;
40 40 void setName(const QString &name) noexcept;
41 41 DateTimeRange range() const noexcept;
42 42 void setRange(const DateTimeRange &range, bool notify=false) noexcept;
43 43 DateTimeRange cacheRange() const noexcept;
44 44 void setCacheRange(const DateTimeRange &cacheRange) noexcept;
45 45
46 46 /// @return the number of points hold by the variable. The number of points is updated each time
47 47 /// the data series changes
48 48 unsigned int nbPoints() const noexcept;
49 49
50 50 /// Returns the real range of the variable, i.e. the min and max x-axis values of the data
51 51 /// series between the range of the variable. The real range is updated each time the variable
52 52 /// range or the data series changed
53 53 /// @return the real range, invalid range if the data series is null or empty
54 54 /// @sa setDataSeries()
55 55 /// @sa setRange()
56 56 std::optional<DateTimeRange> realRange() const noexcept;
57 57
58 58 /// @return the data of the variable, nullptr if there is no data
59 59 std::shared_ptr<IDataSeries> dataSeries() const noexcept;
60 60
61 61 /// @return the type of data that the variable holds
62 62 DataSeriesType type() const noexcept;
63 63
64 64 QVariantHash metadata() const noexcept;
65
66 void updateData(const std::vector<IDataSeries*>& dataSeries,
67 const DateTimeRange& newRange, const DateTimeRange& newCacheRange,
68 bool notify=true);
69
65 70 DEPRECATE(
71
66 72 bool contains(const DateTimeRange &range) const noexcept;
67 73 bool intersect(const DateTimeRange &range) const noexcept;
68 74 bool isInside(const DateTimeRange &range) const noexcept;
69 75
70 76 bool cacheContains(const DateTimeRange &range) const noexcept;
71 77 bool cacheIntersect(const DateTimeRange &range) const noexcept;
72 78 bool cacheIsInside(const DateTimeRange &range) const noexcept;
73 )
74 DEPRECATE(
75 79 QVector<DateTimeRange> provideNotInCacheRangeList(const DateTimeRange &range) const noexcept;
76 80 QVector<DateTimeRange> provideInCacheRangeList(const DateTimeRange &range) const noexcept;
77 )
78 DEPRECATE(
79 81 void mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept;
80 )
81
82 void updateData(const std::vector<IDataSeries*>& dataSeries,
83 const DateTimeRange& newRange, const DateTimeRange& newCacheRange,
84 bool notify=true);
85
86 DEPRECATE(
87 82 static QVector<DateTimeRange> provideNotInCacheRangeList(const DateTimeRange &oldRange,
88 const DateTimeRange &nextRange);
83 const DateTimeRange &nextRange);
89 84
90 85 static QVector<DateTimeRange> provideInCacheRangeList(const DateTimeRange &oldRange,
91 const DateTimeRange &nextRange);
92 )
86 const DateTimeRange &nextRange);
87 )
93 88
89 operator QUuid() {return _uuid;}
94 90 QUuid ID(){return _uuid;}
95 91 signals:
96 92 void updated();
97 DEPRECATE(
98 /// Signal emitted when when the data series of the variable is loaded for the first time
99 void dataInitialized();
93 DEPRECATE(
94 /// Signal emitted when when the data series of the variable is loaded for the first time
95 void dataInitialized();
100 96 )
101 private:
102 class VariablePrivate;
97 private:
98 class VariablePrivate;
103 99 spimpl::unique_impl_ptr<VariablePrivate> impl;
104 100 QUuid _uuid;
105 101 QReadWriteLock m_lock;
106 102 };
107 103
108 104 // Required for using shared_ptr in signals/slots
109 105 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_REGISTRY, std::shared_ptr<Variable>)
110 106 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_VECTOR_REGISTRY, QVector<std::shared_ptr<Variable> >)
111 107
112 108 #endif // SCIQLOP_VARIABLE_H
@@ -1,41 +1,43
1 1 #include <memory>
2 2 #include <vector>
3 3 #include <set>
4 4 #include <QHash>
5 5 #include <QObject>
6 6 #include <QMutexLocker>
7 7 #include <QUuid>
8 8 #include <QItemSelectionModel>
9 9 #include <Common/spimpl.h>
10 10 #include <Variable/Variable.h>
11 11 //#include <Variable/VariableSynchronizationGroup.h>
12 12 #include <Variable/VariableModel.h>
13 13 #include <Data/IDataProvider.h>
14 14 #include "Data/DateTimeRange.h"
15 15
16 16 class VariableController2: public QObject
17 17 {
18 18 class VariableController2Private;
19 19 Q_OBJECT
20 20
21 21 spimpl::unique_impl_ptr<VariableController2Private> impl;
22 22
23 23 public:
24 24 explicit VariableController2();
25 25 std::shared_ptr<Variable> createVariable(const QString &name, const QVariantHash &metadata,
26 26 const std::shared_ptr<IDataProvider>& provider,
27 27 const DateTimeRange &range);
28 28
29 29 void deleteVariable(const std::shared_ptr<Variable>& variable);
30 30 void changeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r);
31 31 void asyncChangeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r);
32 32 const std::set<std::shared_ptr<Variable>> variables();
33 33
34 bool isReady(const std::shared_ptr<Variable>& variable);
35
34 36 void synchronize(const std::shared_ptr<Variable>& var, const std::shared_ptr<Variable>& with);
35 37
36 38
37 39 signals:
38 40 void variableAdded(const std::shared_ptr<Variable>&);
39 41 void variableDeleted(const std::shared_ptr<Variable>&);
40 42
41 43 };
@@ -1,71 +1,75
1 1 #ifndef SCIQLOP_VARIABLESYNCHRONIZATIONGROUP2_H
2 2 #define SCIQLOP_VARIABLESYNCHRONIZATIONGROUP2_H
3 3
4 4 #include <QUuid>
5 5 #include <set>
6 6
7 7 #include "CoreGlobal.h"
8 8 #include <Common/spimpl.h>
9 9 #include <Common/containers.h>
10 10
11 11 /**
12 12 * @brief The VariableSynchronizationGroup2 class holds a list of Variables uuid which are synchronized
13 13 * @note This class is part of SciQLop internals, as a normal user you shouldn't have to care about it
14 14 */
15 15 class SCIQLOP_CORE_EXPORT VariableSynchronizationGroup2
16 16 {
17 17
18 18 public:
19 19 explicit VariableSynchronizationGroup2()=default;
20 20 /**
21 21 * @brief VariableSynchronizationGroup2 is a convenience ctor to build a group with a default variable
22 22 * @param variable
23 23 */
24 24 explicit VariableSynchronizationGroup2(QUuid variable)
25 25 :_variables{{variable}}
26 26 {}
27 27
28 28 /**
29 29 * @brief addVariable adds the given variable to the group, does nothing if the varaible is alredy in the group
30 30 * @param variable
31 31 * @sa removeVariable
32 32 */
33 33 void addVariable(QUuid variable) noexcept
34 34 {
35 35 this->_variables.insert(variable);
36 36 }
37 37
38 38 /**
39 39 * @brief removeVariable removes the given variable from the group, does nothing if the varaible is not in the group
40 40 * @param variable
41 41 * @sa addVariable
42 42 */
43 43 void removeVariable(QUuid variable) noexcept
44 44 {
45 45 this->_variables.erase(variable);
46 46 }
47 47
48 48 /**
49 49 * @brief contains checks if the given variable is in the group
50 50 * @param variable
51 51 * @return true if the variable is in the group
52 52 */
53 53 bool contains(QUuid variable) const noexcept
54 54 {
55 55 return SciQLop::containers::contains(this->_variables,variable);
56 56 }
57 57
58 58 /**
59 59 * @brief variables
60 60 * @return the list of synchronized variables in this group as a std::set
61 61 */
62 62 const std::set<QUuid> &variables() const noexcept
63 63 {
64 64 return this->_variables;
65 65 }
66 66
67 inline QUuid ID(){return _ID;}
68
69 operator QUuid() {return _ID;}
67 70 private:
68 71 std::set<QUuid> _variables;
72 QUuid _ID = QUuid::createUuid();
69 73 };
70 74
71 75 #endif // SCIQLOP_VARIABLESYNCHRONIZATIONGROUP2_H
@@ -1,199 +1,380
1 #include <QQueue>
2 #include <QThreadPool>
3 #include <QRunnable>
4 #include <QObject>
5
1 6 #include "Variable/VariableController2.h"
2 7 #include "Variable/VariableSynchronizationGroup2.h"
3 8 #include <Common/containers.h>
4 9 #include <Common/debug.h>
5 10 #include <Data/DataProviderParameters.h>
6 11 #include <Data/DateTimeRangeHelper.h>
12 #include <Data/DateTimeRange.h>
7 13 #include <Variable/VariableCacheStrategyFactory.h>
14 #include <Variable/private/VCTransaction.h>
15
16 class Transactions
17 {
18 QReadWriteLock _mutex{QReadWriteLock::Recursive};
19 std::map<QUuid,std::optional<std::shared_ptr<VCTransaction>>> _nextTransactions;
20 std::map<QUuid,std::optional<std::shared_ptr<VCTransaction>>> _pendingTransactions;
21 public:
22 void addEntry(QUuid id)
23 {
24 QWriteLocker lock{&_mutex};
25 _nextTransactions[id] = std::nullopt;
26 _pendingTransactions[id] = std::nullopt;
27 }
28
29 void removeEntry(QUuid id)
30 {
31 QWriteLocker lock{&_mutex};
32 _nextTransactions.erase(id);
33 _pendingTransactions.erase(id);
34 }
35
36 std::map<QUuid,std::optional<std::shared_ptr<VCTransaction>>> pendingTransactions()
37 {
38 QReadLocker lock{&_mutex};
39 return _pendingTransactions;
40 }
41
42 std::map<QUuid,std::optional<std::shared_ptr<VCTransaction>>> nextTransactions()
43 {
44 QReadLocker lock{&_mutex};
45 return _nextTransactions;
46 }
47
48 std::optional<std::shared_ptr<VCTransaction>> start(QUuid id)
49 {
50 QWriteLocker lock{&_mutex};
51 _pendingTransactions[id] = _nextTransactions[id];
52 _nextTransactions[id] = std::nullopt;
53 return _pendingTransactions[id];
54 }
55
56 void enqueue(QUuid id, std::shared_ptr<VCTransaction> transaction)
57 {
58 QWriteLocker lock{&_mutex};
59 _nextTransactions[id] = transaction;
60 }
61
62 void complete(QUuid id)
63 {
64 QWriteLocker lock{&_mutex};
65 _pendingTransactions[id] = std::nullopt;
66 }
67
68 bool active(QUuid id)
69 {
70 QReadLocker lock{&_mutex};
71 return _nextTransactions[id].has_value() && _pendingTransactions[id].has_value();
72 }
73 };
8 74
9 75 class VariableController2::VariableController2Private
10 76 {
77 QThreadPool _ThreadPool;
11 78 QMap<QUuid,std::shared_ptr<Variable>> _variables;
12 79 QMap<QUuid,std::shared_ptr<IDataProvider>> _providers;
13 80 QMap<QUuid,std::shared_ptr<VariableSynchronizationGroup2>> _synchronizationGroups;
81 Transactions _transactions;
82 QReadWriteLock _lock{QReadWriteLock::Recursive};
14 83 std::unique_ptr<VariableCacheStrategy> _cacheStrategy;
84
15 85 bool p_contains(const std::shared_ptr<Variable>& variable)
16 86 {
17 return _providers.contains(variable->ID());
87 QReadLocker lock{&_lock};
88 return _providers.contains(*variable);
18 89 }
19 90 bool v_contains(const std::shared_ptr<Variable>& variable)
20 91 {
92 QReadLocker lock{&_lock};
21 93 return SciQLop::containers::contains(this->_variables, variable);
22 94 }
23 95 bool sg_contains(const std::shared_ptr<Variable>& variable)
24 96 {
25 return _synchronizationGroups.contains(variable->ID());
97 QReadLocker lock{&_lock};
98 return _synchronizationGroups.contains(*variable);
26 99 }
27 100
28 void _changeRange(const std::shared_ptr<Variable>& var, DateTimeRange r)
101 void _transactionComplete(QUuid group, std::shared_ptr<VCTransaction> transaction)
102 {
103 {
104 QWriteLocker lock{&transaction->lock};
105 transaction->ready -=1;
106 }
107 if(transaction->ready==0)
108 {
109 _transactions.complete(group);
110 }
111 this->_processTransactions();
112 }
113 void _processTransactions()
114 {
115 QWriteLocker lock{&_lock};
116 auto nextTransactions = _transactions.nextTransactions();
117 auto pendingTransactions = _transactions.pendingTransactions();
118 for( auto [groupID, newTransaction] : nextTransactions)
119 {
120 if(newTransaction.has_value() && !pendingTransactions[groupID].has_value())
121 {
122 _transactions.start(groupID);
123 auto refVar = _variables[newTransaction.value()->refVar];
124 auto ranges = _computeAllRangesInGroup(refVar,newTransaction.value()->range);
125 for( auto const& [ID, range] : ranges)
126 {
127 auto provider = _providers[ID];
128 auto variable = _variables[ID];
129 auto [missingRanges, newCacheRange] = _computeMissingRanges(variable,range);
130 auto exe = new TransactionExe(_variables[ID], provider, missingRanges, range, newCacheRange);
131 QObject::connect(exe,
132 &TransactionExe::transactionComplete,
133 [groupID=groupID,transaction=newTransaction.value(),this]()
134 {
135 this->_transactionComplete(groupID, transaction);
136 }
137 );
138 _ThreadPool.start(exe);
139 }
140 }
141 }
142 }
143
144 std::map<QUuid,DateTimeRange> _computeAllRangesInGroup(const std::shared_ptr<Variable>& refVar, DateTimeRange r)
145 {
146 std::map<QUuid,DateTimeRange> ranges;
147 if(!DateTimeRangeHelper::hasnan(r))
148 {
149 auto group = _synchronizationGroups[*refVar];
150 if(auto transformation = DateTimeRangeHelper::computeTransformation(refVar->range(),r);
151 transformation.has_value())
152 {
153 for(auto varId:group->variables())
154 {
155 auto var = _variables[varId];
156 auto newRange = var->range().transform(transformation.value());
157 ranges[varId] = newRange;
158 }
159 }
160 else // force new range to all variables -> may be weird if more than one var in the group
161 // @TODO ensure that there is no side effects
162 {
163 for(auto varId:group->variables())
164 {
165 auto var = _variables[varId];
166 ranges[varId] = r;
167 }
168 }
169 }
170 else
171 {
172 SCIQLOP_ERROR(VariableController2Private, "Invalid range containing NaN");
173 }
174 return ranges;
175 }
176
177 std::pair<std::vector<DateTimeRange>,DateTimeRange> _computeMissingRanges(const std::shared_ptr<Variable>& var, DateTimeRange r)
29 178 {
30 auto provider = _providers[var->ID()];
31 179 DateTimeRange newCacheRange;
32 180 std::vector<DateTimeRange> missingRanges;
33 181 if(DateTimeRangeHelper::hasnan(var->cacheRange()))
34 182 {
35 183 newCacheRange = _cacheStrategy->computeRange(r,r);
36 184 missingRanges = {newCacheRange};
37 185 }
38 186 else
39 187 {
40 188 newCacheRange = _cacheStrategy->computeRange(var->cacheRange(),r);
41 189 missingRanges = newCacheRange - var->cacheRange();
42 190 }
191 return {missingRanges,newCacheRange};
192 }
193
194 void _changeRange(QUuid id, DateTimeRange r)
195 {
196 _lock.lockForRead();
197 auto var = _variables[id];
198 _lock.unlock();
199 _changeRange(var,r);
200 }
201 void _changeRange(const std::shared_ptr<Variable>& var, DateTimeRange r)
202 {
203 auto provider = _providers[*var];
204 auto [missingRanges, newCacheRange] = _computeMissingRanges(var,r);
43 205 std::vector<IDataSeries*> data;
44 206 for(auto range:missingRanges)
45 207 {
46 data.push_back(provider->getData(DataProviderParameters{{range},var->metadata()}));
208 data.push_back(provider->getData(DataProviderParameters{{range}, var->metadata()}));
47 209 }
48 var->updateData(data,r,newCacheRange,true);
210 var->updateData(data, r, newCacheRange, true);
49 211 }
50 212 public:
51 213 VariableController2Private(QObject* parent=Q_NULLPTR)
52 214 :_cacheStrategy(VariableCacheStrategyFactory::createCacheStrategy(CacheStrategy::SingleThreshold))
53 215 {
54 216 Q_UNUSED(parent);
217 this->_ThreadPool.setMaxThreadCount(32);
55 218 }
56 219
57 ~VariableController2Private() = default;
220 ~VariableController2Private()
221 {
222 while (this->_ThreadPool.activeThreadCount())
223 {
224 this->_ThreadPool.waitForDone(100);
225 }
226 }
58 227
59 228 std::shared_ptr<Variable> createVariable(const QString &name, const QVariantHash &metadata, std::shared_ptr<IDataProvider> provider)
60 229 {
230 QWriteLocker lock{&_lock};
61 231 auto newVar = std::make_shared<Variable>(name,metadata);
62 this->_variables[newVar->ID()] = newVar;
63 this->_providers[newVar->ID()] = std::move(provider);
64 this->_synchronizationGroups[newVar->ID()] = std::make_shared<VariableSynchronizationGroup2>(newVar->ID());
232 this->_variables[*newVar] = newVar;
233 this->_providers[*newVar] = std::move(provider);
234 auto group = std::make_shared<VariableSynchronizationGroup2>(newVar->ID());
235 this->_synchronizationGroups[*newVar] = group;
236 this->_transactions.addEntry(*group);
65 237 return newVar;
66 238 }
67 239
240 bool hasPendingTransactions(const std::shared_ptr<Variable>& variable)
241 {
242 QReadLocker lock{&_lock};
243 auto group = _synchronizationGroups[*variable];
244 return _transactions.active(*group);
245 }
246
68 247 void deleteVariable(const std::shared_ptr<Variable>& variable)
69 248 {
70 249 /*
71 250 * Removing twice a var is ok but a var without provider has to be a hard error
72 251 * this means we got the var controller in an inconsistent state
73 252 */
74 253 if(v_contains(variable))
75 this->_variables.remove(variable->ID());
254 {
255 QWriteLocker lock{&_lock};
256 this->_variables.remove(*variable);
257 }
76 258 if(p_contains(variable))
77 this->_providers.remove(variable->ID());
259 {
260 QWriteLocker lock{&_lock};
261 this->_providers.remove(*variable);
262 }
78 263 else
79 264 SCIQLOP_ERROR(VariableController2Private, "No provider found for given variable");
80 265 }
81 266
82 267 void asyncChangeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r)
83 268 {
84
85 }
86
87 void changeRange(const std::shared_ptr<Variable>& variable, DateTimeRange r)
88 {
89 269 if(p_contains(variable))
90 270 {
91 271 if(!DateTimeRangeHelper::hasnan(r))
92 272 {
93 auto group = _synchronizationGroups[variable->ID()];
94 if(auto transformation = DateTimeRangeHelper::computeTransformation(variable->range(),r);
95 transformation.has_value())
96 {
97 for(auto varId:group->variables())
98 {
99 auto var = _variables[varId];
100 auto newRange = var->range().transform(transformation.value());
101 _changeRange(var,newRange);
102 }
103 }
104 else // force new range to all variables -> may be weird if more than one var in the group
105 // @TODO ensure that there is no side effects
273 auto group = _synchronizationGroups[*variable];
274 // Just overwrite next transaction
106 275 {
107 for(auto varId:group->variables())
108 {
109 auto var = _variables[varId];
110 _changeRange(var,r);
111 }
276 QWriteLocker lock{&_lock};
277 _transactions.enqueue(*group,std::make_shared<VCTransaction>(variable->ID(), r, static_cast<int>(group->variables().size())));
112 278 }
279 _processTransactions();
113 280 }
114 281 else
115 282 {
116 283 SCIQLOP_ERROR(VariableController2Private, "Invalid range containing NaN");
117 284 }
118 285 }
119 286 else
120 287 {
121 288 SCIQLOP_ERROR(VariableController2Private, "No provider found for given variable");
122 289 }
123 290 }
124 291
292 void changeRange(const std::shared_ptr<Variable>& variable, DateTimeRange r)
293 {
294 auto ranges = _computeAllRangesInGroup(variable,r);
295 for( auto const& [ID, range] : ranges)
296 {
297 _changeRange(ID,range);
298 }
299 }
300
125 301 void synchronize(const std::shared_ptr<Variable>& var, const std::shared_ptr<Variable>& with)
126 302 {
127 303 if(v_contains(var) && v_contains(with))
128 304 {
129 305 if(sg_contains(var) && sg_contains(with))
130 306 {
131
307 QWriteLocker lock{&_lock};
132 308 auto dest_group = this->_synchronizationGroups[with->ID()];
133 this->_synchronizationGroups[var->ID()] = dest_group;
134 dest_group->addVariable(var->ID());
309 this->_synchronizationGroups[*var] = dest_group;
310 dest_group->addVariable(*var);
135 311 }
136 312 else
137 313 {
138 314 SCIQLOP_ERROR(VariableController2Private, "At least one of the given variables isn't in a sync group");
139 315 }
140 316 }
141 317 else
142 318 {
143 319 SCIQLOP_ERROR(VariableController2Private, "At least one of the given variables is not found");
144 320 }
145 321 }
146 322
147 323 const std::set<std::shared_ptr<Variable>> variables()
148 324 {
149 325 std::set<std::shared_ptr<Variable>> vars;
326 QReadLocker lock{&_lock};
150 327 for(const auto &var:_variables)
151 328 {
152 329 vars.insert(var);
153 330 }
154 331 return vars;
155 332 }
156 333
157 334 };
158 335
159 336 VariableController2::VariableController2()
160 337 :impl{spimpl::make_unique_impl<VariableController2Private>()}
161 338 {}
162 339
163 340 std::shared_ptr<Variable> VariableController2::createVariable(const QString &name, const QVariantHash &metadata, const std::shared_ptr<IDataProvider>& provider, const DateTimeRange &range)
164 341 {
165 342 auto var = impl->createVariable(name, metadata, provider);
166 343 emit variableAdded(var);
167 344 if(!DateTimeRangeHelper::hasnan(range))
168 345 impl->changeRange(var,range);
169 346 else
170 347 SCIQLOP_ERROR(VariableController2, "Creating a variable with default constructed DateTimeRange is an error");
171 348 return var;
172 349 }
173 350
174 351 void VariableController2::deleteVariable(const std::shared_ptr<Variable>& variable)
175 352 {
176 353 impl->deleteVariable(variable);
177 354 emit variableDeleted(variable);
178 355 }
179 356
180 357 void VariableController2::changeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r)
181 358 {
182 359 impl->changeRange(variable, r);
183 360 }
184 361
185 362 void VariableController2::asyncChangeRange(const std::shared_ptr<Variable> &variable, const DateTimeRange &r)
186 363 {
187 364 impl->asyncChangeRange(variable, r);
188 365 }
189 366
190 367 const std::set<std::shared_ptr<Variable> > VariableController2::variables()
191 368 {
192 369 return impl->variables();
193 370 }
194 371
372 bool VariableController2::isReady(const std::shared_ptr<Variable> &variable)
373 {
374 return impl->hasPendingTransactions(variable);
375 }
376
195 377 void VariableController2::synchronize(const std::shared_ptr<Variable> &var, const std::shared_ptr<Variable> &with)
196 378 {
197 379 impl->synchronize(var, with);
198 380 }
199
@@ -1,49 +1,50
1 1 add_definitions(-DCORE_TESTS_RESOURCES_DIR="${CMAKE_CURRENT_LIST_DIR}/../tests-resources")
2 2
3 3 FILE (GLOB_RECURSE TestUtilsSources
4 4 TestUtils/TestProviders.h
5 5 TestUtils/TestProviders.cpp
6 6 )
7 7
8 8 add_library(TestUtils ${TestUtilsSources})
9 9 target_link_libraries(TestUtils sciqlopcore Qt5::Test)
10 10
11 11 declare_test(TestStringUtils TestStringUtils Common/TestStringUtils.cpp "sciqlopcore;Qt5::Test")
12 12
13 13 declare_test(TestContainers TestContainers Common/TestContainers.cpp "sciqlopcore;Qt5::Test")
14 14 declare_test(TestSyncGroup TestSyncGroup Variable/TestSyncGroup.cpp "sciqlopcore;Qt5::Test")
15 15
16 16 declare_test(TestDateTimeRange TestDateTimeRange Data/TestDateTimeRange.cpp "sciqlopcore;Qt5::Test")
17 17
18 18
19 19 declare_test(TestDataSeriesUtils TestDataSeriesUtils Data/TestDataSeriesUtils.cpp "sciqlopcore;Qt5::Test")
20 20 declare_test(TestOptionalAxis TestOptionalAxis Data/TestOptionalAxis.cpp "sciqlopcore;Qt5::Test")
21 21 declare_test(TestSpectrogramSeries TestSpectrogramSeries
22 22 "Data/TestSpectrogramSeries.cpp;Data/DataSeriesBuilders.h;Data/DataSeriesBuilders.cpp;Data/DataSeriesTestsUtils.h;Data/DataSeriesTestsUtils.cpp"
23 23 "sciqlopcore;Qt5::Test")
24 24 declare_test(TestOneDimArrayData TestOneDimArrayData Data/TestOneDimArrayData.cpp "sciqlopcore;Qt5::Test")
25 25 declare_test(TestScalarSeries TestScalarSeries
26 26 "Data/TestScalarSeries.cpp;Data/DataSeriesBuilders.h;Data/DataSeriesBuilders.cpp;Data/DataSeriesTestsUtils.h;Data/DataSeriesTestsUtils.cpp"
27 27 "sciqlopcore;Qt5::Test")
28 28 declare_test(TestTwoDimArrayData TestTwoDimArrayData Data/TestTwoDimArrayData.cpp "sciqlopcore;Qt5::Test")
29 29 declare_test(TestVectorSeries TestVectorSeries
30 30 "Data/TestVectorSeries.cpp;Data/DataSeriesBuilders.h;Data/DataSeriesBuilders.cpp;Data/DataSeriesTestsUtils.h;Data/DataSeriesTestsUtils.cpp"
31 31 "sciqlopcore;Qt5::Test")
32 32
33 33 declare_test(TestDataSourceController TestDataSourceController
34 34 "DataSource/TestDataSourceController.cpp;DataSource/DataSourceItemBuilder.cpp"
35 35 "sciqlopcore;Qt5::Test")
36 36 declare_test(TestDataSourceItem TestDataSourceItem
37 37 "DataSource/TestDataSourceItem.cpp;DataSource/DataSourceItemBuilder.cpp"
38 38 "sciqlopcore;Qt5::Test")
39 39
40 40 declare_test(TestVariable TestVariable Variable/TestVariable.cpp "sciqlopcore;Qt5::Test")
41 41 declare_test(TestVariableCacheController TestVariableCacheController Variable/TestVariableCacheController.cpp "sciqlopcore;Qt5::Test")
42 42 declare_test(TestVariableController TestVariableController Variable/TestVariableController.cpp "sciqlopcore;Qt5::Test")
43 43 declare_test(TestVariableSync TestVariableSync Variable/TestVariableSync.cpp "sciqlopcore;Qt5::Test")
44 44
45 45 declare_test(TestDownloader TestDownloader Network/TestDownloader.cpp "sciqlopcore;Qt5::Test")
46 46
47 47
48 48 declare_test(TestVariableController2 TestVariableController2 Variable/TestVariableController2.cpp "sciqlopcore;TestUtils;Qt5::Test")
49 declare_test(TestVariableController2Async TestVariableController2Async Variable/TestVariableController2Async.cpp "sciqlopcore;TestUtils;Qt5::Test")
49 50 declare_test(TestVariableController2WithSync TestVariableController2WithSync Variable/TestVariableController2WithSync.cpp "sciqlopcore;TestUtils;Qt5::Test")
General Comments 0
You need to be logged in to leave comments. Login now