blob: 00e75b433f3e47dcd771254a699807732ce431d2 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@android.com8a1c16f2008-12-17 15:59:43 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2008 The Android Open Source Project
reed@android.com8a1c16f2008-12-17 15:59:43 +00004 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00005 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@android.com8a1c16f2008-12-17 15:59:43 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
mike@reedtribe.orge9e08cc2011-04-29 01:44:52 +000010#ifndef SkPtrSet_DEFINED
11#define SkPtrSet_DEFINED
reed@android.com8a1c16f2008-12-17 15:59:43 +000012
13#include "SkRefCnt.h"
mike@reedtribe.org227b5162012-08-12 19:25:08 +000014#include "SkFlattenable.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000015#include "SkTDArray.h"
16
mike@reedtribe.orge8f754a2011-04-29 01:02:43 +000017/**
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 */
mike@reedtribe.orge9e08cc2011-04-29 01:44:52 +000023class SkPtrSet : public SkRefCnt {
reed@android.com8a1c16f2008-12-17 15:59:43 +000024public:
robertphillips@google.com15e9d3e2012-06-21 20:25:03 +000025 SK_DECLARE_INST_COUNT(SkPtrSet)
26
mike@reedtribe.orge8f754a2011-04-29 01:02:43 +000027 /**
reed@google.com8d90eeb2011-05-04 18:03:00 +000028 * 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 /**
mike@reedtribe.orge8f754a2011-04-29 01:02:43 +000034 * 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 *
mike@reedtribe.orge9e08cc2011-04-29 01:44:52 +000037 * If the ptr is NULL, it is not added, and 0 is returned.
mike@reedtribe.orge8f754a2011-04-29 01:02:43 +000038 */
mike@reedtribe.orge9e08cc2011-04-29 01:44:52 +000039 uint32_t add(void*);
rmistry@google.comfbfcd562012-08-23 18:09:54 +000040
mike@reedtribe.orge8f754a2011-04-29 01:02:43 +000041 /**
42 * Return the number of (non-null) ptrs in the set.
43 */
reed@android.com8a1c16f2008-12-17 15:59:43 +000044 int count() const { return fList.count(); }
mike@reedtribe.orge8f754a2011-04-29 01:02:43 +000045
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 */
mike@reedtribe.orge9e08cc2011-04-29 01:44:52 +000053 void copyToArray(void* array[]) const;
reed@android.com8a1c16f2008-12-17 15:59:43 +000054
mike@reedtribe.orge8f754a2011-04-29 01:02:43 +000055 /**
56 * Call decPtr() on each ptr in the set, and the reset the size of the set
57 * to 0.
58 */
reed@android.com8a1c16f2008-12-17 15:59:43 +000059 void reset();
60
61protected:
62 virtual void incPtr(void* ptr) {}
63 virtual void decPtr(void* ptr) {}
64
65private:
66 struct Pair {
mike@reedtribe.orge8f754a2011-04-29 01:02:43 +000067 void* fPtr; // never NULL
68 uint32_t fIndex; // 1...N
reed@android.com8a1c16f2008-12-17 15:59:43 +000069 };
mike@reedtribe.orge8f754a2011-04-29 01:02:43 +000070
71 // we store the ptrs in sorted-order (using Cmp) so that we can efficiently
mike@reedtribe.orge9e08cc2011-04-29 01:44:52 +000072 // detect duplicates when add() is called. Hence we need to store the
mike@reedtribe.orge8f754a2011-04-29 01:02:43 +000073 // ptr and its ID/fIndex explicitly, since the ptr's position in the array
74 // is not related to its "index".
reed@android.com8a1c16f2008-12-17 15:59:43 +000075 SkTDArray<Pair> fList;
rmistry@google.comfbfcd562012-08-23 18:09:54 +000076
bsalomon@google.comc9677952012-04-10 21:03:23 +000077 static int Cmp(const Pair* a, const Pair* b);
rmistry@google.comfbfcd562012-08-23 18:09:54 +000078
reed@android.com8a1c16f2008-12-17 15:59:43 +000079 typedef SkRefCnt INHERITED;
80};
81
mike@reedtribe.orge9e08cc2011-04-29 01:44:52 +000082/**
83 * Templated wrapper for SkPtrSet, just meant to automate typecasting
84 * parameters to and from void* (which the base class expects).
85 */
86template <typename T> class SkTPtrSet : public SkPtrSet {
87public:
reed@google.com6bac9472011-06-21 19:24:00 +000088 uint32_t find(T ptr) {
89 return this->INHERITED::find((void*)ptr);
90 }
mike@reedtribe.orge9e08cc2011-04-29 01:44:52 +000091 uint32_t add(T ptr) {
92 return this->INHERITED::add((void*)ptr);
93 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +000094
mike@reedtribe.orge9e08cc2011-04-29 01:44:52 +000095 void copyToArray(T* array) const {
96 this->INHERITED::copyToArray((void**)array);
97 }
98
99private:
100 typedef SkPtrSet INHERITED;
101};
102
mike@reedtribe.org227b5162012-08-12 19:25:08 +0000103/**
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 */
108class SkRefCntSet : public SkTPtrSet<SkRefCnt*> {
109public:
110 virtual ~SkRefCntSet();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000111
mike@reedtribe.org227b5162012-08-12 19:25:08 +0000112protected:
113 // overrides
114 virtual void incPtr(void*);
115 virtual void decPtr(void*);
116};
117
118class 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 */
124class SkNamedFactorySet : public SkRefCnt {
125public:
robertphillips@google.coma22e2112012-08-16 14:58:06 +0000126 SK_DECLARE_INST_COUNT(SkNamedFactorySet)
127
mike@reedtribe.org227b5162012-08-12 19:25:08 +0000128 SkNamedFactorySet();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000129
mike@reedtribe.org227b5162012-08-12 19:25:08 +0000130 /**
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);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000136
mike@reedtribe.org227b5162012-08-12 19:25:08 +0000137 /**
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();
143private:
144 int fNextAddedFactory;
145 SkFactorySet fFactorySet;
146 SkTDArray<const char*> fNames;
robertphillips@google.coma22e2112012-08-16 14:58:06 +0000147
148 typedef SkRefCnt INHERITED;
mike@reedtribe.org227b5162012-08-12 19:25:08 +0000149};
150
reed@android.com8a1c16f2008-12-17 15:59:43 +0000151#endif