OpenShot Library | OpenShotAudio  0.2.2
juce_Singleton.h
1 
2 /** @weakgroup juce_core-memory
3  * @{
4  */
5 /*
6  ==============================================================================
7 
8  This file is part of the JUCE library.
9  Copyright (c) 2017 - ROLI Ltd.
10 
11  JUCE is an open source library subject to commercial or open-source
12  licensing.
13 
14  The code included in this file is provided under the terms of the ISC license
15  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
16  To use, copy, modify, and/or distribute this software for any purpose with or
17  without fee is hereby granted provided that the above copyright notice and
18  this permission notice appear in all copies.
19 
20  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
21  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
22  DISCLAIMED.
23 
24  ==============================================================================
25 */
26 
27 namespace juce
28 {
29 
30 //==============================================================================
31 /**
32  Used by the JUCE_DECLARE_SINGLETON macros to manage a static pointer
33  to a singleton instance.
34 
35  You generally won't use this directly, but see the macros JUCE_DECLARE_SINGLETON,
36  JUCE_DECLARE_SINGLETON_SINGLETHREADED, JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL,
37  and JUCE_IMPLEMENT_SINGLETON for how it is intended to be used.
38 
39  @tags{Core}
40 */
41 template <typename Type, typename MutexType, bool onlyCreateOncePerRun>
42 struct SingletonHolder : private MutexType // (inherited so we can use the empty-base-class optimisation)
43 {
44  SingletonHolder() = default;
45 
47  {
48  /* The static singleton holder is being deleted before the object that it holds
49  has been deleted. This could mean that you've forgotten to call clearSingletonInstance()
50  in the class's destructor, or have failed to delete it before your app shuts down.
51  If you're having trouble cleaning up your singletons, perhaps consider using the
52  SharedResourcePointer class instead.
53  */
54  jassert (instance == nullptr);
55  }
56 
57  /** Returns the current instance, or creates a new instance if there isn't one. */
58  Type* get()
59  {
60  if (instance == nullptr)
61  {
62  typename MutexType::ScopedLockType sl (*this);
63 
64  if (instance == nullptr)
65  {
66  auto once = onlyCreateOncePerRun; // (local copy avoids VS compiler warning about this being constant)
67 
68  if (once)
69  {
70  static bool createdOnceAlready = false;
71 
72  if (createdOnceAlready)
73  {
74  // This means that the doNotRecreateAfterDeletion flag was set
75  // and you tried to create the singleton more than once.
76  jassertfalse;
77  return nullptr;
78  }
79 
80  createdOnceAlready = true;
81  }
82 
83  static bool alreadyInside = false;
84 
85  if (alreadyInside)
86  {
87  // This means that your object's constructor has done something which has
88  // ended up causing a recursive loop of singleton creation..
89  jassertfalse;
90  }
91  else
92  {
93  alreadyInside = true;
95  alreadyInside = false;
96  }
97  }
98  }
99 
100  return instance;
101  }
102 
103  /** Returns the current instance, or creates a new instance if there isn't one, but doesn't do
104  any locking, or checking for recursion or error conditions.
105  */
107  {
108  if (instance == nullptr)
109  {
110  auto newObject = new Type(); // (create into a local so that instance is still null during construction)
111  instance = newObject;
112  }
113 
114  return instance;
115  }
116 
117  /** Deletes and resets the current instance, if there is one. */
119  {
120  typename MutexType::ScopedLockType sl (*this);
121  auto old = instance;
122  instance = nullptr;
123  delete old;
124  }
125 
126  /** Called by the class's destructor to clear the pointer if it is currently set to the given object. */
127  void clear (Type* expectedObject) noexcept
128  {
129  if (instance == expectedObject)
130  instance = nullptr;
131  }
132 
133  Type* instance = nullptr;
134 };
135 
136 
137 //==============================================================================
138 /**
139  Macro to generate the appropriate methods and boilerplate for a singleton class.
140 
141  To use this, add the line JUCE_DECLARE_SINGLETON(MyClass, doNotRecreateAfterDeletion)
142  to the class's definition.
143 
144  Then put a macro JUCE_IMPLEMENT_SINGLETON(MyClass) along with the class's
145  implementation code.
146 
147  It's also a very good idea to also add the call clearSingletonInstance() in your class's
148  destructor, in case it is deleted by other means than deleteInstance()
149 
150  Clients can then call the static method MyClass::getInstance() to get a pointer
151  to the singleton, or MyClass::getInstanceWithoutCreating() which will return nullptr if
152  no instance currently exists.
153 
154  e.g. @code
155 
156  struct MySingleton
157  {
158  MySingleton() {}
159 
160  ~MySingleton()
161  {
162  // this ensures that no dangling pointers are left when the
163  // singleton is deleted.
164  clearSingletonInstance();
165  }
166 
167  JUCE_DECLARE_SINGLETON (MySingleton, false)
168  };
169 
170  // ..and this goes in a suitable .cpp file:
171  JUCE_IMPLEMENT_SINGLETON (MySingleton)
172 
173 
174  // example of usage:
175  auto* m = MySingleton::getInstance(); // creates the singleton if there isn't already one.
176 
177  ...
178 
179  MySingleton::deleteInstance(); // safely deletes the singleton (if it's been created).
180 
181  @endcode
182 
183  If doNotRecreateAfterDeletion = true, it won't allow the object to be created more
184  than once during the process's lifetime - i.e. after you've created and deleted the
185  object, getInstance() will refuse to create another one. This can be useful to stop
186  objects being accidentally re-created during your app's shutdown code.
187 
188  If you know that your object will only be created and deleted by a single thread, you
189  can use the slightly more efficient JUCE_DECLARE_SINGLETON_SINGLETHREADED macro instead
190  of this one.
191 
192  @see JUCE_IMPLEMENT_SINGLETON, JUCE_DECLARE_SINGLETON_SINGLETHREADED
193 */
194 #define JUCE_DECLARE_SINGLETON(Classname, doNotRecreateAfterDeletion) \
195 \
196  static juce::SingletonHolder<Classname, juce::CriticalSection, doNotRecreateAfterDeletion> singletonHolder; \
197  friend decltype (singletonHolder); \
198 \
199  static Classname* JUCE_CALLTYPE getInstance() { return singletonHolder.get(); } \
200  static Classname* JUCE_CALLTYPE getInstanceWithoutCreating() noexcept { return singletonHolder.instance; } \
201  static void JUCE_CALLTYPE deleteInstance() noexcept { singletonHolder.deleteInstance(); } \
202  void clearSingletonInstance() noexcept { singletonHolder.clear (this); }
203 
204 
205 //==============================================================================
206 /** This is a counterpart to the JUCE_DECLARE_SINGLETON macros.
207 
208  After adding the JUCE_DECLARE_SINGLETON to the class definition, this macro has
209  to be used in the cpp file.
210 */
211 #define JUCE_IMPLEMENT_SINGLETON(Classname) \
212 \
213  decltype (Classname::singletonHolder) Classname::singletonHolder;
214 
215 
216 //==============================================================================
217 /**
218  Macro to declare member variables and methods for a singleton class.
219 
220  This is exactly the same as JUCE_DECLARE_SINGLETON, but doesn't use a critical
221  section to make access to it thread-safe. If you know that your object will
222  only ever be created or deleted by a single thread, then this is a
223  more efficient version to use.
224 
225  If doNotRecreateAfterDeletion = true, it won't allow the object to be created more
226  than once during the process's lifetime - i.e. after you've created and deleted the
227  object, getInstance() will refuse to create another one. This can be useful to stop
228  objects being accidentally re-created during your app's shutdown code.
229 
230  See the documentation for JUCE_DECLARE_SINGLETON for more information about
231  how to use it. Just like JUCE_DECLARE_SINGLETON you need to also have a
232  corresponding JUCE_IMPLEMENT_SINGLETON statement somewhere in your code.
233 
234  @see JUCE_IMPLEMENT_SINGLETON, JUCE_DECLARE_SINGLETON, JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL
235 */
236 #define JUCE_DECLARE_SINGLETON_SINGLETHREADED(Classname, doNotRecreateAfterDeletion) \
237 \
238  static juce::SingletonHolder<Classname, juce::DummyCriticalSection, doNotRecreateAfterDeletion> singletonHolder; \
239  friend decltype (singletonHolder); \
240 \
241  static Classname* JUCE_CALLTYPE getInstance() { return singletonHolder.get(); } \
242  static Classname* JUCE_CALLTYPE getInstanceWithoutCreating() noexcept { return singletonHolder.instance; } \
243  static void JUCE_CALLTYPE deleteInstance() noexcept { singletonHolder.deleteInstance(); } \
244  void clearSingletonInstance() noexcept { singletonHolder.clear (this); }
245 
246 
247 //==============================================================================
248 /**
249  Macro to declare member variables and methods for a singleton class.
250 
251  This is like JUCE_DECLARE_SINGLETON_SINGLETHREADED, but doesn't do any checking
252  for recursion or repeated instantiation. It's intended for use as a lightweight
253  version of a singleton, where you're using it in very straightforward
254  circumstances and don't need the extra checking.
255 
256  See the documentation for JUCE_DECLARE_SINGLETON for more information about
257  how to use it. Just like JUCE_DECLARE_SINGLETON you need to also have a
258  corresponding JUCE_IMPLEMENT_SINGLETON statement somewhere in your code.
259 
260  @see JUCE_IMPLEMENT_SINGLETON, JUCE_DECLARE_SINGLETON
261 */
262 #define JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL(Classname) \
263 \
264  static juce::SingletonHolder<Classname, juce::DummyCriticalSection, false> singletonHolder; \
265  friend decltype (singletonHolder); \
266 \
267  static Classname* JUCE_CALLTYPE getInstance() { return singletonHolder.getWithoutChecking(); } \
268  static Classname* JUCE_CALLTYPE getInstanceWithoutCreating() noexcept { return singletonHolder.instance; } \
269  static void JUCE_CALLTYPE deleteInstance() noexcept { singletonHolder.deleteInstance(); } \
270  void clearSingletonInstance() noexcept { singletonHolder.clear (this); }
271 
272 
273 //==============================================================================
274 #ifndef DOXYGEN
275  // These are ancient macros, and have now been updated with new names to match the JUCE style guide,
276  // so please update your code to use the newer versions!
277  #define juce_DeclareSingleton(Classname, doNotRecreate) JUCE_DECLARE_SINGLETON(Classname, doNotRecreate)
278  #define juce_DeclareSingleton_SingleThreaded(Classname, doNotRecreate) JUCE_DECLARE_SINGLETON_SINGLETHREADED(Classname, doNotRecreate)
279  #define juce_DeclareSingleton_SingleThreaded_Minimal(Classname) JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL(Classname)
280  #define juce_ImplementSingleton(Classname) JUCE_IMPLEMENT_SINGLETON(Classname)
281  #define juce_ImplementSingleton_SingleThreaded(Classname) JUCE_IMPLEMENT_SINGLETON(Classname)
282 #endif
283 
284 } // namespace juce
285 
286 /** @}*/
Type * getWithoutChecking()
Returns the current instance, or creates a new instance if there isn&#39;t one, but doesn&#39;t do any lockin...
void clear(Type *expectedObject) noexcept
Called by the class&#39;s destructor to clear the pointer if it is currently set to the given object...
void deleteInstance()
Deletes and resets the current instance, if there is one.
Used by the JUCE_DECLARE_SINGLETON macros to manage a static pointer to a singleton instance...