##// END OF EJS Templates
Quick variable model copied from existing one...
jeandet -
r21:5a50815a763f
parent child
Show More
@@ -0,0 +1,62
1 #ifndef SCIQLOP_VARIABLEMODEL2_H
2 #define SCIQLOP_VARIABLEMODEL2_H
3
4 #include "CoreGlobal.h"
5
6 #include <Data/DateTimeRange.h>
7
8 #include <QAbstractTableModel>
9 #include <QLoggingCategory>
10
11 #include <Common/MetaTypes.h>
12 #include <Common/spimpl.h>
13
14
15
16 class IDataSeries;
17 class Variable;
18 class VariableController2;
19
20 /**
21 * @brief The VariableModel class aims to hold the variables that have been created in SciQlop
22 */
23 class SCIQLOP_CORE_EXPORT VariableModel2 : public QAbstractTableModel {
24 enum VariableRoles { ProgressRole = Qt::UserRole };
25 Q_OBJECT
26 std::shared_ptr<VariableController2> _variableController;
27 public:
28 explicit VariableModel2(const std::shared_ptr<VariableController2>& variableController, QObject *parent = nullptr);
29
30 // /////////////////////////// //
31 // QAbstractTableModel methods //
32 // /////////////////////////// //
33
34 virtual int columnCount(const QModelIndex &parent = QModelIndex{}) const override;
35 virtual int rowCount(const QModelIndex &parent = QModelIndex{}) const override;
36 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
37 virtual QVariant headerData(int section, Qt::Orientation orientation,
38 int role = Qt::DisplayRole) const override;
39 virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
40
41 // ///////////////// //
42 // Drag&Drop methods //
43 // ///////////////// //
44
45 virtual Qt::DropActions supportedDropActions() const override;
46 virtual Qt::DropActions supportedDragActions() const override;
47 virtual QStringList mimeTypes() const override;
48 virtual QMimeData *mimeData(const QModelIndexList &indexes) const override;
49 virtual bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
50 const QModelIndex &parent) const override;
51 virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
52 const QModelIndex &parent) override;
53
54
55 signals:
56
57 private slots:
58 /// Slot called when data of a variable has been updated
59 void variableUpdated() noexcept;
60 };
61
62 #endif // SCIQLOP_VARIABLEMODEL2_H
@@ -0,0 +1,250
1 #include <Variable/Variable.h>
2 #include <Variable/VariableController2.h>
3 #include <Variable/VariableModel2.h>
4
5 #include <Common/DateUtils.h>
6 #include <Common/MimeTypesDef.h>
7 #include <Common/StringUtils.h>
8
9 #include <Data/IDataSeries.h>
10
11 #include <DataSource/DataSourceController.h>
12 #include <Time/TimeController.h>
13
14 #include <QMimeData>
15 #include <QSize>
16 #include <QTimer>
17 #include <unordered_map>
18
19 namespace {
20
21 // Column indexes
22 const auto NAME_COLUMN = 0;
23 const auto TSTART_COLUMN = 1;
24 const auto TEND_COLUMN = 2;
25 const auto NBPOINTS_COLUMN = 3;
26 const auto UNIT_COLUMN = 4;
27 const auto MISSION_COLUMN = 5;
28 const auto PLUGIN_COLUMN = 6;
29 const auto NB_COLUMNS = 7;
30
31 // Column properties
32 const auto DEFAULT_HEIGHT = 25;
33 const auto DEFAULT_WIDTH = 100;
34
35 struct ColumnProperties {
36 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
37 int height = DEFAULT_HEIGHT)
38 : m_Name{name}, m_Width{width}, m_Height{height}
39 {
40 }
41
42 QString m_Name;
43 int m_Width;
44 int m_Height;
45 };
46
47 const auto COLUMN_PROPERTIES = QHash<int, ColumnProperties>{
48 {NAME_COLUMN, {QObject::tr("Name")}}, {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
49 {TEND_COLUMN, {QObject::tr("tEnd"), 180}}, {NBPOINTS_COLUMN, {QObject::tr("Nb points")}},
50 {UNIT_COLUMN, {QObject::tr("Unit")}}, {MISSION_COLUMN, {QObject::tr("Mission")}},
51 {PLUGIN_COLUMN, {QObject::tr("Plugin")}}};
52
53 QString uniqueName(const QString &defaultName,
54 const std::vector<std::shared_ptr<Variable> > &variables)
55 {
56 auto forbiddenNames = std::vector<QString>(variables.size());
57 std::transform(variables.cbegin(), variables.cend(), forbiddenNames.begin(),
58 [](const auto &variable) { return variable->name(); });
59 auto uniqueName = StringUtils::uniqueName(defaultName, forbiddenNames);
60 Q_ASSERT(!uniqueName.isEmpty());
61
62 return uniqueName;
63 }
64
65 } // namespace
66
67
68
69 VariableModel2::VariableModel2(const std::shared_ptr<VariableController2> &variableController, QObject *parent)
70 : QAbstractTableModel{parent}, _variableController{variableController}
71 {
72 }
73
74
75 int VariableModel2::columnCount(const QModelIndex &parent) const
76 {
77 Q_UNUSED(parent);
78
79 return NB_COLUMNS;
80 }
81
82 int VariableModel2::rowCount(const QModelIndex &parent) const
83 {
84 Q_UNUSED(parent);
85 return static_cast<int>(_variableController->variables().size());
86 }
87
88 QVariant VariableModel2::data(const QModelIndex &index, int role) const
89 {
90 if (!index.isValid()) {
91 return QVariant{};
92 }
93
94 if (index.row() < 0 || index.row() >= rowCount()) {
95 return QVariant{};
96 }
97
98 if (role == Qt::DisplayRole) {
99 if (auto variable = _variableController->variables()[index.row()]) {
100 switch (index.column()) {
101 case NAME_COLUMN:
102 return variable->name();
103 case TSTART_COLUMN: {
104 if(auto range = variable->realRange(); range.has_value())
105 return DateUtils::dateTime(range.value().m_TStart).toString(DATETIME_FORMAT);
106 return QVariant{};
107 }
108 case TEND_COLUMN: {
109 if(auto range = variable->realRange(); range.has_value())
110 return DateUtils::dateTime(range.value().m_TEnd).toString(DATETIME_FORMAT);
111 return QVariant{};
112 }
113 case NBPOINTS_COLUMN:
114 return variable->nbPoints();
115 case UNIT_COLUMN:
116 return variable->metadata().value(QStringLiteral("units"));
117 case MISSION_COLUMN:
118 return variable->metadata().value(QStringLiteral("mission"));
119 case PLUGIN_COLUMN:
120 return variable->metadata().value(QStringLiteral("plugin"));
121 default:
122 // No action
123 break;
124 }
125 }
126 }
127 else if (role == VariableRoles::ProgressRole) {
128 return QVariant{};
129 }
130
131 return QVariant{};
132 }
133
134 QVariant VariableModel2::headerData(int section, Qt::Orientation orientation, int role) const
135 {
136 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
137 return QVariant{};
138 }
139
140 if (orientation == Qt::Horizontal) {
141 auto propertiesIt = COLUMN_PROPERTIES.find(section);
142 if (propertiesIt != COLUMN_PROPERTIES.cend()) {
143 // Role is either DisplayRole or SizeHintRole
144 return (role == Qt::DisplayRole)
145 ? QVariant{propertiesIt->m_Name}
146 : QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
147 }
148 else {
149 qWarning(LOG_VariableModel())
150 << tr("Can't get header data (unknown column %1)").arg(section);
151 }
152 }
153
154 return QVariant{};
155 }
156
157 Qt::ItemFlags VariableModel2::flags(const QModelIndex &index) const
158 {
159 return QAbstractTableModel::flags(index) | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
160 }
161
162 Qt::DropActions VariableModel2::supportedDropActions() const
163 {
164 return Qt::CopyAction | Qt::MoveAction;
165 }
166
167 Qt::DropActions VariableModel2::supportedDragActions() const
168 {
169 return Qt::CopyAction | Qt::MoveAction;
170 }
171
172 QStringList VariableModel2::mimeTypes() const
173 {
174 return {MIME_TYPE_VARIABLE_LIST, MIME_TYPE_TIME_RANGE};
175 }
176
177 QMimeData *VariableModel2::mimeData(const QModelIndexList &indexes) const
178 {
179 auto mimeData = new QMimeData;
180 std::vector<std::shared_ptr<Variable> > variables;
181
182 DateTimeRange firstTimeRange;
183 for (const auto &index : indexes) {
184 if (index.column() == 0) { // only the first column
185 auto variable = _variableController->variables()[index.row()];
186 if (variable.get() && index.isValid()) {
187
188 if (variables.size()==0) {
189 // Gets the range of the first variable
190 firstTimeRange = std::move(variable->range());
191 }
192 variables.push_back(variable);
193 }
194 }
195 }
196
197 auto variablesEncodedData = _variableController->mimeData(variables);
198 mimeData->setData(MIME_TYPE_VARIABLE_LIST, variablesEncodedData);
199
200 if (variables.size() == 1) {
201 // No time range MIME data if multiple variables are dragged
202 auto timeEncodedData = TimeController::mimeDataForTimeRange(firstTimeRange);
203 mimeData->setData(MIME_TYPE_TIME_RANGE, timeEncodedData);
204 }
205
206 return mimeData;
207 }
208
209 bool VariableModel2::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row,
210 int column, const QModelIndex &parent) const
211 {
212 // drop of a product
213 return data->hasFormat(MIME_TYPE_PRODUCT_LIST)
214 || (data->hasFormat(MIME_TYPE_TIME_RANGE) && parent.isValid()
215 && !data->hasFormat(MIME_TYPE_VARIABLE_LIST));
216 }
217
218 bool VariableModel2::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
219 const QModelIndex &parent)
220 {
221 auto dropDone = false;
222
223 if (data->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
224 auto productList
225 = DataSourceController::productsDataForMimeData(data->data(MIME_TYPE_PRODUCT_LIST));
226
227 for (auto metaData : productList) {
228 //emit requestVariable(metaData.toHash());
229 //@TODO No idea what this does
230 }
231
232 dropDone = true;
233 }
234 else if (data->hasFormat(MIME_TYPE_TIME_RANGE) && parent.isValid()) {
235 auto variable = _variableController->variables()[parent.row()];
236 auto range = TimeController::timeRangeForMimeData(data->data(MIME_TYPE_TIME_RANGE));
237
238 _variableController->asyncChangeRange(variable, range);
239
240 dropDone = true;
241 }
242
243 return dropDone;
244 }
245
246 void VariableModel2::variableUpdated() noexcept
247 {
248
249 }
250
@@ -1,192 +1,194
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
7
8 OPTION (Catalog "builds catalog API" OFF)
8 OPTION (Catalog "builds catalog API" OFF)
9
9
10 set(CMAKE_CXX_STANDARD 17)
10 set(CMAKE_CXX_STANDARD 17)
11
11
12 set(CMAKE_AUTOMOC ON)
12 set(CMAKE_AUTOMOC ON)
13 #https://gitlab.kitware.com/cmake/cmake/issues/15227
13 #https://gitlab.kitware.com/cmake/cmake/issues/15227
14 #set(CMAKE_AUTOUIC ON)
14 #set(CMAKE_AUTOUIC ON)
15 if(POLICY CMP0071)
15 if(POLICY CMP0071)
16 cmake_policy(SET CMP0071 OLD)
16 cmake_policy(SET CMP0071 OLD)
17 endif()
17 endif()
18 set(CMAKE_AUTORCC ON)
18 set(CMAKE_AUTORCC ON)
19 set(CMAKE_INCLUDE_CURRENT_DIR ON)
19 set(CMAKE_INCLUDE_CURRENT_DIR ON)
20
20
21 find_package(Qt5 COMPONENTS Core Widgets Network PrintSupport Svg Test REQUIRED)
21 find_package(Qt5 COMPONENTS Core Widgets Network PrintSupport Svg Test REQUIRED)
22
22
23 find_package(pybind11 CONFIG QUIET)
23 find_package(pybind11 CONFIG QUIET)
24 if (NOT pybind11_FOUND)
24 if (NOT pybind11_FOUND)
25 execute_process(COMMAND git submodule init external/pybind11 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
25 execute_process(COMMAND git submodule init external/pybind11 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
26 execute_process(COMMAND git submodule update external/pybind11 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
26 execute_process(COMMAND git submodule update external/pybind11 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
27 add_subdirectory(external/pybind11)
27 add_subdirectory(external/pybind11)
28 endif()
28 endif()
29
29
30 macro(declare_test testname testexe sources libraries)
30 macro(declare_test testname testexe sources libraries)
31 add_executable(${testexe} ${sources})
31 add_executable(${testexe} ${sources})
32 target_link_libraries(${testexe} ${libraries})
32 target_link_libraries(${testexe} ${libraries})
33 add_test(NAME ${testname} COMMAND ${testexe})
33 add_test(NAME ${testname} COMMAND ${testexe})
34 endmacro(declare_test)
34 endmacro(declare_test)
35
35
36 enable_testing()
36 enable_testing()
37
37
38 FILE (GLOB_RECURSE core_SRCS
38 FILE (GLOB_RECURSE core_SRCS
39 ./include/DataSource/DataSourceItemMergeHelper.h
39 ./include/DataSource/DataSourceItemMergeHelper.h
40 ./include/DataSource/DataSourceItemAction.h
40 ./include/DataSource/DataSourceItemAction.h
41 ./include/DataSource/DataSourceItem.h
41 ./include/DataSource/DataSourceItem.h
42 ./include/DataSource/DataSourceController.h
42 ./include/DataSource/DataSourceController.h
43 ./include/Common/SortUtils.h
43 ./include/Common/SortUtils.h
44 ./include/Common/spimpl.h
44 ./include/Common/spimpl.h
45 ./include/Common/MimeTypesDef.h
45 ./include/Common/MimeTypesDef.h
46 ./include/Common/MetaTypes.h
46 ./include/Common/MetaTypes.h
47 ./include/Common/StringUtils.h
47 ./include/Common/StringUtils.h
48 ./include/Common/SignalWaiter.h
48 ./include/Common/SignalWaiter.h
49 ./include/Common/DateUtils.h
49 ./include/Common/DateUtils.h
50 ./include/Common/Numeric.h
50 ./include/Common/Numeric.h
51 ./include/Common/deprecate.h
51 ./include/Common/deprecate.h
52 ./include/Common/containers.h
52 ./include/Common/containers.h
53 ./include/Common/debug.h
53 ./include/Common/debug.h
54 ./include/Plugin/IPlugin.h
54 ./include/Plugin/IPlugin.h
55 ./include/Data/ArrayDataIterator.h
55 ./include/Data/ArrayDataIterator.h
56 ./include/Data/VariableRequest.h
56 ./include/Data/VariableRequest.h
57 ./include/Data/VectorSeries.h
57 ./include/Data/VectorSeries.h
58 ./include/Data/DateTimeRange.h
58 ./include/Data/DateTimeRange.h
59 ./include/Data/DateTimeRangeHelper.h
59 ./include/Data/DateTimeRangeHelper.h
60 ./include/Data/ScalarSeries.h
60 ./include/Data/ScalarSeries.h
61 ./include/Data/DataSeriesMergeHelper.h
61 ./include/Data/DataSeriesMergeHelper.h
62 ./include/Data/DataSeries.h
62 ./include/Data/DataSeries.h
63 ./include/Data/AcquisitionDataPacket.h
63 ./include/Data/AcquisitionDataPacket.h
64 ./include/Data/DataSeriesType.h
64 ./include/Data/DataSeriesType.h
65 ./include/Data/AcquisitionRequest.h
65 ./include/Data/AcquisitionRequest.h
66 ./include/Data/SqpIterator.h
66 ./include/Data/SqpIterator.h
67 ./include/Data/ArrayData.h
67 ./include/Data/ArrayData.h
68 ./include/Data/DataSeriesIterator.h
68 ./include/Data/DataSeriesIterator.h
69 ./include/Data/DataSeriesUtils.h
69 ./include/Data/DataSeriesUtils.h
70 ./include/Data/SpectrogramSeries.h
70 ./include/Data/SpectrogramSeries.h
71 ./include/Data/Unit.h
71 ./include/Data/Unit.h
72 ./include/Data/DataProviderParameters.h
72 ./include/Data/DataProviderParameters.h
73 ./include/Data/OptionalAxis.h
73 ./include/Data/OptionalAxis.h
74 ./include/Data/IDataProvider.h
74 ./include/Data/IDataProvider.h
75 ./include/Data/IDataSeries.h
75 ./include/Data/IDataSeries.h
76 ./include/Network/NetworkController.h
76 ./include/Network/NetworkController.h
77 ./include/Network/Downloader.h
77 ./include/Network/Downloader.h
78 ./include/Version.h
78 ./include/Version.h
79 ./include/CoreGlobal.h
79 ./include/CoreGlobal.h
80 ./include/Visualization/VisualizationController.h
80 ./include/Visualization/VisualizationController.h
81 ./include/PluginManager/PluginManager.h
81 ./include/PluginManager/PluginManager.h
82 ./include/Variable/VariableModel.h
82 ./include/Variable/VariableModel.h
83 ./include/Variable/VariableModel2.h
83 ./include/Variable/VariableAcquisitionWorker.h
84 ./include/Variable/VariableAcquisitionWorker.h
84 ./include/Variable/VariableCacheStrategy.h
85 ./include/Variable/VariableCacheStrategy.h
85 ./include/Variable/VariableSynchronizationGroup.h
86 ./include/Variable/VariableSynchronizationGroup.h
86 ./include/Variable/VariableSynchronizationGroup2.h
87 ./include/Variable/VariableSynchronizationGroup2.h
87 ./include/Variable/ProportionalCacheStrategy.h
88 ./include/Variable/ProportionalCacheStrategy.h
88 ./include/Variable/SingleThresholdCacheStrategy.h
89 ./include/Variable/SingleThresholdCacheStrategy.h
89 ./include/Variable/VariableCacheStrategyFactory.h
90 ./include/Variable/VariableCacheStrategyFactory.h
90 ./include/Variable/Variable.h
91 ./include/Variable/Variable.h
91 ./include/Variable/VariableCacheController.h
92 ./include/Variable/VariableCacheController.h
92 ./include/Variable/VariableController.h
93 ./include/Variable/VariableController.h
93 ./include/Variable/VariableController2.h
94 ./include/Variable/VariableController2.h
94 ./include/Variable/private/VCTransaction.h
95 ./include/Variable/private/VCTransaction.h
95 ./include/Time/TimeController.h
96 ./include/Time/TimeController.h
96 ./include/Settings/ISqpSettingsBindable.h
97 ./include/Settings/ISqpSettingsBindable.h
97 ./include/Settings/SqpSettingsDefs.h
98 ./include/Settings/SqpSettingsDefs.h
98
99
99 ./src/DataSource/DataSourceItem.cpp
100 ./src/DataSource/DataSourceItem.cpp
100 ./src/DataSource/DataSourceItemAction.cpp
101 ./src/DataSource/DataSourceItemAction.cpp
101 ./src/DataSource/DataSourceItemMergeHelper.cpp
102 ./src/DataSource/DataSourceItemMergeHelper.cpp
102 ./src/DataSource/DataSourceController.cpp
103 ./src/DataSource/DataSourceController.cpp
103 ./src/Common/DateUtils.cpp
104 ./src/Common/DateUtils.cpp
104 ./src/Common/MimeTypesDef.cpp
105 ./src/Common/MimeTypesDef.cpp
105 ./src/Common/StringUtils.cpp
106 ./src/Common/StringUtils.cpp
106 ./src/Common/SignalWaiter.cpp
107 ./src/Common/SignalWaiter.cpp
107 ./src/Data/ScalarSeries.cpp
108 ./src/Data/ScalarSeries.cpp
108 ./src/Data/DataSeriesIterator.cpp
109 ./src/Data/DataSeriesIterator.cpp
109 ./src/Data/OptionalAxis.cpp
110 ./src/Data/OptionalAxis.cpp
110 ./src/Data/ArrayDataIterator.cpp
111 ./src/Data/ArrayDataIterator.cpp
111 ./src/Data/SpectrogramSeries.cpp
112 ./src/Data/SpectrogramSeries.cpp
112 ./src/Data/DataSeriesUtils.cpp
113 ./src/Data/DataSeriesUtils.cpp
113 ./src/Data/VectorSeries.cpp
114 ./src/Data/VectorSeries.cpp
114 ./src/Network/NetworkController.cpp
115 ./src/Network/NetworkController.cpp
115 ./src/Network/Downloader.cpp
116 ./src/Network/Downloader.cpp
116 ./src/Visualization/VisualizationController.cpp
117 ./src/Visualization/VisualizationController.cpp
117 ./src/PluginManager/PluginManager.cpp
118 ./src/PluginManager/PluginManager.cpp
118 ./src/Variable/VariableController.cpp
119 ./src/Variable/VariableController.cpp
119 ./src/Variable/VariableController2.cpp
120 ./src/Variable/VariableController2.cpp
120 ./src/Variable/VariableModel.cpp
121 ./src/Variable/VariableModel.cpp
122 ./src/Variable/VariableModel2.cpp
121 ./src/Variable/VariableCacheController.cpp
123 ./src/Variable/VariableCacheController.cpp
122 ./src/Variable/VariableSynchronizationGroup.cpp
124 ./src/Variable/VariableSynchronizationGroup.cpp
123 ./src/Variable/VariableSynchronizationGroup2.cpp
125 ./src/Variable/VariableSynchronizationGroup2.cpp
124 ./src/Variable/Variable.cpp
126 ./src/Variable/Variable.cpp
125 ./src/Variable/VariableAcquisitionWorker.cpp
127 ./src/Variable/VariableAcquisitionWorker.cpp
126 ./src/Version.cpp
128 ./src/Version.cpp
127 ./src/Time/TimeController.cpp
129 ./src/Time/TimeController.cpp
128 ./src/Settings/SqpSettingsDefs.cpp
130 ./src/Settings/SqpSettingsDefs.cpp
129
131
130 )
132 )
131
133
132
134
133 IF(Catalog)
135 IF(Catalog)
134 FILE (GLOB_RECURSE core_catalog_SRCS
136 FILE (GLOB_RECURSE core_catalog_SRCS
135 ./src/Catalogue/CatalogueController.cpp
137 ./src/Catalogue/CatalogueController.cpp
136 ./include/Catalogue/CatalogueController.h
138 ./include/Catalogue/CatalogueController.h
137 )
139 )
138 ELSE()
140 ELSE()
139 FILE (GLOB_RECURSE core_catalog_SRCS
141 FILE (GLOB_RECURSE core_catalog_SRCS
140 )
142 )
141 ENDIF(Catalog)
143 ENDIF(Catalog)
142
144
143 add_definitions(-DCORE_STATIC)
145 add_definitions(-DCORE_STATIC)
144 #add_definitions(-DHIDE_DEPRECATED)
146 #add_definitions(-DHIDE_DEPRECATED)
145 add_definitions(-DSCIQLOP_CRASH_ON_ERROR)
147 add_definitions(-DSCIQLOP_CRASH_ON_ERROR)
146
148
147 add_library(sciqlopcore ${core_SRCS} ${core_catalog_SRCS})
149 add_library(sciqlopcore ${core_SRCS} ${core_catalog_SRCS})
148 SET_TARGET_PROPERTIES(sciqlopcore PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
150 SET_TARGET_PROPERTIES(sciqlopcore PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
149
151
150 target_include_directories(sciqlopcore PUBLIC
152 target_include_directories(sciqlopcore PUBLIC
151 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
153 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
152 $<INSTALL_INTERFACE:include/SciQLOP>
154 $<INSTALL_INTERFACE:include/SciQLOP>
153 )
155 )
154
156
155 target_link_libraries(sciqlopcore PUBLIC
157 target_link_libraries(sciqlopcore PUBLIC
156 Qt5::Core
158 Qt5::Core
157 Qt5::Network
159 Qt5::Network
158 )
160 )
159
161
160 if(Catalog)
162 if(Catalog)
161 target_link_libraries(sciqlopcore PUBLIC
163 target_link_libraries(sciqlopcore PUBLIC
162 catalogs
164 catalogs
163 )
165 )
164 endif()
166 endif()
165
167
166
168
167 pybind11_add_module(sciqlopqt src/pybind11_wrappers/QtWrappers.cpp)
169 pybind11_add_module(sciqlopqt src/pybind11_wrappers/QtWrappers.cpp)
168 target_link_libraries(sciqlopqt PUBLIC Qt5::Core)
170 target_link_libraries(sciqlopqt PUBLIC Qt5::Core)
169
171
170 pybind11_add_module(pysciqlopcore src/pybind11_wrappers/CoreWrappers.cpp)
172 pybind11_add_module(pysciqlopcore src/pybind11_wrappers/CoreWrappers.cpp)
171 target_link_libraries(pysciqlopcore PUBLIC sciqlopcore)
173 target_link_libraries(pysciqlopcore PUBLIC sciqlopcore)
172
174
173 add_library(pysciqlop src/pybind11_wrappers/pywrappers_common.h)
175 add_library(pysciqlop src/pybind11_wrappers/pywrappers_common.h)
174 target_link_libraries(pysciqlop PUBLIC Qt5::Core)
176 target_link_libraries(pysciqlop PUBLIC Qt5::Core)
175 target_include_directories(pysciqlop PUBLIC
177 target_include_directories(pysciqlop PUBLIC
176 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/pybind11_wrappers/>
178 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/pybind11_wrappers/>
177 $<INSTALL_INTERFACE:include/SciQLOP/py_wrappers>
179 $<INSTALL_INTERFACE:include/SciQLOP/py_wrappers>
178 )
180 )
179
181
180 SET_PROPERTY(GLOBAL PROPERTY CORE_PYTHON_PATH ${CMAKE_CURRENT_BINARY_DIR})
182 SET_PROPERTY(GLOBAL PROPERTY CORE_PYTHON_PATH ${CMAKE_CURRENT_BINARY_DIR})
181
183
182
184
183 install(TARGETS sciqlopcore EXPORT SciQLOPCoreConfig
185 install(TARGETS sciqlopcore EXPORT SciQLOPCoreConfig
184 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
186 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
185 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
187 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
186 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
188 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
187
189
188 install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/SciQLOP)
190 install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/SciQLOP)
189 install(EXPORT SciQLOPCoreConfig DESTINATION share/SciQLOPCore/cmake)
191 install(EXPORT SciQLOPCoreConfig DESTINATION share/SciQLOPCore/cmake)
190 export(TARGETS sciqlopcore FILE SciQLOPCoreConfig.cmake)
192 export(TARGETS sciqlopcore FILE SciQLOPCoreConfig.cmake)
191
193
192 add_subdirectory(tests)
194 add_subdirectory(tests)
@@ -1,44 +1,46
1 #include <memory>
1 #include <memory>
2 #include <vector>
2 #include <vector>
3 #include <set>
3 #include <set>
4 #include <QHash>
4 #include <QHash>
5 #include <QObject>
5 #include <QObject>
6 #include <QMutexLocker>
6 #include <QMutexLocker>
7 #include <QUuid>
7 #include <QUuid>
8 #include <QByteArray>
8 #include <QItemSelectionModel>
9 #include <QItemSelectionModel>
9 #include <Common/spimpl.h>
10 #include <Common/spimpl.h>
10 #include <Variable/Variable.h>
11 #include <Variable/Variable.h>
11 //#include <Variable/VariableSynchronizationGroup.h>
12 //#include <Variable/VariableSynchronizationGroup.h>
12 #include <Variable/VariableModel.h>
13 #include <Variable/VariableModel.h>
13 #include <Data/IDataProvider.h>
14 #include <Data/IDataProvider.h>
14 #include "Data/DateTimeRange.h"
15 #include "Data/DateTimeRange.h"
15
16
16 class VariableController2: public QObject
17 class VariableController2: public QObject
17 {
18 {
18 class VariableController2Private;
19 class VariableController2Private;
19 Q_OBJECT
20 Q_OBJECT
20
21
21 spimpl::unique_impl_ptr<VariableController2Private> impl;
22 spimpl::unique_impl_ptr<VariableController2Private> impl;
22
23
23 public:
24 public:
24 explicit VariableController2();
25 explicit VariableController2();
25 std::shared_ptr<Variable> createVariable(const QString &name, const QVariantHash &metadata,
26 std::shared_ptr<Variable> createVariable(const QString &name, const QVariantHash &metadata,
26 const std::shared_ptr<IDataProvider>& provider,
27 const std::shared_ptr<IDataProvider>& provider,
27 const DateTimeRange &range);
28 const DateTimeRange &range);
28
29
29 std::shared_ptr<Variable> cloneVariable(const std::shared_ptr<Variable>& variable);
30 std::shared_ptr<Variable> cloneVariable(const std::shared_ptr<Variable>& variable);
30 void deleteVariable(const std::shared_ptr<Variable>& variable);
31 void deleteVariable(const std::shared_ptr<Variable>& variable);
31 void changeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r);
32 void changeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r);
32 void asyncChangeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r);
33 void asyncChangeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r);
33 const std::set<std::shared_ptr<Variable>> variables();
34 const std::vector<std::shared_ptr<Variable>> variables();
34
35
35 bool isReady(const std::shared_ptr<Variable>& variable);
36 bool isReady(const std::shared_ptr<Variable>& variable);
36
37
37 void synchronize(const std::shared_ptr<Variable>& var, const std::shared_ptr<Variable>& with);
38 void synchronize(const std::shared_ptr<Variable>& var, const std::shared_ptr<Variable>& with);
38
39
40 QByteArray mimeData(const std::vector<std::shared_ptr<Variable>> &variables) const;
39
41
40 signals:
42 signals:
41 void variableAdded(const std::shared_ptr<Variable>&);
43 void variableAdded(const std::shared_ptr<Variable>&);
42 void variableDeleted(const std::shared_ptr<Variable>&);
44 void variableDeleted(const std::shared_ptr<Variable>&);
43
45
44 };
46 };
@@ -1,347 +1,358
1 #include <QQueue>
1 #include <QQueue>
2 #include <QThreadPool>
2 #include <QThreadPool>
3 #include <QRunnable>
3 #include <QRunnable>
4 #include <QObject>
4 #include <QObject>
5 #include <QDataStream>
5
6
6 #include "Variable/VariableController2.h"
7 #include "Variable/VariableController2.h"
7 #include "Variable/VariableSynchronizationGroup2.h"
8 #include "Variable/VariableSynchronizationGroup2.h"
8 #include <Common/containers.h>
9 #include <Common/containers.h>
9 #include <Common/debug.h>
10 #include <Common/debug.h>
10 #include <Data/DataProviderParameters.h>
11 #include <Data/DataProviderParameters.h>
11 #include <Data/DateTimeRangeHelper.h>
12 #include <Data/DateTimeRangeHelper.h>
12 #include <Data/DateTimeRange.h>
13 #include <Data/DateTimeRange.h>
13 #include <Variable/VariableCacheStrategyFactory.h>
14 #include <Variable/VariableCacheStrategyFactory.h>
14 #include <Variable/private/VCTransaction.h>
15 #include <Variable/private/VCTransaction.h>
15 #include <QCoreApplication>
16 #include <QCoreApplication>
16
17
17
18
18
19
19 class VariableController2::VariableController2Private
20 class VariableController2::VariableController2Private
20 {
21 {
21 struct threadSafeVaraiblesMaps
22 struct threadSafeVaraiblesMaps
22 {
23 {
23 inline void addVariable(const std::shared_ptr<Variable>& variable, const std::shared_ptr<IDataProvider>& provider, const std::shared_ptr<VariableSynchronizationGroup2>& synchronizationGroup)
24 inline void addVariable(const std::shared_ptr<Variable>& variable, const std::shared_ptr<IDataProvider>& provider, const std::shared_ptr<VariableSynchronizationGroup2>& synchronizationGroup)
24 {
25 {
25 QWriteLocker lock{&_lock};
26 QWriteLocker lock{&_lock};
26 _variables[*variable] = variable;
27 _variables[*variable] = variable;
27 _providers[*variable] = provider;
28 _providers[*variable] = provider;
28 _synchronizationGroups[*variable] = synchronizationGroup;
29 _synchronizationGroups[*variable] = synchronizationGroup;
29 }
30 }
30
31
31 inline void removeVariable(const std::shared_ptr<Variable>& variable)
32 inline void removeVariable(const std::shared_ptr<Variable>& variable)
32 {
33 {
33 QWriteLocker lock{&_lock};
34 QWriteLocker lock{&_lock};
34 _variables.remove(*variable);
35 _variables.remove(*variable);
35 _providers.remove(*variable);
36 _providers.remove(*variable);
36 _synchronizationGroups.remove(*variable);
37 _synchronizationGroups.remove(*variable);
37 }
38 }
38
39
39 inline void synchronize(const std::shared_ptr<Variable>& variable, const std::optional<std::shared_ptr<Variable>>& with)
40 inline void synchronize(const std::shared_ptr<Variable>& variable, const std::optional<std::shared_ptr<Variable>>& with)
40 {
41 {
41 QWriteLocker lock{&_lock};
42 QWriteLocker lock{&_lock};
42 if(with.has_value())
43 if(with.has_value())
43 {
44 {
44 auto newGroup = _synchronizationGroups[*with.value()];
45 auto newGroup = _synchronizationGroups[*with.value()];
45 newGroup->addVariable(*variable);
46 newGroup->addVariable(*variable);
46 _synchronizationGroups[*variable] = newGroup;
47 _synchronizationGroups[*variable] = newGroup;
47 }
48 }
48 else
49 else
49 {
50 {
50 _synchronizationGroups[*variable] = std::make_shared<VariableSynchronizationGroup2>(*variable);
51 _synchronizationGroups[*variable] = std::make_shared<VariableSynchronizationGroup2>(*variable);
51 }
52 }
52 }
53 }
53
54
54 inline std::shared_ptr<Variable> variable(QUuid variable)
55 inline std::shared_ptr<Variable> variable(QUuid variable)
55 {
56 {
56 QReadLocker lock{&_lock};
57 QReadLocker lock{&_lock};
57 [[unlikely]]
58 [[unlikely]]
58 if(!_variables.contains(variable))
59 if(!_variables.contains(variable))
59 SCIQLOP_ERROR(threadSafeVaraiblesMaps,"Unknown Variable");
60 SCIQLOP_ERROR(threadSafeVaraiblesMaps,"Unknown Variable");
60 return _variables[variable];
61 return _variables[variable];
61 }
62 }
62
63
63 inline const std::set<std::shared_ptr<Variable>> variables()
64 inline const std::vector<std::shared_ptr<Variable>> variables()
64 {
65 {
65 std::set<std::shared_ptr<Variable>> vars;
66 std::vector<std::shared_ptr<Variable>> vars;
66 QReadLocker lock{&_lock};
67 QReadLocker lock{&_lock};
67 for(const auto &var:_variables)
68 for(const auto &var:_variables)
68 {
69 {
69 vars.insert(var);
70 vars.push_back(var);
70 }
71 }
71 return vars;
72 return vars;
72 }
73 }
73
74
74 inline std::shared_ptr<IDataProvider> provider(QUuid variable)
75 inline std::shared_ptr<IDataProvider> provider(QUuid variable)
75 {
76 {
76 QReadLocker lock{&_lock};
77 QReadLocker lock{&_lock};
77 [[unlikely]]
78 [[unlikely]]
78 if(!_providers.contains(variable))
79 if(!_providers.contains(variable))
79 SCIQLOP_ERROR(threadSafeVaraiblesMaps,"Unknown Variable");
80 SCIQLOP_ERROR(threadSafeVaraiblesMaps,"Unknown Variable");
80 return _providers[variable];
81 return _providers[variable];
81 }
82 }
82
83
83 inline std::shared_ptr<VariableSynchronizationGroup2> group(QUuid variable)
84 inline std::shared_ptr<VariableSynchronizationGroup2> group(QUuid variable)
84 {
85 {
85 QReadLocker lock{&_lock};
86 QReadLocker lock{&_lock};
86 [[unlikely]]
87 [[unlikely]]
87 if(!_synchronizationGroups.contains(variable))
88 if(!_synchronizationGroups.contains(variable))
88 SCIQLOP_ERROR(threadSafeVaraiblesMaps,"Unknown Variable");
89 SCIQLOP_ERROR(threadSafeVaraiblesMaps,"Unknown Variable");
89 return _synchronizationGroups[variable];
90 return _synchronizationGroups[variable];
90 }
91 }
91
92
92 inline bool has(const std::shared_ptr<Variable>& variable)
93 inline bool has(const std::shared_ptr<Variable>& variable)
93 {
94 {
94 QReadLocker lock{&_lock};
95 QReadLocker lock{&_lock};
95 return _variables.contains(*variable);
96 return _variables.contains(*variable);
96 }
97 }
97
98
98 private:
99 private:
99 QMap<QUuid,std::shared_ptr<Variable>> _variables;
100 QMap<QUuid,std::shared_ptr<Variable>> _variables;
100 QMap<QUuid,std::shared_ptr<IDataProvider>> _providers;
101 QMap<QUuid,std::shared_ptr<IDataProvider>> _providers;
101 QMap<QUuid,std::shared_ptr<VariableSynchronizationGroup2>> _synchronizationGroups;
102 QMap<QUuid,std::shared_ptr<VariableSynchronizationGroup2>> _synchronizationGroups;
102 QReadWriteLock _lock{QReadWriteLock::Recursive};
103 QReadWriteLock _lock{QReadWriteLock::Recursive};
103 }_maps;
104 }_maps;
104 QThreadPool _ThreadPool;
105 QThreadPool _ThreadPool;
105 VCTransactionsQueues _transactions;
106 VCTransactionsQueues _transactions;
106 std::unique_ptr<VariableCacheStrategy> _cacheStrategy;
107 std::unique_ptr<VariableCacheStrategy> _cacheStrategy;
107
108
108 void _transactionComplete(QUuid group, std::shared_ptr<VCTransaction> transaction)
109 void _transactionComplete(QUuid group, std::shared_ptr<VCTransaction> transaction)
109 {
110 {
110 if(transaction->done())
111 if(transaction->done())
111 {
112 {
112 _transactions.complete(group);
113 _transactions.complete(group);
113 }
114 }
114 this->_processTransactions();
115 this->_processTransactions();
115 }
116 }
116 void _processTransactions()
117 void _processTransactions()
117 {
118 {
118 auto nextTransactions = _transactions.nextTransactions();
119 auto nextTransactions = _transactions.nextTransactions();
119 auto pendingTransactions = _transactions.pendingTransactions();
120 auto pendingTransactions = _transactions.pendingTransactions();
120 for( auto [groupID, newTransaction] : nextTransactions)
121 for( auto [groupID, newTransaction] : nextTransactions)
121 {
122 {
122 if(newTransaction.has_value() && !pendingTransactions[groupID].has_value())
123 if(newTransaction.has_value() && !pendingTransactions[groupID].has_value())
123 {
124 {
124 _transactions.start(groupID);
125 _transactions.start(groupID);
125 auto refVar = _maps.variable(newTransaction.value()->refVar);
126 auto refVar = _maps.variable(newTransaction.value()->refVar);
126 auto ranges = _computeAllRangesInGroup(refVar,newTransaction.value()->range);
127 auto ranges = _computeAllRangesInGroup(refVar,newTransaction.value()->range);
127 for( auto const& [ID, range] : ranges)
128 for( auto const& [ID, range] : ranges)
128 {
129 {
129 auto provider = _maps.provider(ID);
130 auto provider = _maps.provider(ID);
130 auto variable = _maps.variable(ID);
131 auto variable = _maps.variable(ID);
131 auto [missingRanges, newCacheRange] = _computeMissingRanges(variable,range);
132 auto [missingRanges, newCacheRange] = _computeMissingRanges(variable,range);
132 auto exe = new TransactionExe(variable, provider, missingRanges, range, newCacheRange);
133 auto exe = new TransactionExe(variable, provider, missingRanges, range, newCacheRange);
133 QObject::connect(exe,
134 QObject::connect(exe,
134 &TransactionExe::transactionComplete,
135 &TransactionExe::transactionComplete,
135 [groupID=groupID,transaction=newTransaction.value(),this]()
136 [groupID=groupID,transaction=newTransaction.value(),this]()
136 {
137 {
137 this->_transactionComplete(groupID, transaction);
138 this->_transactionComplete(groupID, transaction);
138 }
139 }
139 );
140 );
140 _ThreadPool.start(exe);
141 _ThreadPool.start(exe);
141 }
142 }
142 }
143 }
143 }
144 }
144 }
145 }
145
146
146 std::map<QUuid,DateTimeRange> _computeAllRangesInGroup(const std::shared_ptr<Variable>& refVar, DateTimeRange r)
147 std::map<QUuid,DateTimeRange> _computeAllRangesInGroup(const std::shared_ptr<Variable>& refVar, DateTimeRange r)
147 {
148 {
148 std::map<QUuid,DateTimeRange> ranges;
149 std::map<QUuid,DateTimeRange> ranges;
149 if(!DateTimeRangeHelper::hasnan(r))
150 if(!DateTimeRangeHelper::hasnan(r))
150 {
151 {
151 auto group = _maps.group(*refVar);
152 auto group = _maps.group(*refVar);
152 if(auto transformation = DateTimeRangeHelper::computeTransformation(refVar->range(),r);
153 if(auto transformation = DateTimeRangeHelper::computeTransformation(refVar->range(),r);
153 transformation.has_value())
154 transformation.has_value())
154 {
155 {
155 for(auto varId:group->variables())
156 for(auto varId:group->variables())
156 {
157 {
157 auto var = _maps.variable(varId);
158 auto var = _maps.variable(varId);
158 auto newRange = var->range().transform(transformation.value());
159 auto newRange = var->range().transform(transformation.value());
159 ranges[varId] = newRange;
160 ranges[varId] = newRange;
160 }
161 }
161 }
162 }
162 else // force new range to all variables -> may be weird if more than one var in the group
163 else // force new range to all variables -> may be weird if more than one var in the group
163 // @TODO ensure that there is no side effects
164 // @TODO ensure that there is no side effects
164 {
165 {
165 for(auto varId:group->variables())
166 for(auto varId:group->variables())
166 {
167 {
167 auto var = _maps.variable(varId);
168 auto var = _maps.variable(varId);
168 ranges[varId] = r;
169 ranges[varId] = r;
169 }
170 }
170 }
171 }
171 }
172 }
172 else
173 else
173 {
174 {
174 SCIQLOP_ERROR(VariableController2Private, "Invalid range containing NaN");
175 SCIQLOP_ERROR(VariableController2Private, "Invalid range containing NaN");
175 }
176 }
176 return ranges;
177 return ranges;
177 }
178 }
178
179
179 std::pair<std::vector<DateTimeRange>,DateTimeRange> _computeMissingRanges(const std::shared_ptr<Variable>& var, DateTimeRange r)
180 std::pair<std::vector<DateTimeRange>,DateTimeRange> _computeMissingRanges(const std::shared_ptr<Variable>& var, DateTimeRange r)
180 {
181 {
181 DateTimeRange newCacheRange;
182 DateTimeRange newCacheRange;
182 std::vector<DateTimeRange> missingRanges;
183 std::vector<DateTimeRange> missingRanges;
183 if(DateTimeRangeHelper::hasnan(var->cacheRange()))
184 if(DateTimeRangeHelper::hasnan(var->cacheRange()))
184 {
185 {
185 newCacheRange = _cacheStrategy->computeRange(r,r);
186 newCacheRange = _cacheStrategy->computeRange(r,r);
186 missingRanges = {newCacheRange};
187 missingRanges = {newCacheRange};
187 }
188 }
188 else
189 else
189 {
190 {
190 newCacheRange = _cacheStrategy->computeRange(var->cacheRange(),r);
191 newCacheRange = _cacheStrategy->computeRange(var->cacheRange(),r);
191 missingRanges = newCacheRange - var->cacheRange();
192 missingRanges = newCacheRange - var->cacheRange();
192 }
193 }
193 return {missingRanges,newCacheRange};
194 return {missingRanges,newCacheRange};
194 }
195 }
195
196
196 void _changeRange(QUuid id, DateTimeRange r)
197 void _changeRange(QUuid id, DateTimeRange r)
197 {
198 {
198 _changeRange(_maps.variable(id) ,r);
199 _changeRange(_maps.variable(id) ,r);
199 }
200 }
200 void _changeRange(const std::shared_ptr<Variable>& var, DateTimeRange r)
201 void _changeRange(const std::shared_ptr<Variable>& var, DateTimeRange r)
201 {
202 {
202 auto provider = _maps.provider(*var);
203 auto provider = _maps.provider(*var);
203 auto [missingRanges, newCacheRange] = _computeMissingRanges(var,r);
204 auto [missingRanges, newCacheRange] = _computeMissingRanges(var,r);
204 std::vector<IDataSeries*> data;
205 std::vector<IDataSeries*> data;
205 for(auto range:missingRanges)
206 for(auto range:missingRanges)
206 {
207 {
207 data.push_back(provider->getData(DataProviderParameters{{range}, var->metadata()}));
208 data.push_back(provider->getData(DataProviderParameters{{range}, var->metadata()}));
208 }
209 }
209 var->updateData(data, r, newCacheRange, true);
210 var->updateData(data, r, newCacheRange, true);
210 }
211 }
211 public:
212 public:
212 VariableController2Private(QObject* parent=Q_NULLPTR)
213 VariableController2Private(QObject* parent=Q_NULLPTR)
213 :_cacheStrategy(VariableCacheStrategyFactory::createCacheStrategy(CacheStrategy::SingleThreshold))
214 :_cacheStrategy(VariableCacheStrategyFactory::createCacheStrategy(CacheStrategy::SingleThreshold))
214 {
215 {
215 Q_UNUSED(parent);
216 Q_UNUSED(parent);
216 this->_ThreadPool.setMaxThreadCount(32);
217 this->_ThreadPool.setMaxThreadCount(32);
217 }
218 }
218
219
219 /*
220 /*
220 * This dtor has to like this even if this is ugly, because default dtor would rely on
221 * This dtor has to like this even if this is ugly, because default dtor would rely on
221 * declaration order to destruct members and that would always lead to regressions when
222 * declaration order to destruct members and that would always lead to regressions when
222 * modifying class members
223 * modifying class members
223 */
224 */
224 ~VariableController2Private()
225 ~VariableController2Private()
225 {
226 {
226 while (this->_ThreadPool.activeThreadCount())
227 while (this->_ThreadPool.activeThreadCount())
227 {
228 {
228 this->_ThreadPool.waitForDone(100);
229 this->_ThreadPool.waitForDone(100);
229 }
230 }
230 }
231 }
231
232
232 std::shared_ptr<Variable> createVariable(const QString &name, const QVariantHash &metadata, std::shared_ptr<IDataProvider> provider)
233 std::shared_ptr<Variable> createVariable(const QString &name, const QVariantHash &metadata, std::shared_ptr<IDataProvider> provider)
233 {
234 {
234 auto newVar = std::make_shared<Variable>(name,metadata);
235 auto newVar = std::make_shared<Variable>(name,metadata);
235 auto group = std::make_shared<VariableSynchronizationGroup2>(newVar->ID());
236 auto group = std::make_shared<VariableSynchronizationGroup2>(newVar->ID());
236 _maps.addVariable(newVar,std::move(provider),group);
237 _maps.addVariable(newVar,std::move(provider),group);
237 this->_transactions.addEntry(*group);
238 this->_transactions.addEntry(*group);
238 return newVar;
239 return newVar;
239 }
240 }
240
241
241 std::shared_ptr<Variable> cloneVariable(const std::shared_ptr<Variable>& variable)
242 std::shared_ptr<Variable> cloneVariable(const std::shared_ptr<Variable>& variable)
242 {
243 {
243 auto newVar = variable->clone();
244 auto newVar = variable->clone();
244 _maps.synchronize(newVar,std::nullopt);
245 _maps.synchronize(newVar,std::nullopt);
245 _maps.addVariable(newVar,_maps.provider(*variable),_maps.group(*newVar));
246 _maps.addVariable(newVar,_maps.provider(*variable),_maps.group(*newVar));
246 this->_transactions.addEntry(*_maps.group(*newVar));
247 this->_transactions.addEntry(*_maps.group(*newVar));
247 return newVar;
248 return newVar;
248 }
249 }
249
250
250 bool hasPendingTransactions(const std::shared_ptr<Variable>& variable)
251 bool hasPendingTransactions(const std::shared_ptr<Variable>& variable)
251 {
252 {
252 return _transactions.active(*_maps.group(*variable));
253 return _transactions.active(*_maps.group(*variable));
253 }
254 }
254
255
255 void deleteVariable(const std::shared_ptr<Variable>& variable)
256 void deleteVariable(const std::shared_ptr<Variable>& variable)
256 {
257 {
257 _maps.removeVariable(variable);
258 _maps.removeVariable(variable);
258 }
259 }
259
260
260 void asyncChangeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r)
261 void asyncChangeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r)
261 {
262 {
262 if(!DateTimeRangeHelper::hasnan(r))
263 if(!DateTimeRangeHelper::hasnan(r))
263 {
264 {
264 auto group = _maps.group(*variable);
265 auto group = _maps.group(*variable);
265 // Just overwrite next transaction
266 // Just overwrite next transaction
266 {
267 {
267 _transactions.enqueue(*group,std::make_shared<VCTransaction>(variable->ID(), r, static_cast<int>(group->variables().size())));
268 _transactions.enqueue(*group,std::make_shared<VCTransaction>(variable->ID(), r, static_cast<int>(group->variables().size())));
268 }
269 }
269 _processTransactions();
270 _processTransactions();
270 }
271 }
271 else
272 else
272 {
273 {
273 SCIQLOP_ERROR(VariableController2Private, "Invalid range containing NaN");
274 SCIQLOP_ERROR(VariableController2Private, "Invalid range containing NaN");
274 }
275 }
275 }
276 }
276
277
277 void changeRange(const std::shared_ptr<Variable>& variable, DateTimeRange r)
278 void changeRange(const std::shared_ptr<Variable>& variable, DateTimeRange r)
278 {
279 {
279 asyncChangeRange(variable,r);
280 asyncChangeRange(variable,r);
280 while (hasPendingTransactions(variable))
281 while (hasPendingTransactions(variable))
281 {
282 {
282 QCoreApplication::processEvents();
283 QCoreApplication::processEvents();
283 }
284 }
284 }
285 }
285
286
286 inline void synchronize(const std::shared_ptr<Variable>& var, const std::shared_ptr<Variable>& with)
287 inline void synchronize(const std::shared_ptr<Variable>& var, const std::shared_ptr<Variable>& with)
287 {
288 {
288 _maps.synchronize(var, with);
289 _maps.synchronize(var, with);
289 }
290 }
290
291
291 inline const std::set<std::shared_ptr<Variable>> variables()
292 inline const std::vector<std::shared_ptr<Variable>> variables()
292 {
293 {
293 return _maps.variables();
294 return _maps.variables();
294 }
295 }
295
296
296 };
297 };
297
298
298 VariableController2::VariableController2()
299 VariableController2::VariableController2()
299 :impl{spimpl::make_unique_impl<VariableController2Private>()}
300 :impl{spimpl::make_unique_impl<VariableController2Private>()}
300 {}
301 {}
301
302
302 std::shared_ptr<Variable> VariableController2::createVariable(const QString &name, const QVariantHash &metadata, const std::shared_ptr<IDataProvider>& provider, const DateTimeRange &range)
303 std::shared_ptr<Variable> VariableController2::createVariable(const QString &name, const QVariantHash &metadata, const std::shared_ptr<IDataProvider>& provider, const DateTimeRange &range)
303 {
304 {
304 auto var = impl->createVariable(name, metadata, provider);
305 auto var = impl->createVariable(name, metadata, provider);
305 emit variableAdded(var);
306 emit variableAdded(var);
306 if(!DateTimeRangeHelper::hasnan(range))
307 if(!DateTimeRangeHelper::hasnan(range))
307 impl->changeRange(var,range);
308 impl->changeRange(var,range);
308 else
309 else
309 SCIQLOP_ERROR(VariableController2, "Creating a variable with default constructed DateTimeRange is an error");
310 SCIQLOP_ERROR(VariableController2, "Creating a variable with default constructed DateTimeRange is an error");
310 return var;
311 return var;
311 }
312 }
312
313
313 std::shared_ptr<Variable> VariableController2::cloneVariable(const std::shared_ptr<Variable> &variable)
314 std::shared_ptr<Variable> VariableController2::cloneVariable(const std::shared_ptr<Variable> &variable)
314 {
315 {
315 return impl->cloneVariable(variable);
316 return impl->cloneVariable(variable);
316 }
317 }
317
318
318 void VariableController2::deleteVariable(const std::shared_ptr<Variable>& variable)
319 void VariableController2::deleteVariable(const std::shared_ptr<Variable>& variable)
319 {
320 {
320 impl->deleteVariable(variable);
321 impl->deleteVariable(variable);
321 emit variableDeleted(variable);
322 emit variableDeleted(variable);
322 }
323 }
323
324
324 void VariableController2::changeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r)
325 void VariableController2::changeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r)
325 {
326 {
326 impl->changeRange(variable, r);
327 impl->changeRange(variable, r);
327 }
328 }
328
329
329 void VariableController2::asyncChangeRange(const std::shared_ptr<Variable> &variable, const DateTimeRange &r)
330 void VariableController2::asyncChangeRange(const std::shared_ptr<Variable> &variable, const DateTimeRange &r)
330 {
331 {
331 impl->asyncChangeRange(variable, r);
332 impl->asyncChangeRange(variable, r);
332 }
333 }
333
334
334 const std::set<std::shared_ptr<Variable> > VariableController2::variables()
335 const std::vector<std::shared_ptr<Variable> > VariableController2::variables()
335 {
336 {
336 return impl->variables();
337 return impl->variables();
337 }
338 }
338
339
339 bool VariableController2::isReady(const std::shared_ptr<Variable> &variable)
340 bool VariableController2::isReady(const std::shared_ptr<Variable> &variable)
340 {
341 {
341 return impl->hasPendingTransactions(variable);
342 return impl->hasPendingTransactions(variable);
342 }
343 }
343
344
344 void VariableController2::synchronize(const std::shared_ptr<Variable> &var, const std::shared_ptr<Variable> &with)
345 void VariableController2::synchronize(const std::shared_ptr<Variable> &var, const std::shared_ptr<Variable> &with)
345 {
346 {
346 impl->synchronize(var, with);
347 impl->synchronize(var, with);
347 }
348 }
349
350 QByteArray VariableController2::mimeData(const std::vector<std::shared_ptr<Variable> > &variables) const
351 {
352 auto encodedData = QByteArray{};
353 QDataStream stream{&encodedData, QIODevice::WriteOnly};
354 for (auto &var : variables) {
355 stream << var->ID().toByteArray();
356 }
357 return encodedData;
358 }
General Comments 0
You need to be logged in to leave comments. Login now