HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_SubSystem.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT_SubSystem.h
7  *
8  * COMMENTS:
9  *
10  *
11  */
12 
13 #ifndef __UT_SUBSYSTEM_H__
14 #define __UT_SUBSYSTEM_H__
15 
16 #include "UT_API.h"
17 
18 #define UT_ENABLE_SUBSYSTEMS
19 
20 #include "UT_NonCopyable.h"
21 #include "UT_UniquePtr.h"
22 
23 #include <SYS/SYS_StaticInit.h>
24 #include <SYS/SYS_TypeTraits.h>
25 
26 #include <type_traits>
27 
28 class UT_ThreadIOPool;
30 
31 /// All subsystems should derive from this interface. Each subsystem then
32 /// defines how to initialize and shutdown its components.
33 /// All components of a subsystem should be lazy initialized.
34 ///
35 /// To add a new subsystem:
36 /// 1. Add a new entry to the @ref Type enum below.
37 /// 2. In a header, declare a class deriving from @c UT_ISubSystem, use
38 /// @c UT_SUBSYSTEM_CLASS(your_type) inside it.
39 /// 3. Override @c initialize_() / @c shutdown_().
40 /// 4. End the header with @c UT_SUBSYSTEM_DECLARE(your_api, YourSubSystem).
41 /// 5. In the matching .C file, add @c UT_SUBSYSTEM_IMPL(YourSubSystem).
42 /// 6. Access the singleton anywhere via @c UTgetSubSystem<YourSubSystem>().
43 ///
45 {
46 public:
47  enum Type
48  {
54  MAX_SUBSYSTEMS
55  };
56 
58 
59  virtual ~UT_ISubSystem() = default;
60 
61  /// The type of the subsystem.
62  virtual Type type() const = 0;
63 
64  template <typename SubSystemT>
65  static bool registerSubSystem(SubSystemT& subsys)
66  {
67  static_assert(
68  std::is_base_of_v<UT_ISubSystem, SubSystemT>
69  && std::is_default_constructible_v<SubSystemT>);
70  return registerSubSystem_(SYSaddressof(subsys));
71  }
72 
73 protected:
74  UT_ISubSystem() = default;
75 
76  /// Initialize this subsystem
77  virtual void initialize_() = 0;
78  /// Shutdown this subsystem
79  virtual void shutdown_() = 0;
80 private:
81  friend class ut_SubSystemRegistry;
82 
83  static bool registerSubSystem_(UT_ISubSystem* subsys);
84 };
85 
86 #define UT_SUBSYSTEM_CLASS(sub_type) \
87 public: \
88  static constexpr Type subsystem_type = UT_ISubSystem::Type::sub_type; \
89  Type type() const override \
90  { \
91  return subsystem_type; \
92  } \
93  \
94 private: \
95  static bool theIsRegistered;
96 
97 #define UT_SUBSYSTEM_IMPL_INNER(cls) \
98  static SYS_StaticInit<cls> theSubSystem; \
99  static void cls##Init() \
100  { \
101  UT_ISubSystem::registerSubSystem<cls>(*theSubSystem); \
102  } \
103  static void cls##CleanUp() \
104  { \
105  }
106 
107 #define UT_SUBSYSTEM_IMPL(cls) \
108  namespace cls_Namespace \
109  { \
110  UT_SUBSYSTEM_IMPL_INNER(cls) \
111  SYSimplementStaticInit(cls); \
112  }
113 
114 #define UT_SUBSYSTEM_DECLARE(api, cls) \
115  namespace cls_Namespace \
116  { \
117  SYSdeclareStaticInit(api, cls) \
118  }
119 
120 /// The subsystem to initialize and cleanup UT.
121 class UT_API UT_SubSystem final : public UT_ISubSystem
122 {
123  UT_SUBSYSTEM_CLASS(UT_SUBSYSTEM);
124 public:
125  UT_SubSystem();
126  ~UT_SubSystem() override;
127 
128 protected:
129 
130  void initialize_() override;
131  void shutdown_() override;
132 
133 private:
134  friend class ut_SubSystemAccessor;
135 
136  class Impl;
137  UT_UniquePtr<Impl> myImpl;
138 };
139 
140 /// The general purpose thread pool. Any work can be done on this pool. The
141 /// exception to this is licensing work. We must not do any licensing work on
142 /// this thread as license checks will end up blocking the thread causing a hang
143 /// waiting for licensing work to be processed.
145 
146 /// Initialize all subsystems
148 /// Shutdown all subsystems. initialize() must be called prior to this
149 /// function.
151 
152 namespace UT_SubSystemImpl
153 {
154 SYSdeclareStaticObject(UT_API, theRegistry);
155 
157 } // namespace UT_SubSystemImpl
158 
159 template <typename T>
160 T*
162 {
163  static_assert(std::is_base_of_v<UT_ISubSystem, T>);
164  return static_cast<T*>(UT_SubSystemImpl::utGetSubSystem(T::subsystem_type));
165 }
166 
168 
169 #endif // __UT_SUBSYSTEM_H__
type
Definition: core.h:556
The subsystem to initialize and cleanup UT.
Definition: UT_SubSystem.h:121
#define UT_API
Definition: UT_API.h:14
virtual void shutdown_()=0
Shutdown this subsystem.
T * UTgetSubSystem()
Definition: UT_SubSystem.h:161
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
SYS_NO_DISCARD_RESULT SYS_FORCE_INLINE constexpr T * SYSaddressof(T &val) noexcept
UT_API void UTsubSystemShutdown()
#define UT_NON_COPYABLE(CLASS)
Define deleted copy constructor and assignment operator inside a class.
GLdouble t
Definition: glad.h:2397
UT_API UT_ThreadIOPool & UThoudiniIOPool()
#define UT_SUBSYSTEM_CLASS(sub_type)
Definition: UT_SubSystem.h:86
static bool registerSubSystem(SubSystemT &subsys)
Definition: UT_SubSystem.h:65
#define UT_SUBSYSTEM_DECLARE(api, cls)
Definition: UT_SubSystem.h:114
SYSdeclareStaticObject(UT_API, theRegistry)
virtual void initialize_()=0
Initialize this subsystem.
UT_API void UTsubSystemInitialize()
Initialize all subsystems.
UT_API UT_ISubSystem * utGetSubSystem(UT_SubSystem::Type t)