##// END OF EJS Templates
Basic serial variable creation and update...
jeandet -
r2:c7f53bda4647
parent child
Show More
@@ -0,0 +1,9
1 #ifndef DEBUG_H
2 #define DEBUG_H
3
4 #ifdef SCIQLOP_CRASH_ON_ERROR
5 #define SCIQLOP_ERROR(x) assert(false)
6 #else
7 #define SCIQLOP_ERROR(x)
8 #endif
9 #endif
@@ -1,187 +1,188
1 1 cmake_minimum_required(VERSION 3.6)
2 2 project(SciQLOPCore CXX)
3 3
4 4 OPTION (CPPCHECK "Analyzes the source code with cppcheck" OFF)
5 5 OPTION (CLANG_TIDY "Analyzes the source code with Clang Tidy" OFF)
6 6 OPTION (IWYU "Analyzes the source code with Include What You Use" OFF)
7 7
8 8 OPTION (Catalog "builds catalog API" OFF)
9 9
10 10 set(CMAKE_CXX_STANDARD 17)
11 11
12 12 set(CMAKE_AUTOMOC ON)
13 13 #https://gitlab.kitware.com/cmake/cmake/issues/15227
14 14 #set(CMAKE_AUTOUIC ON)
15 15 if(POLICY CMP0071)
16 16 cmake_policy(SET CMP0071 OLD)
17 17 endif()
18 18 set(CMAKE_AUTORCC ON)
19 19 set(CMAKE_INCLUDE_CURRENT_DIR ON)
20 20
21 21 find_package(Qt5 COMPONENTS Core Widgets Network PrintSupport Svg Test REQUIRED)
22 22
23 23 find_package(pybind11 CONFIG QUIET)
24 24 if (NOT pybind11_FOUND)
25 25 execute_process(COMMAND git submodule init external/pybind11 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
26 26 execute_process(COMMAND git submodule update external/pybind11 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
27 27 add_subdirectory(external/pybind11)
28 28 endif()
29 29
30 30 macro(declare_test testname testexe sources libraries)
31 31 add_executable(${testexe} ${sources})
32 32 target_link_libraries(${testexe} ${libraries})
33 33 add_test(NAME ${testname} COMMAND ${testexe})
34 34 endmacro(declare_test)
35 35
36 36 enable_testing()
37 37
38 38 FILE (GLOB_RECURSE core_SRCS
39 39 ./include/DataSource/DataSourceItemMergeHelper.h
40 40 ./include/DataSource/DataSourceItemAction.h
41 41 ./include/DataSource/DataSourceItem.h
42 42 ./include/DataSource/DataSourceController.h
43 43 ./include/Common/SortUtils.h
44 44 ./include/Common/spimpl.h
45 45 ./include/Common/MimeTypesDef.h
46 46 ./include/Common/MetaTypes.h
47 47 ./include/Common/StringUtils.h
48 48 ./include/Common/SignalWaiter.h
49 49 ./include/Common/DateUtils.h
50 50 ./include/Common/Numeric.h
51 51 ./include/Common/deprecate.h
52 52 ./include/Common/containers.h
53 ./include/Common/debug.h
53 54 ./include/Plugin/IPlugin.h
54 55 ./include/Data/ArrayDataIterator.h
55 56 ./include/Data/VariableRequest.h
56 57 ./include/Data/VectorSeries.h
57 58 ./include/Data/DateTimeRange.h
58 59 ./include/Data/ScalarSeries.h
59 60 ./include/Data/DataSeriesMergeHelper.h
60 61 ./include/Data/DataSeries.h
61 62 ./include/Data/AcquisitionDataPacket.h
62 63 ./include/Data/DataSeriesType.h
63 64 ./include/Data/AcquisitionRequest.h
64 65 ./include/Data/SqpIterator.h
65 66 ./include/Data/ArrayData.h
66 67 ./include/Data/DataSeriesIterator.h
67 68 ./include/Data/DataSeriesUtils.h
68 69 ./include/Data/SpectrogramSeries.h
69 70 ./include/Data/Unit.h
70 71 ./include/Data/DataProviderParameters.h
71 72 ./include/Data/OptionalAxis.h
72 73 ./include/Data/IDataProvider.h
73 74 ./include/Data/IDataSeries.h
74 75 ./include/Network/NetworkController.h
75 76 ./include/Network/Downloader.h
76 77 ./include/Version.h
77 78 ./include/CoreGlobal.h
78 79 ./include/Visualization/VisualizationController.h
79 80 ./include/PluginManager/PluginManager.h
80 81 ./include/Variable/VariableModel.h
81 82 ./include/Variable/VariableAcquisitionWorker.h
82 83 ./include/Variable/VariableCacheStrategy.h
83 84 ./include/Variable/VariableSynchronizationGroup.h
84 85 ./include/Variable/VariableSynchronizationGroup2.h
85 86 ./include/Variable/VariableSingleThresholdCacheStrategy.h
86 87 ./include/Variable/VariableCacheStrategyFactory.h
87 88 ./include/Variable/Variable.h
88 89 ./include/Variable/VariableCacheController.h
89 90 ./include/Variable/VariableController.h
90 91 ./include/Variable/VariableController2.h
91 92 ./include/Time/TimeController.h
92 93 ./include/Settings/ISqpSettingsBindable.h
93 94 ./include/Settings/SqpSettingsDefs.h
94 95
95 96 ./src/DataSource/DataSourceItem.cpp
96 97 ./src/DataSource/DataSourceItemAction.cpp
97 98 ./src/DataSource/DataSourceItemMergeHelper.cpp
98 99 ./src/DataSource/DataSourceController.cpp
99 100 ./src/Common/DateUtils.cpp
100 101 ./src/Common/MimeTypesDef.cpp
101 102 ./src/Common/StringUtils.cpp
102 103 ./src/Common/SignalWaiter.cpp
103 104 ./src/Data/ScalarSeries.cpp
104 105 ./src/Data/DataSeriesIterator.cpp
105 106 ./src/Data/OptionalAxis.cpp
106 107 ./src/Data/ArrayDataIterator.cpp
107 108 ./src/Data/SpectrogramSeries.cpp
108 109 ./src/Data/DataSeriesUtils.cpp
109 110 ./src/Data/VectorSeries.cpp
110 111 ./src/Network/NetworkController.cpp
111 112 ./src/Network/Downloader.cpp
112 113 ./src/Visualization/VisualizationController.cpp
113 114 ./src/PluginManager/PluginManager.cpp
114 115 ./src/Variable/VariableController.cpp
115 116 ./src/Variable/VariableController2.cpp
116 117 ./src/Variable/VariableModel.cpp
117 118 ./src/Variable/VariableCacheController.cpp
118 119 ./src/Variable/VariableSynchronizationGroup.cpp
119 120 ./src/Variable/VariableSynchronizationGroup2.cpp
120 121 ./src/Variable/Variable.cpp
121 122 ./src/Variable/VariableAcquisitionWorker.cpp
122 123 ./src/Version.cpp
123 124 ./src/Time/TimeController.cpp
124 125 ./src/Settings/SqpSettingsDefs.cpp
125 126
126 127 )
127 128
128 129
129 130 IF(Catalog)
130 131 FILE (GLOB_RECURSE core_catalog_SRCS
131 132 ./src/Catalogue/CatalogueController.cpp
132 133 ./include/Catalogue/CatalogueController.h
133 134 )
134 135 ELSE()
135 136 FILE (GLOB_RECURSE core_catalog_SRCS
136 137 )
137 138 ENDIF(Catalog)
138 139
139 140 add_definitions(-DCORE_STATIC)
140 141 #add_definitions(-DHIDE_DEPRECATED)
141 142
142 143 add_library(sciqlopcore ${core_SRCS} ${core_catalog_SRCS})
143 144 SET_TARGET_PROPERTIES(sciqlopcore PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
144 145
145 146 target_include_directories(sciqlopcore PUBLIC
146 147 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
147 148 $<INSTALL_INTERFACE:include/SciQLOP>
148 149 )
149 150
150 151 target_link_libraries(sciqlopcore PUBLIC
151 152 Qt5::Core
152 153 Qt5::Network
153 154 )
154 155
155 156 if(Catalog)
156 157 target_link_libraries(sciqlopcore PUBLIC
157 158 catalogs
158 159 )
159 160 endif()
160 161
161 162
162 163 pybind11_add_module(sciqlopqt src/pybind11_wrappers/QtWrappers.cpp)
163 164 target_link_libraries(sciqlopqt PUBLIC Qt5::Core)
164 165
165 166 pybind11_add_module(pysciqlopcore src/pybind11_wrappers/CoreWrappers.cpp)
166 167 target_link_libraries(pysciqlopcore PUBLIC sciqlopcore)
167 168
168 169 add_library(pysciqlop src/pybind11_wrappers/pywrappers_common.h)
169 170 target_link_libraries(pysciqlop PUBLIC Qt5::Core)
170 171 target_include_directories(pysciqlop PUBLIC
171 172 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/pybind11_wrappers/>
172 173 $<INSTALL_INTERFACE:include/SciQLOP/py_wrappers>
173 174 )
174 175
175 176 SET_PROPERTY(GLOBAL PROPERTY CORE_PYTHON_PATH ${CMAKE_CURRENT_BINARY_DIR})
176 177
177 178
178 179 install(TARGETS sciqlopcore EXPORT SciQLOPCoreConfig
179 180 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
180 181 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
181 182 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
182 183
183 184 install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/SciQLOP)
184 185 install(EXPORT SciQLOPCoreConfig DESTINATION share/SciQLOPCore/cmake)
185 186 export(TARGETS sciqlopcore FILE SciQLOPCoreConfig.cmake)
186 187
187 188 add_subdirectory(tests)
@@ -1,107 +1,112
1 1 #ifndef SCIQLOP_IDATAPROVIDER_H
2 2 #define SCIQLOP_IDATAPROVIDER_H
3 3
4 4 #include "CoreGlobal.h"
5 5 #include <Common/deprecate.h>
6 6
7 7 #include <memory>
8 8
9 9 #include <QObject>
10 10 #include <QUuid>
11 11
12 12 #include <Common/MetaTypes.h>
13 13
14 14 #include <Data/DateTimeRange.h>
15 15
16 16 #include <functional>
17 17
18 18 class DataProviderParameters;
19 19 class IDataSeries;
20 20 DEPRECATE(
21 21 class QNetworkReply;
22 22 class QNetworkRequest;
23 23 )
24 24
25 25 /**
26 26 * @brief The IDataProvider interface aims to declare a data provider.
27 27 *
28 28 * A data provider is an entity that generates data and returns it according to various parameters
29 29 * (time interval, product to retrieve the data, etc.)
30 30 *
31 31 * @sa IDataSeries
32 32 */
33 33 class SCIQLOP_CORE_EXPORT IDataProvider : public QObject {
34 34
35 35 Q_OBJECT
36 36 public:
37 37 virtual ~IDataProvider() noexcept = default;
38 38 virtual std::shared_ptr<IDataProvider> clone() const = 0;
39 39
40 40 DEPRECATE(
41 41 /**
42 42 * @brief requestDataLoading provide datas for the data identified by acqIdentifier and
43 43 * parameters
44 44 */
45 45 virtual void requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters)
46 46 = 0;
47 47 )
48 48
49 virtual QUuid getData(const DataProviderParameters &parameters){return QUuid::createUuid();}
49 // Synchronous call -> asyncGetData may be written for asynchronous get
50 virtual IDataSeries* getData(const DataProviderParameters &parameters)
51 {
52 Q_UNUSED(parameters);
53 return nullptr;
54 }
50 55
51 56
52 57 DEPRECATE(
53 58 /**
54 59 * @brief requestDataAborting stop data loading of the data identified by acqIdentifier
55 60 */
56 61 virtual void requestDataAborting(QUuid acqIdentifier) = 0;
57 62 )
58 63
59 virtual void abort(QUuid requestID){}
64 virtual void abort(QUuid requestID){Q_UNUSED(requestID);}
60 65
61 66 signals:
62 67 DEPRECATE(
63 68 /**
64 69 * @brief dataProvided send dataSeries under dateTime and that corresponds of the data
65 70 * identified by acqIdentifier
66 71 */
67 72 void dataProvided(QUuid acqIdentifier, std::shared_ptr<IDataSeries> dateSeriesAcquired,
68 73 const DateTimeRange &dataRangeAcquired);
69 74 )
70 75
71 76 void finished(QUuid requestID, std::shared_ptr<IDataSeries> dataSerie,
72 77 const DateTimeRange &range);
73 78
74 79 DEPRECATE(
75 80 /**
76 81 * @brief dataProvidedProgress notify the progression of the data identifier by acqIdentifier
77 82 */
78 83 void dataProvidedProgress(QUuid acqIdentifier, double progress);
79 84 )
80 85
81 86 void progress(QUuid requestID, double progress);
82 87
83 88 DEPRECATE(
84 89 /**
85 90 * @brief dataProvidedFailed notify that data acquisition has failed
86 91 */
87 92 void dataProvidedFailed(QUuid acqIdentifier);
88 93 )
89 94
90 95 void failed(QUuid requestID);
91 96
92 97 /**
93 98 * @brief requestConstructed send a request for the data identified by acqIdentifier
94 99 * @callback is the methode call by the reply of the request when it is finished.
95 100 */
96 101 DEPRECATE(
97 102 void requestConstructed(std::shared_ptr<QNetworkRequest> request, QUuid acqIdentifier,
98 103 std::function<void(QNetworkReply *, QUuid)> callback);
99 104 )
100 105 };
101 106
102 107 // Required for using shared_ptr in signals/slots
103 108 SCIQLOP_REGISTER_META_TYPE(IDATAPROVIDER_PTR_REGISTRY, std::shared_ptr<IDataProvider>)
104 109 SCIQLOP_REGISTER_META_TYPE(IDATAPROVIDER_FUNCTION_REGISTRY,
105 110 std::function<void(QNetworkReply *, QUuid)>)
106 111
107 112 #endif // SCIQLOP_IDATAPROVIDER_H
@@ -1,95 +1,102
1 1 #ifndef SCIQLOP_VARIABLE_H
2 2 #define SCIQLOP_VARIABLE_H
3 3
4 4 #include "CoreGlobal.h"
5 5
6 6 #include <Data/DataSeriesIterator.h>
7 7 #include <Data/DataSeriesType.h>
8 8 #include <Data/DateTimeRange.h>
9 9
10 10 #include <QLoggingCategory>
11 11 #include <QObject>
12 #include <QUuid>
12 13
14 #include <Common/deprecate.h>
13 15 #include <Common/MetaTypes.h>
14 16 #include <Common/spimpl.h>
15 17
16 18 Q_DECLARE_LOGGING_CATEGORY(LOG_Variable)
17 19
18 20 class IDataSeries;
19 21 class QString;
20 22
21 23 /**
22 24 * @brief The Variable class represents a variable in SciQlop.
23 25 */
24 26 class SCIQLOP_CORE_EXPORT Variable : public QObject {
25 27
26 28 Q_OBJECT
27 29
28 30 public:
29 31 explicit Variable(const QString &name, const QVariantHash &metadata = {});
30 32
31 33 /// Copy ctor
32 34 explicit Variable(const Variable &other);
33 35
34 36 std::shared_ptr<Variable> clone() const;
35 37
36 38 QString name() const noexcept;
37 39 void setName(const QString &name) noexcept;
38 40 DateTimeRange range() const noexcept;
39 41 void setRange(const DateTimeRange &range) noexcept;
40 42 DateTimeRange cacheRange() const noexcept;
41 43 void setCacheRange(const DateTimeRange &cacheRange) noexcept;
42 44
43 45 /// @return the number of points hold by the variable. The number of points is updated each time
44 46 /// the data series changes
45 47 int nbPoints() const noexcept;
46 48
47 49 /// Returns the real range of the variable, i.e. the min and max x-axis values of the data
48 50 /// series between the range of the variable. The real range is updated each time the variable
49 51 /// range or the data series changed
50 52 /// @return the real range, invalid range if the data series is null or empty
51 53 /// @sa setDataSeries()
52 54 /// @sa setRange()
53 55 DateTimeRange realRange() const noexcept;
54 56
55 57 /// @return the data of the variable, nullptr if there is no data
56 58 std::shared_ptr<IDataSeries> dataSeries() const noexcept;
57 59
58 60 /// @return the type of data that the variable holds
59 61 DataSeriesType type() const noexcept;
60 62
61 63 QVariantHash metadata() const noexcept;
62 64
63 65 bool contains(const DateTimeRange &range) const noexcept;
64 66 bool intersect(const DateTimeRange &range) const noexcept;
65 67 bool isInside(const DateTimeRange &range) const noexcept;
66 68
67 69 bool cacheContains(const DateTimeRange &range) const noexcept;
68 70 bool cacheIntersect(const DateTimeRange &range) const noexcept;
69 71 bool cacheIsInside(const DateTimeRange &range) const noexcept;
70 72
71 73 QVector<DateTimeRange> provideNotInCacheRangeList(const DateTimeRange &range) const noexcept;
72 74 QVector<DateTimeRange> provideInCacheRangeList(const DateTimeRange &range) const noexcept;
75 DEPRECATE(
73 76 void mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept;
77 )
78 void mergeDataSeries(IDataSeries* dataSeries) noexcept;
74 79
75 80 static QVector<DateTimeRange> provideNotInCacheRangeList(const DateTimeRange &oldRange,
76 81 const DateTimeRange &nextRange);
77 82
78 83 static QVector<DateTimeRange> provideInCacheRangeList(const DateTimeRange &oldRange,
79 84 const DateTimeRange &nextRange);
80 85
86 QUuid ID(){return _uuid;}
81 87 signals:
82 88 void updated();
83 89 /// Signal emitted when when the data series of the variable is loaded for the first time
84 90 void dataInitialized();
85 91
86 92 private:
87 93 class VariablePrivate;
88 94 spimpl::unique_impl_ptr<VariablePrivate> impl;
95 QUuid _uuid;
89 96 };
90 97
91 98 // Required for using shared_ptr in signals/slots
92 99 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_REGISTRY, std::shared_ptr<Variable>)
93 100 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_VECTOR_REGISTRY, QVector<std::shared_ptr<Variable> >)
94 101
95 102 #endif // SCIQLOP_VARIABLE_H
@@ -1,26 +1,36
1 #include <Common/spimpl.h>
2 1 #include <memory>
3 2 #include <vector>
4 3 #include <QHash>
4 #include <QObject>
5 #include <QMutexLocker>
6 #include <QUuid>
7 #include <QItemSelectionModel>
8 #include <Common/spimpl.h>
5 9 #include <Variable/Variable.h>
6 10 #include <Variable/VariableSynchronizationGroup.h>
7 11 #include <Variable/VariableModel.h>
8 12 #include <Data/IDataProvider.h>
9 13 #include "Data/DateTimeRange.h"
10 #include <QMutexLocker>
11 #include <QUuid>
12 #include <QItemSelectionModel>
13 14
14 class VariableController2Private;
15 class VariableController2
15 class VariableController2: public QObject
16 16 {
17 class VariableController2Private;
18 Q_OBJECT
19
17 20 spimpl::unique_impl_ptr<VariableController2Private> impl;
18 21
19 22 public:
20 23 explicit VariableController2();
21 24 std::shared_ptr<Variable> createVariable(const QString &name, const QVariantHash &metadata,
22 25 std::shared_ptr<IDataProvider> provider, const DateTimeRange &range);
23 void changeRange(QUuid variable, DateTimeRange r);
24 void asyncChangeRange(QUuid variable, DateTimeRange r);
26
27 void deleteVariable(std::shared_ptr<Variable> variable);
28 void changeRange(std::shared_ptr<Variable> variable, DateTimeRange r);
29 void asyncChangeRange(std::shared_ptr<Variable> variable, DateTimeRange r);
30 const std::set<std::shared_ptr<Variable> > &variables();
31
32 signals:
33 void variableAdded(std::shared_ptr<Variable>);
34 void variableDeleted(std::shared_ptr<Variable>);
25 35
26 36 };
@@ -1,430 +1,461
1 1 #include "Variable/Variable.h"
2 2
3 3 #include <Data/IDataSeries.h>
4 4 #include <Data/DateTimeRange.h>
5 5
6 6 #include <QMutex>
7 7 #include <QReadWriteLock>
8 8 #include <QThread>
9 #include <Common/debug.h>
9 10
10 11 Q_LOGGING_CATEGORY(LOG_Variable, "Variable")
11 12
12 13 namespace {
13 14
14 15 /**
15 16 * Searches in metadata for a value that can be converted to DataSeriesType
16 17 * @param metadata the metadata where to search
17 18 * @return the value converted to a DataSeriesType if it was found, UNKNOWN type otherwise
18 19 * @sa DataSeriesType
19 20 */
20 21 DataSeriesType findDataSeriesType(const QVariantHash &metadata)
21 22 {
22 23 auto dataSeriesType = DataSeriesType::UNKNOWN;
23 24
24 25 // Go through the metadata and stop at the first value that could be converted to DataSeriesType
25 26 for (auto it = metadata.cbegin(), end = metadata.cend();
26 27 it != end && dataSeriesType == DataSeriesType::UNKNOWN; ++it) {
27 28 dataSeriesType = DataSeriesTypeUtils::fromString(it.value().toString());
28 29 }
29 30
30 31 return dataSeriesType;
31 32 }
32 33
33 34 } // namespace
34 35
35 36 struct Variable::VariablePrivate {
36 37 explicit VariablePrivate(const QString &name, const QVariantHash &metadata)
37 38 : m_Name{name},
38 39 m_Range{INVALID_RANGE},
39 40 m_CacheRange{INVALID_RANGE},
40 41 m_Metadata{metadata},
41 42 m_DataSeries{nullptr},
42 43 m_RealRange{INVALID_RANGE},
43 44 m_NbPoints{0},
44 45 m_Type{findDataSeriesType(m_Metadata)}
45 46 {
46 47 }
47 48
48 49 VariablePrivate(const VariablePrivate &other)
49 50 : m_Name{other.m_Name},
50 51 m_Range{other.m_Range},
51 52 m_CacheRange{other.m_CacheRange},
52 53 m_Metadata{other.m_Metadata},
53 54 m_DataSeries{other.m_DataSeries != nullptr ? other.m_DataSeries->clone() : nullptr},
54 55 m_RealRange{other.m_RealRange},
55 56 m_NbPoints{other.m_NbPoints},
56 57 m_Type{findDataSeriesType(m_Metadata)}
57 58 {
58 59 }
59 60
60 61 void lockRead() { m_Lock.lockForRead(); }
61 62 void lockWrite() { m_Lock.lockForWrite(); }
62 63 void unlock() { m_Lock.unlock(); }
63 64
64 65 void purgeDataSeries()
65 66 {
66 67 if (m_DataSeries) {
67 68 m_DataSeries->purge(m_CacheRange.m_TStart, m_CacheRange.m_TEnd);
68 69 }
69 70 updateRealRange();
70 71 updateNbPoints();
71 72 }
72 73
73 74 void updateNbPoints() { m_NbPoints = m_DataSeries ? m_DataSeries->nbPoints() : 0; }
74 75
75 76 /// Updates real range according to current variable range and data series
76 77 void updateRealRange()
77 78 {
78 79 if (m_DataSeries) {
79 80 m_DataSeries->lockRead();
80 81 auto end = m_DataSeries->cend();
81 82 auto minXAxisIt = m_DataSeries->minXAxisData(m_Range.m_TStart);
82 83 auto maxXAxisIt = m_DataSeries->maxXAxisData(m_Range.m_TEnd);
83 84
84 85 m_RealRange
85 86 = (minXAxisIt != end && maxXAxisIt != end && minXAxisIt->x() <= maxXAxisIt->x())
86 87 ? DateTimeRange{minXAxisIt->x(), maxXAxisIt->x()}
87 88 : INVALID_RANGE;
88 89 m_DataSeries->unlock();
89 90 }
90 91 else {
91 92 m_RealRange = INVALID_RANGE;
92 93 }
93 94 }
94 95
95 96 QString m_Name;
96 97
97 98 DateTimeRange m_Range;
98 99 DateTimeRange m_CacheRange;
99 100 QVariantHash m_Metadata;
100 101 std::shared_ptr<IDataSeries> m_DataSeries;
101 102 DateTimeRange m_RealRange;
102 103 int m_NbPoints;
103 104 DataSeriesType m_Type;
104 105
105 106 QReadWriteLock m_Lock;
106 107 };
107 108
108 109 Variable::Variable(const QString &name, const QVariantHash &metadata)
109 : impl{spimpl::make_unique_impl<VariablePrivate>(name, metadata)}
110 : impl{spimpl::make_unique_impl<VariablePrivate>(name, metadata)},
111 _uuid{QUuid::createUuid()}
110 112 {
111 113 }
112 114
113 115 Variable::Variable(const Variable &other)
114 : impl{spimpl::make_unique_impl<VariablePrivate>(*other.impl)}
116 : impl{spimpl::make_unique_impl<VariablePrivate>(*other.impl)},
117 _uuid{QUuid::createUuid()} //is a clone but must have a != uuid
115 118 {
116 119 }
117 120
118 121 std::shared_ptr<Variable> Variable::clone() const
119 122 {
120 123 return std::make_shared<Variable>(*this);
121 124 }
122 125
123 126 QString Variable::name() const noexcept
124 127 {
125 128 impl->lockRead();
126 129 auto name = impl->m_Name;
127 130 impl->unlock();
128 131 return name;
129 132 }
130 133
131 134 void Variable::setName(const QString &name) noexcept
132 135 {
133 136 impl->lockWrite();
134 137 impl->m_Name = name;
135 138 impl->unlock();
136 139 }
137 140
138 141 DateTimeRange Variable::range() const noexcept
139 142 {
140 143 impl->lockRead();
141 144 auto range = impl->m_Range;
142 145 impl->unlock();
143 146 return range;
144 147 }
145 148
146 149 void Variable::setRange(const DateTimeRange &range) noexcept
147 150 {
148 151 impl->lockWrite();
149 152 impl->m_Range = range;
150 153 impl->updateRealRange();
151 154 impl->unlock();
152 155 }
153 156
154 157 DateTimeRange Variable::cacheRange() const noexcept
155 158 {
156 159 impl->lockRead();
157 160 auto cacheRange = impl->m_CacheRange;
158 161 impl->unlock();
159 162 return cacheRange;
160 163 }
161 164
162 165 void Variable::setCacheRange(const DateTimeRange &cacheRange) noexcept
163 166 {
164 167 impl->lockWrite();
165 168 if (cacheRange != impl->m_CacheRange) {
166 169 impl->m_CacheRange = cacheRange;
167 170 }
168 171 impl->unlock();
169 172 }
170 173
171 174 int Variable::nbPoints() const noexcept
172 175 {
173 176 return impl->m_NbPoints;
174 177 }
175 178
176 179 DateTimeRange Variable::realRange() const noexcept
177 180 {
178 181 return impl->m_RealRange;
179 182 }
180 183
181 184 void Variable::mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
182 185 {
183 186 qCDebug(LOG_Variable()) << "TORM Variable::mergeDataSeries"
184 187 << QThread::currentThread()->objectName();
185 188 if (!dataSeries) {
186 189 /// @todo ALX : log
187 190 return;
188 191 }
189 192
190 193 auto dataInit = false;
191 194
192 195 // Add or merge the data
193 196 impl->lockWrite();
194 197 if (!impl->m_DataSeries) {
195 198 impl->m_DataSeries = dataSeries->clone();
196 199 dataInit = true;
197 200 }
198 201 else {
199 202 impl->m_DataSeries->merge(dataSeries.get());
200 203 }
201 204 impl->purgeDataSeries();
202 205 impl->unlock();
203 206
204 207 if (dataInit) {
205 208 emit dataInitialized();
206 209 }
207 210 }
208 211
212 void Variable::mergeDataSeries(IDataSeries *dataSeries) noexcept
213 {
214 if (dataSeries==nullptr) {
215 SCIQLOP_ERROR("Given IDataSeries is nullptr");
216 return;
217 }
218
219 auto dataInit = false;
220 // @TODO move to impl to Pimpl this is what it stands for...
221 // Add or merge the data
222 impl->lockWrite();
223 if (!impl->m_DataSeries) {
224 //@TODO find a better way
225 impl->m_DataSeries = dataSeries->clone();
226 dataInit = true;
227 delete dataSeries;
228 }
229 else {
230 impl->m_DataSeries->merge(dataSeries);
231 }
232 impl->purgeDataSeries();
233 impl->unlock();
234
235 if (dataInit) {
236 emit dataInitialized();
237 }
238 }
239
209 240
210 241 std::shared_ptr<IDataSeries> Variable::dataSeries() const noexcept
211 242 {
212 243 impl->lockRead();
213 244 auto dataSeries = impl->m_DataSeries;
214 245 impl->unlock();
215 246
216 247 return dataSeries;
217 248 }
218 249
219 250 DataSeriesType Variable::type() const noexcept
220 251 {
221 252 impl->lockRead();
222 253 auto type = impl->m_Type;
223 254 impl->unlock();
224 255
225 256 return type;
226 257 }
227 258
228 259 QVariantHash Variable::metadata() const noexcept
229 260 {
230 261 impl->lockRead();
231 262 auto metadata = impl->m_Metadata;
232 263 impl->unlock();
233 264 return metadata;
234 265 }
235 266
236 267 bool Variable::contains(const DateTimeRange &range) const noexcept
237 268 {
238 269 impl->lockRead();
239 270 auto res = impl->m_Range.contains(range);
240 271 impl->unlock();
241 272 return res;
242 273 }
243 274
244 275 bool Variable::intersect(const DateTimeRange &range) const noexcept
245 276 {
246 277
247 278 impl->lockRead();
248 279 auto res = impl->m_Range.intersect(range);
249 280 impl->unlock();
250 281 return res;
251 282 }
252 283
253 284 bool Variable::isInside(const DateTimeRange &range) const noexcept
254 285 {
255 286 impl->lockRead();
256 287 auto res = range.contains(DateTimeRange{impl->m_Range.m_TStart, impl->m_Range.m_TEnd});
257 288 impl->unlock();
258 289 return res;
259 290 }
260 291
261 292 bool Variable::cacheContains(const DateTimeRange &range) const noexcept
262 293 {
263 294 impl->lockRead();
264 295 auto res = impl->m_CacheRange.contains(range);
265 296 impl->unlock();
266 297 return res;
267 298 }
268 299
269 300 bool Variable::cacheIntersect(const DateTimeRange &range) const noexcept
270 301 {
271 302 impl->lockRead();
272 303 auto res = impl->m_CacheRange.intersect(range);
273 304 impl->unlock();
274 305 return res;
275 306 }
276 307
277 308 bool Variable::cacheIsInside(const DateTimeRange &range) const noexcept
278 309 {
279 310 impl->lockRead();
280 311 auto res = range.contains(DateTimeRange{impl->m_CacheRange.m_TStart, impl->m_CacheRange.m_TEnd});
281 312 impl->unlock();
282 313 return res;
283 314 }
284 315
285 316
286 317 QVector<DateTimeRange> Variable::provideNotInCacheRangeList(const DateTimeRange &range) const noexcept
287 318 {
288 319 // This code assume that cach in contigue. Can return 0, 1 or 2 SqpRange
289 320 auto notInCache = QVector<DateTimeRange>{};
290 321 if (impl->m_CacheRange != INVALID_RANGE) {
291 322
292 323 if (!this->cacheContains(range)) {
293 324 if (range.m_TEnd <= impl->m_CacheRange.m_TStart
294 325 || range.m_TStart >= impl->m_CacheRange.m_TEnd) {
295 326 notInCache << range;
296 327 }
297 328 else if (range.m_TStart < impl->m_CacheRange.m_TStart
298 329 && range.m_TEnd <= impl->m_CacheRange.m_TEnd) {
299 330 notInCache << DateTimeRange{range.m_TStart, impl->m_CacheRange.m_TStart};
300 331 }
301 332 else if (range.m_TStart < impl->m_CacheRange.m_TStart
302 333 && range.m_TEnd > impl->m_CacheRange.m_TEnd) {
303 334 notInCache << DateTimeRange{range.m_TStart, impl->m_CacheRange.m_TStart}
304 335 << DateTimeRange{impl->m_CacheRange.m_TEnd, range.m_TEnd};
305 336 }
306 337 else if (range.m_TStart < impl->m_CacheRange.m_TEnd) {
307 338 notInCache << DateTimeRange{impl->m_CacheRange.m_TEnd, range.m_TEnd};
308 339 }
309 340 else {
310 341 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
311 342 << QThread::currentThread();
312 343 }
313 344 }
314 345 }
315 346 else {
316 347 notInCache << range;
317 348 }
318 349
319 350 return notInCache;
320 351 }
321 352
322 353 QVector<DateTimeRange> Variable::provideInCacheRangeList(const DateTimeRange &range) const noexcept
323 354 {
324 355 // This code assume that cach in contigue. Can return 0 or 1 SqpRange
325 356
326 357 auto inCache = QVector<DateTimeRange>{};
327 358
328 359 if (impl->m_CacheRange != INVALID_RANGE) {
329 360
330 361 if (this->cacheIntersect(range)) {
331 362 if (range.m_TStart <= impl->m_CacheRange.m_TStart
332 363 && range.m_TEnd >= impl->m_CacheRange.m_TStart
333 364 && range.m_TEnd < impl->m_CacheRange.m_TEnd) {
334 365 inCache << DateTimeRange{impl->m_CacheRange.m_TStart, range.m_TEnd};
335 366 }
336 367
337 368 else if (range.m_TStart >= impl->m_CacheRange.m_TStart
338 369 && range.m_TEnd <= impl->m_CacheRange.m_TEnd) {
339 370 inCache << range;
340 371 }
341 372 else if (range.m_TStart > impl->m_CacheRange.m_TStart
342 373 && range.m_TEnd > impl->m_CacheRange.m_TEnd) {
343 374 inCache << DateTimeRange{range.m_TStart, impl->m_CacheRange.m_TEnd};
344 375 }
345 376 else if (range.m_TStart <= impl->m_CacheRange.m_TStart
346 377 && range.m_TEnd >= impl->m_CacheRange.m_TEnd) {
347 378 inCache << impl->m_CacheRange;
348 379 }
349 380 else {
350 381 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
351 382 << QThread::currentThread();
352 383 }
353 384 }
354 385 }
355 386
356 387 return inCache;
357 388 }
358 389
359 390
360 391 QVector<DateTimeRange> Variable::provideNotInCacheRangeList(const DateTimeRange &oldRange,
361 392 const DateTimeRange &nextRange)
362 393 {
363 394
364 395 // This code assume that cach in contigue. Can return 0, 1 or 2 SqpRange
365 396 auto notInCache = QVector<DateTimeRange>{};
366 397 if (oldRange != INVALID_RANGE) {
367 398
368 399 if (!oldRange.contains(nextRange)) {
369 400 if (nextRange.m_TEnd <= oldRange.m_TStart || nextRange.m_TStart >= oldRange.m_TEnd) {
370 401 notInCache << nextRange;
371 402 }
372 403 else if (nextRange.m_TStart < oldRange.m_TStart
373 404 && nextRange.m_TEnd <= oldRange.m_TEnd) {
374 405 notInCache << DateTimeRange{nextRange.m_TStart, oldRange.m_TStart};
375 406 }
376 407 else if (nextRange.m_TStart < oldRange.m_TStart && nextRange.m_TEnd > oldRange.m_TEnd) {
377 408 notInCache << DateTimeRange{nextRange.m_TStart, oldRange.m_TStart}
378 409 << DateTimeRange{oldRange.m_TEnd, nextRange.m_TEnd};
379 410 }
380 411 else if (nextRange.m_TStart < oldRange.m_TEnd) {
381 412 notInCache << DateTimeRange{oldRange.m_TEnd, nextRange.m_TEnd};
382 413 }
383 414 else {
384 415 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
385 416 << QThread::currentThread();
386 417 }
387 418 }
388 419 }
389 420 else {
390 421 notInCache << nextRange;
391 422 }
392 423
393 424 return notInCache;
394 425 }
395 426
396 427 QVector<DateTimeRange> Variable::provideInCacheRangeList(const DateTimeRange &oldRange,
397 428 const DateTimeRange &nextRange)
398 429 {
399 430 // This code assume that cach is contigue. Can return 0 or 1 SqpRange
400 431
401 432 auto inCache = QVector<DateTimeRange>{};
402 433
403 434 if (oldRange != INVALID_RANGE) {
404 435
405 436 if (oldRange.intersect(nextRange)) {
406 437 if (nextRange.m_TStart <= oldRange.m_TStart && nextRange.m_TEnd >= oldRange.m_TStart
407 438 && nextRange.m_TEnd < oldRange.m_TEnd) {
408 439 inCache << DateTimeRange{oldRange.m_TStart, nextRange.m_TEnd};
409 440 }
410 441
411 442 else if (nextRange.m_TStart >= oldRange.m_TStart
412 443 && nextRange.m_TEnd <= oldRange.m_TEnd) {
413 444 inCache << nextRange;
414 445 }
415 446 else if (nextRange.m_TStart > oldRange.m_TStart && nextRange.m_TEnd > oldRange.m_TEnd) {
416 447 inCache << DateTimeRange{nextRange.m_TStart, oldRange.m_TEnd};
417 448 }
418 449 else if (nextRange.m_TStart <= oldRange.m_TStart
419 450 && nextRange.m_TEnd >= oldRange.m_TEnd) {
420 451 inCache << oldRange;
421 452 }
422 453 else {
423 454 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
424 455 << QThread::currentThread();
425 456 }
426 457 }
427 458 }
428 459
429 460 return inCache;
430 461 }
@@ -1,25 +1,83
1 1 #include "Variable/VariableController2.h"
2 #include <Common/containers.h>
3 #include <Common/debug.h>
4 #include <Data/DataProviderParameters.h>
2 5
3
4 class VariableController2Private
6 class VariableController2::VariableController2Private
5 7 {
6
8 std::set<std::shared_ptr<Variable>> _variables;
9 QMap<QUuid,std::shared_ptr<IDataProvider>> _providers;
7 10 public:
8 11 VariableController2Private(QObject* parent=Q_NULLPTR)
9 {}
12 {
13 Q_UNUSED(parent);
14 }
15
10 16 ~VariableController2Private() = default;
17
11 18 std::shared_ptr<Variable> createVariable(const QString &name, const QVariantHash &metadata, std::shared_ptr<IDataProvider> provider, const DateTimeRange &range)
12 19 {
13 return std::make_shared<Variable>(name,metadata);
20 auto newVar = std::make_shared<Variable>(name,metadata);
21 this->_variables.insert(newVar);
22 this->_providers[newVar->ID()] = provider;
23 return newVar;
24 }
25
26 void deleteVariable(std::shared_ptr<Variable> variable)
27 {
28 if(this->_providers.contains(variable->ID()))
29 this->_providers.remove(variable->ID());
30 if(SciQLop::containers::contains(this->_variables, variable))
31 this->_variables.erase(variable);
32 }
33
34 void changeRange(std::shared_ptr<Variable> variable, DateTimeRange r)
35 {
36 if(_providers.contains(variable->ID()))
37 {
38 auto provider = _providers[variable->ID()];
39 auto data = provider->getData(DataProviderParameters{{r},variable->metadata()});
40 variable->mergeDataSeries(data);
41 }
42 else
43 {
44 SCIQLOP_ERROR("No provider found for given variable");
45 }
46 }
47
48
49 const std::set<std::shared_ptr<Variable>>& variables()
50 {
51 return _variables;
14 52 }
53
15 54 };
16 55
17 56 VariableController2::VariableController2()
18 57 :impl{spimpl::make_unique_impl<VariableController2Private>()}
19 58 {}
20 59
21 60 std::shared_ptr<Variable> VariableController2::createVariable(const QString &name, const QVariantHash &metadata, std::shared_ptr<IDataProvider> provider, const DateTimeRange &range)
22 61 {
23 return impl->createVariable(name, metadata, provider, range);
62 auto var = impl->createVariable(name, metadata, provider, range);
63 emit variableAdded(var);
64 impl->changeRange(var,range);
65 return var;
66 }
67
68 void VariableController2::deleteVariable(std::shared_ptr<Variable> variable)
69 {
70 impl->deleteVariable(variable);
71 emit variableDeleted(variable);
72 }
73
74 void VariableController2::changeRange(std::shared_ptr<Variable> variable, DateTimeRange r)
75 {
76 impl->changeRange(variable, r);
77 }
78
79 const std::set<std::shared_ptr<Variable> > &VariableController2::variables()
80 {
81 return impl->variables();
24 82 }
25 83
@@ -1,30 +1,108
1 #include <cmath>
1 2 #include <QtTest>
2 3 #include <QObject>
4 #include <Variable/VariableController2.h>
5 #include <Data/DateTimeRange.h>
6 #include <Data/IDataProvider.h>
7 #include <Data/ScalarSeries.h>
8 #include <Data/DataProviderParameters.h>
9 #include <Common/containers.h>
3 10
11 class FakeProvider: public IDataProvider
12 {
13 public:
14 FakeProvider() = default;
4 15
5 class TestVariableController2 : public QObject
16 std::shared_ptr<IDataProvider> clone() const override{ return std::make_shared<FakeProvider>(); }
17
18 IDataSeries* getData(const DataProviderParameters &parameters) override
19 {
20 auto tstart = parameters.m_Times[0].m_TStart;
21 auto tend = parameters.m_Times[0].m_TEnd;
22 std::vector<double> x;
23 std::vector<double> y;
24 for(auto i = tstart;i<tend;i+=1.) //1 seconde data resolution
25 {
26 x.push_back(i);
27 y.push_back(i);
28 }
29 auto serie = new ScalarSeries(std::move(x),std::move(y),Unit("Secondes",true),Unit("Volts",false));
30 return serie;
31 }
32
33
34
35 void requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters) override
36 {
37 Q_UNUSED(acqIdentifier)
38 Q_UNUSED(parameters)
39 }
40
41 void requestDataAborting(QUuid acqIdentifier) override
42 {
43 Q_UNUSED(acqIdentifier)
44 }
45
46 };
6 47
48 class TestVariableController2 : public QObject
7 49 {
8 50 Q_OBJECT
9 51 public:
10 52 explicit TestVariableController2(QObject *parent = nullptr) : QObject(parent){}
11 53 signals:
12 54
13 55 private slots:
14 56 void initTestCase(){}
15 57 void cleanupTestCase(){}
16 58
17 void test1()
59 void testCreateVariable()
60 {
61 VariableController2 vc;
62 bool callbackCalled = false;
63 connect(&vc,&VariableController2::variableAdded, [&callbackCalled](std::shared_ptr<Variable>){callbackCalled=true;});
64 auto provider = std::make_shared<FakeProvider>();
65 QVERIFY(!callbackCalled);
66 auto var1 = vc.createVariable("var1",{},provider,DateTimeRange());
67 QVERIFY(SciQLop::containers::contains(vc.variables(), var1));
68 QVERIFY(callbackCalled);
69 }
70
71 void testDeleteVariable()
72 {
73 VariableController2 vc;
74 bool callbackCalled = false;
75 connect(&vc,&VariableController2::variableDeleted, [&callbackCalled](std::shared_ptr<Variable>){callbackCalled=true;});
76 auto provider = std::make_shared<FakeProvider>();
77 auto var1 = vc.createVariable("var1",{},provider,DateTimeRange());
78 QVERIFY(SciQLop::containers::contains(vc.variables(), var1));
79 QVERIFY(!callbackCalled);
80 vc.deleteVariable(var1);
81 QVERIFY(!SciQLop::containers::contains(vc.variables(), var1));
82 QVERIFY(callbackCalled);
83 }
84
85 void testGetData()
18 86 {
19 QCOMPARE(1+1, 2);
87 VariableController2 vc;
88 auto provider = std::make_shared<FakeProvider>();
89 auto range1 = DateTimeRange::fromDateTime(QDate(2018,8,7),QTime(14,00),
90 QDate(2018,8,7),QTime(16,00));
91 auto range2 = DateTimeRange::fromDateTime(QDate(2018,8,7),QTime(12,00),
92 QDate(2018,8,7),QTime(18,00));
93 auto var1 = vc.createVariable("var1", {}, provider, range1);
94 QCOMPARE(var1->nbPoints(), int(range1.delta()));
95 vc.changeRange(var1, range2);
96 QCOMPARE(var1->nbPoints(), int(range2.delta()));
97
20 98 }
21 99
22 100 private:
23 101
24 102 };
25 103
26 104
27 105 QTEST_MAIN(TestVariableController2)
28 106
29 107 #include "TestVariableController2.moc"
30 108
General Comments 0
You need to be logged in to leave comments. Login now