##// END OF EJS Templates
Creates duplicate only if the variable is in the model
Alexandre Leroux -
r710:1edff56171b6
parent child
Show More
@@ -1,89 +1,96
1 #ifndef SCIQLOP_VARIABLEMODEL_H
1 #ifndef SCIQLOP_VARIABLEMODEL_H
2 #define SCIQLOP_VARIABLEMODEL_H
2 #define SCIQLOP_VARIABLEMODEL_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Data/SqpRange.h>
6 #include <Data/SqpRange.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 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableModel)
14 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableModel)
15
15
16 enum VariableRoles { ProgressRole = Qt::UserRole };
16 enum VariableRoles { ProgressRole = Qt::UserRole };
17
17
18
18
19 class IDataSeries;
19 class IDataSeries;
20 class Variable;
20 class Variable;
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 VariableModel : public QAbstractTableModel {
25 class SCIQLOP_CORE_EXPORT VariableModel : public QAbstractTableModel {
26 Q_OBJECT
26 Q_OBJECT
27 public:
27 public:
28 explicit VariableModel(QObject *parent = nullptr);
28 explicit VariableModel(QObject *parent = nullptr);
29
29
30 /**
30 /**
31 * Adds an existing variable in the model.
31 * Adds an existing variable in the model.
32 * @param variable the variable to add.
32 * @param variable the variable to add.
33 * @remarks the variable's name is modified to avoid name duplicates
33 * @remarks the variable's name is modified to avoid name duplicates
34 * @remarks this method does nothing if the variable already exists in the model
34 * @remarks this method does nothing if the variable already exists in the model
35 */
35 */
36 void addVariable(std::shared_ptr<Variable> variable) noexcept;
36 void addVariable(std::shared_ptr<Variable> variable) noexcept;
37
37
38 /**
38 /**
39 * Checks that a variable is contained in the model
40 * @param variable the variable to check
41 * @return true if the variable is in the model, false otherwise
42 */
43 bool containsVariable(std::shared_ptr<Variable> variable) const noexcept;
44
45 /**
39 * Creates a new variable in the model
46 * Creates a new variable in the model
40 * @param name the name of the new variable
47 * @param name the name of the new variable
41 * @param dateTime the dateTime of the new variable
48 * @param dateTime the dateTime of the new variable
42 * @param metadata the metadata associated to the new variable
49 * @param metadata the metadata associated to the new variable
43 * @return the pointer to the new variable
50 * @return the pointer to the new variable
44 */
51 */
45 std::shared_ptr<Variable> createVariable(const QString &name, const SqpRange &dateTime,
52 std::shared_ptr<Variable> createVariable(const QString &name, const SqpRange &dateTime,
46 const QVariantHash &metadata) noexcept;
53 const QVariantHash &metadata) noexcept;
47
54
48 /**
55 /**
49 * Deletes a variable from the model, if it exists
56 * Deletes a variable from the model, if it exists
50 * @param variable the variable to delete
57 * @param variable the variable to delete
51 */
58 */
52 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
59 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
53
60
54
61
55 std::shared_ptr<Variable> variable(int index) const;
62 std::shared_ptr<Variable> variable(int index) const;
56 std::vector<std::shared_ptr<Variable> > variables() const;
63 std::vector<std::shared_ptr<Variable> > variables() const;
57
64
58 void setDataProgress(std::shared_ptr<Variable> variable, double progress);
65 void setDataProgress(std::shared_ptr<Variable> variable, double progress);
59
66
60
67
61 // /////////////////////////// //
68 // /////////////////////////// //
62 // QAbstractTableModel methods //
69 // QAbstractTableModel methods //
63 // /////////////////////////// //
70 // /////////////////////////// //
64
71
65 virtual int columnCount(const QModelIndex &parent = QModelIndex{}) const override;
72 virtual int columnCount(const QModelIndex &parent = QModelIndex{}) const override;
66 virtual int rowCount(const QModelIndex &parent = QModelIndex{}) const override;
73 virtual int rowCount(const QModelIndex &parent = QModelIndex{}) const override;
67 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
74 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
68 virtual QVariant headerData(int section, Qt::Orientation orientation,
75 virtual QVariant headerData(int section, Qt::Orientation orientation,
69 int role = Qt::DisplayRole) const override;
76 int role = Qt::DisplayRole) const override;
70
77
71
78
72 void abortProgress(const QModelIndex &index);
79 void abortProgress(const QModelIndex &index);
73
80
74 signals:
81 signals:
75 void abortProgessRequested(std::shared_ptr<Variable> variable);
82 void abortProgessRequested(std::shared_ptr<Variable> variable);
76
83
77 private:
84 private:
78 class VariableModelPrivate;
85 class VariableModelPrivate;
79 spimpl::unique_impl_ptr<VariableModelPrivate> impl;
86 spimpl::unique_impl_ptr<VariableModelPrivate> impl;
80
87
81 private slots:
88 private slots:
82 /// Slot called when data of a variable has been updated
89 /// Slot called when data of a variable has been updated
83 void onVariableUpdated() noexcept;
90 void onVariableUpdated() noexcept;
84 };
91 };
85
92
86 // Registers QVector<int> metatype so it can be used in VariableModel::dataChanged() signal
93 // Registers QVector<int> metatype so it can be used in VariableModel::dataChanged() signal
87 SCIQLOP_REGISTER_META_TYPE(QVECTOR_INT_REGISTRY, QVector<int>)
94 SCIQLOP_REGISTER_META_TYPE(QVECTOR_INT_REGISTRY, QVector<int>)
88
95
89 #endif // SCIQLOP_VARIABLEMODEL_H
96 #endif // SCIQLOP_VARIABLEMODEL_H
@@ -1,755 +1,763
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableAcquisitionWorker.h>
2 #include <Variable/VariableAcquisitionWorker.h>
3 #include <Variable/VariableCacheStrategy.h>
3 #include <Variable/VariableCacheStrategy.h>
4 #include <Variable/VariableController.h>
4 #include <Variable/VariableController.h>
5 #include <Variable/VariableModel.h>
5 #include <Variable/VariableModel.h>
6 #include <Variable/VariableSynchronizationGroup.h>
6 #include <Variable/VariableSynchronizationGroup.h>
7
7
8 #include <Data/DataProviderParameters.h>
8 #include <Data/DataProviderParameters.h>
9 #include <Data/IDataProvider.h>
9 #include <Data/IDataProvider.h>
10 #include <Data/IDataSeries.h>
10 #include <Data/IDataSeries.h>
11 #include <Data/VariableRequest.h>
11 #include <Data/VariableRequest.h>
12 #include <Time/TimeController.h>
12 #include <Time/TimeController.h>
13
13
14 #include <QMutex>
14 #include <QMutex>
15 #include <QThread>
15 #include <QThread>
16 #include <QUuid>
16 #include <QUuid>
17 #include <QtCore/QItemSelectionModel>
17 #include <QtCore/QItemSelectionModel>
18
18
19 #include <deque>
19 #include <deque>
20 #include <set>
20 #include <set>
21 #include <unordered_map>
21 #include <unordered_map>
22
22
23 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
23 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
24
24
25 namespace {
25 namespace {
26
26
27 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
27 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
28 const SqpRange &oldGraphRange)
28 const SqpRange &oldGraphRange)
29 {
29 {
30 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
30 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
31
31
32 auto varRangeRequested = varRange;
32 auto varRangeRequested = varRange;
33 switch (zoomType) {
33 switch (zoomType) {
34 case AcquisitionZoomType::ZoomIn: {
34 case AcquisitionZoomType::ZoomIn: {
35 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
35 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
36 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
36 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
37 varRangeRequested.m_TStart += deltaLeft;
37 varRangeRequested.m_TStart += deltaLeft;
38 varRangeRequested.m_TEnd -= deltaRight;
38 varRangeRequested.m_TEnd -= deltaRight;
39 break;
39 break;
40 }
40 }
41
41
42 case AcquisitionZoomType::ZoomOut: {
42 case AcquisitionZoomType::ZoomOut: {
43 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
43 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
44 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
44 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
45 varRangeRequested.m_TStart -= deltaLeft;
45 varRangeRequested.m_TStart -= deltaLeft;
46 varRangeRequested.m_TEnd += deltaRight;
46 varRangeRequested.m_TEnd += deltaRight;
47 break;
47 break;
48 }
48 }
49 case AcquisitionZoomType::PanRight: {
49 case AcquisitionZoomType::PanRight: {
50 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
50 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
51 varRangeRequested.m_TStart += deltaRight;
51 varRangeRequested.m_TStart += deltaRight;
52 varRangeRequested.m_TEnd += deltaRight;
52 varRangeRequested.m_TEnd += deltaRight;
53 break;
53 break;
54 }
54 }
55 case AcquisitionZoomType::PanLeft: {
55 case AcquisitionZoomType::PanLeft: {
56 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
56 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
57 varRangeRequested.m_TStart -= deltaLeft;
57 varRangeRequested.m_TStart -= deltaLeft;
58 varRangeRequested.m_TEnd -= deltaLeft;
58 varRangeRequested.m_TEnd -= deltaLeft;
59 break;
59 break;
60 }
60 }
61 case AcquisitionZoomType::Unknown: {
61 case AcquisitionZoomType::Unknown: {
62 qCCritical(LOG_VariableController())
62 qCCritical(LOG_VariableController())
63 << VariableController::tr("Impossible to synchronize: zoom type unknown");
63 << VariableController::tr("Impossible to synchronize: zoom type unknown");
64 break;
64 break;
65 }
65 }
66 default:
66 default:
67 qCCritical(LOG_VariableController()) << VariableController::tr(
67 qCCritical(LOG_VariableController()) << VariableController::tr(
68 "Impossible to synchronize: zoom type not take into account");
68 "Impossible to synchronize: zoom type not take into account");
69 // No action
69 // No action
70 break;
70 break;
71 }
71 }
72
72
73 return varRangeRequested;
73 return varRangeRequested;
74 }
74 }
75 }
75 }
76
76
77 struct VariableController::VariableControllerPrivate {
77 struct VariableController::VariableControllerPrivate {
78 explicit VariableControllerPrivate(VariableController *parent)
78 explicit VariableControllerPrivate(VariableController *parent)
79 : m_WorkingMutex{},
79 : m_WorkingMutex{},
80 m_VariableModel{new VariableModel{parent}},
80 m_VariableModel{new VariableModel{parent}},
81 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
81 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
82 m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
82 m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
83 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
83 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
84 q{parent}
84 q{parent}
85 {
85 {
86
86
87 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
87 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
88 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
88 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
89 }
89 }
90
90
91
91
92 virtual ~VariableControllerPrivate()
92 virtual ~VariableControllerPrivate()
93 {
93 {
94 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
94 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
95 m_VariableAcquisitionWorkerThread.quit();
95 m_VariableAcquisitionWorkerThread.quit();
96 m_VariableAcquisitionWorkerThread.wait();
96 m_VariableAcquisitionWorkerThread.wait();
97 }
97 }
98
98
99
99
100 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested,
100 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested,
101 QUuid varRequestId);
101 QUuid varRequestId);
102
102
103 QVector<SqpRange> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
103 QVector<SqpRange> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
104 const SqpRange &dateTime);
104 const SqpRange &dateTime);
105
105
106 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
106 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
107 std::shared_ptr<IDataSeries>
107 std::shared_ptr<IDataSeries>
108 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
108 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
109
109
110 void registerProvider(std::shared_ptr<IDataProvider> provider);
110 void registerProvider(std::shared_ptr<IDataProvider> provider);
111
111
112 void storeVariableRequest(QUuid varId, QUuid varRequestId, const VariableRequest &varRequest);
112 void storeVariableRequest(QUuid varId, QUuid varRequestId, const VariableRequest &varRequest);
113 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries);
113 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries);
114 void updateVariableRequest(QUuid varRequestId);
114 void updateVariableRequest(QUuid varRequestId);
115 void cancelVariableRequest(QUuid varRequestId);
115 void cancelVariableRequest(QUuid varRequestId);
116
116
117 QMutex m_WorkingMutex;
117 QMutex m_WorkingMutex;
118 /// Variable model. The VariableController has the ownership
118 /// Variable model. The VariableController has the ownership
119 VariableModel *m_VariableModel;
119 VariableModel *m_VariableModel;
120 QItemSelectionModel *m_VariableSelectionModel;
120 QItemSelectionModel *m_VariableSelectionModel;
121
121
122
122
123 TimeController *m_TimeController{nullptr};
123 TimeController *m_TimeController{nullptr};
124 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
124 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
125 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
125 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
126 QThread m_VariableAcquisitionWorkerThread;
126 QThread m_VariableAcquisitionWorkerThread;
127
127
128 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
128 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
129 m_VariableToProviderMap;
129 m_VariableToProviderMap;
130 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
130 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
131 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
131 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
132 m_GroupIdToVariableSynchronizationGroupMap;
132 m_GroupIdToVariableSynchronizationGroupMap;
133 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
133 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
134 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
134 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
135
135
136 std::map<QUuid, std::map<QUuid, VariableRequest> > m_VarRequestIdToVarIdVarRequestMap;
136 std::map<QUuid, std::map<QUuid, VariableRequest> > m_VarRequestIdToVarIdVarRequestMap;
137
137
138 std::map<QUuid, std::deque<QUuid> > m_VarIdToVarRequestIdQueueMap;
138 std::map<QUuid, std::deque<QUuid> > m_VarIdToVarRequestIdQueueMap;
139
139
140
140
141 VariableController *q;
141 VariableController *q;
142 };
142 };
143
143
144
144
145 VariableController::VariableController(QObject *parent)
145 VariableController::VariableController(QObject *parent)
146 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
146 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
147 {
147 {
148 qCDebug(LOG_VariableController()) << tr("VariableController construction")
148 qCDebug(LOG_VariableController()) << tr("VariableController construction")
149 << QThread::currentThread();
149 << QThread::currentThread();
150
150
151 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
151 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
152 &VariableController::onAbortProgressRequested);
152 &VariableController::onAbortProgressRequested);
153
153
154 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
154 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
155 &VariableController::onDataProvided);
155 &VariableController::onDataProvided);
156 connect(impl->m_VariableAcquisitionWorker.get(),
156 connect(impl->m_VariableAcquisitionWorker.get(),
157 &VariableAcquisitionWorker::variableRequestInProgress, this,
157 &VariableAcquisitionWorker::variableRequestInProgress, this,
158 &VariableController::onVariableRetrieveDataInProgress);
158 &VariableController::onVariableRetrieveDataInProgress);
159
159
160 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
160 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
161 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
161 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
162 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
162 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
163 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
163 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
164
164
165
165
166 impl->m_VariableAcquisitionWorkerThread.start();
166 impl->m_VariableAcquisitionWorkerThread.start();
167 }
167 }
168
168
169 VariableController::~VariableController()
169 VariableController::~VariableController()
170 {
170 {
171 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
171 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
172 << QThread::currentThread();
172 << QThread::currentThread();
173 this->waitForFinish();
173 this->waitForFinish();
174 }
174 }
175
175
176 VariableModel *VariableController::variableModel() noexcept
176 VariableModel *VariableController::variableModel() noexcept
177 {
177 {
178 return impl->m_VariableModel;
178 return impl->m_VariableModel;
179 }
179 }
180
180
181 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
181 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
182 {
182 {
183 return impl->m_VariableSelectionModel;
183 return impl->m_VariableSelectionModel;
184 }
184 }
185
185
186 void VariableController::setTimeController(TimeController *timeController) noexcept
186 void VariableController::setTimeController(TimeController *timeController) noexcept
187 {
187 {
188 impl->m_TimeController = timeController;
188 impl->m_TimeController = timeController;
189 }
189 }
190
190
191 std::shared_ptr<Variable>
191 std::shared_ptr<Variable>
192 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
192 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
193 {
193 {
194 // Clones variable
194 if (impl->m_VariableModel->containsVariable(variable)) {
195 auto duplicate = variable->clone();
195 // Clones variable
196 auto duplicate = variable->clone();
196
197
197 // Adds clone to model
198 // Adds clone to model
198 impl->m_VariableModel->addVariable(duplicate);
199 impl->m_VariableModel->addVariable(duplicate);
199
200
200 return duplicate;
201 return duplicate;
202 }
203 else {
204 qCCritical(LOG_VariableController())
205 << tr("Can't create duplicate of variable %1: variable not registered in the model")
206 .arg(variable->name());
207 return nullptr;
208 }
201 }
209 }
202
210
203 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
211 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
204 {
212 {
205 if (!variable) {
213 if (!variable) {
206 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
214 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
207 return;
215 return;
208 }
216 }
209
217
210 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
218 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
211 // make some treatments before the deletion
219 // make some treatments before the deletion
212 emit variableAboutToBeDeleted(variable);
220 emit variableAboutToBeDeleted(variable);
213
221
214 // Deletes identifier
222 // Deletes identifier
215 impl->m_VariableToIdentifierMap.erase(variable);
223 impl->m_VariableToIdentifierMap.erase(variable);
216
224
217 // Deletes provider
225 // Deletes provider
218 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
226 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
219 qCDebug(LOG_VariableController())
227 qCDebug(LOG_VariableController())
220 << tr("Number of providers deleted for variable %1: %2")
228 << tr("Number of providers deleted for variable %1: %2")
221 .arg(variable->name(), QString::number(nbProvidersDeleted));
229 .arg(variable->name(), QString::number(nbProvidersDeleted));
222
230
223
231
224 // Deletes from model
232 // Deletes from model
225 impl->m_VariableModel->deleteVariable(variable);
233 impl->m_VariableModel->deleteVariable(variable);
226 }
234 }
227
235
228 void VariableController::deleteVariables(
236 void VariableController::deleteVariables(
229 const QVector<std::shared_ptr<Variable> > &variables) noexcept
237 const QVector<std::shared_ptr<Variable> > &variables) noexcept
230 {
238 {
231 for (auto variable : qAsConst(variables)) {
239 for (auto variable : qAsConst(variables)) {
232 deleteVariable(variable);
240 deleteVariable(variable);
233 }
241 }
234 }
242 }
235
243
236 void VariableController::abortProgress(std::shared_ptr<Variable> variable)
244 void VariableController::abortProgress(std::shared_ptr<Variable> variable)
237 {
245 {
238 }
246 }
239
247
240 std::shared_ptr<Variable>
248 std::shared_ptr<Variable>
241 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
249 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
242 std::shared_ptr<IDataProvider> provider) noexcept
250 std::shared_ptr<IDataProvider> provider) noexcept
243 {
251 {
244 if (!impl->m_TimeController) {
252 if (!impl->m_TimeController) {
245 qCCritical(LOG_VariableController())
253 qCCritical(LOG_VariableController())
246 << tr("Impossible to create variable: The time controller is null");
254 << tr("Impossible to create variable: The time controller is null");
247 return nullptr;
255 return nullptr;
248 }
256 }
249
257
250 auto range = impl->m_TimeController->dateTime();
258 auto range = impl->m_TimeController->dateTime();
251
259
252 if (auto newVariable = impl->m_VariableModel->createVariable(name, range, metadata)) {
260 if (auto newVariable = impl->m_VariableModel->createVariable(name, range, metadata)) {
253 auto identifier = QUuid::createUuid();
261 auto identifier = QUuid::createUuid();
254
262
255 // store the provider
263 // store the provider
256 impl->registerProvider(provider);
264 impl->registerProvider(provider);
257
265
258 // Associate the provider
266 // Associate the provider
259 impl->m_VariableToProviderMap[newVariable] = provider;
267 impl->m_VariableToProviderMap[newVariable] = provider;
260 impl->m_VariableToIdentifierMap[newVariable] = identifier;
268 impl->m_VariableToIdentifierMap[newVariable] = identifier;
261
269
262
270
263 auto varRequestId = QUuid::createUuid();
271 auto varRequestId = QUuid::createUuid();
264 qCInfo(LOG_VariableController()) << "processRequest for" << name << varRequestId;
272 qCInfo(LOG_VariableController()) << "processRequest for" << name << varRequestId;
265 impl->processRequest(newVariable, range, varRequestId);
273 impl->processRequest(newVariable, range, varRequestId);
266 impl->updateVariableRequest(varRequestId);
274 impl->updateVariableRequest(varRequestId);
267
275
268 return newVariable;
276 return newVariable;
269 }
277 }
270 }
278 }
271
279
272 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
280 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
273 {
281 {
274 // TODO check synchronisation and Rescale
282 // TODO check synchronisation and Rescale
275 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
283 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
276 << QThread::currentThread()->objectName();
284 << QThread::currentThread()->objectName();
277 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
285 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
278 auto varRequestId = QUuid::createUuid();
286 auto varRequestId = QUuid::createUuid();
279
287
280 for (const auto &selectedRow : qAsConst(selectedRows)) {
288 for (const auto &selectedRow : qAsConst(selectedRows)) {
281 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
289 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
282 selectedVariable->setRange(dateTime);
290 selectedVariable->setRange(dateTime);
283 impl->processRequest(selectedVariable, dateTime, varRequestId);
291 impl->processRequest(selectedVariable, dateTime, varRequestId);
284
292
285 // notify that rescale operation has to be done
293 // notify that rescale operation has to be done
286 emit rangeChanged(selectedVariable, dateTime);
294 emit rangeChanged(selectedVariable, dateTime);
287 }
295 }
288 }
296 }
289 impl->updateVariableRequest(varRequestId);
297 impl->updateVariableRequest(varRequestId);
290 }
298 }
291
299
292 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
300 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
293 const SqpRange &cacheRangeRequested,
301 const SqpRange &cacheRangeRequested,
294 QVector<AcquisitionDataPacket> dataAcquired)
302 QVector<AcquisitionDataPacket> dataAcquired)
295 {
303 {
296 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
304 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
297 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
305 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
298 if (!varRequestId.isNull()) {
306 if (!varRequestId.isNull()) {
299 impl->updateVariableRequest(varRequestId);
307 impl->updateVariableRequest(varRequestId);
300 }
308 }
301 }
309 }
302
310
303 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
311 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
304 {
312 {
305 if (auto var = impl->findVariable(identifier)) {
313 if (auto var = impl->findVariable(identifier)) {
306 impl->m_VariableModel->setDataProgress(var, progress);
314 impl->m_VariableModel->setDataProgress(var, progress);
307 }
315 }
308 else {
316 else {
309 qCCritical(LOG_VariableController())
317 qCCritical(LOG_VariableController())
310 << tr("Impossible to notify progression of a null variable");
318 << tr("Impossible to notify progression of a null variable");
311 }
319 }
312 }
320 }
313
321
314 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
322 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
315 {
323 {
316 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
324 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
317 << QThread::currentThread()->objectName();
325 << QThread::currentThread()->objectName();
318
326
319 auto it = impl->m_VariableToIdentifierMap.find(variable);
327 auto it = impl->m_VariableToIdentifierMap.find(variable);
320 if (it != impl->m_VariableToIdentifierMap.cend()) {
328 if (it != impl->m_VariableToIdentifierMap.cend()) {
321 impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
329 impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
322 }
330 }
323 else {
331 else {
324 qCWarning(LOG_VariableController())
332 qCWarning(LOG_VariableController())
325 << tr("Aborting progression of inexistant variable detected !!!")
333 << tr("Aborting progression of inexistant variable detected !!!")
326 << QThread::currentThread()->objectName();
334 << QThread::currentThread()->objectName();
327 }
335 }
328 }
336 }
329
337
330 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
338 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
331 {
339 {
332 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
340 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
333 << QThread::currentThread()->objectName()
341 << QThread::currentThread()->objectName()
334 << synchronizationGroupId;
342 << synchronizationGroupId;
335 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
343 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
336 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
344 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
337 std::make_pair(synchronizationGroupId, vSynchroGroup));
345 std::make_pair(synchronizationGroupId, vSynchroGroup));
338 }
346 }
339
347
340 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
348 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
341 {
349 {
342 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
350 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
343 }
351 }
344
352
345 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
353 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
346 QUuid synchronizationGroupId)
354 QUuid synchronizationGroupId)
347
355
348 {
356 {
349 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
357 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
350 << synchronizationGroupId;
358 << synchronizationGroupId;
351 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
359 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
352 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
360 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
353 auto groupIdToVSGIt
361 auto groupIdToVSGIt
354 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
362 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
355 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
363 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
356 impl->m_VariableIdGroupIdMap.insert(
364 impl->m_VariableIdGroupIdMap.insert(
357 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
365 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
358 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
366 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
359 }
367 }
360 else {
368 else {
361 qCCritical(LOG_VariableController())
369 qCCritical(LOG_VariableController())
362 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
370 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
363 << variable->name();
371 << variable->name();
364 }
372 }
365 }
373 }
366 else {
374 else {
367 qCCritical(LOG_VariableController())
375 qCCritical(LOG_VariableController())
368 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
376 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
369 }
377 }
370 }
378 }
371
379
372
380
373 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
381 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
374 const SqpRange &range, const SqpRange &oldRange,
382 const SqpRange &range, const SqpRange &oldRange,
375 bool synchronise)
383 bool synchronise)
376 {
384 {
377 // NOTE: oldRange isn't really necessary since oldRange == variable->range().
385 // NOTE: oldRange isn't really necessary since oldRange == variable->range().
378
386
379 // we want to load data of the variable for the dateTime.
387 // we want to load data of the variable for the dateTime.
380 // First we check if the cache contains some of them.
388 // First we check if the cache contains some of them.
381 // For the other, we ask the provider to give them.
389 // For the other, we ask the provider to give them.
382
390
383 auto varRequestId = QUuid::createUuid();
391 auto varRequestId = QUuid::createUuid();
384 qCInfo(LOG_VariableController()) << "VariableController::onRequestDataLoading"
392 qCInfo(LOG_VariableController()) << "VariableController::onRequestDataLoading"
385 << QThread::currentThread()->objectName() << varRequestId;
393 << QThread::currentThread()->objectName() << varRequestId;
386
394
387 for (const auto &var : variables) {
395 for (const auto &var : variables) {
388 qCDebug(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId;
396 qCDebug(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId;
389 impl->processRequest(var, range, varRequestId);
397 impl->processRequest(var, range, varRequestId);
390 }
398 }
391
399
392 if (synchronise) {
400 if (synchronise) {
393 // Get the group ids
401 // Get the group ids
394 qCDebug(LOG_VariableController())
402 qCDebug(LOG_VariableController())
395 << "TORM VariableController::onRequestDataLoading for synchro var ENABLE";
403 << "TORM VariableController::onRequestDataLoading for synchro var ENABLE";
396 auto groupIds = std::set<QUuid>{};
404 auto groupIds = std::set<QUuid>{};
397 auto groupIdToOldRangeMap = std::map<QUuid, SqpRange>{};
405 auto groupIdToOldRangeMap = std::map<QUuid, SqpRange>{};
398 for (const auto &var : variables) {
406 for (const auto &var : variables) {
399 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(var);
407 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(var);
400 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
408 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
401 auto vId = varToVarIdIt->second;
409 auto vId = varToVarIdIt->second;
402 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
410 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
403 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
411 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
404 auto gId = varIdToGroupIdIt->second;
412 auto gId = varIdToGroupIdIt->second;
405 groupIdToOldRangeMap.insert(std::make_pair(gId, var->range()));
413 groupIdToOldRangeMap.insert(std::make_pair(gId, var->range()));
406 if (groupIds.find(gId) == groupIds.cend()) {
414 if (groupIds.find(gId) == groupIds.cend()) {
407 qCDebug(LOG_VariableController()) << "Synchro detect group " << gId;
415 qCDebug(LOG_VariableController()) << "Synchro detect group " << gId;
408 groupIds.insert(gId);
416 groupIds.insert(gId);
409 }
417 }
410 }
418 }
411 }
419 }
412 }
420 }
413
421
414 // We assume here all group ids exist
422 // We assume here all group ids exist
415 for (const auto &gId : groupIds) {
423 for (const auto &gId : groupIds) {
416 auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId);
424 auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId);
417 auto vSyncIds = vSynchronizationGroup->getIds();
425 auto vSyncIds = vSynchronizationGroup->getIds();
418 qCDebug(LOG_VariableController()) << "Var in synchro group ";
426 qCDebug(LOG_VariableController()) << "Var in synchro group ";
419 for (auto vId : vSyncIds) {
427 for (auto vId : vSyncIds) {
420 auto var = impl->findVariable(vId);
428 auto var = impl->findVariable(vId);
421
429
422 // Don't process already processed var
430 // Don't process already processed var
423 if (!variables.contains(var)) {
431 if (!variables.contains(var)) {
424 if (var != nullptr) {
432 if (var != nullptr) {
425 qCDebug(LOG_VariableController()) << "processRequest synchro for"
433 qCDebug(LOG_VariableController()) << "processRequest synchro for"
426 << var->name();
434 << var->name();
427 auto vSyncRangeRequested = computeSynchroRangeRequested(
435 auto vSyncRangeRequested = computeSynchroRangeRequested(
428 var->range(), range, groupIdToOldRangeMap.at(gId));
436 var->range(), range, groupIdToOldRangeMap.at(gId));
429 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
437 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
430 impl->processRequest(var, vSyncRangeRequested, varRequestId);
438 impl->processRequest(var, vSyncRangeRequested, varRequestId);
431 }
439 }
432 else {
440 else {
433 qCCritical(LOG_VariableController())
441 qCCritical(LOG_VariableController())
434
442
435 << tr("Impossible to synchronize a null variable");
443 << tr("Impossible to synchronize a null variable");
436 }
444 }
437 }
445 }
438 }
446 }
439 }
447 }
440 }
448 }
441
449
442 impl->updateVariableRequest(varRequestId);
450 impl->updateVariableRequest(varRequestId);
443 }
451 }
444
452
445
453
446 void VariableController::initialize()
454 void VariableController::initialize()
447 {
455 {
448 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
456 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
449 impl->m_WorkingMutex.lock();
457 impl->m_WorkingMutex.lock();
450 qCDebug(LOG_VariableController()) << tr("VariableController init END");
458 qCDebug(LOG_VariableController()) << tr("VariableController init END");
451 }
459 }
452
460
453 void VariableController::finalize()
461 void VariableController::finalize()
454 {
462 {
455 impl->m_WorkingMutex.unlock();
463 impl->m_WorkingMutex.unlock();
456 }
464 }
457
465
458 void VariableController::waitForFinish()
466 void VariableController::waitForFinish()
459 {
467 {
460 QMutexLocker locker{&impl->m_WorkingMutex};
468 QMutexLocker locker{&impl->m_WorkingMutex};
461 }
469 }
462
470
463 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
471 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
464 {
472 {
465 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
473 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
466 auto zoomType = AcquisitionZoomType::Unknown;
474 auto zoomType = AcquisitionZoomType::Unknown;
467 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
475 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
468 zoomType = AcquisitionZoomType::ZoomOut;
476 zoomType = AcquisitionZoomType::ZoomOut;
469 }
477 }
470 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
478 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
471 zoomType = AcquisitionZoomType::PanRight;
479 zoomType = AcquisitionZoomType::PanRight;
472 }
480 }
473 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
481 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
474 zoomType = AcquisitionZoomType::PanLeft;
482 zoomType = AcquisitionZoomType::PanLeft;
475 }
483 }
476 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
484 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
477 zoomType = AcquisitionZoomType::ZoomIn;
485 zoomType = AcquisitionZoomType::ZoomIn;
478 }
486 }
479 else {
487 else {
480 qCCritical(LOG_VariableController()) << "getZoomType: Unknown type detected";
488 qCCritical(LOG_VariableController()) << "getZoomType: Unknown type detected";
481 }
489 }
482 return zoomType;
490 return zoomType;
483 }
491 }
484
492
485 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
493 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
486 const SqpRange &rangeRequested,
494 const SqpRange &rangeRequested,
487 QUuid varRequestId)
495 QUuid varRequestId)
488 {
496 {
489
497
490 // TODO: protect at
498 // TODO: protect at
491 auto varRequest = VariableRequest{};
499 auto varRequest = VariableRequest{};
492 auto varId = m_VariableToIdentifierMap.at(var);
500 auto varId = m_VariableToIdentifierMap.at(var);
493
501
494 auto varStrategyRangesRequested
502 auto varStrategyRangesRequested
495 = m_VariableCacheStrategy->computeStrategyRanges(var->range(), rangeRequested);
503 = m_VariableCacheStrategy->computeStrategyRanges(var->range(), rangeRequested);
496 auto notInCacheRangeList = var->provideNotInCacheRangeList(varStrategyRangesRequested.second);
504 auto notInCacheRangeList = var->provideNotInCacheRangeList(varStrategyRangesRequested.second);
497 auto inCacheRangeList = var->provideInCacheRangeList(varStrategyRangesRequested.second);
505 auto inCacheRangeList = var->provideInCacheRangeList(varStrategyRangesRequested.second);
498
506
499 if (!notInCacheRangeList.empty()) {
507 if (!notInCacheRangeList.empty()) {
500 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
508 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
501 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
509 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
502 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM processRequest RR ") << rangeRequested;
510 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM processRequest RR ") << rangeRequested;
503 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM processRequest R ")
511 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM processRequest R ")
504 << varStrategyRangesRequested.first;
512 << varStrategyRangesRequested.first;
505 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM processRequest CR ")
513 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM processRequest CR ")
506 << varStrategyRangesRequested.second;
514 << varStrategyRangesRequested.second;
507 // store VarRequest
515 // store VarRequest
508 storeVariableRequest(varId, varRequestId, varRequest);
516 storeVariableRequest(varId, varRequestId, varRequest);
509
517
510 auto varProvider = m_VariableToProviderMap.at(var);
518 auto varProvider = m_VariableToProviderMap.at(var);
511 if (varProvider != nullptr) {
519 if (varProvider != nullptr) {
512 auto varRequestIdCanceled = m_VariableAcquisitionWorker->pushVariableRequest(
520 auto varRequestIdCanceled = m_VariableAcquisitionWorker->pushVariableRequest(
513 varRequestId, varId, varStrategyRangesRequested.first,
521 varRequestId, varId, varStrategyRangesRequested.first,
514 varStrategyRangesRequested.second,
522 varStrategyRangesRequested.second,
515 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
523 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
516 varProvider);
524 varProvider);
517
525
518 if (!varRequestIdCanceled.isNull()) {
526 if (!varRequestIdCanceled.isNull()) {
519 qCInfo(LOG_VariableAcquisitionWorker()) << tr("varRequestIdCanceled: ")
527 qCInfo(LOG_VariableAcquisitionWorker()) << tr("varRequestIdCanceled: ")
520 << varRequestIdCanceled;
528 << varRequestIdCanceled;
521 cancelVariableRequest(varRequestIdCanceled);
529 cancelVariableRequest(varRequestIdCanceled);
522 }
530 }
523 }
531 }
524 else {
532 else {
525 qCCritical(LOG_VariableController())
533 qCCritical(LOG_VariableController())
526 << "Impossible to provide data with a null provider";
534 << "Impossible to provide data with a null provider";
527 }
535 }
528
536
529 if (!inCacheRangeList.empty()) {
537 if (!inCacheRangeList.empty()) {
530 emit q->updateVarDisplaying(var, inCacheRangeList.first());
538 emit q->updateVarDisplaying(var, inCacheRangeList.first());
531 }
539 }
532 }
540 }
533 else {
541 else {
534
542
535 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
543 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
536 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
544 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
537 // store VarRequest
545 // store VarRequest
538 storeVariableRequest(varId, varRequestId, varRequest);
546 storeVariableRequest(varId, varRequestId, varRequest);
539 acceptVariableRequest(varId,
547 acceptVariableRequest(varId,
540 var->dataSeries()->subDataSeries(varStrategyRangesRequested.second));
548 var->dataSeries()->subDataSeries(varStrategyRangesRequested.second));
541 }
549 }
542 }
550 }
543
551
544 std::shared_ptr<Variable>
552 std::shared_ptr<Variable>
545 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
553 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
546 {
554 {
547 std::shared_ptr<Variable> var;
555 std::shared_ptr<Variable> var;
548 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
556 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
549
557
550 auto end = m_VariableToIdentifierMap.cend();
558 auto end = m_VariableToIdentifierMap.cend();
551 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
559 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
552 if (it != end) {
560 if (it != end) {
553 var = it->first;
561 var = it->first;
554 }
562 }
555 else {
563 else {
556 qCCritical(LOG_VariableController())
564 qCCritical(LOG_VariableController())
557 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
565 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
558 }
566 }
559
567
560 return var;
568 return var;
561 }
569 }
562
570
563 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
571 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
564 const QVector<AcquisitionDataPacket> acqDataPacketVector)
572 const QVector<AcquisitionDataPacket> acqDataPacketVector)
565 {
573 {
566 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
574 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
567 << acqDataPacketVector.size();
575 << acqDataPacketVector.size();
568 std::shared_ptr<IDataSeries> dataSeries;
576 std::shared_ptr<IDataSeries> dataSeries;
569 if (!acqDataPacketVector.isEmpty()) {
577 if (!acqDataPacketVector.isEmpty()) {
570 dataSeries = acqDataPacketVector[0].m_DateSeries;
578 dataSeries = acqDataPacketVector[0].m_DateSeries;
571 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
579 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
572 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
580 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
573 }
581 }
574 }
582 }
575 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
583 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
576 << acqDataPacketVector.size();
584 << acqDataPacketVector.size();
577 return dataSeries;
585 return dataSeries;
578 }
586 }
579
587
580 void VariableController::VariableControllerPrivate::registerProvider(
588 void VariableController::VariableControllerPrivate::registerProvider(
581 std::shared_ptr<IDataProvider> provider)
589 std::shared_ptr<IDataProvider> provider)
582 {
590 {
583 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
591 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
584 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
592 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
585 << provider->objectName();
593 << provider->objectName();
586 m_ProviderSet.insert(provider);
594 m_ProviderSet.insert(provider);
587 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
595 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
588 &VariableAcquisitionWorker::onVariableDataAcquired);
596 &VariableAcquisitionWorker::onVariableDataAcquired);
589 connect(provider.get(), &IDataProvider::dataProvidedProgress,
597 connect(provider.get(), &IDataProvider::dataProvidedProgress,
590 m_VariableAcquisitionWorker.get(),
598 m_VariableAcquisitionWorker.get(),
591 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
599 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
592 }
600 }
593 else {
601 else {
594 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
602 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
595 }
603 }
596 }
604 }
597
605
598 void VariableController::VariableControllerPrivate::storeVariableRequest(
606 void VariableController::VariableControllerPrivate::storeVariableRequest(
599 QUuid varId, QUuid varRequestId, const VariableRequest &varRequest)
607 QUuid varId, QUuid varRequestId, const VariableRequest &varRequest)
600 {
608 {
601 // First request for the variable. we can create an entry for it
609 // First request for the variable. we can create an entry for it
602 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
610 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
603 if (varIdToVarRequestIdQueueMapIt == m_VarIdToVarRequestIdQueueMap.cend()) {
611 if (varIdToVarRequestIdQueueMapIt == m_VarIdToVarRequestIdQueueMap.cend()) {
604 auto varRequestIdQueue = std::deque<QUuid>{};
612 auto varRequestIdQueue = std::deque<QUuid>{};
605 qCDebug(LOG_VariableController()) << tr("Store REQUEST in QUEUE");
613 qCDebug(LOG_VariableController()) << tr("Store REQUEST in QUEUE");
606 varRequestIdQueue.push_back(varRequestId);
614 varRequestIdQueue.push_back(varRequestId);
607 m_VarIdToVarRequestIdQueueMap.insert(std::make_pair(varId, std::move(varRequestIdQueue)));
615 m_VarIdToVarRequestIdQueueMap.insert(std::make_pair(varId, std::move(varRequestIdQueue)));
608 }
616 }
609 else {
617 else {
610 qCDebug(LOG_VariableController()) << tr("Store REQUEST in EXISTING QUEUE");
618 qCDebug(LOG_VariableController()) << tr("Store REQUEST in EXISTING QUEUE");
611 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
619 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
612 varRequestIdQueue.push_back(varRequestId);
620 varRequestIdQueue.push_back(varRequestId);
613 }
621 }
614
622
615 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
623 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
616 if (varRequestIdToVarIdVarRequestMapIt == m_VarRequestIdToVarIdVarRequestMap.cend()) {
624 if (varRequestIdToVarIdVarRequestMapIt == m_VarRequestIdToVarIdVarRequestMap.cend()) {
617 auto varIdToVarRequestMap = std::map<QUuid, VariableRequest>{};
625 auto varIdToVarRequestMap = std::map<QUuid, VariableRequest>{};
618 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
626 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
619 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in MAP");
627 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in MAP");
620 m_VarRequestIdToVarIdVarRequestMap.insert(
628 m_VarRequestIdToVarIdVarRequestMap.insert(
621 std::make_pair(varRequestId, std::move(varIdToVarRequestMap)));
629 std::make_pair(varRequestId, std::move(varIdToVarRequestMap)));
622 }
630 }
623 else {
631 else {
624 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
632 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
625 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in EXISTING MAP");
633 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in EXISTING MAP");
626 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
634 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
627 }
635 }
628 }
636 }
629
637
630 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
638 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
631 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
639 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
632 {
640 {
633 QUuid varRequestId;
641 QUuid varRequestId;
634 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
642 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
635 if (varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.cend()) {
643 if (varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.cend()) {
636 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
644 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
637 varRequestId = varRequestIdQueue.front();
645 varRequestId = varRequestIdQueue.front();
638 auto varRequestIdToVarIdVarRequestMapIt
646 auto varRequestIdToVarIdVarRequestMapIt
639 = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
647 = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
640 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
648 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
641 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
649 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
642 auto varIdToVarRequestMapIt = varIdToVarRequestMap.find(varId);
650 auto varIdToVarRequestMapIt = varIdToVarRequestMap.find(varId);
643 if (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) {
651 if (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) {
644 qCDebug(LOG_VariableController()) << tr("acceptVariableRequest");
652 qCDebug(LOG_VariableController()) << tr("acceptVariableRequest");
645 auto &varRequest = varIdToVarRequestMapIt->second;
653 auto &varRequest = varIdToVarRequestMapIt->second;
646 varRequest.m_DataSeries = dataSeries;
654 varRequest.m_DataSeries = dataSeries;
647 varRequest.m_CanUpdate = true;
655 varRequest.m_CanUpdate = true;
648 }
656 }
649 else {
657 else {
650 qCDebug(LOG_VariableController())
658 qCDebug(LOG_VariableController())
651 << tr("Impossible to acceptVariableRequest of a unknown variable id attached "
659 << tr("Impossible to acceptVariableRequest of a unknown variable id attached "
652 "to a variableRequestId")
660 "to a variableRequestId")
653 << varRequestId << varId;
661 << varRequestId << varId;
654 }
662 }
655 }
663 }
656 else {
664 else {
657 qCCritical(LOG_VariableController())
665 qCCritical(LOG_VariableController())
658 << tr("Impossible to acceptVariableRequest of a unknown variableRequestId")
666 << tr("Impossible to acceptVariableRequest of a unknown variableRequestId")
659 << varRequestId;
667 << varRequestId;
660 }
668 }
661
669
662 qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in QUEUE ?")
670 qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in QUEUE ?")
663 << varRequestIdQueue.size();
671 << varRequestIdQueue.size();
664 varRequestIdQueue.pop_front();
672 varRequestIdQueue.pop_front();
665 qCDebug(LOG_VariableController()) << tr("2: erase REQUEST in QUEUE ?")
673 qCDebug(LOG_VariableController()) << tr("2: erase REQUEST in QUEUE ?")
666 << varRequestIdQueue.size();
674 << varRequestIdQueue.size();
667 if (varRequestIdQueue.empty()) {
675 if (varRequestIdQueue.empty()) {
668 m_VarIdToVarRequestIdQueueMap.erase(varId);
676 m_VarIdToVarRequestIdQueueMap.erase(varId);
669 }
677 }
670 }
678 }
671 else {
679 else {
672 qCCritical(LOG_VariableController())
680 qCCritical(LOG_VariableController())
673 << tr("Impossible to acceptVariableRequest of a unknown variable id") << varId;
681 << tr("Impossible to acceptVariableRequest of a unknown variable id") << varId;
674 }
682 }
675
683
676 return varRequestId;
684 return varRequestId;
677 }
685 }
678
686
679 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
687 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
680 {
688 {
681
689
682 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
690 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
683 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
691 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
684 bool processVariableUpdate = true;
692 bool processVariableUpdate = true;
685 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
693 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
686 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
694 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
687 (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) && processVariableUpdate;
695 (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) && processVariableUpdate;
688 ++varIdToVarRequestMapIt) {
696 ++varIdToVarRequestMapIt) {
689 processVariableUpdate &= varIdToVarRequestMapIt->second.m_CanUpdate;
697 processVariableUpdate &= varIdToVarRequestMapIt->second.m_CanUpdate;
690 qCDebug(LOG_VariableController()) << tr("updateVariableRequest")
698 qCDebug(LOG_VariableController()) << tr("updateVariableRequest")
691 << processVariableUpdate;
699 << processVariableUpdate;
692 }
700 }
693
701
694 if (processVariableUpdate) {
702 if (processVariableUpdate) {
695 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
703 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
696 varIdToVarRequestMapIt != varIdToVarRequestMap.cend(); ++varIdToVarRequestMapIt) {
704 varIdToVarRequestMapIt != varIdToVarRequestMap.cend(); ++varIdToVarRequestMapIt) {
697 if (auto var = findVariable(varIdToVarRequestMapIt->first)) {
705 if (auto var = findVariable(varIdToVarRequestMapIt->first)) {
698 auto &varRequest = varIdToVarRequestMapIt->second;
706 auto &varRequest = varIdToVarRequestMapIt->second;
699 var->setRange(varRequest.m_RangeRequested);
707 var->setRange(varRequest.m_RangeRequested);
700 var->setCacheRange(varRequest.m_CacheRangeRequested);
708 var->setCacheRange(varRequest.m_CacheRangeRequested);
701 qCDebug(LOG_VariableController()) << tr("1: onDataProvided")
709 qCDebug(LOG_VariableController()) << tr("1: onDataProvided")
702 << varRequest.m_RangeRequested;
710 << varRequest.m_RangeRequested;
703 qCDebug(LOG_VariableController()) << tr("2: onDataProvided")
711 qCDebug(LOG_VariableController()) << tr("2: onDataProvided")
704 << varRequest.m_CacheRangeRequested;
712 << varRequest.m_CacheRangeRequested;
705 var->mergeDataSeries(varRequest.m_DataSeries);
713 var->mergeDataSeries(varRequest.m_DataSeries);
706 qCDebug(LOG_VariableController()) << tr("3: onDataProvided")
714 qCDebug(LOG_VariableController()) << tr("3: onDataProvided")
707 << varRequest.m_DataSeries->range();
715 << varRequest.m_DataSeries->range();
708 qCDebug(LOG_VariableController()) << tr("4: onDataProvided");
716 qCDebug(LOG_VariableController()) << tr("4: onDataProvided");
709
717
710 /// @todo MPL: confirm
718 /// @todo MPL: confirm
711 // Variable update is notified only if there is no pending request for it
719 // Variable update is notified only if there is no pending request for it
712 if (m_VarIdToVarRequestIdQueueMap.count(varIdToVarRequestMapIt->first) == 0) {
720 if (m_VarIdToVarRequestIdQueueMap.count(varIdToVarRequestMapIt->first) == 0) {
713 emit var->updated();
721 emit var->updated();
714 }
722 }
715 }
723 }
716 else {
724 else {
717 qCCritical(LOG_VariableController())
725 qCCritical(LOG_VariableController())
718 << tr("Impossible to update data to a null variable");
726 << tr("Impossible to update data to a null variable");
719 }
727 }
720 }
728 }
721
729
722 // cleaning varRequestId
730 // cleaning varRequestId
723 qCDebug(LOG_VariableController()) << tr("0: erase REQUEST in MAP ?")
731 qCDebug(LOG_VariableController()) << tr("0: erase REQUEST in MAP ?")
724 << m_VarRequestIdToVarIdVarRequestMap.size();
732 << m_VarRequestIdToVarIdVarRequestMap.size();
725 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
733 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
726 qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in MAP ?")
734 qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in MAP ?")
727 << m_VarRequestIdToVarIdVarRequestMap.size();
735 << m_VarRequestIdToVarIdVarRequestMap.size();
728 }
736 }
729 }
737 }
730 else {
738 else {
731 qCCritical(LOG_VariableController())
739 qCCritical(LOG_VariableController())
732 << tr("Cannot updateVariableRequest for a unknow varRequestId") << varRequestId;
740 << tr("Cannot updateVariableRequest for a unknow varRequestId") << varRequestId;
733 }
741 }
734 }
742 }
735
743
736 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
744 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
737 {
745 {
738 // cleaning varRequestId
746 // cleaning varRequestId
739 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
747 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
740
748
741 for (auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.begin();
749 for (auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.begin();
742 varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.end();) {
750 varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.end();) {
743 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
751 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
744 varRequestIdQueue.erase(
752 varRequestIdQueue.erase(
745 std::remove(varRequestIdQueue.begin(), varRequestIdQueue.end(), varRequestId),
753 std::remove(varRequestIdQueue.begin(), varRequestIdQueue.end(), varRequestId),
746 varRequestIdQueue.end());
754 varRequestIdQueue.end());
747 if (varRequestIdQueue.empty()) {
755 if (varRequestIdQueue.empty()) {
748 varIdToVarRequestIdQueueMapIt
756 varIdToVarRequestIdQueueMapIt
749 = m_VarIdToVarRequestIdQueueMap.erase(varIdToVarRequestIdQueueMapIt);
757 = m_VarIdToVarRequestIdQueueMap.erase(varIdToVarRequestIdQueueMapIt);
750 }
758 }
751 else {
759 else {
752 ++varIdToVarRequestIdQueueMapIt;
760 ++varIdToVarRequestIdQueueMapIt;
753 }
761 }
754 }
762 }
755 }
763 }
@@ -1,284 +1,290
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableModel.h>
2 #include <Variable/VariableModel.h>
3
3
4 #include <Common/DateUtils.h>
4 #include <Common/DateUtils.h>
5 #include <Common/StringUtils.h>
5 #include <Common/StringUtils.h>
6
6
7 #include <Data/IDataSeries.h>
7 #include <Data/IDataSeries.h>
8
8
9 #include <QSize>
9 #include <QSize>
10 #include <unordered_map>
10 #include <unordered_map>
11
11
12 Q_LOGGING_CATEGORY(LOG_VariableModel, "VariableModel")
12 Q_LOGGING_CATEGORY(LOG_VariableModel, "VariableModel")
13
13
14 namespace {
14 namespace {
15
15
16 // Column indexes
16 // Column indexes
17 const auto NAME_COLUMN = 0;
17 const auto NAME_COLUMN = 0;
18 const auto TSTART_COLUMN = 1;
18 const auto TSTART_COLUMN = 1;
19 const auto TEND_COLUMN = 2;
19 const auto TEND_COLUMN = 2;
20 const auto UNIT_COLUMN = 3;
20 const auto UNIT_COLUMN = 3;
21 const auto MISSION_COLUMN = 4;
21 const auto MISSION_COLUMN = 4;
22 const auto PLUGIN_COLUMN = 5;
22 const auto PLUGIN_COLUMN = 5;
23 const auto NB_COLUMNS = 6;
23 const auto NB_COLUMNS = 6;
24
24
25 // Column properties
25 // Column properties
26 const auto DEFAULT_HEIGHT = 25;
26 const auto DEFAULT_HEIGHT = 25;
27 const auto DEFAULT_WIDTH = 100;
27 const auto DEFAULT_WIDTH = 100;
28
28
29 struct ColumnProperties {
29 struct ColumnProperties {
30 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
30 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
31 int height = DEFAULT_HEIGHT)
31 int height = DEFAULT_HEIGHT)
32 : m_Name{name}, m_Width{width}, m_Height{height}
32 : m_Name{name}, m_Width{width}, m_Height{height}
33 {
33 {
34 }
34 }
35
35
36 QString m_Name;
36 QString m_Name;
37 int m_Width;
37 int m_Width;
38 int m_Height;
38 int m_Height;
39 };
39 };
40
40
41 const auto COLUMN_PROPERTIES = QHash<int, ColumnProperties>{
41 const auto COLUMN_PROPERTIES = QHash<int, ColumnProperties>{
42 {NAME_COLUMN, {QObject::tr("Name")}}, {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
42 {NAME_COLUMN, {QObject::tr("Name")}}, {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
43 {TEND_COLUMN, {QObject::tr("tEnd"), 180}}, {UNIT_COLUMN, {QObject::tr("Unit")}},
43 {TEND_COLUMN, {QObject::tr("tEnd"), 180}}, {UNIT_COLUMN, {QObject::tr("Unit")}},
44 {MISSION_COLUMN, {QObject::tr("Mission")}}, {PLUGIN_COLUMN, {QObject::tr("Plugin")}}};
44 {MISSION_COLUMN, {QObject::tr("Mission")}}, {PLUGIN_COLUMN, {QObject::tr("Plugin")}}};
45
45
46 /// Format for datetimes
46 /// Format for datetimes
47 const auto DATETIME_FORMAT = QStringLiteral("dd/MM/yyyy \nhh:mm:ss:zzz");
47 const auto DATETIME_FORMAT = QStringLiteral("dd/MM/yyyy \nhh:mm:ss:zzz");
48
48
49 QString uniqueName(const QString &defaultName,
49 QString uniqueName(const QString &defaultName,
50 const std::vector<std::shared_ptr<Variable> > &variables)
50 const std::vector<std::shared_ptr<Variable> > &variables)
51 {
51 {
52 auto forbiddenNames = std::vector<QString>(variables.size());
52 auto forbiddenNames = std::vector<QString>(variables.size());
53 std::transform(variables.cbegin(), variables.cend(), forbiddenNames.begin(),
53 std::transform(variables.cbegin(), variables.cend(), forbiddenNames.begin(),
54 [](const auto &variable) { return variable->name(); });
54 [](const auto &variable) { return variable->name(); });
55 auto uniqueName = StringUtils::uniqueName(defaultName, forbiddenNames);
55 auto uniqueName = StringUtils::uniqueName(defaultName, forbiddenNames);
56 Q_ASSERT(!uniqueName.isEmpty());
56 Q_ASSERT(!uniqueName.isEmpty());
57
57
58 return uniqueName;
58 return uniqueName;
59 }
59 }
60
60
61 } // namespace
61 } // namespace
62
62
63 struct VariableModel::VariableModelPrivate {
63 struct VariableModel::VariableModelPrivate {
64 /// Variables created in SciQlop
64 /// Variables created in SciQlop
65 std::vector<std::shared_ptr<Variable> > m_Variables;
65 std::vector<std::shared_ptr<Variable> > m_Variables;
66 std::unordered_map<std::shared_ptr<Variable>, double> m_VariableToProgress;
66 std::unordered_map<std::shared_ptr<Variable>, double> m_VariableToProgress;
67
67
68 /// Return the row index of the variable. -1 if it's not found
68 /// Return the row index of the variable. -1 if it's not found
69 int indexOfVariable(Variable *variable) const noexcept;
69 int indexOfVariable(Variable *variable) const noexcept;
70 };
70 };
71
71
72 VariableModel::VariableModel(QObject *parent)
72 VariableModel::VariableModel(QObject *parent)
73 : QAbstractTableModel{parent}, impl{spimpl::make_unique_impl<VariableModelPrivate>()}
73 : QAbstractTableModel{parent}, impl{spimpl::make_unique_impl<VariableModelPrivate>()}
74 {
74 {
75 }
75 }
76
76
77 void VariableModel::addVariable(std::shared_ptr<Variable> variable) noexcept
77 void VariableModel::addVariable(std::shared_ptr<Variable> variable) noexcept
78 {
78 {
79 auto insertIndex = rowCount();
79 auto insertIndex = rowCount();
80 beginInsertRows({}, insertIndex, insertIndex);
80 beginInsertRows({}, insertIndex, insertIndex);
81
81
82 // Generates unique name for the variable
82 // Generates unique name for the variable
83 variable->setName(uniqueName(variable->name(), impl->m_Variables));
83 variable->setName(uniqueName(variable->name(), impl->m_Variables));
84
84
85 impl->m_Variables.push_back(variable);
85 impl->m_Variables.push_back(variable);
86 connect(variable.get(), &Variable::updated, this, &VariableModel::onVariableUpdated);
86 connect(variable.get(), &Variable::updated, this, &VariableModel::onVariableUpdated);
87
87
88 endInsertRows();
88 endInsertRows();
89 }
89 }
90
90
91 bool VariableModel::containsVariable(std::shared_ptr<Variable> variable) const noexcept
92 {
93 auto end = impl->m_Variables.cend();
94 return std::find(impl->m_Variables.cbegin(), end, variable) != end;
95 }
96
91 std::shared_ptr<Variable> VariableModel::createVariable(const QString &name,
97 std::shared_ptr<Variable> VariableModel::createVariable(const QString &name,
92 const SqpRange &dateTime,
98 const SqpRange &dateTime,
93 const QVariantHash &metadata) noexcept
99 const QVariantHash &metadata) noexcept
94 {
100 {
95 auto variable = std::make_shared<Variable>(name, dateTime, metadata);
101 auto variable = std::make_shared<Variable>(name, dateTime, metadata);
96 addVariable(variable);
102 addVariable(variable);
97
103
98 return variable;
104 return variable;
99 }
105 }
100
106
101 void VariableModel::deleteVariable(std::shared_ptr<Variable> variable) noexcept
107 void VariableModel::deleteVariable(std::shared_ptr<Variable> variable) noexcept
102 {
108 {
103 if (!variable) {
109 if (!variable) {
104 qCCritical(LOG_Variable()) << "Can't delete a null variable from the model";
110 qCCritical(LOG_Variable()) << "Can't delete a null variable from the model";
105 return;
111 return;
106 }
112 }
107
113
108 // Finds variable in the model
114 // Finds variable in the model
109 auto begin = impl->m_Variables.cbegin();
115 auto begin = impl->m_Variables.cbegin();
110 auto end = impl->m_Variables.cend();
116 auto end = impl->m_Variables.cend();
111 auto it = std::find(begin, end, variable);
117 auto it = std::find(begin, end, variable);
112 if (it != end) {
118 if (it != end) {
113 auto removeIndex = std::distance(begin, it);
119 auto removeIndex = std::distance(begin, it);
114
120
115 // Deletes variable
121 // Deletes variable
116 beginRemoveRows({}, removeIndex, removeIndex);
122 beginRemoveRows({}, removeIndex, removeIndex);
117 impl->m_Variables.erase(it);
123 impl->m_Variables.erase(it);
118 endRemoveRows();
124 endRemoveRows();
119 }
125 }
120 else {
126 else {
121 qCritical(LOG_VariableModel())
127 qCritical(LOG_VariableModel())
122 << tr("Can't delete variable %1 from the model: the variable is not in the model")
128 << tr("Can't delete variable %1 from the model: the variable is not in the model")
123 .arg(variable->name());
129 .arg(variable->name());
124 }
130 }
125
131
126 // Removes variable from progress map
132 // Removes variable from progress map
127 impl->m_VariableToProgress.erase(variable);
133 impl->m_VariableToProgress.erase(variable);
128 }
134 }
129
135
130
136
131 std::shared_ptr<Variable> VariableModel::variable(int index) const
137 std::shared_ptr<Variable> VariableModel::variable(int index) const
132 {
138 {
133 return (index >= 0 && index < impl->m_Variables.size()) ? impl->m_Variables[index] : nullptr;
139 return (index >= 0 && index < impl->m_Variables.size()) ? impl->m_Variables[index] : nullptr;
134 }
140 }
135
141
136 std::vector<std::shared_ptr<Variable> > VariableModel::variables() const
142 std::vector<std::shared_ptr<Variable> > VariableModel::variables() const
137 {
143 {
138 return impl->m_Variables;
144 return impl->m_Variables;
139 }
145 }
140
146
141 void VariableModel::setDataProgress(std::shared_ptr<Variable> variable, double progress)
147 void VariableModel::setDataProgress(std::shared_ptr<Variable> variable, double progress)
142 {
148 {
143 if (progress > 0.0) {
149 if (progress > 0.0) {
144 impl->m_VariableToProgress[variable] = progress;
150 impl->m_VariableToProgress[variable] = progress;
145 }
151 }
146 else {
152 else {
147 impl->m_VariableToProgress.erase(variable);
153 impl->m_VariableToProgress.erase(variable);
148 }
154 }
149 auto modelIndex = createIndex(impl->indexOfVariable(variable.get()), NAME_COLUMN);
155 auto modelIndex = createIndex(impl->indexOfVariable(variable.get()), NAME_COLUMN);
150
156
151 emit dataChanged(modelIndex, modelIndex);
157 emit dataChanged(modelIndex, modelIndex);
152 }
158 }
153
159
154 int VariableModel::columnCount(const QModelIndex &parent) const
160 int VariableModel::columnCount(const QModelIndex &parent) const
155 {
161 {
156 Q_UNUSED(parent);
162 Q_UNUSED(parent);
157
163
158 return NB_COLUMNS;
164 return NB_COLUMNS;
159 }
165 }
160
166
161 int VariableModel::rowCount(const QModelIndex &parent) const
167 int VariableModel::rowCount(const QModelIndex &parent) const
162 {
168 {
163 Q_UNUSED(parent);
169 Q_UNUSED(parent);
164
170
165 return impl->m_Variables.size();
171 return impl->m_Variables.size();
166 }
172 }
167
173
168 QVariant VariableModel::data(const QModelIndex &index, int role) const
174 QVariant VariableModel::data(const QModelIndex &index, int role) const
169 {
175 {
170 if (!index.isValid()) {
176 if (!index.isValid()) {
171 return QVariant{};
177 return QVariant{};
172 }
178 }
173
179
174 if (index.row() < 0 || index.row() >= rowCount()) {
180 if (index.row() < 0 || index.row() >= rowCount()) {
175 return QVariant{};
181 return QVariant{};
176 }
182 }
177
183
178 if (role == Qt::DisplayRole) {
184 if (role == Qt::DisplayRole) {
179 if (auto variable = impl->m_Variables.at(index.row()).get()) {
185 if (auto variable = impl->m_Variables.at(index.row()).get()) {
180 switch (index.column()) {
186 switch (index.column()) {
181 case NAME_COLUMN:
187 case NAME_COLUMN:
182 return variable->name();
188 return variable->name();
183 case TSTART_COLUMN: {
189 case TSTART_COLUMN: {
184 auto range = variable->realRange();
190 auto range = variable->realRange();
185 return range != INVALID_RANGE
191 return range != INVALID_RANGE
186 ? DateUtils::dateTime(range.m_TStart).toString(DATETIME_FORMAT)
192 ? DateUtils::dateTime(range.m_TStart).toString(DATETIME_FORMAT)
187 : QVariant{};
193 : QVariant{};
188 }
194 }
189 case TEND_COLUMN: {
195 case TEND_COLUMN: {
190 auto range = variable->realRange();
196 auto range = variable->realRange();
191 return range != INVALID_RANGE
197 return range != INVALID_RANGE
192 ? DateUtils::dateTime(range.m_TEnd).toString(DATETIME_FORMAT)
198 ? DateUtils::dateTime(range.m_TEnd).toString(DATETIME_FORMAT)
193 : QVariant{};
199 : QVariant{};
194 }
200 }
195 case UNIT_COLUMN:
201 case UNIT_COLUMN:
196 return variable->metadata().value(QStringLiteral("units"));
202 return variable->metadata().value(QStringLiteral("units"));
197 case MISSION_COLUMN:
203 case MISSION_COLUMN:
198 return variable->metadata().value(QStringLiteral("mission"));
204 return variable->metadata().value(QStringLiteral("mission"));
199 case PLUGIN_COLUMN:
205 case PLUGIN_COLUMN:
200 return variable->metadata().value(QStringLiteral("plugin"));
206 return variable->metadata().value(QStringLiteral("plugin"));
201 default:
207 default:
202 // No action
208 // No action
203 break;
209 break;
204 }
210 }
205
211
206 qWarning(LOG_VariableModel())
212 qWarning(LOG_VariableModel())
207 << tr("Can't get data (unknown column %1)").arg(index.column());
213 << tr("Can't get data (unknown column %1)").arg(index.column());
208 }
214 }
209 else {
215 else {
210 qWarning(LOG_VariableModel()) << tr("Can't get data (no variable)");
216 qWarning(LOG_VariableModel()) << tr("Can't get data (no variable)");
211 }
217 }
212 }
218 }
213 else if (role == VariableRoles::ProgressRole) {
219 else if (role == VariableRoles::ProgressRole) {
214 if (auto variable = impl->m_Variables.at(index.row())) {
220 if (auto variable = impl->m_Variables.at(index.row())) {
215
221
216 auto it = impl->m_VariableToProgress.find(variable);
222 auto it = impl->m_VariableToProgress.find(variable);
217 if (it != impl->m_VariableToProgress.cend()) {
223 if (it != impl->m_VariableToProgress.cend()) {
218 return it->second;
224 return it->second;
219 }
225 }
220 }
226 }
221 }
227 }
222
228
223 return QVariant{};
229 return QVariant{};
224 }
230 }
225
231
226 QVariant VariableModel::headerData(int section, Qt::Orientation orientation, int role) const
232 QVariant VariableModel::headerData(int section, Qt::Orientation orientation, int role) const
227 {
233 {
228 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
234 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
229 return QVariant{};
235 return QVariant{};
230 }
236 }
231
237
232 if (orientation == Qt::Horizontal) {
238 if (orientation == Qt::Horizontal) {
233 auto propertiesIt = COLUMN_PROPERTIES.find(section);
239 auto propertiesIt = COLUMN_PROPERTIES.find(section);
234 if (propertiesIt != COLUMN_PROPERTIES.cend()) {
240 if (propertiesIt != COLUMN_PROPERTIES.cend()) {
235 // Role is either DisplayRole or SizeHintRole
241 // Role is either DisplayRole or SizeHintRole
236 return (role == Qt::DisplayRole)
242 return (role == Qt::DisplayRole)
237 ? QVariant{propertiesIt->m_Name}
243 ? QVariant{propertiesIt->m_Name}
238 : QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
244 : QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
239 }
245 }
240 else {
246 else {
241 qWarning(LOG_VariableModel())
247 qWarning(LOG_VariableModel())
242 << tr("Can't get header data (unknown column %1)").arg(section);
248 << tr("Can't get header data (unknown column %1)").arg(section);
243 }
249 }
244 }
250 }
245
251
246 return QVariant{};
252 return QVariant{};
247 }
253 }
248
254
249 void VariableModel::abortProgress(const QModelIndex &index)
255 void VariableModel::abortProgress(const QModelIndex &index)
250 {
256 {
251 if (auto variable = impl->m_Variables.at(index.row())) {
257 if (auto variable = impl->m_Variables.at(index.row())) {
252 emit abortProgessRequested(variable);
258 emit abortProgessRequested(variable);
253 }
259 }
254 }
260 }
255
261
256 void VariableModel::onVariableUpdated() noexcept
262 void VariableModel::onVariableUpdated() noexcept
257 {
263 {
258 // Finds variable that has been updated in the model
264 // Finds variable that has been updated in the model
259 if (auto updatedVariable = dynamic_cast<Variable *>(sender())) {
265 if (auto updatedVariable = dynamic_cast<Variable *>(sender())) {
260 auto updatedVariableIndex = impl->indexOfVariable(updatedVariable);
266 auto updatedVariableIndex = impl->indexOfVariable(updatedVariable);
261
267
262 if (updatedVariableIndex > -1) {
268 if (updatedVariableIndex > -1) {
263 emit dataChanged(createIndex(updatedVariableIndex, 0),
269 emit dataChanged(createIndex(updatedVariableIndex, 0),
264 createIndex(updatedVariableIndex, columnCount() - 1));
270 createIndex(updatedVariableIndex, columnCount() - 1));
265 }
271 }
266 }
272 }
267 }
273 }
268
274
269 int VariableModel::VariableModelPrivate::indexOfVariable(Variable *variable) const noexcept
275 int VariableModel::VariableModelPrivate::indexOfVariable(Variable *variable) const noexcept
270 {
276 {
271 auto begin = std::cbegin(m_Variables);
277 auto begin = std::cbegin(m_Variables);
272 auto end = std::cend(m_Variables);
278 auto end = std::cend(m_Variables);
273 auto it
279 auto it
274 = std::find_if(begin, end, [variable](const auto &var) { return var.get() == variable; });
280 = std::find_if(begin, end, [variable](const auto &var) { return var.get() == variable; });
275
281
276 if (it != end) {
282 if (it != end) {
277 // Gets the index of the variable in the model: we assume here that views have the same
283 // Gets the index of the variable in the model: we assume here that views have the same
278 // order as the model
284 // order as the model
279 return std::distance(begin, it);
285 return std::distance(begin, it);
280 }
286 }
281 else {
287 else {
282 return -1;
288 return -1;
283 }
289 }
284 }
290 }
General Comments 0
You need to be logged in to leave comments. Login now