1 /* 2 ============================================================================== 3 4 This file is part of the JUCE library. 5 Copyright (c) 2020 - 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 23 namespace juce 24 { 25 26 //============================================================================== 27 /** 28 Used by the JUCE_DECLARE_SINGLETON macros to manage a static pointer 29 to a singleton instance. 30 31 You generally won't use this directly, but see the macros JUCE_DECLARE_SINGLETON, 32 JUCE_DECLARE_SINGLETON_SINGLETHREADED, JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL, 33 and JUCE_IMPLEMENT_SINGLETON for how it is intended to be used. 34 35 @tags{Core} 36 */ 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 ~SingletonHolderSingletonHolder42 ~SingletonHolder() 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 53 /** Returns the current instance, or creates a new instance if there isn't one. */ getSingletonHolder54 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; 90 getWithoutChecking(); 91 alreadyInside = false; 92 } 93 } 94 } 95 96 return instance; 97 } 98 99 /** Returns the current instance, or creates a new instance if there isn't one, but doesn't do 100 any locking, or checking for recursion or error conditions. 101 */ getWithoutCheckingSingletonHolder102 Type* getWithoutChecking() 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 113 /** Deletes and resets the current instance, if there is one. */ deleteInstanceSingletonHolder114 void deleteInstance() 115 { 116 typename MutexType::ScopedLockType sl (*this); 117 auto old = instance; 118 instance = nullptr; 119 delete old; 120 } 121 122 /** Called by the class's destructor to clear the pointer if it is currently set to the given object. */ clearSingletonHolder123 void clear (Type* expectedObject) noexcept 124 { 125 if (instance == expectedObject) 126 instance = nullptr; 127 } 128 129 Type* instance = nullptr; 130 }; 131 132 133 //============================================================================== 134 /** 135 Macro to generate the appropriate methods and boilerplate for a singleton class. 136 137 To use this, add the line JUCE_DECLARE_SINGLETON(MyClass, doNotRecreateAfterDeletion) 138 to the class's definition. 139 140 Then put a macro JUCE_IMPLEMENT_SINGLETON(MyClass) along with the class's 141 implementation code. 142 143 It's also a very good idea to also add the call clearSingletonInstance() in your class's 144 destructor, in case it is deleted by other means than deleteInstance() 145 146 Clients can then call the static method MyClass::getInstance() to get a pointer 147 to the singleton, or MyClass::getInstanceWithoutCreating() which will return nullptr if 148 no instance currently exists. 149 150 e.g. @code 151 152 struct MySingleton 153 { 154 MySingleton() {} 155 156 ~MySingleton() 157 { 158 // this ensures that no dangling pointers are left when the 159 // singleton is deleted. 160 clearSingletonInstance(); 161 } 162 163 JUCE_DECLARE_SINGLETON (MySingleton, false) 164 }; 165 166 // ..and this goes in a suitable .cpp file: 167 JUCE_IMPLEMENT_SINGLETON (MySingleton) 168 169 170 // example of usage: 171 auto* m = MySingleton::getInstance(); // creates the singleton if there isn't already one. 172 173 ... 174 175 MySingleton::deleteInstance(); // safely deletes the singleton (if it's been created). 176 177 @endcode 178 179 If doNotRecreateAfterDeletion = true, it won't allow the object to be created more 180 than once during the process's lifetime - i.e. after you've created and deleted the 181 object, getInstance() will refuse to create another one. This can be useful to stop 182 objects being accidentally re-created during your app's shutdown code. 183 184 If you know that your object will only be created and deleted by a single thread, you 185 can use the slightly more efficient JUCE_DECLARE_SINGLETON_SINGLETHREADED macro instead 186 of this one. 187 188 @see JUCE_IMPLEMENT_SINGLETON, JUCE_DECLARE_SINGLETON_SINGLETHREADED 189 */ 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 //============================================================================== 202 /** This is a counterpart to the JUCE_DECLARE_SINGLETON macros. 203 204 After adding the JUCE_DECLARE_SINGLETON to the class definition, this macro has 205 to be used in the cpp file. 206 */ 207 #define JUCE_IMPLEMENT_SINGLETON(Classname) \ 208 \ 209 decltype (Classname::singletonHolder) Classname::singletonHolder; 210 211 212 //============================================================================== 213 /** 214 Macro to declare member variables and methods for a singleton class. 215 216 This is exactly the same as JUCE_DECLARE_SINGLETON, but doesn't use a critical 217 section to make access to it thread-safe. If you know that your object will 218 only ever be created or deleted by a single thread, then this is a 219 more efficient version to use. 220 221 If doNotRecreateAfterDeletion = true, it won't allow the object to be created more 222 than once during the process's lifetime - i.e. after you've created and deleted the 223 object, getInstance() will refuse to create another one. This can be useful to stop 224 objects being accidentally re-created during your app's shutdown code. 225 226 See the documentation for JUCE_DECLARE_SINGLETON for more information about 227 how to use it. Just like JUCE_DECLARE_SINGLETON you need to also have a 228 corresponding JUCE_IMPLEMENT_SINGLETON statement somewhere in your code. 229 230 @see JUCE_IMPLEMENT_SINGLETON, JUCE_DECLARE_SINGLETON, JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL 231 */ 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 //============================================================================== 244 /** 245 Macro to declare member variables and methods for a singleton class. 246 247 This is like JUCE_DECLARE_SINGLETON_SINGLETHREADED, but doesn't do any checking 248 for recursion or repeated instantiation. It's intended for use as a lightweight 249 version of a singleton, where you're using it in very straightforward 250 circumstances and don't need the extra checking. 251 252 See the documentation for JUCE_DECLARE_SINGLETON for more information about 253 how to use it. Just like JUCE_DECLARE_SINGLETON you need to also have a 254 corresponding JUCE_IMPLEMENT_SINGLETON statement somewhere in your code. 255 256 @see JUCE_IMPLEMENT_SINGLETON, JUCE_DECLARE_SINGLETON 257 */ 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 281