##// END OF EJS Templates
commit processRequest
Alexandre Leroux -
r682:d41b2e70981c
parent child
Show More
@@ -0,0 +1,27
1 #ifndef SCIQLOP_ACQUISITIONUTILS_H
2 #define SCIQLOP_ACQUISITIONUTILS_H
3
4 #include "CoreGlobal.h"
5
6 #include <QLoggingCategory>
7
8 Q_DECLARE_LOGGING_CATEGORY(LOG_AcquisitionUtils)
9
10 class SqpRange;
11
12 /**
13 * Possible types of zoom operation
14 */
15 enum class AcquisitionZoomType { ZoomOut, ZoomIn, PanRight, PanLeft, Unknown };
16
17 struct SCIQLOP_CORE_EXPORT AcquisitionUtils {
18 /**
19 * Returns the zoom operation which results from the two ranges passed in parameters
20 * @param range the range after operation
21 * @param oldRange the range before operation
22 * @return the operation type
23 */
24 static AcquisitionZoomType getZoomType(const SqpRange &range, const SqpRange &oldRange);
25 };
26
27 #endif // SCIQLOP_ACQUISITIONUTILS_H
@@ -0,0 +1,27
1 #include "Data/AcquisitionUtils.h"
2
3 #include "Data/SqpRange.h"
4
5 Q_LOGGING_CATEGORY(LOG_AcquisitionUtils, "AcquisitionUtils")
6
7 AcquisitionZoomType AcquisitionUtils::getZoomType(const SqpRange &range, const SqpRange &oldRange)
8 {
9 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
10 auto zoomType = AcquisitionZoomType::Unknown;
11 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
12 zoomType = AcquisitionZoomType::ZoomOut;
13 }
14 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
15 zoomType = AcquisitionZoomType::PanRight;
16 }
17 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
18 zoomType = AcquisitionZoomType::PanLeft;
19 }
20 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
21 zoomType = AcquisitionZoomType::ZoomIn;
22 }
23 else {
24 qCCritical(LOG_AcquisitionUtils()) << "getZoomType: Unknown type detected";
25 }
26 return zoomType;
27 }
@@ -1,88 +1,88
1 1 /*------------------------------------------------------------------------------
2 2 -- This file is a part of the QLop Software
3 3 -- Copyright (C) 2015, Plasma Physics Laboratory - CNRS
4 4 --
5 5 -- This program is free software; you can redistribute it and/or modify
6 6 -- it under the terms of the GNU General Public License as published by
7 7 -- the Free Software Foundation; either version 2 of the License, or
8 8 -- (at your option) any later version.
9 9 --
10 10 -- This program is distributed in the hope that it will be useful,
11 11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 -- GNU General Public License for more details.
14 14 --
15 15 -- You should have received a copy of the GNU General Public License
16 16 -- along with this program; if not, write to the Free Software
17 17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18 -------------------------------------------------------------------------------*/
19 19 /*-- Author : Alexis Jeandet
20 20 -- Mail : alexis.jeandet@member.fsf.org
21 21 ----------------------------------------------------------------------------*/
22 22 #include "MainWindow.h"
23 23 #include <QProcessEnvironment>
24 24 #include <QThread>
25 25 #include <SqpApplication.h>
26 26 #include <qglobal.h>
27 27
28 28 #include <Plugin/PluginManager.h>
29 29 #include <QDir>
30 30
31 31 #include <QLoggingCategory>
32 32
33 33 Q_LOGGING_CATEGORY(LOG_Main, "Main")
34 34
35 35 namespace {
36 36
37 37 const auto PLUGIN_DIRECTORY_NAME = QStringLiteral("plugins");
38 38
39 39
40 40 } // namespace
41 41
42 42 int main(int argc, char *argv[])
43 43 {
44 QLoggingCategory::setFilterRules(
45 "*.warning=false\n"
46 "*.info=false\n"
47 "*.debug=false\n"
48 "AmdaProvider.info=true\n"
49 "NetworkController.info=true\n"
50 "VariableAcquisitionWorker.info=true\n");
44 // QLoggingCategory::setFilterRules(
45 // "*.warning=false\n"
46 // "*.info=false\n"
47 // "*.debug=false\n"
48 // "AmdaProvider.info=true\n"
49 // "NetworkController.info=true\n"
50 // "VariableAcquisitionWorker.info=true\n");
51 51
52 52 SqpApplication a{argc, argv};
53 53 SqpApplication::setOrganizationName("LPP");
54 54 SqpApplication::setOrganizationDomain("lpp.fr");
55 55 SqpApplication::setApplicationName("SciQLop");
56 56 MainWindow w;
57 57 w.show();
58 58
59 59 // Loads plugins
60 60 auto pluginDir = QDir{a.applicationDirPath()};
61 61 auto pluginLookupPath = {
62 62 a.applicationDirPath(),
63 63 a.applicationDirPath() + "/" + PLUGIN_DIRECTORY_NAME,
64 64 a.applicationDirPath() + "/../lib64/SciQlop",
65 65 a.applicationDirPath() + "/../lib64/sciqlop",
66 66 a.applicationDirPath() + "/../lib/SciQlop",
67 67 a.applicationDirPath() + "/../lib/sciqlop",
68 68 a.applicationDirPath() + "/../plugins",
69 69 };
70 70
71 71 #if _WIN32 || _WIN64
72 72 pluginDir.mkdir(PLUGIN_DIRECTORY_NAME);
73 73 pluginDir.cd(PLUGIN_DIRECTORY_NAME);
74 74 #endif
75 75
76 76 PluginManager pluginManager{};
77 77
78 78 for (auto &&path : pluginLookupPath) {
79 79 QDir directory{path};
80 80 if (directory.exists()) {
81 81 qCDebug(LOG_Main())
82 82 << QObject::tr("Plugin directory: %1").arg(directory.absolutePath());
83 83 pluginManager.loadPlugins(directory);
84 84 }
85 85 }
86 86
87 87 return a.exec();
88 88 }
@@ -1,28 +1,26
1 1 #ifndef SCIQLOP_VARIABLEREQUEST_H
2 2 #define SCIQLOP_VARIABLEREQUEST_H
3 3
4 4 #include <QObject>
5 5
6 6 #include <QUuid>
7 7
8 8 #include <Common/MetaTypes.h>
9 9 #include <Data/IDataSeries.h>
10 10 #include <Data/SqpRange.h>
11 11
12 12 #include <memory>
13 13
14 14 /**
15 15 * @brief The VariableRequest struct holds the information of an acquisition request
16 16 */
17 17 struct VariableRequest {
18 VariableRequest() { m_CanUpdate = false; }
19
20 SqpRange m_RangeRequested;
21 SqpRange m_CacheRangeRequested;
22 std::shared_ptr<IDataSeries> m_DataSeries;
23 bool m_CanUpdate;
18 SqpRange m_RangeRequested{INVALID_RANGE};
19 SqpRange m_CacheRangeRequested{INVALID_RANGE};
20 std::shared_ptr<IDataSeries> m_DataSeries{nullptr};
21 bool m_CanUpdate{false};
24 22 };
25 23
26 24 SCIQLOP_REGISTER_META_TYPE(VARIABLEREQUEST_REGISTRY, VariableRequest)
27 25
28 26 #endif // SCIQLOP_VARIABLEREQUEST_H
@@ -1,133 +1,125
1 1 #ifndef SCIQLOP_VARIABLECONTROLLER_H
2 2 #define SCIQLOP_VARIABLECONTROLLER_H
3 3
4 4 #include "CoreGlobal.h"
5 5
6 6 #include <Data/AcquisitionDataPacket.h>
7 7 #include <Data/SqpRange.h>
8 8
9 9 #include <QLoggingCategory>
10 10 #include <QObject>
11 11 #include <QUuid>
12 12
13 13 #include <Common/spimpl.h>
14 14
15 15 class IDataProvider;
16 16 class QItemSelectionModel;
17 17 class TimeController;
18 18 class Variable;
19 19 class VariableModel;
20 20
21 21 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableController)
22 22
23
24 /**
25 * Possible types of zoom operation
26 */
27 enum class AcquisitionZoomType { ZoomOut, ZoomIn, PanRight, PanLeft, Unknown };
28
29
30 23 /**
31 24 * @brief The VariableController class aims to handle the variables in SciQlop.
32 25 */
33 26 class SCIQLOP_CORE_EXPORT VariableController : public QObject {
34 27 Q_OBJECT
35 28 public:
36 29 explicit VariableController(QObject *parent = 0);
37 30 virtual ~VariableController();
38 31
39 32 VariableModel *variableModel() noexcept;
40 33 QItemSelectionModel *variableSelectionModel() noexcept;
41 34
42 35 void setTimeController(TimeController *timeController) noexcept;
43 36
44 37 /**
45 38 * Clones the variable passed in parameter and adds the duplicate to the controller
46 39 * @param variable the variable to duplicate
47 40 * @return the duplicate created, nullptr if the variable couldn't be created
48 41 */
49 42 std::shared_ptr<Variable> cloneVariable(std::shared_ptr<Variable> variable) noexcept;
50 43
51 44 /**
52 45 * Deletes from the controller the variable passed in parameter.
53 46 *
54 47 * Delete a variable includes:
55 48 * - the deletion of the various references to the variable in SciQlop
56 49 * - the deletion of the model variable
57 50 * - the deletion of the provider associated with the variable
58 51 * - removing the cache associated with the variable
59 52 *
60 53 * @param variable the variable to delete from the controller.
61 54 */
62 55 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
63 56
64 57 /**
65 58 * Deletes from the controller the variables passed in parameter.
66 59 * @param variables the variables to delete from the controller.
67 60 * @sa deleteVariable()
68 61 */
69 62 void deleteVariables(const QVector<std::shared_ptr<Variable> > &variables) noexcept;
70 63
71 64 /**
72 65 * @brief abort the variable retrieve data progression
73 66 */
74 67 void abortProgress(std::shared_ptr<Variable> variable);
75 68
76 static AcquisitionZoomType getZoomType(const SqpRange &range, const SqpRange &oldRange);
77 69 signals:
78 70 /// Signal emitted when a variable is about to be deleted from the controller
79 71 void variableAboutToBeDeleted(std::shared_ptr<Variable> variable);
80 72
81 73 /// Signal emitted when a data acquisition is requested on a range for a variable
82 74 void rangeChanged(std::shared_ptr<Variable> variable, const SqpRange &range);
83 75
84 76 /// Signal emitted when a sub range of the cacheRange of the variable can be displayed
85 77 void updateVarDisplaying(std::shared_ptr<Variable> variable, const SqpRange &range);
86 78
87 79 public slots:
88 80 /// Request the data loading of the variable whithin range
89 81 void onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables, const SqpRange &range,
90 82 const SqpRange &oldRange, bool synchronise);
91 83 /**
92 84 * Creates a new variable and adds it to the model
93 85 * @param name the name of the new variable
94 86 * @param metadata the metadata of the new variable
95 87 * @param provider the data provider for the new variable
96 88 * @return the pointer to the new variable or nullptr if the creation failed
97 89 */
98 90 std::shared_ptr<Variable> createVariable(const QString &name, const QVariantHash &metadata,
99 91 std::shared_ptr<IDataProvider> provider) noexcept;
100 92
101 93 /// Update the temporal parameters of every selected variable to dateTime
102 94 void onDateTimeOnSelection(const SqpRange &dateTime);
103 95
104 96
105 97 void onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
106 98 const SqpRange &cacheRangeRequested,
107 99 QVector<AcquisitionDataPacket> dataAcquired);
108 100
109 101 void onVariableRetrieveDataInProgress(QUuid identifier, double progress);
110 102
111 103 /// Cancel the current request for the variable
112 104 void onAbortProgressRequested(std::shared_ptr<Variable> variable);
113 105
114 106 // synchronization group methods
115 107 void onAddSynchronizationGroupId(QUuid synchronizationGroupId);
116 108 void onRemoveSynchronizationGroupId(QUuid synchronizationGroupId);
117 109 void onAddSynchronized(std::shared_ptr<Variable> variable, QUuid synchronizationGroupId);
118 110
119 111 /// Desynchronizes the variable of the group whose identifier is passed in parameter
120 112 /// @remarks the method does nothing if the variable is not part of the group
121 113 void desynchronize(std::shared_ptr<Variable> variable, QUuid synchronizationGroupId);
122 114
123 115 void initialize();
124 116 void finalize();
125 117
126 118 private:
127 119 void waitForFinish();
128 120
129 121 class VariableControllerPrivate;
130 122 spimpl::unique_impl_ptr<VariableControllerPrivate> impl;
131 123 };
132 124
133 125 #endif // SCIQLOP_VARIABLECONTROLLER_H
@@ -1,63 +1,64
1 1
2 2 core_moc_headers = [
3 3 'include/Data/IDataProvider.h',
4 4 'include/DataSource/DataSourceController.h',
5 5 'include/DataSource/DataSourceItemAction.h',
6 6 'include/Network/NetworkController.h',
7 7 'include/Time/TimeController.h',
8 8 'include/Variable/Variable.h',
9 9 'include/Variable/VariableCacheController.h',
10 10 'include/Variable/VariableController.h',
11 11 'include/Variable/VariableAcquisitionWorker.h',
12 12 'include/Variable/VariableCacheStrategy.h',
13 13 'include/Variable/VariableSynchronizationGroup.h',
14 14 'include/Variable/VariableModel.h',
15 15 'include/Visualization/VisualizationController.h'
16 16 ]
17 17
18 18
19 19 core_moc_files = qt5.preprocess(moc_headers : core_moc_headers)
20 20
21 21 core_sources = [
22 22 'src/Common/DateUtils.cpp',
23 23 'src/Common/StringUtils.cpp',
24 'src/Data/AcquisitionUtils.cpp',
24 25 'src/Data/ScalarSeries.cpp',
25 26 'src/Data/DataSeriesIterator.cpp',
26 27 'src/Data/ArrayDataIterator.cpp',
27 28 'src/Data/VectorSeries.cpp',
28 29 'src/DataSource/DataSourceController.cpp',
29 30 'src/DataSource/DataSourceItem.cpp',
30 31 'src/DataSource/DataSourceItemAction.cpp',
31 32 'src/Network/NetworkController.cpp',
32 33 'src/Plugin/PluginManager.cpp',
33 34 'src/Settings/SqpSettingsDefs.cpp',
34 35 'src/Time/TimeController.cpp',
35 36 'src/Variable/Variable.cpp',
36 37 'src/Variable/VariableCacheController.cpp',
37 38 'src/Variable/VariableController.cpp',
38 39 'src/Variable/VariableAcquisitionWorker.cpp',
39 40 'src/Variable/VariableCacheStrategy.cpp',
40 41 'src/Variable/VariableSynchronizationGroup.cpp',
41 42 'src/Variable/VariableModel.cpp',
42 43 'src/Visualization/VisualizationController.cpp'
43 44 ]
44 45
45 46 core_inc = include_directories(['include', '../plugin/include'])
46 47
47 48 sciqlop_core_lib = library('sciqlopcore',
48 49 core_sources,
49 50 core_moc_files,
50 51 cpp_args : '-DCORE_LIB',
51 52 include_directories : core_inc,
52 53 dependencies : [qt5core, qt5network],
53 54 install : true
54 55 )
55 56
56 57
57 58 sciqlop_core = declare_dependency(link_with : sciqlop_core_lib,
58 59 include_directories : core_inc,
59 60 dependencies : [qt5core, qt5network])
60 61
61 62
62 63 subdir('tests')
63 64
This diff has been collapsed as it changes many lines, (600 lines changed) Show them Hide them
@@ -1,806 +1,702
1 1 #include <Variable/Variable.h>
2 2 #include <Variable/VariableAcquisitionWorker.h>
3 3 #include <Variable/VariableCacheStrategy.h>
4 4 #include <Variable/VariableController.h>
5 5 #include <Variable/VariableModel.h>
6 6 #include <Variable/VariableSynchronizationGroup.h>
7 7
8 #include <Data/AcquisitionUtils.h>
8 9 #include <Data/DataProviderParameters.h>
9 10 #include <Data/IDataProvider.h>
10 11 #include <Data/IDataSeries.h>
11 12 #include <Data/VariableRequest.h>
12 13 #include <Time/TimeController.h>
13 14
14 15 #include <QMutex>
15 16 #include <QThread>
16 17 #include <QUuid>
17 18 #include <QtCore/QItemSelectionModel>
18 19
19 20 #include <deque>
20 21 #include <set>
21 22 #include <unordered_map>
22 23
23 24 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
24 25
25 26 namespace {
26 27
27 28 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
28 29 const SqpRange &oldGraphRange)
29 30 {
30 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
31 auto zoomType = AcquisitionUtils::getZoomType(graphRange, oldGraphRange);
31 32
32 33 auto varRangeRequested = varRange;
33 34 switch (zoomType) {
34 35 case AcquisitionZoomType::ZoomIn: {
35 36 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
36 37 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
37 38 varRangeRequested.m_TStart += deltaLeft;
38 39 varRangeRequested.m_TEnd -= deltaRight;
39 40 break;
40 41 }
41 42
42 43 case AcquisitionZoomType::ZoomOut: {
43 44 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
44 45 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
45 46 varRangeRequested.m_TStart -= deltaLeft;
46 47 varRangeRequested.m_TEnd += deltaRight;
47 48 break;
48 49 }
49 50 case AcquisitionZoomType::PanRight: {
50 51 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
51 52 varRangeRequested.m_TStart += deltaRight;
52 53 varRangeRequested.m_TEnd += deltaRight;
53 54 break;
54 55 }
55 56 case AcquisitionZoomType::PanLeft: {
56 57 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
57 58 varRangeRequested.m_TStart -= deltaLeft;
58 59 varRangeRequested.m_TEnd -= deltaLeft;
59 60 break;
60 61 }
61 62 case AcquisitionZoomType::Unknown: {
62 63 qCCritical(LOG_VariableController())
63 64 << VariableController::tr("Impossible to synchronize: zoom type unknown");
64 65 break;
65 66 }
66 67 default:
67 68 qCCritical(LOG_VariableController()) << VariableController::tr(
68 69 "Impossible to synchronize: zoom type not take into account");
69 70 // No action
70 71 break;
71 72 }
72 73
73 74 return varRangeRequested;
74 75 }
75 }
76 } // namespace
76 77
77 78 struct VariableController::VariableControllerPrivate {
78 79 explicit VariableControllerPrivate(VariableController *parent)
79 80 : m_WorkingMutex{},
80 81 m_VariableModel{new VariableModel{parent}},
81 82 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
82 83 m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
83 84 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
84 85 q{parent}
85 86 {
86
87 87 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
88 88 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
89 89 }
90 90
91
92 91 virtual ~VariableControllerPrivate()
93 92 {
94 93 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
95 94 m_VariableAcquisitionWorkerThread.quit();
96 95 m_VariableAcquisitionWorkerThread.wait();
97 96 }
98 97
98 void processRequest(std::shared_ptr<Variable> variable, const SqpRange &rangeRequested)
99 {
100 Q_ASSERT(variable != nullptr);
101
102 if (!m_VariableModel->containsVariable(variable)) {
103 qCCritical(LOG_VariableController())
104 << QObject::tr("Can't process request for variable %1: variable is not registered")
105 .arg(variable->name());
106 return;
107 }
108
109 // Gets ranges in/out of variable range
110 auto requestRange
111 = m_VariableCacheStrategy->computeStrategyRanges(variable->range(), rangeRequested);
112 auto notInCacheRanges = variable->provideNotInCacheRangeList(requestRange.second);
113 auto inCacheRanges = variable->provideInCacheRangeList(requestRange.second);
114
115 // Creates request for out-of-cache ranges
116 if (!notInCacheRanges.isEmpty()) {
117 // Gets provider for request
118 if (auto provider = m_Providers.at(variable)) {
119 VariableRequest request{requestRange.first, requestRange.second};
120 // m_VariableAcquisitionWorker->pushVariableRequest();
121 }
122 }
123
124 // Calls UI update for in-cache range
125 if (!inCacheRanges.isEmpty()) {
126 emit q->updateVarDisplaying(variable, inCacheRanges.first());
127 }
128 }
99 129
100 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested,
101 QUuid varRequestId);
130 std::shared_ptr<Variable> findVariable(QUuid vIdentifier)
131 {
132 /// @todo ALX
133 std::shared_ptr<Variable> var;
134 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
102 135
103 QVector<SqpRange> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
104 const SqpRange &dateTime);
136 auto end = m_VariableToIdentifierMap.cend();
137 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
138 if (it != end) {
139 var = it->first;
140 }
141 else {
142 qCCritical(LOG_VariableController())
143 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
144 }
105 145
106 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
146 return var;
147 }
107 148 std::shared_ptr<IDataSeries>
108 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
149 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector)
150 {
151 /// @todo ALX
152 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
153 << acqDataPacketVector.size();
154 std::shared_ptr<IDataSeries> dataSeries;
155 if (!acqDataPacketVector.isEmpty()) {
156 dataSeries = acqDataPacketVector[0].m_DateSeries;
157 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
158 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
159 }
160 }
161 qCDebug(LOG_VariableController())
162 << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
163 << acqDataPacketVector.size();
164 return dataSeries;
165 }
109 166
110 void registerProvider(std::shared_ptr<IDataProvider> provider);
167 void registerProvider(std::shared_ptr<IDataProvider> provider)
168 {
169 Q_ASSERT(provider != nullptr);
170 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
171 &VariableAcquisitionWorker::onVariableDataAcquired);
172 connect(provider.get(), &IDataProvider::dataProvidedProgress,
173 m_VariableAcquisitionWorker.get(),
174 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
175 }
176
177 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
178 {
179 /// @todo ALX
180 QUuid varRequestId;
181 // auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
182 // if (varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.cend()) {
183 // auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
184 // varRequestId = varRequestIdQueue.front();
185 // auto varRequestIdToVarIdVarRequestMapIt
186 // = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
187 // if (varRequestIdToVarIdVarRequestMapIt !=
188 // m_VarRequestIdToVarIdVarRequestMap.cend()) {
189 // auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
190 // auto varIdToVarRequestMapIt = varIdToVarRequestMap.find(varId);
191 // if (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) {
192 // qCDebug(LOG_VariableController()) << tr("acceptVariableRequest");
193 // auto &varRequest = varIdToVarRequestMapIt->second;
194 // varRequest.m_DataSeries = dataSeries;
195 // varRequest.m_CanUpdate = true;
196 // }
197 // else {
198 // qCDebug(LOG_VariableController()) << tr("Impossible to
199 // acceptVariableRequest "
200 // "of a unknown variable id
201 // attached "
202 // "to a variableRequestId")
203 // << varRequestId << varId;
204 // }
205 // }
206 // else {
207 // qCCritical(LOG_VariableController())
208 // << tr("Impossible to acceptVariableRequest of a unknown
209 // variableRequestId")
210 // << varRequestId;
211 // }
212
213 // qCDebug(LOG_VariableController())
214 // << tr("1: erase REQUEST in QUEUE ?") << varRequestIdQueue.size();
215 // varRequestIdQueue.pop_front();
216 // qCDebug(LOG_VariableController())
217 // << tr("2: erase REQUEST in QUEUE ?") << varRequestIdQueue.size();
218 // if (varRequestIdQueue.empty()) {
219 // m_VarIdToVarRequestIdQueueMap.erase(varId);
220 // }
221 // }
222 // else {
223 // qCCritical(LOG_VariableController())
224 // << tr("Impossible to acceptVariableRequest of a unknown variable id") <<
225 // varId;
226 // }
111 227
112 void storeVariableRequest(QUuid varId, QUuid varRequestId, const VariableRequest &varRequest);
113 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries);
114 void updateVariableRequest(QUuid varRequestId);
115 void cancelVariableRequest(QUuid varRequestId);
228 return varRequestId;
229 }
230 void updateVariableRequest(QUuid varRequestId)
231 {
232 /// @todo ALX
233 // auto varRequestIdToVarIdVarRequestMapIt
234 // = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
235 // if (varRequestIdToVarIdVarRequestMapIt !=
236 // m_VarRequestIdToVarIdVarRequestMap.cend()) {
237 // bool processVariableUpdate = true;
238 // auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
239 // for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
240 // (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) &&
241 // processVariableUpdate;
242 // ++varIdToVarRequestMapIt) {
243 // processVariableUpdate &= varIdToVarRequestMapIt->second.m_CanUpdate;
244 // qCDebug(LOG_VariableController())
245 // << tr("updateVariableRequest") << processVariableUpdate;
246 // }
247
248 // if (processVariableUpdate) {
249 // for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
250 // varIdToVarRequestMapIt != varIdToVarRequestMap.cend();
251 // ++varIdToVarRequestMapIt) {
252 // if (auto var = findVariable(varIdToVarRequestMapIt->first)) {
253 // auto &varRequest = varIdToVarRequestMapIt->second;
254 // var->setRange(varRequest.m_RangeRequested);
255 // var->setCacheRange(varRequest.m_CacheRangeRequested);
256 // qCDebug(LOG_VariableController())
257 // << tr("1: onDataProvided") << varRequest.m_RangeRequested;
258 // qCDebug(LOG_VariableController())
259 // << tr("2: onDataProvided") <<
260 // varRequest.m_CacheRangeRequested;
261 // var->mergeDataSeries(varRequest.m_DataSeries);
262 // qCDebug(LOG_VariableController())
263 // << tr("3: onDataProvided") <<
264 // varRequest.m_DataSeries->range();
265 // qCDebug(LOG_VariableController()) << tr("4: onDataProvided");
266
267 // /// @todo MPL: confirm
268 // // Variable update is notified only if there is no pending request
269 // for it
270 // if
271 // (m_VarIdToVarRequestIdQueueMap.count(varIdToVarRequestMapIt->first)
272 // == 0) {
273 // emit var->updated();
274 // }
275 // }
276 // else {
277 // qCCritical(LOG_VariableController())
278 // << tr("Impossible to update data to a null variable");
279 // }
280 // }
281
282 // // cleaning varRequestId
283 // qCDebug(LOG_VariableController()) << tr("0: erase REQUEST in MAP ?")
284 // <<
285 // m_VarRequestIdToVarIdVarRequestMap.size();
286 // m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
287 // qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in MAP ?")
288 // <<
289 // m_VarRequestIdToVarIdVarRequestMap.size();
290 // }
291 // }
292 // else {
293 // qCCritical(LOG_VariableController())
294 // << tr("Cannot updateVariableRequest for a unknow varRequestId") <<
295 // varRequestId;
296 // }
297 }
298
299 void cancelVariableRequest(QUuid varRequestId)
300 {
301 /// @todo ALX
302 // // cleaning varRequestId
303 // m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
304
305 // for (auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.begin();
306 // varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.end();) {
307 // auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
308 // varRequestIdQueue.erase(
309 // std::remove(varRequestIdQueue.begin(), varRequestIdQueue.end(),
310 // varRequestId),
311 // varRequestIdQueue.end());
312 // if (varRequestIdQueue.empty()) {
313 // varIdToVarRequestIdQueueMapIt
314 // = m_VarIdToVarRequestIdQueueMap.erase(varIdToVarRequestIdQueueMapIt);
315 // }
316 // else {
317 // ++varIdToVarRequestIdQueueMapIt;
318 // }
319 // }
320 }
116 321
117 322 QMutex m_WorkingMutex;
118 323 /// Variable model. The VariableController has the ownership
119 324 VariableModel *m_VariableModel;
120 325 QItemSelectionModel *m_VariableSelectionModel;
121 326
122
123 327 TimeController *m_TimeController{nullptr};
124 328 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
125 329 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
126 330 QThread m_VariableAcquisitionWorkerThread;
127 331
128 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
129 m_VariableToProviderMap;
332 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> > m_Providers;
130 333 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
131 334 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
132 335 m_GroupIdToVariableSynchronizationGroupMap;
133 336 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
134 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
135
136 std::map<QUuid, std::map<QUuid, VariableRequest> > m_VarRequestIdToVarIdVarRequestMap;
137
138 std::map<QUuid, std::deque<QUuid> > m_VarIdToVarRequestIdQueueMap;
139
140 337
141 338 VariableController *q;
142 339 };
143 340
144
145 341 VariableController::VariableController(QObject *parent)
146 342 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
147 343 {
148 344 qCDebug(LOG_VariableController())
149 345 << tr("VariableController construction") << QThread::currentThread();
150 346
151 347 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
152 348 &VariableController::onAbortProgressRequested);
153 349
154 350 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
155 351 &VariableController::onDataProvided);
156 352 connect(impl->m_VariableAcquisitionWorker.get(),
157 353 &VariableAcquisitionWorker::variableRequestInProgress, this,
158 354 &VariableController::onVariableRetrieveDataInProgress);
159 355
160 356 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
161 357 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
162 358 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
163 359 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
164 360
165 361
166 362 impl->m_VariableAcquisitionWorkerThread.start();
167 363 }
168 364
169 365 VariableController::~VariableController()
170 366 {
171 367 qCDebug(LOG_VariableController())
172 368 << tr("VariableController destruction") << QThread::currentThread();
173 369 this->waitForFinish();
174 370 }
175 371
176 372 VariableModel *VariableController::variableModel() noexcept
177 373 {
178 374 return impl->m_VariableModel;
179 375 }
180 376
181 377 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
182 378 {
183 379 return impl->m_VariableSelectionModel;
184 380 }
185 381
186 382 void VariableController::setTimeController(TimeController *timeController) noexcept
187 383 {
188 384 impl->m_TimeController = timeController;
189 385 }
190 386
191 387 std::shared_ptr<Variable>
192 388 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
193 389 {
194 390 if (impl->m_VariableModel->containsVariable(variable)) {
195 391 // Clones variable
196 392 auto duplicate = variable->clone();
197 393
198 394 // Adds clone to model
199 395 impl->m_VariableModel->addVariable(duplicate);
200 396
201 397 // Generates clone identifier
202 398 impl->m_VariableToIdentifierMap[duplicate] = QUuid::createUuid();
203 399
204 400 // Registers provider
205 auto variableProvider = impl->m_VariableToProviderMap.at(variable);
401 auto variableProvider = impl->m_Providers.at(variable);
206 402 auto duplicateProvider = variableProvider != nullptr ? variableProvider->clone() : nullptr;
207 403
208 impl->m_VariableToProviderMap[duplicate] = duplicateProvider;
404 impl->m_Providers[duplicate] = duplicateProvider;
209 405 if (duplicateProvider) {
210 406 impl->registerProvider(duplicateProvider);
211 407 }
212 408
213 409 return duplicate;
214 410 }
215 411 else {
216 412 qCCritical(LOG_VariableController())
217 413 << tr("Can't create duplicate of variable %1: variable not registered in the model")
218 414 .arg(variable->name());
219 415 return nullptr;
220 416 }
221 417 }
222 418
223 419 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
224 420 {
225 421 if (!variable) {
226 422 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
227 423 return;
228 424 }
229 425
230 426 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
231 427 // make some treatments before the deletion
232 428 emit variableAboutToBeDeleted(variable);
233 429
234 430 // Deletes identifier
235 431 impl->m_VariableToIdentifierMap.erase(variable);
236 432
237 433 // Deletes provider
238 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
434 auto nbProvidersDeleted = impl->m_Providers.erase(variable);
239 435 qCDebug(LOG_VariableController())
240 436 << tr("Number of providers deleted for variable %1: %2")
241 437 .arg(variable->name(), QString::number(nbProvidersDeleted));
242 438
243 439
244 440 // Deletes from model
245 441 impl->m_VariableModel->deleteVariable(variable);
246 442 }
247 443
248 444 void VariableController::deleteVariables(
249 445 const QVector<std::shared_ptr<Variable> > &variables) noexcept
250 446 {
251 447 for (auto variable : qAsConst(variables)) {
252 448 deleteVariable(variable);
253 449 }
254 450 }
255 451
256 452 void VariableController::abortProgress(std::shared_ptr<Variable> variable)
257 453 {
258 454 }
259 455
260 456 std::shared_ptr<Variable>
261 457 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
262 458 std::shared_ptr<IDataProvider> provider) noexcept
263 459 {
264 460 if (!impl->m_TimeController) {
265 461 qCCritical(LOG_VariableController())
266 462 << tr("Impossible to create variable: The time controller is null");
267 463 return nullptr;
268 464 }
269 465
270 466 auto range = impl->m_TimeController->dateTime();
271 467
272 468 if (auto newVariable = impl->m_VariableModel->createVariable(name, range, metadata)) {
273 469 auto identifier = QUuid::createUuid();
274 470
275 471 // store the provider
276 472 impl->registerProvider(provider);
277 473
278 474 // Associate the provider
279 impl->m_VariableToProviderMap[newVariable] = provider;
475 impl->m_Providers[newVariable] = provider;
280 476 impl->m_VariableToIdentifierMap[newVariable] = identifier;
281 477
282
283 auto varRequestId = QUuid::createUuid();
284 qCInfo(LOG_VariableController()) << "processRequest for" << name << varRequestId;
285 impl->processRequest(newVariable, range, varRequestId);
286 impl->updateVariableRequest(varRequestId);
478 impl->processRequest(newVariable, range);
479 /// @todo ALX
480 // impl->updateVariableRequest(varRequestId);
287 481
288 482 return newVariable;
289 483 }
290 484 }
291 485
292 486 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
293 487 {
294 488 // TODO check synchronisation and Rescale
295 489 qCDebug(LOG_VariableController())
296 490 << "VariableController::onDateTimeOnSelection" << QThread::currentThread()->objectName();
297 491 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
298 auto varRequestId = QUuid::createUuid();
299
300 492 for (const auto &selectedRow : qAsConst(selectedRows)) {
301 493 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
302 494 selectedVariable->setRange(dateTime);
303 impl->processRequest(selectedVariable, dateTime, varRequestId);
495 impl->processRequest(selectedVariable, dateTime);
304 496
305 497 // notify that rescale operation has to be done
306 498 emit rangeChanged(selectedVariable, dateTime);
307 499 }
308 500 }
309 impl->updateVariableRequest(varRequestId);
501
502 /// @todo ALX
503 // impl->updateVariableRequest(varRequestId);
310 504 }
311 505
312 506 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
313 507 const SqpRange &cacheRangeRequested,
314 508 QVector<AcquisitionDataPacket> dataAcquired)
315 509 {
316 510 qCInfo(LOG_VariableController()) << "VariableController::onDataProvided";
317 511 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
318 512 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
319 513 if (!varRequestId.isNull()) {
320 514 impl->updateVariableRequest(varRequestId);
321 515 }
322 516 }
323 517
324 518 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
325 519 {
326 520 if (auto var = impl->findVariable(identifier)) {
327 521 impl->m_VariableModel->setDataProgress(var, progress);
328 522 }
329 523 else {
330 524 qCCritical(LOG_VariableController())
331 525 << tr("Impossible to notify progression of a null variable");
332 526 }
333 527 }
334 528
335 529 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
336 530 {
337 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
338 << QThread::currentThread()->objectName();
531 /// @todo ALX
532 // qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
533 // << QThread::currentThread()->objectName();
339 534
340 auto it = impl->m_VariableToIdentifierMap.find(variable);
341 if (it != impl->m_VariableToIdentifierMap.cend()) {
342 impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
343 }
344 else {
345 qCWarning(LOG_VariableController())
346 << tr("Aborting progression of inexistant variable detected !!!")
347 << QThread::currentThread()->objectName();
348 }
535 // auto it = impl->m_VariableToIdentifierMap.find(variable);
536 // if (it != impl->m_VariableToIdentifierMap.cend()) {
537 // impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
538 // }
539 // else {
540 // qCWarning(LOG_VariableController())
541 // << tr("Aborting progression of inexistant variable detected !!!")
542 // << QThread::currentThread()->objectName();
543 // }
349 544 }
350 545
351 546 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
352 547 {
353 548 qCDebug(LOG_VariableController())
354 549 << "TORM: VariableController::onAddSynchronizationGroupId"
355 550 << QThread::currentThread()->objectName() << synchronizationGroupId;
356 551 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
357 552 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
358 553 std::make_pair(synchronizationGroupId, vSynchroGroup));
359 554 }
360 555
361 556 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
362 557 {
363 558 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
364 559 }
365 560
366 561 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
367 562 QUuid synchronizationGroupId)
368 563
369 564 {
370 565 qCDebug(LOG_VariableController())
371 566 << "TORM: VariableController::onAddSynchronized" << synchronizationGroupId;
372 567 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
373 568 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
374 569 auto groupIdToVSGIt
375 570 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
376 571 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
377 572 impl->m_VariableIdGroupIdMap.insert(
378 573 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
379 574 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
380 575 }
381 576 else {
382 577 qCCritical(LOG_VariableController())
383 578 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
384 579 << variable->name();
385 580 }
386 581 }
387 582 else {
388 583 qCCritical(LOG_VariableController())
389 584 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
390 585 }
391 586 }
392 587
393 588 void VariableController::desynchronize(std::shared_ptr<Variable> variable,
394 589 QUuid synchronizationGroupId)
395 590 {
396 591 // Gets variable id
397 592 auto variableIt = impl->m_VariableToIdentifierMap.find(variable);
398 593 if (variableIt == impl->m_VariableToIdentifierMap.cend()) {
399 594 qCCritical(LOG_VariableController())
400 595 << tr("Can't desynchronize variable %1: variable identifier not found")
401 596 .arg(variable->name());
402 597 return;
403 598 }
404 599
405 600 // Gets synchronization group
406 601 auto groupIt = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
407 602 if (groupIt == impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
408 603 qCCritical(LOG_VariableController())
409 604 << tr("Can't desynchronize variable %1: unknown synchronization group")
410 605 .arg(variable->name());
411 606 return;
412 607 }
413 608
414 609 auto variableId = variableIt->second;
415 610
416 611 // Removes variable from synchronization group
417 612 auto synchronizationGroup = groupIt->second;
418 613 synchronizationGroup->removeVariableId(variableId);
419 614
420 615 // Removes link between variable and synchronization group
421 616 impl->m_VariableIdGroupIdMap.erase(variableId);
422 617 }
423 618
424 619 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
425 620 const SqpRange &range, const SqpRange &oldRange,
426 621 bool synchronise)
427 622 {
428 623 // NOTE: oldRange isn't really necessary since oldRange == variable->range().
429 624
430 625 // we want to load data of the variable for the dateTime.
431 626 // First we check if the cache contains some of them.
432 627 // For the other, we ask the provider to give them.
433
434 auto varRequestId = QUuid::createUuid();
435 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
436 << QThread::currentThread()->objectName() << varRequestId;
437
438 628 for (const auto &var : variables) {
439 qCDebug(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId;
440 impl->processRequest(var, range, varRequestId);
629 impl->processRequest(var, range);
441 630 }
442 631
443 632 if (synchronise) {
444 633 // Get the group ids
445 634 qCDebug(LOG_VariableController())
446 635 << "TORM VariableController::onRequestDataLoading for synchro var ENABLE";
447 636 auto groupIds = std::set<QUuid>{};
448 637 auto groupIdToOldRangeMap = std::map<QUuid, SqpRange>{};
449 638 for (const auto &var : variables) {
450 639 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(var);
451 640 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
452 641 auto vId = varToVarIdIt->second;
453 642 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
454 643 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
455 644 auto gId = varIdToGroupIdIt->second;
456 645 groupIdToOldRangeMap.insert(std::make_pair(gId, var->range()));
457 646 if (groupIds.find(gId) == groupIds.cend()) {
458 647 qCDebug(LOG_VariableController()) << "Synchro detect group " << gId;
459 648 groupIds.insert(gId);
460 649 }
461 650 }
462 651 }
463 652 }
464 653
465 654 // We assume here all group ids exist
466 655 for (const auto &gId : groupIds) {
467 656 auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId);
468 657 auto vSyncIds = vSynchronizationGroup->getIds();
469 658 qCDebug(LOG_VariableController()) << "Var in synchro group ";
470 659 for (auto vId : vSyncIds) {
471 660 auto var = impl->findVariable(vId);
472 661
473 662 // Don't process already processed var
474 663 if (!variables.contains(var)) {
475 664 if (var != nullptr) {
476 665 qCDebug(LOG_VariableController())
477 666 << "processRequest synchro for" << var->name();
478 667 auto vSyncRangeRequested = computeSynchroRangeRequested(
479 668 var->range(), range, groupIdToOldRangeMap.at(gId));
480 669 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
481 impl->processRequest(var, vSyncRangeRequested, varRequestId);
670 impl->processRequest(var, vSyncRangeRequested);
482 671 }
483 672 else {
484 673 qCCritical(LOG_VariableController())
485 674
486 675 << tr("Impossible to synchronize a null variable");
487 676 }
488 677 }
489 678 }
490 679 }
491 680 }
492 681
493 impl->updateVariableRequest(varRequestId);
682 /// @todo ALX
683 // impl->updateVariableRequest(varRequestId);
494 684 }
495 685
496 686
497 687 void VariableController::initialize()
498 688 {
499 689 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
500 690 impl->m_WorkingMutex.lock();
501 691 qCDebug(LOG_VariableController()) << tr("VariableController init END");
502 692 }
503 693
504 694 void VariableController::finalize()
505 695 {
506 696 impl->m_WorkingMutex.unlock();
507 697 }
508 698
509 699 void VariableController::waitForFinish()
510 700 {
511 701 QMutexLocker locker{&impl->m_WorkingMutex};
512 702 }
513
514 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
515 {
516 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
517 auto zoomType = AcquisitionZoomType::Unknown;
518 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
519 zoomType = AcquisitionZoomType::ZoomOut;
520 }
521 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
522 zoomType = AcquisitionZoomType::PanRight;
523 }
524 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
525 zoomType = AcquisitionZoomType::PanLeft;
526 }
527 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
528 zoomType = AcquisitionZoomType::ZoomIn;
529 }
530 else {
531 qCCritical(LOG_VariableController()) << "getZoomType: Unknown type detected";
532 }
533 return zoomType;
534 }
535
536 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
537 const SqpRange &rangeRequested,
538 QUuid varRequestId)
539 {
540
541 // TODO: protect at
542 auto varRequest = VariableRequest{};
543 auto varId = m_VariableToIdentifierMap.at(var);
544
545 auto varStrategyRangesRequested
546 = m_VariableCacheStrategy->computeStrategyRanges(var->range(), rangeRequested);
547 auto notInCacheRangeList = var->provideNotInCacheRangeList(varStrategyRangesRequested.second);
548 auto inCacheRangeList = var->provideInCacheRangeList(varStrategyRangesRequested.second);
549
550 if (!notInCacheRangeList.empty()) {
551 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
552 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
553 qCInfo(LOG_VariableController()) << tr("TORM processRequest RR ") << rangeRequested;
554 qCInfo(LOG_VariableController())
555 << tr("TORM processRequest R ") << varStrategyRangesRequested.first;
556 qCInfo(LOG_VariableController())
557 << tr("TORM processRequest CR ") << varStrategyRangesRequested.second;
558 // store VarRequest
559 storeVariableRequest(varId, varRequestId, varRequest);
560
561 auto varProvider = m_VariableToProviderMap.at(var);
562 if (varProvider != nullptr) {
563 auto varRequestIdCanceled = m_VariableAcquisitionWorker->pushVariableRequest(
564 varRequestId, varId, varStrategyRangesRequested.first,
565 varStrategyRangesRequested.second,
566 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
567 varProvider);
568
569 if (!varRequestIdCanceled.isNull()) {
570 qCInfo(LOG_VariableController())
571 << tr("varRequestIdCanceled: ") << varRequestIdCanceled;
572 cancelVariableRequest(varRequestIdCanceled);
573 }
574 }
575 else {
576 qCCritical(LOG_VariableController())
577 << "Impossible to provide data with a null provider";
578 }
579
580 if (!inCacheRangeList.empty()) {
581 emit q->updateVarDisplaying(var, inCacheRangeList.first());
582 }
583 }
584 else {
585
586 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
587 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
588 // store VarRequest
589 storeVariableRequest(varId, varRequestId, varRequest);
590 acceptVariableRequest(varId,
591 var->dataSeries()->subDataSeries(varStrategyRangesRequested.second));
592 }
593 }
594
595 std::shared_ptr<Variable>
596 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
597 {
598 std::shared_ptr<Variable> var;
599 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
600
601 auto end = m_VariableToIdentifierMap.cend();
602 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
603 if (it != end) {
604 var = it->first;
605 }
606 else {
607 qCCritical(LOG_VariableController())
608 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
609 }
610
611 return var;
612 }
613
614 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
615 const QVector<AcquisitionDataPacket> acqDataPacketVector)
616 {
617 qCDebug(LOG_VariableController())
618 << tr("TORM: retrieveDataSeries acqDataPacketVector size") << acqDataPacketVector.size();
619 std::shared_ptr<IDataSeries> dataSeries;
620 if (!acqDataPacketVector.isEmpty()) {
621 dataSeries = acqDataPacketVector[0].m_DateSeries;
622 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
623 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
624 }
625 }
626 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
627 << acqDataPacketVector.size();
628 return dataSeries;
629 }
630
631 void VariableController::VariableControllerPrivate::registerProvider(
632 std::shared_ptr<IDataProvider> provider)
633 {
634 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
635 qCDebug(LOG_VariableController())
636 << tr("Registering of a new provider") << provider->objectName();
637 m_ProviderSet.insert(provider);
638 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
639 &VariableAcquisitionWorker::onVariableDataAcquired);
640 connect(provider.get(), &IDataProvider::dataProvidedProgress,
641 m_VariableAcquisitionWorker.get(),
642 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
643 }
644 else {
645 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
646 }
647 }
648
649 void VariableController::VariableControllerPrivate::storeVariableRequest(
650 QUuid varId, QUuid varRequestId, const VariableRequest &varRequest)
651 {
652 // First request for the variable. we can create an entry for it
653 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
654 if (varIdToVarRequestIdQueueMapIt == m_VarIdToVarRequestIdQueueMap.cend()) {
655 auto varRequestIdQueue = std::deque<QUuid>{};
656 qCInfo(LOG_VariableController()) << tr("Store REQUEST in QUEUE");
657 varRequestIdQueue.push_back(varRequestId);
658 m_VarIdToVarRequestIdQueueMap.insert(std::make_pair(varId, std::move(varRequestIdQueue)));
659 }
660 else {
661 qCInfo(LOG_VariableController()) << tr("Store REQUEST in EXISTING QUEUE");
662 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
663 varRequestIdQueue.push_back(varRequestId);
664 }
665
666 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
667 if (varRequestIdToVarIdVarRequestMapIt == m_VarRequestIdToVarIdVarRequestMap.cend()) {
668 auto varIdToVarRequestMap = std::map<QUuid, VariableRequest>{};
669 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
670 qCInfo(LOG_VariableController()) << tr("Store REQUESTID in MAP");
671 m_VarRequestIdToVarIdVarRequestMap.insert(
672 std::make_pair(varRequestId, std::move(varIdToVarRequestMap)));
673 }
674 else {
675 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
676 qCInfo(LOG_VariableController()) << tr("Store REQUESTID in EXISTING MAP");
677 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
678 }
679 }
680
681 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
682 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
683 {
684 QUuid varRequestId;
685 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
686 if (varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.cend()) {
687 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
688 varRequestId = varRequestIdQueue.front();
689 auto varRequestIdToVarIdVarRequestMapIt
690 = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
691 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
692 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
693 auto varIdToVarRequestMapIt = varIdToVarRequestMap.find(varId);
694 if (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) {
695 qCDebug(LOG_VariableController()) << tr("acceptVariableRequest");
696 auto &varRequest = varIdToVarRequestMapIt->second;
697 varRequest.m_DataSeries = dataSeries;
698 varRequest.m_CanUpdate = true;
699 }
700 else {
701 qCDebug(LOG_VariableController())
702 << tr("Impossible to acceptVariableRequest of a unknown variable id attached "
703 "to a variableRequestId")
704 << varRequestId << varId;
705 }
706 }
707 else {
708 qCCritical(LOG_VariableController())
709 << tr("Impossible to acceptVariableRequest of a unknown variableRequestId")
710 << varRequestId;
711 }
712
713 qCDebug(LOG_VariableController())
714 << tr("1: erase REQUEST in QUEUE ?") << varRequestIdQueue.size();
715 varRequestIdQueue.pop_front();
716 qCDebug(LOG_VariableController())
717 << tr("2: erase REQUEST in QUEUE ?") << varRequestIdQueue.size();
718 if (varRequestIdQueue.empty()) {
719 m_VarIdToVarRequestIdQueueMap.erase(varId);
720 }
721 }
722 else {
723 qCCritical(LOG_VariableController())
724 << tr("Impossible to acceptVariableRequest of a unknown variable id") << varId;
725 }
726
727 return varRequestId;
728 }
729
730 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
731 {
732
733 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
734 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
735 bool processVariableUpdate = true;
736 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
737 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
738 (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) && processVariableUpdate;
739 ++varIdToVarRequestMapIt) {
740 processVariableUpdate &= varIdToVarRequestMapIt->second.m_CanUpdate;
741 qCDebug(LOG_VariableController())
742 << tr("updateVariableRequest") << processVariableUpdate;
743 }
744
745 if (processVariableUpdate) {
746 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
747 varIdToVarRequestMapIt != varIdToVarRequestMap.cend(); ++varIdToVarRequestMapIt) {
748 if (auto var = findVariable(varIdToVarRequestMapIt->first)) {
749 auto &varRequest = varIdToVarRequestMapIt->second;
750 var->setRange(varRequest.m_RangeRequested);
751 var->setCacheRange(varRequest.m_CacheRangeRequested);
752 qCDebug(LOG_VariableController())
753 << tr("1: onDataProvided") << varRequest.m_RangeRequested;
754 qCDebug(LOG_VariableController())
755 << tr("2: onDataProvided") << varRequest.m_CacheRangeRequested;
756 var->mergeDataSeries(varRequest.m_DataSeries);
757 qCDebug(LOG_VariableController())
758 << tr("3: onDataProvided") << varRequest.m_DataSeries->range();
759 qCDebug(LOG_VariableController()) << tr("4: onDataProvided");
760
761 /// @todo MPL: confirm
762 // Variable update is notified only if there is no pending request for it
763 if (m_VarIdToVarRequestIdQueueMap.count(varIdToVarRequestMapIt->first) == 0) {
764 emit var->updated();
765 }
766 }
767 else {
768 qCCritical(LOG_VariableController())
769 << tr("Impossible to update data to a null variable");
770 }
771 }
772
773 // cleaning varRequestId
774 qCDebug(LOG_VariableController())
775 << tr("0: erase REQUEST in MAP ?") << m_VarRequestIdToVarIdVarRequestMap.size();
776 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
777 qCDebug(LOG_VariableController())
778 << tr("1: erase REQUEST in MAP ?") << m_VarRequestIdToVarIdVarRequestMap.size();
779 }
780 }
781 else {
782 qCCritical(LOG_VariableController())
783 << tr("Cannot updateVariableRequest for a unknow varRequestId") << varRequestId;
784 }
785 }
786
787 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
788 {
789 // cleaning varRequestId
790 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
791
792 for (auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.begin();
793 varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.end();) {
794 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
795 varRequestIdQueue.erase(
796 std::remove(varRequestIdQueue.begin(), varRequestIdQueue.end(), varRequestId),
797 varRequestIdQueue.end());
798 if (varRequestIdQueue.empty()) {
799 varIdToVarRequestIdQueueMapIt
800 = m_VarIdToVarRequestIdQueueMap.erase(varIdToVarRequestIdQueueMapIt);
801 }
802 else {
803 ++varIdToVarRequestIdQueueMapIt;
804 }
805 }
806 }
@@ -1,302 +1,303
1 1 #include "Visualization/VisualizationZoneWidget.h"
2 2
3 3 #include "Visualization/IVisualizationWidgetVisitor.h"
4 4 #include "Visualization/QCustomPlotSynchronizer.h"
5 5 #include "Visualization/VisualizationGraphWidget.h"
6 6 #include "ui_VisualizationZoneWidget.h"
7 7
8 #include <Data/AcquisitionUtils.h>
8 9 #include <Data/SqpRange.h>
9 10 #include <Variable/Variable.h>
10 11 #include <Variable/VariableController.h>
11 12
12 13 #include <QUuid>
13 14 #include <SqpApplication.h>
14 15 #include <cmath>
15 16
16 17 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
17 18
18 19 namespace {
19 20
20 21 /// Minimum height for graph added in zones (in pixels)
21 22 const auto GRAPH_MINIMUM_HEIGHT = 300;
22 23
23 24 /// Generates a default name for a new graph, according to the number of graphs already displayed in
24 25 /// the zone
25 26 QString defaultGraphName(const QLayout &layout)
26 27 {
27 28 auto count = 0;
28 29 for (auto i = 0; i < layout.count(); ++i) {
29 30 if (dynamic_cast<VisualizationGraphWidget *>(layout.itemAt(i)->widget())) {
30 31 count++;
31 32 }
32 33 }
33 34
34 35 return QObject::tr("Graph %1").arg(count + 1);
35 36 }
36 37
37 38 /**
38 39 * Applies a function to all graphs of the zone represented by its layout
39 40 * @param layout the layout that contains graphs
40 41 * @param fun the function to apply to each graph
41 42 */
42 43 template <typename Fun>
43 44 void processGraphs(QLayout &layout, Fun fun)
44 45 {
45 46 for (auto i = 0; i < layout.count(); ++i) {
46 47 if (auto item = layout.itemAt(i)) {
47 48 if (auto visualizationGraphWidget
48 49 = dynamic_cast<VisualizationGraphWidget *>(item->widget())) {
49 50 fun(*visualizationGraphWidget);
50 51 }
51 52 }
52 53 }
53 54 }
54 55
55 56 } // namespace
56 57
57 58 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
58 59
59 60 explicit VisualizationZoneWidgetPrivate()
60 61 : m_SynchronisationGroupId{QUuid::createUuid()},
61 62 m_Synchronizer{std::make_unique<QCustomPlotSynchronizer>()}
62 63 {
63 64 }
64 65 QUuid m_SynchronisationGroupId;
65 66 std::unique_ptr<IGraphSynchronizer> m_Synchronizer;
66 67 };
67 68
68 69 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
69 70 : QWidget{parent},
70 71 ui{new Ui::VisualizationZoneWidget},
71 72 impl{spimpl::make_unique_impl<VisualizationZoneWidgetPrivate>()}
72 73 {
73 74 ui->setupUi(this);
74 75
75 76 ui->zoneNameLabel->setText(name);
76 77
77 78 // 'Close' options : widget is deleted when closed
78 79 setAttribute(Qt::WA_DeleteOnClose);
79 80 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
80 81 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
81 82
82 83 // Synchronisation id
83 84 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronizationGroupId",
84 85 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
85 86 }
86 87
87 88 VisualizationZoneWidget::~VisualizationZoneWidget()
88 89 {
89 90 delete ui;
90 91 }
91 92
92 93 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
93 94 {
94 95 // Synchronize new graph with others in the zone
95 96 impl->m_Synchronizer->addGraph(*graphWidget);
96 97
97 98 ui->visualizationZoneFrame->layout()->addWidget(graphWidget);
98 99 }
99 100
100 101 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
101 102 {
102 103 auto graphWidget = new VisualizationGraphWidget{
103 104 defaultGraphName(*ui->visualizationZoneFrame->layout()), this};
104 105
105 106
106 107 // Set graph properties
107 108 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
108 109 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
109 110
110 111
111 112 // Lambda to synchronize zone widget
112 113 auto synchronizeZoneWidget = [this, graphWidget](const SqpRange &graphRange,
113 114 const SqpRange &oldGraphRange) {
114 115
115 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
116 auto zoomType = AcquisitionUtils::getZoomType(graphRange, oldGraphRange);
116 117 auto frameLayout = ui->visualizationZoneFrame->layout();
117 118 for (auto i = 0; i < frameLayout->count(); ++i) {
118 119 auto graphChild
119 120 = dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
120 121 if (graphChild && (graphChild != graphWidget)) {
121 122
122 123 auto graphChildRange = graphChild->graphRange();
123 124 switch (zoomType) {
124 125 case AcquisitionZoomType::ZoomIn: {
125 126 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
126 127 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
127 128 graphChildRange.m_TStart += deltaLeft;
128 129 graphChildRange.m_TEnd -= deltaRight;
129 130 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomIn");
130 131 qCDebug(LOG_VisualizationZoneWidget())
131 132 << tr("TORM: deltaLeft") << deltaLeft;
132 133 qCDebug(LOG_VisualizationZoneWidget())
133 134 << tr("TORM: deltaRight") << deltaRight;
134 135 qCDebug(LOG_VisualizationZoneWidget())
135 136 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
136 137
137 138 break;
138 139 }
139 140
140 141 case AcquisitionZoomType::ZoomOut: {
141 142 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomOut");
142 143 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
143 144 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
144 145 qCDebug(LOG_VisualizationZoneWidget())
145 146 << tr("TORM: deltaLeft") << deltaLeft;
146 147 qCDebug(LOG_VisualizationZoneWidget())
147 148 << tr("TORM: deltaRight") << deltaRight;
148 149 qCDebug(LOG_VisualizationZoneWidget())
149 150 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
150 151 graphChildRange.m_TStart -= deltaLeft;
151 152 graphChildRange.m_TEnd += deltaRight;
152 153 break;
153 154 }
154 155 case AcquisitionZoomType::PanRight: {
155 156 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanRight");
156 157 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
157 158 graphChildRange.m_TStart += deltaRight;
158 159 graphChildRange.m_TEnd += deltaRight;
159 160 qCDebug(LOG_VisualizationZoneWidget())
160 161 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
161 162 break;
162 163 }
163 164 case AcquisitionZoomType::PanLeft: {
164 165 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanLeft");
165 166 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
166 167 graphChildRange.m_TStart -= deltaLeft;
167 168 graphChildRange.m_TEnd -= deltaLeft;
168 169 break;
169 170 }
170 171 case AcquisitionZoomType::Unknown: {
171 172 qCDebug(LOG_VisualizationZoneWidget())
172 173 << tr("Impossible to synchronize: zoom type unknown");
173 174 break;
174 175 }
175 176 default:
176 177 qCCritical(LOG_VisualizationZoneWidget())
177 178 << tr("Impossible to synchronize: zoom type not take into account");
178 179 // No action
179 180 break;
180 181 }
181 182 graphChild->enableAcquisition(false);
182 183 qCDebug(LOG_VisualizationZoneWidget())
183 184 << tr("TORM: Range before: ") << graphChild->graphRange();
184 185 qCDebug(LOG_VisualizationZoneWidget())
185 186 << tr("TORM: Range after : ") << graphChildRange;
186 187 qCDebug(LOG_VisualizationZoneWidget())
187 188 << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart;
188 189 graphChild->setGraphRange(graphChildRange);
189 190 graphChild->enableAcquisition(true);
190 191 }
191 192 }
192 193 };
193 194
194 195 // connection for synchronization
195 196 connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
196 197 connect(graphWidget, &VisualizationGraphWidget::variableAdded, this,
197 198 &VisualizationZoneWidget::onVariableAdded);
198 199 connect(graphWidget, &VisualizationGraphWidget::variableAboutToBeRemoved, this,
199 200 &VisualizationZoneWidget::onVariableAboutToBeRemoved);
200 201
201 202 auto range = SqpRange{};
202 203
203 204 // Apply visitor to graph children
204 205 auto layout = ui->visualizationZoneFrame->layout();
205 206 if (layout->count() > 0) {
206 207 // Case of a new graph in a existant zone
207 208 if (auto visualizationGraphWidget
208 209 = dynamic_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
209 210 range = visualizationGraphWidget->graphRange();
210 211 }
211 212 }
212 213 else {
213 214 // Case of a new graph as the first of the zone
214 215 range = variable->range();
215 216 }
216 217
217 218 this->addGraph(graphWidget);
218 219
219 220 graphWidget->addVariable(variable, range);
220 221
221 222 // get y using variable range
222 223 if (auto dataSeries = variable->dataSeries()) {
223 224 dataSeries->lockRead();
224 225 auto valuesBounds
225 226 = dataSeries->valuesBounds(variable->range().m_TStart, variable->range().m_TEnd);
226 227 auto end = dataSeries->cend();
227 228 if (valuesBounds.first != end && valuesBounds.second != end) {
228 229 auto rangeValue = [](const auto &value) { return std::isnan(value) ? 0. : value; };
229 230
230 231 auto minValue = rangeValue(valuesBounds.first->minValue());
231 232 auto maxValue = rangeValue(valuesBounds.second->maxValue());
232 233
233 234 graphWidget->setYRange(SqpRange{minValue, maxValue});
234 235 }
235 236 dataSeries->unlock();
236 237 }
237 238
238 239 return graphWidget;
239 240 }
240 241
241 242 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
242 243 {
243 244 if (visitor) {
244 245 visitor->visitEnter(this);
245 246
246 247 // Apply visitor to graph children: widgets different from graphs are not visited (no
247 248 // action)
248 249 processGraphs(
249 250 *ui->visualizationZoneFrame->layout(),
250 251 [visitor](VisualizationGraphWidget &graphWidget) { graphWidget.accept(visitor); });
251 252
252 253 visitor->visitLeave(this);
253 254 }
254 255 else {
255 256 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
256 257 }
257 258 }
258 259
259 260 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
260 261 {
261 262 // A tab can always accomodate a variable
262 263 Q_UNUSED(variable);
263 264 return true;
264 265 }
265 266
266 267 bool VisualizationZoneWidget::contains(const Variable &variable) const
267 268 {
268 269 Q_UNUSED(variable);
269 270 return false;
270 271 }
271 272
272 273 QString VisualizationZoneWidget::name() const
273 274 {
274 275 return ui->zoneNameLabel->text();
275 276 }
276 277
277 278 void VisualizationZoneWidget::closeEvent(QCloseEvent *event)
278 279 {
279 280 // Closes graphs in the zone
280 281 processGraphs(*ui->visualizationZoneFrame->layout(),
281 282 [](VisualizationGraphWidget &graphWidget) { graphWidget.close(); });
282 283
283 284 // Delete synchronization group from variable controller
284 285 QMetaObject::invokeMethod(&sqpApp->variableController(), "onRemoveSynchronizationGroupId",
285 286 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
286 287
287 288 QWidget::closeEvent(event);
288 289 }
289 290
290 291 void VisualizationZoneWidget::onVariableAdded(std::shared_ptr<Variable> variable)
291 292 {
292 293 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronized",
293 294 Qt::QueuedConnection, Q_ARG(std::shared_ptr<Variable>, variable),
294 295 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
295 296 }
296 297
297 298 void VisualizationZoneWidget::onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable)
298 299 {
299 300 QMetaObject::invokeMethod(&sqpApp->variableController(), "desynchronize", Qt::QueuedConnection,
300 301 Q_ARG(std::shared_ptr<Variable>, variable),
301 302 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
302 303 }
General Comments 0
You need to be logged in to leave comments. Login now