@@ -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 = |
|
|
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); | |
|
99 | 101 | |
|
100 | void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested, | |
|
101 | QUuid varRequestId); | |
|
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 | } | |
|
102 | 108 | |
|
103 | QVector<SqpRange> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable, | |
|
104 | const SqpRange &dateTime); | |
|
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 | } | |
|
105 | 123 | |
|
106 | std::shared_ptr<Variable> findVariable(QUuid vIdentifier); | |
|
124 | // Calls UI update for in-cache range | |
|
125 | if (!inCacheRanges.isEmpty()) { | |
|
126 | emit q->updateVarDisplaying(variable, inCacheRanges.first()); | |
|
127 | } | |
|
128 | } | |
|
129 | ||
|
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; }; | |
|
135 | ||
|
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 | } | |
|
145 | ||
|
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 | } | |
|
111 | 176 | |
|
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 |
|
|
|
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 | // } | |
|
227 | ||
|
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_ |
|
|
401 | auto variableProvider = impl->m_Providers.at(variable); | |
|
206 | 402 | auto duplicateProvider = variableProvider != nullptr ? variableProvider->clone() : nullptr; |
|
207 | 403 | |
|
208 |
impl->m_ |
|
|
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_ |
|
|
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_ |
|
|
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 |
|
|
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 |
|
|
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 = |
|
|
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