##// END OF EJS Templates
Implements move operations (2)...
Alexandre Leroux -
r1185:4e9317891e93
parent child
Show More
@@ -1,154 +1,178
1 1 #include "FuzzingOperations.h"
2 2 #include "FuzzingUtils.h"
3 3
4 4 #include <Data/IDataProvider.h>
5 5
6 6 #include <Variable/Variable.h>
7 7 #include <Variable/VariableController.h>
8 8
9 9 #include <QUuid>
10 10
11 11 #include <functional>
12 12
13 13 Q_LOGGING_CATEGORY(LOG_FuzzingOperations, "FuzzingOperations")
14 14
15 15 namespace {
16 16
17 17 struct CreateOperation : public IFuzzingOperation {
18 18 bool canExecute(std::shared_ptr<Variable> variable) const override
19 19 {
20 20 // A variable can be created only if it doesn't exist yet
21 21 return variable == nullptr;
22 22 }
23 23
24 24 void execute(std::shared_ptr<Variable> &variable, VariableController &variableController,
25 25 const Properties &properties) const override
26 26 {
27 27 // Retrieves metadata pool from properties, and choose one of the metadata entries to
28 28 // associate it with the variable
29 29 auto metaDataPool = properties.value(METADATA_POOL_PROPERTY).value<MetadataPool>();
30 30 auto variableMetadata = RandomGenerator::instance().randomChoice(metaDataPool);
31 31
32 32 // Retrieves provider
33 33 auto variableProvider
34 34 = properties.value(PROVIDER_PROPERTY).value<std::shared_ptr<IDataProvider> >();
35 35
36 36 auto variableName = QString{"Var_%1"}.arg(QUuid::createUuid().toString());
37 37 qCInfo(LOG_FuzzingOperations())
38 38 << "Creating variable" << variableName << "(metadata:" << variableMetadata << ")";
39 39
40 40 auto newVariable
41 41 = variableController.createVariable(variableName, variableMetadata, variableProvider);
42 42 std::swap(variable, newVariable);
43 43 }
44 44 };
45 45
46 46 /**
47 47 * Defines a move operation through a range.
48 48 *
49 49 * A move operation is determined by three functions:
50 50 * - Two 'move' functions, used to indicate in which direction the beginning and the end of a range
51 51 * are going during the operation. These functions will be:
52 52 * -- {<- / <-} for pan left
53 53 * -- {-> / ->} for pan right
54 54 * -- {-> / <-} for zoom in
55 55 * -- {<- / ->} for zoom out
56 56 * - One 'max move' functions, used to compute the max delta at which the operation can move a
57 57 * range, according to a max range. For exemple, for a range of {1, 5} and a max range of {0, 10},
58 58 * max deltas will be:
59 59 * -- {0, 4} for pan left
60 60 * -- {6, 10} for pan right
61 61 * -- {3, 3} for zoom in
62 62 * -- {0, 6} for zoom out (same spacing left and right)
63 63 */
64 64 struct MoveOperation : public IFuzzingOperation {
65 65 using MoveFunction = std::function<double(double currentValue, double maxValue)>;
66 66 using MaxMoveFunction = std::function<double(const SqpRange &range, const SqpRange &maxRange)>;
67 67
68 68 explicit MoveOperation(MoveFunction rangeStartMoveFun, MoveFunction rangeEndMoveFun,
69 69 MaxMoveFunction maxMoveFun,
70 70 const QString &label = QStringLiteral("Move operation"))
71 71 : m_RangeStartMoveFun{std::move(rangeStartMoveFun)},
72 72 m_RangeEndMoveFun{std::move(rangeEndMoveFun)},
73 73 m_MaxMoveFun{std::move(maxMoveFun)},
74 74 m_Label{label}
75 75 {
76 76 }
77 77
78 78 bool canExecute(std::shared_ptr<Variable> variable) const override
79 79 {
80 80 return variable != nullptr;
81 81 }
82 82
83 83 void execute(std::shared_ptr<Variable> &variable, VariableController &variableController,
84 84 const Properties &properties) const override
85 85 {
86 // Gets the max range defined
87 auto maxRange = properties.value(MAX_RANGE_PROPERTY, QVariant::fromValue(INVALID_RANGE))
88 .value<SqpRange>();
89 auto variableRange = variable->range();
90
91 if (maxRange == INVALID_RANGE || variableRange.m_TStart < maxRange.m_TStart
92 || variableRange.m_TEnd > maxRange.m_TEnd) {
93 qCWarning(LOG_FuzzingOperations()) << "Can't execute operation: invalid max range";
94 return;
95 }
96
97 // Computes the max delta at which the variable can move, up to the limits of the max range
98 auto deltaMax = m_MaxMoveFun(variable->range(), maxRange);
99
100 // Generates random delta that will be used to move variable
101 auto delta = RandomGenerator::instance().generateDouble(0, deltaMax);
102
103 // Moves variable to its new range
104 auto newVariableRange = SqpRange{m_RangeStartMoveFun(variableRange.m_TStart, delta),
105 m_RangeEndMoveFun(variableRange.m_TEnd, delta)};
106 qCInfo(LOG_FuzzingOperations())
107 << "Performing" << m_Label << "on" << variable->name() << "(from" << variableRange
108 << "to" << newVariableRange << ")...";
109 variableController.onRequestDataLoading({variable}, newVariableRange, false);
86 110 }
87 111
88 112 MoveFunction m_RangeStartMoveFun;
89 113 MoveFunction m_RangeEndMoveFun;
90 114 MaxMoveFunction m_MaxMoveFun;
91 115 QString m_Label;
92 116 };
93 117
94 118 struct UnknownOperation : public IFuzzingOperation {
95 119 bool canExecute(std::shared_ptr<Variable> variable) const override
96 120 {
97 121 Q_UNUSED(variable);
98 122 return false;
99 123 }
100 124
101 125 void execute(std::shared_ptr<Variable> &variable, VariableController &variableController,
102 126 const Properties &properties) const override
103 127 {
104 128 Q_UNUSED(variable);
105 129 Q_UNUSED(variableController);
106 130 Q_UNUSED(properties);
107 131 // Does nothing
108 132 }
109 133 };
110 134
111 135 } // namespace
112 136
113 137 std::unique_ptr<IFuzzingOperation> FuzzingOperationFactory::create(FuzzingOperationType type)
114 138 {
115 139 switch (type) {
116 140 case FuzzingOperationType::CREATE:
117 141 return std::make_unique<CreateOperation>();
118 142 case FuzzingOperationType::PAN_LEFT:
119 143 return std::make_unique<MoveOperation>(
120 144 std::minus<double>(), std::minus<double>(),
121 145 [](const SqpRange &range, const SqpRange &maxRange) {
122 146 return range.m_TStart - maxRange.m_TStart;
123 147 },
124 148 QStringLiteral("Pan left operation"));
125 149 case FuzzingOperationType::PAN_RIGHT:
126 150 return std::make_unique<MoveOperation>(
127 151 std::plus<double>(), std::plus<double>(),
128 152 [](const SqpRange &range, const SqpRange &maxRange) {
129 153 return maxRange.m_TEnd - range.m_TEnd;
130 154 },
131 155 QStringLiteral("Pan right operation"));
132 156 case FuzzingOperationType::ZOOM_IN:
133 157 return std::make_unique<MoveOperation>(
134 158 std::plus<double>(), std::minus<double>(),
135 159 [](const SqpRange &range, const SqpRange &maxRange) {
136 160 Q_UNUSED(maxRange)
137 161 return range.m_TEnd - (range.m_TStart + range.m_TEnd) / 2.;
138 162 },
139 163 QStringLiteral("Zoom in operation"));
140 164 case FuzzingOperationType::ZOOM_OUT:
141 165 return std::make_unique<MoveOperation>(
142 166 std::minus<double>(), std::plus<double>(),
143 167 [](const SqpRange &range, const SqpRange &maxRange) {
144 168 return std::min(range.m_TStart - maxRange.m_TStart,
145 169 maxRange.m_TEnd - range.m_TEnd);
146 170 },
147 171 QStringLiteral("Zoom out operation"));
148 172 default:
149 173 // Default case returns unknown operation
150 174 break;
151 175 }
152 176
153 177 return std::make_unique<UnknownOperation>();
154 178 }
General Comments 0
You need to be logged in to leave comments. Login now