All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
registryManager.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef TF_REGISTRYMANAGER_H
25 #define TF_REGISTRYMANAGER_H
26 
29 
30 #include "pxr/pxr.h"
31 
32 #include "pxr/base/arch/attributes.h"
33 #include "pxr/base/tf/preprocessorUtilsLite.h"
34 #include "pxr/base/tf/api.h"
35 
36 #include <boost/noncopyable.hpp>
37 #include <boost/preprocessor/cat.hpp>
38 #include <boost/preprocessor/stringize.hpp>
39 
40 #include <functional>
41 #include <typeinfo>
42 
43 PXR_NAMESPACE_OPEN_SCOPE
44 
52 class TfRegistryManager : boost::noncopyable {
53 public:
54  // The type of a registration function. The arguments are not used.
55  typedef void (*RegistrationFunctionType)(void*, void*);
56  typedef std::function<void ()> UnloadFunctionType;
57 
59  TF_API static TfRegistryManager& GetInstance();
60 
68  template <class T>
69  void SubscribeTo() {
70  _SubscribeTo(typeid(T));
71  }
72 
77  template <class T>
78  void UnsubscribeFrom() {
79  _UnsubscribeFrom(typeid(T));
80  }
81 
102  TF_API bool AddFunctionForUnload(const UnloadFunctionType&);
103 
114  TF_API static void RunUnloadersAtExit();
115 
116 private:
117  TF_API TfRegistryManager();
118  TF_API ~TfRegistryManager();
119 
120  TF_API void _SubscribeTo(const std::type_info&);
121  TF_API void _UnsubscribeFrom(const std::type_info&);
122 };
123 
124 TF_API void Tf_RegistryInitCtor(char const *name);
125 TF_API void Tf_RegistryInitDtor(char const *name);
126 
127 namespace {
128 struct Tf_RegistryStaticInit {
129  Tf_RegistryStaticInit() {
130  Tf_RegistryInitCtor(BOOST_PP_STRINGIZE(MFB_ALT_PACKAGE_NAME));
131  }
132  ~Tf_RegistryStaticInit() {
133  Tf_RegistryInitDtor(BOOST_PP_STRINGIZE(MFB_ALT_PACKAGE_NAME));
134  }
135 };
136 }
137 
138 // Private class used to indicate the library has finished registering
139 // functions, to indicate that the library is being unloaded and to
140 // add functions to the registry.
141 class Tf_RegistryInit {
142 public:
143  TF_API static void Add(const char* libName,
144  TfRegistryManager::RegistrationFunctionType func,
145  const char* typeName);
146  template <class T, class U>
147  static void Add(const char* libName,
148  void (*func)(T*, U*),
149  const char* typeName)
150  {
151  Add(libName,(TfRegistryManager::RegistrationFunctionType)func,typeName);
152  }
153 };
154 
155 // The ARCH_CONSTRUCTOR priority for registering registry functions.
156 #define TF_REGISTRY_PRIORITY 100
157 
158 //
159 // Macros for adding registry functions outside class templates.
160 //
161 
162 // Define a registry function outside of a template. Follow the macro with
163 // the body of the function inside braces. KEY_TYPE and TAG must be types.
164 #define TF_REGISTRY_DEFINE_WITH_TYPE(KEY_TYPE, TAG) \
165  static void _Tf_RegistryFunction(KEY_TYPE*, TAG*); \
166  ARCH_CONSTRUCTOR(BOOST_PP_CAT(_Tf_RegistryAdd, __LINE__), \
167  TF_REGISTRY_PRIORITY, KEY_TYPE*, TAG*) \
168  { \
169  Tf_RegistryInit::Add(BOOST_PP_STRINGIZE(MFB_ALT_PACKAGE_NAME), \
170  (void(*)(KEY_TYPE*, TAG*))_Tf_RegistryFunction, \
171  BOOST_PP_STRINGIZE(KEY_TYPE)); \
172  } \
173  _ARCH_ENSURE_PER_LIB_INIT(Tf_RegistryStaticInit, _tfRegistryInit); \
174  static void _Tf_RegistryFunction(KEY_TYPE*, TAG*)
175 
176 // Define a registry function outside of a template. Follow the macro with
177 // the body of the function inside braces. KEY_TYPE must be a type and NAME
178 // must be a valid C++ name.
179 #define TF_REGISTRY_DEFINE(KEY_TYPE, NAME) \
180  static void BOOST_PP_CAT(_Tf_RegistryFunction, NAME)(KEY_TYPE*, void*); \
181  ARCH_CONSTRUCTOR(BOOST_PP_CAT(_Tf_RegistryAdd, NAME), \
182  TF_REGISTRY_PRIORITY, KEY_TYPE*) \
183  { \
184  Tf_RegistryInit::Add(BOOST_PP_STRINGIZE(MFB_ALT_PACKAGE_NAME), \
185  (void(*)(KEY_TYPE*, void*)) \
186  BOOST_PP_CAT(_Tf_RegistryFunction, NAME), \
187  BOOST_PP_STRINGIZE(KEY_TYPE)); \
188  } \
189  _ARCH_ENSURE_PER_LIB_INIT(Tf_RegistryStaticInit, _tfRegistryInit); \
190  static void BOOST_PP_CAT(_Tf_RegistryFunction, NAME)(KEY_TYPE*, void*)
191 
192 
220 #define TF_REGISTRY_FUNCTION(KEY_TYPE) \
221  TF_REGISTRY_DEFINE(KEY_TYPE, __LINE__)
222 
261 #define TF_REGISTRY_FUNCTION_WITH_TAG(KEY_TYPE, TAG) \
262  TF_REGISTRY_DEFINE(KEY_TYPE, BOOST_PP_CAT(TAG, __LINE__))
263 
264 PXR_NAMESPACE_CLOSE_SCOPE
265 
266 #endif // TF_REGISTRYMANAGER_H
static TF_API TfRegistryManager & GetInstance()
Return the singleton TfRegistryManager instance.
TF_API bool AddFunctionForUnload(const UnloadFunctionType &)
Add an action to be performed at code unload time.
void UnsubscribeFrom()
Cancel any previous subscriptions to service T.
void SubscribeTo()
Request that any initialization for service T be performed.
static TF_API void RunUnloadersAtExit()
Run unload functions program exit time.
Manage initialization of registries.