1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2008 The Android Open Source Project
48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
10e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org#ifndef SkPtrSet_DEFINED
11e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org#define SkPtrSet_DEFINED
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRefCnt.h"
14227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org#include "SkFlattenable.h"
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTDArray.h"
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
17e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org/**
18e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org *  Maintains a set of ptrs, assigning each a unique ID [1...N]. Duplicate ptrs
19e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org *  return the same ID (since its a set). Subclasses can override inPtr()
20e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org *  and decPtr(). incPtr() is called each time a unique ptr is added ot the
21e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org *  set. decPtr() is called on each ptr when the set is destroyed or reset.
22e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org */
23e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.orgclass SkPtrSet : public SkRefCnt {
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
2515e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com    SK_DECLARE_INST_COUNT(SkPtrSet)
2615e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com
27e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org    /**
288d90eeba09484cfc702e82a332c4a7a978a5cfc1reed@google.com     *  Search for the specified ptr in the set. If it is found, return its
298d90eeba09484cfc702e82a332c4a7a978a5cfc1reed@google.com     *  32bit ID [1..N], or if not found, return 0. Always returns 0 for NULL.
308d90eeba09484cfc702e82a332c4a7a978a5cfc1reed@google.com     */
318d90eeba09484cfc702e82a332c4a7a978a5cfc1reed@google.com    uint32_t find(void*) const;
328d90eeba09484cfc702e82a332c4a7a978a5cfc1reed@google.com
338d90eeba09484cfc702e82a332c4a7a978a5cfc1reed@google.com    /**
34e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org     *  Add the specified ptr to the set, returning a unique 32bit ID for it
35e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org     *  [1...N]. Duplicate ptrs will return the same ID.
36e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org     *
37e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org     *  If the ptr is NULL, it is not added, and 0 is returned.
38e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org     */
39e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org    uint32_t add(void*);
40fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
41e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org    /**
42e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org     *  Return the number of (non-null) ptrs in the set.
43e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org     */
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int count() const { return fList.count(); }
45e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org
46e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org    /**
47e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org     *  Copy the ptrs in the set into the specified array (allocated by the
48e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org     *  caller). The ptrs are assgined to the array based on their corresponding
49e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org     *  ID. e.g. array[ptr.ID - 1] = ptr.
50e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org     *
51e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org     *  incPtr() and decPtr() are not called during this operation.
52e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org     */
53e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org    void copyToArray(void* array[]) const;
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
55e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org    /**
56e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org     *  Call decPtr() on each ptr in the set, and the reset the size of the set
57e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org     *  to 0.
58e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org     */
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void reset();
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
61acb882c239c0cfea738fe63ed9de48ddc2ddc76afmalita    /**
62acb882c239c0cfea738fe63ed9de48ddc2ddc76afmalita     * Set iterator.
63acb882c239c0cfea738fe63ed9de48ddc2ddc76afmalita     */
64acb882c239c0cfea738fe63ed9de48ddc2ddc76afmalita    class Iter {
65acb882c239c0cfea738fe63ed9de48ddc2ddc76afmalita    public:
66acb882c239c0cfea738fe63ed9de48ddc2ddc76afmalita        Iter(const SkPtrSet& set)
67acb882c239c0cfea738fe63ed9de48ddc2ddc76afmalita            : fSet(set)
68acb882c239c0cfea738fe63ed9de48ddc2ddc76afmalita            , fIndex(0) {}
69acb882c239c0cfea738fe63ed9de48ddc2ddc76afmalita
70acb882c239c0cfea738fe63ed9de48ddc2ddc76afmalita        /**
71acb882c239c0cfea738fe63ed9de48ddc2ddc76afmalita         * Return the next ptr in the set or null if the end was reached.
72acb882c239c0cfea738fe63ed9de48ddc2ddc76afmalita         */
73acb882c239c0cfea738fe63ed9de48ddc2ddc76afmalita        void* next() {
74acb882c239c0cfea738fe63ed9de48ddc2ddc76afmalita            return fIndex < fSet.fList.count() ? fSet.fList[fIndex++].fPtr : NULL;
75acb882c239c0cfea738fe63ed9de48ddc2ddc76afmalita        }
76acb882c239c0cfea738fe63ed9de48ddc2ddc76afmalita
77acb882c239c0cfea738fe63ed9de48ddc2ddc76afmalita    private:
78acb882c239c0cfea738fe63ed9de48ddc2ddc76afmalita        const SkPtrSet& fSet;
79acb882c239c0cfea738fe63ed9de48ddc2ddc76afmalita        int             fIndex;
80acb882c239c0cfea738fe63ed9de48ddc2ddc76afmalita    };
81acb882c239c0cfea738fe63ed9de48ddc2ddc76afmalita
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
8393c7ee34dc5c8f6bfad65809f4b39f8d00d7f0d4sugoi@google.com    virtual void incPtr(void*) {}
8493c7ee34dc5c8f6bfad65809f4b39f8d00d7f0d4sugoi@google.com    virtual void decPtr(void*) {}
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    struct Pair {
88e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org        void*       fPtr;   // never NULL
89e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org        uint32_t    fIndex; // 1...N
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    };
91e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org
92e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org    // we store the ptrs in sorted-order (using Cmp) so that we can efficiently
93e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org    // detect duplicates when add() is called. Hence we need to store the
94e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org    // ptr and its ID/fIndex explicitly, since the ptr's position in the array
95e8f754a41ccaa87719839a5112e59e1b9a63a037mike@reedtribe.org    // is not related to its "index".
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkTDArray<Pair>  fList;
97fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
9820f7f173e05b60f541910d0c1da9850ac73e2958bsalomon@google.com    static bool Less(const Pair& a, const Pair& b);
99fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    typedef SkRefCnt INHERITED;
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
103e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org/**
104e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org *  Templated wrapper for SkPtrSet, just meant to automate typecasting
105e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org *  parameters to and from void* (which the base class expects).
106e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org */
107e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.orgtemplate <typename T> class SkTPtrSet : public SkPtrSet {
108e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.orgpublic:
1096bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com    uint32_t find(T ptr) {
1106bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com        return this->INHERITED::find((void*)ptr);
1116bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com    }
112e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org    uint32_t add(T ptr) {
113e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org        return this->INHERITED::add((void*)ptr);
114e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org    }
115fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
116e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org    void copyToArray(T* array) const {
117e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org        this->INHERITED::copyToArray((void**)array);
118e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org    }
119e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org
120e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.orgprivate:
121e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org    typedef SkPtrSet INHERITED;
122e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org};
123e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org
124227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org/**
125227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org *  Subclass of SkTPtrSet specialed to call ref() and unref() when the
126227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org *  base class's incPtr() and decPtr() are called. This makes it a valid owner
127227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org *  of each ptr, which is released when the set is reset or destroyed.
128227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org */
129227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.orgclass SkRefCntSet : public SkTPtrSet<SkRefCnt*> {
130227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.orgpublic:
131227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org    virtual ~SkRefCntSet();
132fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
133227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.orgprotected:
134227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org    // overrides
135227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org    virtual void incPtr(void*);
136227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org    virtual void decPtr(void*);
137227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org};
138227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org
139227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.orgclass SkFactorySet : public SkTPtrSet<SkFlattenable::Factory> {};
140227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org
141227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org/**
142227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org * Similar to SkFactorySet, but only allows Factorys that have registered names.
143227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org * Also has a function to return the next added Factory's name.
144227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org */
145227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.orgclass SkNamedFactorySet : public SkRefCnt {
146227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.orgpublic:
147a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SK_DECLARE_INST_COUNT(SkNamedFactorySet)
148a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com
149227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org    SkNamedFactorySet();
150fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
151227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org    /**
152227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org     * Find the specified Factory in the set. If it is not already in the set,
153227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org     * and has registered its name, add it to the set, and return its index.
154227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org     * If the Factory has no registered name, return 0.
155227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org     */
156227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org    uint32_t find(SkFlattenable::Factory);
157fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
158227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org    /**
159227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org     * If new Factorys have been added to the set, return the name of the first
160227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org     * Factory added after the Factory name returned by the last call to this
161227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org     * function.
162227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org     */
163227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org    const char* getNextAddedFactoryName();
164227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.orgprivate:
165227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org    int                    fNextAddedFactory;
166227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org    SkFactorySet           fFactorySet;
167227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org    SkTDArray<const char*> fNames;
168a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com
169a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    typedef SkRefCnt INHERITED;
170227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org};
171227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org
1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
173