Line data Source code
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 0 : 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 : */
43 0 : 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:
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 : */
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:
82 0 : virtual void incPtr(void*) {}
83 0 : 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 0 : template <typename T> class SkTPtrSet : public SkPtrSet {
107 : public:
108 0 : uint32_t find(T ptr) {
109 0 : return this->INHERITED::find((void*)ptr);
110 : }
111 0 : uint32_t add(T ptr) {
112 0 : return this->INHERITED::add((void*)ptr);
113 : }
114 :
115 0 : void copyToArray(T* array) const {
116 0 : this->INHERITED::copyToArray((void**)array);
117 0 : }
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 0 : 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 0 : 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 0 : 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
|