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