Browse Source

Rewrote MessageManagerLock (again), hopefully now making it bulletproof. Also gave it an extra constructor and changed the threads section of the juce demo to use messagemanagerlocks to animate its components. Stopped using NSLog on the mac because it's unsafe for non-literal strings. Added a bodge to fake italic fonts on the mac if a real italic is unavailable. Added a new class: CallbackMessage, for triggering a custom callback on the event thread. Updated the RTAS plugin build to use the 8.0 version of the SDK. Fixed a problem with ComponentDraggers when working inside a magnifier component.

tags/2021-05-28
jules 16 years ago
parent
commit
540474d0ce
41 changed files with 2560 additions and 2225 deletions
  1. +0
    -2
      build/linux/platform_specific_code/juce_linux_Windowing.cpp
  2. +4
    -0
      build/macosx/Juce.xcodeproj/project.pbxproj
  3. +0
    -1
      build/macosx/platform_specific_code/juce_mac_AppleRemote.mm
  4. +0
    -2
      build/macosx/platform_specific_code/juce_mac_AudioCDBurner.mm
  5. +3
    -3
      build/macosx/platform_specific_code/juce_mac_Debugging.mm
  6. +6
    -5
      build/macosx/platform_specific_code/juce_mac_Fonts.mm
  7. +0
    -5
      build/macosx/platform_specific_code/juce_mac_MainMenu.mm
  8. +6
    -6
      build/macosx/platform_specific_code/juce_mac_MessageManager.mm
  9. +0
    -25
      build/macosx/platform_specific_code/juce_mac_NSViewComponentPeer.mm
  10. +1
    -1
      build/macosx/platform_specific_code/juce_mac_Network.mm
  11. +0
    -2
      build/macosx/platform_specific_code/juce_mac_WebBrowserComponent.mm
  12. +0
    -2
      build/win32/platform_specific_code/juce_win32_Messaging.cpp
  13. +0
    -2
      build/win32/platform_specific_code/juce_win32_Windowing.cpp
  14. +8
    -2
      build/win32/vc8/JUCE.vcproj
  15. +26
    -24
      extras/audio plugins/How to use this framework.txt
  16. +0
    -1
      extras/audio plugins/wrapper/AU/juce_AU_Wrapper.mm
  17. +32
    -22
      extras/audio plugins/wrapper/RTAS/juce_RTAS_Wrapper.cpp
  18. +0
    -23
      extras/audio plugins/wrapper/VST/juce_VST_Wrapper.cpp
  19. +0
    -1
      extras/juce demo/src/BinaryData.cpp
  20. +30
    -27
      extras/juce demo/src/demos/ThreadingDemo.cpp
  21. +0
    -1
      extras/the jucer/src/BinaryData.cpp
  22. +200
    -120
      juce_amalgamated.cpp
  23. +1734
    -1669
      juce_amalgamated.h
  24. +128
    -124
      src/juce_app_includes.h
  25. +2
    -8
      src/juce_appframework/application/juce_Application.cpp
  26. +15
    -16
      src/juce_appframework/audio/audio_file_formats/flac/libFLAC/stream_decoder.c
  27. +21
    -0
      src/juce_appframework/audio/audio_sources/juce_ResamplingAudioSource.cpp
  28. +0
    -2
      src/juce_appframework/audio/plugins/formats/juce_VSTPluginFormat.cpp
  29. +88
    -0
      src/juce_appframework/events/juce_CallbackMessage.h
  30. +138
    -36
      src/juce_appframework/events/juce_MessageManager.cpp
  31. +41
    -31
      src/juce_appframework/events/juce_MessageManager.h
  32. +7
    -7
      src/juce_appframework/gui/components/controls/juce_TextEditor.h
  33. +8
    -2
      src/juce_appframework/gui/components/controls/juce_TreeView.cpp
  34. +6
    -0
      src/juce_appframework/gui/components/controls/juce_TreeView.h
  35. +1
    -1
      src/juce_appframework/gui/components/juce_Component.h
  36. +5
    -5
      src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp
  37. +5
    -2
      src/juce_appframework/gui/components/mouse/juce_ComponentDragger.cpp
  38. +1
    -1
      src/juce_appframework/gui/components/windows/juce_AlertWindow.h
  39. +1
    -1
      src/juce_appframework/gui/components/windows/juce_ThreadWithProgressWindow.cpp
  40. +1
    -1
      src/juce_appframework/gui/graphics/geometry/juce_Rectangle.h
  41. +42
    -42
      src/juce_core_includes.h

+ 0
- 2
build/linux/platform_specific_code/juce_linux_Windowing.cpp View File

@@ -2595,8 +2595,6 @@ void juce_windowMessageReceive (XEvent* event)
{
LinuxComponentPeer* const peer = LinuxComponentPeer::getPeerFor (event->xany.window);
const MessageManagerLock messLock;
if (ComponentPeer::isValidPeer (peer))
peer->handleWindowMessage (event);
}


+ 4
- 0
build/macosx/Juce.xcodeproj/project.pbxproj View File

@@ -473,6 +473,7 @@
84A48BEB08A22E4B00752A2B /* juce_TimeSliceThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84A48A2508A22E4A00752A2B /* juce_TimeSliceThread.cpp */; };
84A48BEC08A22E4B00752A2B /* juce_TimeSliceThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 84A48A2608A22E4A00752A2B /* juce_TimeSliceThread.h */; };
84A48BED08A22E4B00752A2B /* juce_WaitableEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84A48A2708A22E4A00752A2B /* juce_WaitableEvent.h */; };
84B1C1330F6287E70068E14F /* juce_CallbackMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 84B1C1320F6287E70068E14F /* juce_CallbackMessage.h */; };
84BC4E290C8DD38C00FA249B /* juce_AudioPlayHead.h in Headers */ = {isa = PBXBuildFile; fileRef = 84BC4E210C8DD38C00FA249B /* juce_AudioPlayHead.h */; };
84BC4E2A0C8DD38C00FA249B /* juce_AudioProcessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84BC4E220C8DD38C00FA249B /* juce_AudioProcessor.cpp */; };
84BC4E2B0C8DD38C00FA249B /* juce_AudioProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = 84BC4E230C8DD38C00FA249B /* juce_AudioProcessor.h */; };
@@ -1060,6 +1061,7 @@
84A48A2508A22E4A00752A2B /* juce_TimeSliceThread.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_TimeSliceThread.cpp; path = ../../src/juce_core/threads/juce_TimeSliceThread.cpp; sourceTree = SOURCE_ROOT; };
84A48A2608A22E4A00752A2B /* juce_TimeSliceThread.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce_TimeSliceThread.h; path = ../../src/juce_core/threads/juce_TimeSliceThread.h; sourceTree = SOURCE_ROOT; };
84A48A2708A22E4A00752A2B /* juce_WaitableEvent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce_WaitableEvent.h; path = ../../src/juce_core/threads/juce_WaitableEvent.h; sourceTree = SOURCE_ROOT; };
84B1C1320F6287E70068E14F /* juce_CallbackMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_CallbackMessage.h; sourceTree = "<group>"; };
84BC4E210C8DD38C00FA249B /* juce_AudioPlayHead.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_AudioPlayHead.h; sourceTree = "<group>"; };
84BC4E220C8DD38C00FA249B /* juce_AudioProcessor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = juce_AudioProcessor.cpp; sourceTree = "<group>"; };
84BC4E230C8DD38C00FA249B /* juce_AudioProcessor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_AudioProcessor.h; sourceTree = "<group>"; };
@@ -1495,6 +1497,7 @@
84A4886908A22E4900752A2B /* juce_ActionListenerList.h */,
84A4886A08A22E4900752A2B /* juce_AsyncUpdater.cpp */,
84A4886B08A22E4900752A2B /* juce_AsyncUpdater.h */,
84B1C1320F6287E70068E14F /* juce_CallbackMessage.h */,
84A4886C08A22E4900752A2B /* juce_ChangeBroadcaster.cpp */,
84A4886D08A22E4900752A2B /* juce_ChangeBroadcaster.h */,
84A4886E08A22E4900752A2B /* juce_ChangeListener.h */,
@@ -2547,6 +2550,7 @@
8457783E0E8947C8006D9E4E /* juce_NSViewComponent.h in Headers */,
84E025060E94028C003E41AF /* juce_posix_SharedCode.h in Headers */,
84F8B60D0EB5B9230020D98D /* juce_mac_NativeIncludes.h in Headers */,
84B1C1330F6287E70068E14F /* juce_CallbackMessage.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};


+ 0
- 1
build/macosx/platform_specific_code/juce_mac_AppleRemote.mm View File

@@ -265,7 +265,6 @@ void AppleRemoteDevice::handleCallbackInternal()
{
if (strcmp (cookies, buttonPatterns + i) == 0)
{
const MessageManagerLock mml;
buttonPressed ((ButtonType) buttonNum, totalValues > 0);
break;
}


+ 0
- 2
build/macosx/platform_specific_code/juce_mac_AudioCDBurner.mm View File

@@ -161,8 +161,6 @@ END_JUCE_NAMESPACE
JUCE_NAMESPACE::Thread::sleep (300);
float progress = [[[burn status] objectForKey: DRStatusPercentCompleteKey] floatValue];
NSLog ([[burn status] description]);
if (listener != 0 && listener->audioCDBurnProgress (progress))
{
[burn abort];


+ 3
- 3
build/macosx/platform_specific_code/juce_mac_Debugging.mm View File

@@ -36,8 +36,8 @@
//==============================================================================
void Logger::outputDebugString (const String& text) throw()
{
const ScopedAutoReleasePool pool;
NSLog (juceStringToNS (text + T("\n")));
fputs (text.toUTF8(), stderr);
fputs ("\n", stderr);
}
void Logger::outputDebugPrintf (const tchar* format, ...) throw()
@@ -45,7 +45,7 @@ void Logger::outputDebugPrintf (const tchar* format, ...) throw()
String text;
va_list args;
va_start (args, format);
text.vprintf(format, args);
text.vprintf (format, args);
outputDebugString (text);
}


+ 6
- 5
build/macosx/platform_specific_code/juce_mac_Fonts.mm View File

@@ -41,7 +41,7 @@ class FontHelper
public:
String name;
bool isBold, isItalic;
bool isBold, isItalic, needsItalicTransform;
float fontSize, totalSize, ascent;
int refCount;
NSMutableDictionary* attributes;
@@ -54,6 +54,7 @@ public:
name (name_),
isBold (bold_),
isItalic (italic_),
needsItalicTransform (false),
fontSize (size_),
refCount (1)
{
@@ -67,10 +68,7 @@ public:
NSFont* newFont = [[NSFontManager sharedFontManager] convertFont: font toHaveTrait: NSItalicFontMask];
if (newFont == font)
{
// couldn't find an italic version, so fake it with obliqueness..
[attributes setObject: [NSNumber numberWithFloat: 0.16] forKey: NSObliquenessAttributeName];
}
needsItalicTransform = true; // couldn't find a proper italic version, so fake it with a transform..
font = newFont;
}
@@ -155,6 +153,9 @@ public:
break;
}
}
if (needsItalicTransform)
path->applyTransform (AffineTransform::identity.sheared (-0.15, 0));
}
return kerning != 0;


+ 0
- 5
build/macosx/platform_specific_code/juce_mac_MainMenu.mm View File

@@ -212,16 +212,11 @@ public:
void updateMenus()
{
if (Time::getMillisecondCounter() > lastUpdateTime + 500)
{
const MessageManagerLock mml;
menuBarItemsChanged (0);
}
}
void invoke (const int commandId, ApplicationCommandManager* const commandManager, const int topLevelIndex) const
{
const MessageManagerLock mml;
if (currentModel != 0)
{
if (commandManager != 0)


+ 6
- 6
build/macosx/platform_specific_code/juce_mac_MessageManager.mm View File

@@ -61,7 +61,6 @@ public:
{
if (JUCEApplication::getInstance() != 0)
{
const MessageManagerLock mml;
JUCEApplication::getInstance()->systemRequestedQuit();
return NSTerminateCancel;
}
@@ -73,7 +72,6 @@ public:
{
if (JUCEApplication::getInstance() != 0)
{
const MessageManagerLock mml;
JUCEApplication::getInstance()->anotherInstanceStarted (nsStringToJuce (filename));
return YES;
}
@@ -89,14 +87,12 @@ public:
if (files.size() > 0 && JUCEApplication::getInstance() != 0)
{
const MessageManagerLock mml;
JUCEApplication::getInstance()->anotherInstanceStarted (files.joinIntoString (T(" ")));
}
}
virtual void focusChanged()
{
const MessageManagerLock mml;
juce_HandleProcessFocusChange();
}
@@ -108,11 +104,10 @@ public:
virtual void performCallback (CallbackMessagePayload* pl)
{
const MessageManagerLock mml;
pl->result = (*pl->function) (pl->parameter);
pl->hasBeenExecuted = true;
}
virtual void deleteSelf()
{
delete this;
@@ -357,6 +352,11 @@ void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* call
}
else
{
// If a thread has a MessageManagerLock and then tries to call this method, it'll
// deadlock because the message manager is blocked from running, so can never
// call your function..
jassert (! MessageManager::getInstance()->currentThreadHasLockedMessageManager());
const ScopedAutoReleasePool pool;
CallbackMessagePayload cmp;


+ 0
- 25
build/macosx/platform_specific_code/juce_mac_NSViewComponentPeer.mm View File

@@ -918,8 +918,6 @@ NSRect NSViewComponentPeer::constrainRect (NSRect r)
{
if (constrainer != 0)
{
const MessageManagerLock mml;
NSRect current = [window frame];
current.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - current.origin.y - current.size.height;
@@ -1082,8 +1080,6 @@ void NSViewComponentPeer::setIcon (const Image& /*newIcon*/)
//==============================================================================
void NSViewComponentPeer::viewFocusGain()
{
const MessageManagerLock messLock;
if (currentlyFocusedPeer != this)
{
if (ComponentPeer::isValidPeer (currentlyFocusedPeer))
@@ -1146,8 +1142,6 @@ void NSViewComponentPeer::textInputRequired (int /*x*/, int /*y*/)
bool NSViewComponentPeer::handleKeyEvent (NSEvent* ev, bool isKeyDown)
{
const MessageManagerLock mml;
String unicode (nsStringToJuce ([ev characters]));
String unmodified (nsStringToJuce ([ev charactersIgnoringModifiers]));
int keyCode = getKeyCodeFromEvent (ev);
@@ -1187,7 +1181,6 @@ bool NSViewComponentPeer::handleKeyEvent (NSEvent* ev, bool isKeyDown)
bool NSViewComponentPeer::redirectKeyDown (NSEvent* ev)
{
const MessageManagerLock mml;
updateKeysDown (ev, true);
bool used = handleKeyEvent (ev, true);
@@ -1203,14 +1196,12 @@ bool NSViewComponentPeer::redirectKeyDown (NSEvent* ev)
bool NSViewComponentPeer::redirectKeyUp (NSEvent* ev)
{
const MessageManagerLock mml;
updateKeysDown (ev, false);
return handleKeyEvent (ev, false);
}
void NSViewComponentPeer::redirectModKeyChange (NSEvent* ev)
{
const MessageManagerLock mml;
updateModifiers (ev);
handleModifierKeysChange();
}
@@ -1218,7 +1209,6 @@ void NSViewComponentPeer::redirectModKeyChange (NSEvent* ev)
#if MACOS_10_4_OR_EARLIER
bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev)
{
const MessageManagerLock mml;
if ([ev type] == NSKeyDown)
return redirectKeyDown (ev);
else if ([ev type] == NSKeyUp)
@@ -1231,7 +1221,6 @@ bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev)
//==============================================================================
void NSViewComponentPeer::redirectMouseDown (NSEvent* ev)
{
const MessageManagerLock mml;
updateModifiers (ev);
currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]);
int x, y;
@@ -1242,7 +1231,6 @@ void NSViewComponentPeer::redirectMouseDown (NSEvent* ev)
void NSViewComponentPeer::redirectMouseUp (NSEvent* ev)
{
const MessageManagerLock mml;
const int oldMods = currentModifiers;
updateModifiers (ev);
currentModifiers &= ~getModifierForButtonNumber ([ev buttonNumber]);
@@ -1254,7 +1242,6 @@ void NSViewComponentPeer::redirectMouseUp (NSEvent* ev)
void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev)
{
const MessageManagerLock mml;
updateModifiers (ev);
currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]);
int x, y;
@@ -1265,7 +1252,6 @@ void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev)
void NSViewComponentPeer::redirectMouseMove (NSEvent* ev)
{
const MessageManagerLock mml;
updateModifiers (ev);
int x, y;
getMousePos (ev, view, x, y);
@@ -1275,7 +1261,6 @@ void NSViewComponentPeer::redirectMouseMove (NSEvent* ev)
void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev)
{
const MessageManagerLock mml;
updateModifiers (ev);
int x, y;
getMousePos (ev, view, x, y);
@@ -1285,7 +1270,6 @@ void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev)
void NSViewComponentPeer::redirectMouseExit (NSEvent* ev)
{
const MessageManagerLock mml;
updateModifiers (ev);
int x, y;
getMousePos (ev, view, x, y);
@@ -1295,7 +1279,6 @@ void NSViewComponentPeer::redirectMouseExit (NSEvent* ev)
void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev)
{
const MessageManagerLock mml;
updateModifiers (ev);
handleMouseWheel (roundFloatToInt ([ev deltaX] * 10.0f),
@@ -1306,8 +1289,6 @@ void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev)
//==============================================================================
BOOL NSViewComponentPeer::sendDragCallback (int type, id <NSDraggingInfo> sender)
{
const MessageManagerLock mml;
NSString* bestType
= [[sender draggingPasteboard] availableTypeFromArray: [view getSupportedDragTypes]];
@@ -1358,7 +1339,6 @@ void NSViewComponentPeer::drawRect (NSRect r)
if (r.size.width < 1.0f || r.size.height < 1.0f)
return;
const MessageManagerLock mml;
const float y = [view frame].size.height - (r.origin.y + r.size.height);
JuceNSImage temp ((int) (r.size.width + 0.5f),
@@ -1392,8 +1372,6 @@ void NSViewComponentPeer::drawRect (NSRect r)
bool NSViewComponentPeer::canBecomeKeyWindow()
{
const MessageManagerLock mml;
// If running as a plugin, let the component decide whether it's going to allow the window to get focused.
return JUCEApplication::getInstance() != 0
|| (isValidPeer (this) && getComponent()->getWantsKeyboardFocus());
@@ -1401,8 +1379,6 @@ bool NSViewComponentPeer::canBecomeKeyWindow()
bool NSViewComponentPeer::windowShouldClose()
{
const MessageManagerLock mml;
if (! isValidPeer (this))
return YES;
@@ -1412,7 +1388,6 @@ bool NSViewComponentPeer::windowShouldClose()
void NSViewComponentPeer::redirectMovedOrResized()
{
const MessageManagerLock mml;
handleMovedOrResized();
}


+ 1
- 1
build/macosx/platform_specific_code/juce_mac_Network.mm View File

@@ -284,7 +284,7 @@ public:
- (void) connection: (NSURLConnection*) connection didFailWithError: (NSError*) error
{
NSLog ([error description]);
DBG (nsStringToJuce ([error description]));
hasFailed = true;
initialised = true;
runLoopThread->signalThreadShouldExit();


+ 0
- 2
build/macosx/platform_specific_code/juce_mac_WebBrowserComponent.mm View File

@@ -69,8 +69,6 @@ END_JUCE_NAMESPACE
{
NSURL* url = [actionInformation valueForKey: @"WebActionOriginalURLKey"];
const MessageManagerLock mml;
if (ownerComponent->pageAboutToLoad (nsStringToJuce ([url absoluteString])))
[listener use];
else


+ 0
- 2
build/win32/platform_specific_code/juce_win32_Messaging.cpp View File

@@ -101,8 +101,6 @@ bool juce_dispatchNextMessageOnSystemQueue (const bool returnIfNoPendingMessages
if (GetMessage (&m, (HWND) 0, 0, 0) > 0)
{
const MessageManagerLock mml;
if (m.message == specialId
&& m.hwnd == juce_messageWindowHandle)
{


+ 0
- 2
build/win32/platform_specific_code/juce_win32_Windowing.cpp View File

@@ -1805,8 +1805,6 @@ private:
LRESULT peerWindowProc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
{
{
const MessageManagerLock messLock;
if (isValidPeer (this))
{
switch (message)


+ 8
- 2
build/win32/vc8/JUCE.vcproj View File

@@ -43,7 +43,7 @@
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
MinimalRebuild="false"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
RuntimeTypeInfo="true"
@@ -117,6 +117,7 @@
WholeProgramOptimization="true"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
StringPooling="true"
MinimalRebuild="false"
RuntimeLibrary="0"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
@@ -184,7 +185,7 @@
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;JUCE_DLL_BUILD;JUCE_DLL"
MinimalRebuild="true"
MinimalRebuild="false"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
RuntimeTypeInfo="true"
@@ -269,6 +270,7 @@
WholeProgramOptimization="true"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;JUCE_DLL_BUILD;JUCE_DLL"
StringPooling="true"
MinimalRebuild="false"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
RuntimeTypeInfo="true"
@@ -1222,6 +1224,10 @@
RelativePath="..\..\..\src\juce_appframework\events\juce_AsyncUpdater.h"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\events\juce_CallbackMessage.h"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\events\juce_ChangeBroadcaster.cpp"
>


+ 26
- 24
extras/audio plugins/How to use this framework.txt View File

@@ -87,28 +87,30 @@ make it easier to update to the latest code.
- From the Digidesign website, download their latest Plug-In SDK
- Install the SDK and build some of the demo plugins to make sure it all works.
- In Visual Studio: Add all of these to your include path:
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\EffectClasses
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses\Interfaces
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Utilities
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\RTASP_Adapt
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\CoreClasses
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Controls
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Meters
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ViewClasses
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\DSPClasses
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Interfaces
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\common
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\common\Platform
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\SignalProcessing\Public
c:\yourdirectory\PT_73_SDK\AlturaPorts\SADriver\Interfaces
c:\yourdirectory\PT_73_SDK\AlturaPorts\DigiPublic\Interfaces
c:\yourdirectory\PT_73_SDK\AlturaPorts\Fic\Interfaces\DAEClient
c:\yourdirectory\PT_73_SDK\AlturaPorts\NewFileLibs\Cmn
c:\yourdirectory\PT_73_SDK\AlturaPorts\NewFileLibs\DOA
c:\yourdirectory\PT_73_SDK\AlturaPorts\AlturaSource\PPC_H
c:\yourdirectory\PT_73_SDK\AlturaPorts\AlturaSource\AppSupport
c:\yourdirectory\PT_73_SDK\AvidCode\AVX2sdk\AVX\avx2\avx2sdk\inc
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\EffectClasses
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses\Interfaces
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Utilities
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\RTASP_Adapt
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\CoreClasses
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Controls
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Meters
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ViewClasses
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\DSPClasses
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Interfaces
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\common
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\common\Platform
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\SignalProcessing\Public
C:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugIns\DSPManager\Interfaces
c:\yourdirectory\PT_80_SDK\AlturaPorts\SADriver\Interfaces
c:\yourdirectory\PT_80_SDK\AlturaPorts\DigiPublic\Interfaces
c:\yourdirectory\PT_80_SDK\AlturaPorts\Fic\Interfaces\DAEClient
c:\yourdirectory\PT_80_SDK\AlturaPorts\NewFileLibs\Cmn
c:\yourdirectory\PT_80_SDK\AlturaPorts\NewFileLibs\DOA
c:\yourdirectory\PT_80_SDK\AlturaPorts\AlturaSource\PPC_H
c:\yourdirectory\PT_80_SDK\AlturaPorts\AlturaSource\AppSupport
c:\yourdirectory\PT_80_SDK\AvidCode\AVX2sdk\AVX\avx2\avx2sdk\inc
C:\yourdirectory\PT_80_SDK\xplat\AVX\avx2\avx2sdk\inc
- In Visual Studio: Using the Digidesign demo projects in the SDK, make sure you've compiled
debug and release versions of the following static libraries:
DAE.lib, DigiExt.lib, DSI.lib, PlugInLib.lib.
@@ -267,8 +269,8 @@ If you also want to build an RTAS, then carry on reading...
the "libPluginLibrary.a" item inside it. Drag this subitem down to your Target/"Link Binary With Libraries"
build stage and drop it there to add it to the link process.
- In your Info.plist, change the "Bundle OS Type Code" to "TDMw", and the "Bundle Creator OS Type Code" to
"PTul".
- You may need to remove the "OTHER_CFLAGS = -x c++" from the RTAS settings file to stop it complaining about
"PTul".
- You may need to remove the "OTHER_CFLAGS = -x c++" from the RTAS settings file to stop it complaining about
obj-C code
You should now be able to build an RTAS! Again, just renaming the finished bundle to ".dpm" and


+ 0
- 1
extras/audio plugins/wrapper/AU/juce_AU_Wrapper.mm View File

@@ -617,7 +617,6 @@ public:
#endif
}
OSStatus ProcessBufferLists (AudioUnitRenderActionFlags& ioActionFlags,
const AudioBufferList& inBuffer,
AudioBufferList& outBuffer,


+ 32
- 22
extras/audio plugins/wrapper/RTAS/juce_RTAS_Wrapper.cpp View File

@@ -29,6 +29,12 @@
==============================================================================
*/
#ifdef _MSC_VER
// (this is a workaround for a build problem in VC9)
#define _DO_NOT_DECLARE_INTERLOCKED_INTRINSICS_IN_MEMORY
#include <intrin.h>
#endif
#include "juce_RTAS_DigiCode_Header.h"
#if JucePlugin_Build_RTAS
@@ -43,28 +49,30 @@
To be able to include all the Digidesign headers correctly, you'll need to add this
lot to your include path:
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\EffectClasses
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses\Interfaces
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Utilities
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\RTASP_Adapt
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\CoreClasses
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Controls
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Meters
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ViewClasses
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\DSPClasses
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Interfaces
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\common
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\common\Platform
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\SignalProcessing\Public
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugIns\DSPManager\Interfaces
c:\yourdirectory\PT_711_SDK\AlturaPorts\SADriver\Interfaces
c:\yourdirectory\PT_711_SDK\AlturaPorts\DigiPublic\Interfaces
c:\yourdirectory\PT_711_SDK\AlturaPorts\Fic\Interfaces\DAEClient
c:\yourdirectory\PT_711_SDK\AlturaPorts\NewFileLibs\Cmn
c:\yourdirectory\PT_711_SDK\AlturaPorts\NewFileLibs\DOA
c:\yourdirectory\PT_711_SDK\AlturaPorts\AlturaSource\PPC_H
c:\yourdirectory\PT_711_SDK\AlturaPorts\AlturaSource\AppSupport
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\EffectClasses
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses\Interfaces
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Utilities
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\RTASP_Adapt
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\CoreClasses
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Controls
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Meters
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ViewClasses
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\DSPClasses
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Interfaces
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\common
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\common\Platform
c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\SignalProcessing\Public
C:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugIns\DSPManager\Interfaces
c:\yourdirectory\PT_80_SDK\AlturaPorts\SADriver\Interfaces
c:\yourdirectory\PT_80_SDK\AlturaPorts\DigiPublic\Interfaces
c:\yourdirectory\PT_80_SDK\AlturaPorts\Fic\Interfaces\DAEClient
c:\yourdirectory\PT_80_SDK\AlturaPorts\NewFileLibs\Cmn
c:\yourdirectory\PT_80_SDK\AlturaPorts\NewFileLibs\DOA
c:\yourdirectory\PT_80_SDK\AlturaPorts\AlturaSource\PPC_H
c:\yourdirectory\PT_80_SDK\AlturaPorts\AlturaSource\AppSupport
c:\yourdirectory\PT_80_SDK\AvidCode\AVX2sdk\AVX\avx2\avx2sdk\inc
C:\yourdirectory\PT_80_SDK\xplat\AVX\avx2\avx2sdk\inc
NB. If you hit a huge pile of bugs around here, make sure that you've not got the
Apple QuickTime headers before the PT headers in your path, because there are
@@ -983,7 +991,9 @@ void initialiseMacRTAS();
CProcessGroupInterface* CProcessGroup::CreateProcessGroup()
{
#if JUCE_MAC
initialiseMacRTAS();
#endif
initialiseJuce_NonGUI();
return new JucePlugInGroup();
}


+ 0
- 23
extras/audio plugins/wrapper/VST/juce_VST_Wrapper.cpp View File

@@ -292,12 +292,7 @@ public:
Component* const c = getChildComponent (0);
if (c != 0)
{
#if JUCE_LINUX
const MessageManagerLock mml;
#endif
c->setBounds (0, 0, getWidth(), getHeight());
}
}
void childBoundsChanged (Component* child);
@@ -428,10 +423,6 @@ public:
{
if (editorComp == 0)
{
#if JUCE_LINUX
const MessageManagerLock mml;
#endif
AudioProcessorEditor* const ed = filter->createEditorIfNeeded();
if (ed != 0)
@@ -1086,8 +1077,6 @@ public:
if (MessageManager::getInstance()->isThisTheMessageThread()
&& ! recursionCheck)
{
const MessageManagerLock mml;
recursionCheck = true;
juce_callAnyTimersSynchronously();
@@ -1106,10 +1095,6 @@ public:
if (editorComp == 0)
{
#if JUCE_LINUX
const MessageManagerLock mml;
#endif
AudioProcessorEditor* const ed = filter->createEditorIfNeeded();
if (ed != 0)
@@ -1136,10 +1121,6 @@ public:
jassert (! recursionCheck);
recursionCheck = true;
#if JUCE_LINUX
const MessageManagerLock mml;
#endif
if (editorComp != 0)
{
Component* const modalComponent = Component::getCurrentlyModalComponent();
@@ -1197,10 +1178,6 @@ public:
if (editorComp != 0)
{
#if JUCE_LINUX
const MessageManagerLock mml;
#endif
editorComp->setOpaque (true);
editorComp->setVisible (false);


+ 0
- 1
extras/juce demo/src/BinaryData.cpp View File

@@ -7999,4 +7999,3 @@ static const unsigned char temp17[] = {47,42,13,10,32,32,61,61,61,61,61,61,61,61
111,109,109,97,110,100,77,97,110,97,103,101,114,41,13,10,123,13,10,32,32,32,32,114,101,116,117,114,110,32,110,101,119,32,87,105,100,103,101,116,
115,68,101,109,111,32,40,99,111,109,109,97,110,100,77,97,110,97,103,101,114,41,59,13,10,125,13,10,0,0};
const char* BinaryData::widgetsdemo_cpp = (const char*) temp17;

+ 30
- 27
extras/juce demo/src/demos/ThreadingDemo.cpp View File

@@ -33,13 +33,11 @@
//==============================================================================
class BouncingBallComp : public Component,
public AsyncUpdater
class BouncingBallComp : public Component
{
float x, y, size, dx, dy, w, h, parentWidth, parentHeight;
float innerX, innerY;
Colour colour;
CriticalSection lock;
Thread::ThreadID threadId;
public:
@@ -88,25 +86,8 @@ public:
parentHeight = getParentHeight() - size;
}
void handleAsyncUpdate()
{
const ScopedLock sl (lock);
setBounds (((int) x) - 2,
((int) y) - 2,
((int) size) + 4,
((int) size) + 4);
innerX = x - getX();
innerY = y - getY();
repaint();
}
void moveBall()
{
const ScopedLock sl (lock);
threadId = Thread::getCurrentThreadId(); // this is so the component can print the thread ID inside the ball
x += dx;
@@ -124,10 +105,15 @@ public:
if (y > parentHeight)
dy = -fabsf (dy);
// this is called on a background thread, so we don't want to call
// any UI code from here - instead we'll trigger an event that will update
// the component's position later. This is a safe way to avoid deadlocks
triggerAsyncUpdate();
setBounds (((int) x) - 2,
((int) y) - 2,
((int) size) + 4,
((int) size) + 4);
innerX = x - getX();
innerY = y - getY();
repaint();
}
juce_UseDebuggingNewOperator
@@ -166,10 +152,18 @@ public:
// called, so we should check it often, and exit as soon as it gets flagged.
while (! threadShouldExit())
{
moveBall();
// sleep a bit so the threads don't all grind the CPU to a halt..
wait (interval);
// because this is a background thread, we mustn't do any UI work without
// first grabbing a MessageManagerLock..
const MessageManagerLock mml (Thread::getCurrentThread());
if (! mml.lockWasGained()) // if something is trying to kill this job, the lock
return; // will fail, in which case we'd better return..
// now we've got the UI thread locked, we can mess about with the components
moveBall();
}
}
@@ -196,9 +190,18 @@ public:
// this is the code that runs this job. It'll be repeatedly called until we return
// jobHasFinished instead of jobNeedsRunningAgain.
moveBall();
Thread::sleep (30);
// because this is a background thread, we mustn't do any UI work without
// first grabbing a MessageManagerLock..
const MessageManagerLock mml (this);
// before moving the ball, we need to check whether the lock was actually gained, because
// if something is trying to stop this job, it will have failed..
if (mml.lockWasGained())
moveBall();
return jobNeedsRunningAgain;
}


+ 0
- 1
extras/the jucer/src/BinaryData.cpp View File

@@ -911,4 +911,3 @@ static const unsigned char temp4[] = {137,80,78,71,13,10,26,10,0,0,0,13,73,72,68
0,98,28,9,155,95,0,2,104,68,236,11,1,8,160,17,225,73,128,0,3,0,120,52,172,151,198,78,252,63,0,0,0,0,73,69,78,68,174,66,
96,130,0,0};
const char* BinaryData::prefs_misc_png = (const char*) temp4;

+ 200
- 120
juce_amalgamated.cpp View File

@@ -15680,12 +15680,8 @@ int JUCEApplication::main (String& commandLine, JUCEApplication* const app)
{
juce_setCurrentThreadName ("Juce Message Thread");

{
const MessageManagerLock mml;

// let the app do its setting-up..
app->initialise (app->commandLineParameters);
}
// let the app do its setting-up..
app->initialise (app->commandLineParameters);

// register for broadcast new app messages
MessageManager::getInstance()->registerBroadcastListener (app);
@@ -15732,7 +15728,6 @@ int JUCEApplication::shutdownAppAndClearUp()
JUCE_TRY
{
// give the app a chance to clean up..
const MessageManagerLock mml;
app->shutdown();
}
#if JUCE_CATCH_UNHANDLED_EXCEPTIONS
@@ -15830,7 +15825,6 @@ void JUCE_PUBLIC_FUNCTION shutdownJuce_GUI()
const ScopedAutoReleasePool pool;
#endif
{
const MessageManagerLock mml;
DeletedAtShutdown::deleteAll();

LookAndFeel::clearDefaultLookAndFeel();
@@ -21936,6 +21930,27 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf
for (int i = jmin (2, info.buffer->getNumChannels()); --i >= 0;)
applyFilter (info.buffer->getSampleData (i, info.startSample), info.numSamples, filterStates[i]);
}
else if (ratio <= 1.0001)
{
// if the filter's not currently being applied, keep it stoked with the last couple of samples to avoid discontinuities
for (int i = jmin (2, info.buffer->getNumChannels()); --i >= 0;)
{
const float* const endOfBuffer = info.buffer->getSampleData (i, info.startSample + info.numSamples - 1);
FilterState& fs = filterStates[i];

if (info.numSamples > 1)
{
fs.y2 = fs.x2 = *(endOfBuffer - 1);
}
else
{
fs.y2 = fs.y1;
fs.x2 = fs.x1;
}

fs.y1 = fs.x1 = *endOfBuffer;
}
}

jassert (sampsInBuffer >= 0);
}
@@ -32272,8 +32287,6 @@ VstIntPtr VSTPluginInstance::handleCallback (VstInt32 opcode, VstInt32 index, Vs
if (getActiveEditor() != 0)
dispatch (effEditIdle, 0, 0, 0, 0);
#endif
const MessageManagerLock mml;

juce_callAnyTimersSynchronously();

handleUpdateNowIfNeeded();
@@ -36799,9 +36812,9 @@ static const int quitMessageId = 0xfffff321;
MessageManager::MessageManager() throw()
: broadcastListeners (0),
quitMessagePosted (false),
quitMessageReceived (false)
quitMessageReceived (false),
threadWithLock (0)
{
currentLockingThreadId = 0;
messageThreadId = Thread::getCurrentThreadId();
}

@@ -36832,26 +36845,46 @@ void MessageManager::postMessageToQueue (Message* const message)
delete message;
}

CallbackMessage::CallbackMessage() throw() {}
CallbackMessage::~CallbackMessage() throw() {}

void CallbackMessage::post()
{
if (MessageManager::instance != 0)
MessageManager::instance->postCallbackMessage (this);
}

void MessageManager::postCallbackMessage (Message* const message)
{
message->messageRecipient = 0;
postMessageToQueue (message);
}

// not for public use..
void MessageManager::deliverMessage (void* message)
{
const MessageManagerLock lock;

Message* const m = (Message*) message;
MessageListener* const recipient = m->messageRecipient;

if (messageListeners.contains (recipient))
JUCE_TRY
{
JUCE_TRY
if (messageListeners.contains (recipient))
{
recipient->handleMessage (*m);
}
JUCE_CATCH_EXCEPTION
}
else if (recipient == 0 && m->intParameter1 == quitMessageId)
{
quitMessageReceived = true;
else if (recipient == 0)
{
if (m->intParameter1 == quitMessageId)
{
quitMessageReceived = true;
}
else if (dynamic_cast <CallbackMessage*> (m) != 0)
{
(dynamic_cast <CallbackMessage*> (m))->messageCallback();
}
}
}
JUCE_CATCH_EXCEPTION

delete m;
}
@@ -36926,57 +36959,136 @@ void MessageManager::setCurrentMessageThread (const Thread::ThreadID threadId) t

bool MessageManager::currentThreadHasLockedMessageManager() const throw()
{
return Thread::getCurrentThreadId() == currentLockingThreadId;
const Thread::ThreadID thisThread = Thread::getCurrentThreadId();
return thisThread == messageThreadId || thisThread == threadWithLock;
}

MessageManagerLock::MessageManagerLock() throw()
: lastLockingThreadId (0),
locked (false)
/* The only safe way to lock the message thread while another thread does
some work is by posting a special message, whose purpose is to tie up the event
loop until the other thread has finished its business.

Any other approach can get horribly deadlocked if the OS uses its own hidden locks which
get locked before making an event callback, because if the same OS lock gets indirectly
accessed from another thread inside a MM lock, you're screwed. (this is exactly what happens
in Cocoa).
*/
class SharedLockingEvents : public ReferenceCountedObject
{
if (MessageManager::instance != 0)
public:
SharedLockingEvents() throw() {}
~SharedLockingEvents() {}

/* This class just holds a couple of events to communicate between the MMLockMessage
and the MessageManagerLock. Because both of these objects may be deleted at any time,
this shared data must be kept in a separate, ref-counted container. */
WaitableEvent lockedEvent, releaseEvent;
};

class MMLockMessage : public CallbackMessage
{
public:
MMLockMessage (SharedLockingEvents* const events_) throw()
: events (events_)
{}

~MMLockMessage() throw() {}

ReferenceCountedObjectPtr <SharedLockingEvents> events;

void messageCallback()
{
MessageManager::instance->messageDispatchLock.enter();
lastLockingThreadId = MessageManager::instance->currentLockingThreadId;
MessageManager::instance->currentLockingThreadId = Thread::getCurrentThreadId();
locked = true;
events->lockedEvent.signal();
events->releaseEvent.wait();
}

juce_UseDebuggingNewOperator

MMLockMessage (const MMLockMessage&);
const MMLockMessage& operator= (const MMLockMessage&);
};

MessageManagerLock::MessageManagerLock (Thread* const threadToCheck) throw()
: locked (false),
needsUnlocking (false)
{
init (threadToCheck, 0);
}

MessageManagerLock::MessageManagerLock (Thread* const thread) throw()
: locked (false)
MessageManagerLock::MessageManagerLock (ThreadPoolJob* const jobToCheckForExitSignal) throw()
: locked (false),
needsUnlocking (false)
{
jassert (thread != 0); // This will only work if you give it a valid thread!
init (0, jobToCheckForExitSignal);
}

void MessageManagerLock::init (Thread* const threadToCheck, ThreadPoolJob* const job) throw()
{
if (MessageManager::instance != 0)
{
for (;;)
if (MessageManager::instance->currentThreadHasLockedMessageManager())
{
if (MessageManager::instance->messageDispatchLock.tryEnter())
locked = true; // either we're on the message thread, or this it's a re-entrant call.
}
else
{
if (threadToCheck == 0 && job == 0)
{
locked = true;
lastLockingThreadId = MessageManager::instance->currentLockingThreadId;
MessageManager::instance->currentLockingThreadId = Thread::getCurrentThreadId();
break;
MessageManager::instance->lockingLock.enter();
}
else
{
while (! MessageManager::instance->lockingLock.tryEnter())
{
if ((threadToCheck != 0 && threadToCheck->threadShouldExit())
|| (job != 0 && job->shouldExit()))
return;

if (thread != 0 && thread->threadShouldExit())
break;
Thread::sleep (1);
}
}

Thread::sleep (1);
SharedLockingEvents* const events = new SharedLockingEvents();
sharedEvents = events;
events->incReferenceCount();

(new MMLockMessage (events))->post();

while (! events->lockedEvent.wait (50))
{
if ((threadToCheck != 0 && threadToCheck->threadShouldExit())
|| (job != 0 && job->shouldExit()))
{
events->releaseEvent.signal();
events->decReferenceCount();
MessageManager::instance->lockingLock.exit();
return;
}
}

jassert (MessageManager::instance->threadWithLock == 0);

MessageManager::instance->threadWithLock = Thread::getCurrentThreadId();
locked = true;
needsUnlocking = true;
}
}
}

MessageManagerLock::~MessageManagerLock() throw()
{
if (locked && MessageManager::instance != 0)
if (needsUnlocking && MessageManager::instance != 0)
{
MessageManager::instance->currentLockingThreadId = lastLockingThreadId;
MessageManager::instance->messageDispatchLock.exit();
jassert (MessageManager::instance->currentThreadHasLockedMessageManager());

((SharedLockingEvents*) sharedEvents)->releaseEvent.signal();
((SharedLockingEvents*) sharedEvents)->decReferenceCount();
MessageManager::instance->threadWithLock = 0;
MessageManager::instance->lockingLock.exit();
}
}

END_JUCE_NAMESPACE

/********* End of inlined file: juce_MessageManager.cpp *********/

/********* Start of inlined file: juce_MultiTimer.cpp *********/
@@ -52429,13 +52541,19 @@ void TreeViewItem::treeHasChanged() const throw()

void TreeViewItem::repaintItem() const
{
if (ownerView != 0)
if (ownerView != 0 && areAllParentsOpen())
{
const Rectangle r (getItemPosition (false));
const Rectangle r (getItemPosition (true));
ownerView->viewport->repaint (0, r.getY(), r.getRight(), r.getHeight());
}
}

bool TreeViewItem::areAllParentsOpen() const throw()
{
return parentItem == 0
|| (parentItem->isOpen() && parentItem->areAllParentsOpen());
}

void TreeViewItem::updatePositions (int newY)
{
y = newY;
@@ -65757,8 +65875,8 @@ void ComponentDragger::dragComponent (Component* const componentToDrag, const Mo

if (componentToDrag->isValidComponent())
{
int x = originalX + e.getDistanceFromDragStartX();
int y = originalY + e.getDistanceFromDragStartY();
int x = originalX;
int y = originalY;
int w = componentToDrag->getWidth();
int h = componentToDrag->getHeight();

@@ -65766,6 +65884,9 @@ void ComponentDragger::dragComponent (Component* const componentToDrag, const Mo
if (parentComp != 0)
parentComp->globalPositionToRelative (x, y);

x += e.getDistanceFromDragStartX();
y += e.getDistanceFromDragStartY();

if (constrainer != 0)
constrainer->setBoundsForComponent (componentToDrag, x, y, w, h,
false, false, false, false);
@@ -119536,23 +119657,22 @@ FLAC__StreamDecoderWriteStatus write_audio_frame_to_client_(FLAC__StreamDecoder
return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data);
}
}
else {
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}
}
else {
/*
* If we never got STREAMINFO, turn off MD5 checking to save
* cycles since we don't have a sum to compare to anyway
*/
if(!decoder->private_->has_stream_info)
decoder->private_->do_md5_checking = false;
if(decoder->private_->do_md5_checking) {
if(!FLAC__MD5Accumulate(&decoder->private_->md5context, buffer, frame->header.channels, frame->header.blocksize, (frame->header.bits_per_sample+7) / 8))
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data);

return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}

/*
* If we never got STREAMINFO, turn off MD5 checking to save
* cycles since we don't have a sum to compare to anyway
*/
if(!decoder->private_->has_stream_info)
decoder->private_->do_md5_checking = false;
if(decoder->private_->do_md5_checking) {
if(!FLAC__MD5Accumulate(&decoder->private_->md5context, buffer, frame->header.channels, frame->header.blocksize, (frame->header.bits_per_sample+7) / 8))
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}

return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data);
}

void send_error_to_client_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status)
@@ -242235,8 +242355,6 @@ bool juce_dispatchNextMessageOnSystemQueue (const bool returnIfNoPendingMessages

if (GetMessage (&m, (HWND) 0, 0, 0) > 0)
{
const MessageManagerLock mml;

if (m.message == specialId
&& m.hwnd == juce_messageWindowHandle)
{
@@ -244127,8 +244245,6 @@ private:
LRESULT peerWindowProc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
{
{
const MessageManagerLock messLock;

if (isValidPeer (this))
{
switch (message)
@@ -263070,8 +263186,6 @@ void juce_windowMessageReceive (XEvent* event)
{
LinuxComponentPeer* const peer = LinuxComponentPeer::getPeerFor (event->xany.window);

const MessageManagerLock messLock;

if (ComponentPeer::isValidPeer (peer))
peer->handleWindowMessage (event);
}
@@ -264524,7 +264638,7 @@ public:

- (void) connection: (NSURLConnection*) connection didFailWithError: (NSError*) error
{
NSLog ([error description]);
DBG (nsStringToJuce ([error description]));
hasFailed = true;
initialised = true;
runLoopThread->signalThreadShouldExit();
@@ -266004,8 +266118,8 @@ void juce_updateMultiMonitorInfo (Array <Rectangle>& monitorCoords, const bool c

void Logger::outputDebugString (const String& text) throw()
{
const ScopedAutoReleasePool pool;
NSLog (juceStringToNS (text + T("\n")));
fputs (text.toUTF8(), stderr);
fputs ("\n", stderr);
}

void Logger::outputDebugPrintf (const tchar* format, ...) throw()
@@ -266013,7 +266127,7 @@ void Logger::outputDebugPrintf (const tchar* format, ...) throw()
String text;
va_list args;
va_start (args, format);
text.vprintf(format, args);
text.vprintf (format, args);
outputDebugString (text);
}

@@ -266914,8 +267028,6 @@ NSRect NSViewComponentPeer::constrainRect (NSRect r)
{
if (constrainer != 0)
{
const MessageManagerLock mml;

NSRect current = [window frame];
current.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - current.origin.y - current.size.height;

@@ -267077,8 +267189,6 @@ void NSViewComponentPeer::setIcon (const Image& /*newIcon*/)

void NSViewComponentPeer::viewFocusGain()
{
const MessageManagerLock messLock;

if (currentlyFocusedPeer != this)
{
if (ComponentPeer::isValidPeer (currentlyFocusedPeer))
@@ -267141,8 +267251,6 @@ void NSViewComponentPeer::textInputRequired (int /*x*/, int /*y*/)

bool NSViewComponentPeer::handleKeyEvent (NSEvent* ev, bool isKeyDown)
{
const MessageManagerLock mml;

String unicode (nsStringToJuce ([ev characters]));
String unmodified (nsStringToJuce ([ev charactersIgnoringModifiers]));
int keyCode = getKeyCodeFromEvent (ev);
@@ -267182,7 +267290,6 @@ bool NSViewComponentPeer::handleKeyEvent (NSEvent* ev, bool isKeyDown)

bool NSViewComponentPeer::redirectKeyDown (NSEvent* ev)
{
const MessageManagerLock mml;
updateKeysDown (ev, true);
bool used = handleKeyEvent (ev, true);

@@ -267198,14 +267305,12 @@ bool NSViewComponentPeer::redirectKeyDown (NSEvent* ev)

bool NSViewComponentPeer::redirectKeyUp (NSEvent* ev)
{
const MessageManagerLock mml;
updateKeysDown (ev, false);
return handleKeyEvent (ev, false);
}

void NSViewComponentPeer::redirectModKeyChange (NSEvent* ev)
{
const MessageManagerLock mml;
updateModifiers (ev);
handleModifierKeysChange();
}
@@ -267213,7 +267318,6 @@ void NSViewComponentPeer::redirectModKeyChange (NSEvent* ev)
#if MACOS_10_4_OR_EARLIER
bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev)
{
const MessageManagerLock mml;
if ([ev type] == NSKeyDown)
return redirectKeyDown (ev);
else if ([ev type] == NSKeyUp)
@@ -267225,7 +267329,6 @@ bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev)

void NSViewComponentPeer::redirectMouseDown (NSEvent* ev)
{
const MessageManagerLock mml;
updateModifiers (ev);
currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]);
int x, y;
@@ -267236,7 +267339,6 @@ void NSViewComponentPeer::redirectMouseDown (NSEvent* ev)

void NSViewComponentPeer::redirectMouseUp (NSEvent* ev)
{
const MessageManagerLock mml;
const int oldMods = currentModifiers;
updateModifiers (ev);
currentModifiers &= ~getModifierForButtonNumber ([ev buttonNumber]);
@@ -267248,7 +267350,6 @@ void NSViewComponentPeer::redirectMouseUp (NSEvent* ev)

void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev)
{
const MessageManagerLock mml;
updateModifiers (ev);
currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]);
int x, y;
@@ -267259,7 +267360,6 @@ void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev)

void NSViewComponentPeer::redirectMouseMove (NSEvent* ev)
{
const MessageManagerLock mml;
updateModifiers (ev);
int x, y;
getMousePos (ev, view, x, y);
@@ -267269,7 +267369,6 @@ void NSViewComponentPeer::redirectMouseMove (NSEvent* ev)

void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev)
{
const MessageManagerLock mml;
updateModifiers (ev);
int x, y;
getMousePos (ev, view, x, y);
@@ -267279,7 +267378,6 @@ void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev)

void NSViewComponentPeer::redirectMouseExit (NSEvent* ev)
{
const MessageManagerLock mml;
updateModifiers (ev);
int x, y;
getMousePos (ev, view, x, y);
@@ -267289,7 +267387,6 @@ void NSViewComponentPeer::redirectMouseExit (NSEvent* ev)

void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev)
{
const MessageManagerLock mml;
updateModifiers (ev);

handleMouseWheel (roundFloatToInt ([ev deltaX] * 10.0f),
@@ -267299,8 +267396,6 @@ void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev)

BOOL NSViewComponentPeer::sendDragCallback (int type, id <NSDraggingInfo> sender)
{
const MessageManagerLock mml;

NSString* bestType
= [[sender draggingPasteboard] availableTypeFromArray: [view getSupportedDragTypes]];

@@ -267351,7 +267446,6 @@ void NSViewComponentPeer::drawRect (NSRect r)
if (r.size.width < 1.0f || r.size.height < 1.0f)
return;

const MessageManagerLock mml;
const float y = [view frame].size.height - (r.origin.y + r.size.height);

JuceNSImage temp ((int) (r.size.width + 0.5f),
@@ -267385,8 +267479,6 @@ void NSViewComponentPeer::drawRect (NSRect r)

bool NSViewComponentPeer::canBecomeKeyWindow()
{
const MessageManagerLock mml;

// If running as a plugin, let the component decide whether it's going to allow the window to get focused.
return JUCEApplication::getInstance() != 0
|| (isValidPeer (this) && getComponent()->getWantsKeyboardFocus());
@@ -267394,8 +267486,6 @@ bool NSViewComponentPeer::canBecomeKeyWindow()

bool NSViewComponentPeer::windowShouldClose()
{
const MessageManagerLock mml;

if (! isValidPeer (this))
return YES;

@@ -267405,7 +267495,6 @@ bool NSViewComponentPeer::windowShouldClose()

void NSViewComponentPeer::redirectMovedOrResized()
{
const MessageManagerLock mml;
handleMovedOrResized();
}

@@ -268036,7 +268125,6 @@ void AppleRemoteDevice::handleCallbackInternal()
{
if (strcmp (cookies, buttonPatterns + i) == 0)
{
const MessageManagerLock mml;
buttonPressed ((ButtonType) buttonNum, totalValues > 0);
break;
}
@@ -268515,16 +268603,11 @@ public:
void updateMenus()
{
if (Time::getMillisecondCounter() > lastUpdateTime + 500)
{
const MessageManagerLock mml;
menuBarItemsChanged (0);
}
}

void invoke (const int commandId, ApplicationCommandManager* const commandManager, const int topLevelIndex) const
{
const MessageManagerLock mml;

if (currentModel != 0)
{
if (commandManager != 0)
@@ -269336,8 +269419,6 @@ END_JUCE_NAMESPACE
JUCE_NAMESPACE::Thread::sleep (300);
float progress = [[[burn status] objectForKey: DRStatusPercentCompleteKey] floatValue];

NSLog ([[burn status] description]);

if (listener != 0 && listener->audioCDBurnProgress (progress))
{
[burn abort];
@@ -269618,7 +269699,7 @@ class FontHelper

public:
String name;
bool isBold, isItalic;
bool isBold, isItalic, needsItalicTransform;
float fontSize, totalSize, ascent;
int refCount;
NSMutableDictionary* attributes;
@@ -269631,6 +269712,7 @@ public:
name (name_),
isBold (bold_),
isItalic (italic_),
needsItalicTransform (false),
fontSize (size_),
refCount (1)
{
@@ -269644,10 +269726,7 @@ public:
NSFont* newFont = [[NSFontManager sharedFontManager] convertFont: font toHaveTrait: NSItalicFontMask];

if (newFont == font)
{
// couldn't find an italic version, so fake it with obliqueness..
[attributes setObject: [NSNumber numberWithFloat: 0.16] forKey: NSObliquenessAttributeName];
}
needsItalicTransform = true; // couldn't find a proper italic version, so fake it with a transform..

font = newFont;
}
@@ -269732,6 +269811,9 @@ public:
break;
}
}

if (needsItalicTransform)
path->applyTransform (AffineTransform::identity.sheared (-0.15, 0));
}

return kerning != 0;
@@ -269962,7 +270044,6 @@ public:
{
if (JUCEApplication::getInstance() != 0)
{
const MessageManagerLock mml;
JUCEApplication::getInstance()->systemRequestedQuit();
return NSTerminateCancel;
}
@@ -269974,7 +270055,6 @@ public:
{
if (JUCEApplication::getInstance() != 0)
{
const MessageManagerLock mml;
JUCEApplication::getInstance()->anotherInstanceStarted (nsStringToJuce (filename));
return YES;
}
@@ -269990,14 +270070,12 @@ public:

if (files.size() > 0 && JUCEApplication::getInstance() != 0)
{
const MessageManagerLock mml;
JUCEApplication::getInstance()->anotherInstanceStarted (files.joinIntoString (T(" ")));
}
}

virtual void focusChanged()
{
const MessageManagerLock mml;
juce_HandleProcessFocusChange();
}

@@ -270009,7 +270087,6 @@ public:

virtual void performCallback (CallbackMessagePayload* pl)
{
const MessageManagerLock mml;
pl->result = (*pl->function) (pl->parameter);
pl->hasBeenExecuted = true;
}
@@ -270257,6 +270334,11 @@ void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* call
}
else
{
// If a thread has a MessageManagerLock and then tries to call this method, it'll
// deadlock because the message manager is blocked from running, so can never
// call your function..
jassert (! MessageManager::getInstance()->currentThreadHasLockedMessageManager());

const ScopedAutoReleasePool pool;

CallbackMessagePayload cmp;
@@ -270316,8 +270398,6 @@ END_JUCE_NAMESPACE
{
NSURL* url = [actionInformation valueForKey: @"WebActionOriginalURLKey"];

const MessageManagerLock mml;

if (ownerComponent->pageAboutToLoad (nsStringToJuce ([url absoluteString])))
[listener use];
else


+ 1734
- 1669
juce_amalgamated.h
File diff suppressed because it is too large
View File


+ 128
- 124
src/juce_app_includes.h View File

@@ -29,8 +29,8 @@
==============================================================================
*/
#ifndef __JUCE_APP_INCLUDES_JUCEHEADER__
#define __JUCE_APP_INCLUDES_JUCEHEADER__
#ifndef __JUCE_JUCE_APP_INCLUDES_INCLUDEFILES__
#define __JUCE_JUCE_APP_INCLUDES_INCLUDEFILES__
#ifndef __JUCE_APPLICATION_JUCEHEADER__
#include "juce_appframework/application/juce_Application.h"
@@ -197,6 +197,18 @@
#ifndef __JUCE_PLUGINLISTCOMPONENT_JUCEHEADER__
#include "juce_appframework/audio/plugins/juce_PluginListComponent.h"
#endif
#ifndef __JUCE_FLACAUDIOFORMAT_JUCEHEADER__
#include "juce_appframework/audio/audio_file_formats/juce_FlacAudioFormat.h"
#endif
#ifndef __JUCE_WAVAUDIOFORMAT_JUCEHEADER__
#include "juce_appframework/audio/audio_file_formats/juce_WavAudioFormat.h"
#endif
#ifndef __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__
#include "juce_appframework/audio/audio_file_formats/juce_OggVorbisAudioFormat.h"
#endif
#ifndef __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__
#include "juce_appframework/audio/audio_file_formats/juce_QuickTimeAudioFormat.h"
#endif
#ifndef __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__
#include "juce_appframework/audio/audio_file_formats/juce_AiffAudioFormat.h"
#endif
@@ -227,17 +239,27 @@
#ifndef __JUCE_AUDIOTHUMBNAILCACHE_JUCEHEADER__
#include "juce_appframework/audio/audio_file_formats/juce_AudioThumbnailCache.h"
#endif
#ifndef __JUCE_FLACAUDIOFORMAT_JUCEHEADER__
#include "juce_appframework/audio/audio_file_formats/juce_FlacAudioFormat.h"
#ifndef __JUCE_INTERPROCESSCONNECTIONSERVER_JUCEHEADER__
#include "juce_appframework/events/juce_InterprocessConnectionServer.h"
#endif
#ifndef __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__
#include "juce_appframework/audio/audio_file_formats/juce_OggVorbisAudioFormat.h"
#ifndef __JUCE_MESSAGE_JUCEHEADER__
#include "juce_appframework/events/juce_Message.h"
#endif
#ifndef __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__
#include "juce_appframework/audio/audio_file_formats/juce_QuickTimeAudioFormat.h"
#ifndef __JUCE_TIMER_JUCEHEADER__
#include "juce_appframework/events/juce_Timer.h"
#endif
#ifndef __JUCE_WAVAUDIOFORMAT_JUCEHEADER__
#include "juce_appframework/audio/audio_file_formats/juce_WavAudioFormat.h"
#ifndef __JUCE_MESSAGELISTENER_JUCEHEADER__
#include "juce_appframework/events/juce_MessageListener.h"
#endif
#ifndef __JUCE_MULTITIMER_JUCEHEADER__
#include "juce_appframework/events/juce_MultiTimer.h"
#endif
#ifndef __JUCE_MESSAGEMANAGER_JUCEHEADER__
#include "juce_appframework/events/juce_MessageManager.h"
#endif
#include "juce_appframework/events/._juce_CallbackMessage.h"
#ifndef __JUCE_CALLBACKMESSAGE_JUCEHEADER__
#include "juce_appframework/events/juce_CallbackMessage.h"
#endif
#ifndef __JUCE_ACTIONBROADCASTER_JUCEHEADER__
#include "juce_appframework/events/juce_ActionBroadcaster.h"
@@ -263,24 +285,6 @@
#ifndef __JUCE_INTERPROCESSCONNECTION_JUCEHEADER__
#include "juce_appframework/events/juce_InterprocessConnection.h"
#endif
#ifndef __JUCE_INTERPROCESSCONNECTIONSERVER_JUCEHEADER__
#include "juce_appframework/events/juce_InterprocessConnectionServer.h"
#endif
#ifndef __JUCE_MESSAGE_JUCEHEADER__
#include "juce_appframework/events/juce_Message.h"
#endif
#ifndef __JUCE_MESSAGELISTENER_JUCEHEADER__
#include "juce_appframework/events/juce_MessageListener.h"
#endif
#ifndef __JUCE_MESSAGEMANAGER_JUCEHEADER__
#include "juce_appframework/events/juce_MessageManager.h"
#endif
#ifndef __JUCE_MULTITIMER_JUCEHEADER__
#include "juce_appframework/events/juce_MultiTimer.h"
#endif
#ifndef __JUCE_TIMER_JUCEHEADER__
#include "juce_appframework/events/juce_Timer.h"
#endif
#ifndef __JUCE_BRUSH_JUCEHEADER__
#include "juce_appframework/gui/graphics/brushes/juce_Brush.h"
#endif
@@ -338,9 +342,6 @@
#ifndef __JUCE_RECTANGLEPLACEMENT_JUCEHEADER__
#include "juce_appframework/gui/graphics/contexts/juce_RectanglePlacement.h"
#endif
#ifndef __JUCE_AFFINETRANSFORM_JUCEHEADER__
#include "juce_appframework/gui/graphics/geometry/juce_AffineTransform.h"
#endif
#ifndef __JUCE_BORDERSIZE_JUCEHEADER__
#include "juce_appframework/gui/graphics/geometry/juce_BorderSize.h"
#endif
@@ -362,11 +363,14 @@
#ifndef __JUCE_POSITIONEDRECTANGLE_JUCEHEADER__
#include "juce_appframework/gui/graphics/geometry/juce_PositionedRectangle.h"
#endif
#ifndef __JUCE_RECTANGLELIST_JUCEHEADER__
#include "juce_appframework/gui/graphics/geometry/juce_RectangleList.h"
#endif
#ifndef __JUCE_RECTANGLE_JUCEHEADER__
#include "juce_appframework/gui/graphics/geometry/juce_Rectangle.h"
#endif
#ifndef __JUCE_RECTANGLELIST_JUCEHEADER__
#include "juce_appframework/gui/graphics/geometry/juce_RectangleList.h"
#ifndef __JUCE_AFFINETRANSFORM_JUCEHEADER__
#include "juce_appframework/gui/graphics/geometry/juce_AffineTransform.h"
#endif
#ifndef __JUCE_IMAGE_JUCEHEADER__
#include "juce_appframework/gui/graphics/imaging/juce_Image.h"
@@ -395,9 +399,6 @@
#ifndef __JUCE_DRAWABLETEXT_JUCEHEADER__
#include "juce_appframework/gui/graphics/drawables/juce_DrawableText.h"
#endif
#ifndef __JUCE_COMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/juce_Component.h"
#endif
#ifndef __JUCE_COMPONENTDELETIONWATCHER_JUCEHEADER__
#include "juce_appframework/gui/components/juce_ComponentDeletionWatcher.h"
#endif
@@ -407,14 +408,8 @@
#ifndef __JUCE_DESKTOP_JUCEHEADER__
#include "juce_appframework/gui/components/juce_Desktop.h"
#endif
#ifndef __JUCE_ARROWBUTTON_JUCEHEADER__
#include "juce_appframework/gui/components/buttons/juce_ArrowButton.h"
#endif
#ifndef __JUCE_BUTTON_JUCEHEADER__
#include "juce_appframework/gui/components/buttons/juce_Button.h"
#endif
#ifndef __JUCE_DRAWABLEBUTTON_JUCEHEADER__
#include "juce_appframework/gui/components/buttons/juce_DrawableButton.h"
#ifndef __JUCE_COMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/juce_Component.h"
#endif
#ifndef __JUCE_HYPERLINKBUTTON_JUCEHEADER__
#include "juce_appframework/gui/components/buttons/juce_HyperlinkButton.h"
@@ -434,6 +429,15 @@
#ifndef __JUCE_TOOLBARBUTTON_JUCEHEADER__
#include "juce_appframework/gui/components/buttons/juce_ToolbarButton.h"
#endif
#ifndef __JUCE_ARROWBUTTON_JUCEHEADER__
#include "juce_appframework/gui/components/buttons/juce_ArrowButton.h"
#endif
#ifndef __JUCE_BUTTON_JUCEHEADER__
#include "juce_appframework/gui/components/buttons/juce_Button.h"
#endif
#ifndef __JUCE_DRAWABLEBUTTON_JUCEHEADER__
#include "juce_appframework/gui/components/buttons/juce_DrawableButton.h"
#endif
#ifndef __JUCE_DROPSHADOWEFFECT_JUCEHEADER__
#include "juce_appframework/gui/graphics/effects/juce_DropShadowEffect.h"
#endif
@@ -476,12 +480,6 @@
#ifndef __JUCE_POPUPMENUCUSTOMCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/menus/juce_PopupMenuCustomComponent.h"
#endif
#ifndef __JUCE_COMPONENTDRAGGER_JUCEHEADER__
#include "juce_appframework/gui/components/mouse/juce_ComponentDragger.h"
#endif
#ifndef __JUCE_DRAGANDDROPCONTAINER_JUCEHEADER__
#include "juce_appframework/gui/components/mouse/juce_DragAndDropContainer.h"
#endif
#ifndef __JUCE_DRAGANDDROPTARGET_JUCEHEADER__
#include "juce_appframework/gui/components/mouse/juce_DragAndDropTarget.h"
#endif
@@ -506,47 +504,59 @@
#ifndef __JUCE_TOOLTIPCLIENT_JUCEHEADER__
#include "juce_appframework/gui/components/mouse/juce_TooltipClient.h"
#endif
#ifndef __JUCE_COMPONENTDRAGGER_JUCEHEADER__
#include "juce_appframework/gui/components/mouse/juce_ComponentDragger.h"
#endif
#ifndef __JUCE_DRAGANDDROPCONTAINER_JUCEHEADER__
#include "juce_appframework/gui/components/mouse/juce_DragAndDropContainer.h"
#endif
#ifndef __JUCE_TOOLBARITEMFACTORY_JUCEHEADER__
#include "juce_appframework/gui/components/controls/juce_ToolbarItemFactory.h"
#endif
#ifndef __JUCE_TOOLBARITEMPALETTE_JUCEHEADER__
#include "juce_appframework/gui/components/controls/juce_ToolbarItemPalette.h"
#endif
#ifndef __JUCE_SLIDER_JUCEHEADER__
#include "juce_appframework/gui/components/controls/juce_Slider.h"
#endif
#ifndef __JUCE_TOOLBARITEMCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/controls/juce_ToolbarItemComponent.h"
#endif
#ifndef __JUCE_TREEVIEW_JUCEHEADER__
#include "juce_appframework/gui/components/controls/juce_TreeView.h"
#endif
#ifndef __JUCE_TEXTEDITOR_JUCEHEADER__
#include "juce_appframework/gui/components/controls/juce_TextEditor.h"
#endif
#ifndef __JUCE_COMBOBOX_JUCEHEADER__
#include "juce_appframework/gui/components/controls/juce_ComboBox.h"
#endif
#ifndef __JUCE_LABEL_JUCEHEADER__
#include "juce_appframework/gui/components/controls/juce_Label.h"
#endif
#ifndef __JUCE_LISTBOX_JUCEHEADER__
#include "juce_appframework/gui/components/controls/juce_ListBox.h"
#endif
#ifndef __JUCE_PROGRESSBAR_JUCEHEADER__
#include "juce_appframework/gui/components/controls/juce_ProgressBar.h"
#endif
#ifndef __JUCE_SLIDER_JUCEHEADER__
#include "juce_appframework/gui/components/controls/juce_Slider.h"
#endif
#ifndef __JUCE_SLIDERLISTENER_JUCEHEADER__
#include "juce_appframework/gui/components/controls/juce_SliderListener.h"
#endif
#ifndef __JUCE_TABLEHEADERCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/controls/juce_TableHeaderComponent.h"
#endif
#ifndef __JUCE_TABLELISTBOX_JUCEHEADER__
#include "juce_appframework/gui/components/controls/juce_TableListBox.h"
#endif
#ifndef __JUCE_TEXTEDITOR_JUCEHEADER__
#include "juce_appframework/gui/components/controls/juce_TextEditor.h"
#ifndef __JUCE_TABLEHEADERCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/controls/juce_TableHeaderComponent.h"
#endif
#ifndef __JUCE_TOOLBAR_JUCEHEADER__
#include "juce_appframework/gui/components/controls/juce_Toolbar.h"
#endif
#ifndef __JUCE_TOOLBARITEMCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/controls/juce_ToolbarItemComponent.h"
#endif
#ifndef __JUCE_TOOLBARITEMFACTORY_JUCEHEADER__
#include "juce_appframework/gui/components/controls/juce_ToolbarItemFactory.h"
#ifndef __JUCE_LABEL_JUCEHEADER__
#include "juce_appframework/gui/components/controls/juce_Label.h"
#endif
#ifndef __JUCE_TOOLBARITEMPALETTE_JUCEHEADER__
#include "juce_appframework/gui/components/controls/juce_ToolbarItemPalette.h"
#ifndef __JUCE_SLIDERPROPERTYCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/properties/juce_SliderPropertyComponent.h"
#endif
#ifndef __JUCE_TREEVIEW_JUCEHEADER__
#include "juce_appframework/gui/components/controls/juce_TreeView.h"
#ifndef __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/properties/juce_TextPropertyComponent.h"
#endif
#ifndef __JUCE_BOOLEANPROPERTYCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/properties/juce_BooleanPropertyComponent.h"
@@ -563,54 +573,66 @@
#ifndef __JUCE_PROPERTYPANEL_JUCEHEADER__
#include "juce_appframework/gui/components/properties/juce_PropertyPanel.h"
#endif
#ifndef __JUCE_SLIDERPROPERTYCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/properties/juce_SliderPropertyComponent.h"
#endif
#ifndef __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/properties/juce_TextPropertyComponent.h"
#endif
#ifndef __JUCE_COMPONENTANIMATOR_JUCEHEADER__
#include "juce_appframework/gui/components/layout/juce_ComponentAnimator.h"
#endif
#ifndef __JUCE_COMPONENTBOUNDSCONSTRAINER_JUCEHEADER__
#include "juce_appframework/gui/components/layout/juce_ComponentBoundsConstrainer.h"
#ifndef __JUCE_MULTIDOCUMENTPANEL_JUCEHEADER__
#include "juce_appframework/gui/components/layout/juce_MultiDocumentPanel.h"
#endif
#ifndef __JUCE_COMPONENTMOVEMENTWATCHER_JUCEHEADER__
#include "juce_appframework/gui/components/layout/juce_ComponentMovementWatcher.h"
#endif
#ifndef __JUCE_GROUPCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/layout/juce_GroupComponent.h"
#endif
#ifndef __JUCE_MULTIDOCUMENTPANEL_JUCEHEADER__
#include "juce_appframework/gui/components/layout/juce_MultiDocumentPanel.h"
#endif
#ifndef __JUCE_RESIZABLEBORDERCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/layout/juce_ResizableBorderComponent.h"
#endif
#ifndef __JUCE_RESIZABLECORNERCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/layout/juce_ResizableCornerComponent.h"
#endif
#ifndef __JUCE_SCROLLBAR_JUCEHEADER__
#include "juce_appframework/gui/components/layout/juce_ScrollBar.h"
#endif
#ifndef __JUCE_TABBEDBUTTONBAR_JUCEHEADER__
#include "juce_appframework/gui/components/layout/juce_TabbedButtonBar.h"
#endif
#ifndef __JUCE_RESIZABLECORNERCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/layout/juce_ResizableCornerComponent.h"
#endif
#ifndef __JUCE_STRETCHABLELAYOUTMANAGER_JUCEHEADER__
#include "juce_appframework/gui/components/layout/juce_StretchableLayoutManager.h"
#endif
#ifndef __JUCE_TABBEDCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/layout/juce_TabbedComponent.h"
#endif
#ifndef __JUCE_STRETCHABLELAYOUTRESIZERBAR_JUCEHEADER__
#include "juce_appframework/gui/components/layout/juce_StretchableLayoutResizerBar.h"
#endif
#ifndef __JUCE_STRETCHABLEOBJECTRESIZER_JUCEHEADER__
#include "juce_appframework/gui/components/layout/juce_StretchableObjectResizer.h"
#endif
#ifndef __JUCE_TABBEDBUTTONBAR_JUCEHEADER__
#include "juce_appframework/gui/components/layout/juce_TabbedButtonBar.h"
#endif
#ifndef __JUCE_TABBEDCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/layout/juce_TabbedComponent.h"
#endif
#ifndef __JUCE_VIEWPORT_JUCEHEADER__
#include "juce_appframework/gui/components/layout/juce_Viewport.h"
#endif
#ifndef __JUCE_COMPONENTANIMATOR_JUCEHEADER__
#include "juce_appframework/gui/components/layout/juce_ComponentAnimator.h"
#endif
#ifndef __JUCE_COMPONENTBOUNDSCONSTRAINER_JUCEHEADER__
#include "juce_appframework/gui/components/layout/juce_ComponentBoundsConstrainer.h"
#endif
#ifndef __JUCE_GROUPCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/layout/juce_GroupComponent.h"
#endif
#ifndef __JUCE_FILENAMECOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/filebrowser/juce_FilenameComponent.h"
#endif
#ifndef __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/filebrowser/juce_FilePreviewComponent.h"
#endif
#ifndef __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/filebrowser/juce_FileSearchPathListComponent.h"
#endif
#ifndef __JUCE_FILETREECOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/filebrowser/juce_FileTreeComponent.h"
#endif
#ifndef __JUCE_WILDCARDFILEFILTER_JUCEHEADER__
#include "juce_appframework/gui/components/filebrowser/juce_WildcardFileFilter.h"
#endif
#ifndef __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/filebrowser/juce_ImagePreviewComponent.h"
#endif
#ifndef __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/filebrowser/juce_DirectoryContentsDisplayComponent.h"
#endif
@@ -635,24 +657,6 @@
#ifndef __JUCE_FILELISTCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/filebrowser/juce_FileListComponent.h"
#endif
#ifndef __JUCE_FILENAMECOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/filebrowser/juce_FilenameComponent.h"
#endif
#ifndef __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/filebrowser/juce_FilePreviewComponent.h"
#endif
#ifndef __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/filebrowser/juce_FileSearchPathListComponent.h"
#endif
#ifndef __JUCE_FILETREECOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/filebrowser/juce_FileTreeComponent.h"
#endif
#ifndef __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/filebrowser/juce_ImagePreviewComponent.h"
#endif
#ifndef __JUCE_WILDCARDFILEFILTER_JUCEHEADER__
#include "juce_appframework/gui/components/filebrowser/juce_WildcardFileFilter.h"
#endif
#ifndef __JUCE_ALERTWINDOW_JUCEHEADER__
#include "juce_appframework/gui/components/windows/juce_AlertWindow.h"
#endif
@@ -671,15 +675,21 @@
#ifndef __JUCE_SPLASHSCREEN_JUCEHEADER__
#include "juce_appframework/gui/components/windows/juce_SplashScreen.h"
#endif
#ifndef __JUCE_THREADWITHPROGRESSWINDOW_JUCEHEADER__
#include "juce_appframework/gui/components/windows/juce_ThreadWithProgressWindow.h"
#endif
#ifndef __JUCE_TOOLTIPWINDOW_JUCEHEADER__
#include "juce_appframework/gui/components/windows/juce_TooltipWindow.h"
#endif
#ifndef __JUCE_THREADWITHPROGRESSWINDOW_JUCEHEADER__
#include "juce_appframework/gui/components/windows/juce_ThreadWithProgressWindow.h"
#endif
#ifndef __JUCE_TOPLEVELWINDOW_JUCEHEADER__
#include "juce_appframework/gui/components/windows/juce_TopLevelWindow.h"
#endif
#ifndef __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/special/juce_SystemTrayIconComponent.h"
#endif
#ifndef __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/special/juce_WebBrowserComponent.h"
#endif
#ifndef __JUCE_ACTIVEXCONTROLCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/special/juce_ActiveXControlComponent.h"
#endif
@@ -716,12 +726,6 @@
#ifndef __JUCE_QUICKTIMEMOVIECOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/special/juce_QuickTimeMovieComponent.h"
#endif
#ifndef __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/special/juce_SystemTrayIconComponent.h"
#endif
#ifndef __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/special/juce_WebBrowserComponent.h"
#endif
#ifndef __JUCE_LOOKANDFEEL_JUCEHEADER__
#include "juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.h"
#endif
@@ -744,4 +748,4 @@
#include "juce_appframework/documents/juce_UndoManager.h"
#endif
#endif // __JUCE_APP_INCLUDES_JUCEHEADER__
#endif

+ 2
- 8
src/juce_appframework/application/juce_Application.cpp View File

@@ -194,12 +194,8 @@ int JUCEApplication::main (String& commandLine, JUCEApplication* const app)
{
juce_setCurrentThreadName ("Juce Message Thread");
{
const MessageManagerLock mml;
// let the app do its setting-up..
app->initialise (app->commandLineParameters);
}
// let the app do its setting-up..
app->initialise (app->commandLineParameters);
// register for broadcast new app messages
MessageManager::getInstance()->registerBroadcastListener (app);
@@ -246,7 +242,6 @@ int JUCEApplication::shutdownAppAndClearUp()
JUCE_TRY
{
// give the app a chance to clean up..
const MessageManagerLock mml;
app->shutdown();
}
#if JUCE_CATCH_UNHANDLED_EXCEPTIONS
@@ -346,7 +341,6 @@ void JUCE_PUBLIC_FUNCTION shutdownJuce_GUI()
const ScopedAutoReleasePool pool;
#endif
{
const MessageManagerLock mml;
DeletedAtShutdown::deleteAll();
LookAndFeel::clearDefaultLookAndFeel();


+ 15
- 16
src/juce_appframework/audio/audio_file_formats/flac/libFLAC/stream_decoder.c View File

@@ -2945,23 +2945,22 @@ FLAC__StreamDecoderWriteStatus write_audio_frame_to_client_(FLAC__StreamDecoder
return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data);
}
}
else {
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}
}
else {
/*
* If we never got STREAMINFO, turn off MD5 checking to save
* cycles since we don't have a sum to compare to anyway
*/
if(!decoder->private_->has_stream_info)
decoder->private_->do_md5_checking = false;
if(decoder->private_->do_md5_checking) {
if(!FLAC__MD5Accumulate(&decoder->private_->md5context, buffer, frame->header.channels, frame->header.blocksize, (frame->header.bits_per_sample+7) / 8))
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data);
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}
/*
* If we never got STREAMINFO, turn off MD5 checking to save
* cycles since we don't have a sum to compare to anyway
*/
if(!decoder->private_->has_stream_info)
decoder->private_->do_md5_checking = false;
if(decoder->private_->do_md5_checking) {
if(!FLAC__MD5Accumulate(&decoder->private_->md5context, buffer, frame->header.channels, frame->header.blocksize, (frame->header.bits_per_sample+7) / 8))
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data);
}
void send_error_to_client_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status)


+ 21
- 0
src/juce_appframework/audio/audio_sources/juce_ResamplingAudioSource.cpp View File

@@ -179,6 +179,27 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf
for (int i = jmin (2, info.buffer->getNumChannels()); --i >= 0;)
applyFilter (info.buffer->getSampleData (i, info.startSample), info.numSamples, filterStates[i]);
}
else if (ratio <= 1.0001)
{
// if the filter's not currently being applied, keep it stoked with the last couple of samples to avoid discontinuities
for (int i = jmin (2, info.buffer->getNumChannels()); --i >= 0;)
{
const float* const endOfBuffer = info.buffer->getSampleData (i, info.startSample + info.numSamples - 1);
FilterState& fs = filterStates[i];
if (info.numSamples > 1)
{
fs.y2 = fs.x2 = *(endOfBuffer - 1);
}
else
{
fs.y2 = fs.y1;
fs.x2 = fs.x1;
}
fs.y1 = fs.x1 = *endOfBuffer;
}
}
jassert (sampsInBuffer >= 0);
}


+ 0
- 2
src/juce_appframework/audio/plugins/formats/juce_VSTPluginFormat.cpp View File

@@ -2339,8 +2339,6 @@ VstIntPtr VSTPluginInstance::handleCallback (VstInt32 opcode, VstInt32 index, Vs
if (getActiveEditor() != 0)
dispatch (effEditIdle, 0, 0, 0, 0);
#endif
const MessageManagerLock mml;
juce_callAnyTimersSynchronously();
handleUpdateNowIfNeeded();


+ 88
- 0
src/juce_appframework/events/juce_CallbackMessage.h View File

@@ -0,0 +1,88 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the
GNU General Public License, as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.
JUCE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef __JUCE_CALLBACKMESSAGE_JUCEHEADER__
#define __JUCE_CALLBACKMESSAGE_JUCEHEADER__
#include "juce_Message.h"
//==============================================================================
/**
A message that calls a custom function when it gets delivered.
You can use this class to fire off actions that you want to be performed later
on the message thread.
Unlike other Message objects, these don't get sent to a MessageListener, you
just call the post() method to send them, and when they arrive, your
messageCallback() method will automatically be invoked.
@see MessageListener, MessageManager, ActionListener, ChangeListener
*/
class JUCE_API CallbackMessage : public Message
{
public:
//==============================================================================
CallbackMessage() throw();
/** Destructor. */
~CallbackMessage() throw();
//==============================================================================
/** Called when the message is delivered.
You should implement this method and make it do whatever action you want
to perform.
Note that like all other messages, this object will be deleted immediately
after this method has been invoked.
*/
virtual void messageCallback() = 0;
/** Instead of sending this message to a MessageListener, just call this method
to post it to the event queue.
After you've called this, this object will belong to the MessageManager,
which will delete it later. So make sure you don't delete the object yourself,
call post() more than once, or call post() on a stack-based obect!
*/
void post();
//==============================================================================
juce_UseDebuggingNewOperator
private:
CallbackMessage (const CallbackMessage&);
const CallbackMessage& operator= (const CallbackMessage&);
};
#endif // __JUCE_CALLBACKMESSAGE_JUCEHEADER__

+ 138
- 36
src/juce_appframework/events/juce_MessageManager.cpp View File

@@ -38,6 +38,7 @@ BEGIN_JUCE_NAMESPACE
#include "../application/juce_Application.h"
#include "../gui/components/juce_Component.h"
#include "../../juce_core/threads/juce_Thread.h"
#include "../../juce_core/threads/juce_ScopedLock.h"
#include "../../juce_core/basics/juce_Time.h"
@@ -46,7 +47,6 @@ BEGIN_JUCE_NAMESPACE
bool juce_dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages);
bool juce_postMessageToSystemQueue (void* message);
//==============================================================================
MessageManager* MessageManager::instance = 0;
@@ -55,9 +55,9 @@ static const int quitMessageId = 0xfffff321;
MessageManager::MessageManager() throw()
: broadcastListeners (0),
quitMessagePosted (false),
quitMessageReceived (false)
quitMessageReceived (false),
threadWithLock (0)
{
currentLockingThreadId = 0;
messageThreadId = Thread::getCurrentThreadId();
}
@@ -88,27 +88,48 @@ void MessageManager::postMessageToQueue (Message* const message)
delete message;
}
//==============================================================================
CallbackMessage::CallbackMessage() throw() {}
CallbackMessage::~CallbackMessage() throw() {}
void CallbackMessage::post()
{
if (MessageManager::instance != 0)
MessageManager::instance->postCallbackMessage (this);
}
void MessageManager::postCallbackMessage (Message* const message)
{
message->messageRecipient = 0;
postMessageToQueue (message);
}
//==============================================================================
// not for public use..
void MessageManager::deliverMessage (void* message)
{
const MessageManagerLock lock;
Message* const m = (Message*) message;
MessageListener* const recipient = m->messageRecipient;
if (messageListeners.contains (recipient))
JUCE_TRY
{
JUCE_TRY
if (messageListeners.contains (recipient))
{
recipient->handleMessage (*m);
}
JUCE_CATCH_EXCEPTION
}
else if (recipient == 0 && m->intParameter1 == quitMessageId)
{
quitMessageReceived = true;
else if (recipient == 0)
{
if (m->intParameter1 == quitMessageId)
{
quitMessageReceived = true;
}
else if (dynamic_cast <CallbackMessage*> (m) != 0)
{
(dynamic_cast <CallbackMessage*> (m))->messageCallback();
}
}
}
JUCE_CATCH_EXCEPTION
delete m;
}
@@ -186,54 +207,135 @@ void MessageManager::setCurrentMessageThread (const Thread::ThreadID threadId) t
bool MessageManager::currentThreadHasLockedMessageManager() const throw()
{
return Thread::getCurrentThreadId() == currentLockingThreadId;
const Thread::ThreadID thisThread = Thread::getCurrentThreadId();
return thisThread == messageThreadId || thisThread == threadWithLock;
}
//==============================================================================
MessageManagerLock::MessageManagerLock() throw()
: lastLockingThreadId (0),
locked (false)
//==============================================================================
/* The only safe way to lock the message thread while another thread does
some work is by posting a special message, whose purpose is to tie up the event
loop until the other thread has finished its business.
Any other approach can get horribly deadlocked if the OS uses its own hidden locks which
get locked before making an event callback, because if the same OS lock gets indirectly
accessed from another thread inside a MM lock, you're screwed. (this is exactly what happens
in Cocoa).
*/
class SharedLockingEvents : public ReferenceCountedObject
{
if (MessageManager::instance != 0)
public:
SharedLockingEvents() throw() {}
~SharedLockingEvents() {}
/* This class just holds a couple of events to communicate between the MMLockMessage
and the MessageManagerLock. Because both of these objects may be deleted at any time,
this shared data must be kept in a separate, ref-counted container. */
WaitableEvent lockedEvent, releaseEvent;
};
class MMLockMessage : public CallbackMessage
{
public:
MMLockMessage (SharedLockingEvents* const events_) throw()
: events (events_)
{}
~MMLockMessage() throw() {}
ReferenceCountedObjectPtr <SharedLockingEvents> events;
void messageCallback()
{
MessageManager::instance->messageDispatchLock.enter();
lastLockingThreadId = MessageManager::instance->currentLockingThreadId;
MessageManager::instance->currentLockingThreadId = Thread::getCurrentThreadId();
locked = true;
events->lockedEvent.signal();
events->releaseEvent.wait();
}
juce_UseDebuggingNewOperator
MMLockMessage (const MMLockMessage&);
const MMLockMessage& operator= (const MMLockMessage&);
};
//==============================================================================
MessageManagerLock::MessageManagerLock (Thread* const threadToCheck) throw()
: locked (false),
needsUnlocking (false)
{
init (threadToCheck, 0);
}
MessageManagerLock::MessageManagerLock (Thread* const thread) throw()
: locked (false)
MessageManagerLock::MessageManagerLock (ThreadPoolJob* const jobToCheckForExitSignal) throw()
: locked (false),
needsUnlocking (false)
{
jassert (thread != 0); // This will only work if you give it a valid thread!
init (0, jobToCheckForExitSignal);
}
void MessageManagerLock::init (Thread* const threadToCheck, ThreadPoolJob* const job) throw()
{
if (MessageManager::instance != 0)
{
for (;;)
if (MessageManager::instance->currentThreadHasLockedMessageManager())
{
locked = true; // either we're on the message thread, or this it's a re-entrant call.
}
else
{
if (MessageManager::instance->messageDispatchLock.tryEnter())
if (threadToCheck == 0 && job == 0)
{
MessageManager::instance->lockingLock.enter();
}
else
{
while (! MessageManager::instance->lockingLock.tryEnter())
{
if ((threadToCheck != 0 && threadToCheck->threadShouldExit())
|| (job != 0 && job->shouldExit()))
return;
Thread::sleep (1);
}
}
SharedLockingEvents* const events = new SharedLockingEvents();
sharedEvents = events;
events->incReferenceCount();
(new MMLockMessage (events))->post();
while (! events->lockedEvent.wait (50))
{
locked = true;
lastLockingThreadId = MessageManager::instance->currentLockingThreadId;
MessageManager::instance->currentLockingThreadId = Thread::getCurrentThreadId();
break;
if ((threadToCheck != 0 && threadToCheck->threadShouldExit())
|| (job != 0 && job->shouldExit()))
{
events->releaseEvent.signal();
events->decReferenceCount();
MessageManager::instance->lockingLock.exit();
return;
}
}
if (thread != 0 && thread->threadShouldExit())
break;
jassert (MessageManager::instance->threadWithLock == 0);
Thread::sleep (1);
MessageManager::instance->threadWithLock = Thread::getCurrentThreadId();
locked = true;
needsUnlocking = true;
}
}
}
MessageManagerLock::~MessageManagerLock() throw()
{
if (locked && MessageManager::instance != 0)
if (needsUnlocking && MessageManager::instance != 0)
{
MessageManager::instance->currentLockingThreadId = lastLockingThreadId;
MessageManager::instance->messageDispatchLock.exit();
jassert (MessageManager::instance->currentThreadHasLockedMessageManager());
((SharedLockingEvents*) sharedEvents)->releaseEvent.signal();
((SharedLockingEvents*) sharedEvents)->decReferenceCount();
MessageManager::instance->threadWithLock = 0;
MessageManager::instance->lockingLock.exit();
}
}


+ 41
- 31
src/juce_appframework/events/juce_MessageManager.h View File

@@ -36,7 +36,9 @@
#include "../../juce_core/containers/juce_SortedSet.h"
#include "../../juce_core/containers/juce_VoidArray.h"
#include "../../juce_core/threads/juce_Thread.h"
#include "../../juce_core/threads/juce_ThreadPool.h"
#include "juce_ActionListenerList.h"
#include "juce_CallbackMessage.h"
class Component;
class MessageManagerLock;
@@ -175,6 +177,7 @@ private:
friend class MessageListener;
friend class ChangeBroadcaster;
friend class ActionBroadcaster;
friend class CallbackMessage;
static MessageManager* instance;
SortedSet<const MessageListener*> messageListeners;
@@ -188,13 +191,14 @@ private:
static void* exitModalLoopCallback (void*);
void postMessageToQueue (Message* const message);
void postCallbackMessage (Message* const message);
static void doPlatformSpecificInitialisation();
static void doPlatformSpecificShutdown();
friend class MessageManagerLock;
CriticalSection messageDispatchLock;
Thread::ThreadID currentLockingThreadId;
Thread::ThreadID volatile threadWithLock;
CriticalSection lockingLock;
MessageManager (const MessageManager&);
const MessageManager& operator= (const MessageManager&);
@@ -239,36 +243,23 @@ public:
//==============================================================================
/** Tries to acquire a lock on the message manager.
If this constructor
When this constructor returns, the message manager will have finished processing the
last message and will not send another message until this MessageManagerLock is
deleted.
The constructor attempts to gain a lock on the message loop, and the lock will be
kept for the lifetime of this object.
If the current thread already has the lock, nothing will be done, so it's perfectly
safe to create these locks recursively.
*/
MessageManagerLock() throw();
/** Releases the current thread's lock on the message manager.
Make sure this object is created and deleted by the same thread,
otherwise there are no guarantees what will happen!
*/
~MessageManagerLock() throw();
//==============================================================================
/** Tries to acquire a lock on the message manager.
This does the same thing as the normal constructor, but while it's waiting to get
the lock, it checks the specified thread to see if it has been given the
Optionally, you can pass a thread object here, and while waiting to obtain the lock,
this method will keep checking whether the thread has been given the
Thread::signalThreadShouldExit() signal. If this happens, then it will return
without gaining the lock.
without gaining the lock. If you pass a thread, you must check whether the lock was
successful by calling lockWasGained(). If this is false, your thread is being told to
die, so you should take evasive action.
To find out whether the lock was successful, call lockWasGained(). If this is
false, your thread is being told to die, so you'd better get out of there.
If you pass zero for the thread object, it will wait indefinitely for the lock - be
careful when doing this, because it's very easy to deadlock if your message thread
attempts to call stopThread() on a thread just as that thread attempts to get the
message lock.
If the current thread already has the lock, nothing will be done, so it's perfectly
safe to create these locks recursively.
If the calling thread already has the lock, nothing will be done, so it's safe and
quick to use these locks recursively.
E.g.
@code
@@ -291,9 +282,26 @@ public:
@endcode
*/
MessageManagerLock (Thread* const threadToCheckForExitSignal) throw();
MessageManagerLock (Thread* const threadToCheckForExitSignal = 0) throw();
//==============================================================================
/** This has the same behaviour as the other constructor, but takes a ThreadPoolJob
instead of a thread.
See the MessageManagerLock (Thread*) constructor for details on how this works.
*/
MessageManagerLock (ThreadPoolJob* const jobToCheckForExitSignal) throw();
//==============================================================================
/** Releases the current thread's lock on the message manager.
Make sure this object is created and deleted by the same thread,
otherwise there are no guarantees what will happen!
*/
~MessageManagerLock() throw();
//==============================================================================
/** Returns true if the lock was successfully acquired.
(See the constructor that takes a Thread for more info).
@@ -302,8 +310,10 @@ public:
private:
Thread::ThreadID lastLockingThreadId;
bool locked;
bool locked, needsUnlocking;
void* sharedEvents;
void init (Thread* const thread, ThreadPoolJob* const job) throw();
};


+ 7
- 7
src/juce_appframework/gui/components/controls/juce_TextEditor.h View File

@@ -467,6 +467,13 @@ l */
*/
int getTextIndexAt (const int x, const int y) throw();
/** Counts the number of characters in the text.
This is quicker than getting the text as a string if you just need to know
the length.
*/
int getTotalNumChars() throw();
/** Returns the total width of the text, as it is currently laid-out.
This may be larger than the size of the TextEditor, and can change when
@@ -590,13 +597,6 @@ protected:
/** Used internally to dispatch a text-change message. */
void textChanged() throw();
/** Counts the number of characters in the text.
This is quicker than getting the text as a string if you just need to know
the length.
*/
int getTotalNumChars() throw();
/** Begins a new transaction in the UndoManager.
*/
void newTransaction() throw();


+ 8
- 2
src/juce_appframework/gui/components/controls/juce_TreeView.cpp View File

@@ -1006,13 +1006,19 @@ void TreeViewItem::treeHasChanged() const throw()
void TreeViewItem::repaintItem() const
{
if (ownerView != 0)
if (ownerView != 0 && areAllParentsOpen())
{
const Rectangle r (getItemPosition (false));
const Rectangle r (getItemPosition (true));
ownerView->viewport->repaint (0, r.getY(), r.getRight(), r.getHeight());
}
}
bool TreeViewItem::areAllParentsOpen() const throw()
{
return parentItem == 0
|| (parentItem->isOpen() && parentItem->areAllParentsOpen());
}
void TreeViewItem::updatePositions (int newY)
{
y = newY;


+ 6
- 0
src/juce_appframework/gui/components/controls/juce_TreeView.h View File

@@ -166,6 +166,12 @@ public:
*/
int getRowNumberInTree() const throw();
/** Returns true if all the item's parent nodes are open.
This is useful to check whether the item might actually be visible or not.
*/
bool areAllParentsOpen() const throw();
/** Changes whether lines are drawn to connect any sub-items to this item.
By default, line-drawing is turned on.


+ 1
- 1
src/juce_appframework/gui/components/juce_Component.h View File

@@ -1774,7 +1774,7 @@ public:
of the components in this list is the reverse of the order in which they became
modal - so the component at index 0 is always the active component, and the others
are progressively earlier ones that are themselves now blocked by later ones.
@returns the modal component, or null if no components are modal (or if the
index is out of range)
@see getNumCurrentlyModalComponents, runModalLoop, isCurrentlyModal


+ 5
- 5
src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp View File

@@ -476,7 +476,7 @@ AlertWindow* LookAndFeel::createAlertWindow (const String& title,
Component* associatedComponent)
{
AlertWindow* aw = new AlertWindow (title, message, iconType);
if (numButtons == 1)
{
aw->addButton (button1, 0,
@@ -489,7 +489,7 @@ AlertWindow* LookAndFeel::createAlertWindow (const String& title,
KeyPress button2ShortCut (CharacterFunctions::toLowerCase (button2[0]), 0, 0);
if (button1ShortCut == button2ShortCut)
button2ShortCut = KeyPress();
if (numButtons == 2)
{
aw->addButton (button1, 1, KeyPress (KeyPress::returnKey, 0, 0), button1ShortCut);
@@ -498,7 +498,7 @@ AlertWindow* LookAndFeel::createAlertWindow (const String& title,
else
{
jassert (numButtons == 3);
aw->addButton (button1, 1, button1ShortCut);
aw->addButton (button2, 2, button2ShortCut);
aw->addButton (button3, 0, KeyPress (KeyPress::escapeKey, 0, 0));
@@ -538,8 +538,8 @@ void LookAndFeel::drawAlertBox (Graphics& g,
colour = 0x55ff5555;
character = '!';
icon.addTriangle (iconRect.getX() + iconRect.getWidth() * 0.5f, (float) iconRect.getY(),
(float) iconRect.getRight(), (float) iconRect.getBottom(),
icon.addTriangle (iconRect.getX() + iconRect.getWidth() * 0.5f, (float) iconRect.getY(),
(float) iconRect.getRight(), (float) iconRect.getBottom(),
(float) iconRect.getX(), (float) iconRect.getBottom());
icon = icon.createPathWithRoundedCorners (5.0f);


+ 5
- 2
src/juce_appframework/gui/components/mouse/juce_ComponentDragger.cpp View File

@@ -71,8 +71,8 @@ void ComponentDragger::dragComponent (Component* const componentToDrag, const Mo
if (componentToDrag->isValidComponent())
{
int x = originalX + e.getDistanceFromDragStartX();
int y = originalY + e.getDistanceFromDragStartY();
int x = originalX;
int y = originalY;
int w = componentToDrag->getWidth();
int h = componentToDrag->getHeight();
@@ -80,6 +80,9 @@ void ComponentDragger::dragComponent (Component* const componentToDrag, const Mo
if (parentComp != 0)
parentComp->globalPositionToRelative (x, y);
x += e.getDistanceFromDragStartX();
y += e.getDistanceFromDragStartY();
if (constrainer != 0)
constrainer->setBoundsForComponent (componentToDrag, x, y, w, h,
false, false, false, false);


+ 1
- 1
src/juce_appframework/gui/components/windows/juce_AlertWindow.h View File

@@ -294,7 +294,7 @@ public:
@param associatedComponent if this is non-zero, it specifies the component that the
alert window should be associated with. Depending on the look
and feel, this might be used for positioning of the alert window.
@returns one of the following values:
- 0 if the third button was pressed (normally used for 'cancel')
- 1 if the first button was pressed (normally used for 'yes')


+ 1
- 1
src/juce_appframework/gui/components/windows/juce_ThreadWithProgressWindow.cpp View File

@@ -50,7 +50,7 @@ ThreadWithProgressWindow::ThreadWithProgressWindow (const String& title,
timeOutMsWhenCancelling (timeOutMsWhenCancelling_)
{
alertWindow = LookAndFeel::getDefaultLookAndFeel()
.createAlertWindow (title, String::empty, cancelButtonText, String::empty, String::empty,
.createAlertWindow (title, String::empty, cancelButtonText, String::empty, String::empty,
AlertWindow::NoIcon, 1, 0);
if (hasProgressBar)


+ 1
- 1
src/juce_appframework/gui/graphics/geometry/juce_Rectangle.h View File

@@ -123,7 +123,7 @@ public:
@see getBottom
*/
void setBottom (const int newBottom) throw();
/** Moves the rectangle's position by adding amount to its x and y co-ordinates. */
void translate (const int deltaX,
const int deltaY) throw();


+ 42
- 42
src/juce_core_includes.h View File

@@ -32,21 +32,9 @@
#ifndef __JUCE_JUCE_CORE_INCLUDES_INCLUDEFILES__
#define __JUCE_JUCE_CORE_INCLUDES_INCLUDEFILES__
#ifndef __JUCE_ATOMIC_JUCEHEADER__
#include "juce_core/basics/juce_Atomic.h"
#endif
#ifndef __JUCE_DATACONVERSIONS_JUCEHEADER__
#include "juce_core/basics/juce_DataConversions.h"
#endif
#ifndef __JUCE_FILELOGGER_JUCEHEADER__
#include "juce_core/basics/juce_FileLogger.h"
#endif
#ifndef __JUCE_INITIALISATION_JUCEHEADER__
#include "juce_core/basics/juce_Initialisation.h"
#endif
#ifndef __JUCE_LOGGER_JUCEHEADER__
#include "juce_core/basics/juce_Logger.h"
#endif
#ifndef __JUCE_MATHSFUNCTIONS_JUCEHEADER__
#include "juce_core/basics/juce_MathsFunctions.h"
#endif
@@ -74,6 +62,30 @@
#ifndef __JUCE_TIME_JUCEHEADER__
#include "juce_core/basics/juce_Time.h"
#endif
#ifndef __JUCE_ATOMIC_JUCEHEADER__
#include "juce_core/basics/juce_Atomic.h"
#endif
#ifndef __JUCE_DATACONVERSIONS_JUCEHEADER__
#include "juce_core/basics/juce_DataConversions.h"
#endif
#ifndef __JUCE_FILELOGGER_JUCEHEADER__
#include "juce_core/basics/juce_FileLogger.h"
#endif
#ifndef __JUCE_LOGGER_JUCEHEADER__
#include "juce_core/basics/juce_Logger.h"
#endif
#ifndef __JUCE_REFERENCECOUNTEDARRAY_JUCEHEADER__
#include "juce_core/containers/juce_ReferenceCountedArray.h"
#endif
#ifndef __JUCE_REFERENCECOUNTEDOBJECT_JUCEHEADER__
#include "juce_core/containers/juce_ReferenceCountedObject.h"
#endif
#ifndef __JUCE_SPARSESET_JUCEHEADER__
#include "juce_core/containers/juce_SparseSet.h"
#endif
#ifndef __JUCE_VOIDARRAY_JUCEHEADER__
#include "juce_core/containers/juce_VoidArray.h"
#endif
#ifndef __JUCE_ARRAY_JUCEHEADER__
#include "juce_core/containers/juce_Array.h"
#endif
@@ -95,21 +107,9 @@
#ifndef __JUCE_PROPERTYSET_JUCEHEADER__
#include "juce_core/containers/juce_PropertySet.h"
#endif
#ifndef __JUCE_REFERENCECOUNTEDARRAY_JUCEHEADER__
#include "juce_core/containers/juce_ReferenceCountedArray.h"
#endif
#ifndef __JUCE_REFERENCECOUNTEDOBJECT_JUCEHEADER__
#include "juce_core/containers/juce_ReferenceCountedObject.h"
#endif
#ifndef __JUCE_SORTEDSET_JUCEHEADER__
#include "juce_core/containers/juce_SortedSet.h"
#endif
#ifndef __JUCE_SPARSESET_JUCEHEADER__
#include "juce_core/containers/juce_SparseSet.h"
#endif
#ifndef __JUCE_VOIDARRAY_JUCEHEADER__
#include "juce_core/containers/juce_VoidArray.h"
#endif
#ifndef __JUCE_INPUTSTREAM_JUCEHEADER__
#include "juce_core/io/juce_InputStream.h"
#endif
@@ -152,6 +152,12 @@
#ifndef __JUCE_URL_JUCEHEADER__
#include "juce_core/io/network/juce_URL.h"
#endif
#ifndef __JUCE_MEMORYOUTPUTSTREAM_JUCEHEADER__
#include "juce_core/io/streams/juce_MemoryOutputStream.h"
#endif
#ifndef __JUCE_SUBREGIONSTREAM_JUCEHEADER__
#include "juce_core/io/streams/juce_SubregionStream.h"
#endif
#ifndef __JUCE_BUFFEREDINPUTSTREAM_JUCEHEADER__
#include "juce_core/io/streams/juce_BufferedInputStream.h"
#endif
@@ -170,12 +176,6 @@
#ifndef __JUCE_MEMORYINPUTSTREAM_JUCEHEADER__
#include "juce_core/io/streams/juce_MemoryInputStream.h"
#endif
#ifndef __JUCE_MEMORYOUTPUTSTREAM_JUCEHEADER__
#include "juce_core/io/streams/juce_MemoryOutputStream.h"
#endif
#ifndef __JUCE_SUBREGIONSTREAM_JUCEHEADER__
#include "juce_core/io/streams/juce_SubregionStream.h"
#endif
#ifndef __JUCE_PERFORMANCECOUNTER_JUCEHEADER__
#include "juce_core/misc/juce_PerformanceCounter.h"
#endif
@@ -209,6 +209,18 @@
#ifndef __JUCE_XMLELEMENT_JUCEHEADER__
#include "juce_core/text/juce_XmlElement.h"
#endif
#ifndef __JUCE_THREAD_JUCEHEADER__
#include "juce_core/threads/juce_Thread.h"
#endif
#ifndef __JUCE_THREADPOOL_JUCEHEADER__
#include "juce_core/threads/juce_ThreadPool.h"
#endif
#ifndef __JUCE_TIMESLICETHREAD_JUCEHEADER__
#include "juce_core/threads/juce_TimeSliceThread.h"
#endif
#ifndef __JUCE_WAITABLEEVENT_JUCEHEADER__
#include "juce_core/threads/juce_WaitableEvent.h"
#endif
#ifndef __JUCE_CRITICALSECTION_JUCEHEADER__
#include "juce_core/threads/juce_CriticalSection.h"
#endif
@@ -233,17 +245,5 @@
#ifndef __JUCE_SCOPEDWRITELOCK_JUCEHEADER__
#include "juce_core/threads/juce_ScopedWriteLock.h"
#endif
#ifndef __JUCE_THREAD_JUCEHEADER__
#include "juce_core/threads/juce_Thread.h"
#endif
#ifndef __JUCE_THREADPOOL_JUCEHEADER__
#include "juce_core/threads/juce_ThreadPool.h"
#endif
#ifndef __JUCE_TIMESLICETHREAD_JUCEHEADER__
#include "juce_core/threads/juce_TimeSliceThread.h"
#endif
#ifndef __JUCE_WAITABLEEVENT_JUCEHEADER__
#include "juce_core/threads/juce_WaitableEvent.h"
#endif
#endif

Loading…
Cancel
Save