180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2009 The Android Open Source Project
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef SkTRegistry_DEFINED
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkTRegistry_DEFINED
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTypes.h"
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** Template class that registers itself (in the constructor) into a linked-list
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    and provides a function-pointer. This can be used to auto-register a set of
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    services, e.g. a set of image codecs.
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergertemplate <typename T> class SkTRegistry : SkNoncopyable {
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    typedef T Factory;
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    explicit SkTRegistry(T fact) : fFact(fact) {
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_BUILD_FOR_ANDROID
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // work-around for double-initialization bug
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        {
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkTRegistry* reg = gHead;
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            while (reg) {
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                if (reg == this) {
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    return;
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                reg = reg->fChain;
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fChain = gHead;
370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        gHead  = this;
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static const SkTRegistry* Head() { return gHead; }
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkTRegistry* next() const { return fChain; }
430a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    const Factory& factory() const { return fFact; }
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Factory      fFact;
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkTRegistry* fChain;
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static SkTRegistry* gHead;
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// The caller still needs to declare an instance of this somewhere
530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergertemplate <typename T> SkTRegistry<T>* SkTRegistry<T>::gHead;
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
56