blob: 4184e4999e70e4243c2585f5204b7a3a90377f25 [file] [log] [blame]
reed@android.com00bf85a2009-01-22 13:04:56 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * Copyright 2009 The Android Open Source Project
reed@android.com00bf85a2009-01-22 13:04:56 +00003 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00004 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
reed@android.com00bf85a2009-01-22 13:04:56 +00006 */
7
Mike Reedab273fa2017-01-11 13:58:55 -05008#ifndef sk_tools_Registry_DEFINED
9#define sk_tools_Registry_DEFINED
reed@android.com00bf85a2009-01-22 13:04:56 +000010
Ben Wagnerd5148e32018-07-16 17:44:06 -040011#include "SkNoncopyable.h"
reed@android.com00bf85a2009-01-22 13:04:56 +000012#include "SkTypes.h"
13
Mike Reedab273fa2017-01-11 13:58:55 -050014namespace sk_tools {
15
reed@android.com00bf85a2009-01-22 13:04:56 +000016/** Template class that registers itself (in the constructor) into a linked-list
17 and provides a function-pointer. This can be used to auto-register a set of
18 services, e.g. a set of image codecs.
19 */
Mike Reedab273fa2017-01-11 13:58:55 -050020template <typename T> class Registry : SkNoncopyable {
reed@android.com00bf85a2009-01-22 13:04:56 +000021public:
mtklein@google.combd6343b2013-09-04 17:20:18 +000022 typedef T Factory;
reed@android.com00bf85a2009-01-22 13:04:56 +000023
Mike Reedab273fa2017-01-11 13:58:55 -050024 explicit Registry(T fact) : fFact(fact) {
djsollen@google.com56c69772011-11-08 19:00:26 +000025#ifdef SK_BUILD_FOR_ANDROID
reed@android.com57b799e2009-04-01 20:26:42 +000026 // work-around for double-initialization bug
27 {
Mike Reedab273fa2017-01-11 13:58:55 -050028 Registry* reg = gHead;
reed@android.com57b799e2009-04-01 20:26:42 +000029 while (reg) {
30 if (reg == this) {
31 return;
32 }
33 reg = reg->fChain;
34 }
35 }
36#endif
reed@android.com00bf85a2009-01-22 13:04:56 +000037 fChain = gHead;
mtklein@google.combd6343b2013-09-04 17:20:18 +000038 gHead = this;
reed@android.com00bf85a2009-01-22 13:04:56 +000039 }
40
Mike Reedab273fa2017-01-11 13:58:55 -050041 static const Registry* Head() { return gHead; }
reed@android.com00bf85a2009-01-22 13:04:56 +000042
Mike Reedab273fa2017-01-11 13:58:55 -050043 const Registry* next() const { return fChain; }
mtklein@google.combd6343b2013-09-04 17:20:18 +000044 const Factory& factory() const { return fFact; }
reed@android.com00bf85a2009-01-22 13:04:56 +000045
46private:
Mike Reedab273fa2017-01-11 13:58:55 -050047 Factory fFact;
48 Registry* fChain;
reed@android.com00bf85a2009-01-22 13:04:56 +000049
Mike Reedab273fa2017-01-11 13:58:55 -050050 static Registry* gHead;
reed@android.com00bf85a2009-01-22 13:04:56 +000051};
52
reed@android.comf523e252009-01-26 23:15:37 +000053// The caller still needs to declare an instance of this somewhere
Mike Reedab273fa2017-01-11 13:58:55 -050054template <typename T> Registry<T>* Registry<T>::gHead;
55
56} // namespace sk_tools
reed@android.com00bf85a2009-01-22 13:04:56 +000057
58#endif