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