From e159587a9bb1d3e2d00c479834e3087b60884e24 Mon Sep 17 00:00:00 2001 From: Julian Storer Date: Thu, 21 Apr 2011 12:20:08 +0100 Subject: [PATCH] Decentralised some initialisation code. Minor fixes for Array, Component, iOS fonts. --- .../Project/jucer_ProjectExport_XCode.h | 2 +- .../iOS/Juce Demo.xcodeproj/project.pbxproj | 4 + .../iOS/HelloWorld.xcodeproj/project.pbxproj | 4 + juce_amalgamated.cpp | 400 ++++++++++-------- juce_amalgamated.h | 28 +- src/containers/juce_Array.h | 2 +- src/core/juce_Initialisation.cpp | 39 -- src/core/juce_StandardHeader.h | 2 +- src/core/juce_SystemStats.cpp | 19 +- src/core/juce_SystemStats.h | 19 +- src/cryptography/juce_Primes.cpp | 2 +- src/gui/components/juce_Component.cpp | 7 +- src/io/streams/juce_OutputStream.cpp | 30 +- src/io/streams/zlib/zutil.c | 2 +- src/io/streams/zlib/zutil.h | 4 +- src/maths/juce_Random.cpp | 19 +- src/maths/juce_Random.h | 5 + .../android/juce_android_SystemStats.cpp | 12 +- src/native/linux/juce_linux_SystemStats.cpp | 12 +- src/native/mac/juce_mac_NativeIncludes.h | 1 + src/native/mac/juce_mac_SystemStats.mm | 117 ++--- src/native/windows/juce_win32_SystemStats.cpp | 112 ++--- src/text/juce_LocalisedStrings.cpp | 17 + src/text/juce_String.cpp | 14 + 24 files changed, 489 insertions(+), 384 deletions(-) diff --git a/extras/Introjucer/Source/Project/jucer_ProjectExport_XCode.h b/extras/Introjucer/Source/Project/jucer_ProjectExport_XCode.h index 3265cafd27..005ce50bb5 100644 --- a/extras/Introjucer/Source/Project/jucer_ProjectExport_XCode.h +++ b/extras/Introjucer/Source/Project/jucer_ProjectExport_XCode.h @@ -682,7 +682,7 @@ private: if (iPhone) { - s.addTokens ("UIKit Foundation CoreGraphics AudioToolbox QuartzCore OpenGLES", false); + s.addTokens ("UIKit Foundation CoreGraphics CoreText AudioToolbox QuartzCore OpenGLES", false); } else { diff --git a/extras/JuceDemo/Builds/iOS/Juce Demo.xcodeproj/project.pbxproj b/extras/JuceDemo/Builds/iOS/Juce Demo.xcodeproj/project.pbxproj index bdd390fa9a..384ecb815e 100644 --- a/extras/JuceDemo/Builds/iOS/Juce Demo.xcodeproj/project.pbxproj +++ b/extras/JuceDemo/Builds/iOS/Juce Demo.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ 1DF18F6B9CCFF7BD07C36AC2 = { isa = PBXBuildFile; fileRef = CE3A43E4FB4D61350C000764; }; 3BE296F09A47C0ECE4D91CF5 = { isa = PBXBuildFile; fileRef = 90E63FC1333F952D526FF194; }; 7938A4501BDD574C4121B988 = { isa = PBXBuildFile; fileRef = 0D376A9686DFA1EAF983841C; }; + 8223C2805B1A9ECA27926EB5 = { isa = PBXBuildFile; fileRef = 1CFED196602026EF91937A0E; }; 36AEC0EAE7AB9D061AD9EFEF = { isa = PBXBuildFile; fileRef = 7B6D428682221857EAEA1C7D; }; F1BAE9DCD179C8784FF28F8D = { isa = PBXBuildFile; fileRef = 4A96850C150C1C6D87A0D21A; }; 268F2BF480CF9844E2F2B974 = { isa = PBXBuildFile; fileRef = B72353F9624D99DB6F93E400; }; @@ -42,6 +43,7 @@ CE3A43E4FB4D61350C000764 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 90E63FC1333F952D526FF194 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 0D376A9686DFA1EAF983841C = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 1CFED196602026EF91937A0E = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; }; 7B6D428682221857EAEA1C7D = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; 4A96850C150C1C6D87A0D21A = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; B72353F9624D99DB6F93E400 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; @@ -149,6 +151,7 @@ CE3A43E4FB4D61350C000764, 90E63FC1333F952D526FF194, 0D376A9686DFA1EAF983841C, + 1CFED196602026EF91937A0E, 7B6D428682221857EAEA1C7D, 4A96850C150C1C6D87A0D21A, B72353F9624D99DB6F93E400 ); name = Frameworks; sourceTree = ""; }; @@ -266,6 +269,7 @@ 1DF18F6B9CCFF7BD07C36AC2, 3BE296F09A47C0ECE4D91CF5, 7938A4501BDD574C4121B988, + 8223C2805B1A9ECA27926EB5, 36AEC0EAE7AB9D061AD9EFEF, F1BAE9DCD179C8784FF28F8D, 268F2BF480CF9844E2F2B974 ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/extras/example projects/Builds/iOS/HelloWorld.xcodeproj/project.pbxproj b/extras/example projects/Builds/iOS/HelloWorld.xcodeproj/project.pbxproj index 4baaa6e159..e7309a3f75 100644 --- a/extras/example projects/Builds/iOS/HelloWorld.xcodeproj/project.pbxproj +++ b/extras/example projects/Builds/iOS/HelloWorld.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ BAEB975FAD8A99FA884DC593 = { isa = PBXBuildFile; fileRef = 6B236CD90C0803738D7B5235; }; D8DBAED4AB03622A655367C6 = { isa = PBXBuildFile; fileRef = 3DE047A554FB376BE3DA4C65; }; 1622BC343C98F98AC2AC0459 = { isa = PBXBuildFile; fileRef = AA21728A979A53287A0DEFED; }; + 2F1CDA747BD63008A80CB986 = { isa = PBXBuildFile; fileRef = B9E8EA7A70EBC92D121DD5EF; }; D397D8CEF8663F449B4439C0 = { isa = PBXBuildFile; fileRef = 18665A7A93EDBA956B64774E; }; 9EA4F1C0E2356AB5C07CE95E = { isa = PBXBuildFile; fileRef = E6809DE026C8BEAB082B3DEB; }; C37934E8A18A3A82637C1445 = { isa = PBXBuildFile; fileRef = 541D7BED72093B09E01E3FD1; }; @@ -21,6 +22,7 @@ 6B236CD90C0803738D7B5235 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 3DE047A554FB376BE3DA4C65 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; AA21728A979A53287A0DEFED = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + B9E8EA7A70EBC92D121DD5EF = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; }; 18665A7A93EDBA956B64774E = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; E6809DE026C8BEAB082B3DEB = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 541D7BED72093B09E01E3FD1 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; @@ -52,6 +54,7 @@ 6B236CD90C0803738D7B5235, 3DE047A554FB376BE3DA4C65, AA21728A979A53287A0DEFED, + B9E8EA7A70EBC92D121DD5EF, 18665A7A93EDBA956B64774E, E6809DE026C8BEAB082B3DEB, 541D7BED72093B09E01E3FD1 ); name = Frameworks; sourceTree = ""; }; @@ -145,6 +148,7 @@ BAEB975FAD8A99FA884DC593, D8DBAED4AB03622A655367C6, 1622BC343C98F98AC2AC0459, + 2F1CDA747BD63008A80CB986, D397D8CEF8663F449B4439C0, 9EA4F1C0E2356AB5C07CE95E, C37934E8A18A3A82637C1445 ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index 489189784d..59b30e9316 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -872,6 +872,7 @@ protected: #import #import #import + #import #include #if JUCE_OPENGL #include @@ -1406,6 +1407,12 @@ Random::Random (const int64 seedValue) noexcept { } +Random::Random() + : seed (1) +{ + setSeedRandomly(); +} + Random::~Random() noexcept { } @@ -1429,6 +1436,12 @@ void Random::setSeedRandomly() combineSeed (Time::currentTimeMillis()); } +Random& Random::getSystemRandom() noexcept +{ + static Random sysRand; + return sysRand; +} + int Random::nextInt() noexcept { seed = (seed * literal64bit (0x5deece66d) + 11) & literal64bit (0xffffffffffff); @@ -1496,12 +1509,6 @@ void Random::fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numB arrayToChange.setBit (startBit + numBits, nextBool()); } -Random& Random::getSystemRandom() noexcept -{ - static Random sysRand (1); - return sysRand; -} - END_JUCE_NAMESPACE /*** End of inlined file: juce_Random.cpp ***/ @@ -1654,10 +1661,27 @@ END_JUCE_NAMESPACE /*** Start of inlined file: juce_SystemStats.cpp ***/ BEGIN_JUCE_NAMESPACE -SystemStats::CPUFlags SystemStats::cpuFlags; +const SystemStats::CPUFlags& SystemStats::getCPUFlags() +{ + static CPUFlags cpuFlags; + return cpuFlags; +} const String SystemStats::getJUCEVersion() { + // Some basic tests, to keep an eye on things and make sure these types work ok + // on all platforms. Let me know if any of these assertions fail on your system! + static_jassert (sizeof (pointer_sized_int) == sizeof (void*)); + static_jassert (sizeof (int8) == 1); + static_jassert (sizeof (uint8) == 1); + static_jassert (sizeof (int16) == 2); + static_jassert (sizeof (uint16) == 2); + static_jassert (sizeof (int32) == 4); + static_jassert (sizeof (uint32) == 4); + static_jassert (sizeof (int64) == 8); + static_jassert (sizeof (uint64) == 8); + + // (these confusing macros convert numbers into a single string literal) #define JUCE_STRINGIFYVERSION2(a) #a #define JUCE_STRINGIFYVERSION(a) JUCE_STRINGIFYVERSION2(a) @@ -2209,10 +2233,6 @@ BEGIN_JUCE_NAMESPACE #endif -#if JUCE_DEBUG - extern void juce_CheckForDanglingStreams(); // (in juce_OutputStream.cpp) -#endif - static bool juceInitialisedNonGUI = false; JUCE_API void JUCE_CALLTYPE initialiseJuce_NonGUI() @@ -2221,34 +2241,8 @@ JUCE_API void JUCE_CALLTYPE initialiseJuce_NonGUI() { juceInitialisedNonGUI = true; - JUCE_AUTORELEASEPOOL - DBG (SystemStats::getJUCEVersion()); - SystemStats::initialiseStats(); - Random::getSystemRandom().setSeedRandomly(); // (mustn't call this before initialiseStats() because it relies on the time being set up) } - - // Some basic tests, to keep an eye on things and make sure these types work ok - // on all platforms. Let me know if any of these assertions fail on your system! - static_jassert (sizeof (pointer_sized_int) == sizeof (void*)); - static_jassert (sizeof (int8) == 1); - static_jassert (sizeof (uint8) == 1); - static_jassert (sizeof (int16) == 2); - static_jassert (sizeof (uint16) == 2); - static_jassert (sizeof (int32) == 4); - static_jassert (sizeof (uint32) == 4); - static_jassert (sizeof (int64) == 8); - static_jassert (sizeof (uint64) == 8); - - #if JUCE_NATIVE_WCHAR_IS_UTF8 - static_jassert (sizeof (wchar_t) == 1); - #elif JUCE_NATIVE_WCHAR_IS_UTF16 - static_jassert (sizeof (wchar_t) == 2); - #elif JUCE_NATIVE_WCHAR_IS_UTF32 - static_jassert (sizeof (wchar_t) == 4); - #else - #error "native wchar_t size is unknown" - #endif } JUCE_API void JUCE_CALLTYPE shutdownJuce_NonGUI() @@ -2257,14 +2251,7 @@ JUCE_API void JUCE_CALLTYPE shutdownJuce_NonGUI() { juceInitialisedNonGUI = false; - JUCE_AUTORELEASEPOOL - - LocalisedStrings::setCurrentMappings (nullptr); Thread::stopAllThreads (3000); - - #if JUCE_DEBUG - juce_CheckForDanglingStreams(); - #endif } } @@ -6720,7 +6707,7 @@ const BigInteger Primes::createProbablePrime (const int bitLength, { randomSeeds = defaultSeeds; numRandomSeeds = numElementsInArray (defaultSeeds); - Random r (0); + Random r; for (int j = 10; --j >= 0;) { @@ -7123,32 +7110,40 @@ END_JUCE_NAMESPACE BEGIN_JUCE_NAMESPACE #if JUCE_DEBUG -static Array activeStreams; -void juce_CheckForDanglingStreams() +struct DanglingStreamChecker { - /* - It's always a bad idea to leak any object, but if you're leaking output - streams, then there's a good chance that you're failing to flush a file - to disk properly, which could result in corrupted data and other similar - nastiness.. - */ - jassert (activeStreams.size() == 0); + DanglingStreamChecker() {} + + ~DanglingStreamChecker() + { + /* + It's always a bad idea to leak any object, but if you're leaking output + streams, then there's a good chance that you're failing to flush a file + to disk properly, which could result in corrupted data and other similar + nastiness.. + */ + jassert (activeStreams.size() == 0); + } + + Array activeStreams; }; + +static DanglingStreamChecker danglingStreamChecker; #endif OutputStream::OutputStream() : newLineString (NewLine::getDefault()) { #if JUCE_DEBUG - activeStreams.add (this); + danglingStreamChecker.activeStreams.add (this); #endif } OutputStream::~OutputStream() { #if JUCE_DEBUG - activeStreams.removeValue (this); + danglingStreamChecker.activeStreams.removeValue (this); #endif } @@ -11418,6 +11413,23 @@ const String LocalisedStrings::translate (const String& text) const namespace { + #if JUCE_CHECK_MEMORY_LEAKS + // By using this object to force a LocalisedStrings object to be created + // before the currentMappings object, we can force the static order-of-destruction to + // delete the currentMappings object first, which avoids a bogus leak warning. + // (Oddly, just creating a LocalisedStrings on the stack doesn't work in gcc, it + // has to be created with 'new' for this to work..) + struct LeakAvoidanceTrick + { + LeakAvoidanceTrick() + { + const ScopedPointer dummy (new LocalisedStrings (String())); + } + }; + + LeakAvoidanceTrick leakAvoidanceTrick; + #endif + SpinLock currentMappingsLock; ScopedPointer currentMappings; @@ -11706,6 +11718,20 @@ private: return reinterpret_cast (reinterpret_cast (text.getAddress()) - (reinterpret_cast (reinterpret_cast (1)->text) - 1)); } + + void compileTimeChecks() + { + // Let me know if any of these assertions fail on your system! + #if JUCE_NATIVE_WCHAR_IS_UTF8 + static_jassert (sizeof (wchar_t) == 1); + #elif JUCE_NATIVE_WCHAR_IS_UTF16 + static_jassert (sizeof (wchar_t) == 2); + #elif JUCE_NATIVE_WCHAR_IS_UTF32 + static_jassert (sizeof (wchar_t) == 4); + #else + #error "native wchar_t size is unknown" + #endif + } }; StringHolder StringHolder::empty; @@ -41089,6 +41115,8 @@ void Component::setAlwaysOnTop (const bool shouldStayOnTop) { if (shouldStayOnTop != flags.alwaysOnTopFlag) { + BailOutChecker checker (this); + flags.alwaysOnTopFlag = shouldStayOnTop; if (isOnDesktop()) @@ -41109,10 +41137,11 @@ void Component::setAlwaysOnTop (const bool shouldStayOnTop) } } - if (shouldStayOnTop) + if (shouldStayOnTop && ! checker.shouldBailOut()) toFront (false); - internalHierarchyChanged(); + if (! checker.shouldBailOut()) + internalHierarchyChanged(); } } @@ -100215,7 +100244,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #endif /* Diagnostic functions */ -#ifdef DEBUG +#if 0 # include extern int z_verbose; extern void z_error OF((const char *m)); @@ -100232,6 +100261,8 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # define Tracevv(x) # define Tracec(c,x) # define Tracecv(c,x) +# define z_error(x) +# define z_verbose 0 #endif voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); @@ -106759,7 +106790,7 @@ uLong ZEXPORT zlibCompileFlags() return flags; }*/ -#ifdef DEBUG +#if 0 # ifndef verbose # define verbose 0 @@ -243208,9 +243239,6 @@ void Logger::outputDebugString (const String& text) OutputDebugString ((text + "\n").toWideCharPointer()); } -static int64 hiResTicksPerSecond; -static double hiResTicksScaleFactor; - #if JUCE_USE_INTRINSICS || JUCE_64BIT // CPU info functions using intrinsics... @@ -243275,38 +243303,33 @@ const String SystemStats::getCpuVendor() } #endif -void SystemStats::initialiseStats() +SystemStats::CPUFlags::CPUFlags() { - cpuFlags.hasMMX = IsProcessorFeaturePresent (PF_MMX_INSTRUCTIONS_AVAILABLE) != 0; - cpuFlags.hasSSE = IsProcessorFeaturePresent (PF_XMMI_INSTRUCTIONS_AVAILABLE) != 0; - cpuFlags.hasSSE2 = IsProcessorFeaturePresent (PF_XMMI64_INSTRUCTIONS_AVAILABLE) != 0; + hasMMX = IsProcessorFeaturePresent (PF_MMX_INSTRUCTIONS_AVAILABLE) != 0; + hasSSE = IsProcessorFeaturePresent (PF_XMMI_INSTRUCTIONS_AVAILABLE) != 0; + hasSSE2 = IsProcessorFeaturePresent (PF_XMMI64_INSTRUCTIONS_AVAILABLE) != 0; #ifdef PF_AMD3D_INSTRUCTIONS_AVAILABLE - cpuFlags.has3DNow = IsProcessorFeaturePresent (PF_AMD3D_INSTRUCTIONS_AVAILABLE) != 0; + has3DNow = IsProcessorFeaturePresent (PF_AMD3D_INSTRUCTIONS_AVAILABLE) != 0; #else - cpuFlags.has3DNow = IsProcessorFeaturePresent (PF_3DNOW_INSTRUCTIONS_AVAILABLE) != 0; + has3DNow = IsProcessorFeaturePresent (PF_3DNOW_INSTRUCTIONS_AVAILABLE) != 0; #endif + SYSTEM_INFO systemInfo; + GetSystemInfo (&systemInfo); + numCpus = systemInfo.dwNumberOfProcessors; +} + +#if JUCE_MSVC && JUCE_CHECK_MEMORY_LEAKS +struct DebugFlagsInitialiser +{ + DebugFlagsInitialiser() { - SYSTEM_INFO systemInfo; - GetSystemInfo (&systemInfo); - cpuFlags.numCpus = systemInfo.dwNumberOfProcessors; + _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); } +}; - LARGE_INTEGER f; - QueryPerformanceFrequency (&f); - hiResTicksPerSecond = f.QuadPart; - hiResTicksScaleFactor = 1000.0 / hiResTicksPerSecond; - - String s (SystemStats::getJUCEVersion()); - - const MMRESULT res = timeBeginPeriod (1); - (void) res; - jassert (res == TIMERR_NOERROR); - - #if JUCE_MSVC && JUCE_CHECK_MEMORY_LEAKS - _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); - #endif -} +static DebugFlagsInitialiser debugFlagsInitialiser; +#endif SystemStats::OperatingSystemType SystemStats::getOperatingSystemType() { @@ -243379,34 +243402,54 @@ uint32 juce_millisecondsSinceStartup() noexcept return (uint32) timeGetTime(); } -int64 Time::getHighResolutionTicks() noexcept +class HiResCounterHandler { - LARGE_INTEGER ticks; - QueryPerformanceCounter (&ticks); +public: + HiResCounterHandler() + : hiResTicksOffset (0) + { + const MMRESULT res = timeBeginPeriod (1); + (void) res; + jassert (res == TIMERR_NOERROR); + + LARGE_INTEGER f; + QueryPerformanceFrequency (&f); + hiResTicksPerSecond = f.QuadPart; + hiResTicksScaleFactor = 1000.0 / hiResTicksPerSecond; + } - const int64 mainCounterAsHiResTicks = (juce_millisecondsSinceStartup() * hiResTicksPerSecond) / 1000; - const int64 newOffset = mainCounterAsHiResTicks - ticks.QuadPart; + inline int64 getHighResolutionTicks() noexcept + { + LARGE_INTEGER ticks; + QueryPerformanceCounter (&ticks); - // fix for a very obscure PCI hardware bug that can make the counter - // sometimes jump forwards by a few seconds.. - static int64 hiResTicksOffset = 0; - const int64 offsetDrift = abs64 (newOffset - hiResTicksOffset); + const int64 mainCounterAsHiResTicks = (juce_millisecondsSinceStartup() * hiResTicksPerSecond) / 1000; + const int64 newOffset = mainCounterAsHiResTicks - ticks.QuadPart; - if (offsetDrift > (hiResTicksPerSecond >> 1)) - hiResTicksOffset = newOffset; + // fix for a very obscure PCI hardware bug that can make the counter + // sometimes jump forwards by a few seconds.. + const int64 offsetDrift = abs64 (newOffset - hiResTicksOffset); - return ticks.QuadPart + hiResTicksOffset; -} + if (offsetDrift > (hiResTicksPerSecond >> 1)) + hiResTicksOffset = newOffset; -double Time::getMillisecondCounterHiRes() noexcept -{ - return getHighResolutionTicks() * hiResTicksScaleFactor; -} + return ticks.QuadPart + hiResTicksOffset; + } -int64 Time::getHighResolutionTicksPerSecond() noexcept -{ - return hiResTicksPerSecond; -} + inline double getMillisecondCounterHiRes() noexcept + { + return getHighResolutionTicks() * hiResTicksScaleFactor; + } + + int64 hiResTicksPerSecond, hiResTicksOffset; + double hiResTicksScaleFactor; +}; + +static HiResCounterHandler hiResCounterHandler; + +int64 Time::getHighResolutionTicksPerSecond() noexcept { return hiResCounterHandler.hiResTicksPerSecond; } +int64 Time::getHighResolutionTicks() noexcept { return hiResCounterHandler.getHighResolutionTicks(); } +double Time::getMillisecondCounterHiRes() noexcept { return hiResCounterHandler.getMillisecondCounterHiRes(); } static int64 juce_getClockCycleCounter() noexcept { @@ -261378,15 +261421,15 @@ const String SystemStats::getComputerName() return String::empty; } -void SystemStats::initialiseStats() +SystemStats::CPUFlags::CPUFlags() { const String flags (LinuxStatsHelpers::getCpuInfo ("flags")); - cpuFlags.hasMMX = flags.contains ("mmx"); - cpuFlags.hasSSE = flags.contains ("sse"); - cpuFlags.hasSSE2 = flags.contains ("sse2"); - cpuFlags.has3DNow = flags.contains ("3dnow"); + hasMMX = flags.contains ("mmx"); + hasSSE = flags.contains ("sse"); + hasSSE2 = flags.contains ("sse2"); + has3DNow = flags.contains ("3dnow"); - cpuFlags.numCpus = LinuxStatsHelpers::getCpuInfo ("processor").getIntValue() + 1; + numCpus = LinuxStatsHelpers::getCpuInfo ("processor").getIntValue() + 1; } void PlatformUtilities::fpuReset() @@ -268596,10 +268639,7 @@ const String SystemClipboard::getTextFromClipboard() namespace SystemStatsHelpers { - static int64 highResTimerFrequency = 0; - static double highResTimerToMillisecRatio = 0; - - #if JUCE_INTEL + #if JUCE_INTEL void doCPUID (uint32& a, uint32& b, uint32& c, uint32& d, uint32 type) { uint32 la = a, lb = b, lc = c, ld = d; @@ -268615,56 +268655,50 @@ namespace SystemStatsHelpers a = la; b = lb; c = lc; d = ld; } - #endif + #endif } -void SystemStats::initialiseStats() +SystemStats::CPUFlags::CPUFlags() { - using namespace SystemStatsHelpers; - static bool initialised = false; - - if (! initialised) - { - initialised = true; - - #if JUCE_MAC - [NSApplication sharedApplication]; - #endif - - #if JUCE_INTEL - uint32 familyModel = 0, extFeatures = 0, features = 0, dummy = 0; - doCPUID (familyModel, extFeatures, dummy, features, 1); - - cpuFlags.hasMMX = ((features & (1 << 23)) != 0); - cpuFlags.hasSSE = ((features & (1 << 25)) != 0); - cpuFlags.hasSSE2 = ((features & (1 << 26)) != 0); - cpuFlags.has3DNow = ((extFeatures & (1 << 31)) != 0); - #else - cpuFlags.hasMMX = false; - cpuFlags.hasSSE = false; - cpuFlags.hasSSE2 = false; - cpuFlags.has3DNow = false; - #endif + #if JUCE_INTEL + uint32 familyModel = 0, extFeatures = 0, features = 0, dummy = 0; + SystemStatsHelpers::doCPUID (familyModel, extFeatures, dummy, features, 1); - #if JUCE_IOS || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) - cpuFlags.numCpus = (int) [[NSProcessInfo processInfo] activeProcessorCount]; - #else - cpuFlags.numCpus = (int) MPProcessors(); - #endif + hasMMX = (features & (1 << 23)) != 0; + hasSSE = (features & (1 << 25)) != 0; + hasSSE2 = (features & (1 << 26)) != 0; + has3DNow = (extFeatures & (1 << 31)) != 0; + #else + hasMMX = false; + hasSSE = false; + hasSSE2 = false; + has3DNow = false; + #endif - mach_timebase_info_data_t timebase; - (void) mach_timebase_info (&timebase); - highResTimerFrequency = (int64) (1.0e9 * timebase.denom / timebase.numer); - highResTimerToMillisecRatio = timebase.numer / (1.0e6 * timebase.denom); + #if JUCE_IOS || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) + numCpus = (int) [[NSProcessInfo processInfo] activeProcessorCount]; + #else + numCpus = (int) MPProcessors(); + #endif +} - String s (SystemStats::getJUCEVersion()); +#if JUCE_MAC +struct SharedAppInitialiser +{ + SharedAppInitialiser() + { + JUCE_AUTORELEASEPOOL + [NSApplication sharedApplication]; rlimit lim; getrlimit (RLIMIT_NOFILE, &lim); lim.rlim_cur = lim.rlim_max = RLIM_INFINITY; setrlimit (RLIMIT_NOFILE, &lim); } -} +}; + +static SharedAppInitialiser sharedAppInitialiser; +#endif SystemStats::OperatingSystemType SystemStats::getOperatingSystemType() { @@ -268755,25 +268789,37 @@ const String SystemStats::getComputerName() return String::empty; } -uint32 juce_millisecondsSinceStartup() noexcept +class HiResCounterHandler { - return (uint32) (mach_absolute_time() * SystemStatsHelpers::highResTimerToMillisecRatio); -} +public: + HiResCounterHandler() + { + mach_timebase_info_data_t timebase; + (void) mach_timebase_info (&timebase); + highResTimerFrequency = (int64) (1.0e9 * timebase.denom / timebase.numer); + highResTimerToMillisecRatio = timebase.numer / (1.0e6 * timebase.denom); + } -double Time::getMillisecondCounterHiRes() noexcept -{ - return mach_absolute_time() * SystemStatsHelpers::highResTimerToMillisecRatio; -} + inline uint32 millisecondsSinceStartup() const noexcept + { + return (uint32) (mach_absolute_time() * highResTimerToMillisecRatio); + } -int64 Time::getHighResolutionTicks() noexcept -{ - return (int64) mach_absolute_time(); -} + inline double getMillisecondCounterHiRes() const noexcept + { + return mach_absolute_time() * highResTimerToMillisecRatio; + } -int64 Time::getHighResolutionTicksPerSecond() noexcept -{ - return SystemStatsHelpers::highResTimerFrequency; -} + int64 highResTimerFrequency; + double highResTimerToMillisecRatio; +}; + +static HiResCounterHandler hiResCounterHandler; + +uint32 juce_millisecondsSinceStartup() noexcept { return hiResCounterHandler.millisecondsSinceStartup(); } +double Time::getMillisecondCounterHiRes() noexcept { return hiResCounterHandler.getMillisecondCounterHiRes(); } +int64 Time::getHighResolutionTicksPerSecond() noexcept { return hiResCounterHandler.highResTimerFrequency; } +int64 Time::getHighResolutionTicks() noexcept { return (int64) mach_absolute_time(); } bool Time::setSystemTimeToThisTime() const { @@ -286270,15 +286316,15 @@ const String SystemStats::getComputerName() return String::empty; } -void SystemStats::initialiseStats() +SystemStats::CPUFlags::CPUFlags() { // TODO - cpuFlags.hasMMX = false; - cpuFlags.hasSSE = false; - cpuFlags.hasSSE2 = false; - cpuFlags.has3DNow = false; + hasMMX = false; + hasSSE = false; + hasSSE2 = false; + has3DNow = false; - cpuFlags.numCpus = jmax (1, sysconf (_SC_NPROCESSORS_ONLN)); + numCpus = jmax (1, sysconf (_SC_NPROCESSORS_ONLN)); } void PlatformUtilities::fpuReset() {} diff --git a/juce_amalgamated.h b/juce_amalgamated.h index 23fdd540d0..54b74ed31f 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -73,7 +73,7 @@ namespace JuceDummyNamespace {} */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 53 -#define JUCE_BUILDNUMBER 78 +#define JUCE_BUILDNUMBER 79 /** Current Juce version number. @@ -7073,7 +7073,7 @@ public: @param index the index of the element being requested (0 is the first element in the array) @see getUnchecked, getFirst, getLast */ - inline ElementType operator[] (const int index) const + const ElementType operator[] (const int index) const { const ScopedLockType lock (getLock()); return isPositiveAndBelow (index, numUsed) ? data.elements [index] @@ -18278,19 +18278,19 @@ public: static const String getCpuVendor(); /** Checks whether Intel MMX instructions are available. */ - static bool hasMMX() noexcept { return cpuFlags.hasMMX; } + static bool hasMMX() noexcept { return getCPUFlags().hasMMX; } /** Checks whether Intel SSE instructions are available. */ - static bool hasSSE() noexcept { return cpuFlags.hasSSE; } + static bool hasSSE() noexcept { return getCPUFlags().hasSSE; } /** Checks whether Intel SSE2 instructions are available. */ - static bool hasSSE2() noexcept { return cpuFlags.hasSSE2; } + static bool hasSSE2() noexcept { return getCPUFlags().hasSSE2; } /** Checks whether AMD 3DNOW instructions are available. */ - static bool has3DNow() noexcept { return cpuFlags.has3DNow; } + static bool has3DNow() noexcept { return getCPUFlags().has3DNow; } /** Returns the number of CPUs. */ - static int getNumCpus() noexcept { return cpuFlags.numCpus; } + static int getNumCpus() noexcept { return getCPUFlags().numCpus; } /** Finds out how much RAM is in the machine. @@ -18305,12 +18305,12 @@ public: */ static int getPageSize(); - // not-for-public-use platform-specific method gets called at startup to initialise things. - static void initialiseStats(); - private: + struct CPUFlags { + CPUFlags(); + int numCpus; bool hasMMX : 1; bool hasSSE : 1; @@ -18318,9 +18318,8 @@ private: bool has3DNow : 1; }; - static CPUFlags cpuFlags; - SystemStats(); + static const CPUFlags& getCPUFlags(); JUCE_DECLARE_NON_COPYABLE (SystemStats); }; @@ -21372,6 +21371,11 @@ public: */ explicit Random (int64 seedValue) noexcept; + /** Creates a Random object using a random seed value. + Internally, this calls setSeedRandomly() to randomise the seed. + */ + Random(); + /** Destructor. */ ~Random() noexcept; diff --git a/src/containers/juce_Array.h b/src/containers/juce_Array.h index 4108572d7a..195638972b 100644 --- a/src/containers/juce_Array.h +++ b/src/containers/juce_Array.h @@ -215,7 +215,7 @@ public: @param index the index of the element being requested (0 is the first element in the array) @see getUnchecked, getFirst, getLast */ - inline ElementType operator[] (const int index) const + const ElementType operator[] (const int index) const { const ScopedLockType lock (getLock()); return isPositiveAndBelow (index, numUsed) ? data.elements [index] diff --git a/src/core/juce_Initialisation.cpp b/src/core/juce_Initialisation.cpp index 4a85c1edf9..0a1c8716a7 100644 --- a/src/core/juce_Initialisation.cpp +++ b/src/core/juce_Initialisation.cpp @@ -28,7 +28,6 @@ BEGIN_JUCE_NAMESPACE #include "../memory/juce_Atomic.h" -#include "../maths/juce_Random.h" #include "juce_PlatformUtilities.h" #include "juce_SystemStats.h" #include "../text/juce_LocalisedStrings.h" @@ -42,11 +41,6 @@ BEGIN_JUCE_NAMESPACE #include "../gui/components/lookandfeel/juce_LookAndFeel.h" #endif -#if JUCE_DEBUG - extern void juce_CheckForDanglingStreams(); // (in juce_OutputStream.cpp) -#endif - - //============================================================================== static bool juceInitialisedNonGUI = false; @@ -56,34 +50,8 @@ JUCE_API void JUCE_CALLTYPE initialiseJuce_NonGUI() { juceInitialisedNonGUI = true; - JUCE_AUTORELEASEPOOL - DBG (SystemStats::getJUCEVersion()); - SystemStats::initialiseStats(); - Random::getSystemRandom().setSeedRandomly(); // (mustn't call this before initialiseStats() because it relies on the time being set up) } - - // Some basic tests, to keep an eye on things and make sure these types work ok - // on all platforms. Let me know if any of these assertions fail on your system! - static_jassert (sizeof (pointer_sized_int) == sizeof (void*)); - static_jassert (sizeof (int8) == 1); - static_jassert (sizeof (uint8) == 1); - static_jassert (sizeof (int16) == 2); - static_jassert (sizeof (uint16) == 2); - static_jassert (sizeof (int32) == 4); - static_jassert (sizeof (uint32) == 4); - static_jassert (sizeof (int64) == 8); - static_jassert (sizeof (uint64) == 8); - - #if JUCE_NATIVE_WCHAR_IS_UTF8 - static_jassert (sizeof (wchar_t) == 1); - #elif JUCE_NATIVE_WCHAR_IS_UTF16 - static_jassert (sizeof (wchar_t) == 2); - #elif JUCE_NATIVE_WCHAR_IS_UTF32 - static_jassert (sizeof (wchar_t) == 4); - #else - #error "native wchar_t size is unknown" - #endif } JUCE_API void JUCE_CALLTYPE shutdownJuce_NonGUI() @@ -92,14 +60,7 @@ JUCE_API void JUCE_CALLTYPE shutdownJuce_NonGUI() { juceInitialisedNonGUI = false; - JUCE_AUTORELEASEPOOL - - LocalisedStrings::setCurrentMappings (nullptr); Thread::stopAllThreads (3000); - - #if JUCE_DEBUG - juce_CheckForDanglingStreams(); - #endif } } diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index 73cafa75e9..ec0b135fde 100644 --- a/src/core/juce_StandardHeader.h +++ b/src/core/juce_StandardHeader.h @@ -33,7 +33,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 53 -#define JUCE_BUILDNUMBER 78 +#define JUCE_BUILDNUMBER 79 /** Current Juce version number. diff --git a/src/core/juce_SystemStats.cpp b/src/core/juce_SystemStats.cpp index 8ea19910a4..ca0e88f69b 100644 --- a/src/core/juce_SystemStats.cpp +++ b/src/core/juce_SystemStats.cpp @@ -34,10 +34,27 @@ BEGIN_JUCE_NAMESPACE //============================================================================== -SystemStats::CPUFlags SystemStats::cpuFlags; +const SystemStats::CPUFlags& SystemStats::getCPUFlags() +{ + static CPUFlags cpuFlags; + return cpuFlags; +} const String SystemStats::getJUCEVersion() { + // Some basic tests, to keep an eye on things and make sure these types work ok + // on all platforms. Let me know if any of these assertions fail on your system! + static_jassert (sizeof (pointer_sized_int) == sizeof (void*)); + static_jassert (sizeof (int8) == 1); + static_jassert (sizeof (uint8) == 1); + static_jassert (sizeof (int16) == 2); + static_jassert (sizeof (uint16) == 2); + static_jassert (sizeof (int32) == 4); + static_jassert (sizeof (uint32) == 4); + static_jassert (sizeof (int64) == 8); + static_jassert (sizeof (uint64) == 8); + + // (these confusing macros convert numbers into a single string literal) #define JUCE_STRINGIFYVERSION2(a) #a #define JUCE_STRINGIFYVERSION(a) JUCE_STRINGIFYVERSION2(a) diff --git a/src/core/juce_SystemStats.h b/src/core/juce_SystemStats.h index d2b3418e5f..4dd874e0d6 100644 --- a/src/core/juce_SystemStats.h +++ b/src/core/juce_SystemStats.h @@ -119,19 +119,19 @@ public: static const String getCpuVendor(); /** Checks whether Intel MMX instructions are available. */ - static bool hasMMX() noexcept { return cpuFlags.hasMMX; } + static bool hasMMX() noexcept { return getCPUFlags().hasMMX; } /** Checks whether Intel SSE instructions are available. */ - static bool hasSSE() noexcept { return cpuFlags.hasSSE; } + static bool hasSSE() noexcept { return getCPUFlags().hasSSE; } /** Checks whether Intel SSE2 instructions are available. */ - static bool hasSSE2() noexcept { return cpuFlags.hasSSE2; } + static bool hasSSE2() noexcept { return getCPUFlags().hasSSE2; } /** Checks whether AMD 3DNOW instructions are available. */ - static bool has3DNow() noexcept { return cpuFlags.has3DNow; } + static bool has3DNow() noexcept { return getCPUFlags().has3DNow; } /** Returns the number of CPUs. */ - static int getNumCpus() noexcept { return cpuFlags.numCpus; } + static int getNumCpus() noexcept { return getCPUFlags().numCpus; } //============================================================================== /** Finds out how much RAM is in the machine. @@ -147,13 +147,13 @@ public: */ static int getPageSize(); - //============================================================================== - // not-for-public-use platform-specific method gets called at startup to initialise things. - static void initialiseStats(); private: + //============================================================================== struct CPUFlags { + CPUFlags(); + int numCpus; bool hasMMX : 1; bool hasSSE : 1; @@ -161,9 +161,8 @@ private: bool has3DNow : 1; }; - static CPUFlags cpuFlags; - SystemStats(); + static const CPUFlags& getCPUFlags(); JUCE_DECLARE_NON_COPYABLE (SystemStats); }; diff --git a/src/cryptography/juce_Primes.cpp b/src/cryptography/juce_Primes.cpp index 11d1712913..948ab99c2c 100644 --- a/src/cryptography/juce_Primes.cpp +++ b/src/cryptography/juce_Primes.cpp @@ -171,7 +171,7 @@ const BigInteger Primes::createProbablePrime (const int bitLength, { randomSeeds = defaultSeeds; numRandomSeeds = numElementsInArray (defaultSeeds); - Random r (0); + Random r; for (int j = 10; --j >= 0;) { diff --git a/src/gui/components/juce_Component.cpp b/src/gui/components/juce_Component.cpp index acfdacc4dc..0a8a52d66d 100644 --- a/src/gui/components/juce_Component.cpp +++ b/src/gui/components/juce_Component.cpp @@ -874,6 +874,8 @@ void Component::setAlwaysOnTop (const bool shouldStayOnTop) { if (shouldStayOnTop != flags.alwaysOnTopFlag) { + BailOutChecker checker (this); + flags.alwaysOnTopFlag = shouldStayOnTop; if (isOnDesktop()) @@ -894,10 +896,11 @@ void Component::setAlwaysOnTop (const bool shouldStayOnTop) } } - if (shouldStayOnTop) + if (shouldStayOnTop && ! checker.shouldBailOut()) toFront (false); - internalHierarchyChanged(); + if (! checker.shouldBailOut()) + internalHierarchyChanged(); } } diff --git a/src/io/streams/juce_OutputStream.cpp b/src/io/streams/juce_OutputStream.cpp index d25bf89c4b..f9bf7c65c9 100644 --- a/src/io/streams/juce_OutputStream.cpp +++ b/src/io/streams/juce_OutputStream.cpp @@ -35,18 +35,26 @@ BEGIN_JUCE_NAMESPACE //============================================================================== #if JUCE_DEBUG -static Array activeStreams; -void juce_CheckForDanglingStreams() +struct DanglingStreamChecker { - /* - It's always a bad idea to leak any object, but if you're leaking output - streams, then there's a good chance that you're failing to flush a file - to disk properly, which could result in corrupted data and other similar - nastiness.. - */ - jassert (activeStreams.size() == 0); + DanglingStreamChecker() {} + + ~DanglingStreamChecker() + { + /* + It's always a bad idea to leak any object, but if you're leaking output + streams, then there's a good chance that you're failing to flush a file + to disk properly, which could result in corrupted data and other similar + nastiness.. + */ + jassert (activeStreams.size() == 0); + } + + Array activeStreams; }; + +static DanglingStreamChecker danglingStreamChecker; #endif //============================================================================== @@ -54,14 +62,14 @@ OutputStream::OutputStream() : newLineString (NewLine::getDefault()) { #if JUCE_DEBUG - activeStreams.add (this); + danglingStreamChecker.activeStreams.add (this); #endif } OutputStream::~OutputStream() { #if JUCE_DEBUG - activeStreams.removeValue (this); + danglingStreamChecker.activeStreams.removeValue (this); #endif } diff --git a/src/io/streams/zlib/zutil.c b/src/io/streams/zlib/zutil.c index 33964c2d6e..630305ca2c 100644 --- a/src/io/streams/zlib/zutil.c +++ b/src/io/streams/zlib/zutil.c @@ -112,7 +112,7 @@ uLong ZEXPORT zlibCompileFlags() return flags; }*/ -#ifdef DEBUG +#if 0 # ifndef verbose # define verbose 0 diff --git a/src/io/streams/zlib/zutil.h b/src/io/streams/zlib/zutil.h index 776f10718d..3939858701 100644 --- a/src/io/streams/zlib/zutil.h +++ b/src/io/streams/zlib/zutil.h @@ -238,7 +238,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #endif /* Diagnostic functions */ -#ifdef DEBUG +#if 0 # include extern int z_verbose; extern void z_error OF((const char *m)); @@ -255,6 +255,8 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # define Tracevv(x) # define Tracec(c,x) # define Tracecv(c,x) +# define z_error(x) +# define z_verbose 0 #endif diff --git a/src/maths/juce_Random.cpp b/src/maths/juce_Random.cpp index e7a83a4955..1008270d50 100644 --- a/src/maths/juce_Random.cpp +++ b/src/maths/juce_Random.cpp @@ -37,6 +37,12 @@ Random::Random (const int64 seedValue) noexcept { } +Random::Random() + : seed (1) +{ + setSeedRandomly(); +} + Random::~Random() noexcept { } @@ -60,6 +66,12 @@ void Random::setSeedRandomly() combineSeed (Time::currentTimeMillis()); } +Random& Random::getSystemRandom() noexcept +{ + static Random sysRand; + return sysRand; +} + //============================================================================== int Random::nextInt() noexcept { @@ -128,11 +140,4 @@ void Random::fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numB arrayToChange.setBit (startBit + numBits, nextBool()); } -//============================================================================== -Random& Random::getSystemRandom() noexcept -{ - static Random sysRand (1); - return sysRand; -} - END_JUCE_NAMESPACE diff --git a/src/maths/juce_Random.h b/src/maths/juce_Random.h index c3e064603c..44515c2a1a 100644 --- a/src/maths/juce_Random.h +++ b/src/maths/juce_Random.h @@ -52,6 +52,11 @@ public: */ explicit Random (int64 seedValue) noexcept; + /** Creates a Random object using a random seed value. + Internally, this calls setSeedRandomly() to randomise the seed. + */ + Random(); + /** Destructor. */ ~Random() noexcept; diff --git a/src/native/android/juce_android_SystemStats.cpp b/src/native/android/juce_android_SystemStats.cpp index 2cea3b69c2..ad809a01b3 100644 --- a/src/native/android/juce_android_SystemStats.cpp +++ b/src/native/android/juce_android_SystemStats.cpp @@ -115,15 +115,15 @@ const String SystemStats::getComputerName() } //============================================================================== -void SystemStats::initialiseStats() +SystemStats::CPUFlags::CPUFlags() { // TODO - cpuFlags.hasMMX = false; - cpuFlags.hasSSE = false; - cpuFlags.hasSSE2 = false; - cpuFlags.has3DNow = false; + hasMMX = false; + hasSSE = false; + hasSSE2 = false; + has3DNow = false; - cpuFlags.numCpus = jmax (1, sysconf (_SC_NPROCESSORS_ONLN)); + numCpus = jmax (1, sysconf (_SC_NPROCESSORS_ONLN)); } void PlatformUtilities::fpuReset() {} diff --git a/src/native/linux/juce_linux_SystemStats.cpp b/src/native/linux/juce_linux_SystemStats.cpp index 0bca563519..aca5a54824 100644 --- a/src/native/linux/juce_linux_SystemStats.cpp +++ b/src/native/linux/juce_linux_SystemStats.cpp @@ -126,15 +126,15 @@ const String SystemStats::getComputerName() } //============================================================================== -void SystemStats::initialiseStats() +SystemStats::CPUFlags::CPUFlags() { const String flags (LinuxStatsHelpers::getCpuInfo ("flags")); - cpuFlags.hasMMX = flags.contains ("mmx"); - cpuFlags.hasSSE = flags.contains ("sse"); - cpuFlags.hasSSE2 = flags.contains ("sse2"); - cpuFlags.has3DNow = flags.contains ("3dnow"); + hasMMX = flags.contains ("mmx"); + hasSSE = flags.contains ("sse"); + hasSSE2 = flags.contains ("sse2"); + has3DNow = flags.contains ("3dnow"); - cpuFlags.numCpus = LinuxStatsHelpers::getCpuInfo ("processor").getIntValue() + 1; + numCpus = LinuxStatsHelpers::getCpuInfo ("processor").getIntValue() + 1; } void PlatformUtilities::fpuReset() diff --git a/src/native/mac/juce_mac_NativeIncludes.h b/src/native/mac/juce_mac_NativeIncludes.h index 06c4888a37..1ea02350ec 100644 --- a/src/native/mac/juce_mac_NativeIncludes.h +++ b/src/native/mac/juce_mac_NativeIncludes.h @@ -36,6 +36,7 @@ #import #import #import + #import #include #if JUCE_OPENGL #include diff --git a/src/native/mac/juce_mac_SystemStats.mm b/src/native/mac/juce_mac_SystemStats.mm index 7223285fc9..6646339872 100644 --- a/src/native/mac/juce_mac_SystemStats.mm +++ b/src/native/mac/juce_mac_SystemStats.mm @@ -29,10 +29,7 @@ namespace SystemStatsHelpers { - static int64 highResTimerFrequency = 0; - static double highResTimerToMillisecRatio = 0; - - #if JUCE_INTEL + #if JUCE_INTEL void doCPUID (uint32& a, uint32& b, uint32& c, uint32& d, uint32 type) { uint32 la = a, lb = b, lc = c, ld = d; @@ -48,57 +45,51 @@ namespace SystemStatsHelpers a = la; b = lb; c = lc; d = ld; } - #endif + #endif } //============================================================================== -void SystemStats::initialiseStats() +SystemStats::CPUFlags::CPUFlags() { - using namespace SystemStatsHelpers; - static bool initialised = false; - - if (! initialised) - { - initialised = true; + #if JUCE_INTEL + uint32 familyModel = 0, extFeatures = 0, features = 0, dummy = 0; + SystemStatsHelpers::doCPUID (familyModel, extFeatures, dummy, features, 1); - #if JUCE_MAC - [NSApplication sharedApplication]; - #endif - - #if JUCE_INTEL - uint32 familyModel = 0, extFeatures = 0, features = 0, dummy = 0; - doCPUID (familyModel, extFeatures, dummy, features, 1); - - cpuFlags.hasMMX = ((features & (1 << 23)) != 0); - cpuFlags.hasSSE = ((features & (1 << 25)) != 0); - cpuFlags.hasSSE2 = ((features & (1 << 26)) != 0); - cpuFlags.has3DNow = ((extFeatures & (1 << 31)) != 0); - #else - cpuFlags.hasMMX = false; - cpuFlags.hasSSE = false; - cpuFlags.hasSSE2 = false; - cpuFlags.has3DNow = false; - #endif - - #if JUCE_IOS || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) - cpuFlags.numCpus = (int) [[NSProcessInfo processInfo] activeProcessorCount]; - #else - cpuFlags.numCpus = (int) MPProcessors(); - #endif + hasMMX = (features & (1 << 23)) != 0; + hasSSE = (features & (1 << 25)) != 0; + hasSSE2 = (features & (1 << 26)) != 0; + has3DNow = (extFeatures & (1 << 31)) != 0; + #else + hasMMX = false; + hasSSE = false; + hasSSE2 = false; + has3DNow = false; + #endif - mach_timebase_info_data_t timebase; - (void) mach_timebase_info (&timebase); - highResTimerFrequency = (int64) (1.0e9 * timebase.denom / timebase.numer); - highResTimerToMillisecRatio = timebase.numer / (1.0e6 * timebase.denom); + #if JUCE_IOS || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) + numCpus = (int) [[NSProcessInfo processInfo] activeProcessorCount]; + #else + numCpus = (int) MPProcessors(); + #endif +} - String s (SystemStats::getJUCEVersion()); +#if JUCE_MAC +struct SharedAppInitialiser +{ + SharedAppInitialiser() + { + JUCE_AUTORELEASEPOOL + [NSApplication sharedApplication]; rlimit lim; getrlimit (RLIMIT_NOFILE, &lim); lim.rlim_cur = lim.rlim_max = RLIM_INFINITY; setrlimit (RLIMIT_NOFILE, &lim); } -} +}; + +static SharedAppInitialiser sharedAppInitialiser; +#endif //============================================================================== SystemStats::OperatingSystemType SystemStats::getOperatingSystemType() @@ -192,25 +183,37 @@ const String SystemStats::getComputerName() } //============================================================================== -uint32 juce_millisecondsSinceStartup() noexcept +class HiResCounterHandler { - return (uint32) (mach_absolute_time() * SystemStatsHelpers::highResTimerToMillisecRatio); -} +public: + HiResCounterHandler() + { + mach_timebase_info_data_t timebase; + (void) mach_timebase_info (&timebase); + highResTimerFrequency = (int64) (1.0e9 * timebase.denom / timebase.numer); + highResTimerToMillisecRatio = timebase.numer / (1.0e6 * timebase.denom); + } -double Time::getMillisecondCounterHiRes() noexcept -{ - return mach_absolute_time() * SystemStatsHelpers::highResTimerToMillisecRatio; -} + inline uint32 millisecondsSinceStartup() const noexcept + { + return (uint32) (mach_absolute_time() * highResTimerToMillisecRatio); + } -int64 Time::getHighResolutionTicks() noexcept -{ - return (int64) mach_absolute_time(); -} + inline double getMillisecondCounterHiRes() const noexcept + { + return mach_absolute_time() * highResTimerToMillisecRatio; + } -int64 Time::getHighResolutionTicksPerSecond() noexcept -{ - return SystemStatsHelpers::highResTimerFrequency; -} + int64 highResTimerFrequency; + double highResTimerToMillisecRatio; +}; + +static HiResCounterHandler hiResCounterHandler; + +uint32 juce_millisecondsSinceStartup() noexcept { return hiResCounterHandler.millisecondsSinceStartup(); } +double Time::getMillisecondCounterHiRes() noexcept { return hiResCounterHandler.getMillisecondCounterHiRes(); } +int64 Time::getHighResolutionTicksPerSecond() noexcept { return hiResCounterHandler.highResTimerFrequency; } +int64 Time::getHighResolutionTicks() noexcept { return (int64) mach_absolute_time(); } bool Time::setSystemTimeToThisTime() const { diff --git a/src/native/windows/juce_win32_SystemStats.cpp b/src/native/windows/juce_win32_SystemStats.cpp index 6a1eee5819..38760b8d7d 100644 --- a/src/native/windows/juce_win32_SystemStats.cpp +++ b/src/native/windows/juce_win32_SystemStats.cpp @@ -34,11 +34,6 @@ void Logger::outputDebugString (const String& text) OutputDebugString ((text + "\n").toWideCharPointer()); } -//============================================================================== -static int64 hiResTicksPerSecond; -static double hiResTicksScaleFactor; - - //============================================================================== #if JUCE_USE_INTRINSICS || JUCE_64BIT @@ -107,38 +102,33 @@ const String SystemStats::getCpuVendor() //============================================================================== -void SystemStats::initialiseStats() +SystemStats::CPUFlags::CPUFlags() { - cpuFlags.hasMMX = IsProcessorFeaturePresent (PF_MMX_INSTRUCTIONS_AVAILABLE) != 0; - cpuFlags.hasSSE = IsProcessorFeaturePresent (PF_XMMI_INSTRUCTIONS_AVAILABLE) != 0; - cpuFlags.hasSSE2 = IsProcessorFeaturePresent (PF_XMMI64_INSTRUCTIONS_AVAILABLE) != 0; + hasMMX = IsProcessorFeaturePresent (PF_MMX_INSTRUCTIONS_AVAILABLE) != 0; + hasSSE = IsProcessorFeaturePresent (PF_XMMI_INSTRUCTIONS_AVAILABLE) != 0; + hasSSE2 = IsProcessorFeaturePresent (PF_XMMI64_INSTRUCTIONS_AVAILABLE) != 0; #ifdef PF_AMD3D_INSTRUCTIONS_AVAILABLE - cpuFlags.has3DNow = IsProcessorFeaturePresent (PF_AMD3D_INSTRUCTIONS_AVAILABLE) != 0; + has3DNow = IsProcessorFeaturePresent (PF_AMD3D_INSTRUCTIONS_AVAILABLE) != 0; #else - cpuFlags.has3DNow = IsProcessorFeaturePresent (PF_3DNOW_INSTRUCTIONS_AVAILABLE) != 0; + has3DNow = IsProcessorFeaturePresent (PF_3DNOW_INSTRUCTIONS_AVAILABLE) != 0; #endif + SYSTEM_INFO systemInfo; + GetSystemInfo (&systemInfo); + numCpus = systemInfo.dwNumberOfProcessors; +} + +#if JUCE_MSVC && JUCE_CHECK_MEMORY_LEAKS +struct DebugFlagsInitialiser +{ + DebugFlagsInitialiser() { - SYSTEM_INFO systemInfo; - GetSystemInfo (&systemInfo); - cpuFlags.numCpus = systemInfo.dwNumberOfProcessors; + _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); } +}; - LARGE_INTEGER f; - QueryPerformanceFrequency (&f); - hiResTicksPerSecond = f.QuadPart; - hiResTicksScaleFactor = 1000.0 / hiResTicksPerSecond; - - String s (SystemStats::getJUCEVersion()); - - const MMRESULT res = timeBeginPeriod (1); - (void) res; - jassert (res == TIMERR_NOERROR); - - #if JUCE_MSVC && JUCE_CHECK_MEMORY_LEAKS - _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); - #endif -} +static DebugFlagsInitialiser debugFlagsInitialiser; +#endif //============================================================================== SystemStats::OperatingSystemType SystemStats::getOperatingSystemType() @@ -214,35 +204,57 @@ uint32 juce_millisecondsSinceStartup() noexcept return (uint32) timeGetTime(); } -int64 Time::getHighResolutionTicks() noexcept +//============================================================================== +class HiResCounterHandler { - LARGE_INTEGER ticks; - QueryPerformanceCounter (&ticks); +public: + HiResCounterHandler() + : hiResTicksOffset (0) + { + const MMRESULT res = timeBeginPeriod (1); + (void) res; + jassert (res == TIMERR_NOERROR); + + LARGE_INTEGER f; + QueryPerformanceFrequency (&f); + hiResTicksPerSecond = f.QuadPart; + hiResTicksScaleFactor = 1000.0 / hiResTicksPerSecond; + } - const int64 mainCounterAsHiResTicks = (juce_millisecondsSinceStartup() * hiResTicksPerSecond) / 1000; - const int64 newOffset = mainCounterAsHiResTicks - ticks.QuadPart; + inline int64 getHighResolutionTicks() noexcept + { + LARGE_INTEGER ticks; + QueryPerformanceCounter (&ticks); - // fix for a very obscure PCI hardware bug that can make the counter - // sometimes jump forwards by a few seconds.. - static int64 hiResTicksOffset = 0; - const int64 offsetDrift = abs64 (newOffset - hiResTicksOffset); + const int64 mainCounterAsHiResTicks = (juce_millisecondsSinceStartup() * hiResTicksPerSecond) / 1000; + const int64 newOffset = mainCounterAsHiResTicks - ticks.QuadPart; - if (offsetDrift > (hiResTicksPerSecond >> 1)) - hiResTicksOffset = newOffset; + // fix for a very obscure PCI hardware bug that can make the counter + // sometimes jump forwards by a few seconds.. + const int64 offsetDrift = abs64 (newOffset - hiResTicksOffset); - return ticks.QuadPart + hiResTicksOffset; -} + if (offsetDrift > (hiResTicksPerSecond >> 1)) + hiResTicksOffset = newOffset; -double Time::getMillisecondCounterHiRes() noexcept -{ - return getHighResolutionTicks() * hiResTicksScaleFactor; -} + return ticks.QuadPart + hiResTicksOffset; + } -int64 Time::getHighResolutionTicksPerSecond() noexcept -{ - return hiResTicksPerSecond; -} + inline double getMillisecondCounterHiRes() noexcept + { + return getHighResolutionTicks() * hiResTicksScaleFactor; + } + + int64 hiResTicksPerSecond, hiResTicksOffset; + double hiResTicksScaleFactor; +}; +static HiResCounterHandler hiResCounterHandler; + +int64 Time::getHighResolutionTicksPerSecond() noexcept { return hiResCounterHandler.hiResTicksPerSecond; } +int64 Time::getHighResolutionTicks() noexcept { return hiResCounterHandler.getHighResolutionTicks(); } +double Time::getMillisecondCounterHiRes() noexcept { return hiResCounterHandler.getMillisecondCounterHiRes(); } + +//============================================================================== static int64 juce_getClockCycleCounter() noexcept { #if JUCE_USE_INTRINSICS diff --git a/src/text/juce_LocalisedStrings.cpp b/src/text/juce_LocalisedStrings.cpp index d1fbe948fc..bb05fa26f3 100644 --- a/src/text/juce_LocalisedStrings.cpp +++ b/src/text/juce_LocalisedStrings.cpp @@ -54,6 +54,23 @@ const String LocalisedStrings::translate (const String& text) const namespace { + #if JUCE_CHECK_MEMORY_LEAKS + // By using this object to force a LocalisedStrings object to be created + // before the currentMappings object, we can force the static order-of-destruction to + // delete the currentMappings object first, which avoids a bogus leak warning. + // (Oddly, just creating a LocalisedStrings on the stack doesn't work in gcc, it + // has to be created with 'new' for this to work..) + struct LeakAvoidanceTrick + { + LeakAvoidanceTrick() + { + const ScopedPointer dummy (new LocalisedStrings (String())); + } + }; + + LeakAvoidanceTrick leakAvoidanceTrick; + #endif + SpinLock currentMappingsLock; ScopedPointer currentMappings; diff --git a/src/text/juce_String.cpp b/src/text/juce_String.cpp index 57597c7dec..7ba38e3429 100644 --- a/src/text/juce_String.cpp +++ b/src/text/juce_String.cpp @@ -215,6 +215,20 @@ private: return reinterpret_cast (reinterpret_cast (text.getAddress()) - (reinterpret_cast (reinterpret_cast (1)->text) - 1)); } + + void compileTimeChecks() + { + // Let me know if any of these assertions fail on your system! + #if JUCE_NATIVE_WCHAR_IS_UTF8 + static_jassert (sizeof (wchar_t) == 1); + #elif JUCE_NATIVE_WCHAR_IS_UTF16 + static_jassert (sizeof (wchar_t) == 2); + #elif JUCE_NATIVE_WCHAR_IS_UTF32 + static_jassert (sizeof (wchar_t) == 4); + #else + #error "native wchar_t size is unknown" + #endif + } }; StringHolder StringHolder::empty;