##// END OF EJS Templates
commit
Alexandre Leroux -
r684:90684a2a46fa
parent child
Show More
@@ -1,58 +1,59
1 1 #ifndef SCIQLOP_VARIABLEACQUISITIONWORKER_H
2 2 #define SCIQLOP_VARIABLEACQUISITIONWORKER_H
3 3
4 4 #include "CoreGlobal.h"
5 5
6 6 #include <Data/DataProviderParameters.h>
7 7 #include <QLoggingCategory>
8 8 #include <QObject>
9 9 #include <QUuid>
10 10
11 11 #include <Data/AcquisitionDataPacket.h>
12 12 #include <Data/IDataSeries.h>
13 13 #include <Data/SqpRange.h>
14 14 #include <Data/VariableRequest.h>
15 15
16 16 #include <QLoggingCategory>
17 17
18 18 #include <Common/spimpl.h>
19 19
20 20 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableAcquisitionWorker)
21 21
22 22 class Variable;
23 23 class IDataProvider;
24 24
25 25 /// This class aims to handle all acquisition request
26 26 class SCIQLOP_CORE_EXPORT VariableAcquisitionWorker : public QObject {
27 27 Q_OBJECT
28 28 public:
29 29 explicit VariableAcquisitionWorker(QObject *parent = 0);
30 30 virtual ~VariableAcquisitionWorker();
31 31
32 void cancelVariableRequest(std::shared_ptr<Variable> variable);
32 33 void pushVariableRequest(std::shared_ptr<Variable> variable, VariableRequest request);
33 34
34 35 void abortProgressRequested(QUuid vIdentifier);
35 36
36 37 void initialize();
37 38 void finalize();
38 39 signals:
39 40 void dataProvided(std::shared_ptr<Variable> variable, VariableRequest request);
40 41 void variableRequestInProgress(QUuid vIdentifier, double progress);
41 42
42 43 public slots:
43 44 void onDataAcquired(QUuid acquisitionId, std::shared_ptr<IDataSeries> dataSeries,
44 45 SqpRange range);
45 46 void onVariableAcquisitionCanceled(QUuid acqIdentifier);
46 47 void onVariableRetrieveDataInProgress(QUuid acqIdentifier, double progress);
47 48
48 49 private:
49 50 void waitForFinish();
50 51
51 52 class VariableAcquisitionWorkerPrivate;
52 53 spimpl::unique_impl_ptr<VariableAcquisitionWorkerPrivate> impl;
53 54
54 55 private slots:
55 56 void executeAcquisition(QUuid acquisitionId);
56 57 };
57 58
58 59 #endif // SCIQLOP_VARIABLEACQUISITIONWORKER_H
@@ -1,68 +1,67
1 1 #ifndef SCIQLOP_VARIABLESYNCHRONIZER_H
2 2 #define SCIQLOP_VARIABLESYNCHRONIZER_H
3 3
4 4 #include "CoreGlobal.h"
5 5
6 6 #include <Common/spimpl.h>
7 7
8 8 #include <QLoggingCategory>
9 9 #include <QUuid>
10 10
11 11 #include <memory>
12 12 #include <set>
13 13
14 14 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableSynchronizer)
15 15
16 16 class Variable;
17 17
18 18 /**
19 19 * @brief The VariableAcquisitionWorker class handles synchronization between variables
20 20 */
21 21 class SCIQLOP_CORE_EXPORT VariableSynchronizer : public QObject {
22 22 Q_OBJECT
23 23 public:
24 24 using GroupId = QUuid;
25 25
26 26 explicit VariableSynchronizer(QObject *parent = 0);
27 27
28 28 /**
29 29 * Adds a synchronization group under the identifier passed as a parameter. If a group with this
30 30 * identifier already exists, the method does nothing.
31 31 * @param groupId the group identifier
32 32 */
33 33 void addGroup(GroupId groupId) noexcept;
34 34
35 35 /**
36 36 * Adds a variable to a synchronization group. If the variable is already registered under
37 37 * another group, or the synchronization doesn't exist, the method does nothing
38 38 * @param variable the variable to synchronize
39 39 * @param groupId the synchronization group identifier
40 40 */
41 41 void addVariable(std::shared_ptr<Variable> variable, GroupId groupId) noexcept;
42 42
43 43 /**
44 44 * Removes the synchronization group under the identifier passed as a parameter. If no group
45 45 * exists with this identifier, the method does nothing.
46 46 * @param groupId the group identifier
47 47 */
48 48 void removeGroup(GroupId groupId) noexcept;
49 49
50 50 /**
51 * Removes a variable from a synchronization group. If the synchronization group doesn't exist
52 * or if the variable isn't in it, the method does nothing
51 * Removes a variable from its synchronization group. If the variable isn't in a synchronization
52 * group, the method does nothing
53 53 * @param variable the variable to desynchronize
54 * @param groupId the synchronization group identifier
55 54 */
56 void removeVariable(std::shared_ptr<Variable> variable, GroupId groupId) noexcept;
55 void removeVariable(std::shared_ptr<Variable> variable) noexcept;
57 56
58 57 /// @return the variables in the same group than the variable passed as a parameter (including
59 58 /// the variable)
60 59 std::set<std::shared_ptr<Variable> >
61 60 synchronizedVariables(std::shared_ptr<Variable> variable) const noexcept;
62 61
63 62 private:
64 63 class VariableSynchronizerPrivate;
65 64 spimpl::unique_impl_ptr<VariableSynchronizerPrivate> impl;
66 65 };
67 66
68 67 #endif // SCIQLOP_VARIABLESYNCHRONIZER_H
@@ -1,189 +1,192
1 1 #include "Variable/VariableAcquisitionWorker.h"
2 2
3 3 #include "Variable/Variable.h"
4 4
5 5 #include <Data/IDataProvider.h>
6 6 #include <Data/SqpRange.h>
7 7 #include <unordered_map>
8 8 #include <utility>
9 9
10 10 #include <QMutex>
11 11 #include <QReadWriteLock>
12 12 #include <QThread>
13 13 #include <QtConcurrent/QtConcurrent>
14 14
15 15 Q_LOGGING_CATEGORY(LOG_VariableAcquisitionWorker, "VariableAcquisitionWorker")
16 16
17 17 namespace {
18 18
19 19 using AcquisitionId = QUuid;
20 20 using VariableId = QUuid;
21 21
22 22 struct Acquisition {
23 23 std::shared_ptr<Variable> m_Variable{nullptr};
24 24 VariableRequest m_Request{};
25 25 AcquisitionId m_Id{QUuid::createUuid()};
26 26 };
27 27
28 28 } // namespace
29 29
30 30 struct VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate {
31 31
32 32 explicit VariableAcquisitionWorkerPrivate() : m_Lock{QReadWriteLock::Recursive} {}
33 33
34 34 void lockRead() { m_Lock.lockForRead(); }
35 35 void lockWrite() { m_Lock.lockForWrite(); }
36 36 void unlock() { m_Lock.unlock(); }
37 37
38 38 void eraseAcquisition(AcquisitionId id)
39 39 {
40 40 auto it = m_Acquisitions.find(id);
41 41 if (it != m_Acquisitions.end()) {
42 42 // Removes from index
43 43 m_AcquisitionsIndex.erase(it->second.m_Variable);
44 44
45 45 // Removes request
46 46 m_Acquisitions.erase(it);
47 47 }
48 48 }
49 49
50 50 std::map<AcquisitionId, Acquisition>::iterator insertAcquisition(Acquisition acquisition)
51 51 {
52 52 auto variable = acquisition.m_Variable;
53 53
54 54 // Inserts acquisition
55 55 auto result
56 56 = m_Acquisitions.insert(std::make_pair(acquisition.m_Id, std::move(acquisition)));
57 57 if (result.second) {
58 58 // Inserts index
59 59 m_AcquisitionsIndex[variable] = &result.first->second;
60 60 return result.first;
61 61 }
62 62 else {
63 63 return m_Acquisitions.end();
64 64 }
65 65 }
66 66
67 67 QMutex m_WorkingMutex;
68 68 QReadWriteLock m_Lock;
69 69
70 70 std::map<AcquisitionId, Acquisition> m_Acquisitions;
71 71 std::map<std::shared_ptr<Variable>, Acquisition *> m_AcquisitionsIndex;
72 72 };
73 73
74 74 VariableAcquisitionWorker::VariableAcquisitionWorker(QObject *parent)
75 75 : QObject{parent}, impl{spimpl::make_unique_impl<VariableAcquisitionWorkerPrivate>()}
76 76 {
77 77 }
78 78
79 79 VariableAcquisitionWorker::~VariableAcquisitionWorker()
80 80 {
81 81 qCInfo(LOG_VariableAcquisitionWorker())
82 82 << tr("VariableAcquisitionWorker destruction") << QThread::currentThread();
83 83 this->waitForFinish();
84 84 }
85 85
86 void VariableAcquisitionWorker::cancelVariableRequest(std::shared_ptr<Variable> variable)
87 {
88 /// @todo ALX
89 }
90
86 91 void VariableAcquisitionWorker::pushVariableRequest(std::shared_ptr<Variable> variable,
87 92 VariableRequest request)
88 93 {
89 94 impl->lockWrite();
90 95
91 96 // Checks if there is a current request for variable
92 97 auto oldAcquisitionIt = impl->m_AcquisitionsIndex.find(variable);
93 98 if (oldAcquisitionIt != impl->m_AcquisitionsIndex.cend()) {
94 99 auto &oldAcquisition = *oldAcquisitionIt->second;
95 100 /// @todo ALX
96 101 // QtConcurrent::run(
97 102 // [ provider = request->m_Provider, acqIdentifier = request->m_AcqIdentifier ]()
98 103 // {
99 104 // provider->requestDataAborting(acqIdentifier);
100 105 // });
101 106
102 107 impl->eraseAcquisition(oldAcquisition.m_Id);
103 108 }
104 109
105 110 // Sets request for variable
106 111 Acquisition newAcquisition{variable, std::move(request)};
107 112 auto newAcquisitionIt = impl->insertAcquisition(std::move(newAcquisition));
108 113 if (newAcquisitionIt != impl->m_Acquisitions.end()) {
109 114 impl->unlock();
110 115
111 116 QMetaObject::invokeMethod(this, "executeAcquisition", Qt::QueuedConnection,
112 117 Q_ARG(QUuid, newAcquisitionIt->first));
113 118 }
114 119 else {
115 120 impl->unlock();
116 121 }
117 122 }
118 123
119 124 void VariableAcquisitionWorker::abortProgressRequested(QUuid vIdentifier)
120 125 {
121 126 // TODO
122 127 }
123 128
124 129 void VariableAcquisitionWorker::onVariableRetrieveDataInProgress(QUuid acqIdentifier,
125 130 double progress)
126 131 {
127 132 // TODO
128 133 }
129 134
130 135 void VariableAcquisitionWorker::onDataAcquired(QUuid acquisitionId,
131 136 std::shared_ptr<IDataSeries> dataSeries,
132 137 SqpRange range)
133 138 {
134 139 impl->lockWrite();
135 140
136 141 auto it = impl->m_Acquisitions.find(acquisitionId);
137 142 if (it != impl->m_Acquisitions.cend()) {
138 143 auto &acquisition = it->second;
139 144 auto &request = acquisition.m_Request;
140 145
141 qInfo(LOG_VariableAcquisitionWorker()) << "Data acquired for " << printRange(range);
142
143 146 // Store the result
144 147 request.addResult(dataSeries);
145 148
146 149 if (request.isFinished()) {
147 150 emit dataProvided(acquisition.m_Variable, std::move(request));
148 151 impl->eraseAcquisition(acquisitionId);
149 152 }
150 153 }
151 154 impl->unlock();
152 155 }
153 156
154 157 void VariableAcquisitionWorker::onVariableAcquisitionCanceled(QUuid acqIdentifier)
155 158 {
156 159 }
157 160
158 161 void VariableAcquisitionWorker::initialize()
159 162 {
160 163 qCDebug(LOG_VariableAcquisitionWorker())
161 164 << tr("VariableAcquisitionWorker init") << QThread::currentThread();
162 165 impl->m_WorkingMutex.lock();
163 166 qCDebug(LOG_VariableAcquisitionWorker()) << tr("VariableAcquisitionWorker init END");
164 167 }
165 168
166 169 void VariableAcquisitionWorker::finalize()
167 170 {
168 171 impl->m_WorkingMutex.unlock();
169 172 }
170 173
171 174 void VariableAcquisitionWorker::waitForFinish()
172 175 {
173 176 QMutexLocker locker{&impl->m_WorkingMutex};
174 177 }
175 178
176 179 void VariableAcquisitionWorker::executeAcquisition(QUuid acquisitionId)
177 180 {
178 181 impl->lockRead();
179 182 auto it = impl->m_Acquisitions.find(acquisitionId);
180 183 if (it != impl->m_Acquisitions.cend()) {
181 184 auto &request = it->second.m_Request;
182 185 impl->unlock();
183 186 request.m_Provider->requestDataLoading(acquisitionId, request.m_ProviderParameters);
184 187 }
185 188 else {
186 189 impl->unlock();
187 190 // TODO log no acqIdentifier recognized
188 191 }
189 192 }
@@ -1,434 +1,442
1 1 #include <Variable/Variable.h>
2 2 #include <Variable/VariableAcquisitionWorker.h>
3 3 #include <Variable/VariableCacheStrategy.h>
4 4 #include <Variable/VariableController.h>
5 5 #include <Variable/VariableModel.h>
6 6 #include <Variable/VariableSynchronizer.h>
7 7
8 8 #include <Data/AcquisitionUtils.h>
9 9 #include <Data/DataProviderParameters.h>
10 10 #include <Data/IDataProvider.h>
11 11 #include <Data/IDataSeries.h>
12 12 #include <Data/VariableRequest.h>
13 13 #include <Time/TimeController.h>
14 14
15 15 #include <QMutex>
16 16 #include <QThread>
17 17 #include <QUuid>
18 18 #include <QtCore/QItemSelectionModel>
19 19
20 20 #include <unordered_map>
21 21
22 22 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
23 23
24 24 namespace {
25 25
26 26 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
27 27 const SqpRange &oldGraphRange)
28 28 {
29 29 auto zoomType = AcquisitionUtils::getZoomType(graphRange, oldGraphRange);
30 30
31 31 auto varRangeRequested = varRange;
32 32 switch (zoomType) {
33 33 case AcquisitionZoomType::ZoomIn: {
34 34 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
35 35 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
36 36 varRangeRequested.m_TStart += deltaLeft;
37 37 varRangeRequested.m_TEnd -= deltaRight;
38 38 break;
39 39 }
40 40
41 41 case AcquisitionZoomType::ZoomOut: {
42 42 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
43 43 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
44 44 varRangeRequested.m_TStart -= deltaLeft;
45 45 varRangeRequested.m_TEnd += deltaRight;
46 46 break;
47 47 }
48 48 case AcquisitionZoomType::PanRight: {
49 49 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
50 50 varRangeRequested.m_TStart += deltaRight;
51 51 varRangeRequested.m_TEnd += deltaRight;
52 52 break;
53 53 }
54 54 case AcquisitionZoomType::PanLeft: {
55 55 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
56 56 varRangeRequested.m_TStart -= deltaLeft;
57 57 varRangeRequested.m_TEnd -= deltaLeft;
58 58 break;
59 59 }
60 60 case AcquisitionZoomType::Unknown: {
61 61 qCCritical(LOG_VariableController())
62 62 << VariableController::tr("Impossible to synchronize: zoom type unknown");
63 63 break;
64 64 }
65 65 default:
66 66 qCCritical(LOG_VariableController()) << VariableController::tr(
67 67 "Impossible to synchronize: zoom type not take into account");
68 68 // No action
69 69 break;
70 70 }
71 71
72 72 return varRangeRequested;
73 73 }
74 74 } // namespace
75 75
76 76 struct VariableController::VariableControllerPrivate {
77 77 explicit VariableControllerPrivate(VariableController *parent)
78 78 : m_WorkingMutex{},
79 79 m_VariableModel{new VariableModel{parent}},
80 80 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
81 81 m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
82 82 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
83 83 m_VariableSynchronizer{std::make_unique<VariableSynchronizer>()},
84 84 q{parent}
85 85 {
86 86 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
87 87 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
88 88 }
89 89
90 90 virtual ~VariableControllerPrivate()
91 91 {
92 92 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
93 93 m_VariableAcquisitionWorkerThread.quit();
94 94 m_VariableAcquisitionWorkerThread.wait();
95 95 }
96 96
97 97 void processRequest(std::shared_ptr<Variable> variable, const SqpRange &rangeRequested)
98 98 {
99 99 Q_ASSERT(variable != nullptr);
100 100
101 101 if (!m_VariableModel->containsVariable(variable)) {
102 102 qCCritical(LOG_VariableController())
103 103 << QObject::tr("Can't process request for variable %1: variable is not registered")
104 104 .arg(variable->name());
105 105 return;
106 106 }
107 107
108 108 variable->setRange(rangeRequested);
109 109
110 110 // Gets ranges in/out of variable range
111 111 auto requestRange
112 112 = m_VariableCacheStrategy->computeStrategyRanges(variable->range(), rangeRequested);
113 113 auto notInCacheRanges = variable->provideNotInCacheRangeList(requestRange.second);
114 114
115 115 // Creates request for out-of-cache ranges
116 116 if (!notInCacheRanges.isEmpty()) {
117 117 // Gets provider for request
118 118 if (auto provider = m_Providers.at(variable)) {
119 119 DataProviderParameters providerParameters{std::move(notInCacheRanges),
120 120 variable->metadata()};
121 121 VariableRequest request{requestRange.first, requestRange.second, provider,
122 122 std::move(providerParameters)};
123 123 m_VariableAcquisitionWorker->pushVariableRequest(variable, std::move(request));
124 124 }
125 125
126 126 // Calls UI update for in-cache range
127 127 auto inCacheRanges = variable->provideInCacheRangeList(requestRange.second);
128 128 if (!inCacheRanges.isEmpty()) {
129 129 emit q->updateVarDisplaying(variable, inCacheRanges.first());
130 130 }
131 131 }
132 132 else {
133 133 // No request to make: we simply update variable ranges
134 134 variable->setCacheRange(requestRange.second);
135 135 emit variable->updated();
136 136 }
137 137 }
138 138
139 139 void registerProvider(std::shared_ptr<IDataProvider> provider)
140 140 {
141 141 Q_ASSERT(provider != nullptr);
142 142 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
143 143 &VariableAcquisitionWorker::onDataAcquired);
144 144 connect(provider.get(), &IDataProvider::dataProvidedProgress,
145 145 m_VariableAcquisitionWorker.get(),
146 146 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
147 147 }
148 148
149 149 QMutex m_WorkingMutex;
150 150 /// Variable model. The VariableController has the ownership
151 151 VariableModel *m_VariableModel;
152 152 QItemSelectionModel *m_VariableSelectionModel;
153 153
154 154 TimeController *m_TimeController{nullptr};
155 155 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
156 156 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
157 157 QThread m_VariableAcquisitionWorkerThread;
158 158
159 159 /// Handler for variables synchronization
160 160 std::unique_ptr<VariableSynchronizer> m_VariableSynchronizer;
161 161
162 162 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> > m_Providers;
163 163
164 164 VariableController *q;
165 165 };
166 166
167 167 VariableController::VariableController(QObject *parent)
168 168 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
169 169 {
170 170 qCDebug(LOG_VariableController())
171 171 << tr("VariableController construction") << QThread::currentThread();
172 172
173 173 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
174 174 &VariableController::onAbortProgressRequested);
175 175
176 176 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
177 177 &VariableController::onDataProvided);
178 178 connect(impl->m_VariableAcquisitionWorker.get(),
179 179 &VariableAcquisitionWorker::variableRequestInProgress, this,
180 180 &VariableController::onVariableRetrieveDataInProgress);
181 181
182 182 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
183 183 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
184 184 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
185 185 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
186 186
187 187
188 188 impl->m_VariableAcquisitionWorkerThread.start();
189 189 }
190 190
191 191 VariableController::~VariableController()
192 192 {
193 193 qCDebug(LOG_VariableController())
194 194 << tr("VariableController destruction") << QThread::currentThread();
195 195 this->waitForFinish();
196 196 }
197 197
198 198 VariableModel *VariableController::variableModel() noexcept
199 199 {
200 200 return impl->m_VariableModel;
201 201 }
202 202
203 203 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
204 204 {
205 205 return impl->m_VariableSelectionModel;
206 206 }
207 207
208 208 void VariableController::setTimeController(TimeController *timeController) noexcept
209 209 {
210 210 impl->m_TimeController = timeController;
211 211 }
212 212
213 213 std::shared_ptr<Variable>
214 214 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
215 215 {
216 216 if (impl->m_VariableModel->containsVariable(variable)) {
217 217 // Clones variable
218 218 auto duplicate = variable->clone();
219 219
220 220 // Adds clone to model
221 221 impl->m_VariableModel->addVariable(duplicate);
222 222
223 223 // Registers provider
224 224 auto variableProvider = impl->m_Providers.at(variable);
225 225 auto duplicateProvider = variableProvider != nullptr ? variableProvider->clone() : nullptr;
226 226
227 227 impl->m_Providers[duplicate] = duplicateProvider;
228 228 if (duplicateProvider) {
229 229 impl->registerProvider(duplicateProvider);
230 230 }
231 231
232 232 return duplicate;
233 233 }
234 234 else {
235 235 qCCritical(LOG_VariableController())
236 236 << tr("Can't create duplicate of variable %1: variable not registered in the model")
237 237 .arg(variable->name());
238 238 return nullptr;
239 239 }
240 240 }
241 241
242 242 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
243 243 {
244 244 if (!variable) {
245 245 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
246 246 return;
247 247 }
248 248
249 249 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
250 250 // make some treatments before the deletion
251 251 emit variableAboutToBeDeleted(variable);
252 252
253 // Deletes from synchronization group
254 impl->m_VariableSynchronizer->removeVariable(variable);
255
256 // Cancels pending requests
257 impl->m_VariableAcquisitionWorker->cancelVariableRequest(variable);
258
253 259 // Deletes provider
254 260 auto nbProvidersDeleted = impl->m_Providers.erase(variable);
255 261 qCDebug(LOG_VariableController())
256 262 << tr("Number of providers deleted for variable %1: %2")
257 263 .arg(variable->name(), QString::number(nbProvidersDeleted));
258 264
259 265
260 266 // Deletes from model
261 267 impl->m_VariableModel->deleteVariable(variable);
262 268 }
263 269
264 270 void VariableController::deleteVariables(
265 271 const QVector<std::shared_ptr<Variable> > &variables) noexcept
266 272 {
267 273 for (auto variable : qAsConst(variables)) {
268 274 deleteVariable(variable);
269 275 }
270 276 }
271 277
272 278 void VariableController::abortProgress(std::shared_ptr<Variable> variable)
273 279 {
274 280 }
275 281
276 282 std::shared_ptr<Variable>
277 283 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
278 284 std::shared_ptr<IDataProvider> provider) noexcept
279 285 {
280 286 if (!impl->m_TimeController) {
281 287 qCCritical(LOG_VariableController())
282 288 << tr("Impossible to create variable: The time controller is null");
283 289 return nullptr;
284 290 }
285 291
286 292 auto range = impl->m_TimeController->dateTime();
287 293
288 294 if (auto newVariable = impl->m_VariableModel->createVariable(name, range, metadata)) {
289 295 // Associate the provider
290 296 auto newVariableProvider = provider != nullptr ? provider->clone() : nullptr;
291 297 impl->m_Providers[newVariable] = newVariableProvider;
292 298 if (newVariableProvider) {
293 299 impl->registerProvider(newVariableProvider);
294 300 }
295 301
296 302 impl->processRequest(newVariable, range);
297 303
298 304 return newVariable;
299 305 }
300 306 }
301 307
302 308 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
303 309 {
304 310 // TODO check synchronisation and Rescale
305 311 qCDebug(LOG_VariableController())
306 312 << "VariableController::onDateTimeOnSelection" << QThread::currentThread()->objectName();
307 313 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
308 314 for (const auto &selectedRow : qAsConst(selectedRows)) {
309 315 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
310 316 selectedVariable->setRange(dateTime);
311 317 impl->processRequest(selectedVariable, dateTime);
312 318
313 319 // notify that rescale operation has to be done
314 320 emit rangeChanged(selectedVariable, dateTime);
315 321 }
316 322 }
317 323 }
318 324
319 325 void VariableController::onDataProvided(std::shared_ptr<Variable> variable, VariableRequest request)
320 326 {
321 327 Q_ASSERT(variable != nullptr);
322 328
323 329 if (!impl->m_VariableModel->containsVariable(variable)) {
324 330 qCCritical(LOG_VariableController())
325 331 << QObject::tr("Can't update date of variable %1: variable is not registered (anymore)")
326 332 .arg(variable->name());
327 333 return;
328 334 }
329 335
330 336 variable->setCacheRange(request.m_CacheRangeRequested);
331 337 variable->mergeDataSeries(request.m_Result);
332 338 emit variable->updated();
333 339 }
334 340
335 341 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
336 342 {
337 343 /// @todo ALX
338 344 // if (auto var = impl->findVariable(identifier)) {
339 345 // impl->m_VariableModel->setDataProgress(var, progress);
340 346 // }
341 347 // else {
342 348 // qCCritical(LOG_VariableController())
343 349 // << tr("Impossible to notify progression of a null variable");
344 350 // }
345 351 }
346 352
347 353 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
348 354 {
349 355 /// @todo ALX
350 356 // qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
351 357 // << QThread::currentThread()->objectName();
352 358
353 359 // auto it = impl->m_VariableToIdentifierMap.find(variable);
354 360 // if (it != impl->m_VariableToIdentifierMap.cend()) {
355 361 // impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
356 362 // }
357 363 // else {
358 364 // qCWarning(LOG_VariableController())
359 365 // << tr("Aborting progression of inexistant variable detected !!!")
360 366 // << QThread::currentThread()->objectName();
361 367 // }
362 368 }
363 369
364 370 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
365 371 {
366 372 impl->m_VariableSynchronizer->addGroup(synchronizationGroupId);
367 373 }
368 374
369 375 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
370 376 {
371 377 impl->m_VariableSynchronizer->removeGroup(synchronizationGroupId);
372 378 }
373 379
374 380 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
375 381 QUuid synchronizationGroupId)
376 382 {
377 383 impl->m_VariableSynchronizer->addVariable(variable, synchronizationGroupId);
378 384 }
379 385
380 386 void VariableController::desynchronize(std::shared_ptr<Variable> variable,
381 387 QUuid synchronizationGroupId)
382 388 {
383 impl->m_VariableSynchronizer->removeVariable(variable, synchronizationGroupId);
389 // As a variable can't be into more than one synchronization group,we don't need group id here
390 Q_UNUSED(synchronizationGroupId);
391 impl->m_VariableSynchronizer->removeVariable(variable);
384 392 }
385 393
386 394 void VariableController::onRequestDataLoading(const QVector<std::shared_ptr<Variable> > &variables,
387 395 const SqpRange &range, const SqpRange &oldRange,
388 396 bool synchronise)
389 397 {
390 398 // Set of variables that have been processed
391 399 std::set<std::shared_ptr<Variable> > processedVariables;
392 400 std::map<std::shared_ptr<Variable>, SqpRange> oldRanges;
393 401
394 402 // Process requests for all variables
395 403 for (const auto &var : variables) {
396 404 impl->processRequest(var, range);
397 405 processedVariables.insert(var);
398 406 }
399 407
400 408 // Handles synchronisation
401 409 if (synchronise) {
402 410 for (const auto &variable : variables) {
403 411 // Finds the variables in the same synchronization group
404 412 auto synchronizedVariables
405 413 = impl->m_VariableSynchronizer->synchronizedVariables(variable);
406 414 for (const auto &synchronizedVariable : synchronizedVariables) {
407 415 // Processes variable (if it hasn't been already processed)
408 416 if (processedVariables.count(synchronizedVariable) == 0) {
409 417 auto rangeRequested = computeSynchroRangeRequested(
410 418 synchronizedVariable->range(), range, oldRange);
411 419 impl->processRequest(synchronizedVariable, rangeRequested);
412 420 processedVariables.insert(synchronizedVariable);
413 421 }
414 422 }
415 423 }
416 424 }
417 425 }
418 426
419 427 void VariableController::initialize()
420 428 {
421 429 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
422 430 impl->m_WorkingMutex.lock();
423 431 qCDebug(LOG_VariableController()) << tr("VariableController init END");
424 432 }
425 433
426 434 void VariableController::finalize()
427 435 {
428 436 impl->m_WorkingMutex.unlock();
429 437 }
430 438
431 439 void VariableController::waitForFinish()
432 440 {
433 441 QMutexLocker locker{&impl->m_WorkingMutex};
434 442 }
@@ -1,105 +1,104
1 1 #include "Variable/VariableSynchronizer.h"
2 2
3 3 #include "Variable/Variable.h"
4 4
5 5 Q_LOGGING_CATEGORY(LOG_VariableSynchronizer, "VariableSynchronizer")
6 6
7 7 namespace {
8 8
9 9 using GroupId = VariableSynchronizer::GroupId;
10 using Group = std::set<std::shared_ptr<Variable> >;
10 struct Group {
11 GroupId m_Id;
12 std::set<std::shared_ptr<Variable> > m_Variables;
13 };
11 14
12 15 } // namespace
13 16
14 17 struct VariableSynchronizer::VariableSynchronizerPrivate {
15 18 std::map<GroupId, Group> m_Groups;
16 19 std::map<std::shared_ptr<Variable>, Group *> m_GroupsIndex;
17 20 };
18 21
19 22 VariableSynchronizer::VariableSynchronizer(QObject *parent)
20 23 : QObject{parent}, impl{spimpl::make_unique_impl<VariableSynchronizerPrivate>()}
21 24 {
22 25 }
23 26
24 27 void VariableSynchronizer::addGroup(GroupId groupId) noexcept
25 28 {
26 29 if (impl->m_Groups.count(groupId) == 1) {
27 30 qCWarning(LOG_VariableSynchronizer())
28 31 << tr("Can't create new synchronization group: a "
29 32 "group already exists under the passed identifier");
30 33 return;
31 34 }
32 35
33 36 impl->m_Groups.insert(std::make_pair(groupId, Group{}));
34 37 }
35 38
36 39 void VariableSynchronizer::addVariable(std::shared_ptr<Variable> variable, GroupId groupId) noexcept
37 40 {
38 41 if (impl->m_GroupsIndex.count(variable) == 1) {
39 42 qCWarning(LOG_VariableSynchronizer())
40 43 << tr("Can't add variable to a new synchronization group: the variable is already in a "
41 44 "synchronization group");
42 45 return;
43 46 }
44 47
45 48 auto groupIt = impl->m_Groups.find(groupId);
46 49
47 50 if (groupIt == impl->m_Groups.end()) {
48 51 qCWarning(LOG_VariableSynchronizer())
49 52 << tr("Can't add variable to the synchronization group: no group exists under the "
50 53 "passed identifier");
51 54 return;
52 55 }
53 56
54 57 // Registers variable
55 groupIt->second.insert(variable);
58 groupIt->second.m_Variables.insert(variable);
56 59
57 60 // Creates index for variable
58 61 impl->m_GroupsIndex.insert(std::make_pair(variable, &groupIt->second));
59 62 }
60 63
61 64 void VariableSynchronizer::removeGroup(GroupId groupId) noexcept
62 65 {
63 66 auto groupIt = impl->m_Groups.find(groupId);
64 67
65 68 if (groupIt == impl->m_Groups.end()) {
66 69 qCWarning(LOG_VariableSynchronizer()) << tr(
67 70 "Can't remove synchronization group: no group exists under the passed identifier");
68 71 return;
69 72 }
70 73
71 74 // Removes indexes
72 for (const auto &variable : groupIt->second) {
75 for (const auto &variable : groupIt->second.m_Variables) {
73 76 impl->m_GroupsIndex.erase(variable);
74 77 }
75 78
76 79 // Removes group
77 80 impl->m_Groups.erase(groupIt);
78 81 }
79 82
80 void VariableSynchronizer::removeVariable(std::shared_ptr<Variable> variable,
81 GroupId groupId) noexcept
83 void VariableSynchronizer::removeVariable(std::shared_ptr<Variable> variable) noexcept
82 84 {
83 auto groupIt = impl->m_Groups.find(groupId);
85 // Finds group in which the variable is
86 auto variableGroupIt = impl->m_GroupsIndex.find(variable);
87 if (variableGroupIt != impl->m_GroupsIndex.end()) {
88 auto groupId = variableGroupIt->second->m_Id;
84 89
85 if (groupIt == impl->m_Groups.end()) {
86 qCWarning(LOG_VariableSynchronizer())
87 << tr("Can't remove variable from synchronization group: no group exists under the "
88 "passed identifier");
89 return;
90 }
90 // Removes variable index
91 impl->m_GroupsIndex.erase(variableGroupIt);
91 92
92 // Removes variable index
93 impl->m_GroupsIndex.erase(variable);
94
95 // Removes variable from group
96 groupIt->second.erase(variable);
93 // Removes variable from group
94 impl->m_Groups[groupId].m_Variables.erase(variable);
95 }
97 96 }
98 97
99 98 std::set<std::shared_ptr<Variable> >
100 99 VariableSynchronizer::synchronizedVariables(std::shared_ptr<Variable> variable) const noexcept
101 100 {
102 101 auto groupIndexIt = impl->m_GroupsIndex.find(variable);
103 return groupIndexIt != impl->m_GroupsIndex.end() ? *groupIndexIt->second
102 return groupIndexIt != impl->m_GroupsIndex.end() ? groupIndexIt->second->m_Variables
104 103 : std::set<std::shared_ptr<Variable> >{};
105 104 }
General Comments 0
You need to be logged in to leave comments. Login now