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:
parent
1a887cda63
commit
d60f661789
22 changed files with 573 additions and 527 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue