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