##// END OF EJS Templates
Removed old Variable impl...
jeandet -
r69:cc26524fb5d1
parent child
Show More
@@ -1,226 +1,199
1 cmake_minimum_required(VERSION 3.6)
1 cmake_minimum_required(VERSION 3.6)
2 project(SciQLOPCore CXX)
2 project(SciQLOPCore CXX)
3
3
4 OPTION (CPPCHECK "Analyzes the source code with cppcheck" OFF)
4 OPTION (CPPCHECK "Analyzes the source code with cppcheck" OFF)
5 OPTION (CLANG_TIDY "Analyzes the source code with Clang Tidy" OFF)
5 OPTION (CLANG_TIDY "Analyzes the source code with Clang Tidy" OFF)
6 OPTION (IWYU "Analyzes the source code with Include What You Use" OFF)
6 OPTION (IWYU "Analyzes the source code with Include What You Use" OFF)
7 OPTION (PyWrappers "Enables Python 3 wrappers" ON)
7 OPTION (PyWrappers "Enables Python 3 wrappers" ON)
8
8
9 OPTION (Catalog "builds catalog API" ON)
9 OPTION (Catalog "builds catalog API" ON)
10
10
11 set(CMAKE_CXX_STANDARD 17)
11 set(CMAKE_CXX_STANDARD 17)
12
12
13 set(CMAKE_AUTOMOC ON)
13 set(CMAKE_AUTOMOC ON)
14 #https://gitlab.kitware.com/cmake/cmake/issues/15227
14 #https://gitlab.kitware.com/cmake/cmake/issues/15227
15 #set(CMAKE_AUTOUIC ON)
15 #set(CMAKE_AUTOUIC ON)
16 if(POLICY CMP0071)
16 if(POLICY CMP0071)
17 cmake_policy(SET CMP0071 OLD)
17 cmake_policy(SET CMP0071 OLD)
18 endif()
18 endif()
19 set(CMAKE_AUTORCC ON)
19 set(CMAKE_AUTORCC ON)
20 set(CMAKE_INCLUDE_CURRENT_DIR ON)
20 set(CMAKE_INCLUDE_CURRENT_DIR ON)
21
21
22 find_package(Qt5 COMPONENTS Core Widgets Concurrent Network PrintSupport Svg Test REQUIRED)
22 find_package(Qt5 COMPONENTS Core Widgets Concurrent Network PrintSupport Svg Test REQUIRED)
23
23
24 if(PyWrappers)
24 if(PyWrappers)
25 find_package(pybind11 CONFIG QUIET)
25 find_package(pybind11 CONFIG QUIET)
26 if (NOT pybind11_FOUND)
26 if (NOT pybind11_FOUND)
27 if(NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/external/pybind11/CMakeLists.txt)
27 if(NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/external/pybind11/CMakeLists.txt)
28 message("Init submodule pybind11")
28 message("Init submodule pybind11")
29 execute_process(COMMAND git submodule init external/pybind11 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
29 execute_process(COMMAND git submodule init external/pybind11 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
30 execute_process(COMMAND git submodule update external/pybind11 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
30 execute_process(COMMAND git submodule update external/pybind11 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
31 endif()
31 endif()
32 add_subdirectory(external/pybind11)
32 add_subdirectory(external/pybind11)
33 endif()
33 endif()
34 endif()
34 endif()
35
35
36 find_package(catalogicpp CONFIG QUIET)
36 find_package(catalogicpp CONFIG QUIET)
37 if (NOT catalogicpp_FOUND)
37 if (NOT catalogicpp_FOUND)
38 if(NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/external/catalogicpp/CMakeLists.txt)
38 if(NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/external/catalogicpp/CMakeLists.txt)
39 message("Init submodule catalogicpp")
39 message("Init submodule catalogicpp")
40 execute_process(COMMAND git submodule init external/catalogicpp WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
40 execute_process(COMMAND git submodule init external/catalogicpp WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
41 execute_process(COMMAND git submodule update external/catalogicpp WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
41 execute_process(COMMAND git submodule update external/catalogicpp WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
42 endif()
42 endif()
43 add_subdirectory(external/catalogicpp)
43 add_subdirectory(external/catalogicpp)
44 endif()
44 endif()
45
45
46 find_package(TimeSeries CONFIG QUIET)
46 find_package(TimeSeries CONFIG QUIET)
47 if (NOT TimeSeries_FOUND)
47 if (NOT TimeSeries_FOUND)
48 if(NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/external/TimeSeries/CMakeLists.txt)
48 if(NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/external/TimeSeries/CMakeLists.txt)
49 message("Init submodule TimeSeries")
49 message("Init submodule TimeSeries")
50 execute_process(COMMAND git submodule init external/TimeSeries WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
50 execute_process(COMMAND git submodule init external/TimeSeries WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
51 execute_process(COMMAND git submodule update external/TimeSeries WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
51 execute_process(COMMAND git submodule update external/TimeSeries WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
52 endif()
52 endif()
53 add_subdirectory(external/TimeSeries)
53 add_subdirectory(external/TimeSeries)
54 endif()
54 endif()
55
55
56 macro(declare_test testname testexe sources libraries)
56 macro(declare_test testname testexe sources libraries)
57 add_executable(${testexe} ${sources})
57 add_executable(${testexe} ${sources})
58 target_link_libraries(${testexe} ${libraries})
58 target_link_libraries(${testexe} ${libraries})
59 add_test(NAME ${testname} COMMAND ${testexe})
59 add_test(NAME ${testname} COMMAND ${testexe})
60 endmacro(declare_test)
60 endmacro(declare_test)
61
61
62 enable_testing()
62 enable_testing()
63
63
64 FILE (GLOB_RECURSE core_SRCS
64 FILE (GLOB_RECURSE core_SRCS
65 ./include/DataSource/DataSourceItemMergeHelper.h
65 ./include/DataSource/DataSourceItemMergeHelper.h
66 ./include/DataSource/DataSourceItemAction.h
66 ./include/DataSource/DataSourceItemAction.h
67 ./include/DataSource/DataSourceItem.h
67 ./include/DataSource/DataSourceItem.h
68 ./include/DataSource/DataSourceController.h
68 ./include/DataSource/DataSourceController.h
69 ./include/Common/SortUtils.h
69 ./include/Common/SortUtils.h
70 ./include/Common/spimpl.h
70 ./include/Common/spimpl.h
71 ./include/Common/MimeTypesDef.h
71 ./include/Common/MimeTypesDef.h
72 ./include/Common/MetaTypes.h
72 ./include/Common/MetaTypes.h
73 ./include/Common/StringUtils.h
73 ./include/Common/StringUtils.h
74 ./include/Common/SignalWaiter.h
74 ./include/Common/SignalWaiter.h
75 ./include/Common/DateUtils.h
75 ./include/Common/DateUtils.h
76 ./include/Common/Numeric.h
76 ./include/Common/Numeric.h
77 ./include/Common/deprecate.h
77 ./include/Common/deprecate.h
78 ./include/Common/containers.h
78 ./include/Common/containers.h
79 ./include/Common/debug.h
79 ./include/Common/debug.h
80 ./include/Common/cpp_utils.h
80 ./include/Common/cpp_utils.h
81 ./include/Common/variant_with_base.h
82 ./include/Plugin/IPlugin.h
81 ./include/Plugin/IPlugin.h
83 ./include/Data/ArrayDataIterator.h
84 ./include/Data/VectorSeries.h
85 ./include/Data/VectorTimeSerie.h
82 ./include/Data/VectorTimeSerie.h
86 ./include/Data/DateTimeRange.h
83 ./include/Data/DateTimeRange.h
87 ./include/Data/DateTimeRangeHelper.h
84 ./include/Data/DateTimeRangeHelper.h
88 ./include/Data/ScalarSeries.h
89 ./include/Data/ScalarTimeSerie.h
85 ./include/Data/ScalarTimeSerie.h
90 ./include/Data/DataSeriesMergeHelper.h
91 ./include/Data/DataSeries.h
92 ./include/Data/DataSeriesType.h
86 ./include/Data/DataSeriesType.h
93 ./include/Data/SqpIterator.h
87 ./include/Data/SqpIterator.h
94 ./include/Data/ArrayData.h
95 ./include/Data/DataSeriesIterator.h
96 ./include/Data/DataSeriesUtils.h
97 ./include/Data/SpectrogramSeries.h
98 ./include/Data/SpectrogramTimeSerie.h
88 ./include/Data/SpectrogramTimeSerie.h
99 ./include/Data/Unit.h
100 ./include/Data/DataProviderParameters.h
89 ./include/Data/DataProviderParameters.h
101 ./include/Data/OptionalAxis.h
102 ./include/Data/IDataProvider.h
90 ./include/Data/IDataProvider.h
103 ./include/Data/IDataSeries.h
104 ./include/Network/NetworkController.h
91 ./include/Network/NetworkController.h
105 ./include/Network/Downloader.h
92 ./include/Network/Downloader.h
106 ./include/Version.h
93 ./include/Version.h
107 ./include/CoreGlobal.h
94 ./include/CoreGlobal.h
108 ./include/Visualization/VisualizationController.h
95 ./include/Visualization/VisualizationController.h
109 ./include/PluginManager/PluginManager.h
96 ./include/PluginManager/PluginManager.h
110 ./include/Variable/VariableModel2.h
97 ./include/Variable/VariableModel2.h
111 ./include/Variable/VariableCacheStrategy.h
112 ./include/Variable/VariableSynchronizationGroup2.h
98 ./include/Variable/VariableSynchronizationGroup2.h
113 ./include/Variable/ProportionalCacheStrategy.h
114 ./include/Variable/SingleThresholdCacheStrategy.h
115 ./include/Variable/VariableCacheStrategyFactory.h
116 ./include/Variable/Variable.h
117 ./include/Variable/Variable2.h
99 ./include/Variable/Variable2.h
118 ./include/Variable/VariableController2.h
100 ./include/Variable/VariableController2.h
119 ./include/Variable/private/VCTransaction.h
101 ./include/Variable/private/VCTransaction.h
120 ./include/Time/TimeController.h
102 ./include/Time/TimeController.h
121 ./include/Settings/ISqpSettingsBindable.h
103 ./include/Settings/ISqpSettingsBindable.h
122 ./include/Settings/SqpSettingsDefs.h
104 ./include/Settings/SqpSettingsDefs.h
123
105
124 ./src/DataSource/DataSourceItem.cpp
106 ./src/DataSource/DataSourceItem.cpp
125 ./src/DataSource/DataSourceItemAction.cpp
107 ./src/DataSource/DataSourceItemAction.cpp
126 ./src/DataSource/DataSourceItemMergeHelper.cpp
108 ./src/DataSource/DataSourceItemMergeHelper.cpp
127 ./src/DataSource/DataSourceController.cpp
109 ./src/DataSource/DataSourceController.cpp
128 ./src/Common/DateUtils.cpp
110 ./src/Common/DateUtils.cpp
129 ./src/Common/MimeTypesDef.cpp
111 ./src/Common/MimeTypesDef.cpp
130 ./src/Common/StringUtils.cpp
112 ./src/Common/StringUtils.cpp
131 ./src/Common/SignalWaiter.cpp
113 ./src/Common/SignalWaiter.cpp
132 ./src/Data/ScalarSeries.cpp
133 ./src/Data/ScalarTimeSerie.cpp
134 ./src/Data/DataSeriesIterator.cpp
135 ./src/Data/OptionalAxis.cpp
136 ./src/Data/ArrayDataIterator.cpp
137 ./src/Data/SpectrogramSeries.cpp
138 ./src/Data/DataSeriesUtils.cpp
139 ./src/Data/VectorSeries.cpp
140 ./src/Data/VectorTimeSerie.cpp
141 ./src/Network/NetworkController.cpp
114 ./src/Network/NetworkController.cpp
142 ./src/Network/Downloader.cpp
115 ./src/Network/Downloader.cpp
143 ./src/Visualization/VisualizationController.cpp
116 ./src/Visualization/VisualizationController.cpp
144 ./src/PluginManager/PluginManager.cpp
117 ./src/PluginManager/PluginManager.cpp
145 ./src/Variable/VariableController2.cpp
118 ./src/Variable/VariableController2.cpp
146 ./src/Variable/VariableModel2.cpp
119 ./src/Variable/VariableModel2.cpp
147 ./src/Variable/VariableSynchronizationGroup2.cpp
120 ./src/Variable/VariableSynchronizationGroup2.cpp
148 ./src/Variable/Variable.cpp
121 ./src/Variable/Variable.cpp
149 ./src/Variable/Variable2.cpp
122 ./src/Variable/Variable2.cpp
150 ./src/Version.cpp
123 ./src/Version.cpp
151 ./src/Time/TimeController.cpp
124 ./src/Time/TimeController.cpp
152 ./src/Settings/SqpSettingsDefs.cpp
125 ./src/Settings/SqpSettingsDefs.cpp
153
126
154 )
127 )
155
128
156
129
157 IF(Catalog)
130 IF(Catalog)
158 FILE (GLOB_RECURSE core_catalog_SRCS
131 FILE (GLOB_RECURSE core_catalog_SRCS
159 ./src/Catalogue/CatalogueController.cpp
132 ./src/Catalogue/CatalogueController.cpp
160 ./include/Catalogue/CatalogueController.h
133 ./include/Catalogue/CatalogueController.h
161 )
134 )
162 ELSE()
135 ELSE()
163 FILE (GLOB_RECURSE core_catalog_SRCS
136 FILE (GLOB_RECURSE core_catalog_SRCS
164 )
137 )
165 ENDIF(Catalog)
138 ENDIF(Catalog)
166
139
167 add_definitions(-DCORE_STATIC)
140 add_definitions(-DCORE_STATIC)
168 #add_definitions(-DHIDE_DEPRECATED)
141 #add_definitions(-DHIDE_DEPRECATED)
169 add_definitions(-DSCIQLOP_CRASH_ON_ERROR)
142 add_definitions(-DSCIQLOP_CRASH_ON_ERROR)
170
143
171 add_library(sciqlopcore ${core_SRCS} ${core_catalog_SRCS})
144 add_library(sciqlopcore ${core_SRCS} ${core_catalog_SRCS})
172 SET_TARGET_PROPERTIES(sciqlopcore PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
145 SET_TARGET_PROPERTIES(sciqlopcore PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
173 add_definitions(-DCORE_LIB)
146 add_definitions(-DCORE_LIB)
174
147
175 target_include_directories(sciqlopcore PUBLIC
148 target_include_directories(sciqlopcore PUBLIC
176 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
149 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
177 $<INSTALL_INTERFACE:include/SciQLOP>
150 $<INSTALL_INTERFACE:include/SciQLOP>
178 )
151 )
179
152
180 target_link_libraries(sciqlopcore PUBLIC
153 target_link_libraries(sciqlopcore PUBLIC
181 Qt5::Core
154 Qt5::Core
182 Qt5::Network
155 Qt5::Network
183 TimeSeries
156 TimeSeries
184 )
157 )
185
158
186 if(Catalog)
159 if(Catalog)
187 target_link_libraries(sciqlopcore PUBLIC
160 target_link_libraries(sciqlopcore PUBLIC
188 CatalogiCpp
161 CatalogiCpp
189 )
162 )
190 endif()
163 endif()
191
164
192
165
193 if(PyWrappers)
166 if(PyWrappers)
194 if(MINGW)
167 if(MINGW)
195 add_definitions(-D_hypot=hypot)
168 add_definitions(-D_hypot=hypot)
196 endif()
169 endif()
197 pybind11_add_module(sciqlopqt src/pybind11_wrappers/QtWrappers.cpp)
170 pybind11_add_module(sciqlopqt src/pybind11_wrappers/QtWrappers.cpp)
198 target_link_libraries(sciqlopqt PUBLIC Qt5::Core)
171 target_link_libraries(sciqlopqt PUBLIC Qt5::Core)
199
172
200 pybind11_add_module(pysciqlopcore src/pybind11_wrappers/CoreWrappers.cpp)
173 pybind11_add_module(pysciqlopcore src/pybind11_wrappers/CoreWrappers.cpp)
201 target_link_libraries(pysciqlopcore PUBLIC sciqlopcore)
174 target_link_libraries(pysciqlopcore PUBLIC sciqlopcore)
202
175
203 pybind11_add_module(pysciqlopcatalogs src/pybind11_wrappers/CatalogWrappers.cpp)
176 pybind11_add_module(pysciqlopcatalogs src/pybind11_wrappers/CatalogWrappers.cpp)
204 target_link_libraries(pysciqlopcatalogs PUBLIC sciqlopcore)
177 target_link_libraries(pysciqlopcatalogs PUBLIC sciqlopcore)
205
178
206 add_library(pysciqlop src/pybind11_wrappers/pywrappers_common.h)
179 add_library(pysciqlop src/pybind11_wrappers/pywrappers_common.h)
207 target_link_libraries(pysciqlop PUBLIC Qt5::Core)
180 target_link_libraries(pysciqlop PUBLIC Qt5::Core)
208 target_include_directories(pysciqlop PUBLIC
181 target_include_directories(pysciqlop PUBLIC
209 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/pybind11_wrappers/>
182 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/pybind11_wrappers/>
210 $<INSTALL_INTERFACE:include/SciQLOP/py_wrappers>
183 $<INSTALL_INTERFACE:include/SciQLOP/py_wrappers>
211 )
184 )
212 endif()
185 endif()
213
186
214 SET_PROPERTY(GLOBAL PROPERTY CORE_PYTHON_PATH ${CMAKE_CURRENT_BINARY_DIR})
187 SET_PROPERTY(GLOBAL PROPERTY CORE_PYTHON_PATH ${CMAKE_CURRENT_BINARY_DIR})
215
188
216
189
217 install(TARGETS sciqlopcore EXPORT SciQLOPCoreConfig
190 install(TARGETS sciqlopcore EXPORT SciQLOPCoreConfig
218 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
191 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
219 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
192 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
220 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
193 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
221
194
222 install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/SciQLOP)
195 install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/SciQLOP)
223 install(EXPORT SciQLOPCoreConfig DESTINATION share/SciQLOPCore/cmake)
196 install(EXPORT SciQLOPCoreConfig DESTINATION share/SciQLOPCore/cmake)
224 export(TARGETS sciqlopcore FILE SciQLOPCoreConfig.cmake)
197 export(TARGETS sciqlopcore FILE SciQLOPCoreConfig.cmake)
225
198
226 add_subdirectory(tests)
199 add_subdirectory(tests)
@@ -1,98 +1,97
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 <Common/deprecate.h>
8 #include <Common/spimpl.h>
8 #include <Common/spimpl.h>
9 #include <Common/variant_with_base.h>
10 #include <Data/DataSeriesType.h>
9 #include <Data/DataSeriesType.h>
11 #include <Data/DateTimeRange.h>
10 #include <Data/DateTimeRange.h>
12 #include <Data/ScalarTimeSerie.h>
11 #include <Data/ScalarTimeSerie.h>
13 #include <Data/SpectrogramTimeSerie.h>
12 #include <Data/SpectrogramTimeSerie.h>
14 #include <Data/VectorTimeSerie.h>
13 #include <Data/VectorTimeSerie.h>
15 #include <QDataStream>
14 #include <QDataStream>
16 #include <QObject>
15 #include <QObject>
17 #include <QReadWriteLock>
16 #include <QReadWriteLock>
18 #include <QUuid>
17 #include <QUuid>
19 #include <TimeSeries.h>
18 #include <TimeSeries.h>
20 #include <optional>
19 #include <optional>
21
20
22 class SCIQLOP_CORE_EXPORT Variable2 : public QObject
21 class SCIQLOP_CORE_EXPORT Variable2 : public QObject
23 {
22 {
24 Q_OBJECT
23 Q_OBJECT
25
24
26 public:
25 public:
27 explicit Variable2(const QString& name, const QVariantHash& metadata = {});
26 explicit Variable2(const QString& name, const QVariantHash& metadata = {});
28
27
29 /// Copy ctor
28 /// Copy ctor
30 explicit Variable2(const Variable2& other);
29 explicit Variable2(const Variable2& other);
31
30
32 std::shared_ptr<Variable2> clone() const;
31 std::shared_ptr<Variable2> clone() const;
33
32
34 QString name();
33 QString name();
35 void setName(const QString& name);
34 void setName(const QString& name);
36 DateTimeRange range();
35 DateTimeRange range();
37 void setRange(const DateTimeRange& range);
36 void setRange(const DateTimeRange& range);
38 std::optional<DateTimeRange> realRange();
37 std::optional<DateTimeRange> realRange();
39
38
40 std::size_t nbPoints();
39 std::size_t nbPoints();
41
40
42 /// @return the data of the variable, nullptr if there is no data
41 /// @return the data of the variable, nullptr if there is no data
43 std::shared_ptr<TimeSeries::ITimeSerie> data();
42 std::shared_ptr<TimeSeries::ITimeSerie> data();
44
43
45 /// @return the type of data that the variable holds
44 /// @return the type of data that the variable holds
46 DataSeriesType type();
45 DataSeriesType type();
47
46
48 QVariantHash metadata() const noexcept;
47 QVariantHash metadata() const noexcept;
49
48
50 // void setData(const std::vector<AnyTimeSerie*>& dataSeries,
49 // void setData(const std::vector<AnyTimeSerie*>& dataSeries,
51 // const DateTimeRange& range, bool notify = true);
50 // const DateTimeRange& range, bool notify = true);
52
51
53 void setData(const std::vector<TimeSeries::ITimeSerie*>& dataSeries,
52 void setData(const std::vector<TimeSeries::ITimeSerie*>& dataSeries,
54 const DateTimeRange& range, bool notify = true);
53 const DateTimeRange& range, bool notify = true);
55
54
56 static QByteArray
55 static QByteArray
57 mimeData(const std::vector<std::shared_ptr<Variable2>>& variables)
56 mimeData(const std::vector<std::shared_ptr<Variable2>>& variables)
58 {
57 {
59 auto encodedData = QByteArray{};
58 auto encodedData = QByteArray{};
60 QDataStream stream{&encodedData, QIODevice::WriteOnly};
59 QDataStream stream{&encodedData, QIODevice::WriteOnly};
61 for(auto& var : variables)
60 for(auto& var : variables)
62 {
61 {
63 stream << var->ID().toByteArray();
62 stream << var->ID().toByteArray();
64 }
63 }
65 return encodedData;
64 return encodedData;
66 }
65 }
67
66
68 static std::vector<QUuid> IDs(QByteArray mimeData)
67 static std::vector<QUuid> IDs(QByteArray mimeData)
69 {
68 {
70 std::vector<QUuid> variables;
69 std::vector<QUuid> variables;
71 QDataStream stream{mimeData};
70 QDataStream stream{mimeData};
72
71
73 QVariantList ids;
72 QVariantList ids;
74 stream >> ids;
73 stream >> ids;
75 std::transform(std::cbegin(ids), std::cend(ids),
74 std::transform(std::cbegin(ids), std::cend(ids),
76 std::back_inserter(variables),
75 std::back_inserter(variables),
77 [](const auto& id) { return id.toByteArray(); });
76 [](const auto& id) { return id.toByteArray(); });
78 return variables;
77 return variables;
79 }
78 }
80
79
81 operator QUuid() { return _uuid; }
80 operator QUuid() { return _uuid; }
82 QUuid ID() { return _uuid; }
81 QUuid ID() { return _uuid; }
83 signals:
82 signals:
84 void updated(QUuid ID);
83 void updated(QUuid ID);
85
84
86 private:
85 private:
87 struct VariablePrivate;
86 struct VariablePrivate;
88 spimpl::unique_impl_ptr<VariablePrivate> impl;
87 spimpl::unique_impl_ptr<VariablePrivate> impl;
89 QUuid _uuid;
88 QUuid _uuid;
90 QReadWriteLock m_lock;
89 QReadWriteLock m_lock;
91 };
90 };
92
91
93 // Required for using shared_ptr in signals/slots
92 // Required for using shared_ptr in signals/slots
94 // SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_REGISTRY, std::shared_ptr<Variable2>)
93 // SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_REGISTRY, std::shared_ptr<Variable2>)
95 // SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_VECTOR_REGISTRY,
94 // SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_VECTOR_REGISTRY,
96 // QVector<std::shared_ptr<Variable2>>)
95 // QVector<std::shared_ptr<Variable2>>)
97
96
98 #endif // SCIQLOP_VARIABLE2_H
97 #endif // SCIQLOP_VARIABLE2_H
@@ -1,451 +1,447
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 <Common/containers.h>
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/VariableCacheStrategyFactory.h>
17 #include <Variable/private/VCTransaction.h>
16 #include <Variable/private/VCTransaction.h>
18
17
19 class VariableController2::VariableController2Private
18 class VariableController2::VariableController2Private
20 {
19 {
21 struct threadSafeVaraiblesMaps
20 struct threadSafeVaraiblesMaps
22 {
21 {
23 inline void
22 inline void
24 addVariable(const std::shared_ptr<Variable2>& variable,
23 addVariable(const std::shared_ptr<Variable2>& variable,
25 const std::shared_ptr<IDataProvider>& provider,
24 const std::shared_ptr<IDataProvider>& provider,
26 const std::shared_ptr<VariableSynchronizationGroup2>&
25 const std::shared_ptr<VariableSynchronizationGroup2>&
27 synchronizationGroup)
26 synchronizationGroup)
28 {
27 {
29 QWriteLocker lock{&_lock};
28 QWriteLocker lock{&_lock};
30 _variables[*variable] = variable;
29 _variables[*variable] = variable;
31 _providers[*variable] = provider;
30 _providers[*variable] = provider;
32 _synchronizationGroups[*variable] = synchronizationGroup;
31 _synchronizationGroups[*variable] = synchronizationGroup;
33 }
32 }
34
33
35 inline void removeVariable(const std::shared_ptr<Variable2>& variable)
34 inline void removeVariable(const std::shared_ptr<Variable2>& variable)
36 {
35 {
37 QWriteLocker lock{&_lock};
36 QWriteLocker lock{&_lock};
38 _variables.erase(*variable);
37 _variables.erase(*variable);
39 _providers.remove(*variable);
38 _providers.remove(*variable);
40 _synchronizationGroups.remove(*variable);
39 _synchronizationGroups.remove(*variable);
41 }
40 }
42
41
43 inline void
42 inline void
44 synchronize(const std::shared_ptr<Variable2>& variable,
43 synchronize(const std::shared_ptr<Variable2>& variable,
45 const std::optional<std::shared_ptr<Variable2>>& with)
44 const std::optional<std::shared_ptr<Variable2>>& with)
46 {
45 {
47 QWriteLocker lock{&_lock};
46 QWriteLocker lock{&_lock};
48 if(with.has_value())
47 if(with.has_value())
49 {
48 {
50 auto newGroup = _synchronizationGroups[*with.value()];
49 auto newGroup = _synchronizationGroups[*with.value()];
51 newGroup->addVariable(*variable);
50 newGroup->addVariable(*variable);
52 _synchronizationGroups[*variable] = newGroup;
51 _synchronizationGroups[*variable] = newGroup;
53 }
52 }
54 else
53 else
55 {
54 {
56 _synchronizationGroups[*variable] =
55 _synchronizationGroups[*variable] =
57 std::make_shared<VariableSynchronizationGroup2>(*variable);
56 std::make_shared<VariableSynchronizationGroup2>(*variable);
58 }
57 }
59 }
58 }
60
59
61 inline std::shared_ptr<Variable2> variable(QUuid variable)
60 inline std::shared_ptr<Variable2> variable(QUuid variable)
62 {
61 {
63 QReadLocker lock{&_lock};
62 QReadLocker lock{&_lock};
64 auto it = _variables.find(variable);
63 auto it = _variables.find(variable);
65 #if __cplusplus > 201703L
64 #if __cplusplus > 201703L
66 [[unlikely]]
65 [[unlikely]]
67 #endif
66 #endif
68 if(it == _variables.end())
67 if(it == _variables.end())
69 SCIQLOP_ERROR(threadSafeVaraiblesMaps, "Unknown Variable");
68 SCIQLOP_ERROR(threadSafeVaraiblesMaps, "Unknown Variable");
70 return (*it).second;
69 return (*it).second;
71 }
70 }
72
71
73 inline std::shared_ptr<Variable2> variable(int index)
72 inline std::shared_ptr<Variable2> variable(int index)
74 {
73 {
75 QReadLocker lock{&_lock};
74 QReadLocker lock{&_lock};
76 #if __cplusplus > 201703L
75 #if __cplusplus > 201703L
77 [[unlikely]]
76 [[unlikely]]
78 #endif
77 #endif
79 if(!_variables.size() > index)
78 if(!_variables.size() > index)
80 SCIQLOP_ERROR(threadSafeVaraiblesMaps, "Index is out of bounds");
79 SCIQLOP_ERROR(threadSafeVaraiblesMaps, "Index is out of bounds");
81 auto it = _variables.cbegin();
80 auto it = _variables.cbegin();
82 while(index != 0)
81 while(index != 0)
83 {
82 {
84 index -= 1;
83 index -= 1;
85 it++;
84 it++;
86 }
85 }
87 return (*(it)).second;
86 return (*(it)).second;
88 }
87 }
89
88
90 inline const std::vector<std::shared_ptr<Variable2>> variables()
89 inline const std::vector<std::shared_ptr<Variable2>> variables()
91 {
90 {
92 std::vector<std::shared_ptr<Variable2>> vars;
91 std::vector<std::shared_ptr<Variable2>> vars;
93 QReadLocker lock{&_lock};
92 QReadLocker lock{&_lock};
94 for(const auto& [id, var] : _variables)
93 for(const auto& [id, var] : _variables)
95 {
94 {
96 vars.push_back(var);
95 vars.push_back(var);
97 }
96 }
98 return vars;
97 return vars;
99 }
98 }
100
99
101 inline std::shared_ptr<IDataProvider> provider(QUuid variable)
100 inline std::shared_ptr<IDataProvider> provider(QUuid variable)
102 {
101 {
103 QReadLocker lock{&_lock};
102 QReadLocker lock{&_lock};
104 #if __cplusplus > 201703L
103 #if __cplusplus > 201703L
105 [[unlikely]]
104 [[unlikely]]
106 #endif
105 #endif
107 if(!_providers.contains(variable))
106 if(!_providers.contains(variable))
108 SCIQLOP_ERROR(threadSafeVaraiblesMaps, "Unknown Variable");
107 SCIQLOP_ERROR(threadSafeVaraiblesMaps, "Unknown Variable");
109 return _providers[variable];
108 return _providers[variable];
110 }
109 }
111
110
112 inline std::shared_ptr<VariableSynchronizationGroup2> group(QUuid variable)
111 inline std::shared_ptr<VariableSynchronizationGroup2> group(QUuid variable)
113 {
112 {
114 QReadLocker lock{&_lock};
113 QReadLocker lock{&_lock};
115 #if __cplusplus > 201703L
114 #if __cplusplus > 201703L
116 [[unlikely]]
115 [[unlikely]]
117 #endif
116 #endif
118 if(!_synchronizationGroups.contains(variable))
117 if(!_synchronizationGroups.contains(variable))
119 SCIQLOP_ERROR(threadSafeVaraiblesMaps, "Unknown Variable");
118 SCIQLOP_ERROR(threadSafeVaraiblesMaps, "Unknown Variable");
120 return _synchronizationGroups[variable];
119 return _synchronizationGroups[variable];
121 }
120 }
122
121
123 inline bool has(const std::shared_ptr<Variable2>& variable)
122 inline bool has(const std::shared_ptr<Variable2>& variable)
124 {
123 {
125 QReadLocker lock{&_lock};
124 QReadLocker lock{&_lock};
126 return _variables.find(*variable) == _variables.end();
125 return _variables.find(*variable) == _variables.end();
127 }
126 }
128
127
129 private:
128 private:
130 std::map<QUuid, std::shared_ptr<Variable2>> _variables;
129 std::map<QUuid, std::shared_ptr<Variable2>> _variables;
131 QMap<QUuid, std::shared_ptr<IDataProvider>> _providers;
130 QMap<QUuid, std::shared_ptr<IDataProvider>> _providers;
132 QMap<QUuid, std::shared_ptr<VariableSynchronizationGroup2>>
131 QMap<QUuid, std::shared_ptr<VariableSynchronizationGroup2>>
133 _synchronizationGroups;
132 _synchronizationGroups;
134 QReadWriteLock _lock{QReadWriteLock::Recursive};
133 QReadWriteLock _lock{QReadWriteLock::Recursive};
135 } _maps;
134 } _maps;
136 std::vector<QUuid> _variablesToRemove;
135 std::vector<QUuid> _variablesToRemove;
137 QThreadPool* _ThreadPool;
136 QThreadPool* _ThreadPool;
138 VCTransactionsQueues _transactions;
137 VCTransactionsQueues _transactions;
139 std::unique_ptr<VariableCacheStrategy> _cacheStrategy;
140
138
141 void _transactionComplete(QUuid group,
139 void _transactionComplete(QUuid group,
142 std::shared_ptr<VCTransaction> transaction)
140 std::shared_ptr<VCTransaction> transaction)
143 {
141 {
144 if(transaction->done()) { _transactions.complete(group); }
142 if(transaction->done()) { _transactions.complete(group); }
145 this->_processTransactions();
143 this->_processTransactions();
146 }
144 }
147
145
148 void _cleanupVariables()
146 void _cleanupVariables()
149 {
147 {
150 for(auto id : _variablesToRemove)
148 for(auto id : _variablesToRemove)
151 {
149 {
152 auto v = this->variable(id);
150 auto v = this->variable(id);
153 if(!hasPendingTransactions(v))
151 if(!hasPendingTransactions(v))
154 {
152 {
155 _variablesToRemove.erase(std::remove(_variablesToRemove.begin(),
153 _variablesToRemove.erase(std::remove(_variablesToRemove.begin(),
156 _variablesToRemove.end(), id),
154 _variablesToRemove.end(), id),
157 _variablesToRemove.end());
155 _variablesToRemove.end());
158 this->deleteVariable(v);
156 this->deleteVariable(v);
159 }
157 }
160 }
158 }
161 }
159 }
162
160
163 void _processTransactions(bool fragmented = false)
161 void _processTransactions(bool fragmented = false)
164 {
162 {
165 auto nextTransactions = _transactions.nextTransactions();
163 auto nextTransactions = _transactions.nextTransactions();
166 auto pendingTransactions = _transactions.pendingTransactions();
164 auto pendingTransactions = _transactions.pendingTransactions();
167 for(auto [groupID, newTransaction] : nextTransactions)
165 for(auto [groupID, newTransaction] : nextTransactions)
168 {
166 {
169 if(newTransaction.has_value() &&
167 if(newTransaction.has_value() &&
170 !pendingTransactions[groupID].has_value())
168 !pendingTransactions[groupID].has_value())
171 {
169 {
172 _transactions.start(groupID);
170 _transactions.start(groupID);
173 auto refVar = _maps.variable(newTransaction.value()->refVar);
171 auto refVar = _maps.variable(newTransaction.value()->refVar);
174 auto ranges =
172 auto ranges =
175 _computeAllRangesInGroup(refVar, newTransaction.value()->range);
173 _computeAllRangesInGroup(refVar, newTransaction.value()->range);
176 for(auto const& [ID, range] : ranges)
174 for(auto const& [ID, range] : ranges)
177 {
175 {
178 auto provider = _maps.provider(ID);
176 auto provider = _maps.provider(ID);
179 auto variable = _maps.variable(ID);
177 auto variable = _maps.variable(ID);
180 if(fragmented)
178 if(fragmented)
181 {
179 {
182 auto missingRanges = _computeMissingRanges(variable, range);
180 auto missingRanges = _computeMissingRanges(variable, range);
183
181
184 auto exe =
182 auto exe =
185 new TransactionExe(variable, provider, missingRanges, range);
183 new TransactionExe(variable, provider, missingRanges, range);
186 QObject::connect(
184 QObject::connect(
187 exe, &TransactionExe::transactionComplete,
185 exe, &TransactionExe::transactionComplete,
188 [groupID = groupID, transaction = newTransaction.value(),
186 [groupID = groupID, transaction = newTransaction.value(),
189 this]() { this->_transactionComplete(groupID, transaction); });
187 this]() { this->_transactionComplete(groupID, transaction); });
190 _ThreadPool->start(exe);
188 _ThreadPool->start(exe);
191 }
189 }
192 else
190 else
193 {
191 {
194 auto exe = new TransactionExe(variable, provider, {range}, range);
192 auto exe = new TransactionExe(variable, provider, {range}, range);
195 QObject::connect(
193 QObject::connect(
196 exe, &TransactionExe::transactionComplete,
194 exe, &TransactionExe::transactionComplete,
197 [groupID = groupID, transaction = newTransaction.value(),
195 [groupID = groupID, transaction = newTransaction.value(),
198 this]() { this->_transactionComplete(groupID, transaction); });
196 this]() { this->_transactionComplete(groupID, transaction); });
199 _ThreadPool->start(exe);
197 _ThreadPool->start(exe);
200 }
198 }
201 }
199 }
202 }
200 }
203 }
201 }
204 // 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
205 // 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
206 // deleted if they are now idle
204 // deleted if they are now idle
207 _cleanupVariables();
205 _cleanupVariables();
208 }
206 }
209
207
210 std::map<QUuid, DateTimeRange>
208 std::map<QUuid, DateTimeRange>
211 _computeAllRangesInGroup(const std::shared_ptr<Variable2>& refVar,
209 _computeAllRangesInGroup(const std::shared_ptr<Variable2>& refVar,
212 DateTimeRange r)
210 DateTimeRange r)
213 {
211 {
214 std::map<QUuid, DateTimeRange> ranges;
212 std::map<QUuid, DateTimeRange> ranges;
215 if(!DateTimeRangeHelper::hasnan(r))
213 if(!DateTimeRangeHelper::hasnan(r))
216 {
214 {
217 auto group = _maps.group(*refVar);
215 auto group = _maps.group(*refVar);
218 if(auto transformation =
216 if(auto transformation =
219 DateTimeRangeHelper::computeTransformation(refVar->range(), r);
217 DateTimeRangeHelper::computeTransformation(refVar->range(), r);
220 transformation.has_value())
218 transformation.has_value())
221 {
219 {
222 for(auto varId : group->variables())
220 for(auto varId : group->variables())
223 {
221 {
224 auto var = _maps.variable(varId);
222 auto var = _maps.variable(varId);
225 auto newRange = var->range().transform(transformation.value());
223 auto newRange = var->range().transform(transformation.value());
226 ranges[varId] = newRange;
224 ranges[varId] = newRange;
227 }
225 }
228 }
226 }
229 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
230 // var in the group
228 // var in the group
231 // @TODO ensure that there is no side effects
229 // @TODO ensure that there is no side effects
232 {
230 {
233 for(auto varId : group->variables())
231 for(auto varId : group->variables())
234 {
232 {
235 auto var = _maps.variable(varId);
233 auto var = _maps.variable(varId);
236 ranges[varId] = r;
234 ranges[varId] = r;
237 }
235 }
238 }
236 }
239 }
237 }
240 else
238 else
241 {
239 {
242 SCIQLOP_ERROR(VariableController2Private, "Invalid range containing NaN");
240 SCIQLOP_ERROR(VariableController2Private, "Invalid range containing NaN");
243 }
241 }
244 return ranges;
242 return ranges;
245 }
243 }
246
244
247 std::vector<DateTimeRange>
245 std::vector<DateTimeRange>
248 _computeMissingRanges(const std::shared_ptr<Variable2>& var, DateTimeRange r)
246 _computeMissingRanges(const std::shared_ptr<Variable2>& var, DateTimeRange r)
249 {
247 {
250 return r - var->range();
248 return r - var->range();
251 }
249 }
252
250
253 void _changeRange(QUuid id, DateTimeRange r)
251 void _changeRange(QUuid id, DateTimeRange r)
254 {
252 {
255 _changeRange(_maps.variable(id), r);
253 _changeRange(_maps.variable(id), r);
256 }
254 }
257 void _changeRange(const std::shared_ptr<Variable2>& var, DateTimeRange r)
255 void _changeRange(const std::shared_ptr<Variable2>& var, DateTimeRange r)
258 {
256 {
259 auto provider = _maps.provider(*var);
257 auto provider = _maps.provider(*var);
260 auto missingRanges = _computeMissingRanges(var, r);
258 auto missingRanges = _computeMissingRanges(var, r);
261 std::vector<TimeSeries::ITimeSerie*> data;
259 std::vector<TimeSeries::ITimeSerie*> data;
262 for(auto range : missingRanges)
260 for(auto range : missingRanges)
263 {
261 {
264 data.push_back(
262 data.push_back(
265 provider->getData(DataProviderParameters{{range}, var->metadata()}));
263 provider->getData(DataProviderParameters{{range}, var->metadata()}));
266 }
264 }
267 data.push_back(var->data().get()); // might be smarter
265 data.push_back(var->data().get()); // might be smarter
268 var->setData(data, r, true);
266 var->setData(data, r, true);
269 }
267 }
270
268
271 public:
269 public:
272 VariableController2Private(QObject* parent = Q_NULLPTR)
270 VariableController2Private(QObject* parent = Q_NULLPTR)
273 : _cacheStrategy(VariableCacheStrategyFactory::createCacheStrategy(
274 CacheStrategy::SingleThreshold))
275 {
271 {
276 Q_UNUSED(parent);
272 Q_UNUSED(parent);
277 this->_ThreadPool = new QThreadPool();
273 this->_ThreadPool = new QThreadPool();
278 this->_ThreadPool->setMaxThreadCount(32);
274 this->_ThreadPool->setMaxThreadCount(32);
279 }
275 }
280
276
281 /*
277 /*
282 * This dtor has to like this even if this is ugly, because default dtor would
278 * This dtor has to like this even if this is ugly, because default dtor would
283 * rely on declaration order to destruct members and that would always lead to
279 * rely on declaration order to destruct members and that would always lead to
284 * regressions when modifying class members
280 * regressions when modifying class members
285 */
281 */
286 ~VariableController2Private() { delete this->_ThreadPool; }
282 ~VariableController2Private() { delete this->_ThreadPool; }
287
283
288 std::shared_ptr<Variable2>
284 std::shared_ptr<Variable2>
289 createVariable(const QString& name, const QVariantHash& metadata,
285 createVariable(const QString& name, const QVariantHash& metadata,
290 std::shared_ptr<IDataProvider> provider)
286 std::shared_ptr<IDataProvider> provider)
291 {
287 {
292 auto newVar = std::make_shared<Variable2>(name, metadata);
288 auto newVar = std::make_shared<Variable2>(name, metadata);
293 auto group = std::make_shared<VariableSynchronizationGroup2>(newVar->ID());
289 auto group = std::make_shared<VariableSynchronizationGroup2>(newVar->ID());
294 _maps.addVariable(newVar, std::move(provider), group);
290 _maps.addVariable(newVar, std::move(provider), group);
295 this->_transactions.addEntry(*group);
291 this->_transactions.addEntry(*group);
296 return newVar;
292 return newVar;
297 }
293 }
298
294
299 std::shared_ptr<Variable2> variable(QUuid ID) { return _maps.variable(ID); }
295 std::shared_ptr<Variable2> variable(QUuid ID) { return _maps.variable(ID); }
300
296
301 std::shared_ptr<Variable2> variable(int index)
297 std::shared_ptr<Variable2> variable(int index)
302 {
298 {
303 return _maps.variable(index);
299 return _maps.variable(index);
304 }
300 }
305
301
306 std::shared_ptr<Variable2>
302 std::shared_ptr<Variable2>
307 cloneVariable(const std::shared_ptr<Variable2>& variable)
303 cloneVariable(const std::shared_ptr<Variable2>& variable)
308 {
304 {
309 auto newVar = variable->clone();
305 auto newVar = variable->clone();
310 _maps.synchronize(newVar, std::nullopt);
306 _maps.synchronize(newVar, std::nullopt);
311 _maps.addVariable(newVar, _maps.provider(*variable), _maps.group(*newVar));
307 _maps.addVariable(newVar, _maps.provider(*variable), _maps.group(*newVar));
312 this->_transactions.addEntry(*_maps.group(*newVar));
308 this->_transactions.addEntry(*_maps.group(*newVar));
313 return newVar;
309 return newVar;
314 }
310 }
315
311
316 bool hasPendingTransactions(const std::shared_ptr<Variable2>& variable)
312 bool hasPendingTransactions(const std::shared_ptr<Variable2>& variable)
317 {
313 {
318 return _transactions.active(*_maps.group(*variable));
314 return _transactions.active(*_maps.group(*variable));
319 }
315 }
320
316
321 bool hasPendingTransactions()
317 bool hasPendingTransactions()
322 {
318 {
323 bool has = false;
319 bool has = false;
324 for(const auto& var : _maps.variables())
320 for(const auto& var : _maps.variables())
325 {
321 {
326 has |= _transactions.active(*_maps.group(*var));
322 has |= _transactions.active(*_maps.group(*var));
327 }
323 }
328 return has;
324 return has;
329 }
325 }
330
326
331 void deleteVariable(const std::shared_ptr<Variable2>& variable)
327 void deleteVariable(const std::shared_ptr<Variable2>& variable)
332 {
328 {
333 if(!hasPendingTransactions(variable))
329 if(!hasPendingTransactions(variable))
334 _maps.removeVariable(variable);
330 _maps.removeVariable(variable);
335 else
331 else
336 _variablesToRemove.push_back(variable->ID());
332 _variablesToRemove.push_back(variable->ID());
337 }
333 }
338
334
339 void asyncChangeRange(const std::shared_ptr<Variable2>& variable,
335 void asyncChangeRange(const std::shared_ptr<Variable2>& variable,
340 const DateTimeRange& r)
336 const DateTimeRange& r)
341 {
337 {
342 if(!DateTimeRangeHelper::hasnan(r))
338 if(!DateTimeRangeHelper::hasnan(r))
343 {
339 {
344 auto group = _maps.group(*variable);
340 auto group = _maps.group(*variable);
345 // Just overwrite next transaction
341 // Just overwrite next transaction
346 {
342 {
347 _transactions.enqueue(*group,
343 _transactions.enqueue(*group,
348 std::make_shared<VCTransaction>(
344 std::make_shared<VCTransaction>(
349 variable->ID(), r,
345 variable->ID(), r,
350 static_cast<int>(group->variables().size())));
346 static_cast<int>(group->variables().size())));
351 }
347 }
352 _processTransactions();
348 _processTransactions();
353 }
349 }
354 else
350 else
355 {
351 {
356 SCIQLOP_ERROR(VariableController2Private, "Invalid range containing NaN");
352 SCIQLOP_ERROR(VariableController2Private, "Invalid range containing NaN");
357 }
353 }
358 }
354 }
359
355
360 void changeRange(const std::shared_ptr<Variable2>& variable, DateTimeRange r)
356 void changeRange(const std::shared_ptr<Variable2>& variable, DateTimeRange r)
361 {
357 {
362 asyncChangeRange(variable, r);
358 asyncChangeRange(variable, r);
363 while(hasPendingTransactions(variable))
359 while(hasPendingTransactions(variable))
364 {
360 {
365 QCoreApplication::processEvents();
361 QCoreApplication::processEvents();
366 }
362 }
367 }
363 }
368
364
369 inline void synchronize(const std::shared_ptr<Variable2>& var,
365 inline void synchronize(const std::shared_ptr<Variable2>& var,
370 const std::shared_ptr<Variable2>& with)
366 const std::shared_ptr<Variable2>& with)
371 {
367 {
372 _maps.synchronize(var, with);
368 _maps.synchronize(var, with);
373 }
369 }
374
370
375 inline const std::vector<std::shared_ptr<Variable2>> variables()
371 inline const std::vector<std::shared_ptr<Variable2>> variables()
376 {
372 {
377 return _maps.variables();
373 return _maps.variables();
378 }
374 }
379 };
375 };
380
376
381 VariableController2::VariableController2()
377 VariableController2::VariableController2()
382 : impl{spimpl::make_unique_impl<VariableController2Private>()}
378 : impl{spimpl::make_unique_impl<VariableController2Private>()}
383 {}
379 {}
384
380
385 std::shared_ptr<Variable2> VariableController2::createVariable(
381 std::shared_ptr<Variable2> VariableController2::createVariable(
386 const QString& name, const QVariantHash& metadata,
382 const QString& name, const QVariantHash& metadata,
387 const std::shared_ptr<IDataProvider>& provider, const DateTimeRange& range)
383 const std::shared_ptr<IDataProvider>& provider, const DateTimeRange& range)
388 {
384 {
389 auto var = impl->createVariable(name, metadata, provider);
385 auto var = impl->createVariable(name, metadata, provider);
390 var->setRange(range); // even with no data this is it's range
386 var->setRange(range); // even with no data this is it's range
391 if(!DateTimeRangeHelper::hasnan(range))
387 if(!DateTimeRangeHelper::hasnan(range))
392 impl->asyncChangeRange(var, range);
388 impl->asyncChangeRange(var, range);
393 else
389 else
394 SCIQLOP_ERROR(VariableController2, "Creating a variable with default "
390 SCIQLOP_ERROR(VariableController2, "Creating a variable with default "
395 "constructed DateTimeRange is an error");
391 "constructed DateTimeRange is an error");
396 emit variableAdded(var);
392 emit variableAdded(var);
397 return var;
393 return var;
398 }
394 }
399
395
400 std::shared_ptr<Variable2>
396 std::shared_ptr<Variable2>
401 VariableController2::cloneVariable(const std::shared_ptr<Variable2>& variable)
397 VariableController2::cloneVariable(const std::shared_ptr<Variable2>& variable)
402 {
398 {
403 return impl->cloneVariable(variable);
399 return impl->cloneVariable(variable);
404 }
400 }
405
401
406 void VariableController2::deleteVariable(
402 void VariableController2::deleteVariable(
407 const std::shared_ptr<Variable2>& variable)
403 const std::shared_ptr<Variable2>& variable)
408 {
404 {
409 impl->deleteVariable(variable);
405 impl->deleteVariable(variable);
410 emit variableDeleted(variable);
406 emit variableDeleted(variable);
411 }
407 }
412
408
413 void VariableController2::changeRange(
409 void VariableController2::changeRange(
414 const std::shared_ptr<Variable2>& variable, const DateTimeRange& r)
410 const std::shared_ptr<Variable2>& variable, const DateTimeRange& r)
415 {
411 {
416 impl->changeRange(variable, r);
412 impl->changeRange(variable, r);
417 }
413 }
418
414
419 void VariableController2::asyncChangeRange(
415 void VariableController2::asyncChangeRange(
420 const std::shared_ptr<Variable2>& variable, const DateTimeRange& r)
416 const std::shared_ptr<Variable2>& variable, const DateTimeRange& r)
421 {
417 {
422 impl->asyncChangeRange(variable, r);
418 impl->asyncChangeRange(variable, r);
423 }
419 }
424
420
425 const std::vector<std::shared_ptr<Variable2>> VariableController2::variables()
421 const std::vector<std::shared_ptr<Variable2>> VariableController2::variables()
426 {
422 {
427 return impl->variables();
423 return impl->variables();
428 }
424 }
429
425
430 bool VariableController2::isReady(const std::shared_ptr<Variable2>& variable)
426 bool VariableController2::isReady(const std::shared_ptr<Variable2>& variable)
431 {
427 {
432 return !impl->hasPendingTransactions(variable);
428 return !impl->hasPendingTransactions(variable);
433 }
429 }
434
430
435 bool VariableController2::isReady() { return !impl->hasPendingTransactions(); }
431 bool VariableController2::isReady() { return !impl->hasPendingTransactions(); }
436
432
437 void VariableController2::synchronize(const std::shared_ptr<Variable2>& var,
433 void VariableController2::synchronize(const std::shared_ptr<Variable2>& var,
438 const std::shared_ptr<Variable2>& with)
434 const std::shared_ptr<Variable2>& with)
439 {
435 {
440 impl->synchronize(var, with);
436 impl->synchronize(var, with);
441 }
437 }
442
438
443 const std::vector<std::shared_ptr<Variable2>>
439 const std::vector<std::shared_ptr<Variable2>>
444 VariableController2::variables(const std::vector<QUuid>& ids)
440 VariableController2::variables(const std::vector<QUuid>& ids)
445 {
441 {
446 std::vector<std::shared_ptr<Variable2>> variables;
442 std::vector<std::shared_ptr<Variable2>> variables;
447 std::transform(std::cbegin(ids), std::cend(ids),
443 std::transform(std::cbegin(ids), std::cend(ids),
448 std::back_inserter(variables),
444 std::back_inserter(variables),
449 [this](const auto& id) { return impl->variable(id); });
445 [this](const auto& id) { return impl->variable(id); });
450 return variables;
446 return variables;
451 }
447 }
@@ -1,279 +1,278
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 <Common/StringUtils.h>
4 #include <Common/containers.h>
4 #include <Common/containers.h>
5 #include <Data/IDataSeries.h>
6 #include <DataSource/DataSourceController.h>
5 #include <DataSource/DataSourceController.h>
7 #include <QMimeData>
6 #include <QMimeData>
8 #include <QSize>
7 #include <QSize>
9 #include <QTimer>
8 #include <QTimer>
10 #include <Time/TimeController.h>
9 #include <Time/TimeController.h>
11 #include <Variable/Variable2.h>
10 #include <Variable/Variable2.h>
12 #include <Variable/VariableController2.h>
11 #include <Variable/VariableController2.h>
13 #include <Variable/VariableModel2.h>
12 #include <Variable/VariableModel2.h>
14 #include <unordered_map>
13 #include <unordered_map>
15
14
16 namespace
15 namespace
17 {
16 {
18 // Column indexes
17 // Column indexes
19 const auto NAME_COLUMN = 0;
18 const auto NAME_COLUMN = 0;
20 const auto TSTART_COLUMN = 1;
19 const auto TSTART_COLUMN = 1;
21 const auto TEND_COLUMN = 2;
20 const auto TEND_COLUMN = 2;
22 const auto NBPOINTS_COLUMN = 3;
21 const auto NBPOINTS_COLUMN = 3;
23 const auto UNIT_COLUMN = 4;
22 const auto UNIT_COLUMN = 4;
24 const auto MISSION_COLUMN = 5;
23 const auto MISSION_COLUMN = 5;
25 const auto PLUGIN_COLUMN = 6;
24 const auto PLUGIN_COLUMN = 6;
26 const auto NB_COLUMNS = 7;
25 const auto NB_COLUMNS = 7;
27
26
28 // Column properties
27 // Column properties
29 const auto DEFAULT_HEIGHT = 25;
28 const auto DEFAULT_HEIGHT = 25;
30 const auto DEFAULT_WIDTH = 100;
29 const auto DEFAULT_WIDTH = 100;
31
30
32 struct ColumnProperties
31 struct ColumnProperties
33 {
32 {
34 ColumnProperties(const QString& name = {}, int width = DEFAULT_WIDTH,
33 ColumnProperties(const QString& name = {}, int width = DEFAULT_WIDTH,
35 int height = DEFAULT_HEIGHT)
34 int height = DEFAULT_HEIGHT)
36 : m_Name{name}, m_Width{width}, m_Height{height}
35 : m_Name{name}, m_Width{width}, m_Height{height}
37 {}
36 {}
38
37
39 QString m_Name;
38 QString m_Name;
40 int m_Width;
39 int m_Width;
41 int m_Height;
40 int m_Height;
42 };
41 };
43
42
44 const auto COLUMN_PROPERTIES = QHash<int, ColumnProperties>{
43 const auto COLUMN_PROPERTIES = QHash<int, ColumnProperties>{
45 {NAME_COLUMN, {QObject::tr("Name")}},
44 {NAME_COLUMN, {QObject::tr("Name")}},
46 {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
45 {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
47 {TEND_COLUMN, {QObject::tr("tEnd"), 180}},
46 {TEND_COLUMN, {QObject::tr("tEnd"), 180}},
48 {NBPOINTS_COLUMN, {QObject::tr("Nb points")}},
47 {NBPOINTS_COLUMN, {QObject::tr("Nb points")}},
49 {UNIT_COLUMN, {QObject::tr("Unit")}},
48 {UNIT_COLUMN, {QObject::tr("Unit")}},
50 {MISSION_COLUMN, {QObject::tr("Mission")}},
49 {MISSION_COLUMN, {QObject::tr("Mission")}},
51 {PLUGIN_COLUMN, {QObject::tr("Plugin")}}};
50 {PLUGIN_COLUMN, {QObject::tr("Plugin")}}};
52
51
53 QString uniqueName(const QString& defaultName,
52 QString uniqueName(const QString& defaultName,
54 const std::vector<std::shared_ptr<Variable2>>& variables)
53 const std::vector<std::shared_ptr<Variable2>>& variables)
55 {
54 {
56 auto forbiddenNames = std::vector<QString>(variables.size());
55 auto forbiddenNames = std::vector<QString>(variables.size());
57 std::transform(variables.cbegin(), variables.cend(), forbiddenNames.begin(),
56 std::transform(variables.cbegin(), variables.cend(), forbiddenNames.begin(),
58 [](const auto& variable) { return variable->name(); });
57 [](const auto& variable) { return variable->name(); });
59 auto uniqueName = StringUtils::uniqueName(defaultName, forbiddenNames);
58 auto uniqueName = StringUtils::uniqueName(defaultName, forbiddenNames);
60 Q_ASSERT(!uniqueName.isEmpty());
59 Q_ASSERT(!uniqueName.isEmpty());
61
60
62 return uniqueName;
61 return uniqueName;
63 }
62 }
64
63
65 } // namespace
64 } // namespace
66
65
67 VariableModel2::VariableModel2(QObject* parent) : QAbstractTableModel{parent} {}
66 VariableModel2::VariableModel2(QObject* parent) : QAbstractTableModel{parent} {}
68
67
69 int VariableModel2::columnCount(const QModelIndex& parent) const
68 int VariableModel2::columnCount(const QModelIndex& parent) const
70 {
69 {
71 Q_UNUSED(parent);
70 Q_UNUSED(parent);
72
71
73 return NB_COLUMNS;
72 return NB_COLUMNS;
74 }
73 }
75
74
76 int VariableModel2::rowCount(const QModelIndex& parent) const
75 int VariableModel2::rowCount(const QModelIndex& parent) const
77 {
76 {
78 Q_UNUSED(parent);
77 Q_UNUSED(parent);
79 return _variables.size();
78 return _variables.size();
80 }
79 }
81
80
82 QVariant VariableModel2::data(const QModelIndex& index, int role) const
81 QVariant VariableModel2::data(const QModelIndex& index, int role) const
83 {
82 {
84 if(!index.isValid()) { return QVariant{}; }
83 if(!index.isValid()) { return QVariant{}; }
85
84
86 if(index.row() < 0 || index.row() >= rowCount()) { return QVariant{}; }
85 if(index.row() < 0 || index.row() >= rowCount()) { return QVariant{}; }
87
86
88 if(role == Qt::DisplayRole)
87 if(role == Qt::DisplayRole)
89 {
88 {
90 if(auto variable = _variables[index.row()])
89 if(auto variable = _variables[index.row()])
91 {
90 {
92 switch(index.column())
91 switch(index.column())
93 {
92 {
94 case NAME_COLUMN: return variable->name();
93 case NAME_COLUMN: return variable->name();
95 case TSTART_COLUMN:
94 case TSTART_COLUMN:
96 {
95 {
97 if(auto range = variable->realRange(); range.has_value())
96 if(auto range = variable->realRange(); range.has_value())
98 return DateUtils::dateTime(range.value().m_TStart)
97 return DateUtils::dateTime(range.value().m_TStart)
99 .toString(DATETIME_FORMAT);
98 .toString(DATETIME_FORMAT);
100 return QVariant{};
99 return QVariant{};
101 }
100 }
102 case TEND_COLUMN:
101 case TEND_COLUMN:
103 {
102 {
104 if(auto range = variable->realRange(); range.has_value())
103 if(auto range = variable->realRange(); range.has_value())
105 return DateUtils::dateTime(range.value().m_TEnd)
104 return DateUtils::dateTime(range.value().m_TEnd)
106 .toString(DATETIME_FORMAT);
105 .toString(DATETIME_FORMAT);
107 return QVariant{};
106 return QVariant{};
108 }
107 }
109 case NBPOINTS_COLUMN: return int(variable->nbPoints());
108 case NBPOINTS_COLUMN: return int(variable->nbPoints());
110 case UNIT_COLUMN:
109 case UNIT_COLUMN:
111 return variable->metadata().value(QStringLiteral("units"));
110 return variable->metadata().value(QStringLiteral("units"));
112 case MISSION_COLUMN:
111 case MISSION_COLUMN:
113 return variable->metadata().value(QStringLiteral("mission"));
112 return variable->metadata().value(QStringLiteral("mission"));
114 case PLUGIN_COLUMN:
113 case PLUGIN_COLUMN:
115 return variable->metadata().value(QStringLiteral("plugin"));
114 return variable->metadata().value(QStringLiteral("plugin"));
116 default:
115 default:
117 // No action
116 // No action
118 break;
117 break;
119 }
118 }
120 }
119 }
121 }
120 }
122 else if(role == VariableRoles::ProgressRole)
121 else if(role == VariableRoles::ProgressRole)
123 {
122 {
124 return QVariant{};
123 return QVariant{};
125 }
124 }
126
125
127 return QVariant{};
126 return QVariant{};
128 }
127 }
129
128
130 QVariant VariableModel2::headerData(int section, Qt::Orientation orientation,
129 QVariant VariableModel2::headerData(int section, Qt::Orientation orientation,
131 int role) const
130 int role) const
132 {
131 {
133 if(role != Qt::DisplayRole && role != Qt::SizeHintRole) { return QVariant{}; }
132 if(role != Qt::DisplayRole && role != Qt::SizeHintRole) { return QVariant{}; }
134
133
135 if(orientation == Qt::Horizontal)
134 if(orientation == Qt::Horizontal)
136 {
135 {
137 auto propertiesIt = COLUMN_PROPERTIES.find(section);
136 auto propertiesIt = COLUMN_PROPERTIES.find(section);
138 if(propertiesIt != COLUMN_PROPERTIES.cend())
137 if(propertiesIt != COLUMN_PROPERTIES.cend())
139 {
138 {
140 // Role is either DisplayRole or SizeHintRole
139 // Role is either DisplayRole or SizeHintRole
141 return (role == Qt::DisplayRole)
140 return (role == Qt::DisplayRole)
142 ? QVariant{propertiesIt->m_Name}
141 ? QVariant{propertiesIt->m_Name}
143 : QVariant{
142 : QVariant{
144 QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
143 QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
145 }
144 }
146 }
145 }
147
146
148 return QVariant{};
147 return QVariant{};
149 }
148 }
150
149
151 Qt::ItemFlags VariableModel2::flags(const QModelIndex& index) const
150 Qt::ItemFlags VariableModel2::flags(const QModelIndex& index) const
152 {
151 {
153 return QAbstractTableModel::flags(index) | Qt::ItemIsDragEnabled |
152 return QAbstractTableModel::flags(index) | Qt::ItemIsDragEnabled |
154 Qt::ItemIsDropEnabled;
153 Qt::ItemIsDropEnabled;
155 }
154 }
156
155
157 Qt::DropActions VariableModel2::supportedDropActions() const
156 Qt::DropActions VariableModel2::supportedDropActions() const
158 {
157 {
159 return Qt::CopyAction | Qt::MoveAction;
158 return Qt::CopyAction | Qt::MoveAction;
160 }
159 }
161
160
162 Qt::DropActions VariableModel2::supportedDragActions() const
161 Qt::DropActions VariableModel2::supportedDragActions() const
163 {
162 {
164 return Qt::CopyAction | Qt::MoveAction;
163 return Qt::CopyAction | Qt::MoveAction;
165 }
164 }
166
165
167 QStringList VariableModel2::mimeTypes() const
166 QStringList VariableModel2::mimeTypes() const
168 {
167 {
169 return {MIME_TYPE_VARIABLE_LIST, MIME_TYPE_TIME_RANGE};
168 return {MIME_TYPE_VARIABLE_LIST, MIME_TYPE_TIME_RANGE};
170 }
169 }
171
170
172 QMimeData* VariableModel2::mimeData(const QModelIndexList& indexes) const
171 QMimeData* VariableModel2::mimeData(const QModelIndexList& indexes) const
173 {
172 {
174 auto mimeData = new QMimeData;
173 auto mimeData = new QMimeData;
175 std::vector<std::shared_ptr<Variable2>> variables;
174 std::vector<std::shared_ptr<Variable2>> variables;
176
175
177 DateTimeRange firstTimeRange;
176 DateTimeRange firstTimeRange;
178 for(const auto& index : indexes)
177 for(const auto& index : indexes)
179 {
178 {
180 if(index.column() == 0)
179 if(index.column() == 0)
181 { // only the first column
180 { // only the first column
182 auto variable = _variables[index.row()];
181 auto variable = _variables[index.row()];
183 if(variable.get() && index.isValid())
182 if(variable.get() && index.isValid())
184 {
183 {
185 if(variables.size() == 0)
184 if(variables.size() == 0)
186 {
185 {
187 // Gets the range of the first variable
186 // Gets the range of the first variable
188 firstTimeRange = variable->range();
187 firstTimeRange = variable->range();
189 }
188 }
190 variables.push_back(variable);
189 variables.push_back(variable);
191 }
190 }
192 }
191 }
193 }
192 }
194
193
195 auto variablesEncodedData = Variable2::mimeData(variables);
194 auto variablesEncodedData = Variable2::mimeData(variables);
196 mimeData->setData(MIME_TYPE_VARIABLE_LIST, variablesEncodedData);
195 mimeData->setData(MIME_TYPE_VARIABLE_LIST, variablesEncodedData);
197
196
198 if(variables.size() == 1)
197 if(variables.size() == 1)
199 {
198 {
200 // No time range MIME data if multiple variables are dragged
199 // No time range MIME data if multiple variables are dragged
201 auto timeEncodedData = TimeController::mimeDataForTimeRange(firstTimeRange);
200 auto timeEncodedData = TimeController::mimeDataForTimeRange(firstTimeRange);
202 mimeData->setData(MIME_TYPE_TIME_RANGE, timeEncodedData);
201 mimeData->setData(MIME_TYPE_TIME_RANGE, timeEncodedData);
203 }
202 }
204
203
205 return mimeData;
204 return mimeData;
206 }
205 }
207
206
208 bool VariableModel2::canDropMimeData(const QMimeData* data,
207 bool VariableModel2::canDropMimeData(const QMimeData* data,
209 Qt::DropAction action, int row, int column,
208 Qt::DropAction action, int row, int column,
210 const QModelIndex& parent) const
209 const QModelIndex& parent) const
211 {
210 {
212 Q_UNUSED(column);
211 Q_UNUSED(column);
213 // drop of a product
212 // drop of a product
214 return data->hasFormat(MIME_TYPE_PRODUCT_LIST) ||
213 return data->hasFormat(MIME_TYPE_PRODUCT_LIST) ||
215 (data->hasFormat(MIME_TYPE_TIME_RANGE) && parent.isValid() &&
214 (data->hasFormat(MIME_TYPE_TIME_RANGE) && parent.isValid() &&
216 !data->hasFormat(MIME_TYPE_VARIABLE_LIST));
215 !data->hasFormat(MIME_TYPE_VARIABLE_LIST));
217 }
216 }
218
217
219 bool VariableModel2::dropMimeData(const QMimeData* data, Qt::DropAction action,
218 bool VariableModel2::dropMimeData(const QMimeData* data, Qt::DropAction action,
220 int row, int column,
219 int row, int column,
221 const QModelIndex& parent)
220 const QModelIndex& parent)
222 {
221 {
223 auto dropDone = false;
222 auto dropDone = false;
224
223
225 if(data->hasFormat(MIME_TYPE_PRODUCT_LIST))
224 if(data->hasFormat(MIME_TYPE_PRODUCT_LIST))
226 {
225 {
227 auto productList = DataSourceController::productsDataForMimeData(
226 auto productList = DataSourceController::productsDataForMimeData(
228 data->data(MIME_TYPE_PRODUCT_LIST));
227 data->data(MIME_TYPE_PRODUCT_LIST));
229
228
230 for(auto metaData : productList)
229 for(auto metaData : productList)
231 {
230 {
232 emit createVariable(metaData.toHash());
231 emit createVariable(metaData.toHash());
233 }
232 }
234
233
235 dropDone = true;
234 dropDone = true;
236 }
235 }
237 else if(data->hasFormat(MIME_TYPE_TIME_RANGE) && parent.isValid())
236 else if(data->hasFormat(MIME_TYPE_TIME_RANGE) && parent.isValid())
238 {
237 {
239 auto variable = _variables[parent.row()];
238 auto variable = _variables[parent.row()];
240 auto range =
239 auto range =
241 TimeController::timeRangeForMimeData(data->data(MIME_TYPE_TIME_RANGE));
240 TimeController::timeRangeForMimeData(data->data(MIME_TYPE_TIME_RANGE));
242
241
243 emit asyncChangeRange(variable, range);
242 emit asyncChangeRange(variable, range);
244
243
245 dropDone = true;
244 dropDone = true;
246 }
245 }
247
246
248 return dropDone;
247 return dropDone;
249 }
248 }
250
249
251 void VariableModel2::variableUpdated(QUuid id) noexcept
250 void VariableModel2::variableUpdated(QUuid id) noexcept
252 {
251 {
253 emit dataChanged(QModelIndex(), QModelIndex());
252 emit dataChanged(QModelIndex(), QModelIndex());
254 }
253 }
255
254
256 void VariableModel2::variableAdded(const std::shared_ptr<Variable2>& variable)
255 void VariableModel2::variableAdded(const std::shared_ptr<Variable2>& variable)
257 {
256 {
258 if(!SciQLop::containers::contains(_variables, variable))
257 if(!SciQLop::containers::contains(_variables, variable))
259 {
258 {
260 beginInsertRows(QModelIndex(), this->_variables.size(),
259 beginInsertRows(QModelIndex(), this->_variables.size(),
261 this->_variables.size());
260 this->_variables.size());
262 this->_variables.push_back(variable);
261 this->_variables.push_back(variable);
263 endInsertRows();
262 endInsertRows();
264 connect(variable.get(), &Variable2::updated, this,
263 connect(variable.get(), &Variable2::updated, this,
265 &VariableModel2::variableUpdated);
264 &VariableModel2::variableUpdated);
266 }
265 }
267 }
266 }
268
267
269 void VariableModel2::variableDeleted(const std::shared_ptr<Variable2>& variable)
268 void VariableModel2::variableDeleted(const std::shared_ptr<Variable2>& variable)
270 {
269 {
271 auto it = std::find(_variables.begin(), _variables.end(), variable);
270 auto it = std::find(_variables.begin(), _variables.end(), variable);
272 if(it != _variables.end())
271 if(it != _variables.end())
273 {
272 {
274 auto index = std::distance(_variables.begin(), it);
273 auto index = std::distance(_variables.begin(), it);
275 beginRemoveRows(QModelIndex(), index, index);
274 beginRemoveRows(QModelIndex(), index, index);
276 _variables.erase(it);
275 _variables.erase(it);
277 endRemoveRows();
276 endRemoveRows();
278 }
277 }
279 }
278 }
@@ -1,48 +1,43
1 #include <Visualization/VisualizationController.h>
2
3 #include <Variable/Variable.h>
4
5 #include <QMutex>
6 #include <QThread>
7
8 #include <QDir>
1 #include <QDir>
2 #include <QMutex>
9 #include <QStandardPaths>
3 #include <QStandardPaths>
4 #include <QThread>
5 #include <Visualization/VisualizationController.h>
10
6
11 Q_LOGGING_CATEGORY(LOG_VisualizationController, "VisualizationController")
7 Q_LOGGING_CATEGORY(LOG_VisualizationController, "VisualizationController")
12
8
13 class VisualizationController::VisualizationControllerPrivate {
9 class VisualizationController::VisualizationControllerPrivate
10 {
14 public:
11 public:
15 QMutex m_WorkingMutex;
12 QMutex m_WorkingMutex;
16 };
13 };
17
14
18 VisualizationController::VisualizationController(QObject *parent)
15 VisualizationController::VisualizationController(QObject* parent)
19 : impl{spimpl::make_unique_impl<VisualizationControllerPrivate>()}
16 : impl{spimpl::make_unique_impl<VisualizationControllerPrivate>()}
20 {
17 {
21 qCDebug(LOG_VisualizationController()) << tr("VisualizationController construction")
18 qCDebug(LOG_VisualizationController())
22 << QThread::currentThread();
19 << tr("VisualizationController construction") << QThread::currentThread();
23 }
20 }
24
21
25 VisualizationController::~VisualizationController()
22 VisualizationController::~VisualizationController()
26 {
23 {
27 qCDebug(LOG_VisualizationController()) << tr("VisualizationController destruction")
24 qCDebug(LOG_VisualizationController())
28 << QThread::currentThread();
25 << tr("VisualizationController destruction") << QThread::currentThread();
29 this->waitForFinish();
26 this->waitForFinish();
30 }
27 }
31
28
32 void VisualizationController::initialize()
29 void VisualizationController::initialize()
33 {
30 {
34 qCDebug(LOG_VisualizationController()) << tr("VisualizationController init")
31 qCDebug(LOG_VisualizationController())
35 << QThread::currentThread();
32 << tr("VisualizationController init") << QThread::currentThread();
36 impl->m_WorkingMutex.lock();
33 impl->m_WorkingMutex.lock();
37 qCDebug(LOG_VisualizationController()) << tr("VisualizationController init END");
34 qCDebug(LOG_VisualizationController())
35 << tr("VisualizationController init END");
38 }
36 }
39
37
40 void VisualizationController::finalize()
38 void VisualizationController::finalize() { impl->m_WorkingMutex.unlock(); }
41 {
42 impl->m_WorkingMutex.unlock();
43 }
44
39
45 void VisualizationController::waitForFinish()
40 void VisualizationController::waitForFinish()
46 {
41 {
47 QMutexLocker locker{&impl->m_WorkingMutex};
42 QMutexLocker locker{&impl->m_WorkingMutex};
48 }
43 }
@@ -1,349 +1,239
1 #include "CoreWrappers.h"
1 #include "CoreWrappers.h"
2
2
3 #include "pywrappers_common.h"
3 #include "pywrappers_common.h"
4
4
5 #include <Data/DataSeriesType.h>
5 #include <Data/DataSeriesType.h>
6 #include <Data/IDataProvider.h>
6 #include <Data/IDataProvider.h>
7 #include <Data/OptionalAxis.h>
8 #include <Data/ScalarSeries.h>
9 #include <Data/SpectrogramSeries.h>
10 #include <Data/Unit.h>
11 #include <Data/VectorSeries.h>
12 #include <Network/Downloader.h>
7 #include <Network/Downloader.h>
13 #include <Time/TimeController.h>
8 #include <Time/TimeController.h>
14 #include <Variable/Variable2.h>
9 #include <Variable/Variable2.h>
15 #include <Variable/VariableController2.h>
10 #include <Variable/VariableController2.h>
16 #include <pybind11/chrono.h>
11 #include <pybind11/chrono.h>
17 #include <pybind11/embed.h>
12 #include <pybind11/embed.h>
18 #include <pybind11/functional.h>
13 #include <pybind11/functional.h>
19 #include <pybind11/numpy.h>
14 #include <pybind11/numpy.h>
20 #include <pybind11/operators.h>
15 #include <pybind11/operators.h>
21 #include <pybind11/pybind11.h>
16 #include <pybind11/pybind11.h>
22 #include <pybind11/stl.h>
17 #include <pybind11/stl.h>
23 #include <pybind11/stl_bind.h>
18 #include <pybind11/stl_bind.h>
24 #include <sstream>
19 #include <sstream>
25 #include <string>
20 #include <string>
26
21
27 namespace py = pybind11;
22 namespace py = pybind11;
28 using namespace std::chrono;
23 using namespace std::chrono;
29
24
30 template<typename T, typename U, bool row_major = true>
25 template<typename T, typename U, bool row_major = true>
31 void copy_vector(py::array_t<double>& t, py::array_t<double>& values, T& dest_t,
26 void copy_vector(py::array_t<double>& t, py::array_t<double>& values, T& dest_t,
32 U& dest_values)
27 U& dest_values)
33 {
28 {
34 auto t_view = t.unchecked<1>();
29 auto t_view = t.unchecked<1>();
35 auto values_view = values.unchecked<2>();
30 auto values_view = values.unchecked<2>();
36 if constexpr(row_major)
31 if constexpr(row_major)
37 {
32 {
38 for(std::size_t i = 0; i < t.size(); i++)
33 for(std::size_t i = 0; i < t.size(); i++)
39 {
34 {
40 dest_t[i] = t_view[i];
35 dest_t[i] = t_view[i];
41 dest_values[i] = {values_view(i, 0), values_view(i, 1),
36 dest_values[i] = {values_view(i, 0), values_view(i, 1),
42 values_view(i, 2)};
37 values_view(i, 2)};
43 }
38 }
44 }
39 }
45 else
40 else
46 {
41 {
47 for(std::size_t i = 0; i < t.size(); i++)
42 for(std::size_t i = 0; i < t.size(); i++)
48 {
43 {
49 dest_t[i] = t_view[i];
44 dest_t[i] = t_view[i];
50 dest_values[i] = {values_view(0, i), values_view(1, i),
45 dest_values[i] = {values_view(0, i), values_view(1, i),
51 values_view(2, i)};
46 values_view(2, i)};
52 }
47 }
53 }
48 }
54 }
49 }
55
50
56 template<typename T, typename U>
51 template<typename T, typename U>
57 void copy_scalar(py::array_t<double>& t, py::array_t<double>& values, T& dest_t,
52 void copy_scalar(py::array_t<double>& t, py::array_t<double>& values, T& dest_t,
58 U& dest_values)
53 U& dest_values)
59 {
54 {
60 auto t_view = t.unchecked<1>();
55 auto t_view = t.unchecked<1>();
61 auto values_view = values.unchecked<1>();
56 auto values_view = values.unchecked<1>();
62 for(std::size_t i = 0; i < t.size(); i++)
57 for(std::size_t i = 0; i < t.size(); i++)
63 {
58 {
64 dest_t[i] = t_view[i];
59 dest_t[i] = t_view[i];
65 dest_values[i] = values_view[i];
60 dest_values[i] = values_view[i];
66 }
61 }
67 }
62 }
68
63
69 template<typename T, typename U>
64 template<typename T, typename U>
70 void copy_spectro(py::array_t<double>& t, py::array_t<double>& values,
65 void copy_spectro(py::array_t<double>& t, py::array_t<double>& values,
71 T& dest_t, U& dest_values)
66 T& dest_t, U& dest_values)
72 {
67 {
73 auto t_view = t.unchecked<1>();
68 auto t_view = t.unchecked<1>();
74 auto values_view = values.unchecked<2>();
69 auto values_view = values.unchecked<2>();
75 const auto width = values.shape(0);
70 const auto width = values.shape(0);
76 for(std::size_t i = 0; i < t.size(); i++)
71 for(std::size_t i = 0; i < t.size(); i++)
77 {
72 {
78 dest_t[i] = t_view[i];
73 dest_t[i] = t_view[i];
79 for(int j = 0; j < width; j++)
74 for(int j = 0; j < width; j++)
80 {
75 {
81 dest_values[i * width + j] = values_view(j, i);
76 dest_values[i * width + j] = values_view(j, i);
82 }
77 }
83 }
78 }
84 }
79 }
85
80
86 PYBIND11_MODULE(pysciqlopcore, m)
81 PYBIND11_MODULE(pysciqlopcore, m)
87 {
82 {
88 pybind11::bind_vector<std::vector<double>>(m, "VectorDouble");
83 pybind11::bind_vector<std::vector<double>>(m, "VectorDouble");
89
84
90 py::enum_<DataSeriesType>(m, "DataSeriesType")
85 py::enum_<DataSeriesType>(m, "DataSeriesType")
91 .value("SCALAR", DataSeriesType::SCALAR)
86 .value("SCALAR", DataSeriesType::SCALAR)
92 .value("SPECTROGRAM", DataSeriesType::SPECTROGRAM)
87 .value("SPECTROGRAM", DataSeriesType::SPECTROGRAM)
93 .value("VECTOR", DataSeriesType::VECTOR)
88 .value("VECTOR", DataSeriesType::VECTOR)
94 .value("NONE", DataSeriesType::NONE)
89 .value("NONE", DataSeriesType::NONE)
95 .export_values();
90 .export_values();
96
91
97 py::class_<Unit>(m, "Unit")
98 .def_readwrite("name", &Unit::m_Name)
99 .def_readwrite("time_unit", &Unit::m_TimeUnit)
100 .def(py::self == py::self)
101 .def(py::self != py::self)
102 .def("__repr__", __repr__<Unit>);
103
104 py::class_<Response>(m, "Response")
92 py::class_<Response>(m, "Response")
105 .def("status_code", &Response::status_code);
93 .def("status_code", &Response::status_code);
106
94
107 py::class_<Downloader>(m, "Downloader")
95 py::class_<Downloader>(m, "Downloader")
108 .def_static("get", Downloader::get)
96 .def_static("get", Downloader::get)
109 .def_static("getAsync", Downloader::getAsync)
97 .def_static("getAsync", Downloader::getAsync)
110 .def_static("downloadFinished", Downloader::downloadFinished);
98 .def_static("downloadFinished", Downloader::downloadFinished);
111
99
112 py::class_<ArrayDataIteratorValue>(m, "ArrayDataIteratorValue")
113 .def_property_readonly("value", &ArrayDataIteratorValue::first);
114
115 py::class_<OptionalAxis>(m, "OptionalAxis")
116 .def("__len__", &OptionalAxis::size)
117 .def_property_readonly("size", &OptionalAxis::size)
118 .def("__getitem__",
119 [](OptionalAxis& ax, int key) {
120 return (*(ax.begin() + key)).first();
121 },
122 py::is_operator())
123 .def("__iter__",
124 [](OptionalAxis& ax) {
125 return py::make_iterator(ax.begin(), ax.end());
126 },
127 py::keep_alive<0, 1>());
128
129 py::class_<DataSeriesIteratorValue>(m, "DataSeriesIteratorValue")
130 .def_property_readonly("x", &DataSeriesIteratorValue::x)
131 .def_property_readonly("y", &DataSeriesIteratorValue::y)
132 .def("value",
133 py::overload_cast<>(&DataSeriesIteratorValue::value, py::const_))
134 .def("value",
135 py::overload_cast<int>(&DataSeriesIteratorValue::value, py::const_))
136 .def("values", &DataSeriesIteratorValue::values);
137
138 py::class_<IDataSeries, std::shared_ptr<IDataSeries>>(m, "IDataSeries")
139 .def("nbPoints", &IDataSeries::nbPoints)
140 .def_property_readonly("xAxisUnit", &IDataSeries::xAxisUnit)
141 .def_property_readonly("yAxisUnit", &IDataSeries::yAxisUnit)
142 .def_property_readonly("valuesUnit", &IDataSeries::valuesUnit)
143 .def("__getitem__",
144 [](IDataSeries& serie, int key) { return *(serie.begin() + key); },
145 py::is_operator())
146 .def("__len__", &IDataSeries::nbPoints)
147 .def("__iter__",
148 [](IDataSeries& serie) {
149 return py::make_iterator(serie.begin(), serie.end());
150 },
151 py::keep_alive<0, 1>())
152 .def("__repr__", __repr__<IDataSeries>);
153
154 py::class_<ArrayData<1>, std::shared_ptr<ArrayData<1>>>(m, "ArrayData1d")
155 .def("cdata", [](ArrayData<1>& array) { return array.cdata(); });
156
157 py::class_<ScalarSeries, std::shared_ptr<ScalarSeries>, IDataSeries>(
158 m, "ScalarSeries")
159 .def("nbPoints", &ScalarSeries::nbPoints);
160
161 py::class_<VectorSeries, std::shared_ptr<VectorSeries>, IDataSeries>(
162 m, "VectorSeries")
163 .def("nbPoints", &VectorSeries::nbPoints);
164
165 py::class_<DataSeries<2>, std::shared_ptr<DataSeries<2>>, IDataSeries>(
166 m, "DataSeries2d")
167 .def_property_readonly(
168 "xAxis", py::overload_cast<>(&DataSeries<2>::xAxisData, py::const_))
169 .def_property_readonly(
170 "yAxis", py::overload_cast<>(&DataSeries<2>::yAxis, py::const_));
171
172 py::class_<SpectrogramSeries, std::shared_ptr<SpectrogramSeries>,
173 DataSeries<2>>(m, "SpectrogramSeries")
174 .def("nbPoints", &SpectrogramSeries::nbPoints)
175 .def("xRes", &SpectrogramSeries::xResolution);
176
177 py::class_<IDataProvider, std::shared_ptr<IDataProvider>>(m, "IDataProvider");
100 py::class_<IDataProvider, std::shared_ptr<IDataProvider>>(m, "IDataProvider");
178
101
179 py::class_<Variable, std::shared_ptr<Variable>>(m, "Variable")
180 .def(py::init<const QString&>())
181 .def_property("name", &Variable::name, &Variable::setName)
182 .def_property("range", &Variable::range, &Variable::setRange)
183 .def_property("cacheRange", &Variable::cacheRange,
184 &Variable::setCacheRange)
185 .def_property_readonly("nbPoints", &Variable::nbPoints)
186 .def_property_readonly("dataSeries", &Variable::dataSeries)
187 .def("__len__",
188 [](Variable& variable) {
189 auto rng = variable.dataSeries()->xAxisRange(
190 variable.range().m_TStart, variable.range().m_TEnd);
191 return std::distance(rng.first, rng.second);
192 })
193 .def("__iter__",
194 [](Variable& variable) {
195 auto rng = variable.dataSeries()->xAxisRange(
196 variable.range().m_TStart, variable.range().m_TEnd);
197 return py::make_iterator(rng.first, rng.second);
198 },
199 py::keep_alive<0, 1>())
200 .def("__getitem__",
201 [](Variable& variable, int key) {
202 // insane and slow!
203 auto rng = variable.dataSeries()->xAxisRange(
204 variable.range().m_TStart, variable.range().m_TEnd);
205 if(key < 0)
206 return *(rng.second + key);
207 else
208 return *(rng.first + key);
209 })
210 .def("__repr__", __repr__<Variable>);
211
212 py::class_<TimeSeries::ITimeSerie, std::shared_ptr<TimeSeries::ITimeSerie>>(
102 py::class_<TimeSeries::ITimeSerie, std::shared_ptr<TimeSeries::ITimeSerie>>(
213 m, "ITimeSerie")
103 m, "ITimeSerie")
214 .def_property_readonly(
104 .def_property_readonly(
215 "size", [](const TimeSeries::ITimeSerie& ts) { return ts.size(); })
105 "size", [](const TimeSeries::ITimeSerie& ts) { return ts.size(); })
216 .def("__len__",
106 .def("__len__",
217 [](const TimeSeries::ITimeSerie& ts) { return ts.size(); })
107 [](const TimeSeries::ITimeSerie& ts) { return ts.size(); })
218 .def_property_readonly(
108 .def_property_readonly(
219 "shape", [](const TimeSeries::ITimeSerie& ts) { return ts.shape(); })
109 "shape", [](const TimeSeries::ITimeSerie& ts) { return ts.shape(); })
220 .def_property_readonly(
110 .def_property_readonly(
221 "t",
111 "t",
222 [](TimeSeries::ITimeSerie& ts) -> decltype(ts.axis(0))& {
112 [](TimeSeries::ITimeSerie& ts) -> decltype(ts.axis(0))& {
223 return ts.axis(0);
113 return ts.axis(0);
224 },
114 },
225 py::return_value_policy::reference);
115 py::return_value_policy::reference);
226
116
227 py::class_<ScalarTimeSerie, TimeSeries::ITimeSerie>(m, "ScalarTimeSerie")
117 py::class_<ScalarTimeSerie, TimeSeries::ITimeSerie>(m, "ScalarTimeSerie")
228 .def(py::init<>())
118 .def(py::init<>())
229 .def(py::init<std::size_t>())
119 .def(py::init<std::size_t>())
230 .def(py::init([](py::array_t<double> t, py::array_t<double> values) {
120 .def(py::init([](py::array_t<double> t, py::array_t<double> values) {
231 assert(t.size() == values.size());
121 assert(t.size() == values.size());
232 ScalarTimeSerie::axis_t _t(t.size());
122 ScalarTimeSerie::axis_t _t(t.size());
233 ScalarTimeSerie::axis_t _values(t.size());
123 ScalarTimeSerie::axis_t _values(t.size());
234 copy_scalar(t, values, _t, _values);
124 copy_scalar(t, values, _t, _values);
235 return ScalarTimeSerie(_t, _values);
125 return ScalarTimeSerie(_t, _values);
236 }))
126 }))
237 .def("__getitem__",
127 .def("__getitem__",
238 [](ScalarTimeSerie& ts, std::size_t key) { return ts[key]; })
128 [](ScalarTimeSerie& ts, std::size_t key) { return ts[key]; })
239 .def("__setitem__", [](ScalarTimeSerie& ts, std::size_t key,
129 .def("__setitem__", [](ScalarTimeSerie& ts, std::size_t key,
240 double value) { *(ts.begin() + key) = value; });
130 double value) { *(ts.begin() + key) = value; });
241
131
242 py::class_<VectorTimeSerie::raw_value_type>(m, "vector")
132 py::class_<VectorTimeSerie::raw_value_type>(m, "vector")
243 .def(py::init<>())
133 .def(py::init<>())
244 .def(py::init<double, double, double>())
134 .def(py::init<double, double, double>())
245 .def("__repr__", __repr__<VectorTimeSerie::raw_value_type>)
135 .def("__repr__", __repr__<VectorTimeSerie::raw_value_type>)
246 .def_readwrite("x", &VectorTimeSerie::raw_value_type::x)
136 .def_readwrite("x", &VectorTimeSerie::raw_value_type::x)
247 .def_readwrite("y", &VectorTimeSerie::raw_value_type::y)
137 .def_readwrite("y", &VectorTimeSerie::raw_value_type::y)
248 .def_readwrite("z", &VectorTimeSerie::raw_value_type::z);
138 .def_readwrite("z", &VectorTimeSerie::raw_value_type::z);
249
139
250 py::class_<VectorTimeSerie, TimeSeries::ITimeSerie>(m, "VectorTimeSerie")
140 py::class_<VectorTimeSerie, TimeSeries::ITimeSerie>(m, "VectorTimeSerie")
251 .def(py::init<>())
141 .def(py::init<>())
252 .def(py::init<std::size_t>())
142 .def(py::init<std::size_t>())
253 .def(py::init([](py::array_t<double> t, py::array_t<double> values) {
143 .def(py::init([](py::array_t<double> t, py::array_t<double> values) {
254 assert(t.size() * 3 == values.size());
144 assert(t.size() * 3 == values.size());
255 VectorTimeSerie::axis_t _t(t.size());
145 VectorTimeSerie::axis_t _t(t.size());
256 VectorTimeSerie::container_type<VectorTimeSerie::raw_value_type>
146 VectorTimeSerie::container_type<VectorTimeSerie::raw_value_type>
257 _values(t.size());
147 _values(t.size());
258 if(values.shape()[0] == 3 && values.shape(1) != 3)
148 if(values.shape()[0] == 3 && values.shape(1) != 3)
259 {
149 {
260 copy_vector<decltype(_t), decltype(_values), false>(t, values, _t,
150 copy_vector<decltype(_t), decltype(_values), false>(t, values, _t,
261 _values);
151 _values);
262 }
152 }
263 else
153 else
264 {
154 {
265 copy_vector(t, values, _t, _values);
155 copy_vector(t, values, _t, _values);
266 }
156 }
267
157
268 return VectorTimeSerie(_t, _values);
158 return VectorTimeSerie(_t, _values);
269 }))
159 }))
270 .def("__getitem__",
160 .def("__getitem__",
271 [](VectorTimeSerie& ts, std::size_t key)
161 [](VectorTimeSerie& ts, std::size_t key)
272 -> VectorTimeSerie::raw_value_type& { return ts[key]; },
162 -> VectorTimeSerie::raw_value_type& { return ts[key]; },
273 py::return_value_policy::reference)
163 py::return_value_policy::reference)
274 .def("__setitem__", [](VectorTimeSerie& ts, std::size_t key,
164 .def("__setitem__", [](VectorTimeSerie& ts, std::size_t key,
275 VectorTimeSerie::raw_value_type value) {
165 VectorTimeSerie::raw_value_type value) {
276 *(ts.begin() + key) = value;
166 *(ts.begin() + key) = value;
277 });
167 });
278
168
279 py::class_<SpectrogramTimeSerie::iterator_t>(m, "SpectrogramTimeSerieItem")
169 py::class_<SpectrogramTimeSerie::iterator_t>(m, "SpectrogramTimeSerieItem")
280 .def("__getitem__", [](SpectrogramTimeSerie::iterator_t& self,
170 .def("__getitem__", [](SpectrogramTimeSerie::iterator_t& self,
281 std::size_t key) { return (*self)[key]; })
171 std::size_t key) { return (*self)[key]; })
282 .def("__setitem__",
172 .def("__setitem__",
283 [](SpectrogramTimeSerie::iterator_t& self, std::size_t key,
173 [](SpectrogramTimeSerie::iterator_t& self, std::size_t key,
284 double value) { (*self)[key] = value; });
174 double value) { (*self)[key] = value; });
285
175
286 py::class_<SpectrogramTimeSerie, TimeSeries::ITimeSerie>(
176 py::class_<SpectrogramTimeSerie, TimeSeries::ITimeSerie>(
287 m, "SpectrogramTimeSerie")
177 m, "SpectrogramTimeSerie")
288 .def(py::init<>())
178 .def(py::init<>())
289 .def(py::init<const std::vector<std::size_t>>())
179 .def(py::init<const std::vector<std::size_t>>())
290 .def(py::init([](py::array_t<double> t, py::array_t<double> values) {
180 .def(py::init([](py::array_t<double> t, py::array_t<double> values) {
291 assert(t.size() < values.size()); // TODO check geometry
181 assert(t.size() < values.size()); // TODO check geometry
292 SpectrogramTimeSerie::axis_t _t(t.size());
182 SpectrogramTimeSerie::axis_t _t(t.size());
293 SpectrogramTimeSerie::container_type<
183 SpectrogramTimeSerie::container_type<
294 SpectrogramTimeSerie::raw_value_type>
184 SpectrogramTimeSerie::raw_value_type>
295 _values(values.size());
185 _values(values.size());
296 copy_spectro(t, values, _t, _values);
186 copy_spectro(t, values, _t, _values);
297 std::vector<std::size_t> shape;
187 std::vector<std::size_t> shape;
298 shape.push_back(values.shape(1));
188 shape.push_back(values.shape(1));
299 shape.push_back(values.shape(0));
189 shape.push_back(values.shape(0));
300 return SpectrogramTimeSerie(_t, _values, shape);
190 return SpectrogramTimeSerie(_t, _values, shape);
301 }))
191 }))
302 .def("__getitem__",
192 .def("__getitem__",
303 [](SpectrogramTimeSerie& ts,
193 [](SpectrogramTimeSerie& ts,
304 std::size_t key) -> SpectrogramTimeSerie::iterator_t {
194 std::size_t key) -> SpectrogramTimeSerie::iterator_t {
305 return ts.begin() + key;
195 return ts.begin() + key;
306 });
196 });
307
197
308 py::class_<Variable2, std::shared_ptr<Variable2>>(m, "Variable2")
198 py::class_<Variable2, std::shared_ptr<Variable2>>(m, "Variable2")
309 .def(py::init<const QString&>())
199 .def(py::init<const QString&>())
310 .def_property("name", &Variable2::name, &Variable2::setName)
200 .def_property("name", &Variable2::name, &Variable2::setName)
311 .def_property_readonly("range", &Variable2::range)
201 .def_property_readonly("range", &Variable2::range)
312 .def_property_readonly("nbPoints", &Variable2::nbPoints)
202 .def_property_readonly("nbPoints", &Variable2::nbPoints)
313 .def_property_readonly(
203 .def_property_readonly(
314 "data",
204 "data",
315 [](Variable2& var) -> std::shared_ptr<TimeSeries::ITimeSerie> {
205 [](Variable2& var) -> std::shared_ptr<TimeSeries::ITimeSerie> {
316 return var.data();
206 return var.data();
317 })
207 })
318 .def("set_data",
208 .def("set_data",
319 [](Variable2& var, std::vector<TimeSeries::ITimeSerie*> ts_list,
209 [](Variable2& var, std::vector<TimeSeries::ITimeSerie*> ts_list,
320 const DateTimeRange& range) { var.setData(ts_list, range); })
210 const DateTimeRange& range) { var.setData(ts_list, range); })
321 .def("__len__", &Variable2::nbPoints)
211 .def("__len__", &Variable2::nbPoints)
322 .def("__repr__", __repr__<Variable2>);
212 .def("__repr__", __repr__<Variable2>);
323
213
324 py::class_<DateTimeRange>(m, "SqpRange")
214 py::class_<DateTimeRange>(m, "SqpRange")
325 //.def("fromDateTime", &DateTimeRange::fromDateTime,
215 //.def("fromDateTime", &DateTimeRange::fromDateTime,
326 // py::return_value_policy::move)
216 // py::return_value_policy::move)
327 .def(py::init([](double start, double stop) {
217 .def(py::init([](double start, double stop) {
328 return DateTimeRange{start, stop};
218 return DateTimeRange{start, stop};
329 }))
219 }))
330 .def(py::init(
220 .def(py::init(
331 [](system_clock::time_point start, system_clock::time_point stop) {
221 [](system_clock::time_point start, system_clock::time_point stop) {
332 double start_ =
222 double start_ =
333 0.001 *
223 0.001 *
334 duration_cast<milliseconds>(start.time_since_epoch()).count();
224 duration_cast<milliseconds>(start.time_since_epoch()).count();
335 double stop_ =
225 double stop_ =
336 0.001 *
226 0.001 *
337 duration_cast<milliseconds>(stop.time_since_epoch()).count();
227 duration_cast<milliseconds>(stop.time_since_epoch()).count();
338 return DateTimeRange{start_, stop_};
228 return DateTimeRange{start_, stop_};
339 }))
229 }))
340 .def_property_readonly("start",
230 .def_property_readonly("start",
341 [](const DateTimeRange& range) {
231 [](const DateTimeRange& range) {
342 return system_clock::from_time_t(range.m_TStart);
232 return system_clock::from_time_t(range.m_TStart);
343 })
233 })
344 .def_property_readonly("stop",
234 .def_property_readonly("stop",
345 [](const DateTimeRange& range) {
235 [](const DateTimeRange& range) {
346 return system_clock::from_time_t(range.m_TEnd);
236 return system_clock::from_time_t(range.m_TEnd);
347 })
237 })
348 .def("__repr__", __repr__<DateTimeRange>);
238 .def("__repr__", __repr__<DateTimeRange>);
349 }
239 }
@@ -1,79 +1,41
1 #pragma once
1 #pragma once
2 #include "QtWrappers.h"
2 #include "QtWrappers.h"
3 #include "pywrappers_common.h"
3 #include "pywrappers_common.h"
4
4
5 #include <Data/DataSeriesType.h>
5 #include <Data/DataSeriesType.h>
6 #include <Data/DateTimeRange.h>
6 #include <Data/DateTimeRange.h>
7 #include <Data/IDataSeries.h>
8 #include <Data/Unit.h>
9 #include <Variable/Variable.h>
10 #include <Variable/Variable2.h>
7 #include <Variable/Variable2.h>
11 #include <pybind11/pybind11.h>
8 #include <pybind11/pybind11.h>
12 #include <sstream>
9 #include <sstream>
13 #include <string>
10 #include <string>
14
11
15 PYBIND11_MAKE_OPAQUE(std::vector<double>);
12 PYBIND11_MAKE_OPAQUE(std::vector<double>);
16
13
17 std::ostream& operator<<(std::ostream& os, const Unit& u)
18 {
19 os << "=========================" << std::endl
20 << "Unit:" << std::endl
21 << " Name: " << u.m_Name << std::endl
22 << " Is_TimeUnit: " << u.m_TimeUnit << std::endl;
23 return os;
24 }
25
26 std::ostream& operator<<(std::ostream& os, const IDataSeries& ds)
27 {
28 os << "=========================" << std::endl
29 << "DataSerie:" << std::endl
30 << " Number of points:" << ds.nbPoints() << std::endl
31 << " X Axis Unit:" << std::endl
32 << ds.xAxisUnit() << std::endl
33 << " Y Axis Unit:" << std::endl
34 << ds.yAxisUnit() << std::endl
35 << " Values Axis Unit:" << std::endl
36 << ds.valuesUnit() << std::endl;
37 return os;
38 }
39
40 std::ostream& operator<<(std::ostream& os, const DateTimeRange& range)
14 std::ostream& operator<<(std::ostream& os, const DateTimeRange& range)
41 {
15 {
42 os << "=========================" << std::endl
16 os << "=========================" << std::endl
43 << "SqpRange:" << std::endl
17 << "SqpRange:" << std::endl
44 << " Start date: " << DateUtils::dateTime(range.m_TStart).toString()
18 << " Start date: " << DateUtils::dateTime(range.m_TStart).toString()
45 << std::endl
19 << std::endl
46 << " Stop date: " << DateUtils::dateTime(range.m_TEnd).toString()
20 << " Stop date: " << DateUtils::dateTime(range.m_TEnd).toString()
47 << std::endl;
21 << std::endl;
48 return os;
22 return os;
49 }
23 }
50
24
51 std::ostream& operator<<(std::ostream& os, const Variable& variable)
52 {
53 os << "=========================" << std::endl
54 << "Variable:" << std::endl
55 << " Name: " << variable.name() << std::endl
56 << " range: " << std::endl
57 << variable.range() << std::endl
58 << " cache range: " << std::endl
59 << variable.cacheRange() << std::endl;
60 return os;
61 }
62
63 std::ostream& operator<<(std::ostream& os, Variable2& variable)
25 std::ostream& operator<<(std::ostream& os, Variable2& variable)
64 {
26 {
65 os << "=========================" << std::endl
27 os << "=========================" << std::endl
66 << "Variable:" << std::endl
28 << "Variable:" << std::endl
67 << " Name: " << variable.name() << std::endl
29 << " Name: " << variable.name() << std::endl
68 << " range: " << std::endl
30 << " range: " << std::endl
69 << variable.range() << std::endl;
31 << variable.range() << std::endl;
70 return os;
32 return os;
71 }
33 }
72
34
73 std::ostream& operator<<(std::ostream& os,
35 std::ostream& operator<<(std::ostream& os,
74 const VectorTimeSerie::raw_value_type& value)
36 const VectorTimeSerie::raw_value_type& value)
75 {
37 {
76 os << "[" << value.x << ", " << value.y << ", " << value.z << "]"
38 os << "[" << value.x << ", " << value.y << ", " << value.z << "]"
77 << std::endl;
39 << std::endl;
78 return os;
40 return os;
79 }
41 }
@@ -1,65 +1,50
1 add_definitions(-DCORE_TESTS_RESOURCES_DIR="${CMAKE_CURRENT_LIST_DIR}/../tests-resources")
1 add_definitions(-DCORE_TESTS_RESOURCES_DIR="${CMAKE_CURRENT_LIST_DIR}/../tests-resources")
2
2
3 FILE (GLOB_RECURSE TestUtilsSources
3 FILE (GLOB_RECURSE TestUtilsSources
4 TestUtils/TestProviders.h
4 TestUtils/TestProviders.h
5 TestUtils/TestProviders.cpp
5 TestUtils/TestProviders.cpp
6 )
6 )
7
7
8 add_library(TestUtils ${TestUtilsSources})
8 add_library(TestUtils ${TestUtilsSources})
9 target_link_libraries(TestUtils sciqlopcore Qt5::Test)
9 target_link_libraries(TestUtils sciqlopcore Qt5::Test)
10 target_include_directories(TestUtils PUBLIC
10 target_include_directories(TestUtils PUBLIC
11 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/TestUtils
11 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/TestUtils
12 )
12 )
13
13
14 declare_test(TestStringUtils TestStringUtils Common/TestStringUtils.cpp "sciqlopcore;Qt5::Test")
14 declare_test(TestStringUtils TestStringUtils Common/TestStringUtils.cpp "sciqlopcore;Qt5::Test")
15
15
16 declare_test(TestContainers TestContainers Common/TestContainers.cpp "sciqlopcore;Qt5::Test")
16 declare_test(TestContainers TestContainers Common/TestContainers.cpp "sciqlopcore;Qt5::Test")
17 declare_test(TestSyncGroup TestSyncGroup Variable/TestSyncGroup.cpp "sciqlopcore;Qt5::Test")
17 declare_test(TestSyncGroup TestSyncGroup Variable/TestSyncGroup.cpp "sciqlopcore;Qt5::Test")
18
18
19 declare_test(TestDateTimeRange TestDateTimeRange Data/TestDateTimeRange.cpp "sciqlopcore;Qt5::Test")
19 declare_test(TestDateTimeRange TestDateTimeRange Data/TestDateTimeRange.cpp "sciqlopcore;Qt5::Test")
20
20
21
22 declare_test(TestDataSeriesUtils TestDataSeriesUtils Data/TestDataSeriesUtils.cpp "sciqlopcore;Qt5::Test")
23 declare_test(TestOptionalAxis TestOptionalAxis Data/TestOptionalAxis.cpp "sciqlopcore;Qt5::Test")
24 declare_test(TestSpectrogramSeries TestSpectrogramSeries
25 "Data/TestSpectrogramSeries.cpp;Data/DataSeriesBuilders.h;Data/DataSeriesBuilders.cpp;Data/DataSeriesTestsUtils.h;Data/DataSeriesTestsUtils.cpp"
26 "sciqlopcore;Qt5::Test")
27 declare_test(TestOneDimArrayData TestOneDimArrayData Data/TestOneDimArrayData.cpp "sciqlopcore;Qt5::Test")
28 declare_test(TestScalarSeries TestScalarSeries
29 "Data/TestScalarSeries.cpp;Data/DataSeriesBuilders.h;Data/DataSeriesBuilders.cpp;Data/DataSeriesTestsUtils.h;Data/DataSeriesTestsUtils.cpp"
30 "sciqlopcore;Qt5::Test")
31 declare_test(TestTwoDimArrayData TestTwoDimArrayData Data/TestTwoDimArrayData.cpp "sciqlopcore;Qt5::Test")
32 declare_test(TestVectorSeries TestVectorSeries
33 "Data/TestVectorSeries.cpp;Data/DataSeriesBuilders.h;Data/DataSeriesBuilders.cpp;Data/DataSeriesTestsUtils.h;Data/DataSeriesTestsUtils.cpp"
34 "sciqlopcore;Qt5::Test")
35
36 declare_test(TestDataSourceController TestDataSourceController
21 declare_test(TestDataSourceController TestDataSourceController
37 "DataSource/TestDataSourceController.cpp;DataSource/DataSourceItemBuilder.cpp"
22 "DataSource/TestDataSourceController.cpp;DataSource/DataSourceItemBuilder.cpp"
38 "sciqlopcore;Qt5::Test")
23 "sciqlopcore;Qt5::Test")
39 declare_test(TestDataSourceItem TestDataSourceItem
24 declare_test(TestDataSourceItem TestDataSourceItem
40 "DataSource/TestDataSourceItem.cpp;DataSource/DataSourceItemBuilder.cpp"
25 "DataSource/TestDataSourceItem.cpp;DataSource/DataSourceItemBuilder.cpp"
41 "sciqlopcore;Qt5::Test")
26 "sciqlopcore;Qt5::Test")
42
27
43 declare_test(TestVariable TestVariable Variable/TestVariable.cpp "sciqlopcore;Qt5::Test")
28 declare_test(TestVariable TestVariable Variable/TestVariable.cpp "sciqlopcore;Qt5::Test")
44 declare_test(TestDownloader TestDownloader Network/TestDownloader.cpp "sciqlopcore;Qt5::Test;Qt5::Concurrent")
29 declare_test(TestDownloader TestDownloader Network/TestDownloader.cpp "sciqlopcore;Qt5::Test;Qt5::Concurrent")
45
30
46
31
47 declare_test(TestVariableController2 TestVariableController2 Variable/TestVariableController2.cpp "sciqlopcore;TestUtils;Qt5::Test")
32 declare_test(TestVariableController2 TestVariableController2 Variable/TestVariableController2.cpp "sciqlopcore;TestUtils;Qt5::Test")
48 declare_test(TestVariableController2Async TestVariableController2Async Variable/TestVariableController2Async.cpp "sciqlopcore;TestUtils;Qt5::Test")
33 declare_test(TestVariableController2Async TestVariableController2Async Variable/TestVariableController2Async.cpp "sciqlopcore;TestUtils;Qt5::Test")
49 declare_test(TestVariableController2WithSync TestVariableController2WithSync Variable/TestVariableController2WithSync.cpp "sciqlopcore;TestUtils;Qt5::Test")
34 declare_test(TestVariableController2WithSync TestVariableController2WithSync Variable/TestVariableController2WithSync.cpp "sciqlopcore;TestUtils;Qt5::Test")
50
35
51 declare_test(TestCatalogueController TestCatalogueController CatalogueController/TestCatalogueController.cpp "sciqlopcore;TestUtils;Qt5::Test")
36 declare_test(TestCatalogueController TestCatalogueController CatalogueController/TestCatalogueController.cpp "sciqlopcore;TestUtils;Qt5::Test")
52
37
53 add_executable(TestVariablesEmbed TestUtils/PyTestWrapperExe.cpp)
38 add_executable(TestVariablesEmbed TestUtils/PyTestWrapperExe.cpp)
54 target_link_libraries(TestVariablesEmbed PRIVATE pybind11::embed)
39 target_link_libraries(TestVariablesEmbed PRIVATE pybind11::embed)
55 add_test(NAME TestTestVariablesEmbed COMMAND TestVariablesEmbed)
40 add_test(NAME TestTestVariablesEmbed COMMAND TestVariablesEmbed)
56 target_compile_definitions(TestVariablesEmbed PRIVATE -DPYTEST_SCRIPT="${CMAKE_CURRENT_LIST_DIR}/TestVariables.py")
41 target_compile_definitions(TestVariablesEmbed PRIVATE -DPYTEST_SCRIPT="${CMAKE_CURRENT_LIST_DIR}/TestVariables.py")
57 set_tests_properties(TestTestVariablesEmbed PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/../)
42 set_tests_properties(TestTestVariablesEmbed PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/../)
58
43
59 find_package(PythonInterp 3 REQUIRED)
44 find_package(PythonInterp 3 REQUIRED)
60
45
61 add_test(NAME TestVariables
46 add_test(NAME TestVariables
62 COMMAND ${PYTHON_EXECUTABLE}
47 COMMAND ${PYTHON_EXECUTABLE}
63 ${CMAKE_CURRENT_LIST_DIR}/TestVariables.py
48 ${CMAKE_CURRENT_LIST_DIR}/TestVariables.py
64 TestVariables)
49 TestVariables)
65 set_tests_properties(TestVariables PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/../)
50 set_tests_properties(TestVariables PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/../)
@@ -1,71 +1,69
1 #ifndef TESTPROVIDER_H
1 #ifndef TESTPROVIDER_H
2 #define TESTPROVIDER_H
2 #define TESTPROVIDER_H
3
3
4 #include <Data/DataProviderParameters.h>
4 #include <Data/DataProviderParameters.h>
5 #include <Data/DataSeries.h>
6 #include <Data/IDataProvider.h>
5 #include <Data/IDataProvider.h>
7 #include <Data/ScalarSeries.h>
8 #include <Data/ScalarTimeSerie.h>
6 #include <Data/ScalarTimeSerie.h>
9 #include <QUuid>
7 #include <QUuid>
10 #include <QtGlobal>
8 #include <QtGlobal>
11 #include <QtTest>
9 #include <QtTest>
12 #include <TimeSeries.h>
10 #include <TimeSeries.h>
13 #include <Variable/Variable2.h>
11 #include <Variable/Variable2.h>
14 #include <algorithm>
12 #include <algorithm>
15 #include <cmath>
13 #include <cmath>
16 #include <memory>
14 #include <memory>
17 #include <numeric>
15 #include <numeric>
18
16
19 template<int slope> class SimpleRange : public IDataProvider
17 template<int slope> class SimpleRange : public IDataProvider
20 {
18 {
21 public:
19 public:
22 SimpleRange() = default;
20 SimpleRange() = default;
23
21
24 int callCounter = 0;
22 int callCounter = 0;
25 std::shared_ptr<IDataProvider> clone() const override
23 std::shared_ptr<IDataProvider> clone() const override
26 {
24 {
27 return std::make_shared<SimpleRange>();
25 return std::make_shared<SimpleRange>();
28 }
26 }
29
27
30 TimeSeries::ITimeSerie*
28 TimeSeries::ITimeSerie*
31 getData(const DataProviderParameters& parameters) override
29 getData(const DataProviderParameters& parameters) override
32 {
30 {
33 callCounter += 1;
31 callCounter += 1;
34 std::size_t size =
32 std::size_t size =
35 static_cast<std::size_t>(floor(parameters.m_Range.m_TEnd) -
33 static_cast<std::size_t>(floor(parameters.m_Range.m_TEnd) -
36 ceil(parameters.m_Range.m_TStart) + 1.);
34 ceil(parameters.m_Range.m_TStart) + 1.);
37 auto serie = new ScalarTimeSerie(size);
35 auto serie = new ScalarTimeSerie(size);
38 std::generate(std::begin(*serie), std::end(*serie),
36 std::generate(std::begin(*serie), std::end(*serie),
39 [i = ceil(parameters.m_Range.m_TStart)]() mutable {
37 [i = ceil(parameters.m_Range.m_TStart)]() mutable {
40 return std::pair<double, double>{i, i++ * slope};
38 return std::pair<double, double>{i, i++ * slope};
41 });
39 });
42 return serie;
40 return serie;
43 }
41 }
44 };
42 };
45
43
46 template<class T> auto sumdiff(T begin, T end)
44 template<class T> auto sumdiff(T begin, T end)
47 {
45 {
48 std::vector<double> diff_vect(end - begin - 1);
46 std::vector<double> diff_vect(end - begin - 1);
49 auto diff = [](auto next, auto item) { return next.value() - item.value(); };
47 auto diff = [](auto next, auto item) { return next.value() - item.value(); };
50 std::transform(begin + 1, end, begin, diff_vect.begin(), diff);
48 std::transform(begin + 1, end, begin, diff_vect.begin(), diff);
51 return std::accumulate(diff_vect.cbegin(), diff_vect.cend(), 0);
49 return std::accumulate(diff_vect.cbegin(), diff_vect.cend(), 0);
52 }
50 }
53
51
54 template<int slope = 1> struct RangeType
52 template<int slope = 1> struct RangeType
55 {
53 {
56 static void check_properties(std::shared_ptr<Variable2> v, DateTimeRange r)
54 static void check_properties(std::shared_ptr<Variable2> v, DateTimeRange r)
57 {
55 {
58 // TODO
56 // TODO
59 }
57 }
60 };
58 };
61
59
62 template<class T>
60 template<class T>
63 void check_variable_state(std::shared_ptr<Variable2> v, DateTimeRange r)
61 void check_variable_state(std::shared_ptr<Variable2> v, DateTimeRange r)
64 {
62 {
65 auto range = v->data()->axis_range(0);
63 auto range = v->data()->axis_range(0);
66 QVERIFY(range.first >= r.m_TStart);
64 QVERIFY(range.first >= r.m_TStart);
67 QVERIFY(range.second <= r.m_TEnd);
65 QVERIFY(range.second <= r.m_TEnd);
68 T::check_properties(v, r);
66 T::check_properties(v, r);
69 }
67 }
70
68
71 #endif
69 #endif
@@ -1,158 +1,157
1 #include <Common/containers.h>
1 #include <Common/containers.h>
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/ScalarSeries.h>
6 #include <QObject>
5 #include <QObject>
7 #include <QtTest>
6 #include <QtTest>
8 #include <TestUtils/TestProviders.h>
7 #include <TestUtils/TestProviders.h>
9 #include <Variable/VariableController2.h>
8 #include <Variable/VariableController2.h>
10 #include <algorithm>
9 #include <algorithm>
11 #include <cmath>
10 #include <cmath>
12 #include <numeric>
11 #include <numeric>
13
12
14 #define TEST_VC2_FIXTURE(slope) \
13 #define TEST_VC2_FIXTURE(slope) \
15 VariableController2 vc; \
14 VariableController2 vc; \
16 auto provider = std::make_shared<SimpleRange<slope>>();
15 auto provider = std::make_shared<SimpleRange<slope>>();
17
16
18 #define TEST_VC2_CREATE_DEFAULT_VAR(name) \
17 #define TEST_VC2_CREATE_DEFAULT_VAR(name) \
19 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00), \
18 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00), \
20 QDate(2018, 8, 7), QTime(16, 00)); \
19 QDate(2018, 8, 7), QTime(16, 00)); \
21 auto name = vc.createVariable("name", {}, provider, range); \
20 auto name = vc.createVariable("name", {}, provider, range); \
22 while(!vc.isReady(name)) \
21 while(!vc.isReady(name)) \
23 QCoreApplication::processEvents();
22 QCoreApplication::processEvents();
24
23
25 Q_DECLARE_METATYPE(DateTimeRangeTransformation);
24 Q_DECLARE_METATYPE(DateTimeRangeTransformation);
26
25
27 class TestVariableController2 : public QObject
26 class TestVariableController2 : public QObject
28 {
27 {
29 Q_OBJECT
28 Q_OBJECT
30 public:
29 public:
31 explicit TestVariableController2(QObject* parent = nullptr) : QObject(parent)
30 explicit TestVariableController2(QObject* parent = nullptr) : QObject(parent)
32 {}
31 {}
33 signals:
32 signals:
34
33
35 private slots:
34 private slots:
36 void initTestCase() {}
35 void initTestCase() {}
37 void cleanupTestCase() {}
36 void cleanupTestCase() {}
38
37
39 void testCreateVariable()
38 void testCreateVariable()
40 {
39 {
41 TEST_VC2_FIXTURE(2);
40 TEST_VC2_FIXTURE(2);
42 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00),
41 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00),
43 QDate(2018, 8, 7), QTime(16, 00));
42 QDate(2018, 8, 7), QTime(16, 00));
44 bool callbackCalled = false;
43 bool callbackCalled = false;
45 connect(&vc, &VariableController2::variableAdded,
44 connect(&vc, &VariableController2::variableAdded,
46 [&callbackCalled](std::shared_ptr<Variable2>) {
45 [&callbackCalled](std::shared_ptr<Variable2>) {
47 callbackCalled = true;
46 callbackCalled = true;
48 });
47 });
49 QVERIFY(!callbackCalled);
48 QVERIFY(!callbackCalled);
50 auto var1 = vc.createVariable("var1", {}, provider, range);
49 auto var1 = vc.createVariable("var1", {}, provider, range);
51 QVERIFY(SciQLop::containers::contains(vc.variables(), var1));
50 QVERIFY(SciQLop::containers::contains(vc.variables(), var1));
52 QVERIFY(callbackCalled);
51 QVERIFY(callbackCalled);
53 }
52 }
54
53
55 void testDeleteVariable()
54 void testDeleteVariable()
56 {
55 {
57 TEST_VC2_FIXTURE(1);
56 TEST_VC2_FIXTURE(1);
58 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00),
57 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00),
59 QDate(2018, 8, 7), QTime(16, 00));
58 QDate(2018, 8, 7), QTime(16, 00));
60 bool callbackCalled = false;
59 bool callbackCalled = false;
61 connect(&vc, &VariableController2::variableDeleted,
60 connect(&vc, &VariableController2::variableDeleted,
62 [&callbackCalled](std::shared_ptr<Variable2>) {
61 [&callbackCalled](std::shared_ptr<Variable2>) {
63 callbackCalled = true;
62 callbackCalled = true;
64 });
63 });
65 auto var1 = vc.createVariable("var1", {}, provider, range);
64 auto var1 = vc.createVariable("var1", {}, provider, range);
66 while(!vc.isReady(var1))
65 while(!vc.isReady(var1))
67 QCoreApplication::processEvents();
66 QCoreApplication::processEvents();
68 QVERIFY(SciQLop::containers::contains(vc.variables(), var1));
67 QVERIFY(SciQLop::containers::contains(vc.variables(), var1));
69 QVERIFY(!callbackCalled);
68 QVERIFY(!callbackCalled);
70 vc.deleteVariable(var1);
69 vc.deleteVariable(var1);
71 QVERIFY(!SciQLop::containers::contains(vc.variables(), var1));
70 QVERIFY(!SciQLop::containers::contains(vc.variables(), var1));
72 QVERIFY(callbackCalled);
71 QVERIFY(callbackCalled);
73 }
72 }
74
73
75 void testGetData()
74 void testGetData()
76 {
75 {
77 TEST_VC2_FIXTURE(10);
76 TEST_VC2_FIXTURE(10);
78 TEST_VC2_CREATE_DEFAULT_VAR(var1);
77 TEST_VC2_CREATE_DEFAULT_VAR(var1);
79 check_variable_state<RangeType<10>>(var1, range);
78 check_variable_state<RangeType<10>>(var1, range);
80 }
79 }
81
80
82 void testZoom_data()
81 void testZoom_data()
83 {
82 {
84 QTest::addColumn<double>("zoom");
83 QTest::addColumn<double>("zoom");
85 QTest::newRow("Zoom IN 10x") << .1;
84 QTest::newRow("Zoom IN 10x") << .1;
86 QTest::newRow("Zoom OUT 10x") << 10.;
85 QTest::newRow("Zoom OUT 10x") << 10.;
87 QTest::newRow("Zoom IN 1x") << 1.;
86 QTest::newRow("Zoom IN 1x") << 1.;
88 }
87 }
89 void testZoom()
88 void testZoom()
90 {
89 {
91 TEST_VC2_FIXTURE(100);
90 TEST_VC2_FIXTURE(100);
92 TEST_VC2_CREATE_DEFAULT_VAR(var1);
91 TEST_VC2_CREATE_DEFAULT_VAR(var1);
93 check_variable_state<RangeType<100>>(var1, range);
92 check_variable_state<RangeType<100>>(var1, range);
94
93
95 QFETCH(double, zoom);
94 QFETCH(double, zoom);
96 range *= zoom;
95 range *= zoom;
97 vc.changeRange(var1, range);
96 vc.changeRange(var1, range);
98 check_variable_state<RangeType<100>>(var1, range);
97 check_variable_state<RangeType<100>>(var1, range);
99 }
98 }
100
99
101 void testPan_data()
100 void testPan_data()
102 {
101 {
103 QTest::addColumn<double>("pan");
102 QTest::addColumn<double>("pan");
104 QTest::newRow("Right 1000 seconds") << 1000.;
103 QTest::newRow("Right 1000 seconds") << 1000.;
105 QTest::newRow("Left 1000 seconds") << -1000.;
104 QTest::newRow("Left 1000 seconds") << -1000.;
106 QTest::newRow("Right 0.1 seconds") << .1;
105 QTest::newRow("Right 0.1 seconds") << .1;
107 QTest::newRow("Left 0.1 seconds") << -.1;
106 QTest::newRow("Left 0.1 seconds") << -.1;
108 }
107 }
109 void testPan()
108 void testPan()
110 {
109 {
111 TEST_VC2_FIXTURE(10);
110 TEST_VC2_FIXTURE(10);
112 TEST_VC2_CREATE_DEFAULT_VAR(var1);
111 TEST_VC2_CREATE_DEFAULT_VAR(var1);
113 check_variable_state<RangeType<10>>(var1, range);
112 check_variable_state<RangeType<10>>(var1, range);
114
113
115 QFETCH(double, pan);
114 QFETCH(double, pan);
116
115
117 range += Seconds<double>{pan};
116 range += Seconds<double>{pan};
118 vc.changeRange(var1, range);
117 vc.changeRange(var1, range);
119 check_variable_state<RangeType<10>>(var1, range);
118 check_variable_state<RangeType<10>>(var1, range);
120 }
119 }
121
120
122 void testCache_data()
121 void testCache_data()
123 {
122 {
124 QTest::addColumn<DateTimeRangeTransformation>("transformation");
123 QTest::addColumn<DateTimeRangeTransformation>("transformation");
125 QTest::addColumn<int>("expectedIncrement");
124 QTest::addColumn<int>("expectedIncrement");
126 QTest::newRow("zoom in")
125 QTest::newRow("zoom in")
127 << DateTimeRangeTransformation{0.8, Seconds<double>(0.)} << 0;
126 << DateTimeRangeTransformation{0.8, Seconds<double>(0.)} << 0;
128 QTest::newRow("tiny zoom out")
127 QTest::newRow("tiny zoom out")
129 << DateTimeRangeTransformation{1.01, Seconds<double>(0.)} << 0;
128 << DateTimeRangeTransformation{1.01, Seconds<double>(0.)} << 0;
130 QTest::newRow("just under cache zoom out")
129 QTest::newRow("just under cache zoom out")
131 << DateTimeRangeTransformation{2.0 / 1.1, Seconds<double>(0.)} << 0;
130 << DateTimeRangeTransformation{2.0 / 1.1, Seconds<double>(0.)} << 0;
132 QTest::newRow("just over cache zoom out")
131 QTest::newRow("just over cache zoom out")
133 << DateTimeRangeTransformation{2.001 / 1.1, Seconds<double>(0.)} << 2;
132 << DateTimeRangeTransformation{2.001 / 1.1, Seconds<double>(0.)} << 2;
134 QTest::newRow("tiny pan left")
133 QTest::newRow("tiny pan left")
135 << DateTimeRangeTransformation{1., Seconds<double>(-100.)} << 0;
134 << DateTimeRangeTransformation{1., Seconds<double>(-100.)} << 0;
136 QTest::newRow("tiny pan right")
135 QTest::newRow("tiny pan right")
137 << DateTimeRangeTransformation{1., Seconds<double>(100.)} << 0;
136 << DateTimeRangeTransformation{1., Seconds<double>(100.)} << 0;
138 }
137 }
139 void testCache()
138 void testCache()
140 {
139 {
141 QSKIP("The cache is disabled for now");
140 QSKIP("The cache is disabled for now");
142 TEST_VC2_FIXTURE(10);
141 TEST_VC2_FIXTURE(10);
143 TEST_VC2_CREATE_DEFAULT_VAR(var1);
142 TEST_VC2_CREATE_DEFAULT_VAR(var1);
144 check_variable_state<RangeType<10>>(var1, range);
143 check_variable_state<RangeType<10>>(var1, range);
145
144
146 QFETCH(DateTimeRangeTransformation, transformation);
145 QFETCH(DateTimeRangeTransformation, transformation);
147 QFETCH(int, expectedIncrement);
146 QFETCH(int, expectedIncrement);
148 auto initialCount = provider->callCounter;
147 auto initialCount = provider->callCounter;
149 range = range.transform(transformation);
148 range = range.transform(transformation);
150 vc.changeRange(var1, range);
149 vc.changeRange(var1, range);
151 check_variable_state<RangeType<10>>(var1, range);
150 check_variable_state<RangeType<10>>(var1, range);
152 QCOMPARE(provider->callCounter - initialCount, expectedIncrement);
151 QCOMPARE(provider->callCounter - initialCount, expectedIncrement);
153 }
152 }
154 };
153 };
155
154
156 QTEST_MAIN(TestVariableController2)
155 QTEST_MAIN(TestVariableController2)
157
156
158 #include "TestVariableController2.moc"
157 #include "TestVariableController2.moc"
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
This diff has been collapsed as it changes many lines, (510 lines changed) Show them Hide them
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
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
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
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