Chromium Code Reviews| 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 |