##// END OF EJS Templates
Fixed tests due to async var creation, plus minor stuff...
jeandet -
r30:02d2d8643fcb
parent child
Show More
@@ -1,18 +1,18
1 #ifndef SCIQLOP_DATAPROVIDERPARAMETERS_H
1 #ifndef SCIQLOP_DATAPROVIDERPARAMETERS_H
2 #define SCIQLOP_DATAPROVIDERPARAMETERS_H
2 #define SCIQLOP_DATAPROVIDERPARAMETERS_H
3
3
4 #include "DateTimeRange.h"
4 #include "DateTimeRange.h"
5
5
6 /**
6 /**
7 * @brief The DataProviderParameters struct holds the information needed to retrieve data from a
7 * @brief The DataProviderParameters struct holds the information needed to retrieve data from a
8 * data provider
8 * data provider
9 * @sa IDataProvider
9 * @sa IDataProvider
10 */
10 */
11 struct DataProviderParameters {
11 struct DataProviderParameters {
12 /// Times for which retrieve data
12 /// Times for which retrieve data
13 QVector<DateTimeRange> m_Times;
13 DateTimeRange m_Range;
14 /// Extra data that can be used by the provider to retrieve data
14 /// Extra data that can be used by the provider to retrieve data
15 QVariantHash m_Data;
15 QVariantHash m_Data;
16 };
16 };
17
17
18 #endif // SCIQLOP_DATAPROVIDERPARAMETERS_H
18 #endif // SCIQLOP_DATAPROVIDERPARAMETERS_H
@@ -1,52 +1,51
1 #ifndef VARIABLECONTROLLER2_H
1 #ifndef VARIABLECONTROLLER2_H
2 #define VARIABLECONTROLLER2_H
2 #define VARIABLECONTROLLER2_H
3 #include <memory>
3 #include <memory>
4 #include <vector>
4 #include <vector>
5 #include <set>
5 #include <set>
6 #include <QHash>
6 #include <QHash>
7 #include <QObject>
7 #include <QObject>
8 #include <QMutexLocker>
8 #include <QMutexLocker>
9 #include <QUuid>
9 #include <QUuid>
10 #include <QByteArray>
10 #include <QByteArray>
11 #include <QItemSelectionModel>
11 #include <QItemSelectionModel>
12 #include <Common/spimpl.h>
12 #include <Common/spimpl.h>
13 #include <Variable/Variable.h>
13 #include <Variable/Variable.h>
14 #include <Data/IDataProvider.h>
14 #include <Data/IDataProvider.h>
15 #include "Data/DateTimeRange.h"
15 #include "Data/DateTimeRange.h"
16
16
17 class VariableController2: public QObject
17 class VariableController2: public QObject
18 {
18 {
19 class VariableController2Private;
19 class VariableController2Private;
20 Q_OBJECT
20 Q_OBJECT
21
21
22 spimpl::unique_impl_ptr<VariableController2Private> impl;
22 spimpl::unique_impl_ptr<VariableController2Private> impl;
23
23
24 public:
24 public:
25 explicit VariableController2();
25 explicit VariableController2();
26 std::shared_ptr<Variable> createVariable(const QString &name, const QVariantHash &metadata,
26 std::shared_ptr<Variable> createVariable(const QString &name, const QVariantHash &metadata,
27 const std::shared_ptr<IDataProvider>& provider,
27 const std::shared_ptr<IDataProvider>& provider,
28 const DateTimeRange &range);
28 const DateTimeRange &range);
29
29
30 std::shared_ptr<Variable> cloneVariable(const std::shared_ptr<Variable>& variable);
30 std::shared_ptr<Variable> cloneVariable(const std::shared_ptr<Variable>& variable);
31 void deleteVariable(const std::shared_ptr<Variable>& variable);
31 void deleteVariable(const std::shared_ptr<Variable>& variable);
32 void changeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r);
32 void changeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r);
33 void asyncChangeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r);
33 void asyncChangeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r);
34 const std::vector<std::shared_ptr<Variable>> variables();
34 const std::vector<std::shared_ptr<Variable>> variables();
35
35
36 bool isReady(const std::shared_ptr<Variable>& variable);
36 bool isReady(const std::shared_ptr<Variable>& variable);
37 bool isReady();
38
37
39
38 void synchronize(const std::shared_ptr<Variable>& var, const std::shared_ptr<Variable>& with);
40 void synchronize(const std::shared_ptr<Variable>& var, const std::shared_ptr<Variable>& with);
39
41
40 const std::vector<std::shared_ptr<Variable>> variables(const std::vector<QUuid>& ids);
42 const std::vector<std::shared_ptr<Variable>> variables(const std::vector<QUuid>& ids);
41
43
42 const std::shared_ptr<Variable>& operator[] (int index) const;
43 std::shared_ptr<Variable> operator[] (int index);
44
45
44
46 signals:
45 signals:
47 void variableAdded(const std::shared_ptr<Variable>&);
46 void variableAdded(const std::shared_ptr<Variable>&);
48 void variableDeleted(const std::shared_ptr<Variable>&);
47 void variableDeleted(const std::shared_ptr<Variable>&);
49
48
50 };
49 };
51
50
52 #endif //VARIABLECONTROLLER2_H
51 #endif //VARIABLECONTROLLER2_H
@@ -1,66 +1,68
1 #ifndef SCIQLOP_VARIABLEMODEL2_H
1 #ifndef SCIQLOP_VARIABLEMODEL2_H
2 #define SCIQLOP_VARIABLEMODEL2_H
2 #define SCIQLOP_VARIABLEMODEL2_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Data/DateTimeRange.h>
6 #include <Data/DateTimeRange.h>
7
7
8 #include <QAbstractTableModel>
8 #include <QAbstractTableModel>
9 #include <QLoggingCategory>
9 #include <QLoggingCategory>
10
10
11 #include <Common/MetaTypes.h>
11 #include <Common/MetaTypes.h>
12 #include <Common/spimpl.h>
12 #include <Common/spimpl.h>
13
13
14
14
15
15
16 class IDataSeries;
16 class IDataSeries;
17 class Variable;
17 class Variable;
18 class VariableController2;
18 class VariableController2;
19
19
20 enum VariableRoles { ProgressRole = Qt::UserRole };
20 enum VariableRoles { ProgressRole = Qt::UserRole };
21
21
22 /**
22 /**
23 * @brief The VariableModel class aims to hold the variables that have been created in SciQlop
23 * @brief The VariableModel class aims to hold the variables that have been created in SciQlop
24 */
24 */
25 class SCIQLOP_CORE_EXPORT VariableModel2 : public QAbstractTableModel {
25 class SCIQLOP_CORE_EXPORT VariableModel2 : public QAbstractTableModel {
26 Q_OBJECT
26 Q_OBJECT
27 // read only mirror of VariableController2 content
27 // read only mirror of VariableController2 content
28 std::vector<std::shared_ptr<Variable>> _variables;
28 std::vector<std::shared_ptr<Variable>> _variables;
29 public:
29 public:
30 explicit VariableModel2(QObject *parent = nullptr);
30 explicit VariableModel2(QObject *parent = nullptr);
31
31
32 // /////////////////////////// //
32 // /////////////////////////// //
33 // QAbstractTableModel methods //
33 // QAbstractTableModel methods //
34 // /////////////////////////// //
34 // /////////////////////////// //
35
35
36 virtual int columnCount(const QModelIndex &parent = QModelIndex{}) const override;
36 virtual int columnCount(const QModelIndex &parent = QModelIndex{}) const override;
37 virtual int rowCount(const QModelIndex &parent = QModelIndex{}) const override;
37 virtual int rowCount(const QModelIndex &parent = QModelIndex{}) const override;
38 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
38 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
39 virtual QVariant headerData(int section, Qt::Orientation orientation,
39 virtual QVariant headerData(int section, Qt::Orientation orientation,
40 int role = Qt::DisplayRole) const override;
40 int role = Qt::DisplayRole) const override;
41 virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
41 virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
42
42
43 // ///////////////// //
43 // ///////////////// //
44 // Drag&Drop methods //
44 // Drag&Drop methods //
45 // ///////////////// //
45 // ///////////////// //
46
46
47 virtual Qt::DropActions supportedDropActions() const override;
47 virtual Qt::DropActions supportedDropActions() const override;
48 virtual Qt::DropActions supportedDragActions() const override;
48 virtual Qt::DropActions supportedDragActions() const override;
49 virtual QStringList mimeTypes() const override;
49 virtual QStringList mimeTypes() const override;
50 virtual QMimeData *mimeData(const QModelIndexList &indexes) const override;
50 virtual QMimeData *mimeData(const QModelIndexList &indexes) const override;
51 virtual bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
51 virtual bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
52 const QModelIndex &parent) const override;
52 const QModelIndex &parent) const override;
53 virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
53 virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
54 const QModelIndex &parent) override;
54 const QModelIndex &parent) override;
55 const std::vector<std::shared_ptr<Variable>>& variables() const
56 {return _variables;}
55
57
56 signals:
58 signals:
57 void createVariable(const QVariantHash &productData);
59 void createVariable(const QVariantHash &productData);
58 void asyncChangeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r);
60 void asyncChangeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r);
59 public slots:
61 public slots:
60 /// Slot called when data of a variable has been updated
62 /// Slot called when data of a variable has been updated
61 void variableUpdated() noexcept;
63 void variableUpdated() noexcept;
62 void variableAdded(const std::shared_ptr<Variable>&);
64 void variableAdded(const std::shared_ptr<Variable>&);
63 void variableDeleted(const std::shared_ptr<Variable>&);
65 void variableDeleted(const std::shared_ptr<Variable>&);
64 };
66 };
65
67
66 #endif // SCIQLOP_VARIABLEMODEL2_H
68 #endif // SCIQLOP_VARIABLEMODEL2_H
@@ -1,390 +1,396
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 #include <QDataStream>
6
6
7 #include "Variable/VariableController2.h"
7 #include "Variable/VariableController2.h"
8 #include "Variable/VariableSynchronizationGroup2.h"
8 #include "Variable/VariableSynchronizationGroup2.h"
9 #include <Common/containers.h>
9 #include <Common/containers.h>
10 #include <Common/debug.h>
10 #include <Common/debug.h>
11 #include <Data/DataProviderParameters.h>
11 #include <Data/DataProviderParameters.h>
12 #include <Data/DateTimeRangeHelper.h>
12 #include <Data/DateTimeRangeHelper.h>
13 #include <Data/DateTimeRange.h>
13 #include <Data/DateTimeRange.h>
14 #include <Variable/VariableCacheStrategyFactory.h>
14 #include <Variable/VariableCacheStrategyFactory.h>
15 #include <Variable/private/VCTransaction.h>
15 #include <Variable/private/VCTransaction.h>
16 #include <QCoreApplication>
16 #include <QCoreApplication>
17
17
18
18
19
19
20 class VariableController2::VariableController2Private
20 class VariableController2::VariableController2Private
21 {
21 {
22 struct threadSafeVaraiblesMaps
22 struct threadSafeVaraiblesMaps
23 {
23 {
24 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)
25 {
25 {
26 QWriteLocker lock{&_lock};
26 QWriteLocker lock{&_lock};
27 _variables[*variable] = variable;
27 _variables[*variable] = variable;
28 _providers[*variable] = provider;
28 _providers[*variable] = provider;
29 _synchronizationGroups[*variable] = synchronizationGroup;
29 _synchronizationGroups[*variable] = synchronizationGroup;
30 }
30 }
31
31
32 inline void removeVariable(const std::shared_ptr<Variable>& variable)
32 inline void removeVariable(const std::shared_ptr<Variable>& variable)
33 {
33 {
34 QWriteLocker lock{&_lock};
34 QWriteLocker lock{&_lock};
35 _variables.erase(*variable);
35 _variables.erase(*variable);
36 _providers.remove(*variable);
36 _providers.remove(*variable);
37 _synchronizationGroups.remove(*variable);
37 _synchronizationGroups.remove(*variable);
38 }
38 }
39
39
40 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)
41 {
41 {
42 QWriteLocker lock{&_lock};
42 QWriteLocker lock{&_lock};
43 if(with.has_value())
43 if(with.has_value())
44 {
44 {
45 auto newGroup = _synchronizationGroups[*with.value()];
45 auto newGroup = _synchronizationGroups[*with.value()];
46 newGroup->addVariable(*variable);
46 newGroup->addVariable(*variable);
47 _synchronizationGroups[*variable] = newGroup;
47 _synchronizationGroups[*variable] = newGroup;
48 }
48 }
49 else
49 else
50 {
50 {
51 _synchronizationGroups[*variable] = std::make_shared<VariableSynchronizationGroup2>(*variable);
51 _synchronizationGroups[*variable] = std::make_shared<VariableSynchronizationGroup2>(*variable);
52 }
52 }
53 }
53 }
54
54
55 inline std::shared_ptr<Variable> variable(QUuid variable)
55 inline std::shared_ptr<Variable> variable(QUuid variable)
56 {
56 {
57 QReadLocker lock{&_lock};
57 QReadLocker lock{&_lock};
58 auto it = _variables.find(variable);
58 auto it = _variables.find(variable);
59 [[unlikely]]
59 [[unlikely]]
60 if(it==_variables.end())
60 if(it==_variables.end())
61 SCIQLOP_ERROR(threadSafeVaraiblesMaps,"Unknown Variable");
61 SCIQLOP_ERROR(threadSafeVaraiblesMaps,"Unknown Variable");
62 return (*it).second;
62 return (*it).second;
63 }
63 }
64
64
65 inline std::shared_ptr<Variable> variable(int index)
65 inline std::shared_ptr<Variable> variable(int index)
66 {
66 {
67 QReadLocker lock{&_lock};
67 QReadLocker lock{&_lock};
68 [[unlikely]]
68 [[unlikely]]
69 if(!_variables.size() > index)
69 if(!_variables.size() > index)
70 SCIQLOP_ERROR(threadSafeVaraiblesMaps,"Index is out of bounds");
70 SCIQLOP_ERROR(threadSafeVaraiblesMaps,"Index is out of bounds");
71 auto it = _variables.cbegin();
71 auto it = _variables.cbegin();
72 while (index!=0) {
72 while (index!=0) {
73 index-=1;
73 index-=1;
74 it++;
74 it++;
75 }
75 }
76 return (*it).second;
76 return (*it).second;
77 }
77 }
78
78
79 inline const std::vector<std::shared_ptr<Variable>> variables()
79 inline const std::vector<std::shared_ptr<Variable>> variables()
80 {
80 {
81 std::vector<std::shared_ptr<Variable>> vars;
81 std::vector<std::shared_ptr<Variable>> vars;
82 QReadLocker lock{&_lock};
82 QReadLocker lock{&_lock};
83 for(const auto&[id, var]:_variables)
83 for(const auto&[id, var]:_variables)
84 {
84 {
85 vars.push_back(var);
85 vars.push_back(var);
86 }
86 }
87 return vars;
87 return vars;
88 }
88 }
89
89
90 inline std::shared_ptr<IDataProvider> provider(QUuid variable)
90 inline std::shared_ptr<IDataProvider> provider(QUuid variable)
91 {
91 {
92 QReadLocker lock{&_lock};
92 QReadLocker lock{&_lock};
93 [[unlikely]]
93 [[unlikely]]
94 if(!_providers.contains(variable))
94 if(!_providers.contains(variable))
95 SCIQLOP_ERROR(threadSafeVaraiblesMaps,"Unknown Variable");
95 SCIQLOP_ERROR(threadSafeVaraiblesMaps,"Unknown Variable");
96 return _providers[variable];
96 return _providers[variable];
97 }
97 }
98
98
99 inline std::shared_ptr<VariableSynchronizationGroup2> group(QUuid variable)
99 inline std::shared_ptr<VariableSynchronizationGroup2> group(QUuid variable)
100 {
100 {
101 QReadLocker lock{&_lock};
101 QReadLocker lock{&_lock};
102 [[unlikely]]
102 [[unlikely]]
103 if(!_synchronizationGroups.contains(variable))
103 if(!_synchronizationGroups.contains(variable))
104 SCIQLOP_ERROR(threadSafeVaraiblesMaps,"Unknown Variable");
104 SCIQLOP_ERROR(threadSafeVaraiblesMaps,"Unknown Variable");
105 return _synchronizationGroups[variable];
105 return _synchronizationGroups[variable];
106 }
106 }
107
107
108 inline bool has(const std::shared_ptr<Variable>& variable)
108 inline bool has(const std::shared_ptr<Variable>& variable)
109 {
109 {
110 QReadLocker lock{&_lock};
110 QReadLocker lock{&_lock};
111 return _variables.find(*variable)==_variables.end();
111 return _variables.find(*variable)==_variables.end();
112 }
112 }
113
113
114 private:
114 private:
115 std::map<QUuid,std::shared_ptr<Variable>> _variables;
115 std::map<QUuid,std::shared_ptr<Variable>> _variables;
116 QMap<QUuid,std::shared_ptr<IDataProvider>> _providers;
116 QMap<QUuid,std::shared_ptr<IDataProvider>> _providers;
117 QMap<QUuid,std::shared_ptr<VariableSynchronizationGroup2>> _synchronizationGroups;
117 QMap<QUuid,std::shared_ptr<VariableSynchronizationGroup2>> _synchronizationGroups;
118 QReadWriteLock _lock{QReadWriteLock::Recursive};
118 QReadWriteLock _lock{QReadWriteLock::Recursive};
119 }_maps;
119 }_maps;
120 QThreadPool* _ThreadPool;
120 QThreadPool* _ThreadPool;
121 VCTransactionsQueues _transactions;
121 VCTransactionsQueues _transactions;
122 std::unique_ptr<VariableCacheStrategy> _cacheStrategy;
122 std::unique_ptr<VariableCacheStrategy> _cacheStrategy;
123
123
124 void _transactionComplete(QUuid group, std::shared_ptr<VCTransaction> transaction)
124 void _transactionComplete(QUuid group, std::shared_ptr<VCTransaction> transaction)
125 {
125 {
126 if(transaction->done())
126 if(transaction->done())
127 {
127 {
128 _transactions.complete(group);
128 _transactions.complete(group);
129 }
129 }
130 this->_processTransactions();
130 this->_processTransactions();
131 }
131 }
132 void _processTransactions()
132 void _processTransactions()
133 {
133 {
134 auto nextTransactions = _transactions.nextTransactions();
134 auto nextTransactions = _transactions.nextTransactions();
135 auto pendingTransactions = _transactions.pendingTransactions();
135 auto pendingTransactions = _transactions.pendingTransactions();
136 for( auto [groupID, newTransaction] : nextTransactions)
136 for( auto [groupID, newTransaction] : nextTransactions)
137 {
137 {
138 if(newTransaction.has_value() && !pendingTransactions[groupID].has_value())
138 if(newTransaction.has_value() && !pendingTransactions[groupID].has_value())
139 {
139 {
140 _transactions.start(groupID);
140 _transactions.start(groupID);
141 auto refVar = _maps.variable(newTransaction.value()->refVar);
141 auto refVar = _maps.variable(newTransaction.value()->refVar);
142 auto ranges = _computeAllRangesInGroup(refVar,newTransaction.value()->range);
142 auto ranges = _computeAllRangesInGroup(refVar,newTransaction.value()->range);
143 for( auto const& [ID, range] : ranges)
143 for( auto const& [ID, range] : ranges)
144 {
144 {
145 auto provider = _maps.provider(ID);
145 auto provider = _maps.provider(ID);
146 auto variable = _maps.variable(ID);
146 auto variable = _maps.variable(ID);
147 auto [missingRanges, newCacheRange] = _computeMissingRanges(variable,range);
147 auto [missingRanges, newCacheRange] = _computeMissingRanges(variable,range);
148 auto exe = new TransactionExe(variable, provider, missingRanges, range, newCacheRange);
148 auto exe = new TransactionExe(variable, provider, missingRanges, range, newCacheRange);
149 QObject::connect(exe,
149 QObject::connect(exe,
150 &TransactionExe::transactionComplete,
150 &TransactionExe::transactionComplete,
151 [groupID=groupID,transaction=newTransaction.value(),this]()
151 [groupID=groupID,transaction=newTransaction.value(),this]()
152 {
152 {
153 this->_transactionComplete(groupID, transaction);
153 this->_transactionComplete(groupID, transaction);
154 }
154 }
155 );
155 );
156 _ThreadPool->start(exe);
156 _ThreadPool->start(exe);
157 }
157 }
158 }
158 }
159 }
159 }
160 }
160 }
161
161
162 std::map<QUuid,DateTimeRange> _computeAllRangesInGroup(const std::shared_ptr<Variable>& refVar, DateTimeRange r)
162 std::map<QUuid,DateTimeRange> _computeAllRangesInGroup(const std::shared_ptr<Variable>& refVar, DateTimeRange r)
163 {
163 {
164 std::map<QUuid,DateTimeRange> ranges;
164 std::map<QUuid,DateTimeRange> ranges;
165 if(!DateTimeRangeHelper::hasnan(r))
165 if(!DateTimeRangeHelper::hasnan(r))
166 {
166 {
167 auto group = _maps.group(*refVar);
167 auto group = _maps.group(*refVar);
168 if(auto transformation = DateTimeRangeHelper::computeTransformation(refVar->range(),r);
168 if(auto transformation = DateTimeRangeHelper::computeTransformation(refVar->range(),r);
169 transformation.has_value())
169 transformation.has_value())
170 {
170 {
171 for(auto varId:group->variables())
171 for(auto varId:group->variables())
172 {
172 {
173 auto var = _maps.variable(varId);
173 auto var = _maps.variable(varId);
174 auto newRange = var->range().transform(transformation.value());
174 auto newRange = var->range().transform(transformation.value());
175 ranges[varId] = newRange;
175 ranges[varId] = newRange;
176 }
176 }
177 }
177 }
178 else // force new range to all variables -> may be weird if more than one var in the group
178 else // force new range to all variables -> may be weird if more than one var in the group
179 // @TODO ensure that there is no side effects
179 // @TODO ensure that there is no side effects
180 {
180 {
181 for(auto varId:group->variables())
181 for(auto varId:group->variables())
182 {
182 {
183 auto var = _maps.variable(varId);
183 auto var = _maps.variable(varId);
184 ranges[varId] = r;
184 ranges[varId] = r;
185 }
185 }
186 }
186 }
187 }
187 }
188 else
188 else
189 {
189 {
190 SCIQLOP_ERROR(VariableController2Private, "Invalid range containing NaN");
190 SCIQLOP_ERROR(VariableController2Private, "Invalid range containing NaN");
191 }
191 }
192 return ranges;
192 return ranges;
193 }
193 }
194
194
195 std::pair<std::vector<DateTimeRange>,DateTimeRange> _computeMissingRanges(const std::shared_ptr<Variable>& var, DateTimeRange r)
195 std::pair<std::vector<DateTimeRange>,DateTimeRange> _computeMissingRanges(const std::shared_ptr<Variable>& var, DateTimeRange r)
196 {
196 {
197 DateTimeRange newCacheRange;
197 DateTimeRange newCacheRange;
198 std::vector<DateTimeRange> missingRanges;
198 std::vector<DateTimeRange> missingRanges;
199 if(DateTimeRangeHelper::hasnan(var->cacheRange()))
199 if(DateTimeRangeHelper::hasnan(var->cacheRange()))
200 {
200 {
201 newCacheRange = _cacheStrategy->computeRange(r,r);
201 newCacheRange = _cacheStrategy->computeRange(r,r);
202 missingRanges = {newCacheRange};
202 missingRanges = {newCacheRange};
203 }
203 }
204 else
204 else
205 {
205 {
206 newCacheRange = _cacheStrategy->computeRange(var->cacheRange(),r);
206 newCacheRange = _cacheStrategy->computeRange(var->cacheRange(),r);
207 missingRanges = newCacheRange - var->cacheRange();
207 missingRanges = newCacheRange - var->cacheRange();
208 }
208 }
209 return {missingRanges,newCacheRange};
209 return {missingRanges,newCacheRange};
210 }
210 }
211
211
212 void _changeRange(QUuid id, DateTimeRange r)
212 void _changeRange(QUuid id, DateTimeRange r)
213 {
213 {
214 _changeRange(_maps.variable(id) ,r);
214 _changeRange(_maps.variable(id) ,r);
215 }
215 }
216 void _changeRange(const std::shared_ptr<Variable>& var, DateTimeRange r)
216 void _changeRange(const std::shared_ptr<Variable>& var, DateTimeRange r)
217 {
217 {
218 auto provider = _maps.provider(*var);
218 auto provider = _maps.provider(*var);
219 auto [missingRanges, newCacheRange] = _computeMissingRanges(var,r);
219 auto [missingRanges, newCacheRange] = _computeMissingRanges(var,r);
220 std::vector<IDataSeries*> data;
220 std::vector<IDataSeries*> data;
221 for(auto range:missingRanges)
221 for(auto range:missingRanges)
222 {
222 {
223 data.push_back(provider->getData(DataProviderParameters{{range}, var->metadata()}));
223 data.push_back(provider->getData(DataProviderParameters{{range}, var->metadata()}));
224 }
224 }
225 var->updateData(data, r, newCacheRange, true);
225 var->updateData(data, r, newCacheRange, true);
226 }
226 }
227 public:
227 public:
228 VariableController2Private(QObject* parent=Q_NULLPTR)
228 VariableController2Private(QObject* parent=Q_NULLPTR)
229 :_cacheStrategy(VariableCacheStrategyFactory::createCacheStrategy(CacheStrategy::SingleThreshold))
229 :_cacheStrategy(VariableCacheStrategyFactory::createCacheStrategy(CacheStrategy::SingleThreshold))
230 {
230 {
231 Q_UNUSED(parent);
231 Q_UNUSED(parent);
232 this->_ThreadPool = new QThreadPool();
232 this->_ThreadPool = new QThreadPool();
233 this->_ThreadPool->setMaxThreadCount(32);
233 this->_ThreadPool->setMaxThreadCount(32);
234 }
234 }
235
235
236 /*
236 /*
237 * This dtor has to like this even if this is ugly, because default dtor would rely on
237 * This dtor has to like this even if this is ugly, because default dtor would rely on
238 * declaration order to destruct members and that would always lead to regressions when
238 * declaration order to destruct members and that would always lead to regressions when
239 * modifying class members
239 * modifying class members
240 */
240 */
241 ~VariableController2Private()
241 ~VariableController2Private()
242 {
242 {
243 delete this->_ThreadPool;
243 delete this->_ThreadPool;
244 }
244 }
245
245
246 std::shared_ptr<Variable> createVariable(const QString &name, const QVariantHash &metadata, std::shared_ptr<IDataProvider> provider)
246 std::shared_ptr<Variable> createVariable(const QString &name, const QVariantHash &metadata, std::shared_ptr<IDataProvider> provider)
247 {
247 {
248 auto newVar = std::make_shared<Variable>(name,metadata);
248 auto newVar = std::make_shared<Variable>(name,metadata);
249 auto group = std::make_shared<VariableSynchronizationGroup2>(newVar->ID());
249 auto group = std::make_shared<VariableSynchronizationGroup2>(newVar->ID());
250 _maps.addVariable(newVar,std::move(provider),group);
250 _maps.addVariable(newVar,std::move(provider),group);
251 this->_transactions.addEntry(*group);
251 this->_transactions.addEntry(*group);
252 return newVar;
252 return newVar;
253 }
253 }
254
254
255 std::shared_ptr<Variable> variable(QUuid ID)
255 std::shared_ptr<Variable> variable(QUuid ID)
256 {
256 {
257 return _maps.variable(ID);
257 return _maps.variable(ID);
258 }
258 }
259
259
260 std::shared_ptr<Variable> variable(int index)
260 std::shared_ptr<Variable> variable(int index)
261 {
261 {
262 return _maps.variable(index);
262 return _maps.variable(index);
263 }
263 }
264
264
265 std::shared_ptr<Variable> cloneVariable(const std::shared_ptr<Variable>& variable)
265 std::shared_ptr<Variable> cloneVariable(const std::shared_ptr<Variable>& variable)
266 {
266 {
267 auto newVar = variable->clone();
267 auto newVar = variable->clone();
268 _maps.synchronize(newVar,std::nullopt);
268 _maps.synchronize(newVar,std::nullopt);
269 _maps.addVariable(newVar,_maps.provider(*variable),_maps.group(*newVar));
269 _maps.addVariable(newVar,_maps.provider(*variable),_maps.group(*newVar));
270 this->_transactions.addEntry(*_maps.group(*newVar));
270 this->_transactions.addEntry(*_maps.group(*newVar));
271 return newVar;
271 return newVar;
272 }
272 }
273
273
274 bool hasPendingTransactions(const std::shared_ptr<Variable>& variable)
274 bool hasPendingTransactions(const std::shared_ptr<Variable>& variable)
275 {
275 {
276 return _transactions.active(*_maps.group(*variable));
276 return _transactions.active(*_maps.group(*variable));
277 }
277 }
278
278
279 bool hasPendingTransactions()
280 {
281 bool has = false;
282 for(const auto& var:_maps.variables())
283 {
284 has |= _transactions.active(*_maps.group(*var));
285 }
286 return has;
287 }
288
279 void deleteVariable(const std::shared_ptr<Variable>& variable)
289 void deleteVariable(const std::shared_ptr<Variable>& variable)
280 {
290 {
281 _maps.removeVariable(variable);
291 _maps.removeVariable(variable);
282 }
292 }
283
293
284 void asyncChangeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r)
294 void asyncChangeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r)
285 {
295 {
286 if(!DateTimeRangeHelper::hasnan(r))
296 if(!DateTimeRangeHelper::hasnan(r))
287 {
297 {
288 auto group = _maps.group(*variable);
298 auto group = _maps.group(*variable);
289 // Just overwrite next transaction
299 // Just overwrite next transaction
290 {
300 {
291 _transactions.enqueue(*group,std::make_shared<VCTransaction>(variable->ID(), r, static_cast<int>(group->variables().size())));
301 _transactions.enqueue(*group,std::make_shared<VCTransaction>(variable->ID(), r, static_cast<int>(group->variables().size())));
292 }
302 }
293 _processTransactions();
303 _processTransactions();
294 }
304 }
295 else
305 else
296 {
306 {
297 SCIQLOP_ERROR(VariableController2Private, "Invalid range containing NaN");
307 SCIQLOP_ERROR(VariableController2Private, "Invalid range containing NaN");
298 }
308 }
299 }
309 }
300
310
301 void changeRange(const std::shared_ptr<Variable>& variable, DateTimeRange r)
311 void changeRange(const std::shared_ptr<Variable>& variable, DateTimeRange r)
302 {
312 {
303 asyncChangeRange(variable,r);
313 asyncChangeRange(variable,r);
304 while (hasPendingTransactions(variable))
314 while (hasPendingTransactions(variable))
305 {
315 {
306 QCoreApplication::processEvents();
316 QCoreApplication::processEvents();
307 }
317 }
308 }
318 }
309
319
310 inline void synchronize(const std::shared_ptr<Variable>& var, const std::shared_ptr<Variable>& with)
320 inline void synchronize(const std::shared_ptr<Variable>& var, const std::shared_ptr<Variable>& with)
311 {
321 {
312 _maps.synchronize(var, with);
322 _maps.synchronize(var, with);
313 }
323 }
314
324
315 inline const std::vector<std::shared_ptr<Variable>> variables()
325 inline const std::vector<std::shared_ptr<Variable>> variables()
316 {
326 {
317 return _maps.variables();
327 return _maps.variables();
318 }
328 }
319
329
320 };
330 };
321
331
322 VariableController2::VariableController2()
332 VariableController2::VariableController2()
323 :impl{spimpl::make_unique_impl<VariableController2Private>()}
333 :impl{spimpl::make_unique_impl<VariableController2Private>()}
324 {}
334 {}
325
335
326 std::shared_ptr<Variable> VariableController2::createVariable(const QString &name, const QVariantHash &metadata, const std::shared_ptr<IDataProvider>& provider, const DateTimeRange &range)
336 std::shared_ptr<Variable> VariableController2::createVariable(const QString &name, const QVariantHash &metadata, const std::shared_ptr<IDataProvider>& provider, const DateTimeRange &range)
327 {
337 {
328 auto var = impl->createVariable(name, metadata, provider);
338 auto var = impl->createVariable(name, metadata, provider);
339 var->setRange(range); // even with no data this is it's range
329 emit variableAdded(var);
340 emit variableAdded(var);
330 if(!DateTimeRangeHelper::hasnan(range))
341 if(!DateTimeRangeHelper::hasnan(range))
331 impl->asyncChangeRange(var,range);
342 impl->asyncChangeRange(var,range);
332 else
343 else
333 SCIQLOP_ERROR(VariableController2, "Creating a variable with default constructed DateTimeRange is an error");
344 SCIQLOP_ERROR(VariableController2, "Creating a variable with default constructed DateTimeRange is an error");
334 return var;
345 return var;
335 }
346 }
336
347
337 std::shared_ptr<Variable> VariableController2::cloneVariable(const std::shared_ptr<Variable> &variable)
348 std::shared_ptr<Variable> VariableController2::cloneVariable(const std::shared_ptr<Variable> &variable)
338 {
349 {
339 return impl->cloneVariable(variable);
350 return impl->cloneVariable(variable);
340 }
351 }
341
352
342 void VariableController2::deleteVariable(const std::shared_ptr<Variable>& variable)
353 void VariableController2::deleteVariable(const std::shared_ptr<Variable>& variable)
343 {
354 {
344 impl->deleteVariable(variable);
355 impl->deleteVariable(variable);
345 emit variableDeleted(variable);
356 emit variableDeleted(variable);
346 }
357 }
347
358
348 void VariableController2::changeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r)
359 void VariableController2::changeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r)
349 {
360 {
350 impl->changeRange(variable, r);
361 impl->changeRange(variable, r);
351 }
362 }
352
363
353 void VariableController2::asyncChangeRange(const std::shared_ptr<Variable> &variable, const DateTimeRange &r)
364 void VariableController2::asyncChangeRange(const std::shared_ptr<Variable> &variable, const DateTimeRange &r)
354 {
365 {
355 impl->asyncChangeRange(variable, r);
366 impl->asyncChangeRange(variable, r);
356 }
367 }
357
368
358 const std::vector<std::shared_ptr<Variable> > VariableController2::variables()
369 const std::vector<std::shared_ptr<Variable> > VariableController2::variables()
359 {
370 {
360 return impl->variables();
371 return impl->variables();
361 }
372 }
362
373
363 bool VariableController2::isReady(const std::shared_ptr<Variable> &variable)
374 bool VariableController2::isReady(const std::shared_ptr<Variable> &variable)
364 {
375 {
365 return impl->hasPendingTransactions(variable);
376 return !impl->hasPendingTransactions(variable);
377 }
378
379 bool VariableController2::isReady()
380 {
381 return !impl->hasPendingTransactions();
366 }
382 }
367
383
368 void VariableController2::synchronize(const std::shared_ptr<Variable> &var, const std::shared_ptr<Variable> &with)
384 void VariableController2::synchronize(const std::shared_ptr<Variable> &var, const std::shared_ptr<Variable> &with)
369 {
385 {
370 impl->synchronize(var, with);
386 impl->synchronize(var, with);
371 }
387 }
372
388
373 const std::vector<std::shared_ptr<Variable>> VariableController2::variables(const std::vector<QUuid> &ids)
389 const std::vector<std::shared_ptr<Variable>> VariableController2::variables(const std::vector<QUuid> &ids)
374 {
390 {
375 std::vector<std::shared_ptr<Variable>> variables;
391 std::vector<std::shared_ptr<Variable>> variables;
376 for (const auto& id : ids) {
392 for (const auto& id : ids) {
377 variables.push_back(impl->variable(id));
393 variables.push_back(impl->variable(id));
378 }
394 }
379 return variables;
395 return variables;
380 }
396 }
381
382 const std::shared_ptr<Variable> &VariableController2::operator[](int index) const
383 {
384 return impl->variable (index);
385 }
386
387 std::shared_ptr<Variable> VariableController2::operator[](int index)
388 {
389 return impl->variable (index);
390 }
@@ -1,83 +1,83
1 #ifndef TESTPROVIDER_H
1 #ifndef TESTPROVIDER_H
2 #define TESTPROVIDER_H
2 #define TESTPROVIDER_H
3
3
4 #include <memory>
4 #include <memory>
5 #include <cmath>
5 #include <cmath>
6 #include <algorithm>
6 #include <algorithm>
7 #include <numeric>
7 #include <numeric>
8
8
9 #include <QUuid>
9 #include <QUuid>
10 #include <QtGlobal>
10 #include <QtGlobal>
11 #include <QtTest>
11 #include <QtTest>
12
12
13 #include <Data/IDataProvider.h>
13 #include <Data/IDataProvider.h>
14 #include <Data/DataProviderParameters.h>
14 #include <Data/DataProviderParameters.h>
15 #include <Data/DataSeries.h>
15 #include <Data/DataSeries.h>
16 #include <Data/ScalarSeries.h>
16 #include <Data/ScalarSeries.h>
17 #include <Variable/Variable.h>
17 #include <Variable/Variable.h>
18
18
19
19
20 template<int slope>
20 template<int slope>
21 class SimpleRange: public IDataProvider
21 class SimpleRange: public IDataProvider
22 {
22 {
23 public:
23 public:
24 SimpleRange() = default;
24 SimpleRange() = default;
25
25
26 int callCounter = 0;
26 int callCounter = 0;
27 std::shared_ptr<IDataProvider> clone() const override{ return std::make_shared<SimpleRange>(); }
27 std::shared_ptr<IDataProvider> clone() const override{ return std::make_shared<SimpleRange>(); }
28
28
29 IDataSeries* getData(const DataProviderParameters &parameters) override
29 IDataSeries* getData(const DataProviderParameters &parameters) override
30 {
30 {
31 callCounter+=1;
31 callCounter+=1;
32 auto tstart = parameters.m_Times[0].m_TStart;
32 auto tstart = parameters.m_Range.m_TStart;
33 auto tend = parameters.m_Times[0].m_TEnd;
33 auto tend = parameters.m_Range.m_TEnd;
34 std::vector<double> x;
34 std::vector<double> x;
35 std::vector<double> y;
35 std::vector<double> y;
36 for(double i = ceil(tstart);i<=floor(tend);i+=1.) //1 seconde data resolution
36 for(double i = ceil(tstart);i<=floor(tend);i+=1.) //1 seconde data resolution
37 {
37 {
38 x.push_back(i);
38 x.push_back(i);
39 y.push_back(i*slope);
39 y.push_back(i*slope);
40 }
40 }
41 auto serie = new ScalarSeries(std::move(x),std::move(y),Unit("Secondes",true),Unit("Volts",false));
41 auto serie = new ScalarSeries(std::move(x),std::move(y),Unit("Secondes",true),Unit("Volts",false));
42 return serie;
42 return serie;
43 }
43 }
44
44
45 };
45 };
46
46
47
47
48 template <class T>
48 template <class T>
49 auto sumdiff(T begin, T end)
49 auto sumdiff(T begin, T end)
50 {
50 {
51 std::vector<double> diff_vect(end-begin-1);
51 std::vector<double> diff_vect(end-begin-1);
52 auto diff = [](auto next,auto item)
52 auto diff = [](auto next,auto item)
53 {
53 {
54 return next.value() - item.value();
54 return next.value() - item.value();
55 };
55 };
56 std::transform (begin+1, end, begin, diff_vect.begin(),diff);
56 std::transform (begin+1, end, begin, diff_vect.begin(),diff);
57 return std::accumulate(diff_vect.cbegin(), diff_vect.cend(), 0);
57 return std::accumulate(diff_vect.cbegin(), diff_vect.cend(), 0);
58 }
58 }
59
59
60 template <int slope=1>
60 template <int slope=1>
61 struct RangeType
61 struct RangeType
62 {
62 {
63 static void check_properties(std::shared_ptr<Variable> v, DateTimeRange r)
63 static void check_properties(std::shared_ptr<Variable> v, DateTimeRange r)
64 {
64 {
65 auto bounds = v->dataSeries()->valuesBounds(r.m_TStart, r.m_TEnd);
65 auto bounds = v->dataSeries()->valuesBounds(r.m_TStart, r.m_TEnd);
66 auto s = sumdiff(bounds.first, bounds.second) / slope;
66 auto s = sumdiff(bounds.first, bounds.second) / slope;
67 auto nbpoints = bounds.second - bounds.first+1.;
67 auto nbpoints = bounds.second - bounds.first+1.;
68 QCOMPARE(nbpoints, int(s)+2);//<- @TODO weird has to be investigated why +2?
68 QCOMPARE(nbpoints, int(s)+2);//<- @TODO weird has to be investigated why +2?
69 QCOMPARE(bounds.first->x(), bounds.first->value()/slope);
69 QCOMPARE(bounds.first->x(), bounds.first->value()/slope);
70 }
70 }
71 };
71 };
72
72
73 template <class T>
73 template <class T>
74 void check_variable_state(std::shared_ptr<Variable> v, DateTimeRange r)
74 void check_variable_state(std::shared_ptr<Variable> v, DateTimeRange r)
75 {
75 {
76 auto bounds = v->dataSeries()->valuesBounds(r.m_TStart, r.m_TEnd);
76 auto bounds = v->dataSeries()->valuesBounds(r.m_TStart, r.m_TEnd);
77 //generated data has to be inside range
77 //generated data has to be inside range
78 QVERIFY(bounds.first->x() >= r.m_TStart);
78 QVERIFY(bounds.first->x() >= r.m_TStart);
79 QVERIFY(bounds.second->x() <= r.m_TEnd);
79 QVERIFY(bounds.second->x() <= r.m_TEnd);
80 T::check_properties(v,r);
80 T::check_properties(v,r);
81 }
81 }
82
82
83 #endif
83 #endif
@@ -1,144 +1,146
1 #include <cmath>
1 #include <cmath>
2 #include <algorithm>
2 #include <algorithm>
3 #include <numeric>
3 #include <numeric>
4 #include <QtTest>
4 #include <QtTest>
5 #include <QObject>
5 #include <QObject>
6 #include <Variable/VariableController2.h>
6 #include <Variable/VariableController2.h>
7 #include <Data/DateTimeRange.h>
7 #include <Data/DateTimeRange.h>
8 #include <Data/IDataProvider.h>
8 #include <Data/IDataProvider.h>
9 #include <Data/ScalarSeries.h>
9 #include <Data/ScalarSeries.h>
10 #include <Data/DataProviderParameters.h>
10 #include <Data/DataProviderParameters.h>
11 #include <Common/containers.h>
11 #include <Common/containers.h>
12
12
13 #include <TestUtils/TestProviders.h>
13 #include <TestUtils/TestProviders.h>
14
14
15 #define TEST_VC2_FIXTURE(slope) \
15 #define TEST_VC2_FIXTURE(slope) \
16 VariableController2 vc; \
16 VariableController2 vc; \
17 auto provider = std::make_shared<SimpleRange<slope>>();\
17 auto provider = std::make_shared<SimpleRange<slope>>();\
18
18
19 #define TEST_VC2_CREATE_DEFAULT_VAR(name)\
19 #define TEST_VC2_CREATE_DEFAULT_VAR(name)\
20 auto range = DateTimeRange::fromDateTime(QDate(2018,8,7),QTime(14,00),\
20 auto range = DateTimeRange::fromDateTime(QDate(2018,8,7),QTime(14,00),\
21 QDate(2018,8,7),QTime(16,00));\
21 QDate(2018,8,7),QTime(16,00));\
22 auto name = vc.createVariable("name", {}, provider, range);\
22 auto name = vc.createVariable("name", {}, provider, range);\
23 while(!vc.isReady(name))QCoreApplication::processEvents();\
23
24
24 Q_DECLARE_METATYPE(DateTimeRangeTransformation);
25 Q_DECLARE_METATYPE(DateTimeRangeTransformation);
25
26
26
27
27 class TestVariableController2 : public QObject
28 class TestVariableController2 : public QObject
28 {
29 {
29 Q_OBJECT
30 Q_OBJECT
30 public:
31 public:
31 explicit TestVariableController2(QObject *parent = nullptr) : QObject(parent){}
32 explicit TestVariableController2(QObject *parent = nullptr) : QObject(parent){}
32 signals:
33 signals:
33
34
34 private slots:
35 private slots:
35 void initTestCase(){}
36 void initTestCase(){}
36 void cleanupTestCase(){}
37 void cleanupTestCase(){}
37
38
38 void testCreateVariable()
39 void testCreateVariable()
39 {
40 {
40 TEST_VC2_FIXTURE(2);
41 TEST_VC2_FIXTURE(2);
41 auto range = DateTimeRange::fromDateTime(QDate(2018,8,7),QTime(14,00),
42 auto range = DateTimeRange::fromDateTime(QDate(2018,8,7),QTime(14,00),
42 QDate(2018,8,7),QTime(16,00));
43 QDate(2018,8,7),QTime(16,00));
43 bool callbackCalled = false;
44 bool callbackCalled = false;
44 connect(&vc,&VariableController2::variableAdded, [&callbackCalled](std::shared_ptr<Variable>){callbackCalled=true;});
45 connect(&vc,&VariableController2::variableAdded, [&callbackCalled](std::shared_ptr<Variable>){callbackCalled=true;});
45 QVERIFY(!callbackCalled);
46 QVERIFY(!callbackCalled);
46 auto var1 = vc.createVariable("var1", {}, provider, range);
47 auto var1 = vc.createVariable("var1", {}, provider, range);
47 QVERIFY(SciQLop::containers::contains(vc.variables(), var1));
48 QVERIFY(SciQLop::containers::contains(vc.variables(), var1));
48 QVERIFY(callbackCalled);
49 QVERIFY(callbackCalled);
49 }
50 }
50
51
51 void testDeleteVariable()
52 void testDeleteVariable()
52 {
53 {
53 TEST_VC2_FIXTURE(1);
54 TEST_VC2_FIXTURE(1);
54 auto range = DateTimeRange::fromDateTime(QDate(2018,8,7),QTime(14,00),
55 auto range = DateTimeRange::fromDateTime(QDate(2018,8,7),QTime(14,00),
55 QDate(2018,8,7),QTime(16,00));
56 QDate(2018,8,7),QTime(16,00));
56 bool callbackCalled = false;
57 bool callbackCalled = false;
57 connect(&vc,&VariableController2::variableDeleted, [&callbackCalled](std::shared_ptr<Variable>){callbackCalled=true;});
58 connect(&vc,&VariableController2::variableDeleted, [&callbackCalled](std::shared_ptr<Variable>){callbackCalled=true;});
58 auto var1 = vc.createVariable("var1", {}, provider, range);
59 auto var1 = vc.createVariable("var1", {}, provider, range);
60 while(!vc.isReady(var1))QCoreApplication::processEvents();
59 QVERIFY(SciQLop::containers::contains(vc.variables(), var1));
61 QVERIFY(SciQLop::containers::contains(vc.variables(), var1));
60 QVERIFY(!callbackCalled);
62 QVERIFY(!callbackCalled);
61 vc.deleteVariable(var1);
63 vc.deleteVariable(var1);
62 QVERIFY(!SciQLop::containers::contains(vc.variables(), var1));
64 QVERIFY(!SciQLop::containers::contains(vc.variables(), var1));
63 QVERIFY(callbackCalled);
65 QVERIFY(callbackCalled);
64 }
66 }
65
67
66 void testGetData()
68 void testGetData()
67 {
69 {
68 TEST_VC2_FIXTURE(10);
70 TEST_VC2_FIXTURE(10);
69 TEST_VC2_CREATE_DEFAULT_VAR(var1);
71 TEST_VC2_CREATE_DEFAULT_VAR(var1);
70 check_variable_state<RangeType<10>>(var1, range);
72 check_variable_state<RangeType<10>>(var1, range);
71 }
73 }
72
74
73 void testZoom_data()
75 void testZoom_data()
74 {
76 {
75 QTest::addColumn<double>("zoom");
77 QTest::addColumn<double>("zoom");
76 QTest::newRow("Zoom IN 10x") << .1;
78 QTest::newRow("Zoom IN 10x") << .1;
77 QTest::newRow("Zoom OUT 10x") << 10.;
79 QTest::newRow("Zoom OUT 10x") << 10.;
78 QTest::newRow("Zoom IN 1x") << 1.;
80 QTest::newRow("Zoom IN 1x") << 1.;
79 }
81 }
80 void testZoom()
82 void testZoom()
81 {
83 {
82 TEST_VC2_FIXTURE(100);
84 TEST_VC2_FIXTURE(100);
83 TEST_VC2_CREATE_DEFAULT_VAR(var1);
85 TEST_VC2_CREATE_DEFAULT_VAR(var1);
84 check_variable_state<RangeType<100>>(var1, range);
86 check_variable_state<RangeType<100>>(var1, range);
85
87
86 QFETCH(double, zoom);
88 QFETCH(double, zoom);
87 range *=zoom;
89 range *=zoom;
88 vc.changeRange(var1, range);
90 vc.changeRange(var1, range);
89 check_variable_state<RangeType<100>>(var1, range);
91 check_variable_state<RangeType<100>>(var1, range);
90 }
92 }
91
93
92 void testPan_data()
94 void testPan_data()
93 {
95 {
94 QTest::addColumn<double>("pan");
96 QTest::addColumn<double>("pan");
95 QTest::newRow("Right 1000 seconds") << 1000.;
97 QTest::newRow("Right 1000 seconds") << 1000.;
96 QTest::newRow("Left 1000 seconds") << -1000.;
98 QTest::newRow("Left 1000 seconds") << -1000.;
97 QTest::newRow("Right 0.1 seconds") << .1;
99 QTest::newRow("Right 0.1 seconds") << .1;
98 QTest::newRow("Left 0.1 seconds") << -.1;
100 QTest::newRow("Left 0.1 seconds") << -.1;
99 }
101 }
100 void testPan()
102 void testPan()
101 {
103 {
102 TEST_VC2_FIXTURE(10);
104 TEST_VC2_FIXTURE(10);
103 TEST_VC2_CREATE_DEFAULT_VAR(var1);
105 TEST_VC2_CREATE_DEFAULT_VAR(var1);
104 check_variable_state<RangeType<10>>(var1, range);
106 check_variable_state<RangeType<10>>(var1, range);
105
107
106 QFETCH(double, pan);
108 QFETCH(double, pan);
107
109
108 range += Seconds<double>{pan};
110 range += Seconds<double>{pan};
109 vc.changeRange(var1, range);
111 vc.changeRange(var1, range);
110 check_variable_state<RangeType<10>>(var1, range);
112 check_variable_state<RangeType<10>>(var1, range);
111 }
113 }
112
114
113 void testCache_data()
115 void testCache_data()
114 {
116 {
115 QTest::addColumn<DateTimeRangeTransformation>("transformation");
117 QTest::addColumn<DateTimeRangeTransformation>("transformation");
116 QTest::addColumn<int>("expectedIncrement");
118 QTest::addColumn<int>("expectedIncrement");
117 QTest::newRow("zoom in") << DateTimeRangeTransformation{0.8,Seconds<double>(0.)} << 0;
119 QTest::newRow("zoom in") << DateTimeRangeTransformation{0.8,Seconds<double>(0.)} << 0;
118 QTest::newRow("tiny zoom out") << DateTimeRangeTransformation{1.01,Seconds<double>(0.)} << 0;
120 QTest::newRow("tiny zoom out") << DateTimeRangeTransformation{1.01,Seconds<double>(0.)} << 0;
119 QTest::newRow("just under cache zoom out") << DateTimeRangeTransformation{2.0/1.1,Seconds<double>(0.)} << 0;
121 QTest::newRow("just under cache zoom out") << DateTimeRangeTransformation{2.0/1.1,Seconds<double>(0.)} << 0;
120 QTest::newRow("just over cache zoom out") << DateTimeRangeTransformation{2.001/1.1, Seconds<double>(0.)} << 2;
122 QTest::newRow("just over cache zoom out") << DateTimeRangeTransformation{2.001/1.1, Seconds<double>(0.)} << 2;
121 QTest::newRow("tiny pan left") << DateTimeRangeTransformation{1.,Seconds<double>(-100.)} << 0;
123 QTest::newRow("tiny pan left") << DateTimeRangeTransformation{1.,Seconds<double>(-100.)} << 0;
122 QTest::newRow("tiny pan right") << DateTimeRangeTransformation{1.,Seconds<double>(100.)} << 0;
124 QTest::newRow("tiny pan right") << DateTimeRangeTransformation{1.,Seconds<double>(100.)} << 0;
123 }
125 }
124 void testCache()
126 void testCache()
125 {
127 {
126 TEST_VC2_FIXTURE(10);
128 TEST_VC2_FIXTURE(10);
127 TEST_VC2_CREATE_DEFAULT_VAR(var1);
129 TEST_VC2_CREATE_DEFAULT_VAR(var1);
128 check_variable_state<RangeType<10>>(var1, range);
130 check_variable_state<RangeType<10>>(var1, range);
129
131
130 QFETCH(DateTimeRangeTransformation, transformation);
132 QFETCH(DateTimeRangeTransformation, transformation);
131 QFETCH(int, expectedIncrement);
133 QFETCH(int, expectedIncrement);
132 auto initialCount = provider->callCounter;
134 auto initialCount = provider->callCounter;
133 range = range.transform(transformation);
135 range = range.transform(transformation);
134 vc.changeRange(var1, range);
136 vc.changeRange(var1, range);
135 check_variable_state<RangeType<10>>(var1, range);
137 check_variable_state<RangeType<10>>(var1, range);
136 QCOMPARE(provider->callCounter-initialCount, expectedIncrement);
138 QCOMPARE(provider->callCounter-initialCount, expectedIncrement);
137 }
139 }
138 };
140 };
139
141
140
142
141 QTEST_MAIN(TestVariableController2)
143 QTEST_MAIN(TestVariableController2)
142
144
143 #include "TestVariableController2.moc"
145 #include "TestVariableController2.moc"
144
146
@@ -1,127 +1,129
1 #include <cmath>
1 #include <cmath>
2 #include <algorithm>
2 #include <algorithm>
3 #include <numeric>
3 #include <numeric>
4 #include <QtTest>
4 #include <QtTest>
5 #include <QObject>
5 #include <QObject>
6 #include <Variable/VariableController2.h>
6 #include <Variable/VariableController2.h>
7 #include <Data/DateTimeRange.h>
7 #include <Data/DateTimeRange.h>
8 #include <Data/IDataProvider.h>
8 #include <Data/IDataProvider.h>
9 #include <Data/ScalarSeries.h>
9 #include <Data/ScalarSeries.h>
10 #include <Data/DataProviderParameters.h>
10 #include <Data/DataProviderParameters.h>
11 #include <Common/containers.h>
11 #include <Common/containers.h>
12
12
13 #include <TestUtils/TestProviders.h>
13 #include <TestUtils/TestProviders.h>
14
14
15 #define TEST_VC2_FIXTURE(slope) \
15 #define TEST_VC2_FIXTURE(slope) \
16 VariableController2 vc; \
16 VariableController2 vc; \
17 auto provider = std::make_shared<SimpleRange<slope>>();\
17 auto provider = std::make_shared<SimpleRange<slope>>();\
18
18
19 #define TEST_VC2_CREATE_DEFAULT_VARS(name1, name2, name3)\
19 #define TEST_VC2_CREATE_DEFAULT_VARS(name1, name2, name3)\
20 auto range = DateTimeRange::fromDateTime(QDate(2018,8,7),QTime(14,00),\
20 auto range = DateTimeRange::fromDateTime(QDate(2018,8,7),QTime(14,00),\
21 QDate(2018,8,7),QTime(16,00));\
21 QDate(2018,8,7),QTime(16,00));\
22 auto name1 = vc.createVariable("name1", {}, provider, range);\
22 auto name1 = vc.createVariable("name1", {}, provider, range);\
23 while(!vc.isReady(name1))QCoreApplication::processEvents();\
23 auto name2 = vc.cloneVariable(name1);\
24 auto name2 = vc.cloneVariable(name1);\
24 auto name3 = vc.cloneVariable(name2);\
25 auto name3 = vc.cloneVariable(name2);\
25 vc.synchronize(name1,name2);\
26 vc.synchronize(name1,name2);\
27 while(!vc.isReady(name1))QCoreApplication::processEvents();\
26
28
27
29
28 class TestVariableController2WithSync : public QObject
30 class TestVariableController2WithSync : public QObject
29 {
31 {
30 Q_OBJECT
32 Q_OBJECT
31 public:
33 public:
32 explicit TestVariableController2WithSync(QObject *parent = nullptr) : QObject(parent){}
34 explicit TestVariableController2WithSync(QObject *parent = nullptr) : QObject(parent){}
33 signals:
35 signals:
34
36
35 private slots:
37 private slots:
36 void initTestCase(){}
38 void initTestCase(){}
37 void cleanupTestCase(){}
39 void cleanupTestCase(){}
38
40
39 void testCreateVariable()
41 void testCreateVariable()
40 {
42 {
41 TEST_VC2_FIXTURE(2);
43 TEST_VC2_FIXTURE(2);
42 auto range = DateTimeRange::fromDateTime(QDate(2018,8,7),QTime(14,00),
44 auto range = DateTimeRange::fromDateTime(QDate(2018,8,7),QTime(14,00),
43 QDate(2018,8,7),QTime(16,00));
45 QDate(2018,8,7),QTime(16,00));
44 bool callbackCalled = false;
46 bool callbackCalled = false;
45 connect(&vc,&VariableController2::variableAdded, [&callbackCalled](std::shared_ptr<Variable>){callbackCalled=true;});
47 connect(&vc,&VariableController2::variableAdded, [&callbackCalled](std::shared_ptr<Variable>){callbackCalled=true;});
46 QVERIFY(!callbackCalled);
48 QVERIFY(!callbackCalled);
47 auto var1 = vc.createVariable("var1", {}, provider, range);
49 auto var1 = vc.createVariable("var1", {}, provider, range);
48 QVERIFY(SciQLop::containers::contains(vc.variables(), var1));
50 QVERIFY(SciQLop::containers::contains(vc.variables(), var1));
49 QVERIFY(callbackCalled);
51 QVERIFY(callbackCalled);
50 }
52 }
51
53
52 void testDeleteVariable()
54 void testDeleteVariable()
53 {
55 {
54 TEST_VC2_FIXTURE(1);
56 TEST_VC2_FIXTURE(1);
55 auto range = DateTimeRange::fromDateTime(QDate(2018,8,7),QTime(14,00),
57 auto range = DateTimeRange::fromDateTime(QDate(2018,8,7),QTime(14,00),
56 QDate(2018,8,7),QTime(16,00));
58 QDate(2018,8,7),QTime(16,00));
57 bool callbackCalled = false;
59 bool callbackCalled = false;
58 connect(&vc,&VariableController2::variableDeleted, [&callbackCalled](std::shared_ptr<Variable>){callbackCalled=true;});
60 connect(&vc,&VariableController2::variableDeleted, [&callbackCalled](std::shared_ptr<Variable>){callbackCalled=true;});
59 auto var1 = vc.createVariable("var1", {}, provider, range);
61 auto var1 = vc.createVariable("var1", {}, provider, range);
60 QVERIFY(SciQLop::containers::contains(vc.variables(), var1));
62 QVERIFY(SciQLop::containers::contains(vc.variables(), var1));
61 QVERIFY(!callbackCalled);
63 QVERIFY(!callbackCalled);
62 vc.deleteVariable(var1);
64 vc.deleteVariable(var1);
63 QVERIFY(!SciQLop::containers::contains(vc.variables(), var1));
65 QVERIFY(!SciQLop::containers::contains(vc.variables(), var1));
64 QVERIFY(callbackCalled);
66 QVERIFY(callbackCalled);
65 }
67 }
66
68
67 void testGetData()
69 void testGetData()
68 {
70 {
69 TEST_VC2_FIXTURE(10);
71 TEST_VC2_FIXTURE(10);
70 TEST_VC2_CREATE_DEFAULT_VARS(var1,var2,var3);
72 TEST_VC2_CREATE_DEFAULT_VARS(var1,var2,var3);
71 check_variable_state<RangeType<10>>(var1, range);
73 check_variable_state<RangeType<10>>(var1, range);
72 auto newRange = var2->range()*1.5 + Seconds<double>{1000.};
74 auto newRange = var2->range()*1.5 + Seconds<double>{1000.};
73 vc.changeRange(var2, newRange);
75 vc.changeRange(var2, newRange);
74 check_variable_state<RangeType<10>>(var1, newRange);
76 check_variable_state<RangeType<10>>(var1, newRange);
75 check_variable_state<RangeType<10>>(var2, newRange);
77 check_variable_state<RangeType<10>>(var2, newRange);
76 check_variable_state<RangeType<10>>(var3, range);
78 check_variable_state<RangeType<10>>(var3, range);
77 }
79 }
78
80
79 void testZoom_data()
81 void testZoom_data()
80 {
82 {
81 QTest::addColumn<double>("zoom");
83 QTest::addColumn<double>("zoom");
82 QTest::newRow("Zoom IN 10x") << .1;
84 QTest::newRow("Zoom IN 10x") << .1;
83 QTest::newRow("Zoom OUT 10x") << 10.;
85 QTest::newRow("Zoom OUT 10x") << 10.;
84 QTest::newRow("Zoom IN 1x") << 1.;
86 QTest::newRow("Zoom IN 1x") << 1.;
85 }
87 }
86 void testZoom()
88 void testZoom()
87 {
89 {
88 TEST_VC2_FIXTURE(100);
90 TEST_VC2_FIXTURE(100);
89 TEST_VC2_CREATE_DEFAULT_VARS(var1,var2,var3);
91 TEST_VC2_CREATE_DEFAULT_VARS(var1,var2,var3);
90 check_variable_state<RangeType<100>>(var1, range);
92 check_variable_state<RangeType<100>>(var1, range);
91
93
92 QFETCH(double, zoom);
94 QFETCH(double, zoom);
93 range *=zoom;
95 range *=zoom;
94 vc.changeRange(var1, range);
96 vc.changeRange(var1, range);
95 check_variable_state<RangeType<100>>(var1, range);
97 check_variable_state<RangeType<100>>(var1, range);
96 check_variable_state<RangeType<100>>(var2, range);
98 check_variable_state<RangeType<100>>(var2, range);
97 }
99 }
98
100
99 void testPan_data()
101 void testPan_data()
100 {
102 {
101 QTest::addColumn<double>("pan");
103 QTest::addColumn<double>("pan");
102 QTest::newRow("Right 1000 seconds") << 1000.;
104 QTest::newRow("Right 1000 seconds") << 1000.;
103 QTest::newRow("Left 1000 seconds") << -1000.;
105 QTest::newRow("Left 1000 seconds") << -1000.;
104 QTest::newRow("Right 0.1 seconds") << .1;
106 QTest::newRow("Right 0.1 seconds") << .1;
105 QTest::newRow("Left 0.1 seconds") << -.1;
107 QTest::newRow("Left 0.1 seconds") << -.1;
106 }
108 }
107 void testPan()
109 void testPan()
108 {
110 {
109 TEST_VC2_FIXTURE(10);
111 TEST_VC2_FIXTURE(10);
110 TEST_VC2_CREATE_DEFAULT_VARS(var1,var2,var3);
112 TEST_VC2_CREATE_DEFAULT_VARS(var1,var2,var3);
111 check_variable_state<RangeType<10>>(var1, range);
113 check_variable_state<RangeType<10>>(var1, range);
112
114
113 QFETCH(double, pan);
115 QFETCH(double, pan);
114
116
115 range += Seconds<double>{pan};
117 range += Seconds<double>{pan};
116 vc.changeRange(var1, range);
118 vc.changeRange(var1, range);
117 check_variable_state<RangeType<10>>(var1, range);
119 check_variable_state<RangeType<10>>(var1, range);
118 check_variable_state<RangeType<10>>(var2, range);
120 check_variable_state<RangeType<10>>(var2, range);
119 }
121 }
120
122
121 };
123 };
122
124
123
125
124 QTEST_MAIN(TestVariableController2WithSync)
126 QTEST_MAIN(TestVariableController2WithSync)
125
127
126 #include "TestVariableController2WithSync.moc"
128 #include "TestVariableController2WithSync.moc"
127
129
General Comments 0
You need to be logged in to leave comments. Login now