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