OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef CC_BASE_PYRAMID_SEQUENCE_H_ | |
6 #define CC_BASE_PYRAMID_SEQUENCE_H_ | |
7 | |
8 #include <list> | |
9 #include <vector> | |
10 | |
11 #include "base/logging.h" | |
12 #include "cc/base/cc_export.h" | |
13 | |
14 namespace cc { | |
15 | |
16 // This class provides interating mechanism for the mathematical interval | |
vmpstr
2016/08/16 00:40:48
iterating
| |
17 // [start, end] with functionality for inflating the interval. The interval | |
18 // inflation means expanding the start and end by 1 step. Expanding interval | |
19 // [3, 4] by 1 step would give [2, 5], and by 2 steps would give [1, 6]. | |
20 // The iterating mechanism could be used as given below. | |
21 // | |
22 // for (Interval it(FORWARD, 3, 4, 0, 6, false), it; ++it) | |
vmpstr
2016/08/16 00:40:48
I'm not sure what this example is demonstrating, c
| |
23 // int index = it.index(); | |
24 // | |
25 // The output for the above example would be 3, 4. | |
26 class CC_EXPORT Interval { | |
27 public: | |
28 // The types give below decide how to inflate the interval. Suppose the | |
29 // interval is [3, 3] i.e. start = 3 and end = 3. The inflated intervals for | |
30 // different types would be as given below. | |
31 // FORWARD [2, 4] | |
vmpstr
2016/08/16 00:40:48
Can we always have just one direction (ie FORWARD)
| |
32 // BACKWARD [4, 2] | |
33 // DIAGONAL_FORWARD [4, 4] | |
vmpstr
2016/08/16 00:40:48
Why is [4, 4] a valid interval? It seems to not en
| |
34 // DIAGONAL_BACKWARD [2, 2] | |
35 enum class Type : uint16_t { | |
36 FORWARD, | |
37 BACKWARD, | |
38 DIAGONAL_FORWARD, | |
39 DIAGONAL_BACKWARD | |
vmpstr
2016/08/16 00:40:48
If these are not currently used, please remove the
| |
40 }; | |
41 | |
42 // |reverse_order| decides the direction of iteration order, i.e. | |
43 // from start to end or from end to start (called as reverse direction). | |
44 Interval(Type type, | |
45 int start, | |
46 int end, | |
47 int start_inflate_limit, | |
48 int end_inflate_limit, | |
49 bool reverse_order); | |
vmpstr
2016/08/16 00:40:48
As I mentioned in my previous comment, I don't und
| |
50 Interval(const Interval& other); | |
51 Interval(Interval&& other); | |
52 ~Interval(); | |
53 | |
54 Interval& operator=(const Interval& other); | |
55 Interval& operator=(Interval&& other); | |
56 | |
57 operator bool() const { return within_bounds_; } | |
58 Interval& operator++(); | |
59 | |
60 int index() { return current_index_; } | |
61 // This function converts the current interval to level (level >= 0) given. | |
62 void InflateToLevel(int level); | |
63 // Returns the distance between |start_| and |end_| which includes both | |
64 // |start_| and |end_|. | |
65 int GetSpan(); | |
66 | |
67 private: | |
68 using InflateToLevelFnPtr = void (Interval::*)(int level); | |
69 using IsWithinBoundsFnPtr = bool (Interval::*)(); | |
70 | |
71 void Init(Type type); | |
72 void Reset(); | |
73 | |
74 // Interval inflating functions for different Interval types. | |
75 void InflateToLevelForward(int levels); | |
76 void InflateToLevelBackward(int levels); | |
77 void InflateToLevelDiagonalForward(int levels); | |
78 void InflateToLevelDiagonalBackward(int levels); | |
79 | |
80 // Functions for checking the bounds for different Interval types. | |
81 bool IsWithinBoundsForward(); | |
82 bool IsWithinBoundsBackward(); | |
83 bool IsWithinBoundsDiagonal(); | |
84 | |
85 int start_; | |
86 int end_; | |
87 int initial_start_; | |
88 int initial_end_; | |
89 int start_inflate_limit_; | |
90 int end_inflate_limit_; | |
91 bool reverse_order_; | |
92 bool within_bounds_; | |
93 int current_index_; | |
94 int step_; | |
95 | |
96 InflateToLevelFnPtr inflate_to_level_ptr_; | |
97 IsWithinBoundsFnPtr is_within_bounds_ptr_; | |
98 }; | |
vmpstr
2016/08/16 00:40:48
As far as I understand it, this class is just a pa
| |
99 | |
100 // This class implements the 2D sequence (x, y) which uses two intervals, one | |
101 // for traversing the actual interval, called as traversal interval and other | |
102 // for computing the number of levels in the traversal interval. The indices of | |
103 // these two intervals represent the x and y indices. | |
104 // LevelDistance means each level has some distance value associated with it. | |
105 // This distance is the distance from the index of the interest. If there are 5 | |
106 // levels and distance is 10, then the levels would have distances as given | |
107 // below. 0, 10, 20, 30, 40. The first level starts with 0, so as to represent | |
108 // the minimum distance for that level. The distances are stored in sorted | |
109 // order in the vector, so that distance at front is minimum and distance at | |
110 // back is maximum. The layout of the level distance vector for the example | |
111 // would be (0, 0), (1, 10), (2, 20), (3, 30), (4, 40). | |
112 // | |
113 // e.g. If traversal interval is [3, 4], number of levels is 3 and distance is | |
114 // 10, then the triagular sequence would give following data. | |
115 // | |
116 // traversal_interval level index | |
117 // [3, 4] 0 | |
118 // [2, 5] 1 | |
119 // [1, 6] 2 | |
120 // | |
121 // If the |reverse_order| is true, then the iteration sequence would be - | |
122 // | |
123 // traversal_interval level index | |
124 // [1, 6] 2 | |
125 // [2, 5] 1 | |
126 // [3, 4] 0 | |
127 // | |
128 // The indices (x, y) for the normal order would be as given below. | |
129 // | |
130 // (3, 0), (4, 0) (level 1) | |
131 // (2, 1), (3, 1), (4, 1), (5, 1), (level 2) | |
132 // (1, 2), (2, 2), (3, 2), (4, 2), (5, 2), (6, 2) (level 3) | |
133 // | |
134 // The layout as given below looks like a triangle in co-ordinate space and | |
135 // hence the name "TriangularSequence". | |
136 // | |
137 // x 0 1 2 3 4 5 6 7 | |
138 // y.---------------- | |
139 // 0| . . . 3 4 . . . (level 1, distance 0) | |
140 // 1| . . 2 3 4 5 . . (level 2, distance 10) | |
141 // 2| . 1 2 3 4 5 6 . (level 3, distance 20) | |
142 // 3| . . . . . . . . | |
143 // 4| . . . . . . . . | |
144 class CC_EXPORT TriangularSequence { | |
145 public: | |
146 typedef std::list<TriangularSequence> List; | |
147 typedef List::iterator Iterator; | |
148 typedef List::reverse_iterator ReverseIterator; | |
149 | |
150 TriangularSequence(); | |
151 // If |swapped| is false, then the indices in |traversal_interval| represent | |
152 // the x indice and level indices in |level_interval| represent the y indices, | |
153 // otherwise vice-versa. | |
154 TriangularSequence(std::string&& name, | |
155 Interval&& traversal_interval, | |
156 Interval&& level_interval, | |
157 bool swapped, | |
158 int levels_to_skip, | |
159 int distance, | |
160 bool reverse_order); | |
161 TriangularSequence(const TriangularSequence& other); | |
162 TriangularSequence(TriangularSequence&& other); | |
163 ~TriangularSequence(); | |
164 | |
165 TriangularSequence& operator=(const TriangularSequence& other); | |
166 TriangularSequence& operator=(TriangularSequence&& other); | |
167 | |
168 operator bool() const { return !level_distances_.empty(); } | |
169 TriangularSequence& operator++(); | |
170 | |
171 bool is_swapped() { return swapped_; } | |
172 Interval* traversal_interval() { | |
173 DCHECK(*this); | |
174 return &traversal_interval_; | |
175 } | |
176 int level_index() { | |
177 DCHECK(*this); | |
178 return current_level_index_; | |
179 } | |
180 // Get minimum/maximum distance. | |
181 int GetMinimumDistance() const; | |
182 int GetMaximumDistance() const; | |
183 | |
184 private: | |
185 struct LevelDistance { | |
186 LevelDistance(int interval_level, int level_index, int distance) | |
187 : interval_level(interval_level), | |
188 level_index(level_index), | |
189 distance(distance) {} | |
190 | |
191 int interval_level; | |
192 int level_index; | |
193 int distance; | |
194 }; | |
195 | |
196 void Advance(); | |
197 void UpdateCurrent(); | |
198 | |
199 std::string name_; | |
200 Interval traversal_interval_; | |
201 bool swapped_; | |
202 bool reverse_order_; | |
203 int current_level_index_; | |
204 std::vector<LevelDistance> level_distances_; | |
205 }; | |
206 | |
207 // The pyramid sequence is list of 8 triangular sequences, one for each of the | |
208 // directions considered counter-clockwise or clockwise. The ideal pyramid | |
209 // sequence is as given below where it has all 8 directions. | |
210 // | |
211 // 2 T T T T T 1 | |
212 // L 2 T T T 1 R | |
213 // L L 2 T 1 R R | |
214 // L L L * R R R | |
215 // L L 3 B 4 R R | |
216 // L 3 B B B 4 R | |
217 // 3 B B B B B 4 | |
218 // | |
219 // The different triangular sequences for the above pyramid sequence are shown | |
220 // below. | |
221 // | |
222 // (T = top) | |
223 // | | |
224 // (2 = top-left) T T T T T (1 = top-right) | |
225 // 2 T T T 1 | |
226 // L 2 T 1 R | |
227 // L L 2 1 R R | |
228 // (L = left) --> L L L * R R R <-- (R = right) | |
229 // L L 3 4 R R | |
230 // L 3 B 4 R | |
231 // 3 B B B 4 | |
232 // (3 = bottom-left) B B B B B (4 = bottom-right) | |
233 // | | |
234 // (B = bottom) | |
235 // | |
236 // This sequence iterates over all the underlined triangular sequences level | |
237 // by level in increasing or decreasing order of distances. The increasing order | |
238 // of distances is called as TopDownPyramidSequence, while the decreasubg order | |
239 // of distances is called as BottomUpPyramidSequence. The iteration sequence | |
240 // generated by top down pyramid sequence is as given below. (Iteration is | |
241 // considered counter-clockwise.) | |
242 // | |
243 // x 0 1 2 3 4 5 6 | |
244 // y.--------------------- | |
245 // 0| 36 35 34 33 32 31 30 | |
246 // 1| 37 16 15 14 13 12 29 | |
247 // 2| 38 17 4 3 2 11 28 | |
248 // 3| 39 18 5 * 1 10 27 | |
249 // 4| 40 19 6 7 8 9 26 | |
250 // 5| 41 20 21 22 23 24 25 | |
251 // 6| 42 43 44 45 46 47 48 | |
252 // | |
253 // The iteration sequence generated by bottom up pyramid sequence is as given | |
254 // below. (Iteration is considered clockwise.) | |
255 // | |
256 // x 0 1 2 3 4 5 6 | |
257 // y.---------------------- | |
258 // 0| 13 14 15 16 17 18 19 | |
259 // 1| 12 33 34 35 36 37 20 | |
260 // 2| 11 32 45 46 47 38 21 | |
261 // 3| 10 31 44 * 48 39 22 | |
262 // 4| 9 30 43 42 41 40 23 | |
263 // 5| 8 29 28 27 26 25 24 | |
264 // 6| 7 6 5 4 3 2 1 | |
265 class CC_EXPORT PyramidSequence { | |
266 public: | |
267 explicit PyramidSequence(bool reverse_order); | |
268 PyramidSequence(const PyramidSequence& other); | |
269 PyramidSequence(PyramidSequence&& other); | |
270 virtual ~PyramidSequence(); | |
271 | |
272 PyramidSequence& operator=(const PyramidSequence& other); | |
273 PyramidSequence& operator=(PyramidSequence&& other); | |
274 | |
275 virtual void Init(int around_left, | |
276 int around_right, | |
277 int around_top, | |
278 int around_bottom, | |
279 int consider_left, | |
280 int consider_right, | |
281 int consider_top, | |
282 int consider_bottom, | |
283 int ignore_left, | |
284 int ignore_right, | |
285 int ignore_top, | |
286 int ignore_bottom, | |
287 int width, | |
288 int height); | |
289 operator bool() const; | |
290 PyramidSequence& operator++(); | |
291 | |
292 int index_x() const { return index_x_; } | |
293 int index_y() const { return index_y_; } | |
294 | |
295 protected: | |
296 void EmplaceAt(int position, TriangularSequence&& triangular_sequence); | |
297 | |
298 void Advance(); | |
299 void UpdateCurrent(); | |
300 | |
301 void RemoveEmptyTriangularSequences(); | |
302 virtual TriangularSequence* GetNextTriangularSequence() = 0; | |
303 | |
304 bool InConsiderRect() const; | |
305 bool InIgnoreRect() const; | |
306 | |
307 bool reverse_order_; | |
308 TriangularSequence* current_triangular_sequence_; | |
309 Interval* current_traversal_interval_; | |
310 int consider_left_; | |
311 int consider_right_; | |
312 int consider_top_; | |
313 int consider_bottom_; | |
314 int ignore_left_; | |
315 int ignore_right_; | |
316 int ignore_top_; | |
317 int ignore_bottom_; | |
318 int index_x_; | |
319 int index_y_; | |
320 TriangularSequence::List triangular_sequences_; | |
321 }; | |
322 | |
323 class CC_EXPORT TopDownPyramidSequence : public PyramidSequence { | |
324 public: | |
325 TopDownPyramidSequence(); | |
326 TopDownPyramidSequence(const TopDownPyramidSequence& other); | |
327 TopDownPyramidSequence(TopDownPyramidSequence&& other); | |
328 ~TopDownPyramidSequence() override; | |
329 | |
330 TopDownPyramidSequence& operator=(const TopDownPyramidSequence& other); | |
331 TopDownPyramidSequence& operator=(TopDownPyramidSequence&& other); | |
332 | |
333 private: | |
334 TriangularSequence* GetNextTriangularSequence() override; | |
335 }; | |
336 | |
337 class CC_EXPORT BottomUpPyramidSequence : public PyramidSequence { | |
338 public: | |
339 BottomUpPyramidSequence(); | |
340 BottomUpPyramidSequence(const BottomUpPyramidSequence& other); | |
341 BottomUpPyramidSequence(BottomUpPyramidSequence&& other); | |
342 ~BottomUpPyramidSequence() override; | |
343 | |
344 BottomUpPyramidSequence& operator=(const BottomUpPyramidSequence& other); | |
345 BottomUpPyramidSequence& operator=(BottomUpPyramidSequence&& other); | |
346 | |
347 private: | |
348 TriangularSequence* GetNextTriangularSequence() override; | |
349 }; | |
350 | |
351 } // namespace cc | |
352 | |
353 #endif // CC_BASE_PYRAMID_SEQUENCE_H_ | |
OLD | NEW |