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 // Triangular sequence is the representation of numbers in triangular form. This | |
| 17 // takes initial |interval| (start <= number <= end), and inflates that interval | |
| 18 // by the |levels| given, keeping the interval limit defined by the | |
| 19 // |interval_inflate_limit|. | |
| 20 // | |
| 21 // e.g. With intial interval of [3, 4] and levels 4, the triagular sequence | |
| 22 // would be as given below. | |
| 23 // 3 4 (level 1) | |
| 24 // 2 3 4 5 (level 2) | |
| 25 // 1 2 3 4 5 6 (level 3) | |
| 26 // 0 1 2 3 4 5 6 7 (level 4) | |
|
vmpstr
2016/07/19 20:28:28
What would level 5 look like here?
prashant.n
2016/07/20 03:10:49
-1 0 1 2 3 4 5 6 7 8
The inflation of intervals h
| |
| 27 // | |
| 28 // With inflate limit of interval [2, 5] defined for the above example, the | |
| 29 // sequence would be as given below. | |
| 30 // 3 4 | |
| 31 // 2 3 4 5 | |
| 32 // 2 3 4 5 | |
| 33 // 2 3 4 5 | |
| 34 // | |
| 35 // With inflate limit of interval [3, 10] defined for the above example, the | |
| 36 // sequence would be as given below. | |
| 37 // 3 4 | |
| 38 // 3 4 5 | |
| 39 // 3 4 5 6 | |
| 40 // 3 4 5 6 7 | |
| 41 // The triangular sequence can be of four different types as given below. | |
| 42 // 1. FORWARD - start <= end as depicted in above example. | |
| 43 // 2. BACKWARD - start >= end, e.g. initial interval [4, 3] | |
| 44 // 4 3 | |
| 45 // 5 4 3 2 | |
| 46 // 3. DIAGONAL_FORWARD - start == end, in this case inflation happens in | |
| 47 // positive direction. | |
| 48 // e.g. 2, 3, 4, 5 | |
| 49 // 4. DIAGONAL_BACKWARD - start == end, in this case inflation happens in | |
| 50 // negative direction. | |
| 51 // e.g. 5, 4, 3, 2 | |
| 52 class CC_EXPORT TriangularSequence { | |
|
vmpstr
2016/07/19 20:28:28
I think this class is conflating too many settings
prashant.n
2016/07/20 03:10:49
This is to cater different portions of the pyramid
prashant.n
2016/07/20 03:53:10
For this I'll check if we can have container <-> i
| |
| 53 public: | |
| 54 enum class Type : uint16_t { | |
| 55 FORWARD, | |
| 56 BACKWARD, | |
| 57 DIAGONAL_FORWARD, | |
| 58 DIAGONAL_BACKWARD | |
| 59 }; | |
| 60 | |
| 61 // Interval representing start and end, mathematical interval [start, end]. | |
| 62 struct Interval { | |
| 63 Interval(int start, int end) : start(start), end(end) {} | |
| 64 Interval(const Interval& other) = default; | |
|
vmpstr
2016/07/19 20:28:28
You don't need to specify copy/move operations her
prashant.n
2016/07/20 03:10:49
When I tested on Windows (Visual Studio 2013) it w
| |
| 65 Interval(Interval&& other) = default; | |
| 66 Interval& operator=(const Interval& other) = default; | |
| 67 Interval& operator=(Interval&& other) = default; | |
| 68 | |
| 69 int start; | |
| 70 int end; | |
| 71 }; | |
| 72 | |
| 73 // |name| - Name for the sequence. | |
| 74 // |type| - Type of the sequence. | |
| 75 // |interval| - Initial interval. | |
| 76 // |interval_inflate_limit| - Inflating limit for interval. | |
| 77 // |levels| - Number of times inflation should happen. | |
| 78 // |levels_to_skip| - Number of levels to skip. The inital interval is | |
| 79 // inflated to this value, so that the interval to start the sequence is | |
| 80 // pointed to the required level. | |
| 81 // |reverse| - If true the initial interval is inflated to the last level and | |
| 82 // sequence is continued from |levels| to |levels_to_skip|. | |
| 83 TriangularSequence(std::string&& name, | |
| 84 Type type, | |
| 85 Interval&& interval, | |
| 86 Interval&& interval_inflate_limit, | |
| 87 int levels, | |
| 88 int levels_to_skip, | |
| 89 bool reverse); | |
| 90 TriangularSequence(const TriangularSequence& other); | |
| 91 TriangularSequence(TriangularSequence&& other); | |
| 92 ~TriangularSequence(); | |
| 93 | |
| 94 TriangularSequence& operator=(const TriangularSequence& other); | |
| 95 TriangularSequence& operator=(TriangularSequence&& other); | |
| 96 | |
| 97 // Returns whether the sequence at the current level is overflowing the limits | |
| 98 // of the current interval. | |
| 99 bool is_within_bounds() { return within_bounds_; } | |
| 100 | |
| 101 int GetInitialIntervalSpan(); | |
| 102 | |
| 103 // Get the current sequence number, if the number has overflown the current | |
| 104 // level's interval, then interval is inflated and number starting at the next | |
| 105 // interval is returned. If all levels have been traversed, then it returns | |
| 106 // last number in the sequence. | |
| 107 int GetCurrentSequenceNumber(); | |
| 108 // Same like above, but in reverse direction. | |
|
vmpstr
2016/07/19 20:28:28
This is not clear at all. GetCurrentSequenceNumber
prashant.n
2016/07/20 03:10:49
Hmm. I'll write simple functions having more appro
| |
| 109 int GetReverseCurrentSequenceNumber(); | |
| 110 | |
| 111 // Advances the sequence number to the next in the current interval. If number | |
| 112 // overflows the interval, then |within_bounds_| is set to false. | |
| 113 void Advance(); | |
| 114 | |
| 115 private: | |
| 116 using InflateFn = void (TriangularSequence::*)(int levels); | |
| 117 using IsWithinBoundsFn = bool (TriangularSequence::*)(); | |
| 118 | |
| 119 void Init(Type type); | |
| 120 void Reset(); | |
| 121 | |
| 122 // Interval inflating functions for different TriangularSequence types. | |
| 123 void InflateForward(int levels); | |
| 124 void InflateBackward(int levels); | |
| 125 void InflateDiagonalForward(int levels); | |
| 126 void InflateDiagonalBackward(int levels); | |
| 127 | |
| 128 // Functions for checking the bounds for different TriangularSequence types. | |
| 129 bool IsWithinBoundsForward(); | |
| 130 bool IsWithinBoundsBackward(); | |
| 131 bool IsWithinBoundsDiagonal(); | |
| 132 | |
| 133 std::string name_; | |
| 134 Type type_; | |
| 135 Interval interval_; | |
| 136 Interval interval_inflate_limit_; | |
| 137 Interval initial_interval_; | |
| 138 int levels_; | |
| 139 int levels_traversed_; | |
| 140 int levels_limit_; | |
| 141 bool reverse_; | |
| 142 bool within_bounds_; | |
| 143 int current_sequence_number_; | |
| 144 int step_; | |
| 145 | |
| 146 InflateFn inflate_; | |
| 147 IsWithinBoundsFn is_within_bounds_; | |
| 148 }; | |
| 149 | |
| 150 // This class implements the 2D sequence which uses two triangular sequences, | |
| 151 // one for traversing the actual sequence and other for computing the number of | |
| 152 // levels for the traversal sequence. | |
| 153 // | |
| 154 // LevelDistance means each level has some length value associated with it. The | |
| 155 // distance is distance from the viewport or rect of interest. If there are 5 | |
| 156 // levels and distance is 10, then the levels would have distances as given | |
| 157 // below. 0, 10, 20, 30, 40. The first level starts with 0, so as to represent | |
| 158 // the minimum distance for that level. The distances are stored in sorted | |
| 159 // order in the vector, so that distance at front is minimum and distance at | |
| 160 // back is maximum. The layout of the level distance vector for the example | |
| 161 // would be (0, 0), (1, 10), (2, 20), (3, 30), (4, 40). | |
| 162 // | |
| 163 // e.g. If traversal sequence is [3, 4], number of levels is 3 and distance is | |
| 164 // 10, then layout of the level distance sequence would be as given below. | |
| 165 // | |
| 166 // x 0 1 2 3 4 5 6 7 | |
| 167 // y.---------------- | |
| 168 // 0| . . . 3 4 . . . (level 1, distance 0) | |
| 169 // 1| . . 2 3 4 5 . . (level 2, distance 10) | |
| 170 // 2| . 1 2 3 4 5 6 . (level 3, distance 20) | |
| 171 // 3| . . . . . . . . | |
| 172 // 4| . . . . . . . . | |
| 173 // | |
| 174 // When the above sequence is iterated then the indices output would be as given | |
| 175 // below. | |
| 176 // (3, 0), (4, 0) (level 1) | |
| 177 // (2, 1), (3, 1), (4, 1), (5, 1), (level 2) | |
| 178 // (1, 2), (2, 2), (3, 2), (4, 2), (5, 2), (6, 2) (level 3) | |
| 179 // At each level change, this sequence conveys that level has changed. | |
| 180 class CC_EXPORT LevelDistanceSequence { | |
| 181 public: | |
| 182 typedef std::list<LevelDistanceSequence> List; | |
| 183 typedef List::iterator Iterator; | |
| 184 typedef List::reverse_iterator ReverseIterator; | |
| 185 | |
| 186 LevelDistanceSequence(); | |
| 187 // If |reverse| is true, then |traversal_sequence| is iterated from the | |
| 188 // interval at farthest level to the initial interval. If |swapped| is false | |
| 189 // then the sequence numbers in |traversal_sequence| represent the x index and | |
| 190 // sequence numbers in |level_sequence| represent the y index, otherwise vice | |
| 191 // versa. | |
| 192 LevelDistanceSequence(TriangularSequence&& traversal_sequence, | |
| 193 TriangularSequence&& level_sequence, | |
| 194 bool swapped, | |
| 195 int levels_to_skip, | |
| 196 int levels_delta, | |
| 197 int distance, | |
| 198 bool reverse); | |
| 199 LevelDistanceSequence(const LevelDistanceSequence& other); | |
| 200 LevelDistanceSequence(LevelDistanceSequence&& other); | |
| 201 ~LevelDistanceSequence(); | |
| 202 | |
| 203 LevelDistanceSequence& operator=(const LevelDistanceSequence& other); | |
| 204 LevelDistanceSequence& operator=(LevelDistanceSequence&& other); | |
| 205 | |
| 206 // Return true if this sequence is valid or not. | |
| 207 bool IsValid() const { return !level_distances_.empty(); } | |
| 208 | |
| 209 // Gets current indices. | |
| 210 int GetCurrentIndexX() const; | |
| 211 int GetCurrentIndexY() const; | |
| 212 | |
| 213 // Get minimum/maximum distance. | |
| 214 int GetMinimumDistance() const; | |
| 215 int GetMaximumDistance() const; | |
| 216 | |
| 217 // Advances or reverse-advances the |traversal_sequence|. When the interval is | |
| 218 // traversed fully, then this function return false for indicating the current | |
| 219 // level in |traversal_sequence| has been finished. | |
| 220 bool Advance(); | |
| 221 bool ReverseAdvance(); | |
| 222 | |
| 223 private: | |
| 224 struct LevelDistance { | |
| 225 LevelDistance(int level, int distance) : level(level), distance(distance) {} | |
| 226 | |
| 227 int level; | |
| 228 int distance; | |
| 229 }; | |
| 230 | |
| 231 void Reset(); | |
| 232 | |
| 233 TriangularSequence traversal_sequence_; | |
| 234 bool swapped_; | |
| 235 bool reverse_; | |
| 236 int current_sequence_index_; | |
| 237 int current_level_index_; | |
| 238 std::vector<LevelDistance> level_distances_; | |
| 239 }; | |
| 240 | |
| 241 // The pyramid sequence is list of 8 level distance sequences, one for each of | |
| 242 // the directions considered counter-clockwise or clockwise. The actual order | |
| 243 // of level distance sequences is computed by the direction in which coverage is | |
| 244 // required. (See GetCoverageDirectionSequenceForDirections() for more details.) | |
| 245 // The ideal pyramid sequence is as given below where it has all 8 directions. | |
| 246 // | |
| 247 // 2 T T T T T 1 | |
| 248 // L 2 T T T 1 R | |
| 249 // L L 2 T 1 R R | |
| 250 // L L L * R R R | |
| 251 // L L 3 B 4 R R | |
| 252 // L 3 B B B 4 R | |
| 253 // 3 B B B B B 4 | |
| 254 // | |
| 255 // The different level distance sequences for the above pyramid sequence is | |
| 256 // shown below. | |
| 257 // | |
| 258 // (T = top) | |
| 259 // | | |
| 260 // (2 = top-left) T T T T T (1 = top-right) | |
| 261 // 2 T T T 1 | |
| 262 // L 2 T 1 R | |
| 263 // L L 2 1 R R | |
| 264 // (L = left) --> L L L * R R R <-- (R = right) | |
| 265 // L L 3 4 R R | |
| 266 // L 3 B 4 R | |
| 267 // 3 B B B 4 | |
| 268 // (3 = bottom-left) B B B B B (4 = bottom-right) | |
| 269 // | | |
| 270 // (B = bottom) | |
| 271 // | |
| 272 // This sequence iterates over all the underlined level distance sequences level | |
| 273 // by level in increasing or decreasing order of distances. The increasing order | |
| 274 // of distance is called as TopDownPyramidSequence, while the other is called as | |
| 275 // BottomUpPyramidSequence. The iteration sequence generated by top down pyramid | |
| 276 // sequence is as given below. (Iteration is considered counter-clockwise.) | |
| 277 // | |
| 278 // x 0 1 2 3 4 5 6 | |
| 279 // y.--------------------- | |
| 280 // 0| 36 35 34 33 32 31 30 | |
| 281 // 1| 37 16 15 14 13 12 29 | |
| 282 // 2| 38 17 4 3 2 11 28 | |
| 283 // 3| 39 18 5 * 1 10 27 | |
| 284 // 4| 40 19 6 7 8 9 26 | |
| 285 // 5| 41 20 21 22 23 24 25 | |
| 286 // 6| 42 43 44 45 46 47 48 | |
| 287 // | |
| 288 // The iteration sequence generated by bottom up pyramid sequence is as given | |
| 289 // below. (Iteration is considered clockwise.) | |
| 290 // | |
| 291 // x 0 1 2 3 4 5 6 | |
| 292 // y.---------------------- | |
| 293 // 0| 13 14 15 16 17 18 19 | |
| 294 // 1| 12 33 34 35 36 37 20 | |
| 295 // 2| 11 32 45 46 47 38 21 | |
| 296 // 3| 10 31 44 * 48 39 22 | |
| 297 // 4| 9 30 43 42 41 40 23 | |
| 298 // 5| 8 29 28 27 26 25 24 | |
| 299 // 6| 7 6 5 4 3 2 1 | |
| 300 class CC_EXPORT PyramidSequence { | |
| 301 public: | |
| 302 explicit PyramidSequence(bool reverse); | |
| 303 PyramidSequence(const PyramidSequence& other); | |
| 304 PyramidSequence(PyramidSequence&& other); | |
| 305 virtual ~PyramidSequence(); | |
| 306 | |
| 307 PyramidSequence& operator=(const PyramidSequence& other); | |
| 308 PyramidSequence& operator=(PyramidSequence&& other); | |
| 309 | |
| 310 virtual void Init(int around_left, | |
| 311 int around_right, | |
| 312 int around_top, | |
| 313 int around_bottom, | |
| 314 int consider_left, | |
| 315 int consider_right, | |
| 316 int consider_top, | |
| 317 int consider_bottom, | |
| 318 int ignore_left, | |
| 319 int ignore_right, | |
| 320 int ignore_top, | |
| 321 int ignore_bottom, | |
| 322 int width, | |
| 323 int height); | |
| 324 bool IsTraversed(); | |
| 325 | |
| 326 virtual void Advance() = 0; | |
| 327 | |
| 328 void UpdateCurrent(); | |
| 329 int GetCurrentIndexX() const { return index_x_; } | |
| 330 int GetCurrentIndexY() const { return index_y_; } | |
| 331 | |
| 332 protected: | |
| 333 virtual LevelDistanceSequence* GetNextLevelDistanceSequence() = 0; | |
| 334 | |
| 335 void EmplaceAt(int position, LevelDistanceSequence&& level_distance_sequence); | |
| 336 bool InConsiderRect() const; | |
| 337 bool InIgnoreRect() const; | |
| 338 void RemoveEmptyLevelDistanceSequences(); | |
| 339 | |
| 340 bool reverse_; | |
| 341 LevelDistanceSequence* current_level_distance_sequence_; | |
| 342 int consider_left_; | |
| 343 int consider_right_; | |
| 344 int consider_top_; | |
| 345 int consider_bottom_; | |
| 346 int ignore_left_; | |
| 347 int ignore_right_; | |
| 348 int ignore_top_; | |
| 349 int ignore_bottom_; | |
| 350 int index_x_; | |
| 351 int index_y_; | |
| 352 LevelDistanceSequence::List level_distance_sequences_; | |
| 353 }; | |
| 354 | |
| 355 class CC_EXPORT TopDownPyramidSequence : public PyramidSequence { | |
| 356 public: | |
| 357 TopDownPyramidSequence(); | |
| 358 TopDownPyramidSequence(const TopDownPyramidSequence& other); | |
| 359 TopDownPyramidSequence(TopDownPyramidSequence&& other); | |
| 360 ~TopDownPyramidSequence() override; | |
| 361 | |
| 362 TopDownPyramidSequence& operator=(const TopDownPyramidSequence& other); | |
| 363 TopDownPyramidSequence& operator=(TopDownPyramidSequence&& other); | |
| 364 | |
| 365 void Advance() override; | |
| 366 | |
| 367 private: | |
| 368 LevelDistanceSequence* GetNextLevelDistanceSequence() override; | |
| 369 }; | |
| 370 | |
| 371 class CC_EXPORT BottomUpPyramidSequence : public PyramidSequence { | |
| 372 public: | |
| 373 BottomUpPyramidSequence(); | |
| 374 BottomUpPyramidSequence(const BottomUpPyramidSequence& other); | |
| 375 BottomUpPyramidSequence(BottomUpPyramidSequence&& other); | |
| 376 ~BottomUpPyramidSequence() override; | |
| 377 | |
| 378 BottomUpPyramidSequence& operator=(const BottomUpPyramidSequence& other); | |
| 379 BottomUpPyramidSequence& operator=(BottomUpPyramidSequence&& other); | |
| 380 | |
| 381 void Advance() override; | |
| 382 | |
| 383 private: | |
| 384 LevelDistanceSequence* GetNextLevelDistanceSequence() override; | |
| 385 }; | |
| 386 | |
| 387 } // namespace cc | |
| 388 | |
| 389 #endif // CC_BASE_PYRAMID_SEQUENCE_H_ | |
| OLD | NEW |