1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
200bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2009 The Android Open Source Project
400bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
700bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com */
800bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com
9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
1000bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com#ifndef SkTRegistry_DEFINED
1100bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com#define SkTRegistry_DEFINED
1200bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com
1300bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com#include "SkTypes.h"
1400bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com
1500bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com/** Template class that registers itself (in the constructor) into a linked-list
1600bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com    and provides a function-pointer. This can be used to auto-register a set of
1700bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com    services, e.g. a set of image codecs.
1800bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com */
19bd6343b1d60d2a85e930f33f4b06b4502b3e8caamtklein@google.comtemplate <typename T> class SkTRegistry : SkNoncopyable {
2000bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.compublic:
21bd6343b1d60d2a85e930f33f4b06b4502b3e8caamtklein@google.com    typedef T Factory;
2200bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com
23bd6343b1d60d2a85e930f33f4b06b4502b3e8caamtklein@google.com    explicit SkTRegistry(T fact) : fFact(fact) {
2456c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID
2557b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com        // work-around for double-initialization bug
2657b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com        {
2757b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com            SkTRegistry* reg = gHead;
2857b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com            while (reg) {
2957b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com                if (reg == this) {
3057b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com                    return;
3157b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com                }
3257b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com                reg = reg->fChain;
3357b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com            }
3457b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com        }
3557b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com#endif
3600bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com        fChain = gHead;
37bd6343b1d60d2a85e930f33f4b06b4502b3e8caamtklein@google.com        gHead  = this;
3800bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com    }
3900bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com
4000bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com    static const SkTRegistry* Head() { return gHead; }
4100bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com
4200bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com    const SkTRegistry* next() const { return fChain; }
43bd6343b1d60d2a85e930f33f4b06b4502b3e8caamtklein@google.com    const Factory& factory() const { return fFact; }
4400bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com
4500bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.comprivate:
4600bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com    Factory      fFact;
4700bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com    SkTRegistry* fChain;
4800bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com
4900bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com    static SkTRegistry* gHead;
5000bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com};
5100bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com
52f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com// The caller still needs to declare an instance of this somewhere
53bd6343b1d60d2a85e930f33f4b06b4502b3e8caamtklein@google.comtemplate <typename T> SkTRegistry<T>* SkTRegistry<T>::gHead;
5400bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com
5500bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com#endif
56