##// END OF EJS Templates
Transits tokens in provider requests
Alexandre Leroux -
r376:313aeb6a2933
parent child
Show More
@@ -1,38 +1,40
1 #ifndef SCIQLOP_IDATAPROVIDER_H
1 #ifndef SCIQLOP_IDATAPROVIDER_H
2 #define SCIQLOP_IDATAPROVIDER_H
2 #define SCIQLOP_IDATAPROVIDER_H
3
3
4 #include <memory>
4 #include <memory>
5
5
6 #include <QObject>
6 #include <QObject>
7 #include <QUuid>
7
8
8 #include <Common/MetaTypes.h>
9 #include <Common/MetaTypes.h>
9
10
10 #include <Data/SqpDateTime.h>
11 #include <Data/SqpDateTime.h>
11
12
12 class DataProviderParameters;
13 class DataProviderParameters;
13 class IDataSeries;
14 class IDataSeries;
14
15
15 /**
16 /**
16 * @brief The IDataProvider interface aims to declare a data provider.
17 * @brief The IDataProvider interface aims to declare a data provider.
17 *
18 *
18 * A data provider is an entity that generates data and returns it according to various parameters
19 * A data provider is an entity that generates data and returns it according to various parameters
19 * (time interval, product to retrieve the data, etc.)
20 * (time interval, product to retrieve the data, etc.)
20 *
21 *
21 * @sa IDataSeries
22 * @sa IDataSeries
22 */
23 */
23 class IDataProvider : public QObject {
24 class IDataProvider : public QObject {
24
25
25 Q_OBJECT
26 Q_OBJECT
26 public:
27 public:
27 virtual ~IDataProvider() noexcept = default;
28 virtual ~IDataProvider() noexcept = default;
28
29
29 virtual void requestDataLoading(const QVector<SqpDateTime> &dateTimeList) = 0;
30 virtual void requestDataLoading(QUuid token, const QVector<SqpDateTime> &dateTimeList) = 0;
30
31
31 signals:
32 signals:
32 void dataProvided(std::shared_ptr<IDataSeries> dateSerie, const SqpDateTime &dateTime);
33 void dataProvided(QUuid token, std::shared_ptr<IDataSeries> dateSerie,
34 const SqpDateTime &dateTime);
33 };
35 };
34
36
35 // Required for using shared_ptr in signals/slots
37 // Required for using shared_ptr in signals/slots
36 SCIQLOP_REGISTER_META_TYPE(IDATAPROVIDER_PTR_REGISTRY, std::shared_ptr<IDataProvider>)
38 SCIQLOP_REGISTER_META_TYPE(IDATAPROVIDER_PTR_REGISTRY, std::shared_ptr<IDataProvider>)
37
39
38 #endif // SCIQLOP_IDATAPROVIDER_H
40 #endif // SCIQLOP_IDATAPROVIDER_H
@@ -1,197 +1,205
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableCacheController.h>
2 #include <Variable/VariableCacheController.h>
3 #include <Variable/VariableController.h>
3 #include <Variable/VariableController.h>
4 #include <Variable/VariableModel.h>
4 #include <Variable/VariableModel.h>
5
5
6 #include <Data/DataProviderParameters.h>
6 #include <Data/DataProviderParameters.h>
7 #include <Data/IDataProvider.h>
7 #include <Data/IDataProvider.h>
8 #include <Data/IDataSeries.h>
8 #include <Data/IDataSeries.h>
9 #include <Time/TimeController.h>
9 #include <Time/TimeController.h>
10
10
11 #include <QDateTime>
11 #include <QDateTime>
12 #include <QMutex>
12 #include <QMutex>
13 #include <QThread>
13 #include <QThread>
14 #include <QUuid>
14 #include <QtCore/QItemSelectionModel>
15 #include <QtCore/QItemSelectionModel>
15
16
16 #include <unordered_map>
17 #include <unordered_map>
17
18
18 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
19 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
19
20
20 struct VariableController::VariableControllerPrivate {
21 struct VariableController::VariableControllerPrivate {
21 explicit VariableControllerPrivate(VariableController *parent)
22 explicit VariableControllerPrivate(VariableController *parent)
22 : m_WorkingMutex{},
23 : m_WorkingMutex{},
23 m_VariableModel{new VariableModel{parent}},
24 m_VariableModel{new VariableModel{parent}},
24 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
25 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
25 m_VariableCacheController{std::make_unique<VariableCacheController>()}
26 m_VariableCacheController{std::make_unique<VariableCacheController>()}
26 {
27 {
27 }
28 }
28
29
29 QMutex m_WorkingMutex;
30 QMutex m_WorkingMutex;
30 /// Variable model. The VariableController has the ownership
31 /// Variable model. The VariableController has the ownership
31 VariableModel *m_VariableModel;
32 VariableModel *m_VariableModel;
32 QItemSelectionModel *m_VariableSelectionModel;
33 QItemSelectionModel *m_VariableSelectionModel;
33
34
34
35
35 TimeController *m_TimeController{nullptr};
36 TimeController *m_TimeController{nullptr};
36 std::unique_ptr<VariableCacheController> m_VariableCacheController;
37 std::unique_ptr<VariableCacheController> m_VariableCacheController;
37
38
38 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
39 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
39 m_VariableToProviderMap;
40 m_VariableToProviderMap;
41 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToToken;
40 };
42 };
41
43
42 VariableController::VariableController(QObject *parent)
44 VariableController::VariableController(QObject *parent)
43 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
45 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
44 {
46 {
45 qCDebug(LOG_VariableController()) << tr("VariableController construction")
47 qCDebug(LOG_VariableController()) << tr("VariableController construction")
46 << QThread::currentThread();
48 << QThread::currentThread();
47 }
49 }
48
50
49 VariableController::~VariableController()
51 VariableController::~VariableController()
50 {
52 {
51 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
53 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
52 << QThread::currentThread();
54 << QThread::currentThread();
53 this->waitForFinish();
55 this->waitForFinish();
54 }
56 }
55
57
56 VariableModel *VariableController::variableModel() noexcept
58 VariableModel *VariableController::variableModel() noexcept
57 {
59 {
58 return impl->m_VariableModel;
60 return impl->m_VariableModel;
59 }
61 }
60
62
61 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
63 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
62 {
64 {
63 return impl->m_VariableSelectionModel;
65 return impl->m_VariableSelectionModel;
64 }
66 }
65
67
66 void VariableController::setTimeController(TimeController *timeController) noexcept
68 void VariableController::setTimeController(TimeController *timeController) noexcept
67 {
69 {
68 impl->m_TimeController = timeController;
70 impl->m_TimeController = timeController;
69 }
71 }
70
72
71 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
73 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
72 {
74 {
73 if (!variable) {
75 if (!variable) {
74 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
76 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
75 return;
77 return;
76 }
78 }
77
79
78 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
80 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
79 // make some treatments before the deletion
81 // make some treatments before the deletion
80 emit variableAboutToBeDeleted(variable);
82 emit variableAboutToBeDeleted(variable);
81
83
82 // Deletes provider
84 // Deletes provider
83 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
85 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
84 qCDebug(LOG_VariableController())
86 qCDebug(LOG_VariableController())
85 << tr("Number of providers deleted for variable %1: %2")
87 << tr("Number of providers deleted for variable %1: %2")
86 .arg(variable->name(), QString::number(nbProvidersDeleted));
88 .arg(variable->name(), QString::number(nbProvidersDeleted));
87
89
88 // Clears cache
90 // Clears cache
89 impl->m_VariableCacheController->clear(variable);
91 impl->m_VariableCacheController->clear(variable);
90
92
91 // Deletes from model
93 // Deletes from model
92 impl->m_VariableModel->deleteVariable(variable);
94 impl->m_VariableModel->deleteVariable(variable);
93 }
95 }
94
96
95 void VariableController::deleteVariables(
97 void VariableController::deleteVariables(
96 const QVector<std::shared_ptr<Variable> > &variables) noexcept
98 const QVector<std::shared_ptr<Variable> > &variables) noexcept
97 {
99 {
98 for (auto variable : qAsConst(variables)) {
100 for (auto variable : qAsConst(variables)) {
99 deleteVariable(variable);
101 deleteVariable(variable);
100 }
102 }
101 }
103 }
102
104
103 void VariableController::createVariable(const QString &name,
105 void VariableController::createVariable(const QString &name,
104 std::shared_ptr<IDataProvider> provider) noexcept
106 std::shared_ptr<IDataProvider> provider) noexcept
105 {
107 {
106
108
107 if (!impl->m_TimeController) {
109 if (!impl->m_TimeController) {
108 qCCritical(LOG_VariableController())
110 qCCritical(LOG_VariableController())
109 << tr("Impossible to create variable: The time controller is null");
111 << tr("Impossible to create variable: The time controller is null");
110 return;
112 return;
111 }
113 }
112
114
113
115
114 /// @todo : for the moment :
116 /// @todo : for the moment :
115 /// - the provider is only used to retrieve data from the variable for its initialization, but
117 /// - the provider is only used to retrieve data from the variable for its initialization, but
116 /// it will be retained later
118 /// it will be retained later
117 /// - default data are generated for the variable, without taking into account the timerange set
119 /// - default data are generated for the variable, without taking into account the timerange set
118 /// in sciqlop
120 /// in sciqlop
119 auto dateTime = impl->m_TimeController->dateTime();
121 auto dateTime = impl->m_TimeController->dateTime();
120 if (auto newVariable = impl->m_VariableModel->createVariable(name, dateTime)) {
122 if (auto newVariable = impl->m_VariableModel->createVariable(name, dateTime)) {
123 auto token = QUuid::createUuid();
121
124
122 // store the provider
125 // store the provider
123 impl->m_VariableToProviderMap[newVariable] = provider;
126 impl->m_VariableToProviderMap[newVariable] = provider;
127 impl->m_VariableToToken[newVariable] = token;
124
128
125 auto addDateTimeAcquired = [ this, varW = std::weak_ptr<Variable>{newVariable} ](
129 auto addDateTimeAcquired = [ this, varW = std::weak_ptr<Variable>{newVariable} ](
126 auto dataSeriesAcquired, auto dateTimeToPutInCache)
130 QUuid token, auto dataSeriesAcquired, auto dateTimeToPutInCache)
127 {
131 {
128 if (auto variable = varW.lock()) {
132 if (auto variable = varW.lock()) {
133 auto varToken = impl->m_VariableToToken.at(variable);
134 if (varToken == token) {
129 impl->m_VariableCacheController->addDateTime(variable, dateTimeToPutInCache);
135 impl->m_VariableCacheController->addDateTime(variable, dateTimeToPutInCache);
130 variable->setDataSeries(dataSeriesAcquired);
136 variable->setDataSeries(dataSeriesAcquired);
131 }
137 }
138 }
132 };
139 };
133
140
134 connect(provider.get(), &IDataProvider::dataProvided, addDateTimeAcquired);
141 connect(provider.get(), &IDataProvider::dataProvided, addDateTimeAcquired);
135 this->onRequestDataLoading(newVariable, dateTime);
142 this->onRequestDataLoading(newVariable, dateTime);
136 }
143 }
137 }
144 }
138
145
139 void VariableController::onDateTimeOnSelection(const SqpDateTime &dateTime)
146 void VariableController::onDateTimeOnSelection(const SqpDateTime &dateTime)
140 {
147 {
141 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
148 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
142 << QThread::currentThread()->objectName();
149 << QThread::currentThread()->objectName();
143 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
150 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
144
151
145 for (const auto &selectedRow : qAsConst(selectedRows)) {
152 for (const auto &selectedRow : qAsConst(selectedRows)) {
146 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
153 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
147 selectedVariable->setDateTime(dateTime);
154 selectedVariable->setDateTime(dateTime);
148 this->onRequestDataLoading(selectedVariable, dateTime);
155 this->onRequestDataLoading(selectedVariable, dateTime);
149 }
156 }
150 }
157 }
151 }
158 }
152
159
153
160
154 void VariableController::onRequestDataLoading(std::shared_ptr<Variable> variable,
161 void VariableController::onRequestDataLoading(std::shared_ptr<Variable> variable,
155 const SqpDateTime &dateTime)
162 const SqpDateTime &dateTime)
156 {
163 {
157 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
164 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
158 << QThread::currentThread()->objectName();
165 << QThread::currentThread()->objectName();
159 // we want to load data of the variable for the dateTime.
166 // we want to load data of the variable for the dateTime.
160 // First we check if the cache contains some of them.
167 // First we check if the cache contains some of them.
161 // For the other, we ask the provider to give them.
168 // For the other, we ask the provider to give them.
162 if (variable) {
169 if (variable) {
163
170
164 auto dateTimeListNotInCache
171 auto dateTimeListNotInCache
165 = impl->m_VariableCacheController->provideNotInCacheDateTimeList(variable, dateTime);
172 = impl->m_VariableCacheController->provideNotInCacheDateTimeList(variable, dateTime);
166
173
167 if (!dateTimeListNotInCache.empty()) {
174 if (!dateTimeListNotInCache.empty()) {
168 // Ask the provider for each data on the dateTimeListNotInCache
175 // Ask the provider for each data on the dateTimeListNotInCache
176 auto token = impl->m_VariableToToken.at(variable);
169 impl->m_VariableToProviderMap.at(variable)->requestDataLoading(
177 impl->m_VariableToProviderMap.at(variable)->requestDataLoading(
170 std::move(dateTimeListNotInCache));
178 token, std::move(dateTimeListNotInCache));
171 }
179 }
172 else {
180 else {
173 emit variable->updated();
181 emit variable->updated();
174 }
182 }
175 }
183 }
176 else {
184 else {
177 qCCritical(LOG_VariableController()) << tr("Impossible to load data of a variable null");
185 qCCritical(LOG_VariableController()) << tr("Impossible to load data of a variable null");
178 }
186 }
179 }
187 }
180
188
181
189
182 void VariableController::initialize()
190 void VariableController::initialize()
183 {
191 {
184 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
192 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
185 impl->m_WorkingMutex.lock();
193 impl->m_WorkingMutex.lock();
186 qCDebug(LOG_VariableController()) << tr("VariableController init END");
194 qCDebug(LOG_VariableController()) << tr("VariableController init END");
187 }
195 }
188
196
189 void VariableController::finalize()
197 void VariableController::finalize()
190 {
198 {
191 impl->m_WorkingMutex.unlock();
199 impl->m_WorkingMutex.unlock();
192 }
200 }
193
201
194 void VariableController::waitForFinish()
202 void VariableController::waitForFinish()
195 {
203 {
196 QMutexLocker locker{&impl->m_WorkingMutex};
204 QMutexLocker locker{&impl->m_WorkingMutex};
197 }
205 }
@@ -1,26 +1,26
1 #ifndef SCIQLOP_COSINUSPROVIDER_H
1 #ifndef SCIQLOP_COSINUSPROVIDER_H
2 #define SCIQLOP_COSINUSPROVIDER_H
2 #define SCIQLOP_COSINUSPROVIDER_H
3
3
4 #include "MockPluginGlobal.h"
4 #include "MockPluginGlobal.h"
5
5
6 #include <Data/IDataProvider.h>
6 #include <Data/IDataProvider.h>
7
7
8 #include <QLoggingCategory>
8 #include <QLoggingCategory>
9
9
10 Q_DECLARE_LOGGING_CATEGORY(LOG_CosinusProvider)
10 Q_DECLARE_LOGGING_CATEGORY(LOG_CosinusProvider)
11
11
12 /**
12 /**
13 * @brief The CosinusProvider class is an example of how a data provider can generate data
13 * @brief The CosinusProvider class is an example of how a data provider can generate data
14 */
14 */
15 class SCIQLOP_MOCKPLUGIN_EXPORT CosinusProvider : public IDataProvider {
15 class SCIQLOP_MOCKPLUGIN_EXPORT CosinusProvider : public IDataProvider {
16 public:
16 public:
17 void requestDataLoading(const QVector<SqpDateTime> &dateTimeList) override;
17 void requestDataLoading(QUuid token, const QVector<SqpDateTime> &dateTimeList) override;
18
18
19
19
20 private:
20 private:
21 /// @sa IDataProvider::retrieveData()
21 /// @sa IDataProvider::retrieveData()
22 std::shared_ptr<IDataSeries> retrieveData(const DataProviderParameters &parameters) const;
22 std::shared_ptr<IDataSeries> retrieveData(const DataProviderParameters &parameters) const;
23 std::shared_ptr<IDataSeries> retrieveDataSeries(const SqpDateTime &dateTime);
23 std::shared_ptr<IDataSeries> retrieveDataSeries(const SqpDateTime &dateTime);
24 };
24 };
25
25
26 #endif // SCIQLOP_COSINUSPROVIDER_H
26 #endif // SCIQLOP_COSINUSPROVIDER_H
@@ -1,50 +1,50
1 #include "CosinusProvider.h"
1 #include "CosinusProvider.h"
2
2
3 #include <Data/DataProviderParameters.h>
3 #include <Data/DataProviderParameters.h>
4 #include <Data/ScalarSeries.h>
4 #include <Data/ScalarSeries.h>
5
5
6 #include <cmath>
6 #include <cmath>
7
7
8 #include <QDateTime>
8 #include <QDateTime>
9 #include <QThread>
9 #include <QThread>
10
10
11 Q_LOGGING_CATEGORY(LOG_CosinusProvider, "CosinusProvider")
11 Q_LOGGING_CATEGORY(LOG_CosinusProvider, "CosinusProvider")
12
12
13 std::shared_ptr<IDataSeries>
13 std::shared_ptr<IDataSeries>
14 CosinusProvider::retrieveData(const DataProviderParameters &parameters) const
14 CosinusProvider::retrieveData(const DataProviderParameters &parameters) const
15 {
15 {
16 auto dateTime = parameters.m_Time;
16 auto dateTime = parameters.m_Time;
17
17
18 auto dataIndex = 0;
18 auto dataIndex = 0;
19
19
20 // Gets the timerange from the parameters
20 // Gets the timerange from the parameters
21 double freq = 100.0;
21 double freq = 100.0;
22 double start = dateTime.m_TStart * freq; // 100 htz
22 double start = dateTime.m_TStart * freq; // 100 htz
23 double end = dateTime.m_TEnd * freq; // 100 htz
23 double end = dateTime.m_TEnd * freq; // 100 htz
24
24
25 // We assure that timerange is valid
25 // We assure that timerange is valid
26 if (end < start) {
26 if (end < start) {
27 std::swap(start, end);
27 std::swap(start, end);
28 }
28 }
29
29
30 // Generates scalar series containing cosinus values (one value per second)
30 // Generates scalar series containing cosinus values (one value per second)
31 auto scalarSeries
31 auto scalarSeries
32 = std::make_shared<ScalarSeries>(end - start, Unit{QStringLiteral("t"), true}, Unit{});
32 = std::make_shared<ScalarSeries>(end - start, Unit{QStringLiteral("t"), true}, Unit{});
33
33
34 for (auto time = start; time < end; ++time, ++dataIndex) {
34 for (auto time = start; time < end; ++time, ++dataIndex) {
35 const auto timeOnFreq = time / freq;
35 const auto timeOnFreq = time / freq;
36 scalarSeries->setData(dataIndex, timeOnFreq, std::cos(timeOnFreq));
36 scalarSeries->setData(dataIndex, timeOnFreq, std::cos(timeOnFreq));
37 }
37 }
38 return scalarSeries;
38 return scalarSeries;
39 }
39 }
40
40
41 void CosinusProvider::requestDataLoading(const QVector<SqpDateTime> &dateTimeList)
41 void CosinusProvider::requestDataLoading(QUuid token, const QVector<SqpDateTime> &dateTimeList)
42 {
42 {
43 qCDebug(LOG_CosinusProvider()) << "CosinusProvider::requestDataLoading"
43 qCDebug(LOG_CosinusProvider()) << "CosinusProvider::requestDataLoading"
44 << QThread::currentThread()->objectName();
44 << QThread::currentThread()->objectName();
45 // NOTE: Try to use multithread if possible
45 // NOTE: Try to use multithread if possible
46 for (const auto &dateTime : dateTimeList) {
46 for (const auto &dateTime : dateTimeList) {
47 auto scalarSeries = this->retrieveData(DataProviderParameters{dateTime});
47 auto scalarSeries = this->retrieveData(DataProviderParameters{dateTime});
48 emit dataProvided(scalarSeries, dateTime);
48 emit dataProvided(token, scalarSeries, dateTime);
49 }
49 }
50 }
50 }
General Comments 0
You need to be logged in to leave comments. Login now