OpenShot Audio Library | OpenShotAudio 0.3.2
Loading...
Searching...
No Matches
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
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 == 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
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