##// END OF EJS Templates
Merge branch 'feature/ThreadFix' into develop
perrinel -
r371:684b9afd5f2a merge
parent child
Show More
@@ -1,8 +1,9
1 #ifndef SCIQLOP_ARRAYDATA_H
1 #ifndef SCIQLOP_ARRAYDATA_H
2 #define SCIQLOP_ARRAYDATA_H
2 #define SCIQLOP_ARRAYDATA_H
3
3
4 #include <QReadLocker>
5 #include <QReadWriteLock>
4 #include <QVector>
6 #include <QVector>
5
6 /**
7 /**
7 * @brief The ArrayData class represents a dataset for a data series.
8 * @brief The ArrayData class represents a dataset for a data series.
8 *
9 *
@@ -22,10 +23,22 public:
22 template <int D = Dim, typename = std::enable_if_t<D == 1> >
23 template <int D = Dim, typename = std::enable_if_t<D == 1> >
23 explicit ArrayData(int nbColumns) : m_Data{1, QVector<double>{}}
24 explicit ArrayData(int nbColumns) : m_Data{1, QVector<double>{}}
24 {
25 {
26 QWriteLocker locker(&m_Lock);
25 m_Data[0].resize(nbColumns);
27 m_Data[0].resize(nbColumns);
26 }
28 }
27
29
28 /**
30 /**
31 * Ctor for a unidimensional ArrayData
32 * @param nbColumns the number of values the ArrayData will hold
33 */
34 explicit ArrayData(const ArrayData &other)
35 {
36 QReadLocker otherLocker(&other.m_Lock);
37 QWriteLocker locker(&m_Lock);
38 m_Data = other.m_Data;
39 }
40
41 /**
29 * Sets a data at a specified index. The index has to be valid to be effective
42 * Sets a data at a specified index. The index has to be valid to be effective
30 * @param index the index to which the data will be set
43 * @param index the index to which the data will be set
31 * @param data the data to set
44 * @param data the data to set
@@ -34,6 +47,7 public:
34 template <int D = Dim, typename = std::enable_if_t<D == 1> >
47 template <int D = Dim, typename = std::enable_if_t<D == 1> >
35 void setData(int index, double data) noexcept
48 void setData(int index, double data) noexcept
36 {
49 {
50 QWriteLocker locker(&m_Lock);
37 if (index >= 0 && index < m_Data.at(0).size()) {
51 if (index >= 0 && index < m_Data.at(0).size()) {
38 m_Data[0].replace(index, data);
52 m_Data[0].replace(index, data);
39 }
53 }
@@ -44,8 +58,9 public:
44 * @remarks this method is only available for a unidimensional ArrayData
58 * @remarks this method is only available for a unidimensional ArrayData
45 */
59 */
46 template <int D = Dim, typename = std::enable_if_t<D == 1> >
60 template <int D = Dim, typename = std::enable_if_t<D == 1> >
47 const QVector<double> &data() const noexcept
61 QVector<double> data() const noexcept
48 {
62 {
63 QReadLocker locker(&m_Lock);
49 return m_Data[0];
64 return m_Data[0];
50 }
65 }
51
66
@@ -54,8 +69,9 public:
54 * @remarks this method is only available for a unidimensional ArrayData
69 * @remarks this method is only available for a unidimensional ArrayData
55 */
70 */
56 template <int D = Dim, typename = std::enable_if_t<D == 1> >
71 template <int D = Dim, typename = std::enable_if_t<D == 1> >
57 const QVector<double> &data(double tStart, double tEnd) const noexcept
72 QVector<double> data(double tStart, double tEnd) const noexcept
58 {
73 {
74 QReadLocker locker(&m_Lock);
59 return m_Data.at(tStart);
75 return m_Data.at(tStart);
60 }
76 }
61
77
@@ -63,20 +79,30 public:
63 template <int D = Dim, typename = std::enable_if_t<D == 1> >
79 template <int D = Dim, typename = std::enable_if_t<D == 1> >
64 void merge(const ArrayData<1> &arrayData)
80 void merge(const ArrayData<1> &arrayData)
65 {
81 {
82 QWriteLocker locker(&m_Lock);
66 if (!m_Data.empty()) {
83 if (!m_Data.empty()) {
84 QReadLocker otherLocker(&arrayData.m_Lock);
67 m_Data[0] += arrayData.data();
85 m_Data[0] += arrayData.data();
68 }
86 }
69 }
87 }
70
88
71 template <int D = Dim, typename = std::enable_if_t<D == 1> >
89 template <int D = Dim, typename = std::enable_if_t<D == 1> >
72 int size()
90 int size() const
73 {
91 {
92 QReadLocker locker(&m_Lock);
74 return m_Data[0].size();
93 return m_Data[0].size();
75 }
94 }
76
95
96 void clear()
97 {
98 QWriteLocker locker(&m_Lock);
99 m_Data.clear();
100 }
101
77
102
78 private:
103 private:
79 QVector<QVector<double> > m_Data;
104 QVector<QVector<double> > m_Data;
105 mutable QReadWriteLock m_Lock;
80 };
106 };
81
107
82 #endif // SCIQLOP_ARRAYDATA_H
108 #endif // SCIQLOP_ARRAYDATA_H
@@ -6,9 +6,10
6
6
7 #include <QLoggingCategory>
7 #include <QLoggingCategory>
8
8
9 #include <QReadLocker>
10 #include <QReadWriteLock>
9 #include <memory>
11 #include <memory>
10
12
11
12 Q_DECLARE_LOGGING_CATEGORY(LOG_DataSeries)
13 Q_DECLARE_LOGGING_CATEGORY(LOG_DataSeries)
13 Q_LOGGING_CATEGORY(LOG_DataSeries, "DataSeries")
14 Q_LOGGING_CATEGORY(LOG_DataSeries, "DataSeries")
14
15
@@ -38,12 +39,19 public:
38 /// @sa IDataSeries::valuesUnit()
39 /// @sa IDataSeries::valuesUnit()
39 Unit valuesUnit() const override { return m_ValuesUnit; }
40 Unit valuesUnit() const override { return m_ValuesUnit; }
40
41
42 void clear()
43 {
44 m_XAxisData->clear();
45 m_ValuesData->clear();
46 }
47
41 /// @sa IDataSeries::merge()
48 /// @sa IDataSeries::merge()
42 void merge(IDataSeries *dataSeries) override
49 void merge(IDataSeries *dataSeries) override
43 {
50 {
44 if (auto dimDataSeries = dynamic_cast<DataSeries<Dim> *>(dataSeries)) {
51 if (auto dimDataSeries = dynamic_cast<DataSeries<Dim> *>(dataSeries)) {
45 m_XAxisData->merge(*dimDataSeries->xAxisData());
52 m_XAxisData->merge(*dimDataSeries->xAxisData());
46 m_ValuesData->merge(*dimDataSeries->valuesData());
53 m_ValuesData->merge(*dimDataSeries->valuesData());
54 dimDataSeries->clear();
47 }
55 }
48 else {
56 else {
49 qCWarning(LOG_DataSeries())
57 qCWarning(LOG_DataSeries())
@@ -51,6 +59,10 public:
51 }
59 }
52 }
60 }
53
61
62 virtual void lockRead() { m_Lock.lockForRead(); }
63 virtual void lockWrite() { m_Lock.lockForWrite(); }
64 virtual void unlock() { m_Lock.unlock(); }
65
54 protected:
66 protected:
55 /// Protected ctor (DataSeries is abstract)
67 /// Protected ctor (DataSeries is abstract)
56 explicit DataSeries(std::shared_ptr<ArrayData<1> > xAxisData, const Unit &xAxisUnit,
68 explicit DataSeries(std::shared_ptr<ArrayData<1> > xAxisData, const Unit &xAxisUnit,
@@ -88,6 +100,8 private:
88 Unit m_XAxisUnit;
100 Unit m_XAxisUnit;
89 std::shared_ptr<ArrayData<Dim> > m_ValuesData;
101 std::shared_ptr<ArrayData<Dim> > m_ValuesData;
90 Unit m_ValuesUnit;
102 Unit m_ValuesUnit;
103
104 QReadWriteLock m_Lock;
91 };
105 };
92
106
93 #endif // SCIQLOP_DATASERIES_H
107 #endif // SCIQLOP_DATASERIES_H
@@ -51,6 +51,10 public:
51 virtual void merge(IDataSeries *dataSeries) = 0;
51 virtual void merge(IDataSeries *dataSeries) = 0;
52
52
53 virtual std::unique_ptr<IDataSeries> clone() const = 0;
53 virtual std::unique_ptr<IDataSeries> clone() const = 0;
54
55 virtual void lockRead() = 0;
56 virtual void lockWrite() = 0;
57 virtual void unlock() = 0;
54 };
58 };
55
59
56 // Required for using shared_ptr in signals/slots
60 // Required for using shared_ptr in signals/slots
@@ -3,6 +3,9
3 #include <Data/IDataSeries.h>
3 #include <Data/IDataSeries.h>
4 #include <Data/SqpDateTime.h>
4 #include <Data/SqpDateTime.h>
5
5
6 #include <QReadWriteLock>
7 #include <QThread>
8
6 Q_LOGGING_CATEGORY(LOG_Variable, "Variable")
9 Q_LOGGING_CATEGORY(LOG_Variable, "Variable")
7
10
8 struct Variable::VariablePrivate {
11 struct Variable::VariablePrivate {
@@ -57,6 +60,7 void Variable::setDateTime(const SqpDateTime &dateTime) noexcept
57
60
58 void Variable::setDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
61 void Variable::setDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
59 {
62 {
63 qCDebug(LOG_Variable()) << "Variable::setDataSeries" << QThread::currentThread()->objectName();
60 if (!dataSeries) {
64 if (!dataSeries) {
61 /// @todo ALX : log
65 /// @todo ALX : log
62 return;
66 return;
@@ -67,8 +71,11 void Variable::setDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
67 impl->m_DataSeries = dataSeries->clone();
71 impl->m_DataSeries = dataSeries->clone();
68 }
72 }
69 else {
73 else {
74 dataSeries->lockWrite();
75 impl->m_DataSeries->lockWrite();
70 impl->m_DataSeries->merge(dataSeries.get());
76 impl->m_DataSeries->merge(dataSeries.get());
71
77 impl->m_DataSeries->unlock();
78 dataSeries->unlock();
72 emit updated();
79 emit updated();
73 }
80 }
74 }
81 }
@@ -3,6 +3,7
3 #include "Variable/Variable.h"
3 #include "Variable/Variable.h"
4 #include <unordered_map>
4 #include <unordered_map>
5
5
6 #include <QThread>
6 Q_LOGGING_CATEGORY(LOG_VariableCacheController, "VariableCacheController")
7 Q_LOGGING_CATEGORY(LOG_VariableCacheController, "VariableCacheController")
7
8
8 struct VariableCacheController::VariableCacheControllerPrivate {
9 struct VariableCacheController::VariableCacheControllerPrivate {
@@ -32,6 +33,8 VariableCacheController::VariableCacheController(QObject *parent)
32 void VariableCacheController::addDateTime(std::shared_ptr<Variable> variable,
33 void VariableCacheController::addDateTime(std::shared_ptr<Variable> variable,
33 const SqpDateTime &dateTime)
34 const SqpDateTime &dateTime)
34 {
35 {
36 qCDebug(LOG_VariableCacheController()) << "VariableCacheController::addDateTime"
37 << QThread::currentThread()->objectName();
35 if (variable) {
38 if (variable) {
36 auto findVariableIte = impl->m_VariableToSqpDateTimeListMap.find(variable);
39 auto findVariableIte = impl->m_VariableToSqpDateTimeListMap.find(variable);
37 if (findVariableIte == impl->m_VariableToSqpDateTimeListMap.end()) {
40 if (findVariableIte == impl->m_VariableToSqpDateTimeListMap.end()) {
@@ -81,6 +84,9 QVector<SqpDateTime>
81 VariableCacheController::provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
84 VariableCacheController::provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
82 const SqpDateTime &dateTime)
85 const SqpDateTime &dateTime)
83 {
86 {
87 qCDebug(LOG_VariableCacheController())
88 << "VariableCacheController::provideNotInCacheDateTimeList"
89 << QThread::currentThread()->objectName();
84 auto notInCache = QVector<SqpDateTime>{};
90 auto notInCache = QVector<SqpDateTime>{};
85
91
86 // This algorithm is recursif. The idea is to localise the start time then the end time in the
92 // This algorithm is recursif. The idea is to localise the start time then the end time in the
@@ -101,6 +107,8 VariableCacheController::provideNotInCacheDateTimeList(std::shared_ptr<Variable>
101 QVector<SqpDateTime>
107 QVector<SqpDateTime>
102 VariableCacheController::dateCacheList(std::shared_ptr<Variable> variable) const noexcept
108 VariableCacheController::dateCacheList(std::shared_ptr<Variable> variable) const noexcept
103 {
109 {
110 qCDebug(LOG_VariableCacheController()) << "VariableCacheController::dateCacheList"
111 << QThread::currentThread()->objectName();
104 try {
112 try {
105 return impl->m_VariableToSqpDateTimeListMap.at(variable);
113 return impl->m_VariableToSqpDateTimeListMap.at(variable);
106 }
114 }
@@ -152,6 +152,8 void VariableController::createVariable(const QString &name,
152
152
153 void VariableController::onDateTimeOnSelection(const SqpDateTime &dateTime)
153 void VariableController::onDateTimeOnSelection(const SqpDateTime &dateTime)
154 {
154 {
155 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
156 << QThread::currentThread()->objectName();
155 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
157 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
156
158
157 for (const auto &selectedRow : qAsConst(selectedRows)) {
159 for (const auto &selectedRow : qAsConst(selectedRows)) {
@@ -166,6 +168,8 void VariableController::onDateTimeOnSelection(const SqpDateTime &dateTime)
166 void VariableController::onRequestDataLoading(std::shared_ptr<Variable> variable,
168 void VariableController::onRequestDataLoading(std::shared_ptr<Variable> variable,
167 const SqpDateTime &dateTime)
169 const SqpDateTime &dateTime)
168 {
170 {
171 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
172 << QThread::currentThread()->objectName();
169 // we want to load data of the variable for the dateTime.
173 // we want to load data of the variable for the dateTime.
170 // First we check if the cache contains some of them.
174 // First we check if the cache contains some of them.
171 // For the other, we ask the provider to give them.
175 // For the other, we ask the provider to give them.
@@ -18,6 +18,14 public:
18 m_VariableController{std::make_unique<VariableController>()},
18 m_VariableController{std::make_unique<VariableController>()},
19 m_VisualizationController{std::make_unique<VisualizationController>()}
19 m_VisualizationController{std::make_unique<VisualizationController>()}
20 {
20 {
21 QThread::currentThread()->setObjectName("MainThread");
22 m_DataSourceController->moveToThread(&m_DataSourceControllerThread);
23 m_DataSourceControllerThread.setObjectName("DataSourceControllerThread");
24 m_VariableController->moveToThread(&m_VariableControllerThread);
25 m_VariableControllerThread.setObjectName("VariableControllerThread");
26 m_VisualizationController->moveToThread(&m_VisualizationControllerThread);
27 m_VisualizationControllerThread.setObjectName("VisualizationControllerThread");
28
21 // /////////////////////////////// //
29 // /////////////////////////////// //
22 // Connections between controllers //
30 // Connections between controllers //
23 // /////////////////////////////// //
31 // /////////////////////////////// //
@@ -34,9 +42,6 public:
34 m_VisualizationController.get(),
42 m_VisualizationController.get(),
35 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), Qt::DirectConnection);
43 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), Qt::DirectConnection);
36
44
37 m_DataSourceController->moveToThread(&m_DataSourceControllerThread);
38 m_VariableController->moveToThread(&m_VariableControllerThread);
39 m_VisualizationController->moveToThread(&m_VisualizationControllerThread);
40
45
41 // Additionnal init
46 // Additionnal init
42 m_VariableController->setTimeController(m_TimeController.get());
47 m_VariableController->setTimeController(m_TimeController.get());
@@ -5,12 +5,16
5
5
6 #include <Variable/Variable.h>
6 #include <Variable/Variable.h>
7
7
8 #include <QElapsedTimer>
9
10 Q_LOGGING_CATEGORY(LOG_VisualizationGraphHelper, "VisualizationGraphHelper")
8 Q_LOGGING_CATEGORY(LOG_VisualizationGraphHelper, "VisualizationGraphHelper")
11
9
12 namespace {
10 namespace {
13
11
12 class SqpDataContainer : public QCPGraphDataContainer {
13 public:
14 void appendGraphDataUnsorted(const QCPGraphData &data) { mData.append(data); }
15 };
16
17
14 /// Format for datetimes on a axis
18 /// Format for datetimes on a axis
15 const auto DATETIME_TICKER_FORMAT = QStringLiteral("yyyy/MM/dd \nhh:mm:ss");
19 const auto DATETIME_TICKER_FORMAT = QStringLiteral("yyyy/MM/dd \nhh:mm:ss");
16
20
@@ -33,35 +37,36 QSharedPointer<QCPAxisTicker> axisTicker(bool isTimeAxis)
33 void updateScalarData(QCPAbstractPlottable *component, ScalarSeries &scalarSeries,
37 void updateScalarData(QCPAbstractPlottable *component, ScalarSeries &scalarSeries,
34 const SqpDateTime &dateTime)
38 const SqpDateTime &dateTime)
35 {
39 {
36 QElapsedTimer timer;
40 qCDebug(LOG_VisualizationGraphHelper()) << "TORM: updateScalarData"
37 timer.start();
41 << QThread::currentThread()->objectName();
38 if (auto qcpGraph = dynamic_cast<QCPGraph *>(component)) {
42 if (auto qcpGraph = dynamic_cast<QCPGraph *>(component)) {
39 // Clean the graph
43 // Clean the graph
40 // NAIVE approch
44 // NAIVE approch
41 const auto &xData = scalarSeries.xAxisData()->data();
45 scalarSeries.lockRead();
42 const auto &valuesData = scalarSeries.valuesData()->data();
46 {
43 const auto count = xData.count();
47 const auto xData = scalarSeries.xAxisData()->data();
44 qCInfo(LOG_VisualizationGraphHelper()) << "TORM: Current points in cache" << xData.count();
48 const auto valuesData = scalarSeries.valuesData()->data();
45 auto xValue = QVector<double>(count);
49 const auto count = xData.count();
46 auto vValue = QVector<double>(count);
50 qCInfo(LOG_VisualizationGraphHelper()) << "TORM: Current points in cache"
47
51 << xData.count();
48 int n = 0;
52
49 for (auto i = 0; i < count; ++i) {
53 auto dataContainer = qcpGraph->data();
50 const auto x = xData[i];
54 dataContainer->clear();
51 if (x >= dateTime.m_TStart && x <= dateTime.m_TEnd) {
55 auto sqpDataContainer = QSharedPointer<SqpDataContainer>::create();
52 xValue[n] = x;
56 qcpGraph->setData(sqpDataContainer);
53 vValue[n] = valuesData[i];
57
54 ++n;
58 for (auto i = 0; i < count; ++i) {
59 const auto x = xData[i];
60 if (x >= dateTime.m_TStart && x <= dateTime.m_TEnd) {
61 sqpDataContainer->appendGraphDataUnsorted(QCPGraphData(x, valuesData[i]));
62 }
55 }
63 }
64 sqpDataContainer->sort();
65 qCInfo(LOG_VisualizationGraphHelper()) << "TORM: Current points displayed"
66 << sqpDataContainer->size();
56 }
67 }
68 scalarSeries.unlock();
57
69
58 xValue.resize(n);
59 vValue.resize(n);
60
61 qCInfo(LOG_VisualizationGraphHelper()) << "TORM: Current points displayed"
62 << xValue.count();
63
64 qcpGraph->setData(xValue, vValue);
65
70
66 // Display all data
71 // Display all data
67 component->rescaleAxes();
72 component->rescaleAxes();
@@ -79,7 +79,6 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable)
79
79
80 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
80 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
81 }
81 }
82
83 void VisualizationGraphWidget::addVariableUsingGraph(std::shared_ptr<Variable> variable)
82 void VisualizationGraphWidget::addVariableUsingGraph(std::shared_ptr<Variable> variable)
84 {
83 {
85
84
@@ -178,7 +177,8 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
178
177
179 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1)
178 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1)
180 {
179 {
181 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::onRangeChanged");
180 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::onRangeChanged")
181 << QThread::currentThread()->objectName();
182
182
183 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
183 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
184 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
184 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
@@ -18570,7 +18570,7 void QCPLegend::setIconSize(const QSize &size)
18570 }
18570 }
18571
18571
18572 /*! \overload
18572 /*! \overload
18573 */
18573 */
18574 void QCPLegend::setIconSize(int width, int height)
18574 void QCPLegend::setIconSize(int width, int height)
18575 {
18575 {
18576 mIconSize.setWidth(width);
18576 mIconSize.setWidth(width);
@@ -6,6 +6,7
6 #include <cmath>
6 #include <cmath>
7
7
8 #include <QDateTime>
8 #include <QDateTime>
9 #include <QThread>
9
10
10 Q_LOGGING_CATEGORY(LOG_CosinusProvider, "CosinusProvider")
11 Q_LOGGING_CATEGORY(LOG_CosinusProvider, "CosinusProvider")
11
12
@@ -39,6 +40,8 CosinusProvider::retrieveData(const DataProviderParameters &parameters) const
39
40
40 void CosinusProvider::requestDataLoading(const QVector<SqpDateTime> &dateTimeList)
41 void CosinusProvider::requestDataLoading(const QVector<SqpDateTime> &dateTimeList)
41 {
42 {
43 qCDebug(LOG_CosinusProvider()) << "CosinusProvider::requestDataLoading"
44 << QThread::currentThread()->objectName();
42 // NOTE: Try to use multithread if possible
45 // NOTE: Try to use multithread if possible
43 for (const auto &dateTime : dateTimeList) {
46 for (const auto &dateTime : dateTimeList) {
44 auto scalarSeries = this->retrieveData(DataProviderParameters{dateTime});
47 auto scalarSeries = this->retrieveData(DataProviderParameters{dateTime});
General Comments 0
You need to be logged in to leave comments. Login now