100bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2009 The Android Open Source Project
300bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
600bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com */
700bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com
8ab273facbfe496a3d5dd798e6b4b57c41eed7f16Mike Reed#ifndef sk_tools_Registry_DEFINED
9ab273facbfe496a3d5dd798e6b4b57c41eed7f16Mike Reed#define sk_tools_Registry_DEFINED
1000bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com
1100bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com#include "SkTypes.h"
1200bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com
13ab273facbfe496a3d5dd798e6b4b57c41eed7f16Mike Reednamespace sk_tools {
14ab273facbfe496a3d5dd798e6b4b57c41eed7f16Mike Reed
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 */
19ab273facbfe496a3d5dd798e6b4b57c41eed7f16Mike Reedtemplate <typename T> class Registry : SkNoncopyable {
2000bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.compublic:
21bd6343b1d60d2a85e930f33f4b06b4502b3e8caamtklein@google.com    typedef T Factory;
2200bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com
23ab273facbfe496a3d5dd798e6b4b57c41eed7f16Mike Reed    explicit Registry(T fact) : fFact(fact) {
2456c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID
2557b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com        // work-around for double-initialization bug
2657b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com        {
27ab273facbfe496a3d5dd798e6b4b57c41eed7f16Mike Reed            Registry* 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
40ab273facbfe496a3d5dd798e6b4b57c41eed7f16Mike Reed    static const Registry* Head() { return gHead; }
4100bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com
42ab273facbfe496a3d5dd798e6b4b57c41eed7f16Mike Reed    const Registry* next() const { return fChain; }
43bd6343b1d60d2a85e930f33f4b06b4502b3e8caamtklein@google.com    const Factory& factory() const { return fFact; }
4400bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com
4500bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.comprivate:
46ab273facbfe496a3d5dd798e6b4b57c41eed7f16Mike Reed    Factory   fFact;
47ab273facbfe496a3d5dd798e6b4b57c41eed7f16Mike Reed    Registry* fChain;
4800bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com
49ab273facbfe496a3d5dd798e6b4b57c41eed7f16Mike Reed    static Registry* gHead;
5000bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com};
5100bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com
52f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com// The caller still needs to declare an instance of this somewhere
53ab273facbfe496a3d5dd798e6b4b57c41eed7f16Mike Reedtemplate <typename T> Registry<T>* Registry<T>::gHead;
54ab273facbfe496a3d5dd798e6b4b57c41eed7f16Mike Reed
55ab273facbfe496a3d5dd798e6b4b57c41eed7f16Mike Reed}  // namespace sk_tools
5600bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com
5700bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com#endif
58