From cce448e7b028f4547ef174f711db797db9e57e60 Mon Sep 17 00:00:00 2001 From: jules Date: Thu, 28 Jun 2007 09:50:47 +0000 Subject: [PATCH] changes to make sure juce can re-initialise correctly after being de-initialised. --- .../juce_linux_Fonts.cpp | 14 ++--- .../platform_specific_code/juce_mac_Fonts.cpp | 2 +- .../juce_mac_Windowing.cpp | 13 ++-- .../juce_win32_Fonts.cpp | 15 ++--- .../juce_win32_Windowing.cpp | 38 ++++++------ .../wrapper/formats/VST/juce_VstWrapper.cpp | 2 +- .../jucer_FontPropertyComponent.cpp | 2 +- .../juce_AudioFormatManager.h | 2 +- .../audio/devices/juce_AudioDeviceManager.h | 1 + .../windows/juce_TopLevelWindow.cpp | 2 +- src/juce_core/basics/juce_Singleton.h | 61 +++++++++++++++++-- 11 files changed, 103 insertions(+), 49 deletions(-) diff --git a/build/linux/platform_specific_code/juce_linux_Fonts.cpp b/build/linux/platform_specific_code/juce_linux_Fonts.cpp index a2dd2cfad2..937b5b0201 100644 --- a/build/linux/platform_specific_code/juce_linux_Fonts.cpp +++ b/build/linux/platform_specific_code/juce_linux_Fonts.cpp @@ -158,6 +158,8 @@ public: if (ftLib != 0) FT_Done_FreeType (ftLib); + + clearSingletonInstance(); } //============================================================================== @@ -522,15 +524,7 @@ public: 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: //============================================================================== @@ -541,6 +535,8 @@ private: OwnedArray faces; }; +juce_ImplementSingleton_SingleThreaded (FreeTypeInterface); + //============================================================================== void Typeface::initialiseTypefaceCharacteristics (const String& fontName, diff --git a/build/macosx/platform_specific_code/juce_mac_Fonts.cpp b/build/macosx/platform_specific_code/juce_mac_Fonts.cpp index f0281d47a7..163a071694 100644 --- a/build/macosx/platform_specific_code/juce_mac_Fonts.cpp +++ b/build/macosx/platform_specific_code/juce_mac_Fonts.cpp @@ -384,7 +384,7 @@ public: delete this; } - juce_DeclareSingleton_SingleThreaded (ATSFontHelperCache, false) + juce_DeclareSingleton_SingleThreaded_Minimal (ATSFontHelperCache) }; juce_ImplementSingleton_SingleThreaded (ATSFontHelperCache) diff --git a/build/macosx/platform_specific_code/juce_mac_Windowing.cpp b/build/macosx/platform_specific_code/juce_mac_Windowing.cpp index e62012c542..86ebd5cce6 100644 --- a/build/macosx/platform_specific_code/juce_mac_Windowing.cpp +++ b/build/macosx/platform_specific_code/juce_mac_Windowing.cpp @@ -249,7 +249,7 @@ public: clearSingletonInstance(); } - juce_DeclareSingleton_SingleThreaded (MouseCheckTimer, false) + juce_DeclareSingleton_SingleThreaded_Minimal (MouseCheckTimer) bool hasEverHadAMouseMove; @@ -2540,6 +2540,9 @@ Image* juce_createIconForFile (const File& file) //============================================================================== +class MainMenuHandler; +static MainMenuHandler* mainMenu = 0; + class MainMenuHandler : private MenuBarModelListener, private DeletedAtShutdown { @@ -2552,6 +2555,9 @@ public: ~MainMenuHandler() throw() { setMenu (0); + + jassert (mainMenu == this); + mainMenu = 0; } void setMenu (MenuBarModel* const newMenuBarModel) throw() @@ -2795,15 +2801,14 @@ private: } }; -static MainMenuHandler* mainMenu = 0; - void MenuBarModel::setMacMainMenu (MenuBarModel* newMenuBarModel) throw() { if (getMacMainMenu() != newMenuBarModel) { if (newMenuBarModel == 0) { - deleteAndZero (mainMenu); + delete mainMenu; + jassert (mainMenu == 0); // should be zeroed in the destructor } else { diff --git a/build/win32/platform_specific_code/juce_win32_Fonts.cpp b/build/win32/platform_specific_code/juce_win32_Fonts.cpp index 4b1dffd530..073771424b 100644 --- a/build/win32/platform_specific_code/juce_win32_Fonts.cpp +++ b/build/win32/platform_specific_code/juce_win32_Fonts.cpp @@ -37,6 +37,7 @@ BEGIN_JUCE_NAMESPACE #include "../../../src/juce_appframework/gui/graphics/fonts/juce_Font.h" #include "../../../src/juce_appframework/application/juce_DeletedAtShutdown.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" @@ -285,18 +286,12 @@ public: DeleteObject (fontH); 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_, const bool bold_, @@ -455,6 +450,8 @@ public: } }; +juce_ImplementSingleton_SingleThreaded (FontDCHolder); + //============================================================================== static MAT2 identityMatrix; diff --git a/build/win32/platform_specific_code/juce_win32_Windowing.cpp b/build/win32/platform_specific_code/juce_win32_Windowing.cpp index acfdf2d5f8..539f94c292 100644 --- a/build/win32/platform_specific_code/juce_win32_Windowing.cpp +++ b/build/win32/platform_specific_code/juce_win32_Windowing.cpp @@ -69,6 +69,7 @@ BEGIN_JUCE_NAMESPACE #include "../../../src/juce_core/text/juce_StringArray.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/misc/juce_PlatformUtilities.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::rewindKey = 0x30003; + //============================================================================== class WindowsBitmapImage : public Image { @@ -944,7 +946,6 @@ private: BorderSize windowBorder; HICON currentWindowIcon; NOTIFYICONDATA* taskBarIcon; - friend class WindowClassHolder; //============================================================================== class TemporaryImage : public Timer @@ -993,12 +994,6 @@ private: TemporaryImage offscreenImageGenerator; //============================================================================== - static void* createWindowCallback (void* userData) - { - ((Win32ComponentPeer*) userData)->createWindow(); - return 0; - } - class WindowClassHolder : public DeletedAtShutdown { public: @@ -1017,7 +1012,7 @@ private: GetModuleFileName (moduleHandle, moduleFile, 1024); WORD iconNum = 0; -#if JUCE_ENABLE_WIN98_COMPATIBILITY + #if JUCE_ENABLE_WIN98_COMPATIBILITY if (wRegisterClassExW != 0) { WNDCLASSEXW wcex; @@ -1056,7 +1051,7 @@ private: RegisterClassEx (&wcex); } -#else + #else WNDCLASSEXW wcex; wcex.cbSize = sizeof (wcex); wcex.style = CS_OWNDC; @@ -1073,18 +1068,29 @@ private: wcex.lpszMenuName = 0; RegisterClassExW (&wcex); -#endif + #endif } ~WindowClassHolder() { if (ComponentPeer::getNumPeers() == 0) UnregisterClass (windowClassName, (HINSTANCE) PlatformUtilities::getCurrentModuleInstanceHandle()); + + clearSingletonInstance(); } String windowClassName; + + juce_DeclareSingleton_SingleThreaded_Minimal (WindowClassHolder); }; + //============================================================================== + static void* createWindowCallback (void* userData) + { + ((Win32ComponentPeer*) userData)->createWindow(); + return 0; + } + void createWindow() { DWORD exstyle = WS_EX_ACCEPTFILES; @@ -1131,18 +1137,15 @@ private: && Desktop::canUseSemiTransparentWindows()) exstyle |= WS_EX_LAYERED; - static WindowClassHolder* windowClassHolder = 0; - - if (windowClassHolder == 0) - windowClassHolder = new WindowClassHolder(); - #if JUCE_ENABLE_WIN98_COMPATIBILITY + const WindowClassHolder* const windowClassHolder = WindowClassHolder::getInstance(); + if (wCreateWindowExW != 0) hwnd = wCreateWindowExW (exstyle, windowClassHolder->windowClassName, L"", type, 0, 0, 0, 0, 0, 0, 0, 0); else hwnd = CreateWindowEx (exstyle, windowClassHolder->windowClassName, _T(""), type, 0, 0, 0, 0, 0, 0, 0, 0); #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 if (hwnd != 0) @@ -2188,12 +2191,13 @@ private: const Win32ComponentPeer& operator= (const Win32ComponentPeer&); }; - ComponentPeer* Component::createNewPeer (int styleFlags, void* /*nativeWindowToAttachTo*/) { return new Win32ComponentPeer (this, styleFlags); } +juce_ImplementSingleton_SingleThreaded (Win32ComponentPeer::WindowClassHolder); + //============================================================================== void SystemTrayIconComponent::setIconImage (const Image& newImage) { diff --git a/extras/audio plugins/wrapper/formats/VST/juce_VstWrapper.cpp b/extras/audio plugins/wrapper/formats/VST/juce_VstWrapper.cpp index 6391d7d8b3..90d159115a 100644 --- a/extras/audio plugins/wrapper/formats/VST/juce_VstWrapper.cpp +++ b/extras/audio plugins/wrapper/formats/VST/juce_VstWrapper.cpp @@ -194,7 +194,7 @@ public: messageManager->setCurrentMessageThread (originalThreadId); } - juce_DeclareSingleton (SharedMessageThread, true) + juce_DeclareSingleton (SharedMessageThread, false) }; juce_ImplementSingleton (SharedMessageThread); diff --git a/extras/the jucer/src/properties/jucer_FontPropertyComponent.cpp b/extras/the jucer/src/properties/jucer_FontPropertyComponent.cpp index 3d2a435d69..e1b7395161 100644 --- a/extras/the jucer/src/properties/jucer_FontPropertyComponent.cpp +++ b/extras/the jucer/src/properties/jucer_FontPropertyComponent.cpp @@ -51,7 +51,7 @@ public: clearSingletonInstance(); } - juce_DeclareSingleton_SingleThreaded (FontList, false) + juce_DeclareSingleton_SingleThreaded_Minimal (FontList) StringArray fontNames; }; diff --git a/src/juce_appframework/audio/audio_file_formats/juce_AudioFormatManager.h b/src/juce_appframework/audio/audio_file_formats/juce_AudioFormatManager.h index 7f388ed36a..97a711ec25 100644 --- a/src/juce_appframework/audio/audio_file_formats/juce_AudioFormatManager.h +++ b/src/juce_appframework/audio/audio_file_formats/juce_AudioFormatManager.h @@ -61,7 +61,7 @@ public: /** Destructor. */ ~AudioFormatManager(); - juce_DeclareSingleton (AudioFormatManager, true); + juce_DeclareSingleton (AudioFormatManager, false); //============================================================================== /** Adds a format to the manager's list of available file types. diff --git a/src/juce_appframework/audio/devices/juce_AudioDeviceManager.h b/src/juce_appframework/audio/devices/juce_AudioDeviceManager.h index be148a9e88..4eb3754838 100644 --- a/src/juce_appframework/audio/devices/juce_AudioDeviceManager.h +++ b/src/juce_appframework/audio/devices/juce_AudioDeviceManager.h @@ -34,6 +34,7 @@ #include "juce_AudioIODeviceType.h" #include "juce_MidiInput.h" +#include "juce_MidiOutput.h" #include "../../../juce_core/text/juce_XmlElement.h" #include "../../gui/components/controls/juce_ComboBox.h" diff --git a/src/juce_appframework/gui/components/windows/juce_TopLevelWindow.cpp b/src/juce_appframework/gui/components/windows/juce_TopLevelWindow.cpp index f0e6618ad6..64173dc67e 100644 --- a/src/juce_appframework/gui/components/windows/juce_TopLevelWindow.cpp +++ b/src/juce_appframework/gui/components/windows/juce_TopLevelWindow.cpp @@ -61,7 +61,7 @@ public: clearSingletonInstance(); } - juce_DeclareSingleton_SingleThreaded (TopLevelWindowManager, false) + juce_DeclareSingleton_SingleThreaded_Minimal (TopLevelWindowManager) void timerCallback() { diff --git a/src/juce_core/basics/juce_Singleton.h b/src/juce_core/basics/juce_Singleton.h index 8c29a06e2d..dea9032840 100644 --- a/src/juce_core/basics/juce_Singleton.h +++ b/src/juce_core/basics/juce_Singleton.h @@ -109,7 +109,7 @@ static bool createdOnceAlready = false; \ \ const bool problem = alreadyInside || ((allowOnlyOneInstance) && createdOnceAlready); \ - jassert (!problem); \ + jassert (! problem); \ if (! problem) \ { \ createdOnceAlready = true; \ @@ -173,7 +173,7 @@ 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 + @see juce_ImplementSingleton_SingleThreaded, juce_DeclareSingleton, juce_DeclareSingleton_SingleThreaded_Minimal */ #define juce_DeclareSingleton_SingleThreaded(classname, allowOnlyOneInstance) \ \ @@ -187,7 +187,7 @@ static bool createdOnceAlready = false; \ \ const bool problem = alreadyInside || ((allowOnlyOneInstance) && createdOnceAlready); \ - jassert (!problem); \ + jassert (! problem); \ if (! problem) \ { \ createdOnceAlready = true; \ @@ -223,12 +223,63 @@ _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. - 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) \ \