Home | History | Annotate | Download | only in core
      1 
      2 /*
      3  * Copyright 2008 The Android Open Source Project
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #ifndef SkPtrSet_DEFINED
     11 #define SkPtrSet_DEFINED
     12 
     13 #include "SkRefCnt.h"
     14 #include "SkFlattenable.h"
     15 #include "SkTDArray.h"
     16 
     17 /**
     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  */
     23 class SkPtrSet : public SkRefCnt {
     24 public:
     25     SK_DECLARE_INST_COUNT(SkPtrSet)
     26 
     27     /**
     28      *  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     /**
     34      *  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      *
     37      *  If the ptr is NULL, it is not added, and 0 is returned.
     38      */
     39     uint32_t add(void*);
     40 
     41     /**
     42      *  Return the number of (non-null) ptrs in the set.
     43      */
     44     int count() const { return fList.count(); }
     45 
     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      */
     53     void copyToArray(void* array[]) const;
     54 
     55     /**
     56      *  Call decPtr() on each ptr in the set, and the reset the size of the set
     57      *  to 0.
     58      */
     59     void reset();
     60 
     61 protected:
     62     virtual void incPtr(void*) {}
     63     virtual void decPtr(void*) {}
     64 
     65 private:
     66     struct Pair {
     67         void*       fPtr;   // never NULL
     68         uint32_t    fIndex; // 1...N
     69     };
     70 
     71     // we store the ptrs in sorted-order (using Cmp) so that we can efficiently
     72     // detect duplicates when add() is called. Hence we need to store the
     73     // ptr and its ID/fIndex explicitly, since the ptr's position in the array
     74     // is not related to its "index".
     75     SkTDArray<Pair>  fList;
     76 
     77     static bool Less(const Pair& a, const Pair& b);
     78 
     79     typedef SkRefCnt INHERITED;
     80 };
     81 
     82 /**
     83  *  Templated wrapper for SkPtrSet, just meant to automate typecasting
     84  *  parameters to and from void* (which the base class expects).
     85  */
     86 template <typename T> class SkTPtrSet : public SkPtrSet {
     87 public:
     88     uint32_t find(T ptr) {
     89         return this->INHERITED::find((void*)ptr);
     90     }
     91     uint32_t add(T ptr) {
     92         return this->INHERITED::add((void*)ptr);
     93     }
     94 
     95     void copyToArray(T* array) const {
     96         this->INHERITED::copyToArray((void**)array);
     97     }
     98 
     99 private:
    100     typedef SkPtrSet INHERITED;
    101 };
    102 
    103 /**
    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  */
    108 class SkRefCntSet : public SkTPtrSet<SkRefCnt*> {
    109 public:
    110     virtual ~SkRefCntSet();
    111 
    112 protected:
    113     // overrides
    114     virtual void incPtr(void*);
    115     virtual void decPtr(void*);
    116 };
    117 
    118 class 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  */
    124 class SkNamedFactorySet : public SkRefCnt {
    125 public:
    126     SK_DECLARE_INST_COUNT(SkNamedFactorySet)
    127 
    128     SkNamedFactorySet();
    129 
    130     /**
    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);
    136 
    137     /**
    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();
    143 private:
    144     int                    fNextAddedFactory;
    145     SkFactorySet           fFactorySet;
    146     SkTDArray<const char*> fNames;
    147 
    148     typedef SkRefCnt INHERITED;
    149 };
    150 
    151 #endif
    152