##// END OF EJS Templates
Updates states of synchronized variables when there is a move operation
Alexandre Leroux -
r1242:162d6112469c
parent child
Show More
@@ -1,91 +1,107
1 #include "FuzzingDefs.h"
1 #include "FuzzingDefs.h"
2
2
3 const QString NB_MAX_OPERATIONS_PROPERTY = QStringLiteral("component");
3 const QString NB_MAX_OPERATIONS_PROPERTY = QStringLiteral("component");
4 const QString NB_MAX_SYNC_GROUPS_PROPERTY = QStringLiteral("nbSyncGroups");
4 const QString NB_MAX_SYNC_GROUPS_PROPERTY = QStringLiteral("nbSyncGroups");
5 const QString NB_MAX_VARIABLES_PROPERTY = QStringLiteral("nbMaxVariables");
5 const QString NB_MAX_VARIABLES_PROPERTY = QStringLiteral("nbMaxVariables");
6 const QString AVAILABLE_OPERATIONS_PROPERTY = QStringLiteral("availableOperations");
6 const QString AVAILABLE_OPERATIONS_PROPERTY = QStringLiteral("availableOperations");
7 const QString CACHE_TOLERANCE_PROPERTY = QStringLiteral("cacheTolerance");
7 const QString CACHE_TOLERANCE_PROPERTY = QStringLiteral("cacheTolerance");
8 const QString INITIAL_RANGE_PROPERTY = QStringLiteral("initialRange");
8 const QString INITIAL_RANGE_PROPERTY = QStringLiteral("initialRange");
9 const QString MAX_RANGE_PROPERTY = QStringLiteral("maxRange");
9 const QString MAX_RANGE_PROPERTY = QStringLiteral("maxRange");
10 const QString METADATA_POOL_PROPERTY = QStringLiteral("metadataPool");
10 const QString METADATA_POOL_PROPERTY = QStringLiteral("metadataPool");
11 const QString PROVIDER_PROPERTY = QStringLiteral("provider");
11 const QString PROVIDER_PROPERTY = QStringLiteral("provider");
12 const QString OPERATION_DELAY_PROPERTY = QStringLiteral("operationDelay");
12 const QString OPERATION_DELAY_PROPERTY = QStringLiteral("operationDelay");
13 const QString VALIDATORS_PROPERTY = QStringLiteral("validators");
13 const QString VALIDATORS_PROPERTY = QStringLiteral("validators");
14
14
15 // //////////// //
15 // //////////// //
16 // FuzzingState //
16 // FuzzingState //
17 // //////////// //
17 // //////////// //
18
18
19 const SyncGroup &FuzzingState::syncGroup(SyncGroupId id) const
19 const SyncGroup &FuzzingState::syncGroup(SyncGroupId id) const
20 {
20 {
21 return m_SyncGroupsPool.at(id);
21 return m_SyncGroupsPool.at(id);
22 }
22 }
23
23
24 SyncGroup &FuzzingState::syncGroup(SyncGroupId id)
24 SyncGroup &FuzzingState::syncGroup(SyncGroupId id)
25 {
25 {
26 return m_SyncGroupsPool.at(id);
26 return m_SyncGroupsPool.at(id);
27 }
27 }
28
28
29 const VariableState &FuzzingState::variableState(VariableId id) const
29 const VariableState &FuzzingState::variableState(VariableId id) const
30 {
30 {
31 return m_VariablesPool.at(id);
31 return m_VariablesPool.at(id);
32 }
32 }
33
33
34 VariableState &FuzzingState::variableState(VariableId id)
34 VariableState &FuzzingState::variableState(VariableId id)
35 {
35 {
36 return m_VariablesPool.at(id);
36 return m_VariablesPool.at(id);
37 }
37 }
38
38
39 SyncGroupId FuzzingState::syncGroupId(VariableId variableId) const
39 SyncGroupId FuzzingState::syncGroupId(VariableId variableId) const
40 {
40 {
41 auto end = m_SyncGroupsPool.cend();
41 auto end = m_SyncGroupsPool.cend();
42 auto it
42 auto it
43 = std::find_if(m_SyncGroupsPool.cbegin(), end, [&variableId](const auto &syncGroupEntry) {
43 = std::find_if(m_SyncGroupsPool.cbegin(), end, [&variableId](const auto &syncGroupEntry) {
44 const auto &syncGroup = syncGroupEntry.second;
44 const auto &syncGroup = syncGroupEntry.second;
45 return syncGroup.m_Variables.find(variableId) != syncGroup.m_Variables.end();
45 return syncGroup.m_Variables.find(variableId) != syncGroup.m_Variables.end();
46 });
46 });
47
47
48 return it != end ? it->first : SyncGroupId{};
48 return it != end ? it->first : SyncGroupId{};
49 }
49 }
50
50
51 std::vector<SyncGroupId> FuzzingState::syncGroupsIds() const
51 std::vector<SyncGroupId> FuzzingState::syncGroupsIds() const
52 {
52 {
53 std::vector<SyncGroupId> result{};
53 std::vector<SyncGroupId> result{};
54
54
55 for (const auto &entry : m_SyncGroupsPool) {
55 for (const auto &entry : m_SyncGroupsPool) {
56 result.push_back(entry.first);
56 result.push_back(entry.first);
57 }
57 }
58
58
59 return result;
59 return result;
60 }
60 }
61
61
62 void FuzzingState::synchronizeVariable(VariableId variableId, SyncGroupId syncGroupId)
62 void FuzzingState::synchronizeVariable(VariableId variableId, SyncGroupId syncGroupId)
63 {
63 {
64 if (syncGroupId.isNull()) {
64 if (syncGroupId.isNull()) {
65 return;
65 return;
66 }
66 }
67
67
68 // Registers variable into sync group: if it's the first variable, sets the variable range as
68 // Registers variable into sync group: if it's the first variable, sets the variable range as
69 // the sync group range
69 // the sync group range
70 auto &syncGroup = m_SyncGroupsPool.at(syncGroupId);
70 auto &syncGroup = m_SyncGroupsPool.at(syncGroupId);
71 syncGroup.m_Variables.insert(variableId);
71 syncGroup.m_Variables.insert(variableId);
72 if (syncGroup.m_Variables.size() == 1) {
72 if (syncGroup.m_Variables.size() == 1) {
73 auto &variableState = m_VariablesPool.at(variableId);
73 auto &variableState = m_VariablesPool.at(variableId);
74 syncGroup.m_Range = variableState.m_Range;
74 syncGroup.m_Range = variableState.m_Range;
75 }
75 }
76 }
76 }
77
77
78 void FuzzingState::desynchronizeVariable(VariableId variableId, SyncGroupId syncGroupId)
78 void FuzzingState::desynchronizeVariable(VariableId variableId, SyncGroupId syncGroupId)
79 {
79 {
80 if (syncGroupId.isNull()) {
80 if (syncGroupId.isNull()) {
81 return;
81 return;
82 }
82 }
83
83
84 // Unregisters variable from sync group: if there is no more variable in the group, resets the range
84 // Unregisters variable from sync group: if there is no more variable in the group, resets the
85 // range
85 auto &syncGroup = m_SyncGroupsPool.at(syncGroupId);
86 auto &syncGroup = m_SyncGroupsPool.at(syncGroupId);
86 syncGroup.m_Variables.erase(variableId);
87 syncGroup.m_Variables.erase(variableId);
87 if (syncGroup.m_Variables.empty()) {
88 if (syncGroup.m_Variables.empty()) {
88 syncGroup.m_Range = INVALID_RANGE;
89 syncGroup.m_Range = INVALID_RANGE;
89 }
90 }
90 }
91 }
91
92
93 void FuzzingState::updateRanges(VariableId variableId, const SqpRange &newRange)
94 {
95 auto syncGroupId = this->syncGroupId(variableId);
96
97 // Retrieves the variables to update:
98 // - if the variable is synchronized to others, updates all synchronized variables
99 // - otherwise, updates only the variable
100 auto variablesToUpdate = syncGroupId.isNull() ? std::set<VariableId>{variableId}
101 : m_SyncGroupsPool.at(syncGroupId).m_Variables;
102
103 // Sets new range
104 for (const auto &variableId : variablesToUpdate) {
105 m_VariablesPool.at(variableId).m_Range = newRange;
106 }
107 }
@@ -1,118 +1,122
1 #ifndef SCIQLOP_FUZZINGDEFS_H
1 #ifndef SCIQLOP_FUZZINGDEFS_H
2 #define SCIQLOP_FUZZINGDEFS_H
2 #define SCIQLOP_FUZZINGDEFS_H
3
3
4 #include <Data/SqpRange.h>
4 #include <Data/SqpRange.h>
5
5
6 #include <QString>
6 #include <QString>
7 #include <QUuid>
7 #include <QUuid>
8 #include <QVariantHash>
8 #include <QVariantHash>
9
9
10 #include <memory>
10 #include <memory>
11 #include <set>
11 #include <set>
12
12
13 // /////// //
13 // /////// //
14 // Aliases //
14 // Aliases //
15 // /////// //
15 // /////// //
16
16
17 using MetadataPool = std::vector<QVariantHash>;
17 using MetadataPool = std::vector<QVariantHash>;
18 Q_DECLARE_METATYPE(MetadataPool)
18 Q_DECLARE_METATYPE(MetadataPool)
19
19
20 using Properties = QVariantHash;
20 using Properties = QVariantHash;
21
21
22 // ///////// //
22 // ///////// //
23 // Constants //
23 // Constants //
24 // ///////// //
24 // ///////// //
25
25
26 /// Max number of operations to generate
26 /// Max number of operations to generate
27 extern const QString NB_MAX_OPERATIONS_PROPERTY;
27 extern const QString NB_MAX_OPERATIONS_PROPERTY;
28
28
29 /// Max number of sync groups to create through operations
29 /// Max number of sync groups to create through operations
30 extern const QString NB_MAX_SYNC_GROUPS_PROPERTY;
30 extern const QString NB_MAX_SYNC_GROUPS_PROPERTY;
31
31
32 /// Max number of variables to manipulate through operations
32 /// Max number of variables to manipulate through operations
33 extern const QString NB_MAX_VARIABLES_PROPERTY;
33 extern const QString NB_MAX_VARIABLES_PROPERTY;
34
34
35 /// Set of operations available for the test
35 /// Set of operations available for the test
36 extern const QString AVAILABLE_OPERATIONS_PROPERTY;
36 extern const QString AVAILABLE_OPERATIONS_PROPERTY;
37
37
38 /// Tolerance used for variable's cache (in ratio)
38 /// Tolerance used for variable's cache (in ratio)
39 extern const QString CACHE_TOLERANCE_PROPERTY;
39 extern const QString CACHE_TOLERANCE_PROPERTY;
40
40
41 /// Range with which the timecontroller is initialized
41 /// Range with which the timecontroller is initialized
42 extern const QString INITIAL_RANGE_PROPERTY;
42 extern const QString INITIAL_RANGE_PROPERTY;
43
43
44 /// Max range that an operation can reach
44 /// Max range that an operation can reach
45 extern const QString MAX_RANGE_PROPERTY;
45 extern const QString MAX_RANGE_PROPERTY;
46
46
47 /// Set of metadata that can be associated to a variable
47 /// Set of metadata that can be associated to a variable
48 extern const QString METADATA_POOL_PROPERTY;
48 extern const QString METADATA_POOL_PROPERTY;
49
49
50 /// Provider used to retrieve data
50 /// Provider used to retrieve data
51 extern const QString PROVIDER_PROPERTY;
51 extern const QString PROVIDER_PROPERTY;
52
52
53 /// Time left for an operation to execute
53 /// Time left for an operation to execute
54 extern const QString OPERATION_DELAY_PROPERTY;
54 extern const QString OPERATION_DELAY_PROPERTY;
55
55
56 /// Validators used to validate an operation
56 /// Validators used to validate an operation
57 extern const QString VALIDATORS_PROPERTY;
57 extern const QString VALIDATORS_PROPERTY;
58
58
59 // /////// //
59 // /////// //
60 // Structs //
60 // Structs //
61 // /////// //
61 // /////// //
62
62
63 class Variable;
63 class Variable;
64 struct VariableState {
64 struct VariableState {
65 std::shared_ptr<Variable> m_Variable{nullptr};
65 std::shared_ptr<Variable> m_Variable{nullptr};
66 SqpRange m_Range{INVALID_RANGE};
66 SqpRange m_Range{INVALID_RANGE};
67 };
67 };
68
68
69 using VariableId = int;
69 using VariableId = int;
70 using VariablesPool = std::map<VariableId, VariableState>;
70 using VariablesPool = std::map<VariableId, VariableState>;
71
71
72 /**
72 /**
73 * Defines a synchronization group for a fuzzing state. A group reports the variables synchronized
73 * Defines a synchronization group for a fuzzing state. A group reports the variables synchronized
74 * with each other, and the current range of the group (i.e. range of the last synchronized variable
74 * with each other, and the current range of the group (i.e. range of the last synchronized variable
75 * that has been moved)
75 * that has been moved)
76 */
76 */
77 struct SyncGroup {
77 struct SyncGroup {
78 std::set<VariableId> m_Variables{};
78 std::set<VariableId> m_Variables{};
79 SqpRange m_Range{INVALID_RANGE};
79 SqpRange m_Range{INVALID_RANGE};
80 };
80 };
81
81
82 using SyncGroupId = QUuid;
82 using SyncGroupId = QUuid;
83 using SyncGroupsPool = std::map<SyncGroupId, SyncGroup>;
83 using SyncGroupsPool = std::map<SyncGroupId, SyncGroup>;
84
84
85 /**
85 /**
86 * Defines a current state during a fuzzing state. It contains all the variables manipulated during
86 * Defines a current state during a fuzzing state. It contains all the variables manipulated during
87 * the test, as well as the synchronization status of these variables.
87 * the test, as well as the synchronization status of these variables.
88 */
88 */
89 struct FuzzingState {
89 struct FuzzingState {
90 const SyncGroup &syncGroup(SyncGroupId id) const;
90 const SyncGroup &syncGroup(SyncGroupId id) const;
91 SyncGroup &syncGroup(SyncGroupId id);
91 SyncGroup &syncGroup(SyncGroupId id);
92
92
93 const VariableState &variableState(VariableId id) const;
93 const VariableState &variableState(VariableId id) const;
94 VariableState &variableState(VariableId id);
94 VariableState &variableState(VariableId id);
95
95
96 /// @return the identifier of the synchronization group in which the variable passed in
96 /// @return the identifier of the synchronization group in which the variable passed in
97 /// parameter is located. If the variable is not in any group, returns an invalid identifier
97 /// parameter is located. If the variable is not in any group, returns an invalid identifier
98 SyncGroupId syncGroupId(VariableId variableId) const;
98 SyncGroupId syncGroupId(VariableId variableId) const;
99
99
100 /// @return the set of synchronization group identifiers
100 /// @return the set of synchronization group identifiers
101 std::vector<SyncGroupId> syncGroupsIds() const;
101 std::vector<SyncGroupId> syncGroupsIds() const;
102
102
103 /// Updates fuzzing state according to a variable synchronization
103 /// Updates fuzzing state according to a variable synchronization
104 /// @param variableId the variable that is synchronized
104 /// @param variableId the variable that is synchronized
105 /// @param syncGroupId the synchronization group
105 /// @param syncGroupId the synchronization group
106 void synchronizeVariable(VariableId variableId, SyncGroupId syncGroupId);
106 void synchronizeVariable(VariableId variableId, SyncGroupId syncGroupId);
107
107
108 /// Updates fuzzing state according to a variable desynchronization
108 /// Updates fuzzing state according to a variable desynchronization
109 /// @param variableId the variable that is desynchronized
109 /// @param variableId the variable that is desynchronized
110 /// @param syncGroupId the synchronization group from which to remove the variable
110 /// @param syncGroupId the synchronization group from which to remove the variable
111 void desynchronizeVariable(VariableId variableId, SyncGroupId syncGroupId);
111 void desynchronizeVariable(VariableId variableId, SyncGroupId syncGroupId);
112
112
113 /// Updates the range of a variable and all variables to which it is synchronized
114 /// @param the variable for which to affect the range
115 /// @param the range to affect
116 void updateRanges(VariableId variableId, const SqpRange &newRange);
113
117
114 VariablesPool m_VariablesPool;
118 VariablesPool m_VariablesPool;
115 SyncGroupsPool m_SyncGroupsPool;
119 SyncGroupsPool m_SyncGroupsPool;
116 };
120 };
117
121
118 #endif // SCIQLOP_FUZZINGDEFS_H
122 #endif // SCIQLOP_FUZZINGDEFS_H
@@ -1,264 +1,265
1 #include "FuzzingOperations.h"
1 #include "FuzzingOperations.h"
2 #include "FuzzingUtils.h"
2 #include "FuzzingUtils.h"
3
3
4 #include <Data/IDataProvider.h>
4 #include <Data/IDataProvider.h>
5
5
6 #include <Variable/Variable.h>
6 #include <Variable/Variable.h>
7 #include <Variable/VariableController.h>
7 #include <Variable/VariableController.h>
8
8
9 #include <QUuid>
9 #include <QUuid>
10
10
11 #include <functional>
11 #include <functional>
12
12
13 Q_LOGGING_CATEGORY(LOG_FuzzingOperations, "FuzzingOperations")
13 Q_LOGGING_CATEGORY(LOG_FuzzingOperations, "FuzzingOperations")
14
14
15 namespace {
15 namespace {
16
16
17 struct CreateOperation : public IFuzzingOperation {
17 struct CreateOperation : public IFuzzingOperation {
18 bool canExecute(VariableId variableId, const FuzzingState &fuzzingState) const override
18 bool canExecute(VariableId variableId, const FuzzingState &fuzzingState) const override
19 {
19 {
20 // A variable can be created only if it doesn't exist yet
20 // A variable can be created only if it doesn't exist yet
21 return fuzzingState.variableState(variableId).m_Variable == nullptr;
21 return fuzzingState.variableState(variableId).m_Variable == nullptr;
22 }
22 }
23
23
24 void execute(VariableId variableId, FuzzingState &fuzzingState,
24 void execute(VariableId variableId, FuzzingState &fuzzingState,
25 VariableController &variableController,
25 VariableController &variableController,
26 const Properties &properties) const override
26 const Properties &properties) const override
27 {
27 {
28 // Retrieves metadata pool from properties, and choose one of the metadata entries to
28 // Retrieves metadata pool from properties, and choose one of the metadata entries to
29 // associate it with the variable
29 // associate it with the variable
30 auto metaDataPool = properties.value(METADATA_POOL_PROPERTY).value<MetadataPool>();
30 auto metaDataPool = properties.value(METADATA_POOL_PROPERTY).value<MetadataPool>();
31 auto variableMetadata = RandomGenerator::instance().randomChoice(metaDataPool);
31 auto variableMetadata = RandomGenerator::instance().randomChoice(metaDataPool);
32
32
33 // Retrieves provider
33 // Retrieves provider
34 auto variableProvider
34 auto variableProvider
35 = properties.value(PROVIDER_PROPERTY).value<std::shared_ptr<IDataProvider> >();
35 = properties.value(PROVIDER_PROPERTY).value<std::shared_ptr<IDataProvider> >();
36
36
37 auto variableName = QString{"Var_%1"}.arg(QUuid::createUuid().toString());
37 auto variableName = QString{"Var_%1"}.arg(QUuid::createUuid().toString());
38 qCInfo(LOG_FuzzingOperations()).noquote()
38 qCInfo(LOG_FuzzingOperations()).noquote()
39 << "Creating variable" << variableName << "(metadata:" << variableMetadata << ")...";
39 << "Creating variable" << variableName << "(metadata:" << variableMetadata << ")...";
40
40
41 auto newVariable
41 auto newVariable
42 = variableController.createVariable(variableName, variableMetadata, variableProvider);
42 = variableController.createVariable(variableName, variableMetadata, variableProvider);
43
43
44 // Updates variable's state
44 // Updates variable's state
45 auto &variableState = fuzzingState.variableState(variableId);
45 auto &variableState = fuzzingState.variableState(variableId);
46 variableState.m_Range = properties.value(INITIAL_RANGE_PROPERTY).value<SqpRange>();
46 variableState.m_Range = properties.value(INITIAL_RANGE_PROPERTY).value<SqpRange>();
47 std::swap(variableState.m_Variable, newVariable);
47 std::swap(variableState.m_Variable, newVariable);
48 }
48 }
49 };
49 };
50
50
51 struct DeleteOperation : public IFuzzingOperation {
51 struct DeleteOperation : public IFuzzingOperation {
52 bool canExecute(VariableId variableId, const FuzzingState &fuzzingState) const override
52 bool canExecute(VariableId variableId, const FuzzingState &fuzzingState) const override
53 {
53 {
54 // A variable can be delete only if it exists
54 // A variable can be delete only if it exists
55 return fuzzingState.variableState(variableId).m_Variable != nullptr;
55 return fuzzingState.variableState(variableId).m_Variable != nullptr;
56 }
56 }
57
57
58 void execute(VariableId variableId, FuzzingState &fuzzingState,
58 void execute(VariableId variableId, FuzzingState &fuzzingState,
59 VariableController &variableController, const Properties &) const override
59 VariableController &variableController, const Properties &) const override
60 {
60 {
61 auto &variableState = fuzzingState.variableState(variableId);
61 auto &variableState = fuzzingState.variableState(variableId);
62
62
63 qCInfo(LOG_FuzzingOperations()).noquote()
63 qCInfo(LOG_FuzzingOperations()).noquote()
64 << "Deleting variable" << variableState.m_Variable->name() << "...";
64 << "Deleting variable" << variableState.m_Variable->name() << "...";
65 variableController.deleteVariable(variableState.m_Variable);
65 variableController.deleteVariable(variableState.m_Variable);
66
66
67 // Updates variable's state
67 // Updates variable's state
68 variableState.m_Range = INVALID_RANGE;
68 variableState.m_Range = INVALID_RANGE;
69 variableState.m_Variable = nullptr;
69 variableState.m_Variable = nullptr;
70
70
71 // Desynchronizes the variable if it was in a sync group
71 // Desynchronizes the variable if it was in a sync group
72 auto syncGroupId = fuzzingState.syncGroupId(variableId);
72 auto syncGroupId = fuzzingState.syncGroupId(variableId);
73 fuzzingState.desynchronizeVariable(variableId, syncGroupId);
73 fuzzingState.desynchronizeVariable(variableId, syncGroupId);
74 }
74 }
75 };
75 };
76
76
77 /**
77 /**
78 * Defines a move operation through a range.
78 * Defines a move operation through a range.
79 *
79 *
80 * A move operation is determined by three functions:
80 * A move operation is determined by three functions:
81 * - Two 'move' functions, used to indicate in which direction the beginning and the end of a range
81 * - Two 'move' functions, used to indicate in which direction the beginning and the end of a range
82 * are going during the operation. These functions will be:
82 * are going during the operation. These functions will be:
83 * -- {<- / <-} for pan left
83 * -- {<- / <-} for pan left
84 * -- {-> / ->} for pan right
84 * -- {-> / ->} for pan right
85 * -- {-> / <-} for zoom in
85 * -- {-> / <-} for zoom in
86 * -- {<- / ->} for zoom out
86 * -- {<- / ->} for zoom out
87 * - One 'max move' functions, used to compute the max delta at which the operation can move a
87 * - One 'max move' functions, used to compute the max delta at which the operation can move a
88 * range, according to a max range. For exemple, for a range of {1, 5} and a max range of {0, 10},
88 * range, according to a max range. For exemple, for a range of {1, 5} and a max range of {0, 10},
89 * max deltas will be:
89 * max deltas will be:
90 * -- {0, 4} for pan left
90 * -- {0, 4} for pan left
91 * -- {6, 10} for pan right
91 * -- {6, 10} for pan right
92 * -- {3, 3} for zoom in
92 * -- {3, 3} for zoom in
93 * -- {0, 6} for zoom out (same spacing left and right)
93 * -- {0, 6} for zoom out (same spacing left and right)
94 */
94 */
95 struct MoveOperation : public IFuzzingOperation {
95 struct MoveOperation : public IFuzzingOperation {
96 using MoveFunction = std::function<double(double currentValue, double maxValue)>;
96 using MoveFunction = std::function<double(double currentValue, double maxValue)>;
97 using MaxMoveFunction = std::function<double(const SqpRange &range, const SqpRange &maxRange)>;
97 using MaxMoveFunction = std::function<double(const SqpRange &range, const SqpRange &maxRange)>;
98
98
99 explicit MoveOperation(MoveFunction rangeStartMoveFun, MoveFunction rangeEndMoveFun,
99 explicit MoveOperation(MoveFunction rangeStartMoveFun, MoveFunction rangeEndMoveFun,
100 MaxMoveFunction maxMoveFun,
100 MaxMoveFunction maxMoveFun,
101 const QString &label = QStringLiteral("Move operation"))
101 const QString &label = QStringLiteral("Move operation"))
102 : m_RangeStartMoveFun{std::move(rangeStartMoveFun)},
102 : m_RangeStartMoveFun{std::move(rangeStartMoveFun)},
103 m_RangeEndMoveFun{std::move(rangeEndMoveFun)},
103 m_RangeEndMoveFun{std::move(rangeEndMoveFun)},
104 m_MaxMoveFun{std::move(maxMoveFun)},
104 m_MaxMoveFun{std::move(maxMoveFun)},
105 m_Label{label}
105 m_Label{label}
106 {
106 {
107 }
107 }
108
108
109 bool canExecute(VariableId variableId, const FuzzingState &fuzzingState) const override
109 bool canExecute(VariableId variableId, const FuzzingState &fuzzingState) const override
110 {
110 {
111 return fuzzingState.variableState(variableId).m_Variable != nullptr;
111 return fuzzingState.variableState(variableId).m_Variable != nullptr;
112 }
112 }
113
113
114 void execute(VariableId variableId, FuzzingState &fuzzingState,
114 void execute(VariableId variableId, FuzzingState &fuzzingState,
115 VariableController &variableController,
115 VariableController &variableController,
116 const Properties &properties) const override
116 const Properties &properties) const override
117 {
117 {
118 auto &variableState = fuzzingState.variableState(variableId);
118 auto &variableState = fuzzingState.variableState(variableId);
119 auto variable = variableState.m_Variable;
119 auto variable = variableState.m_Variable;
120
120
121 // Gets the max range defined
121 // Gets the max range defined
122 auto maxRange = properties.value(MAX_RANGE_PROPERTY, QVariant::fromValue(INVALID_RANGE))
122 auto maxRange = properties.value(MAX_RANGE_PROPERTY, QVariant::fromValue(INVALID_RANGE))
123 .value<SqpRange>();
123 .value<SqpRange>();
124 auto variableRange = variable->range();
124 auto variableRange = variable->range();
125
125
126 if (maxRange == INVALID_RANGE || variableRange.m_TStart < maxRange.m_TStart
126 if (maxRange == INVALID_RANGE || variableRange.m_TStart < maxRange.m_TStart
127 || variableRange.m_TEnd > maxRange.m_TEnd) {
127 || variableRange.m_TEnd > maxRange.m_TEnd) {
128 qCWarning(LOG_FuzzingOperations()) << "Can't execute operation: invalid max range";
128 qCWarning(LOG_FuzzingOperations()) << "Can't execute operation: invalid max range";
129 return;
129 return;
130 }
130 }
131
131
132 // Computes the max delta at which the variable can move, up to the limits of the max range
132 // Computes the max delta at which the variable can move, up to the limits of the max range
133 auto deltaMax = m_MaxMoveFun(variable->range(), maxRange);
133 auto deltaMax = m_MaxMoveFun(variable->range(), maxRange);
134
134
135 // Generates random delta that will be used to move variable
135 // Generates random delta that will be used to move variable
136 auto delta = RandomGenerator::instance().generateDouble(0, deltaMax);
136 auto delta = RandomGenerator::instance().generateDouble(0, deltaMax);
137
137
138 // Moves variable to its new range
138 // Moves variable to its new range
139 auto isSynchronized = !fuzzingState.syncGroupId(variableId).isNull();
139 auto newVariableRange = SqpRange{m_RangeStartMoveFun(variableRange.m_TStart, delta),
140 auto newVariableRange = SqpRange{m_RangeStartMoveFun(variableRange.m_TStart, delta),
140 m_RangeEndMoveFun(variableRange.m_TEnd, delta)};
141 m_RangeEndMoveFun(variableRange.m_TEnd, delta)};
141 qCInfo(LOG_FuzzingOperations()).noquote()
142 qCInfo(LOG_FuzzingOperations()).noquote()
142 << "Performing" << m_Label << "on" << variable->name() << "(from" << variableRange
143 << "Performing" << m_Label << "on" << variable->name() << "(from" << variableRange
143 << "to" << newVariableRange << ")...";
144 << "to" << newVariableRange << ")...";
144 variableController.onRequestDataLoading({variable}, newVariableRange, false);
145 variableController.onRequestDataLoading({variable}, newVariableRange, isSynchronized);
145
146
146 // Updates variable's state
147 // Updates state
147 variableState.m_Range = newVariableRange;
148 fuzzingState.updateRanges(variableId, newVariableRange);
148 }
149 }
149
150
150 MoveFunction m_RangeStartMoveFun;
151 MoveFunction m_RangeStartMoveFun;
151 MoveFunction m_RangeEndMoveFun;
152 MoveFunction m_RangeEndMoveFun;
152 MaxMoveFunction m_MaxMoveFun;
153 MaxMoveFunction m_MaxMoveFun;
153 QString m_Label;
154 QString m_Label;
154 };
155 };
155
156
156 struct SynchronizeOperation : public IFuzzingOperation {
157 struct SynchronizeOperation : public IFuzzingOperation {
157 bool canExecute(VariableId variableId, const FuzzingState &fuzzingState) const override
158 bool canExecute(VariableId variableId, const FuzzingState &fuzzingState) const override
158 {
159 {
159 auto variable = fuzzingState.variableState(variableId).m_Variable;
160 auto variable = fuzzingState.variableState(variableId).m_Variable;
160 return variable != nullptr && !fuzzingState.m_SyncGroupsPool.empty()
161 return variable != nullptr && !fuzzingState.m_SyncGroupsPool.empty()
161 && fuzzingState.syncGroupId(variableId).isNull();
162 && fuzzingState.syncGroupId(variableId).isNull();
162 }
163 }
163
164
164 void execute(VariableId variableId, FuzzingState &fuzzingState,
165 void execute(VariableId variableId, FuzzingState &fuzzingState,
165 VariableController &variableController, const Properties &) const override
166 VariableController &variableController, const Properties &) const override
166 {
167 {
167 auto &variableState = fuzzingState.variableState(variableId);
168 auto &variableState = fuzzingState.variableState(variableId);
168
169
169 // Chooses a random synchronization group and adds the variable into sync group
170 // Chooses a random synchronization group and adds the variable into sync group
170 auto syncGroupId = RandomGenerator::instance().randomChoice(fuzzingState.syncGroupsIds());
171 auto syncGroupId = RandomGenerator::instance().randomChoice(fuzzingState.syncGroupsIds());
171 qCInfo(LOG_FuzzingOperations()).noquote()
172 qCInfo(LOG_FuzzingOperations()).noquote()
172 << "Adding" << variableState.m_Variable->name() << "into synchronization group"
173 << "Adding" << variableState.m_Variable->name() << "into synchronization group"
173 << syncGroupId << "...";
174 << syncGroupId << "...";
174 variableController.onAddSynchronized(variableState.m_Variable, syncGroupId);
175 variableController.onAddSynchronized(variableState.m_Variable, syncGroupId);
175
176
176 // Updates state
177 // Updates state
177 fuzzingState.synchronizeVariable(variableId, syncGroupId);
178 fuzzingState.synchronizeVariable(variableId, syncGroupId);
178 }
179 }
179 };
180 };
180
181
181 struct DesynchronizeOperation : public IFuzzingOperation {
182 struct DesynchronizeOperation : public IFuzzingOperation {
182 bool canExecute(VariableId variableId, const FuzzingState &fuzzingState) const override
183 bool canExecute(VariableId variableId, const FuzzingState &fuzzingState) const override
183 {
184 {
184 auto variable = fuzzingState.variableState(variableId).m_Variable;
185 auto variable = fuzzingState.variableState(variableId).m_Variable;
185 return variable != nullptr && !fuzzingState.syncGroupId(variableId).isNull();
186 return variable != nullptr && !fuzzingState.syncGroupId(variableId).isNull();
186 }
187 }
187
188
188 void execute(VariableId variableId, FuzzingState &fuzzingState,
189 void execute(VariableId variableId, FuzzingState &fuzzingState,
189 VariableController &variableController, const Properties &) const override
190 VariableController &variableController, const Properties &) const override
190 {
191 {
191 auto &variableState = fuzzingState.variableState(variableId);
192 auto &variableState = fuzzingState.variableState(variableId);
192
193
193 // Gets the sync group of the variable
194 // Gets the sync group of the variable
194 auto syncGroupId = fuzzingState.syncGroupId(variableId);
195 auto syncGroupId = fuzzingState.syncGroupId(variableId);
195
196
196 qCInfo(LOG_FuzzingOperations()).noquote()
197 qCInfo(LOG_FuzzingOperations()).noquote()
197 << "Removing" << variableState.m_Variable->name() << "from synchronization group"
198 << "Removing" << variableState.m_Variable->name() << "from synchronization group"
198 << syncGroupId << "...";
199 << syncGroupId << "...";
199 variableController.onAddSynchronized(variableState.m_Variable, syncGroupId);
200 variableController.onAddSynchronized(variableState.m_Variable, syncGroupId);
200
201
201 // Updates state
202 // Updates state
202 fuzzingState.desynchronizeVariable(variableId, syncGroupId);
203 fuzzingState.desynchronizeVariable(variableId, syncGroupId);
203 }
204 }
204 };
205 };
205
206
206 struct UnknownOperation : public IFuzzingOperation {
207 struct UnknownOperation : public IFuzzingOperation {
207 bool canExecute(VariableId, const FuzzingState &) const override { return false; }
208 bool canExecute(VariableId, const FuzzingState &) const override { return false; }
208
209
209 void execute(VariableId, FuzzingState &, VariableController &,
210 void execute(VariableId, FuzzingState &, VariableController &,
210 const Properties &) const override
211 const Properties &) const override
211 {
212 {
212 }
213 }
213 };
214 };
214
215
215 } // namespace
216 } // namespace
216
217
217 std::unique_ptr<IFuzzingOperation> FuzzingOperationFactory::create(FuzzingOperationType type)
218 std::unique_ptr<IFuzzingOperation> FuzzingOperationFactory::create(FuzzingOperationType type)
218 {
219 {
219 switch (type) {
220 switch (type) {
220 case FuzzingOperationType::CREATE:
221 case FuzzingOperationType::CREATE:
221 return std::make_unique<CreateOperation>();
222 return std::make_unique<CreateOperation>();
222 case FuzzingOperationType::DELETE:
223 case FuzzingOperationType::DELETE:
223 return std::make_unique<DeleteOperation>();
224 return std::make_unique<DeleteOperation>();
224 case FuzzingOperationType::PAN_LEFT:
225 case FuzzingOperationType::PAN_LEFT:
225 return std::make_unique<MoveOperation>(
226 return std::make_unique<MoveOperation>(
226 std::minus<double>(), std::minus<double>(),
227 std::minus<double>(), std::minus<double>(),
227 [](const SqpRange &range, const SqpRange &maxRange) {
228 [](const SqpRange &range, const SqpRange &maxRange) {
228 return range.m_TStart - maxRange.m_TStart;
229 return range.m_TStart - maxRange.m_TStart;
229 },
230 },
230 QStringLiteral("Pan left operation"));
231 QStringLiteral("Pan left operation"));
231 case FuzzingOperationType::PAN_RIGHT:
232 case FuzzingOperationType::PAN_RIGHT:
232 return std::make_unique<MoveOperation>(
233 return std::make_unique<MoveOperation>(
233 std::plus<double>(), std::plus<double>(),
234 std::plus<double>(), std::plus<double>(),
234 [](const SqpRange &range, const SqpRange &maxRange) {
235 [](const SqpRange &range, const SqpRange &maxRange) {
235 return maxRange.m_TEnd - range.m_TEnd;
236 return maxRange.m_TEnd - range.m_TEnd;
236 },
237 },
237 QStringLiteral("Pan right operation"));
238 QStringLiteral("Pan right operation"));
238 case FuzzingOperationType::ZOOM_IN:
239 case FuzzingOperationType::ZOOM_IN:
239 return std::make_unique<MoveOperation>(
240 return std::make_unique<MoveOperation>(
240 std::plus<double>(), std::minus<double>(),
241 std::plus<double>(), std::minus<double>(),
241 [](const SqpRange &range, const SqpRange &maxRange) {
242 [](const SqpRange &range, const SqpRange &maxRange) {
242 Q_UNUSED(maxRange)
243 Q_UNUSED(maxRange)
243 return range.m_TEnd - (range.m_TStart + range.m_TEnd) / 2.;
244 return range.m_TEnd - (range.m_TStart + range.m_TEnd) / 2.;
244 },
245 },
245 QStringLiteral("Zoom in operation"));
246 QStringLiteral("Zoom in operation"));
246 case FuzzingOperationType::ZOOM_OUT:
247 case FuzzingOperationType::ZOOM_OUT:
247 return std::make_unique<MoveOperation>(
248 return std::make_unique<MoveOperation>(
248 std::minus<double>(), std::plus<double>(),
249 std::minus<double>(), std::plus<double>(),
249 [](const SqpRange &range, const SqpRange &maxRange) {
250 [](const SqpRange &range, const SqpRange &maxRange) {
250 return std::min(range.m_TStart - maxRange.m_TStart,
251 return std::min(range.m_TStart - maxRange.m_TStart,
251 maxRange.m_TEnd - range.m_TEnd);
252 maxRange.m_TEnd - range.m_TEnd);
252 },
253 },
253 QStringLiteral("Zoom out operation"));
254 QStringLiteral("Zoom out operation"));
254 case FuzzingOperationType::SYNCHRONIZE:
255 case FuzzingOperationType::SYNCHRONIZE:
255 return std::make_unique<SynchronizeOperation>();
256 return std::make_unique<SynchronizeOperation>();
256 case FuzzingOperationType::DESYNCHRONIZE:
257 case FuzzingOperationType::DESYNCHRONIZE:
257 return std::make_unique<DesynchronizeOperation>();
258 return std::make_unique<DesynchronizeOperation>();
258 default:
259 default:
259 // Default case returns unknown operation
260 // Default case returns unknown operation
260 break;
261 break;
261 }
262 }
262
263
263 return std::make_unique<UnknownOperation>();
264 return std::make_unique<UnknownOperation>();
264 }
265 }
General Comments 0
You need to be logged in to leave comments. Login now