SkFlattenable.h revision c73dd5c6880739f26216f198c757028fd28df1a4
1
2/*
3 * Copyright 2006 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 SkFlattenable_DEFINED
11#define SkFlattenable_DEFINED
12
13#include "SkRefCnt.h"
14
15class SkFlattenableReadBuffer;
16class SkFlattenableWriteBuffer;
17
18#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
19
20#define SK_DEFINE_FLATTENABLE_REGISTRAR(flattenable) \
21    static SkFlattenable::Registrar g##flattenable##Reg(#flattenable, \
22                                                       flattenable::CreateProc);
23#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
24    static SkFlattenable::Registrar g##flattenable##Reg(#flattenable, \
25                                                       flattenable::CreateProc);
26
27#define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
28#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable)
29#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
30
31#else
32
33#define SK_DEFINE_FLATTENABLE_REGISTRAR(flattenable)
34#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
35        SkFlattenable::Registrar(#flattenable, flattenable::CreateProc);
36
37#define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() static void InitializeFlattenables();
38
39#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable) \
40    void flattenable::InitializeFlattenables() {
41
42#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END \
43    }
44
45#endif
46
47#define SK_DECLARE_UNFLATTENABLE_OBJECT() \
48    virtual Factory getFactory() SK_OVERRIDE { return NULL; }; \
49
50#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \
51    virtual Factory getFactory() SK_OVERRIDE { return CreateProc; } \
52    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { \
53        return SkNEW_ARGS(flattenable, (buffer)); \
54    }
55
56/** \class SkFlattenable
57
58 SkFlattenable is the base class for objects that need to be flattened
59 into a data stream for either transport or as part of the key to the
60 font cache.
61 */
62class SK_API SkFlattenable : public SkRefCnt {
63public:
64    SK_DECLARE_INST_COUNT(SkFlattenable)
65
66    typedef SkFlattenable* (*Factory)(SkFlattenableReadBuffer&);
67
68    SkFlattenable() {}
69
70    /** Implement this to return a factory function pointer that can be called
71     to recreate your class given a buffer (previously written to by your
72     override of flatten().
73     */
74    virtual Factory getFactory() = 0;
75
76    static Factory NameToFactory(const char name[]);
77    static const char* FactoryToName(Factory);
78    static void Register(const char name[], Factory);
79
80    class Registrar {
81    public:
82        Registrar(const char name[], Factory factory) {
83            SkFlattenable::Register(name, factory);
84        }
85    };
86
87protected:
88    SkFlattenable(SkFlattenableReadBuffer&) {}
89    /** Override this to write data specific to your subclass into the buffer,
90     being sure to call your super-class' version first. This data will later
91     be passed to your Factory function, returned by getFactory().
92     */
93    virtual void flatten(SkFlattenableWriteBuffer&) const;
94
95private:
96#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
97    static void InitializeFlattenables();
98#endif
99
100    friend class SkGraphics;
101    friend class SkFlattenableWriteBuffer;
102
103    typedef SkRefCnt INHERITED;
104};
105
106///////////////////////////////////////////////////////////////////////////////
107
108#include "SkPtrRecorder.h"
109
110/**
111 *  Subclass of SkTPtrSet specialed to call ref() and unref() when the
112 *  base class's incPtr() and decPtr() are called. This makes it a valid owner
113 *  of each ptr, which is released when the set is reset or destroyed.
114 */
115class SkRefCntSet : public SkTPtrSet<SkRefCnt*> {
116public:
117    virtual ~SkRefCntSet();
118
119protected:
120    // overrides
121    virtual void incPtr(void*);
122    virtual void decPtr(void*);
123};
124
125class SkFactorySet : public SkTPtrSet<SkFlattenable::Factory> {};
126
127/**
128 * Similar to SkFactorySet, but only allows Factorys that have registered names.
129 * Also has a function to return the next added Factory's name.
130 */
131class SkNamedFactorySet : public SkRefCnt {
132public:
133    SkNamedFactorySet();
134
135    /**
136     * Find the specified Factory in the set. If it is not already in the set,
137     * and has registered its name, add it to the set, and return its index.
138     * If the Factory has no registered name, return 0.
139     */
140    uint32_t find(SkFlattenable::Factory);
141
142    /**
143     * If new Factorys have been added to the set, return the name of the first
144     * Factory added after the Factory name returned by the last call to this
145     * function.
146     */
147    const char* getNextAddedFactoryName();
148private:
149    int                    fNextAddedFactory;
150    SkFactorySet           fFactorySet;
151    SkTDArray<const char*> fNames;
152};
153
154#endif
155