| 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 <memory> | 
 |    9 #include <vector> | 
 |   10  | 
 |   11 #include "base/logging.h" | 
 |   12 #include "base/macros.h" | 
 |   13 #include "cc/base/cc_export.h" | 
 |   14 #include "cc/base/index_rect.h" | 
 |   15  | 
 |   16 namespace cc { | 
 |   17  | 
 |   18 // The pyramid sequence covers following 4 directions while iterating, where R | 
 |   19 // is right, T is top, L is left and B is bottom. | 
 |   20 //       T | 
 |   21 //    L  *  R | 
 |   22 //       B | 
 |   23 enum class CoverageDirection : int { | 
 |   24   NONE = -1, | 
 |   25   RIGHT = 0, | 
 |   26   TOP, | 
 |   27   LEFT, | 
 |   28   BOTTOM, | 
 |   29   SIZE | 
 |   30 }; | 
 |   31  | 
 |   32 namespace internal { | 
 |   33  | 
 |   34 // This class provides iterating mechanism for numbers between defined bounds. | 
 |   35 // e.g. For interval having bounds 3 as start and 6 as end, represented as | 
 |   36 // [3, 6], the interval returns 3, 4, 5, 6 sequence for Iterator traversal and | 
 |   37 // returns 6, 5, 4, 3 for ReverseIterator traversal. | 
 |   38 // | 
 |   39 //   start        end | 
 |   40 //     |           | | 
 |   41 //     V           V | 
 |   42 //   ┌───┬───┬───┬───┐ | 
 |   43 //   │ 3 │ 4 │ 5 │ 6 │ | 
 |   44 //   └───┴───┴───┴───┘ | 
 |   45 class CC_EXPORT Interval { | 
 |   46  public: | 
 |   47   class Iterator; | 
 |   48   class ReverseIterator; | 
 |   49  | 
 |   50   Interval() : empty_(true) {} | 
 |   51   Interval(int start, int end) : empty_(false), start_(start), end_(end) {} | 
 |   52  | 
 |   53   Iterator* Begin(); | 
 |   54   ReverseIterator* ReverseBegin(); | 
 |   55  | 
 |   56   // Return the bounds of the interval. | 
 |   57   int start() const { return start_; } | 
 |   58   int end() const { return end_; } | 
 |   59  | 
 |   60   // Returns true if interval is empty. Empty interval does not return any | 
 |   61   // index on traversing. | 
 |   62   bool IsEmpty() const { return empty_; } | 
 |   63  | 
 |   64   // Returns the distance between |start_| and |end_| which includes both | 
 |   65   // |start_| and |end_|. | 
 |   66   int GetSpan() const; | 
 |   67  | 
 |   68   // Return clamped indices for the given indices. | 
 |   69   int GetForwardClampedIndex(int index) const; | 
 |   70   int GetBackwardClampedIndex(int index) const; | 
 |   71  | 
 |   72   // Clamp this interval to the given interval. For these functions, interval | 
 |   73   // and other interval to which this interval is to be clammped should be in | 
 |   74   // the same direction, i.e. both intervals should have either | 
 |   75   // |start_| <= |end_| or |start_| >= |end_|. | 
 |   76   void ForwardClampTo(const Interval* other); | 
 |   77   void BackwardClampTo(const Interval* other); | 
 |   78  | 
 |   79   // Return the inflated intervals for the given |level|. | 
 |   80   void ForwardInflate(int level, Interval* output) const; | 
 |   81   void BackwardInflate(int level, Interval* output) const; | 
 |   82  | 
 |   83   // Returns true if interval contains the given index. | 
 |   84   bool Contains(int index) const; | 
 |   85  | 
 |   86   // For these functions, interval and other interval to which first one is to | 
 |   87   // be intersected should be in the same direction, i.e. both intervals should | 
 |   88   // have |start_| <= |end_| or |start_| >= |end_|. | 
 |   89   bool Intersects(const Interval* interval) const; | 
 |   90   void Intersect(const Interval* interval); | 
 |   91  | 
 |   92   // Iterators. | 
 |   93   class IteratorBase { | 
 |   94    public: | 
 |   95     operator bool() const { return within_bounds_; } | 
 |   96     IteratorBase& operator++(); | 
 |   97     int index() { return current_index_; } | 
 |   98  | 
 |   99    protected: | 
 |  100     explicit IteratorBase(Interval* interval); | 
 |  101  | 
 |  102     virtual bool IsWithinBounds() = 0; | 
 |  103  | 
 |  104     Interval* interval_; | 
 |  105     bool within_bounds_; | 
 |  106     int step_; | 
 |  107     int current_index_; | 
 |  108  | 
 |  109    private: | 
 |  110     DISALLOW_COPY_AND_ASSIGN(IteratorBase); | 
 |  111   }; | 
 |  112  | 
 |  113   class Iterator : public IteratorBase { | 
 |  114    private: | 
 |  115     explicit Iterator(Interval* interval); | 
 |  116  | 
 |  117     bool IsWithinBounds() override; | 
 |  118  | 
 |  119     friend class Interval; | 
 |  120  | 
 |  121     DISALLOW_COPY_AND_ASSIGN(Iterator); | 
 |  122   }; | 
 |  123  | 
 |  124   class ReverseIterator : public IteratorBase { | 
 |  125    private: | 
 |  126     explicit ReverseIterator(Interval* interval); | 
 |  127  | 
 |  128     bool IsWithinBounds() override; | 
 |  129  | 
 |  130     friend class Interval; | 
 |  131  | 
 |  132     DISALLOW_COPY_AND_ASSIGN(ReverseIterator); | 
 |  133   }; | 
 |  134  | 
 |  135  private: | 
 |  136   bool empty_; | 
 |  137   int start_; | 
 |  138   int end_; | 
 |  139 }; | 
 |  140  | 
 |  141 // This class provides affinity based interating mechanism for the given | 
 |  142 // |interval| [start, end] with functionality of inflating the |interval|. | 
 |  143 // The interval inflation means expanding the start and end by n steps forward | 
 |  144 // or backward, based on |forward_direction| argument provided. Suppose the | 
 |  145 // LinearSequence has interval [3, 3] i.e. start = 3 and end = 3, the interval | 
 |  146 // inflated by 1 step in forward direction would be [2, 4] and that of in | 
 |  147 // backward direction would be [4, 2]. | 
 |  148 // The affinity based traversing means portion of |interval| that intersects | 
 |  149 // with |affinity_interval| is traversed before remaining two portions of | 
 |  150 // |interval|. Internally the |interval| is split up into three sub-intervals | 
 |  151 // before traversing as |affinity_sub_interval_|, |before_sub_interval_| and | 
 |  152 // |after_sub_interval_|. These sub-intervals are traversed instead of directly | 
 |  153 // traversing |interval|. First |affinity_sub_interval_| is traversed fully, | 
 |  154 // then remaining two sub-intervals are traversed in alternative fashion. | 
 |  155 // | 
 |  156 // e.g. Suppose LinearSequence has interval [0, 9] and affinity interval | 
 |  157 // [4, 6], then the interval is splitted into three sub-intervals viz. [4, 6], | 
 |  158 // [3, 0], [7, 9]. | 
 |  159 // | 
 |  160 //               affinity_sub_interval | 
 |  161 //                   ┌─────^─────┐ | 
 |  162 //   ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ | 
 |  163 //   │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ | 
 |  164 //   └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ | 
 |  165 //   └───────v───────┘           └─────v─────┘ | 
 |  166 //  before_sub_interval        after_sub_interval | 
 |  167 // | 
 |  168 // On traversal, Iterator returns the sequence as 4, 5, 6, 3, 7, 2, 8, 1, 9, 0 | 
 |  169 // and RerverseIterator returns the sequence as 0, 9, 1, 8, 2, 7, 3, 6, 5, 4. | 
 |  170 class CC_EXPORT LinearSequence { | 
 |  171  public: | 
 |  172   class Iterator; | 
 |  173   class ReverseIterator; | 
 |  174  | 
 |  175   // The |interval| is used for actual traversal. The |affinity_interval| is | 
 |  176   // used for defining affinity in the |interval|. While traversing portion of | 
 |  177   // |interval| which intersects |affinity_interval| is traversed before | 
 |  178   // remaining portions of the interval. The |inflate_limit| is used to clamp | 
 |  179   // the |interval|, when it is inflated to any given |level|. | 
 |  180   LinearSequence(bool forward_direction, | 
 |  181                  std::unique_ptr<Interval> interval, | 
 |  182                  std::unique_ptr<Interval> affinity_interval, | 
 |  183                  std::unique_ptr<Interval> inflate_limit); | 
 |  184   ~LinearSequence(); | 
 |  185  | 
 |  186   Iterator* Begin(); | 
 |  187   ReverseIterator* ReverseBegin(); | 
 |  188  | 
 |  189   // This function inflates the original |interval| to the given |level|, | 
 |  190   // where level >= 0. | 
 |  191   void InflateToLevel(int level); | 
 |  192  | 
 |  193   // Iterators. | 
 |  194   class IteratorBase { | 
 |  195    public: | 
 |  196     ~IteratorBase(); | 
 |  197  | 
 |  198     operator bool() const { return within_bounds_; } | 
 |  199     IteratorBase& operator++(); | 
 |  200     int index() { return current_index_; } | 
 |  201  | 
 |  202    protected: | 
 |  203     enum class SubIntervalIteratorType : unsigned int { | 
 |  204       AFFINITY, | 
 |  205       BEFORE, | 
 |  206       AFTER | 
 |  207     }; | 
 |  208  | 
 |  209     explicit IteratorBase(LinearSequence* level_sequence); | 
 |  210  | 
 |  211     bool IsWithinBounds(); | 
 |  212     virtual SubIntervalIteratorType GetCurrentSubIntervalIteratorType() = 0; | 
 |  213  | 
 |  214     LinearSequence* level_sequence_; | 
 |  215     bool within_bounds_; | 
 |  216     int current_index_; | 
 |  217     std::unique_ptr<Interval::IteratorBase> sub_interval_iterators_[3]; | 
 |  218     SubIntervalIteratorType current_sub_interval_iterator_; | 
 |  219  | 
 |  220    private: | 
 |  221     DISALLOW_COPY_AND_ASSIGN(IteratorBase); | 
 |  222   }; | 
 |  223  | 
 |  224   class Iterator : public IteratorBase { | 
 |  225    public: | 
 |  226     ~Iterator(); | 
 |  227  | 
 |  228    private: | 
 |  229     explicit Iterator(LinearSequence* level_sequence); | 
 |  230  | 
 |  231     SubIntervalIteratorType GetCurrentSubIntervalIteratorType() override; | 
 |  232  | 
 |  233     bool before_first_; | 
 |  234  | 
 |  235     friend class LinearSequence; | 
 |  236  | 
 |  237     DISALLOW_COPY_AND_ASSIGN(Iterator); | 
 |  238   }; | 
 |  239  | 
 |  240   class ReverseIterator : public IteratorBase { | 
 |  241    public: | 
 |  242     ~ReverseIterator(); | 
 |  243  | 
 |  244    private: | 
 |  245     explicit ReverseIterator(LinearSequence* level_sequence); | 
 |  246  | 
 |  247     SubIntervalIteratorType GetCurrentSubIntervalIteratorType() override; | 
 |  248  | 
 |  249     bool after_first_; | 
 |  250     int before_sub_interval_span_; | 
 |  251     int after_sub_interval_span_; | 
 |  252  | 
 |  253     friend class LinearSequence; | 
 |  254  | 
 |  255     DISALLOW_COPY_AND_ASSIGN(ReverseIterator); | 
 |  256   }; | 
 |  257  | 
 |  258  private: | 
 |  259   void TrisectInterval(); | 
 |  260  | 
 |  261   bool forward_direction_; | 
 |  262   std::unique_ptr<Interval> interval_; | 
 |  263   std::unique_ptr<Interval> inflate_limit_; | 
 |  264   std::unique_ptr<Interval> affinity_interval_; | 
 |  265  | 
 |  266   std::unique_ptr<Interval> initial_interval_; | 
 |  267  | 
 |  268   // The |interval_| is split up into following sub-intervals such a way that | 
 |  269   // they are non-intersecting, adjacent and union of these three sub-intervals | 
 |  270   // is |interval_|. | 
 |  271   Interval affinity_sub_interval_; | 
 |  272   Interval before_sub_interval_; | 
 |  273   Interval after_sub_interval_; | 
 |  274  | 
 |  275   DISALLOW_COPY_AND_ASSIGN(LinearSequence); | 
 |  276 }; | 
 |  277  | 
 |  278 // This class implements the 2D sequence (x, y) which uses LinearSequence and | 
 |  279 // Interval to represent the co-ordinates. The linear sequence | 
 |  280 // |traversal_sequence| is used for traversing the actual sequence cross the | 
 |  281 // direction and |level_interval| is used for computing the number of levels in | 
 |  282 // the |traversal_sequence|. The interval in |traversal_sequence| can be | 
 |  283 // inflated max to the levels given by |level_interval|. | 
 |  284 // This class uses LevelDistance structure to represent the distance associated | 
 |  285 // with the level. The first level has distance 0, to represent the minimum | 
 |  286 // distance for the origin level, and increments by the step of |distance| | 
 |  287 // given in LevelDistance for every level. Suppose there are 5 levels and | 
 |  288 // distance is 10, then the levels would have distances as 0, 10, 20, 30, 40. | 
 |  289 // The distances are stored in the sorted order in vector, so that the distance | 
 |  290 // at front is minimum, while the distance at back is maximum. The layout of | 
 |  291 // the level distance vector for the example would be (0, 0), (1, 10), (2, 20), | 
 |  292 // (3, 30), (4, 40). | 
 |  293 // | 
 |  294 // e.g. If traversal sequence has interval [3, 4], number of levels is 3 and | 
 |  295 // distance is 10, then the Iterator would give following data on traversal. | 
 |  296 // | 
 |  297 //   traversal_sequence   level_index | 
 |  298 //         [3, 4]              0 | 
 |  299 //         [2, 5]              1 | 
 |  300 //         [1, 6]              2 | 
 |  301 // | 
 |  302 // The order of iteration for ReverseIterator would be as given below. | 
 |  303 // | 
 |  304 //   traversal_sequence   level index | 
 |  305 //         [1, 6]              2 | 
 |  306 //         [2, 5]              1 | 
 |  307 //         [3, 4]              0 | 
 |  308 // | 
 |  309 // The indices (x, y) for the iterator are as given below. | 
 |  310 // | 
 |  311 // (3, 0), (4, 0)                                    (level 1) | 
 |  312 // (2, 1), (3, 1), (4, 1), (5, 1),                   (level 2) | 
 |  313 // (1, 2), (2, 2), (3, 2), (4, 2), (5, 2), (6, 2)    (level 3) | 
 |  314 // | 
 |  315 // In a way the original interval in |traversal_sequence| and inflated | 
 |  316 // intervals form triangular geometry in co-ordinate space as given below, | 
 |  317 // hence the name TriangularSequence. | 
 |  318 // | 
 |  319 //   x  0   1   2   3   4   5   6 | 
 |  320 //  y ┌───┬───┬───┬───┬───┬───┬───┐ | 
 |  321 //  0 │   │   │   │ 3 │ 4 │   │   │  (level 1, distance 0) | 
 |  322 //    ├───┼───┼───┼───┼───┼───┼───┤ | 
 |  323 //  1 │   │   │ 2 │ 3 │ 4 │ 5 │   │  (level 2, distance 10) | 
 |  324 //    ├───┼───┼───┼───┼───┼───┼───┤ | 
 |  325 //  2 │   │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │  (level 3, distance 20) | 
 |  326 //    ├───┼───┼───┼───┼───┼───┼───┤ | 
 |  327 //  3 │   │   │   │   │   │   │   │ | 
 |  328 //    ├───┼───┼───┼───┼───┼───┼───┤ | 
 |  329 //  4 │   │   │   │   │   │   │   │ | 
 |  330 //    ├───┼───┼───┼───┼───┼───┼───┤ | 
 |  331 //  5 │   │   │   │   │   │   │   │ | 
 |  332 //    ├───┼───┼───┼───┼───┼───┼───┤ | 
 |  333 //  6 │   │   │   │   │   │   │   │ | 
 |  334 //    └───┴───┴───┴───┴───┴───┴───┘ | 
 |  335 class CC_EXPORT TriangularSequence { | 
 |  336  public: | 
 |  337   class Iterator; | 
 |  338   class ReverseIterator; | 
 |  339  | 
 |  340   // The |traversal_sequence| defines the sequence for traversal and | 
 |  341   // |level_interval| defines the number of levels for |traversal_sequence|. | 
 |  342   // If |should_swap_index_representation| is false, then the indices in | 
 |  343   // |traversal_sequence| represent the x indices and level indices in | 
 |  344   // |level_interval| represent the y indices, otherwise vice-versa. The | 
 |  345   // |levels_to_skip| defines the number of levels which should be skipped to | 
 |  346   // avoid unnecessary traversing. Check PyramidSequence::PyramidSequence() for | 
 |  347   // more details on level skipping. The |distance| defines the length for the | 
 |  348   // index. | 
 |  349   TriangularSequence(CoverageDirection coverage_direction, | 
 |  350                      std::unique_ptr<LinearSequence> traversal_sequence, | 
 |  351                      std::unique_ptr<Interval> level_interval, | 
 |  352                      bool should_swap_index_representation, | 
 |  353                      int levels_to_skip, | 
 |  354                      int distance); | 
 |  355   ~TriangularSequence(); | 
 |  356  | 
 |  357   Iterator* Begin(); | 
 |  358   ReverseIterator* ReverseBegin(); | 
 |  359  | 
 |  360   CoverageDirection coverage_direction() const { return coverage_direction_; } | 
 |  361  | 
 |  362   struct LevelDistance { | 
 |  363     LevelDistance(int interval_level, int level_index, int distance) | 
 |  364         : interval_level(interval_level), | 
 |  365           level_index(level_index), | 
 |  366           distance(distance) {} | 
 |  367  | 
 |  368     int interval_level; | 
 |  369     int level_index; | 
 |  370     int distance; | 
 |  371   }; | 
 |  372  | 
 |  373   class IteratorBase { | 
 |  374    public: | 
 |  375     IteratorBase(); | 
 |  376     ~IteratorBase(); | 
 |  377  | 
 |  378     operator bool() const { return !level_distances_.empty(); } | 
 |  379     IteratorBase& operator++(); | 
 |  380     LinearSequence* traversal_sequence() { | 
 |  381       DCHECK(*this); | 
 |  382       return traversal_sequence_; | 
 |  383     } | 
 |  384     int level_index() { | 
 |  385       DCHECK(*this); | 
 |  386       return current_level_index_; | 
 |  387     } | 
 |  388  | 
 |  389     bool is_index_representation_swapped() const { | 
 |  390       return should_swap_index_representation_; | 
 |  391     } | 
 |  392  | 
 |  393     virtual int GetNextDistance() const = 0; | 
 |  394  | 
 |  395    protected: | 
 |  396     explicit IteratorBase(TriangularSequence* triangular_sequence); | 
 |  397  | 
 |  398     virtual void Advance() = 0; | 
 |  399     virtual void UpdateCurrent() = 0; | 
 |  400  | 
 |  401     LinearSequence* traversal_sequence_; | 
 |  402     bool should_swap_index_representation_; | 
 |  403     std::vector<LevelDistance> level_distances_; | 
 |  404     int current_level_index_; | 
 |  405  | 
 |  406    private: | 
 |  407     DISALLOW_COPY_AND_ASSIGN(IteratorBase); | 
 |  408   }; | 
 |  409  | 
 |  410   class Iterator : public IteratorBase { | 
 |  411    public: | 
 |  412     Iterator(); | 
 |  413  | 
 |  414     // Returns next minimum distance. | 
 |  415     int GetNextDistance() const override; | 
 |  416  | 
 |  417    private: | 
 |  418     explicit Iterator(TriangularSequence* triangular_sequence); | 
 |  419  | 
 |  420     void Advance() override; | 
 |  421     void UpdateCurrent() override; | 
 |  422  | 
 |  423     friend class TriangularSequence; | 
 |  424  | 
 |  425     DISALLOW_COPY_AND_ASSIGN(Iterator); | 
 |  426   }; | 
 |  427  | 
 |  428   class ReverseIterator : public IteratorBase { | 
 |  429    public: | 
 |  430     ReverseIterator(); | 
 |  431  | 
 |  432     // Returns next maximum distance. | 
 |  433     int GetNextDistance() const override; | 
 |  434  | 
 |  435    private: | 
 |  436     explicit ReverseIterator(TriangularSequence* triangular_sequence); | 
 |  437  | 
 |  438     void Advance() override; | 
 |  439     void UpdateCurrent() override; | 
 |  440  | 
 |  441     friend class TriangularSequence; | 
 |  442  | 
 |  443     DISALLOW_COPY_AND_ASSIGN(ReverseIterator); | 
 |  444   }; | 
 |  445  | 
 |  446   typedef std::vector<std::unique_ptr<TriangularSequence>> Vector; | 
 |  447   typedef std::vector<TriangularSequence::IteratorBase> IteratorVector; | 
 |  448  | 
 |  449  private: | 
 |  450   CoverageDirection coverage_direction_; | 
 |  451   std::unique_ptr<LinearSequence> traversal_sequence_; | 
 |  452   std::unique_ptr<Interval> level_interval_; | 
 |  453   bool should_swap_index_representation_; | 
 |  454   int levels_to_skip_; | 
 |  455   int distance_; | 
 |  456  | 
 |  457   DISALLOW_COPY_AND_ASSIGN(TriangularSequence); | 
 |  458 }; | 
 |  459  | 
 |  460 // The pyramid sequence consists of 4 triangular sequences, one for each of | 
 |  461 // the directions considered counter-clockwise or clockwise. The ideal pyramid | 
 |  462 // sequence is as given below where it has all triangular sequences in 4 | 
 |  463 // directions. | 
 |  464 // | 
 |  465 //                  ┌───┬───┬───┬───┬───┬───┬───┐ | 
 |  466 //                  │ L │ T │ T │ T │ T │ T │ R │ | 
 |  467 //                  ├───┼───┼───┼───┼───┼───┼───┤ | 
 |  468 //                  │ L │ L │ T │ T │ T │ R │ R │ | 
 |  469 //                  ├───┼───┼───┼───┼───┼───┼───┤ | 
 |  470 //                  │ L │ L │ L │ T │ R │ R │ R │ | 
 |  471 //                  ├───┼───┼───┼───┼───┼───┼───┤ | 
 |  472 //                  │ L │ L │ L │ * │ R │ R │ R │ | 
 |  473 //                  ├───┼───┼───┼───┼───┼───┼───┤ | 
 |  474 //                  │ L │ L │ L │ B │ R │ R │ R │ | 
 |  475 //                  ├───┼───┼───┼───┼───┼───┼───┤ | 
 |  476 //                  │ L │ L │ B │ B │ B │ R │ R │ | 
 |  477 //                  ├───┼───┼───┼───┼───┼───┼───┤ | 
 |  478 //                  │ L │ B │ B │ B │ B │ B │ R │ | 
 |  479 //                  └───┴───┴───┴───┴───┴───┴───┘ | 
 |  480 // | 
 |  481 // The triangular sequences for the above pyramid sequence are shown below. | 
 |  482 // * represents the center. | 
 |  483 // | 
 |  484 //                            (T = top) | 
 |  485 //                      ┌───┬───┬───┬───┬───┐ | 
 |  486 //                      │ T │ T │ T │ T │ T │ | 
 |  487 //              ┌───┐   └───┼───┼───┼───┼───┘   ┌───┐ | 
 |  488 //              │ L │       │ T │ T │ T │       │ R │ | 
 |  489 //              ├───┼───┐   └───┼───┼───┘   ┌───┼───┤ | 
 |  490 //              │ L │ L │       │ T │       │ R │ R │ | 
 |  491 //              ├───┼───┼───┐   └───┘   ┌───┼───┼───┤ | 
 |  492 //              │ L │ L │ L │           │ R │ R │ R │ | 
 |  493 //              ├───┼───┼───┤   ┌───┐   ├───┼───┼───┤ | 
 |  494 //  (L = left)  │ L │ L │ L │   │ * │   │ R │ R │ R │  (R = right) | 
 |  495 //              ├───┼───┼───┤   └───┘   ├───┼───┼───┤ | 
 |  496 //              │ L │ L │ L │           │ R │ R │ R │ | 
 |  497 //              ├───┼───┼───┘   ┌───┐   └───┼───┼───┤ | 
 |  498 //              │ L │ L │       │ B │       │ R │ R │ | 
 |  499 //              ├───┼───┘   ┌───┼───┼───┐   └───┼───┤ | 
 |  500 //              │ L │       │ B │ B │ B │       │ R │ | 
 |  501 //              └───┘   ┌───┼───┼───┼───┼───┐   └───┘ | 
 |  502 //                      │ B │ B │ B │ B │ B │ | 
 |  503 //                      └───┴───┴───┴───┴───┘ | 
 |  504 //                           (B = bottom) | 
 |  505 // | 
 |  506 // This sequence iterates over all the underlined triangular sequences level by | 
 |  507 // level in increasing or decreasing order of distances. The increasing order of | 
 |  508 // distances can be iterated using Iterator, while the decreasing order of | 
 |  509 // distances can be iterated using ReverseIterator. The default coverage for | 
 |  510 // internal triangular sequences is R, T, L, B forming spiral order. | 
 |  511 // The iteration sequence generated by Iterator is as given below. | 
 |  512 // (Iteration is considered counter-clockwise.) | 
 |  513 // | 
 |  514 //   x  0   1   2   3   4   5   6 | 
 |  515 //  y ┌───┬───┬───┬───┬───┬───┬───┐ | 
 |  516 //  0 │ 42│ 36│ 34│ 32│ 33│ 35│ 31│ | 
 |  517 //    ├───┼───┼───┼───┼───┼───┼───┤ | 
 |  518 //  1 │ 40│ 20│ 16│ 14│ 15│ 13│ 29│ | 
 |  519 //    ├───┼───┼───┼───┼───┼───┼───┤ | 
 |  520 //  2 │ 38│ 18│  6│  4│  3│ 11│ 27│ | 
 |  521 //    ├───┼───┼───┼───┼───┼───┼───┤ | 
 |  522 //  3 │ 37│ 17│  5│  *│  1│  9│ 25│ | 
 |  523 //    ├───┼───┼───┼───┼───┼───┼───┤ | 
 |  524 //  4 │ 39│ 19│  7│  8│  2│ 10│ 26│ | 
 |  525 //    ├───┼───┼───┼───┼───┼───┼───┤ | 
 |  526 //  5 │ 41│ 21│ 23│ 22│ 24│ 12│ 28│ | 
 |  527 //    ├───┼───┼───┼───┼───┼───┼───┤ | 
 |  528 //  6 │ 43│ 47│ 45│ 44│ 46│ 48│ 30│ | 
 |  529 //    └───┴───┴───┴───┴───┴───┴───┘ | 
 |  530 // | 
 |  531 // The iteration sequence generated by ReverseIterator is as given below. | 
 |  532 // (Iteration is considered clockwise.) | 
 |  533 // | 
 |  534 //   x  0   1   2   3   4   5   6 | 
 |  535 //  y ┌───┬───┬───┬───┬───┬───┬───┐ | 
 |  536 //  0 │  7│ 13│ 15│ 17│ 16│ 14│ 18│ | 
 |  537 //    ├───┼───┼───┼───┼───┼───┼───┤ | 
 |  538 //  1 │  9│ 29│ 33│ 35│ 34│ 36│ 20│ | 
 |  539 //    ├───┼───┼───┼───┼───┼───┼───┤ | 
 |  540 //  2 │ 11│ 31│ 43│ 45│ 46│ 38│ 22│ | 
 |  541 //    ├───┼───┼───┼───┼───┼───┼───┤ | 
 |  542 //  3 │ 12│ 32│ 44│  *│ 48│ 40│ 24│ | 
 |  543 //    ├───┼───┼───┼───┼───┼───┼───┤ | 
 |  544 //  4 │ 10│ 30│ 42│ 41│ 47│ 39│ 23│ | 
 |  545 //    ├───┼───┼───┼───┼───┼───┼───┤ | 
 |  546 //  5 │  8│ 28│ 26│ 27│ 25│ 37│ 21│ | 
 |  547 //    ├───┼───┼───┼───┼───┼───┼───┤ | 
 |  548 //  6 │  6│  2│  4│  5│  3│  1│ 19│ | 
 |  549 //    └───┴───┴───┴───┴───┴───┴───┘ | 
 |  550 class CC_EXPORT PyramidSequence { | 
 |  551  public: | 
 |  552   class Iterator; | 
 |  553   class ReverseIterator; | 
 |  554  | 
 |  555   // The |around_index_rect| is the index rect computed around some index rect, | 
 |  556   // called as center index rect. In the above example, center index rect is | 
 |  557   // (3, 3, 3, 3), so around index rect for it is (2, 4, 2, 4). | 
 |  558   // The |consider_index_rect| is used to limit the coverage and the | 
 |  559   // |ignore_index_rect| is used to ignore the indices from coverage. For above | 
 |  560   // example consider index rect is (0, 6, 0, 6) and ignore index rect is | 
 |  561   // (-1, -1, -1, -1). | 
 |  562   // The width and height specify the width and height of the single index. This | 
 |  563   // is used for traversing indices based on their distances from center index | 
 |  564   // rect. | 
 |  565   PyramidSequence(const IndexRect& around_index_rect, | 
 |  566                   const IndexRect& consider_index_rect, | 
 |  567                   const IndexRect& ignore_index_rect, | 
 |  568                   int width, | 
 |  569                   int height); | 
 |  570   ~PyramidSequence(); | 
 |  571  | 
 |  572   Iterator* Begin(); | 
 |  573   ReverseIterator* ReverseBegin(); | 
 |  574  | 
 |  575   class IteratorBase { | 
 |  576    public: | 
 |  577     IteratorBase(); | 
 |  578     ~IteratorBase(); | 
 |  579  | 
 |  580     operator bool() const; | 
 |  581     IteratorBase& operator++(); | 
 |  582     int index_x() const { return index_x_; } | 
 |  583     int index_y() const { return index_y_; } | 
 |  584  | 
 |  585    protected: | 
 |  586     explicit IteratorBase(const IndexRect& consider_index_rect, | 
 |  587                           const IndexRect& ignore_index_rect); | 
 |  588  | 
 |  589     virtual bool IsEmpty() const = 0; | 
 |  590     virtual void Advance() = 0; | 
 |  591     virtual void UpdateCurrent() = 0; | 
 |  592  | 
 |  593     IndexRect consider_index_rect_; | 
 |  594     IndexRect ignore_index_rect_; | 
 |  595     int index_x_; | 
 |  596     int index_y_; | 
 |  597  | 
 |  598     TriangularSequence::IteratorBase* current_triangular_sequence_it_; | 
 |  599  | 
 |  600    private: | 
 |  601     DISALLOW_COPY_AND_ASSIGN(IteratorBase); | 
 |  602   }; | 
 |  603  | 
 |  604   class Iterator : public IteratorBase { | 
 |  605    public: | 
 |  606     Iterator(); | 
 |  607     ~Iterator(); | 
 |  608  | 
 |  609    private: | 
 |  610     explicit Iterator(PyramidSequence* pyramid_sequence); | 
 |  611  | 
 |  612     bool IsEmpty() const override; | 
 |  613     void Advance() override; | 
 |  614     void UpdateCurrent() override; | 
 |  615  | 
 |  616     TriangularSequence::IteratorBase* GetNextTriangularSequenceIterator(); | 
 |  617  | 
 |  618     LinearSequence::Iterator* current_traversal_sequence_iterator_; | 
 |  619     std::vector<std::unique_ptr<TriangularSequence::Iterator>> | 
 |  620         triangular_sequence_iterators_; | 
 |  621  | 
 |  622     friend class PyramidSequence; | 
 |  623  | 
 |  624     DISALLOW_COPY_AND_ASSIGN(Iterator); | 
 |  625   }; | 
 |  626  | 
 |  627   class ReverseIterator : public IteratorBase { | 
 |  628    public: | 
 |  629     ReverseIterator(); | 
 |  630     ~ReverseIterator(); | 
 |  631  | 
 |  632    private: | 
 |  633     explicit ReverseIterator(PyramidSequence* pyramid_sequence); | 
 |  634  | 
 |  635     bool IsEmpty() const override; | 
 |  636     void Advance() override; | 
 |  637     void UpdateCurrent() override; | 
 |  638  | 
 |  639     TriangularSequence::IteratorBase* | 
 |  640     GetNextTriangularSequenceReverseIterator(); | 
 |  641  | 
 |  642     LinearSequence::ReverseIterator* | 
 |  643         current_traversal_sequence_reverse_iterator_; | 
 |  644     std::vector<std::unique_ptr<TriangularSequence::ReverseIterator>> | 
 |  645         triangular_sequence_reverse_iterators_; | 
 |  646  | 
 |  647     friend class PyramidSequence; | 
 |  648  | 
 |  649     DISALLOW_COPY_AND_ASSIGN(ReverseIterator); | 
 |  650   }; | 
 |  651  | 
 |  652  private: | 
 |  653   void EmplaceAt(int position, | 
 |  654                  std::unique_ptr<TriangularSequence> triangular_sequence); | 
 |  655  | 
 |  656   IndexRect consider_index_rect_; | 
 |  657   IndexRect ignore_index_rect_; | 
 |  658   TriangularSequence::Vector triangular_sequences_; | 
 |  659  | 
 |  660   DISALLOW_COPY_AND_ASSIGN(PyramidSequence); | 
 |  661 }; | 
 |  662  | 
 |  663 }  // namespace internal | 
 |  664  | 
 |  665 class PyramidSequence { | 
 |  666  public: | 
 |  667   PyramidSequence(); | 
 |  668   PyramidSequence(const IndexRect& around_index_rect, | 
 |  669                   const IndexRect& consider_index_rect, | 
 |  670                   const IndexRect& ignore_index_rect, | 
 |  671                   int width, | 
 |  672                   int height); | 
 |  673   PyramidSequence(const PyramidSequence& other); | 
 |  674   PyramidSequence(PyramidSequence&& other); | 
 |  675   ~PyramidSequence(); | 
 |  676  | 
 |  677   PyramidSequence& operator=(const PyramidSequence& other); | 
 |  678   PyramidSequence& operator=(PyramidSequence&& other); | 
 |  679  | 
 |  680   class Iterator { | 
 |  681    public: | 
 |  682     Iterator(); | 
 |  683     Iterator(const Iterator& other); | 
 |  684     Iterator(Iterator&& other); | 
 |  685     ~Iterator(); | 
 |  686  | 
 |  687     Iterator& operator=(const Iterator& other); | 
 |  688     Iterator& operator=(Iterator&& other); | 
 |  689  | 
 |  690     operator bool() const; | 
 |  691     Iterator& operator++(); | 
 |  692     int index_x() const; | 
 |  693     int index_y() const; | 
 |  694  | 
 |  695    public: | 
 |  696     explicit Iterator(internal::PyramidSequence::Iterator* ptr); | 
 |  697  | 
 |  698     std::shared_ptr<internal::PyramidSequence::Iterator> ptr_; | 
 |  699  | 
 |  700     friend class PyramidSequence; | 
 |  701   }; | 
 |  702  | 
 |  703   class ReverseIterator { | 
 |  704    public: | 
 |  705     ReverseIterator(); | 
 |  706     ReverseIterator(const ReverseIterator& other); | 
 |  707     ReverseIterator(ReverseIterator&& other); | 
 |  708     ~ReverseIterator(); | 
 |  709  | 
 |  710     ReverseIterator& operator=(const ReverseIterator& other); | 
 |  711     ReverseIterator& operator=(ReverseIterator&& other); | 
 |  712  | 
 |  713     operator bool() const; | 
 |  714     ReverseIterator& operator++(); | 
 |  715     int index_x() const; | 
 |  716     int index_y() const; | 
 |  717  | 
 |  718    private: | 
 |  719     explicit ReverseIterator(internal::PyramidSequence::ReverseIterator* ptr); | 
 |  720  | 
 |  721     std::shared_ptr<internal::PyramidSequence::ReverseIterator> ptr_; | 
 |  722  | 
 |  723     friend class PyramidSequence; | 
 |  724   }; | 
 |  725  | 
 |  726   Iterator Begin(); | 
 |  727   ReverseIterator ReverseBegin(); | 
 |  728  | 
 |  729  private: | 
 |  730   std::shared_ptr<internal::PyramidSequence> ptr_; | 
 |  731 }; | 
 |  732  | 
 |  733 }  // namespace cc | 
 |  734  | 
 |  735 #endif  // CC_BASE_PYRAMID_SEQUENCE_H_ | 
| OLD | NEW |