@@ -136,6 +136,9 struct VariableController::VariableControllerPrivate { | |||
|
136 | 136 | void cancelVariableRequest(QUuid varRequestId); |
|
137 | 137 | void executeVarRequest(std::shared_ptr<Variable> var, VariableRequest &varRequest); |
|
138 | 138 | |
|
139 | template <typename VariableIterator> | |
|
140 | void desynchronize(VariableIterator variableIt, const QUuid &syncGroupId); | |
|
141 | ||
|
139 | 142 | QMutex m_WorkingMutex; |
|
140 | 143 | /// Variable model. The VariableController has the ownership |
|
141 | 144 | VariableModel *m_VariableModel; |
@@ -258,8 +261,22 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noex | |||
|
258 | 261 | // make some treatments before the deletion |
|
259 | 262 | emit variableAboutToBeDeleted(variable); |
|
260 | 263 | |
|
264 | auto variableIt = impl->m_VariableToIdentifierMap.find(variable); | |
|
265 | Q_ASSERT(variableIt != impl->m_VariableToIdentifierMap.cend()); | |
|
266 | ||
|
267 | auto variableId = variableIt->second; | |
|
268 | ||
|
269 | // Removes variable's handler | |
|
270 | impl->m_VarIdToVarRequestHandler.erase(variableId); | |
|
271 | ||
|
272 | // Desynchronizes variable (if the variable is in a sync group) | |
|
273 | auto syncGroupIt = impl->m_VariableIdGroupIdMap.find(variableId); | |
|
274 | if (syncGroupIt != impl->m_VariableIdGroupIdMap.cend()) { | |
|
275 | impl->desynchronize(variableIt, syncGroupIt->second); | |
|
276 | } | |
|
277 | ||
|
261 | 278 | // Deletes identifier |
|
262 | impl->m_VariableToIdentifierMap.erase(variable); | |
|
279 | impl->m_VariableToIdentifierMap.erase(variableIt); | |
|
263 | 280 | |
|
264 | 281 | // Deletes provider |
|
265 | 282 | auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable); |
@@ -545,23 +562,7 void VariableController::desynchronize(std::shared_ptr<Variable> variable, | |||
|
545 | 562 | return; |
|
546 | 563 | } |
|
547 | 564 | |
|
548 | // Gets synchronization group | |
|
549 | auto groupIt = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId); | |
|
550 | if (groupIt == impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) { | |
|
551 | qCCritical(LOG_VariableController()) | |
|
552 | << tr("Can't desynchronize variable %1: unknown synchronization group") | |
|
553 | .arg(variable->name()); | |
|
554 | return; | |
|
555 | } | |
|
556 | ||
|
557 | auto variableId = variableIt->second; | |
|
558 | ||
|
559 | // Removes variable from synchronization group | |
|
560 | auto synchronizationGroup = groupIt->second; | |
|
561 | synchronizationGroup->removeVariableId(variableId); | |
|
562 | ||
|
563 | // Removes link between variable and synchronization group | |
|
564 | impl->m_VariableIdGroupIdMap.erase(variableId); | |
|
565 | impl->desynchronize(variableIt, synchronizationGroupId); | |
|
565 | 566 | } |
|
566 | 567 | |
|
567 | 568 | void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables, |
@@ -933,6 +934,7 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid | |||
|
933 | 934 | varHandler->m_PendingVarRequest = VariableRequest{}; |
|
934 | 935 | auto var = findVariable(itVarHandler->first); |
|
935 | 936 | executeVarRequest(var, varHandler->m_RunningVarRequest); |
|
937 | updateVariables(varHandler->m_RunningVarRequest.m_VariableGroupId); | |
|
936 | 938 | break; |
|
937 | 939 | } |
|
938 | 940 | default: |
@@ -1032,7 +1034,14 void VariableController::VariableControllerPrivate::executeVarRequest(std::share | |||
|
1032 | 1034 | { |
|
1033 | 1035 | qCDebug(LOG_VariableController()) << tr("TORM: executeVarRequest"); |
|
1034 | 1036 | |
|
1035 |
auto varId = m_VariableToIdentifierMap. |
|
|
1037 | auto varIdIt = m_VariableToIdentifierMap.find(var); | |
|
1038 | if (varIdIt == m_VariableToIdentifierMap.cend()) { | |
|
1039 | qCWarning(LOG_VariableController()) << tr( | |
|
1040 | "Can't execute request of a variable that is not registered (may has been deleted)"); | |
|
1041 | return; | |
|
1042 | } | |
|
1043 | ||
|
1044 | auto varId = varIdIt->second; | |
|
1036 | 1045 | |
|
1037 | 1046 | auto varCacheRange = var->cacheRange(); |
|
1038 | 1047 | auto varCacheRangeRequested = varRequest.m_CacheRangeRequested; |
@@ -1067,3 +1076,27 void VariableController::VariableControllerPrivate::executeVarRequest(std::share | |||
|
1067 | 1076 | var->dataSeries()->subDataSeries(varRequest.m_CacheRangeRequested)); |
|
1068 | 1077 | } |
|
1069 | 1078 | } |
|
1079 | ||
|
1080 | template <typename VariableIterator> | |
|
1081 | void VariableController::VariableControllerPrivate::desynchronize(VariableIterator variableIt, | |
|
1082 | const QUuid &syncGroupId) | |
|
1083 | { | |
|
1084 | const auto &variable = variableIt->first; | |
|
1085 | const auto &variableId = variableIt->second; | |
|
1086 | ||
|
1087 | // Gets synchronization group | |
|
1088 | auto groupIt = m_GroupIdToVariableSynchronizationGroupMap.find(syncGroupId); | |
|
1089 | if (groupIt == m_GroupIdToVariableSynchronizationGroupMap.cend()) { | |
|
1090 | qCCritical(LOG_VariableController()) | |
|
1091 | << tr("Can't desynchronize variable %1: unknown synchronization group") | |
|
1092 | .arg(variable->name()); | |
|
1093 | return; | |
|
1094 | } | |
|
1095 | ||
|
1096 | // Removes variable from synchronization group | |
|
1097 | auto synchronizationGroup = groupIt->second; | |
|
1098 | synchronizationGroup->removeVariableId(variableId); | |
|
1099 | ||
|
1100 | // Removes link between variable and synchronization group | |
|
1101 | m_VariableIdGroupIdMap.erase(variableId); | |
|
1102 | } |
@@ -25,6 +25,20 namespace Ui { | |||
|
25 | 25 | class VisualizationGraphWidget; |
|
26 | 26 | } // namespace Ui |
|
27 | 27 | |
|
28 | /// Defines options that can be associated with the graph | |
|
29 | enum GraphFlag { | |
|
30 | DisableAll = 0x0, ///< Disables acquisition and synchronization | |
|
31 | EnableAcquisition = 0x1, ///< When this flag is set, the change of the graph's range leads to | |
|
32 | /// the acquisition of data | |
|
33 | EnableSynchronization = 0x2, ///< When this flag is set, the change of the graph's range causes | |
|
34 | /// the call to the synchronization of the graphs contained in the | |
|
35 | /// same zone of this graph | |
|
36 | EnableAll = ~DisableAll ///< Enables acquisition and synchronization | |
|
37 | }; | |
|
38 | ||
|
39 | Q_DECLARE_FLAGS(GraphFlags, GraphFlag) | |
|
40 | Q_DECLARE_OPERATORS_FOR_FLAGS(GraphFlags) | |
|
41 | ||
|
28 | 42 | class VisualizationGraphWidget : public VisualizationDragWidget, public IVisualizationWidget { |
|
29 | 43 | Q_OBJECT |
|
30 | 44 | |
@@ -41,8 +55,8 public: | |||
|
41 | 55 | /// Returns the main VisualizationWidget which contains the graph or nullptr |
|
42 | 56 | VisualizationWidget *parentVisualizationWidget() const; |
|
43 | 57 | |
|
44 | /// If acquisition isn't enable, requestDataLoading signal cannot be emit | |
|
45 | void enableAcquisition(bool enable); | |
|
58 | /// Sets graph options | |
|
59 | void setFlags(GraphFlags flags); | |
|
46 | 60 | |
|
47 | 61 | void addVariable(std::shared_ptr<Variable> variable, SqpRange range); |
|
48 | 62 |
@@ -59,7 +59,7 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate { | |||
|
59 | 59 | |
|
60 | 60 | explicit VisualizationGraphWidgetPrivate(const QString &name) |
|
61 | 61 | : m_Name{name}, |
|
62 | m_DoAcquisition{true}, | |
|
62 | m_Flags{GraphFlag::EnableAll}, | |
|
63 | 63 | m_IsCalibration{false}, |
|
64 | 64 | m_RenderingDelegate{nullptr} |
|
65 | 65 | { |
@@ -77,7 +77,7 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate { | |||
|
77 | 77 | QString m_Name; |
|
78 | 78 | // 1 variable -> n qcpplot |
|
79 | 79 | std::map<std::shared_ptr<Variable>, PlottablesMap> m_VariableToPlotMultiMap; |
|
80 | bool m_DoAcquisition; | |
|
80 | GraphFlags m_Flags; | |
|
81 | 81 | bool m_IsCalibration; |
|
82 | 82 | /// Delegate used to attach rendering features to the plot |
|
83 | 83 | std::unique_ptr<VisualizationGraphRenderingDelegate> m_RenderingDelegate; |
@@ -287,9 +287,9 VisualizationWidget *VisualizationGraphWidget::parentVisualizationWidget() const | |||
|
287 | 287 | return qobject_cast<VisualizationWidget *>(parent); |
|
288 | 288 | } |
|
289 | 289 | |
|
290 |
void VisualizationGraphWidget:: |
|
|
290 | void VisualizationGraphWidget::setFlags(GraphFlags flags) | |
|
291 | 291 | { |
|
292 | impl->m_DoAcquisition = enable; | |
|
292 | impl->m_Flags = std::move(flags); | |
|
293 | 293 | } |
|
294 | 294 | |
|
295 | 295 | void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, SqpRange range) |
@@ -311,9 +311,9 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, S | |||
|
311 | 311 | |
|
312 | 312 | connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated())); |
|
313 | 313 | |
|
314 | this->enableAcquisition(false); | |
|
314 | this->setFlags(GraphFlag::DisableAll); | |
|
315 | 315 | this->setGraphRange(range); |
|
316 | this->enableAcquisition(true); | |
|
316 | this->setFlags(GraphFlag::EnableAll); | |
|
317 | 317 | |
|
318 | 318 | emit requestDataLoading(QVector<std::shared_ptr<Variable> >() << variable, range, false); |
|
319 | 319 | |
@@ -696,12 +696,12 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange | |||
|
696 | 696 | { |
|
697 | 697 | qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: VisualizationGraphWidget::onRangeChanged") |
|
698 | 698 | << QThread::currentThread()->objectName() << "DoAcqui" |
|
699 |
<< impl->m_ |
|
|
699 | << impl->m_Flags.testFlag(GraphFlag::EnableAcquisition); | |
|
700 | 700 | |
|
701 | 701 | auto graphRange = SqpRange{t1.lower, t1.upper}; |
|
702 | 702 | auto oldGraphRange = SqpRange{t2.lower, t2.upper}; |
|
703 | 703 | |
|
704 |
if (impl->m_ |
|
|
704 | if (impl->m_Flags.testFlag(GraphFlag::EnableAcquisition)) { | |
|
705 | 705 | QVector<std::shared_ptr<Variable> > variableUnderGraphVector; |
|
706 | 706 | |
|
707 | 707 | for (auto it = impl->m_VariableToPlotMultiMap.begin(), |
@@ -711,14 +711,14 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange | |||
|
711 | 711 | } |
|
712 | 712 | emit requestDataLoading(std::move(variableUnderGraphVector), graphRange, |
|
713 | 713 | !impl->m_IsCalibration); |
|
714 | } | |
|
714 | 715 | |
|
715 | if (!impl->m_IsCalibration) { | |
|
716 | if (impl->m_Flags.testFlag(GraphFlag::EnableSynchronization) && !impl->m_IsCalibration) { | |
|
716 | 717 |
|
|
717 | 718 |
|
|
718 | 719 |
|
|
719 | 720 |
|
|
720 | 721 |
|
|
721 | } | |
|
722 | 722 | |
|
723 | 723 | auto pos = mapFromGlobal(QCursor::pos()); |
|
724 | 724 | auto axisPos = impl->posToAxisPos(pos, plot()); |
@@ -733,6 +733,9 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange | |||
|
733 | 733 | else { |
|
734 | 734 | qCWarning(LOG_VisualizationGraphWidget()) << "onMouseMove: No parent zone widget"; |
|
735 | 735 | } |
|
736 | ||
|
737 | // Quits calibration | |
|
738 | impl->m_IsCalibration = false; | |
|
736 | 739 | } |
|
737 | 740 | |
|
738 | 741 | void VisualizationGraphWidget::onMouseDoubleClick(QMouseEvent *event) noexcept |
@@ -917,8 +920,6 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept | |||
|
917 | 920 | |
|
918 | 921 | impl->endDrawingZone(this); |
|
919 | 922 | |
|
920 | impl->m_IsCalibration = false; | |
|
921 | ||
|
922 | 923 | // Selection / Deselection |
|
923 | 924 | auto isSelectionZoneMode |
|
924 | 925 | = sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones; |
@@ -264,15 +264,15 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<V | |||
|
264 | 264 | // No action |
|
265 | 265 | break; |
|
266 | 266 | } |
|
267 |
graphChild-> |
|
|
268 |
qCDebug(LOG_VisualizationZoneWidget()) |
|
|
269 |
|
|
|
270 |
qCDebug(LOG_VisualizationZoneWidget()) |
|
|
271 | << graphChildRange; | |
|
267 | graphChild->setFlags(GraphFlag::DisableAll); | |
|
268 | qCDebug(LOG_VisualizationZoneWidget()) | |
|
269 | << tr("TORM: Range before: ") << graphChild->graphRange(); | |
|
270 | qCDebug(LOG_VisualizationZoneWidget()) | |
|
271 | << tr("TORM: Range after : ") << graphChildRange; | |
|
272 | 272 | qCDebug(LOG_VisualizationZoneWidget()) |
|
273 | 273 | << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart; |
|
274 | 274 | graphChild->setGraphRange(graphChildRange); |
|
275 |
graphChild-> |
|
|
275 | graphChild->setFlags(GraphFlag::EnableAll); | |
|
276 | 276 | } |
|
277 | 277 | } |
|
278 | 278 | }; |
@@ -59,9 +59,11 void RescaleAxeOperation::visit(VisualizationGraphWidget *graphWidget) | |||
|
59 | 59 | if (graphWidget) { |
|
60 | 60 | // If the widget contains the variable, rescale it |
|
61 | 61 | if (impl->m_Variable && graphWidget->contains(*impl->m_Variable)) { |
|
62 | graphWidget->enableAcquisition(false); | |
|
62 | // During rescale, acquisition for the graph is disabled but synchronization is still | |
|
63 | // enabled | |
|
64 | graphWidget->setFlags(GraphFlag::EnableSynchronization); | |
|
63 | 65 | graphWidget->setGraphRange(impl->m_Range); |
|
64 |
graphWidget-> |
|
|
66 | graphWidget->setFlags(GraphFlag::EnableAll); | |
|
65 | 67 | } |
|
66 | 68 | } |
|
67 | 69 | else { |
@@ -67,14 +67,18 void FuzzingState::synchronizeVariable(VariableId variableId, SyncGroupId syncGr | |||
|
67 | 67 | return; |
|
68 | 68 | } |
|
69 | 69 | |
|
70 | // Registers variable into sync group: if it's the first variable, sets the variable range as | |
|
71 | // the sync group range | |
|
70 | // Registers variable into sync group | |
|
72 | 71 | auto &syncGroup = m_SyncGroupsPool.at(syncGroupId); |
|
72 | auto &variableState = m_VariablesPool.at(variableId); | |
|
73 | 73 | syncGroup.m_Variables.insert(variableId); |
|
74 | 74 | if (syncGroup.m_Variables.size() == 1) { |
|
75 | auto &variableState = m_VariablesPool.at(variableId); | |
|
75 | // If it's the first variable, sets the variable range as the sync group range | |
|
76 | 76 | syncGroup.m_Range = variableState.m_Range; |
|
77 | 77 | } |
|
78 | else { | |
|
79 | // If a variable is added to an existing group, sets its range to the group's range | |
|
80 | variableState.m_Range = syncGroup.m_Range; | |
|
81 | } | |
|
78 | 82 | } |
|
79 | 83 | |
|
80 | 84 | void FuzzingState::desynchronizeVariable(VariableId variableId, SyncGroupId syncGroupId) |
@@ -97,13 +101,18 void FuzzingState::updateRanges(VariableId variableId, const SqpRange &newRange) | |||
|
97 | 101 | auto syncGroupId = this->syncGroupId(variableId); |
|
98 | 102 | |
|
99 | 103 | // Retrieves the variables to update: |
|
100 |
// - if the variable is synchronized to others, updates |
|
|
104 | // - if the variable is synchronized to others, updates the range of the group and of all | |
|
105 | // synchronized variables | |
|
101 | 106 | // - otherwise, updates only the variable |
|
102 | auto variablesToUpdate = syncGroupId.isNull() ? std::set<VariableId>{variableId} | |
|
103 | : m_SyncGroupsPool.at(syncGroupId).m_Variables; | |
|
107 | if (syncGroupId.isNull()) { | |
|
108 | m_VariablesPool.at(variableId).m_Range = newRange; | |
|
109 | } | |
|
110 | else { | |
|
111 | auto &syncGroup = m_SyncGroupsPool.at(syncGroupId); | |
|
112 | syncGroup.m_Range = newRange; | |
|
104 | 113 | |
|
105 | // Sets new range | |
|
106 | for (const auto &variableId : variablesToUpdate) { | |
|
114 | for (const auto &variableId : syncGroup.m_Variables) { | |
|
107 | 115 | m_VariablesPool.at(variableId).m_Range = newRange; |
|
108 | 116 | } |
|
109 | 117 | } |
|
118 | } |
@@ -176,6 +176,9 struct SynchronizeOperation : public IFuzzingOperation { | |||
|
176 | 176 | |
|
177 | 177 | // Updates state |
|
178 | 178 | fuzzingState.synchronizeVariable(variableId, syncGroupId); |
|
179 | ||
|
180 | variableController.onRequestDataLoading({variableState.m_Variable}, variableState.m_Range, | |
|
181 | false); | |
|
179 | 182 | } |
|
180 | 183 | }; |
|
181 | 184 | |
@@ -197,7 +200,7 struct DesynchronizeOperation : public IFuzzingOperation { | |||
|
197 | 200 | qCInfo(LOG_FuzzingOperations()).noquote() << "Removing" << variableState.m_Variable->name() |
|
198 | 201 | << "from synchronization group" << syncGroupId |
|
199 | 202 | << "..."; |
|
200 |
variableController. |
|
|
203 | variableController.desynchronize(variableState.m_Variable, syncGroupId); | |
|
201 | 204 | |
|
202 | 205 | // Updates state |
|
203 | 206 | fuzzingState.desynchronizeVariable(variableId, syncGroupId); |
@@ -96,7 +96,7 public: | |||
|
96 | 96 | auto dataHoleIt = std::adjacent_find( |
|
97 | 97 | dataIts.first, dataIts.second, [](const auto &it1, const auto &it2) { |
|
98 | 98 | /// @todo: validate resolution |
|
99 |
return std::abs(it1.x() - it2.x()) > 2 * |
|
|
99 | return std::abs(it1.x() - it2.x()) > 2 * LOCALHOST_SERVER_RESOLUTION; | |
|
100 | 100 | }); |
|
101 | 101 | |
|
102 | 102 | if (dataHoleIt != dataIts.second) { |
@@ -370,6 +370,10 void TestAmdaFuzzing::testFuzzing() | |||
|
370 | 370 | |
|
371 | 371 | int main(int argc, char *argv[]) |
|
372 | 372 | { |
|
373 | // Increases the test function timeout (which is 5 minutes by default) to 12 hours | |
|
374 | // https://stackoverflow.com/questions/42655932/setting-timeout-to-qt-test | |
|
375 | qputenv("QTEST_FUNCTION_TIMEOUT", QByteArray::number(12*60*60*1000)); | |
|
376 | ||
|
373 | 377 | QLoggingCategory::setFilterRules( |
|
374 | 378 | "*.warning=false\n" |
|
375 | 379 | "*.info=false\n" |
General Comments 0
You need to be logged in to leave comments.
Login now