mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Simplified some message-handling code.
This commit is contained in:
parent
baee94b197
commit
31209dadfc
9 changed files with 78 additions and 284 deletions
|
|
@ -41,6 +41,8 @@ public:
|
|||
|
||||
private:
|
||||
AsyncUpdater& owner;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE (AsyncUpdaterMessage);
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -192,15 +192,12 @@ private:
|
|||
//==============================================================================
|
||||
friend class InterprocessConnectionServer;
|
||||
|
||||
void initialiseWithSocket (StreamingSocket* socket_);
|
||||
void initialiseWithPipe (NamedPipe* pipe_);
|
||||
|
||||
void handleMessage (const Message& message);
|
||||
|
||||
void initialiseWithSocket (StreamingSocket*);
|
||||
void initialiseWithPipe (NamedPipe*);
|
||||
void handleMessage (const Message&);
|
||||
void connectionMadeInt();
|
||||
void connectionLostInt();
|
||||
void deliverDataInt (const MemoryBlock& data);
|
||||
|
||||
void deliverDataInt (const MemoryBlock&);
|
||||
bool readNextMessageInt();
|
||||
void run();
|
||||
|
||||
|
|
|
|||
|
|
@ -32,16 +32,27 @@ CallbackMessage::~CallbackMessage() {}
|
|||
|
||||
void CallbackMessage::post()
|
||||
{
|
||||
if (MessageManager::instance != nullptr)
|
||||
MessageManager::instance->postMessageToQueue (this);
|
||||
MessageManager* const mm = MessageManager::instance;
|
||||
if (mm != nullptr)
|
||||
mm->postMessageToQueue (this);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
struct QuitMessage : public Message
|
||||
class MessageManager::QuitMessage : public CallbackMessage
|
||||
{
|
||||
QuitMessage() noexcept {}
|
||||
};
|
||||
public:
|
||||
QuitMessage() {}
|
||||
|
||||
void messageCallback()
|
||||
{
|
||||
MessageManager* const mm = MessageManager::instance;
|
||||
if (mm != nullptr)
|
||||
mm->quitMessageReceived = true;
|
||||
}
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (QuitMessage);
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
MessageManager* MessageManager::instance = nullptr;
|
||||
|
|
@ -103,13 +114,7 @@ void MessageManager::deliverMessage (Message* const message)
|
|||
CallbackMessage* const callbackMessage = dynamic_cast <CallbackMessage*> (message);
|
||||
|
||||
if (callbackMessage != nullptr)
|
||||
{
|
||||
callbackMessage->messageCallback();
|
||||
}
|
||||
else if (dynamic_cast <QuitMessage*> (message) != nullptr)
|
||||
{
|
||||
quitMessageReceived = true;
|
||||
}
|
||||
}
|
||||
else if (messageListeners.contains (recipient))
|
||||
{
|
||||
|
|
@ -130,8 +135,7 @@ void MessageManager::runDispatchLoop()
|
|||
|
||||
void MessageManager::stopDispatchLoop()
|
||||
{
|
||||
postMessageToQueue (new QuitMessage());
|
||||
quitMessagePosted = true;
|
||||
(new QuitMessage())->post();
|
||||
}
|
||||
|
||||
bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor)
|
||||
|
|
@ -161,6 +165,41 @@ bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor)
|
|||
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
class AsyncFunctionCallback : public CallbackMessage
|
||||
{
|
||||
public:
|
||||
AsyncFunctionCallback (MessageCallbackFunction* const f, void* const param)
|
||||
: result (nullptr), func (f), parameter (param)
|
||||
{}
|
||||
|
||||
void messageCallback()
|
||||
{
|
||||
result = (*func) (parameter);
|
||||
finished.signal();
|
||||
}
|
||||
|
||||
WaitableEvent finished;
|
||||
void* volatile result;
|
||||
|
||||
private:
|
||||
MessageCallbackFunction* const func;
|
||||
void* const parameter;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE (AsyncFunctionCallback);
|
||||
};
|
||||
|
||||
void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* const func, void* const parameter)
|
||||
{
|
||||
if (MessageManager::getInstance()->isThisTheMessageThread())
|
||||
return func (parameter);
|
||||
|
||||
const ReferenceCountedObjectPtr<AsyncFunctionCallback> message (new AsyncFunctionCallback (func, parameter));
|
||||
message->post();
|
||||
message->finished.wait();
|
||||
return message->result;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void MessageManager::deliverBroadcastMessage (const String& value)
|
||||
{
|
||||
|
|
@ -249,25 +288,27 @@ MessageManagerLock::MessageManagerLock (ThreadPoolJob* const jobToCheckForExitSi
|
|||
|
||||
bool MessageManagerLock::attemptLock (Thread* const threadToCheck, ThreadPoolJob* const job)
|
||||
{
|
||||
if (MessageManager::instance == nullptr)
|
||||
MessageManager* const mm = MessageManager::instance;
|
||||
|
||||
if (mm == nullptr)
|
||||
return false;
|
||||
|
||||
if (MessageManager::instance->currentThreadHasLockedMessageManager())
|
||||
if (mm->currentThreadHasLockedMessageManager())
|
||||
return true;
|
||||
|
||||
if (threadToCheck == nullptr && job == nullptr)
|
||||
{
|
||||
MessageManager::instance->lockingLock.enter();
|
||||
mm->lockingLock.enter();
|
||||
}
|
||||
else
|
||||
{
|
||||
while (! MessageManager::instance->lockingLock.tryEnter())
|
||||
while (! mm->lockingLock.tryEnter())
|
||||
{
|
||||
if ((threadToCheck != nullptr && threadToCheck->threadShouldExit())
|
||||
|| (job != nullptr && job->shouldExit()))
|
||||
return false;
|
||||
|
||||
Thread::sleep (1);
|
||||
Thread::yield();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -281,14 +322,14 @@ bool MessageManagerLock::attemptLock (Thread* const threadToCheck, ThreadPoolJob
|
|||
{
|
||||
blockingMessage->releaseEvent.signal();
|
||||
blockingMessage = nullptr;
|
||||
MessageManager::instance->lockingLock.exit();
|
||||
mm->lockingLock.exit();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
jassert (MessageManager::instance->threadWithLock == 0);
|
||||
jassert (mm->threadWithLock == 0);
|
||||
|
||||
MessageManager::instance->threadWithLock = Thread::getCurrentThreadId();
|
||||
mm->threadWithLock = Thread::getCurrentThreadId();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -296,15 +337,17 @@ MessageManagerLock::~MessageManagerLock() noexcept
|
|||
{
|
||||
if (blockingMessage != nullptr)
|
||||
{
|
||||
jassert (MessageManager::instance == nullptr || MessageManager::instance->currentThreadHasLockedMessageManager());
|
||||
MessageManager* const mm = MessageManager::instance;
|
||||
|
||||
jassert (mm == nullptr || mm->currentThreadHasLockedMessageManager());
|
||||
|
||||
blockingMessage->releaseEvent.signal();
|
||||
blockingMessage = nullptr;
|
||||
|
||||
if (MessageManager::instance != nullptr)
|
||||
if (mm != nullptr)
|
||||
{
|
||||
MessageManager::instance->threadWithLock = 0;
|
||||
MessageManager::instance->lockingLock.exit();
|
||||
mm->threadWithLock = 0;
|
||||
mm->lockingLock.exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,7 +177,8 @@ private:
|
|||
SortedSet <const MessageListener*> messageListeners;
|
||||
ScopedPointer <ActionBroadcaster> broadcaster;
|
||||
|
||||
friend class JUCEApplication;
|
||||
class QuitMessage;
|
||||
friend class QuitMessage;
|
||||
bool quitMessagePosted, quitMessageReceived;
|
||||
Thread::ThreadID messageThreadId;
|
||||
|
||||
|
|
@ -185,7 +186,7 @@ private:
|
|||
Thread::ThreadID volatile threadWithLock;
|
||||
CriticalSection lockingLock;
|
||||
|
||||
void postMessageToQueue (Message* message);
|
||||
void postMessageToQueue (Message*);
|
||||
static bool postMessageToSystemQueue (Message*);
|
||||
static void* exitModalLoopCallback (void*);
|
||||
static void doPlatformSpecificInitialisation();
|
||||
|
|
|
|||
|
|
@ -50,45 +50,6 @@ JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, deliverMessage, void, (jobje
|
|||
message->decReferenceCount();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class AsyncFunctionCaller : public AsyncUpdater
|
||||
{
|
||||
public:
|
||||
static void* call (MessageCallbackFunction* func_, void* parameter_)
|
||||
{
|
||||
if (MessageManager::getInstance()->isThisTheMessageThread())
|
||||
return func_ (parameter_);
|
||||
|
||||
AsyncFunctionCaller caller (func_, parameter_);
|
||||
caller.triggerAsyncUpdate();
|
||||
caller.finished.wait();
|
||||
return caller.result;
|
||||
}
|
||||
|
||||
void handleAsyncUpdate()
|
||||
{
|
||||
result = (*func) (parameter);
|
||||
finished.signal();
|
||||
}
|
||||
|
||||
private:
|
||||
WaitableEvent finished;
|
||||
MessageCallbackFunction* func;
|
||||
void* parameter;
|
||||
void* volatile result;
|
||||
|
||||
AsyncFunctionCaller (MessageCallbackFunction* func_, void* parameter_)
|
||||
: result (nullptr), func (func_), parameter (parameter_)
|
||||
{}
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE (AsyncFunctionCaller);
|
||||
};
|
||||
|
||||
void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* func, void* parameter)
|
||||
{
|
||||
return AsyncFunctionCaller::call (func, parameter);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void MessageManager::broadcastMessage (const String&)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,52 +23,6 @@
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
struct CallbackMessagePayload
|
||||
{
|
||||
MessageCallbackFunction* function;
|
||||
void* parameter;
|
||||
void* volatile result;
|
||||
bool volatile hasBeenExecuted;
|
||||
};
|
||||
|
||||
} // (juce namespace)
|
||||
|
||||
//==============================================================================
|
||||
@interface JuceCustomMessageHandler : NSObject
|
||||
{
|
||||
}
|
||||
|
||||
- (void) performCallback: (id) info;
|
||||
|
||||
@end
|
||||
|
||||
//==============================================================================
|
||||
@implementation JuceCustomMessageHandler
|
||||
|
||||
- (void) performCallback: (id) info
|
||||
{
|
||||
if ([info isKindOfClass: [NSData class]])
|
||||
{
|
||||
juce::CallbackMessagePayload* pl = (juce::CallbackMessagePayload*) [((NSData*) info) bytes];
|
||||
|
||||
if (pl != nullptr)
|
||||
{
|
||||
pl->result = (*pl->function) (pl->parameter);
|
||||
pl->hasBeenExecuted = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
jassertfalse; // should never get here!
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
//==============================================================================
|
||||
namespace juce
|
||||
{
|
||||
|
||||
void MessageManager::runDispatchLoop()
|
||||
{
|
||||
jassert (isThisTheMessageThread()); // must only be called by the message thread
|
||||
|
|
@ -146,36 +100,3 @@ bool MessageManager::postMessageToSystemQueue (Message* message)
|
|||
void MessageManager::broadcastMessage (const String& value)
|
||||
{
|
||||
}
|
||||
|
||||
void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* callback, void* data)
|
||||
{
|
||||
if (isThisTheMessageThread())
|
||||
{
|
||||
return (*callback) (data);
|
||||
}
|
||||
else
|
||||
{
|
||||
jassert (dispatcher != nullptr); // 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..
|
||||
jassert (! MessageManager::getInstance()->currentThreadHasLockedMessageManager());
|
||||
|
||||
JUCE_AUTORELEASEPOOL
|
||||
|
||||
CallbackMessagePayload cmp;
|
||||
cmp.function = callback;
|
||||
cmp.parameter = data;
|
||||
cmp.result = 0;
|
||||
cmp.hasBeenExecuted = false;
|
||||
|
||||
[dispatcher->juceCustomMessageHandler performSelectorOnMainThread: @selector (performCallback:)
|
||||
withObject: [NSData dataWithBytesNoCopy: &cmp
|
||||
length: sizeof (cmp)
|
||||
freeWhenDone: NO]
|
||||
waitUntilDone: YES];
|
||||
|
||||
return cmp.result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -360,49 +360,6 @@ void MessageManager::broadcastMessage (const String& value)
|
|||
/* TODO */
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class AsyncFunctionCaller : public AsyncUpdater
|
||||
{
|
||||
public:
|
||||
static void* call (MessageCallbackFunction* func_, void* parameter_)
|
||||
{
|
||||
if (MessageManager::getInstance()->isThisTheMessageThread())
|
||||
return func_ (parameter_);
|
||||
|
||||
AsyncFunctionCaller caller (func_, parameter_);
|
||||
caller.triggerAsyncUpdate();
|
||||
caller.finished.wait();
|
||||
return caller.result;
|
||||
}
|
||||
|
||||
void handleAsyncUpdate()
|
||||
{
|
||||
result = (*func) (parameter);
|
||||
finished.signal();
|
||||
}
|
||||
|
||||
private:
|
||||
WaitableEvent finished;
|
||||
MessageCallbackFunction* func;
|
||||
void* parameter;
|
||||
void* volatile result;
|
||||
|
||||
AsyncFunctionCaller (MessageCallbackFunction* func_, void* parameter_)
|
||||
: result (nullptr), func (func_), parameter (parameter_)
|
||||
{}
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE (AsyncFunctionCaller);
|
||||
};
|
||||
|
||||
void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* func, void* parameter)
|
||||
{
|
||||
if (LinuxErrorHandling::errorOccurred)
|
||||
return nullptr;
|
||||
|
||||
return AsyncFunctionCaller::call (func, parameter);
|
||||
}
|
||||
|
||||
// this function expects that it will NEVER be called simultaneously for two concurrent threads
|
||||
bool MessageManager::dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -91,20 +91,6 @@ public:
|
|||
(*appFocusChangeCallback)();
|
||||
}
|
||||
|
||||
struct CallbackMessagePayload
|
||||
{
|
||||
MessageCallbackFunction* function;
|
||||
void* parameter;
|
||||
void* volatile result;
|
||||
bool volatile hasBeenExecuted;
|
||||
};
|
||||
|
||||
virtual void performCallback (CallbackMessagePayload* pl)
|
||||
{
|
||||
pl->result = (*pl->function) (pl->parameter);
|
||||
pl->hasBeenExecuted = true;
|
||||
}
|
||||
|
||||
virtual void deleteSelf()
|
||||
{
|
||||
delete this;
|
||||
|
|
@ -159,7 +145,6 @@ using namespace juce;
|
|||
- (void) applicationDidBecomeActive: (NSNotification*) aNotification;
|
||||
- (void) applicationDidResignActive: (NSNotification*) aNotification;
|
||||
- (void) applicationWillUnhide: (NSNotification*) aNotification;
|
||||
- (void) performCallback: (id) info;
|
||||
- (void) broadcastMessageCallback: (NSNotification*) info;
|
||||
- (void) dummyMethod;
|
||||
@end
|
||||
|
|
@ -261,22 +246,6 @@ using namespace juce;
|
|||
redirector->focusChanged();
|
||||
}
|
||||
|
||||
- (void) performCallback: (id) info
|
||||
{
|
||||
if ([info isKindOfClass: [NSData class]])
|
||||
{
|
||||
AppDelegateRedirector::CallbackMessagePayload* pl
|
||||
= (AppDelegateRedirector::CallbackMessagePayload*) [((NSData*) info) bytes];
|
||||
|
||||
if (pl != nullptr)
|
||||
redirector->performCallback (pl);
|
||||
}
|
||||
else
|
||||
{
|
||||
jassertfalse; // should never get here!
|
||||
}
|
||||
}
|
||||
|
||||
- (void) broadcastMessageCallback: (NSNotification*) n
|
||||
{
|
||||
NSDictionary* dict = (NSDictionary*) [n userInfo];
|
||||
|
|
@ -406,34 +375,3 @@ void MessageManager::broadcastMessage (const String& message)
|
|||
object: nil
|
||||
userInfo: info];
|
||||
}
|
||||
|
||||
void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* callback, void* data)
|
||||
{
|
||||
if (isThisTheMessageThread())
|
||||
{
|
||||
return (*callback) (data);
|
||||
}
|
||||
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());
|
||||
|
||||
JUCE_AUTORELEASEPOOL
|
||||
|
||||
AppDelegateRedirector::CallbackMessagePayload cmp;
|
||||
cmp.function = callback;
|
||||
cmp.parameter = data;
|
||||
cmp.result = 0;
|
||||
cmp.hasBeenExecuted = false;
|
||||
|
||||
[juceAppDelegate performSelectorOnMainThread: @selector (performCallback:)
|
||||
withObject: [NSData dataWithBytesNoCopy: &cmp
|
||||
length: sizeof (cmp)
|
||||
freeWhenDone: NO]
|
||||
waitUntilDone: YES];
|
||||
|
||||
return cmp.result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ namespace WindowsMessageHelpers
|
|||
{
|
||||
const unsigned int specialId = WM_APP + 0x4400;
|
||||
const unsigned int broadcastId = WM_APP + 0x4403;
|
||||
const unsigned int specialCallbackId = WM_APP + 0x4402;
|
||||
|
||||
const TCHAR messageWindowName[] = _T("JUCEWindow");
|
||||
ScopedPointer<HiddenMessageWindow> messageWindow;
|
||||
|
|
@ -45,12 +44,7 @@ namespace WindowsMessageHelpers
|
|||
{
|
||||
if (h == juce_messageWindowHandle)
|
||||
{
|
||||
if (message == specialCallbackId)
|
||||
{
|
||||
MessageCallbackFunction* const func = (MessageCallbackFunction*) wParam;
|
||||
return (LRESULT) (*func) ((void*) lParam);
|
||||
}
|
||||
else if (message == specialId)
|
||||
if (message == specialId)
|
||||
{
|
||||
// these are trapped early in the dispatch call, but must also be checked
|
||||
// here in case there are windows modal dialog boxes doing their own
|
||||
|
|
@ -142,26 +136,6 @@ bool MessageManager::postMessageToSystemQueue (Message* message)
|
|||
return PostMessage (juce_messageWindowHandle, WindowsMessageHelpers::specialId, 0, (LPARAM) message) != 0;
|
||||
}
|
||||
|
||||
void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* callback, void* userData)
|
||||
{
|
||||
if (MessageManager::getInstance()->isThisTheMessageThread())
|
||||
{
|
||||
return (*callback) (userData);
|
||||
}
|
||||
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, and can't
|
||||
// call your function..
|
||||
jassert (! MessageManager::getInstance()->currentThreadHasLockedMessageManager());
|
||||
|
||||
return (void*) SendMessage (juce_messageWindowHandle,
|
||||
WindowsMessageHelpers::specialCallbackId,
|
||||
(WPARAM) callback,
|
||||
(LPARAM) userData);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageManager::broadcastMessage (const String& value)
|
||||
{
|
||||
Array<HWND> windows;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue