| @@ -158,6 +158,8 @@ public: | |||||
| if (ftLib != 0) | if (ftLib != 0) | ||||
| FT_Done_FreeType (ftLib); | FT_Done_FreeType (ftLib); | ||||
| clearSingletonInstance(); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -522,15 +524,7 @@ public: | |||||
| sansSerif.add (faces[i]->getFamilyName()); | sansSerif.add (faces[i]->getFamilyName()); | ||||
| } | } | ||||
| static FreeTypeInterface* getInstance() | |||||
| { | |||||
| static FreeTypeInterface* instance = 0; | |||||
| if (instance == 0) | |||||
| instance = new FreeTypeInterface(); | |||||
| return instance; | |||||
| } | |||||
| juce_DeclareSingleton_SingleThreaded_Minimal (FreeTypeInterface, false); | |||||
| private: | private: | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -541,6 +535,8 @@ private: | |||||
| OwnedArray<FreeTypeFontFace> faces; | OwnedArray<FreeTypeFontFace> faces; | ||||
| }; | }; | ||||
| juce_ImplementSingleton_SingleThreaded (FreeTypeInterface); | |||||
| //============================================================================== | //============================================================================== | ||||
| void Typeface::initialiseTypefaceCharacteristics (const String& fontName, | void Typeface::initialiseTypefaceCharacteristics (const String& fontName, | ||||
| @@ -384,7 +384,7 @@ public: | |||||
| delete this; | delete this; | ||||
| } | } | ||||
| juce_DeclareSingleton_SingleThreaded (ATSFontHelperCache, false) | |||||
| juce_DeclareSingleton_SingleThreaded_Minimal (ATSFontHelperCache) | |||||
| }; | }; | ||||
| juce_ImplementSingleton_SingleThreaded (ATSFontHelperCache) | juce_ImplementSingleton_SingleThreaded (ATSFontHelperCache) | ||||
| @@ -249,7 +249,7 @@ public: | |||||
| clearSingletonInstance(); | clearSingletonInstance(); | ||||
| } | } | ||||
| juce_DeclareSingleton_SingleThreaded (MouseCheckTimer, false) | |||||
| juce_DeclareSingleton_SingleThreaded_Minimal (MouseCheckTimer) | |||||
| bool hasEverHadAMouseMove; | bool hasEverHadAMouseMove; | ||||
| @@ -2540,6 +2540,9 @@ Image* juce_createIconForFile (const File& file) | |||||
| //============================================================================== | //============================================================================== | ||||
| class MainMenuHandler; | |||||
| static MainMenuHandler* mainMenu = 0; | |||||
| class MainMenuHandler : private MenuBarModelListener, | class MainMenuHandler : private MenuBarModelListener, | ||||
| private DeletedAtShutdown | private DeletedAtShutdown | ||||
| { | { | ||||
| @@ -2552,6 +2555,9 @@ public: | |||||
| ~MainMenuHandler() throw() | ~MainMenuHandler() throw() | ||||
| { | { | ||||
| setMenu (0); | setMenu (0); | ||||
| jassert (mainMenu == this); | |||||
| mainMenu = 0; | |||||
| } | } | ||||
| void setMenu (MenuBarModel* const newMenuBarModel) throw() | void setMenu (MenuBarModel* const newMenuBarModel) throw() | ||||
| @@ -2795,15 +2801,14 @@ private: | |||||
| } | } | ||||
| }; | }; | ||||
| static MainMenuHandler* mainMenu = 0; | |||||
| void MenuBarModel::setMacMainMenu (MenuBarModel* newMenuBarModel) throw() | void MenuBarModel::setMacMainMenu (MenuBarModel* newMenuBarModel) throw() | ||||
| { | { | ||||
| if (getMacMainMenu() != newMenuBarModel) | if (getMacMainMenu() != newMenuBarModel) | ||||
| { | { | ||||
| if (newMenuBarModel == 0) | if (newMenuBarModel == 0) | ||||
| { | { | ||||
| deleteAndZero (mainMenu); | |||||
| delete mainMenu; | |||||
| jassert (mainMenu == 0); // should be zeroed in the destructor | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -37,6 +37,7 @@ BEGIN_JUCE_NAMESPACE | |||||
| #include "../../../src/juce_appframework/gui/graphics/fonts/juce_Font.h" | #include "../../../src/juce_appframework/gui/graphics/fonts/juce_Font.h" | ||||
| #include "../../../src/juce_appframework/application/juce_DeletedAtShutdown.h" | #include "../../../src/juce_appframework/application/juce_DeletedAtShutdown.h" | ||||
| #include "../../../src/juce_core/basics/juce_SystemStats.h" | #include "../../../src/juce_core/basics/juce_SystemStats.h" | ||||
| #include "../../../src/juce_core/basics/juce_Singleton.h" | |||||
| #include "../../../src/juce_appframework/gui/graphics/imaging/juce_Image.h" | #include "../../../src/juce_appframework/gui/graphics/imaging/juce_Image.h" | ||||
| @@ -285,18 +286,12 @@ public: | |||||
| DeleteObject (fontH); | DeleteObject (fontH); | ||||
| juce_free (kps); | juce_free (kps); | ||||
| } | } | ||||
| } | |||||
| static FontDCHolder* getInstance() throw() | |||||
| { | |||||
| static FontDCHolder* instance = 0; | |||||
| if (instance == 0) | |||||
| instance = new FontDCHolder(); | |||||
| return instance; | |||||
| clearSingletonInstance(); | |||||
| } | } | ||||
| juce_DeclareSingleton_SingleThreaded_Minimal (FontDCHolder); | |||||
| //============================================================================== | //============================================================================== | ||||
| HDC loadFont (const String& fontName_, | HDC loadFont (const String& fontName_, | ||||
| const bool bold_, | const bool bold_, | ||||
| @@ -455,6 +450,8 @@ public: | |||||
| } | } | ||||
| }; | }; | ||||
| juce_ImplementSingleton_SingleThreaded (FontDCHolder); | |||||
| //============================================================================== | //============================================================================== | ||||
| static MAT2 identityMatrix; | static MAT2 identityMatrix; | ||||
| @@ -69,6 +69,7 @@ BEGIN_JUCE_NAMESPACE | |||||
| #include "../../../src/juce_core/text/juce_StringArray.h" | #include "../../../src/juce_core/text/juce_StringArray.h" | ||||
| #include "../../../src/juce_core/basics/juce_SystemStats.h" | #include "../../../src/juce_core/basics/juce_SystemStats.h" | ||||
| #include "../../../src/juce_core/basics/juce_Singleton.h" | |||||
| #include "../../../src/juce_core/threads/juce_Process.h" | #include "../../../src/juce_core/threads/juce_Process.h" | ||||
| #include "../../../src/juce_core/misc/juce_PlatformUtilities.h" | #include "../../../src/juce_core/misc/juce_PlatformUtilities.h" | ||||
| #include "../../../src/juce_appframework/events/juce_Timer.h" | #include "../../../src/juce_appframework/events/juce_Timer.h" | ||||
| @@ -225,6 +226,7 @@ const int KeyPress::stopKey = 0x30001; | |||||
| const int KeyPress::fastForwardKey = 0x30002; | const int KeyPress::fastForwardKey = 0x30002; | ||||
| const int KeyPress::rewindKey = 0x30003; | const int KeyPress::rewindKey = 0x30003; | ||||
| //============================================================================== | //============================================================================== | ||||
| class WindowsBitmapImage : public Image | class WindowsBitmapImage : public Image | ||||
| { | { | ||||
| @@ -944,7 +946,6 @@ private: | |||||
| BorderSize windowBorder; | BorderSize windowBorder; | ||||
| HICON currentWindowIcon; | HICON currentWindowIcon; | ||||
| NOTIFYICONDATA* taskBarIcon; | NOTIFYICONDATA* taskBarIcon; | ||||
| friend class WindowClassHolder; | |||||
| //============================================================================== | //============================================================================== | ||||
| class TemporaryImage : public Timer | class TemporaryImage : public Timer | ||||
| @@ -993,12 +994,6 @@ private: | |||||
| TemporaryImage offscreenImageGenerator; | TemporaryImage offscreenImageGenerator; | ||||
| //============================================================================== | //============================================================================== | ||||
| static void* createWindowCallback (void* userData) | |||||
| { | |||||
| ((Win32ComponentPeer*) userData)->createWindow(); | |||||
| return 0; | |||||
| } | |||||
| class WindowClassHolder : public DeletedAtShutdown | class WindowClassHolder : public DeletedAtShutdown | ||||
| { | { | ||||
| public: | public: | ||||
| @@ -1017,7 +1012,7 @@ private: | |||||
| GetModuleFileName (moduleHandle, moduleFile, 1024); | GetModuleFileName (moduleHandle, moduleFile, 1024); | ||||
| WORD iconNum = 0; | WORD iconNum = 0; | ||||
| #if JUCE_ENABLE_WIN98_COMPATIBILITY | |||||
| #if JUCE_ENABLE_WIN98_COMPATIBILITY | |||||
| if (wRegisterClassExW != 0) | if (wRegisterClassExW != 0) | ||||
| { | { | ||||
| WNDCLASSEXW wcex; | WNDCLASSEXW wcex; | ||||
| @@ -1056,7 +1051,7 @@ private: | |||||
| RegisterClassEx (&wcex); | RegisterClassEx (&wcex); | ||||
| } | } | ||||
| #else | |||||
| #else | |||||
| WNDCLASSEXW wcex; | WNDCLASSEXW wcex; | ||||
| wcex.cbSize = sizeof (wcex); | wcex.cbSize = sizeof (wcex); | ||||
| wcex.style = CS_OWNDC; | wcex.style = CS_OWNDC; | ||||
| @@ -1073,18 +1068,29 @@ private: | |||||
| wcex.lpszMenuName = 0; | wcex.lpszMenuName = 0; | ||||
| RegisterClassExW (&wcex); | RegisterClassExW (&wcex); | ||||
| #endif | |||||
| #endif | |||||
| } | } | ||||
| ~WindowClassHolder() | ~WindowClassHolder() | ||||
| { | { | ||||
| if (ComponentPeer::getNumPeers() == 0) | if (ComponentPeer::getNumPeers() == 0) | ||||
| UnregisterClass (windowClassName, (HINSTANCE) PlatformUtilities::getCurrentModuleInstanceHandle()); | UnregisterClass (windowClassName, (HINSTANCE) PlatformUtilities::getCurrentModuleInstanceHandle()); | ||||
| clearSingletonInstance(); | |||||
| } | } | ||||
| String windowClassName; | String windowClassName; | ||||
| juce_DeclareSingleton_SingleThreaded_Minimal (WindowClassHolder); | |||||
| }; | }; | ||||
| //============================================================================== | |||||
| static void* createWindowCallback (void* userData) | |||||
| { | |||||
| ((Win32ComponentPeer*) userData)->createWindow(); | |||||
| return 0; | |||||
| } | |||||
| void createWindow() | void createWindow() | ||||
| { | { | ||||
| DWORD exstyle = WS_EX_ACCEPTFILES; | DWORD exstyle = WS_EX_ACCEPTFILES; | ||||
| @@ -1131,18 +1137,15 @@ private: | |||||
| && Desktop::canUseSemiTransparentWindows()) | && Desktop::canUseSemiTransparentWindows()) | ||||
| exstyle |= WS_EX_LAYERED; | exstyle |= WS_EX_LAYERED; | ||||
| static WindowClassHolder* windowClassHolder = 0; | |||||
| if (windowClassHolder == 0) | |||||
| windowClassHolder = new WindowClassHolder(); | |||||
| #if JUCE_ENABLE_WIN98_COMPATIBILITY | #if JUCE_ENABLE_WIN98_COMPATIBILITY | ||||
| const WindowClassHolder* const windowClassHolder = WindowClassHolder::getInstance(); | |||||
| if (wCreateWindowExW != 0) | if (wCreateWindowExW != 0) | ||||
| hwnd = wCreateWindowExW (exstyle, windowClassHolder->windowClassName, L"", type, 0, 0, 0, 0, 0, 0, 0, 0); | hwnd = wCreateWindowExW (exstyle, windowClassHolder->windowClassName, L"", type, 0, 0, 0, 0, 0, 0, 0, 0); | ||||
| else | else | ||||
| hwnd = CreateWindowEx (exstyle, windowClassHolder->windowClassName, _T(""), type, 0, 0, 0, 0, 0, 0, 0, 0); | hwnd = CreateWindowEx (exstyle, windowClassHolder->windowClassName, _T(""), type, 0, 0, 0, 0, 0, 0, 0, 0); | ||||
| #else | #else | ||||
| hwnd = CreateWindowExW (exstyle, windowClassHolder->windowClassName, L"", type, 0, 0, 0, 0, 0, 0, 0, 0); | |||||
| hwnd = CreateWindowExW (exstyle, WindowClassHolder::getInstance()->windowClassName, L"", type, 0, 0, 0, 0, 0, 0, 0, 0); | |||||
| #endif | #endif | ||||
| if (hwnd != 0) | if (hwnd != 0) | ||||
| @@ -2188,12 +2191,13 @@ private: | |||||
| const Win32ComponentPeer& operator= (const Win32ComponentPeer&); | const Win32ComponentPeer& operator= (const Win32ComponentPeer&); | ||||
| }; | }; | ||||
| ComponentPeer* Component::createNewPeer (int styleFlags, void* /*nativeWindowToAttachTo*/) | ComponentPeer* Component::createNewPeer (int styleFlags, void* /*nativeWindowToAttachTo*/) | ||||
| { | { | ||||
| return new Win32ComponentPeer (this, styleFlags); | return new Win32ComponentPeer (this, styleFlags); | ||||
| } | } | ||||
| juce_ImplementSingleton_SingleThreaded (Win32ComponentPeer::WindowClassHolder); | |||||
| //============================================================================== | //============================================================================== | ||||
| void SystemTrayIconComponent::setIconImage (const Image& newImage) | void SystemTrayIconComponent::setIconImage (const Image& newImage) | ||||
| { | { | ||||
| @@ -194,7 +194,7 @@ public: | |||||
| messageManager->setCurrentMessageThread (originalThreadId); | messageManager->setCurrentMessageThread (originalThreadId); | ||||
| } | } | ||||
| juce_DeclareSingleton (SharedMessageThread, true) | |||||
| juce_DeclareSingleton (SharedMessageThread, false) | |||||
| }; | }; | ||||
| juce_ImplementSingleton (SharedMessageThread); | juce_ImplementSingleton (SharedMessageThread); | ||||
| @@ -51,7 +51,7 @@ public: | |||||
| clearSingletonInstance(); | clearSingletonInstance(); | ||||
| } | } | ||||
| juce_DeclareSingleton_SingleThreaded (FontList, false) | |||||
| juce_DeclareSingleton_SingleThreaded_Minimal (FontList) | |||||
| StringArray fontNames; | StringArray fontNames; | ||||
| }; | }; | ||||
| @@ -61,7 +61,7 @@ public: | |||||
| /** Destructor. */ | /** Destructor. */ | ||||
| ~AudioFormatManager(); | ~AudioFormatManager(); | ||||
| juce_DeclareSingleton (AudioFormatManager, true); | |||||
| juce_DeclareSingleton (AudioFormatManager, false); | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Adds a format to the manager's list of available file types. | /** Adds a format to the manager's list of available file types. | ||||
| @@ -34,6 +34,7 @@ | |||||
| #include "juce_AudioIODeviceType.h" | #include "juce_AudioIODeviceType.h" | ||||
| #include "juce_MidiInput.h" | #include "juce_MidiInput.h" | ||||
| #include "juce_MidiOutput.h" | |||||
| #include "../../../juce_core/text/juce_XmlElement.h" | #include "../../../juce_core/text/juce_XmlElement.h" | ||||
| #include "../../gui/components/controls/juce_ComboBox.h" | #include "../../gui/components/controls/juce_ComboBox.h" | ||||
| @@ -61,7 +61,7 @@ public: | |||||
| clearSingletonInstance(); | clearSingletonInstance(); | ||||
| } | } | ||||
| juce_DeclareSingleton_SingleThreaded (TopLevelWindowManager, false) | |||||
| juce_DeclareSingleton_SingleThreaded_Minimal (TopLevelWindowManager) | |||||
| void timerCallback() | void timerCallback() | ||||
| { | { | ||||
| @@ -109,7 +109,7 @@ | |||||
| static bool createdOnceAlready = false; \ | static bool createdOnceAlready = false; \ | ||||
| \ | \ | ||||
| const bool problem = alreadyInside || ((allowOnlyOneInstance) && createdOnceAlready); \ | const bool problem = alreadyInside || ((allowOnlyOneInstance) && createdOnceAlready); \ | ||||
| jassert (!problem); \ | |||||
| jassert (! problem); \ | |||||
| if (! problem) \ | if (! problem) \ | ||||
| { \ | { \ | ||||
| createdOnceAlready = true; \ | createdOnceAlready = true; \ | ||||
| @@ -173,7 +173,7 @@ | |||||
| how to use it, the only difference being that you have to use | how to use it, the only difference being that you have to use | ||||
| juce_ImplementSingleton_SingleThreaded instead of juce_ImplementSingleton. | juce_ImplementSingleton_SingleThreaded instead of juce_ImplementSingleton. | ||||
| @see juce_ImplementSingleton_SingleThreaded, juce_DeclareSingleton | |||||
| @see juce_ImplementSingleton_SingleThreaded, juce_DeclareSingleton, juce_DeclareSingleton_SingleThreaded_Minimal | |||||
| */ | */ | ||||
| #define juce_DeclareSingleton_SingleThreaded(classname, allowOnlyOneInstance) \ | #define juce_DeclareSingleton_SingleThreaded(classname, allowOnlyOneInstance) \ | ||||
| \ | \ | ||||
| @@ -187,7 +187,7 @@ | |||||
| static bool createdOnceAlready = false; \ | static bool createdOnceAlready = false; \ | ||||
| \ | \ | ||||
| const bool problem = alreadyInside || ((allowOnlyOneInstance) && createdOnceAlready); \ | const bool problem = alreadyInside || ((allowOnlyOneInstance) && createdOnceAlready); \ | ||||
| jassert (!problem); \ | |||||
| jassert (! problem); \ | |||||
| if (! problem) \ | if (! problem) \ | ||||
| { \ | { \ | ||||
| createdOnceAlready = true; \ | createdOnceAlready = true; \ | ||||
| @@ -223,12 +223,63 @@ | |||||
| _singletonInstance = 0; \ | _singletonInstance = 0; \ | ||||
| } | } | ||||
| //============================================================================== | |||||
| /** | |||||
| Macro to declare member variables and methods for a singleton class. | |||||
| This is like juce_DeclareSingleton_SingleThreaded, but doesn't do any checking | |||||
| for recursion or repeated instantiation. It's intended for use as a lightweight | |||||
| version of a singleton, where you're using it in very straightforward | |||||
| circumstances and don't need the extra checking. | |||||
| Juce use the normal juce_ImplementSingleton_SingleThreaded as the counterpart | |||||
| to this declaration, as you would with juce_DeclareSingleton_SingleThreaded. | |||||
| See the documentation for juce_DeclareSingleton for more information about | |||||
| how to use it, the only difference being that you have to use | |||||
| juce_ImplementSingleton_SingleThreaded instead of juce_ImplementSingleton. | |||||
| @see juce_ImplementSingleton_SingleThreaded, juce_DeclareSingleton | |||||
| */ | |||||
| #define juce_DeclareSingleton_SingleThreaded_Minimal(classname) \ | |||||
| \ | |||||
| static classname* _singletonInstance; \ | |||||
| \ | |||||
| static classname* getInstance() \ | |||||
| { \ | |||||
| if (_singletonInstance == 0) \ | |||||
| _singletonInstance = new classname(); \ | |||||
| \ | |||||
| return _singletonInstance; \ | |||||
| } \ | |||||
| \ | |||||
| static inline classname* getInstanceWithoutCreating() throw() \ | |||||
| { \ | |||||
| return _singletonInstance; \ | |||||
| } \ | |||||
| \ | |||||
| static void deleteInstance() \ | |||||
| { \ | |||||
| if (_singletonInstance != 0) \ | |||||
| { \ | |||||
| classname* const old = _singletonInstance; \ | |||||
| _singletonInstance = 0; \ | |||||
| delete old; \ | |||||
| } \ | |||||
| } \ | |||||
| \ | |||||
| void clearSingletonInstance() throw() \ | |||||
| { \ | |||||
| if (_singletonInstance == this) \ | |||||
| _singletonInstance = 0; \ | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| /** This is a counterpart to the juce_DeclareSingleton_SingleThreaded macro. | /** This is a counterpart to the juce_DeclareSingleton_SingleThreaded macro. | ||||
| After adding the juce_DeclareSingleton_SingleThreaded to the class definition, | |||||
| this macro has to be used in the cpp file. | |||||
| After adding juce_DeclareSingleton_SingleThreaded or juce_DeclareSingleton_SingleThreaded_Minimal | |||||
| to the class definition, this macro has to be used somewhere in the cpp file. | |||||
| */ | */ | ||||
| #define juce_ImplementSingleton_SingleThreaded(classname) \ | #define juce_ImplementSingleton_SingleThreaded(classname) \ | ||||
| \ | \ | ||||