OpenShot Audio Library | OpenShotAudio  0.3.1
juce_Singleton.h
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2017 - ROLI Ltd.
6 
7  JUCE is an open source library subject to commercial or open-source
8  licensing.
9 
10  The code included in this file is provided under the terms of the ISC license
11  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12  To use, copy, modify, and/or distribute this software for any purpose with or
13  without fee is hereby granted provided that the above copyright notice and
14  this permission notice appear in all copies.
15 
16  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18  DISCLAIMED.
19 
20  ==============================================================================
21 */
22 
23 namespace juce
24 {
25 
26 //==============================================================================
37 template <typename Type, typename MutexType, bool onlyCreateOncePerRun>
38 struct SingletonHolder : private MutexType // (inherited so we can use the empty-base-class optimisation)
39 {
40  SingletonHolder() = default;
41 
43  {
44  /* The static singleton holder is being deleted before the object that it holds
45  has been deleted. This could mean that you've forgotten to call clearSingletonInstance()
46  in the class's destructor, or have failed to delete it before your app shuts down.
47  If you're having trouble cleaning up your singletons, perhaps consider using the
48  SharedResourcePointer class instead.
49  */
50  jassert (instance == nullptr);
51  }
52 
54  Type* get()
55  {
56  if (instance == nullptr)
57  {
58  typename MutexType::ScopedLockType sl (*this);
59 
60  if (instance == nullptr)
61  {
62  auto once = onlyCreateOncePerRun; // (local copy avoids VS compiler warning about this being constant)
63 
64  if (once)
65  {
66  static bool createdOnceAlready = false;
67 
68  if (createdOnceAlready)
69  {
70  // This means that the doNotRecreateAfterDeletion flag was set
71  // and you tried to create the singleton more than once.
72  jassertfalse;
73  return nullptr;
74  }
75 
76  createdOnceAlready = true;
77  }
78 
79  static bool alreadyInside = false;
80 
81  if (alreadyInside)
82  {
83  // This means that your object's constructor has done something which has
84  // ended up causing a recursive loop of singleton creation..
85  jassertfalse;
86  }
87  else
88  {
89  alreadyInside = true;
91  alreadyInside = false;
92  }
93  }
94  }
95 
96  return instance;
97  }
98 
103  {
104  if (instance == nullptr)
105  {
106  auto newObject = new Type(); // (create into a local so that instance is still null during construction)
107  instance = newObject;
108  }
109 
110  return instance;
111  }
112 
115  {
116  typename MutexType::ScopedLockType sl (*this);
117  auto old = instance;
118  instance = nullptr;
119  delete old;
120  }
121 
123  void clear (Type* expectedObject) noexcept
124  {
125  if (instance == expectedObject)
126  instance = nullptr;
127  }
128 
129  Type* instance = nullptr;
130 };
131 
132 
133 //==============================================================================
190 #define JUCE_DECLARE_SINGLETON(Classname, doNotRecreateAfterDeletion) \
191 \
192  static juce::SingletonHolder<Classname, juce::CriticalSection, doNotRecreateAfterDeletion> singletonHolder; \
193  friend decltype (singletonHolder); \
194 \
195  static Classname* JUCE_CALLTYPE getInstance() { return singletonHolder.get(); } \
196  static Classname* JUCE_CALLTYPE getInstanceWithoutCreating() noexcept { return singletonHolder.instance; } \
197  static void JUCE_CALLTYPE deleteInstance() noexcept { singletonHolder.deleteInstance(); } \
198  void clearSingletonInstance() noexcept { singletonHolder.clear (this); }
199 
200 
201 //==============================================================================
207 #define JUCE_IMPLEMENT_SINGLETON(Classname) \
208 \
209  decltype (Classname::singletonHolder) Classname::singletonHolder;
210 
211 
212 //==============================================================================
232 #define JUCE_DECLARE_SINGLETON_SINGLETHREADED(Classname, doNotRecreateAfterDeletion) \
233 \
234  static juce::SingletonHolder<Classname, juce::DummyCriticalSection, doNotRecreateAfterDeletion> singletonHolder; \
235  friend decltype (singletonHolder); \
236 \
237  static Classname* JUCE_CALLTYPE getInstance() { return singletonHolder.get(); } \
238  static Classname* JUCE_CALLTYPE getInstanceWithoutCreating() noexcept { return singletonHolder.instance; } \
239  static void JUCE_CALLTYPE deleteInstance() noexcept { singletonHolder.deleteInstance(); } \
240  void clearSingletonInstance() noexcept { singletonHolder.clear (this); }
241 
242 
243 //==============================================================================
258 #define JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL(Classname) \
259 \
260  static juce::SingletonHolder<Classname, juce::DummyCriticalSection, false> singletonHolder; \
261  friend decltype (singletonHolder); \
262 \
263  static Classname* JUCE_CALLTYPE getInstance() { return singletonHolder.getWithoutChecking(); } \
264  static Classname* JUCE_CALLTYPE getInstanceWithoutCreating() noexcept { return singletonHolder.instance; } \
265  static void JUCE_CALLTYPE deleteInstance() noexcept { singletonHolder.deleteInstance(); } \
266  void clearSingletonInstance() noexcept { singletonHolder.clear (this); }
267 
268 
269 //==============================================================================
270 #ifndef DOXYGEN
271  // These are ancient macros, and have now been updated with new names to match the JUCE style guide,
272  // so please update your code to use the newer versions!
273  #define juce_DeclareSingleton(Classname, doNotRecreate) JUCE_DECLARE_SINGLETON(Classname, doNotRecreate)
274  #define juce_DeclareSingleton_SingleThreaded(Classname, doNotRecreate) JUCE_DECLARE_SINGLETON_SINGLETHREADED(Classname, doNotRecreate)
275  #define juce_DeclareSingleton_SingleThreaded_Minimal(Classname) JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL(Classname)
276  #define juce_ImplementSingleton(Classname) JUCE_IMPLEMENT_SINGLETON(Classname)
277  #define juce_ImplementSingleton_SingleThreaded(Classname) JUCE_IMPLEMENT_SINGLETON(Classname)
278 #endif
279 
280 } // namespace juce
void clear(Type *expectedObject) noexcept