OpenShot Audio Library | OpenShotAudio 0.4.0
juce_Singleton.h
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
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
23namespace juce
24{
25
26//==============================================================================
37template <typename Type, typename MutexType, bool onlyCreateOncePerRun>
38struct 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.load() == nullptr);
51 }
52
54 Type* get()
55 {
56 if (auto* ptr = instance.load())
57 return ptr;
58
59 typename MutexType::ScopedLockType sl (*this);
60
61 if (auto* ptr = instance.load())
62 return ptr;
63
64 auto once = onlyCreateOncePerRun; // (local copy avoids VS compiler warning about this being constant)
65
66 if (once)
67 {
68 static bool createdOnceAlready = false;
69
70 if (createdOnceAlready)
71 {
72 // This means that the doNotRecreateAfterDeletion flag was set
73 // and you tried to create the singleton more than once.
74 jassertfalse;
75 return nullptr;
76 }
77
78 createdOnceAlready = true;
79 }
80
81 static bool alreadyInside = false;
82
83 if (alreadyInside)
84 {
85 // This means that your object's constructor has done something which has
86 // ended up causing a recursive loop of singleton creation.
87 jassertfalse;
88 return nullptr;
89 }
90
91 const ScopedValueSetter<bool> scope (alreadyInside, true);
92 return getWithoutChecking();
93 }
94
99 {
100 if (auto* p = instance.load())
101 return p;
102
103 auto* newObject = new Type(); // (create into a local so that instance is still null during construction)
104 instance.store (newObject);
105 return newObject;
106 }
107
110 {
111 typename MutexType::ScopedLockType sl (*this);
112 delete instance.exchange (nullptr);
113 }
114
116 void clear (Type* expectedObject) noexcept
117 {
118 instance.compare_exchange_strong (expectedObject, nullptr);
119 }
120
121 // This must be atomic, otherwise a late call to get() may attempt to read instance while it is
122 // being modified by the very first call to get().
123 std::atomic<Type*> instance { nullptr };
124};
125
126
127//==============================================================================
184#define JUCE_DECLARE_SINGLETON(Classname, doNotRecreateAfterDeletion) \
185\
186 static juce::SingletonHolder<Classname, juce::CriticalSection, doNotRecreateAfterDeletion> singletonHolder; \
187 friend juce::SingletonHolder<Classname, juce::CriticalSection, doNotRecreateAfterDeletion>; \
188\
189 static Classname* JUCE_CALLTYPE getInstance() { return singletonHolder.get(); } \
190 static Classname* JUCE_CALLTYPE getInstanceWithoutCreating() noexcept { return singletonHolder.instance; } \
191 static void JUCE_CALLTYPE deleteInstance() noexcept { singletonHolder.deleteInstance(); } \
192 void clearSingletonInstance() noexcept { singletonHolder.clear (this); }
193
194
195//==============================================================================
201#define JUCE_IMPLEMENT_SINGLETON(Classname) \
202\
203 decltype (Classname::singletonHolder) Classname::singletonHolder;
204
205
206//==============================================================================
226#define JUCE_DECLARE_SINGLETON_SINGLETHREADED(Classname, doNotRecreateAfterDeletion) \
227\
228 static juce::SingletonHolder<Classname, juce::DummyCriticalSection, doNotRecreateAfterDeletion> singletonHolder; \
229 friend decltype (singletonHolder); \
230\
231 static Classname* JUCE_CALLTYPE getInstance() { return singletonHolder.get(); } \
232 static Classname* JUCE_CALLTYPE getInstanceWithoutCreating() noexcept { return singletonHolder.instance; } \
233 static void JUCE_CALLTYPE deleteInstance() noexcept { singletonHolder.deleteInstance(); } \
234 void clearSingletonInstance() noexcept { singletonHolder.clear (this); }
235
236
237//==============================================================================
252#define JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL(Classname) \
253\
254 static juce::SingletonHolder<Classname, juce::DummyCriticalSection, false> singletonHolder; \
255 friend decltype (singletonHolder); \
256\
257 static Classname* JUCE_CALLTYPE getInstance() { return singletonHolder.getWithoutChecking(); } \
258 static Classname* JUCE_CALLTYPE getInstanceWithoutCreating() noexcept { return singletonHolder.instance; } \
259 static void JUCE_CALLTYPE deleteInstance() noexcept { singletonHolder.deleteInstance(); } \
260 void clearSingletonInstance() noexcept { singletonHolder.clear (this); }
261
262
263//==============================================================================
264#ifndef DOXYGEN
265 // These are ancient macros, and have now been updated with new names to match the JUCE style guide,
266 // so please update your code to use the newer versions!
267 #define juce_DeclareSingleton(Classname, doNotRecreate) JUCE_DECLARE_SINGLETON(Classname, doNotRecreate)
268 #define juce_DeclareSingleton_SingleThreaded(Classname, doNotRecreate) JUCE_DECLARE_SINGLETON_SINGLETHREADED(Classname, doNotRecreate)
269 #define juce_DeclareSingleton_SingleThreaded_Minimal(Classname) JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL(Classname)
270 #define juce_ImplementSingleton(Classname) JUCE_IMPLEMENT_SINGLETON(Classname)
271 #define juce_ImplementSingleton_SingleThreaded(Classname) JUCE_IMPLEMENT_SINGLETON(Classname)
272#endif
273
274} // namespace juce
void clear(Type *expectedObject) noexcept