• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright 2008 The Android Open Source Project
3   *
4   * Use of this source code is governed by a BSD-style license that can be
5   * found in the LICENSE file.
6   */
7  
8  
9  #ifndef SkPtrSet_DEFINED
10  #define SkPtrSet_DEFINED
11  
12  #include "SkRefCnt.h"
13  #include "SkFlattenable.h"
14  #include "SkTDArray.h"
15  
16  /**
17   *  Maintains a set of ptrs, assigning each a unique ID [1...N]. Duplicate ptrs
18   *  return the same ID (since its a set). Subclasses can override inPtr()
19   *  and decPtr(). incPtr() is called each time a unique ptr is added ot the
20   *  set. decPtr() is called on each ptr when the set is destroyed or reset.
21   */
22  class SkPtrSet : public SkRefCnt {
23  public:
24  
25  
26      /**
27       *  Search for the specified ptr in the set. If it is found, return its
28       *  32bit ID [1..N], or if not found, return 0. Always returns 0 for nullptr.
29       */
30      uint32_t find(void*) const;
31  
32      /**
33       *  Add the specified ptr to the set, returning a unique 32bit ID for it
34       *  [1...N]. Duplicate ptrs will return the same ID.
35       *
36       *  If the ptr is nullptr, it is not added, and 0 is returned.
37       */
38      uint32_t add(void*);
39  
40      /**
41       *  Return the number of (non-null) ptrs in the set.
42       */
count()43      int count() const { return fList.count(); }
44  
45      /**
46       *  Copy the ptrs in the set into the specified array (allocated by the
47       *  caller). The ptrs are assgined to the array based on their corresponding
48       *  ID. e.g. array[ptr.ID - 1] = ptr.
49       *
50       *  incPtr() and decPtr() are not called during this operation.
51       */
52      void copyToArray(void* array[]) const;
53  
54      /**
55       *  Call decPtr() on each ptr in the set, and the reset the size of the set
56       *  to 0.
57       */
58      void reset();
59  
60      /**
61       * Set iterator.
62       */
63      class Iter {
64      public:
Iter(const SkPtrSet & set)65          Iter(const SkPtrSet& set)
66              : fSet(set)
67              , fIndex(0) {}
68  
69          /**
70           * Return the next ptr in the set or null if the end was reached.
71           */
next()72          void* next() {
73              return fIndex < fSet.fList.count() ? fSet.fList[fIndex++].fPtr : nullptr;
74          }
75  
76      private:
77          const SkPtrSet& fSet;
78          int             fIndex;
79      };
80  
81  protected:
incPtr(void *)82      virtual void incPtr(void*) {}
decPtr(void *)83      virtual void decPtr(void*) {}
84  
85  private:
86      struct Pair {
87          void*       fPtr;   // never nullptr
88          uint32_t    fIndex; // 1...N
89      };
90  
91      // we store the ptrs in sorted-order (using Cmp) so that we can efficiently
92      // detect duplicates when add() is called. Hence we need to store the
93      // ptr and its ID/fIndex explicitly, since the ptr's position in the array
94      // is not related to its "index".
95      SkTDArray<Pair>  fList;
96  
97      static bool Less(const Pair& a, const Pair& b);
98  
99      typedef SkRefCnt INHERITED;
100  };
101  
102  /**
103   *  Templated wrapper for SkPtrSet, just meant to automate typecasting
104   *  parameters to and from void* (which the base class expects).
105   */
106  template <typename T> class SkTPtrSet : public SkPtrSet {
107  public:
find(T ptr)108      uint32_t find(T ptr) {
109          return this->INHERITED::find((void*)ptr);
110      }
add(T ptr)111      uint32_t add(T ptr) {
112          return this->INHERITED::add((void*)ptr);
113      }
114  
copyToArray(T * array)115      void copyToArray(T* array) const {
116          this->INHERITED::copyToArray((void**)array);
117      }
118  
119  private:
120      typedef SkPtrSet INHERITED;
121  };
122  
123  /**
124   *  Subclass of SkTPtrSet specialed to call ref() and unref() when the
125   *  base class's incPtr() and decPtr() are called. This makes it a valid owner
126   *  of each ptr, which is released when the set is reset or destroyed.
127   */
128  class SkRefCntSet : public SkTPtrSet<SkRefCnt*> {
129  public:
130      virtual ~SkRefCntSet();
131  
132  protected:
133      // overrides
134      virtual void incPtr(void*);
135      virtual void decPtr(void*);
136  };
137  
138  class SkFactorySet : public SkTPtrSet<SkFlattenable::Factory> {};
139  
140  /**
141   * Similar to SkFactorySet, but only allows Factorys that have registered names.
142   * Also has a function to return the next added Factory's name.
143   */
144  class SkNamedFactorySet : public SkRefCnt {
145  public:
146  
147  
148      SkNamedFactorySet();
149  
150      /**
151       * Find the specified Factory in the set. If it is not already in the set,
152       * and has registered its name, add it to the set, and return its index.
153       * If the Factory has no registered name, return 0.
154       */
155      uint32_t find(SkFlattenable::Factory);
156  
157      /**
158       * If new Factorys have been added to the set, return the name of the first
159       * Factory added after the Factory name returned by the last call to this
160       * function.
161       */
162      const char* getNextAddedFactoryName();
163  private:
164      int                    fNextAddedFactory;
165      SkFactorySet           fFactorySet;
166      SkTDArray<const char*> fNames;
167  
168      typedef SkRefCnt INHERITED;
169  };
170  
171  #endif
172