1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-25 02:04:23 +00:00

Changed the Message class to be reference-counted, and used this to tighten up some messaging code. Minor tweaks to AudioThumbnail, ReferenceCountedArray.

This commit is contained in:
Julian Storer 2010-12-19 19:33:52 +00:00
parent 1a887cda63
commit d60f661789
22 changed files with 573 additions and 527 deletions

View file

@ -63,6 +63,7 @@ BEGIN_JUCE_NAMESPACE
#include "../application/juce_Application.h"
#include "../utilities/juce_SystemClipboard.h"
#include "../events/juce_MessageManager.h"
#include "../containers/juce_ReferenceCountedArray.h"
#include "../gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h"
#include "../gui/graphics/imaging/juce_ImageFileFormat.h"
#include "../gui/graphics/imaging/juce_CameraDevice.h"
@ -112,6 +113,74 @@ namespace
}
}
//==============================================================================
class MessageQueue
{
public:
MessageQueue()
{
#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 && ! JUCE_IOS
runLoop = CFRunLoopGetMain();
#else
runLoop = CFRunLoopGetCurrent();
#endif
CFRunLoopSourceContext sourceContext;
zerostruct (sourceContext);
sourceContext.info = this;
sourceContext.perform = runLoopSourceCallback;
runLoopSource = CFRunLoopSourceCreate (kCFAllocatorDefault, 1, &sourceContext);
CFRunLoopAddSource (runLoop, runLoopSource, kCFRunLoopCommonModes);
}
~MessageQueue()
{
CFRunLoopRemoveSource (runLoop, runLoopSource, kCFRunLoopCommonModes);
CFRunLoopSourceInvalidate (runLoopSource);
CFRelease (runLoopSource);
}
void post (Message* const message)
{
messages.add (message);
CFRunLoopSourceSignal (runLoopSource);
CFRunLoopWakeUp (runLoop);
}
private:
ReferenceCountedArray <Message, CriticalSection> messages;
CriticalSection lock;
CFRunLoopRef runLoop;
CFRunLoopSourceRef runLoopSource;
bool deliverNextMessage()
{
const Message::Ptr nextMessage (messages.removeAndReturn (0));
if (nextMessage == 0)
return false;
const ScopedAutoReleasePool pool;
MessageManager::getInstance()->deliverMessage (nextMessage);
return true;
}
void runLoopCallback()
{
for (int i = 4; --i >= 0;)
if (! deliverNextMessage())
return;
CFRunLoopSourceSignal (runLoopSource);
CFRunLoopWakeUp (runLoop);
}
static void runLoopSourceCallback (void* info)
{
static_cast <MessageQueue*> (info)->runLoopCallback();
}
};
//==============================================================================
#define JUCE_INCLUDED_FILE 1

View file

@ -153,7 +153,7 @@ public:
private:
CriticalSection lock;
OwnedArray <Message> queue;
ReferenceCountedArray <Message> queue;
int fd[2];
int bytesInSocket;
int totalEventCount;
@ -193,15 +193,15 @@ private:
return true;
}
Message* popNextMessage()
const Message::Ptr popNextMessage()
{
ScopedLock sl (lock);
const ScopedLock sl (lock);
if (bytesInSocket > 0)
{
--bytesInSocket;
ScopedUnlock ul (lock);
const ScopedUnlock ul (lock);
unsigned char x;
size_t numBytes = read (fd[1], &x, 1);
(void) numBytes;
@ -212,7 +212,7 @@ private:
bool dispatchNextInternalMessage()
{
ScopedPointer <Message> msg (popNextMessage());
const Message::Ptr msg (popNextMessage());
if (msg == 0)
return false;
@ -228,7 +228,7 @@ private:
else
{
// Handle "normal" messages
MessageManager::getInstance()->deliverMessage (msg.release());
MessageManager::getInstance()->deliverMessage (msg);
}
return true;

View file

@ -107,79 +107,41 @@ bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor)
}
//==============================================================================
namespace iOSMessageLoopHelpers
struct MessageDispatchSystem
{
static CFRunLoopRef runLoop = 0;
static CFRunLoopSourceRef runLoopSource = 0;
static OwnedArray <Message, CriticalSection>* pendingMessages = 0;
static JuceCustomMessageHandler* juceCustomMessageHandler = 0;
void runLoopSourceCallback (void*)
MessageDispatchSystem()
: juceCustomMessageHandler (0)
{
if (pendingMessages != 0)
{
int numDispatched = 0;
do
{
Message* const nextMessage = pendingMessages->removeAndReturn (0);
if (nextMessage == 0)
return;
const ScopedAutoReleasePool pool;
MessageManager::getInstance()->deliverMessage (nextMessage);
} while (++numDispatched <= 4);
CFRunLoopSourceSignal (runLoopSource);
CFRunLoopWakeUp (runLoop);
}
juceCustomMessageHandler = [[JuceCustomMessageHandler alloc] init];
}
}
~MessageDispatchSystem()
{
[[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget: juceCustomMessageHandler];
[juceCustomMessageHandler release];
}
JuceCustomMessageHandler* juceCustomMessageHandler;
MessageQueue messageQueue;
};
static MessageDispatchSystem* dispatcher = 0;
void MessageManager::doPlatformSpecificInitialisation()
{
using namespace iOSMessageLoopHelpers;
pendingMessages = new OwnedArray <Message, CriticalSection>();
runLoop = CFRunLoopGetCurrent();
CFRunLoopSourceContext sourceContext;
zerostruct (sourceContext);
sourceContext.perform = runLoopSourceCallback;
runLoopSource = CFRunLoopSourceCreate (kCFAllocatorDefault, 1, &sourceContext);
CFRunLoopAddSource (runLoop, runLoopSource, kCFRunLoopCommonModes);
if (juceCustomMessageHandler == 0)
juceCustomMessageHandler = [[JuceCustomMessageHandler alloc] init];
if (dispatcher == 0)
dispatcher = new MessageDispatchSystem();
}
void MessageManager::doPlatformSpecificShutdown()
{
using namespace iOSMessageLoopHelpers;
CFRunLoopSourceInvalidate (runLoopSource);
CFRelease (runLoopSource);
runLoopSource = 0;
deleteAndZero (pendingMessages);
if (juceCustomMessageHandler != 0)
{
[[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget: juceCustomMessageHandler];
[juceCustomMessageHandler release];
juceCustomMessageHandler = 0;
}
deleteAndZero (dispatcher);
}
bool juce_postMessageToSystemQueue (Message* message)
{
using namespace iOSMessageLoopHelpers;
if (pendingMessages != 0)
{
pendingMessages->add (message);
CFRunLoopSourceSignal (runLoopSource);
CFRunLoopWakeUp (runLoop);
}
if (dispatcher != 0)
dispatcher->messageQueue.post (message);
return true;
}
@ -190,14 +152,14 @@ void MessageManager::broadcastMessage (const String& value)
void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* callback, void* data)
{
using namespace iOSMessageLoopHelpers;
if (isThisTheMessageThread())
{
return (*callback) (data);
}
else
{
jassert (dispatcher != 0); // trying to call this when the juce system isn't initialised..
// 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..
@ -211,11 +173,11 @@ void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* call
cmp.result = 0;
cmp.hasBeenExecuted = false;
[juceCustomMessageHandler performSelectorOnMainThread: @selector (performCallback:)
withObject: [NSData dataWithBytesNoCopy: &cmp
length: sizeof (cmp)
freeWhenDone: NO]
waitUntilDone: YES];
[dispatcher->juceCustomMessageHandler performSelectorOnMainThread: @selector (performCallback:)
withObject: [NSData dataWithBytesNoCopy: &cmp
length: sizeof (cmp)
freeWhenDone: NO]
waitUntilDone: YES];
return cmp.result;
}

View file

@ -182,12 +182,12 @@ const File File::getSpecialLocation (const SpecialLocationType type)
case userHomeDirectory: resultPath = nsStringToJuce (NSHomeDirectory()); break;
#if JUCE_IOS
case userDocumentsDirectory: resultPath = getIOSSystemLocation (NSDocumentDirectory); break;
case userDesktopDirectory: resultPath = getIOSSystemLocation (NSDesktopDirectory); break;
case userDocumentsDirectory: resultPath = FileHelpers::getIOSSystemLocation (NSDocumentDirectory); break;
case userDesktopDirectory: resultPath = FileHelpers::getIOSSystemLocation (NSDesktopDirectory); break;
case tempDirectory:
{
File tmp (getIOSSystemLocation (NSCachesDirectory));
File tmp (FileHelpers::getIOSSystemLocation (NSCachesDirectory));
tmp = tmp.getChildFile (juce_getExecutableFile().getFileNameWithoutExtension());
tmp.createDirectory();
return tmp.getFullPathName();

View file

@ -44,24 +44,10 @@ class AppDelegateRedirector
public:
AppDelegateRedirector()
{
#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4
runLoop = CFRunLoopGetMain();
#else
runLoop = CFRunLoopGetCurrent();
#endif
CFRunLoopSourceContext sourceContext;
zerostruct (sourceContext);
sourceContext.info = this;
sourceContext.perform = runLoopSourceCallback;
runLoopSource = CFRunLoopSourceCreate (kCFAllocatorDefault, 1, &sourceContext);
CFRunLoopAddSource (runLoop, runLoopSource, kCFRunLoopCommonModes);
}
virtual ~AppDelegateRedirector()
{
CFRunLoopRemoveSource (runLoop, runLoopSource, kCFRunLoopCommonModes);
CFRunLoopSourceInvalidate (runLoopSource);
CFRelease (runLoopSource);
}
virtual NSApplicationTerminateReply shouldTerminate()
@ -137,40 +123,13 @@ public:
void postMessage (Message* const m)
{
messages.add (m);
CFRunLoopSourceSignal (runLoopSource);
CFRunLoopWakeUp (runLoop);
messageQueue.post (m);
}
private:
CFRunLoopRef runLoop;
CFRunLoopSourceRef runLoopSource;
OwnedArray <Message, CriticalSection> messages;
void runLoopCallback()
{
int numDispatched = 0;
do
{
Message* const nextMessage = messages.removeAndReturn (0);
if (nextMessage == 0)
return;
const ScopedAutoReleasePool pool;
MessageManager::getInstance()->deliverMessage (nextMessage);
} while (++numDispatched <= 4);
CFRunLoopSourceSignal (runLoopSource);
CFRunLoopWakeUp (runLoop);
}
static void runLoopSourceCallback (void* info)
{
static_cast <AppDelegateRedirector*> (info)->runLoopCallback();
}
MessageQueue messageQueue;
};

View file

@ -65,7 +65,9 @@ static LRESULT CALLBACK juce_MessageWndProc (HWND h,
// here in case there are windows modal dialog boxes doing their own
// dispatch loop and not calling our version
MessageManager::getInstance()->deliverMessage ((Message*) lParam);
Message* const message = reinterpret_cast <Message*> (lParam);
MessageManager::getInstance()->deliverMessage (message);
message->decReferenceCount();
return 0;
}
else if (message == broadcastId)
@ -153,7 +155,9 @@ bool juce_dispatchNextMessageOnSystemQueue (const bool returnIfNoPendingMessages
{
if (m.message == specialId && m.hwnd == juce_messageWindowHandle)
{
MessageManager::getInstance()->deliverMessage ((Message*) (void*) m.lParam);
Message* const message = reinterpret_cast <Message*> (m.lParam);
MessageManager::getInstance()->deliverMessage (message);
message->decReferenceCount();
}
else if (m.message == WM_QUIT)
{
@ -184,6 +188,7 @@ bool juce_dispatchNextMessageOnSystemQueue (const bool returnIfNoPendingMessages
//==============================================================================
bool juce_postMessageToSystemQueue (Message* message)
{
message->incReferenceCount();
return PostMessage (juce_messageWindowHandle, specialId, 0, (LPARAM) message) != 0;
}