mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
More internal message class refactoring/decoupling.
This commit is contained in:
parent
31209dadfc
commit
e905f52014
14 changed files with 170 additions and 218 deletions
|
|
@ -53,7 +53,7 @@ void ActionBroadcaster::CallbackReceiver::handleMessage (const Message& message)
|
|||
ActionBroadcaster::ActionBroadcaster()
|
||||
{
|
||||
// are you trying to create this object before or after juce has been intialised??
|
||||
jassert (MessageManager::instance != nullptr);
|
||||
jassert (MessageManager::getInstanceWithoutCreating() != nullptr);
|
||||
|
||||
callback.owner = this;
|
||||
}
|
||||
|
|
@ -61,7 +61,7 @@ ActionBroadcaster::ActionBroadcaster()
|
|||
ActionBroadcaster::~ActionBroadcaster()
|
||||
{
|
||||
// all event-based objects must be deleted BEFORE juce is shut down!
|
||||
jassert (MessageManager::instance != nullptr);
|
||||
jassert (MessageManager::getInstanceWithoutCreating() != nullptr);
|
||||
}
|
||||
|
||||
void ActionBroadcaster::addActionListener (ActionListener* const listener)
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
ChangeBroadcaster::ChangeBroadcaster() noexcept
|
||||
{
|
||||
// are you trying to create this object before or after juce has been intialised??
|
||||
jassert (MessageManager::instance != nullptr);
|
||||
jassert (MessageManager::getInstanceWithoutCreating() != nullptr);
|
||||
|
||||
callback.owner = this;
|
||||
}
|
||||
|
|
@ -34,7 +34,7 @@ ChangeBroadcaster::ChangeBroadcaster() noexcept
|
|||
ChangeBroadcaster::~ChangeBroadcaster()
|
||||
{
|
||||
// all event-based objects must be deleted BEFORE juce is shut down!
|
||||
jassert (MessageManager::instance != nullptr);
|
||||
jassert (MessageManager::getInstanceWithoutCreating() != nullptr);
|
||||
}
|
||||
|
||||
void ChangeBroadcaster::addChangeListener (ChangeListener* const listener)
|
||||
|
|
|
|||
|
|
@ -26,33 +26,34 @@
|
|||
#ifndef __JUCE_CALLBACKMESSAGE_JUCEHEADER__
|
||||
#define __JUCE_CALLBACKMESSAGE_JUCEHEADER__
|
||||
|
||||
#include "juce_Message.h"
|
||||
#include "juce_MessageManager.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A message that calls a custom function when it gets delivered.
|
||||
A message that invokes a callback method 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.
|
||||
To use it, create a subclass of CallbackMessage which implements the messageCallback()
|
||||
method, then call post() to dispatch it. The event thread will then invoke your
|
||||
messageCallback() method later on, and will automatically delete the message object
|
||||
afterwards.
|
||||
|
||||
Always create an instance of a CallbackMessage on the heap, as it will be
|
||||
Always create a new instance of a CallbackMessage on the heap, as it will be
|
||||
deleted automatically after the message has been delivered.
|
||||
|
||||
@see MessageListener, MessageManager, ActionListener, ChangeListener
|
||||
@see MessageManager, MessageListener, ActionListener, ChangeListener
|
||||
*/
|
||||
class JUCE_API CallbackMessage : public Message
|
||||
class JUCE_API CallbackMessage : public MessageManager::MessageBase
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
CallbackMessage() noexcept;
|
||||
CallbackMessage() noexcept {}
|
||||
|
||||
/** Destructor. */
|
||||
~CallbackMessage();
|
||||
~CallbackMessage() {}
|
||||
|
||||
//==============================================================================
|
||||
/** Called when the message is delivered.
|
||||
|
|
@ -65,17 +66,7 @@ public:
|
|||
*/
|
||||
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();
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
// Avoid the leak-detector because for plugins, the host can unload our DLL with undelivered
|
||||
// messages still in the system event queue. These aren't harmful, but can cause annoying assertions.
|
||||
JUCE_DECLARE_NON_COPYABLE (CallbackMessage);
|
||||
|
|
|
|||
|
|
@ -27,39 +27,35 @@
|
|||
#define __JUCE_MESSAGE_JUCEHEADER__
|
||||
|
||||
class MessageListener;
|
||||
class MessageManager;
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** The base class for objects that can be delivered to a MessageListener.
|
||||
/** The base class for objects that can be sent to a MessageListener.
|
||||
|
||||
If you want to send a message that carries some kind of custom data, just
|
||||
create a subclass of Message with some appropriate member variables to hold
|
||||
your data.
|
||||
|
||||
Always create a new instance of a Message object on the heap, as it will be
|
||||
deleted automatically after the message has been delivered.
|
||||
|
||||
@see MessageListener, MessageManager, ActionListener, ChangeListener
|
||||
*/
|
||||
class JUCE_API Message : public ReferenceCountedObject
|
||||
class JUCE_API Message : public MessageManager::MessageBase
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an uninitialised message.
|
||||
|
||||
The class's variables will also be left uninitialised.
|
||||
*/
|
||||
/** Creates an uninitialised message. */
|
||||
Message() noexcept;
|
||||
~Message();
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~Message();
|
||||
|
||||
/** A typedef for pointers to messages. */
|
||||
typedef ReferenceCountedObjectPtr <Message> Ptr;
|
||||
typedef ReferenceCountedObjectPtr<Message> Ptr;
|
||||
|
||||
//==============================================================================
|
||||
private:
|
||||
friend class MessageListener;
|
||||
friend class MessageManager;
|
||||
MessageListener* messageRecipient;
|
||||
WeakReference<MessageListener> recipient;
|
||||
void messageCallback();
|
||||
|
||||
// Avoid the leak-detector because for plugins, the host can unload our DLL with undelivered
|
||||
// messages still in the system event queue. These aren't harmful, but can cause annoying assertions.
|
||||
|
|
|
|||
|
|
@ -23,33 +23,29 @@
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
Message::Message() noexcept {}
|
||||
Message::~Message() {}
|
||||
|
||||
void Message::messageCallback()
|
||||
{
|
||||
MessageListener* const r = recipient;
|
||||
if (r != nullptr)
|
||||
r->handleMessage (*this);
|
||||
}
|
||||
|
||||
MessageListener::MessageListener() noexcept
|
||||
{
|
||||
// are you trying to create a messagelistener before or after juce has been intialised??
|
||||
jassert (MessageManager::instance != nullptr);
|
||||
|
||||
if (MessageManager::instance != nullptr)
|
||||
MessageManager::instance->messageListeners.add (this);
|
||||
// Are you trying to create a messagelistener before or after juce has been intialised??
|
||||
jassert (MessageManager::getInstanceWithoutCreating() != nullptr);
|
||||
}
|
||||
|
||||
MessageListener::~MessageListener()
|
||||
{
|
||||
if (MessageManager::instance != nullptr)
|
||||
MessageManager::instance->messageListeners.removeValue (this);
|
||||
masterReference.clear();
|
||||
}
|
||||
|
||||
void MessageListener::postMessage (Message* const message) const
|
||||
{
|
||||
message->messageRecipient = const_cast <MessageListener*> (this);
|
||||
|
||||
if (MessageManager::instance == nullptr)
|
||||
MessageManager::getInstance();
|
||||
|
||||
MessageManager::instance->postMessageToQueue (message);
|
||||
}
|
||||
|
||||
bool MessageListener::isValidMessageListener() const noexcept
|
||||
{
|
||||
return MessageManager::instance != nullptr
|
||||
&& MessageManager::instance->messageListeners.contains (this);
|
||||
message->recipient = const_cast <MessageListener*> (this);
|
||||
message->post();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
#ifndef __JUCE_MESSAGELISTENER_JUCEHEADER__
|
||||
#define __JUCE_MESSAGELISTENER_JUCEHEADER__
|
||||
|
||||
#include "juce_Message.h"
|
||||
#include "juce_MessageManager.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -37,19 +37,11 @@
|
|||
*/
|
||||
class JUCE_API MessageListener
|
||||
{
|
||||
protected:
|
||||
//==============================================================================
|
||||
/** Creates a MessageListener. */
|
||||
MessageListener() noexcept;
|
||||
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Destructor.
|
||||
MessageListener() noexcept;
|
||||
|
||||
When a MessageListener is deleted, it removes itself from a global list
|
||||
of registered listeners, so that the isValidMessageListener() method
|
||||
will no longer return true.
|
||||
*/
|
||||
/** Destructor. */
|
||||
virtual ~MessageListener();
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -68,25 +60,15 @@ public:
|
|||
This method can be called safely by any thread.
|
||||
|
||||
@param message the message object to send - this will be deleted
|
||||
automatically by the message queue, so don't keep any
|
||||
references to it after calling this method.
|
||||
automatically by the message queue, so make sure it's
|
||||
allocated on the heap, not the stack!
|
||||
@see handleMessage
|
||||
*/
|
||||
void postMessage (Message* message) const;
|
||||
|
||||
//==============================================================================
|
||||
/** Checks whether this MessageListener has been deleted.
|
||||
|
||||
Although not foolproof, this method is safe to call on dangling or null
|
||||
pointers. A list of active MessageListeners is kept internally, so this
|
||||
checks whether the object is on this list or not.
|
||||
|
||||
Note that it's possible to get a false-positive here, if an object is
|
||||
deleted and another is subsequently created that happens to be at the
|
||||
exact same memory location, but I can't think of a good way of avoiding
|
||||
this.
|
||||
*/
|
||||
bool isValidMessageListener() const noexcept;
|
||||
private:
|
||||
WeakReference<MessageListener>::Master masterReference;
|
||||
friend class WeakReference<MessageListener>;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -23,22 +23,7 @@
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
Message::Message() noexcept : messageRecipient (nullptr) {}
|
||||
Message::~Message() {}
|
||||
|
||||
//==============================================================================
|
||||
CallbackMessage::CallbackMessage() noexcept {}
|
||||
CallbackMessage::~CallbackMessage() {}
|
||||
|
||||
void CallbackMessage::post()
|
||||
{
|
||||
MessageManager* const mm = MessageManager::instance;
|
||||
if (mm != nullptr)
|
||||
mm->postMessageToQueue (this);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class MessageManager::QuitMessage : public CallbackMessage
|
||||
class MessageManager::QuitMessage : public MessageManager::MessageBase
|
||||
{
|
||||
public:
|
||||
QuitMessage() {}
|
||||
|
|
@ -55,8 +40,6 @@ private:
|
|||
};
|
||||
|
||||
//==============================================================================
|
||||
MessageManager* MessageManager::instance = nullptr;
|
||||
|
||||
MessageManager::MessageManager() noexcept
|
||||
: quitMessagePosted (false),
|
||||
quitMessageReceived (false),
|
||||
|
|
@ -73,13 +56,12 @@ MessageManager::~MessageManager() noexcept
|
|||
|
||||
doPlatformSpecificShutdown();
|
||||
|
||||
// If you hit this assertion, then you've probably leaked some kind of MessageListener object..
|
||||
jassert (messageListeners.size() == 0);
|
||||
|
||||
jassert (instance == this);
|
||||
instance = nullptr; // do this last in case this instance is still needed by doPlatformSpecificShutdown()
|
||||
}
|
||||
|
||||
MessageManager* MessageManager::instance = nullptr;
|
||||
|
||||
MessageManager* MessageManager::getInstance()
|
||||
{
|
||||
if (instance == nullptr)
|
||||
|
|
@ -91,37 +73,23 @@ MessageManager* MessageManager::getInstance()
|
|||
return instance;
|
||||
}
|
||||
|
||||
inline MessageManager* MessageManager::getInstanceWithoutCreating() noexcept
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
|
||||
void MessageManager::deleteInstance()
|
||||
{
|
||||
deleteAndZero (instance);
|
||||
}
|
||||
|
||||
void MessageManager::postMessageToQueue (Message* const message)
|
||||
{
|
||||
if (quitMessagePosted || ! postMessageToSystemQueue (message))
|
||||
Message::Ptr deleter (message); // (this will delete messages that were just created with a 0 ref count)
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void MessageManager::deliverMessage (Message* const message)
|
||||
void MessageManager::MessageBase::post()
|
||||
{
|
||||
JUCE_TRY
|
||||
{
|
||||
MessageListener* const recipient = message->messageRecipient;
|
||||
MessageManager* const mm = MessageManager::instance;
|
||||
|
||||
if (recipient == nullptr)
|
||||
{
|
||||
CallbackMessage* const callbackMessage = dynamic_cast <CallbackMessage*> (message);
|
||||
|
||||
if (callbackMessage != nullptr)
|
||||
callbackMessage->messageCallback();
|
||||
}
|
||||
else if (messageListeners.contains (recipient))
|
||||
{
|
||||
recipient->handleMessage (*message);
|
||||
}
|
||||
}
|
||||
JUCE_CATCH_EXCEPTION
|
||||
if (mm == nullptr || mm->quitMessagePosted || ! postMessageToSystemQueue (this))
|
||||
Ptr deleter (this); // (this will delete messages that were just created with a 0 ref count)
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -166,7 +134,7 @@ bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor)
|
|||
#endif
|
||||
|
||||
//==============================================================================
|
||||
class AsyncFunctionCallback : public CallbackMessage
|
||||
class AsyncFunctionCallback : public MessageManager::MessageBase
|
||||
{
|
||||
public:
|
||||
AsyncFunctionCallback (MessageCallbackFunction* const f, void* const param)
|
||||
|
|
@ -258,10 +226,10 @@ bool MessageManager::currentThreadHasLockedMessageManager() const noexcept
|
|||
accessed from another thread inside a MM lock, you're screwed. (this is exactly what happens
|
||||
in Cocoa).
|
||||
*/
|
||||
class MessageManagerLock::BlockingMessage : public CallbackMessage
|
||||
class MessageManagerLock::BlockingMessage : public MessageManager::MessageBase
|
||||
{
|
||||
public:
|
||||
BlockingMessage() {}
|
||||
BlockingMessage() noexcept {}
|
||||
|
||||
void messageCallback()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
#ifndef __JUCE_MESSAGEMANAGER_JUCEHEADER__
|
||||
#define __JUCE_MESSAGEMANAGER_JUCEHEADER__
|
||||
|
||||
#include "juce_CallbackMessage.h"
|
||||
class MessageManagerLock;
|
||||
class ThreadPoolJob;
|
||||
class ActionListener;
|
||||
|
|
@ -40,9 +39,10 @@ typedef void* (MessageCallbackFunction) (void* userData);
|
|||
|
||||
|
||||
//==============================================================================
|
||||
/** Delivers Message objects to MessageListeners, and handles the event-dispatch loop.
|
||||
/**
|
||||
This class is in charge of the application's event-dispatch loop.
|
||||
|
||||
@see Message, MessageListener, MessageManagerLock, JUCEApplication
|
||||
@see Message, CallbackMessage, MessageManagerLock, JUCEApplication
|
||||
*/
|
||||
class JUCE_API MessageManager
|
||||
{
|
||||
|
|
@ -51,6 +51,9 @@ public:
|
|||
/** Returns the global instance of the MessageManager. */
|
||||
static MessageManager* getInstance();
|
||||
|
||||
/** Returns the global instance of the MessageManager, or nullptr if it doesn't exist. */
|
||||
static MessageManager* getInstanceWithoutCreating() noexcept;
|
||||
|
||||
/** Deletes the global MessageManager instance.
|
||||
Does nothing if no instance had been created.
|
||||
*/
|
||||
|
|
@ -156,10 +159,28 @@ public:
|
|||
/** Deregisters a broadcast listener. */
|
||||
void deregisterBroadcastListener (ActionListener* listener);
|
||||
|
||||
//==============================================================================
|
||||
/** Internal class used as the base class for all message objects.
|
||||
You shouldn't need to use this directly - see the CallbackMessage or Message
|
||||
classes instead.
|
||||
*/
|
||||
class JUCE_API MessageBase : public ReferenceCountedObject
|
||||
{
|
||||
public:
|
||||
MessageBase() noexcept {}
|
||||
virtual ~MessageBase() {}
|
||||
|
||||
virtual void messageCallback() = 0;
|
||||
void post();
|
||||
|
||||
typedef ReferenceCountedObjectPtr<MessageBase> Ptr;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE (MessageBase);
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
#ifndef DOXYGEN
|
||||
// Internal methods - do not use!
|
||||
void deliverMessage (Message*);
|
||||
void deliverBroadcastMessage (const String&);
|
||||
~MessageManager() noexcept;
|
||||
#endif
|
||||
|
|
@ -168,26 +189,20 @@ private:
|
|||
//==============================================================================
|
||||
MessageManager() noexcept;
|
||||
|
||||
friend class MessageListener;
|
||||
friend class ChangeBroadcaster;
|
||||
friend class ActionBroadcaster;
|
||||
friend class CallbackMessage;
|
||||
static MessageManager* instance;
|
||||
|
||||
SortedSet <const MessageListener*> messageListeners;
|
||||
ScopedPointer <ActionBroadcaster> broadcaster;
|
||||
|
||||
friend class MessageBase;
|
||||
class QuitMessage;
|
||||
friend class QuitMessage;
|
||||
friend class MessageManagerLock;
|
||||
|
||||
ScopedPointer <ActionBroadcaster> broadcaster;
|
||||
bool quitMessagePosted, quitMessageReceived;
|
||||
Thread::ThreadID messageThreadId;
|
||||
|
||||
friend class MessageManagerLock;
|
||||
Thread::ThreadID volatile threadWithLock;
|
||||
CriticalSection lockingLock;
|
||||
|
||||
void postMessageToQueue (Message*);
|
||||
static bool postMessageToSystemQueue (Message*);
|
||||
static bool postMessageToSystemQueue (MessageBase*);
|
||||
static void* exitModalLoopCallback (void*);
|
||||
static void doPlatformSpecificInitialisation();
|
||||
static void doPlatformSpecificShutdown();
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPend
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
bool MessageManager::postMessageToSystemQueue (Message* message)
|
||||
bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* const message)
|
||||
{
|
||||
message->incReferenceCount();
|
||||
getEnv()->CallVoidMethod (android.activity, JuceAppActivity.postMessage, (jlong) (pointer_sized_uint) message);
|
||||
|
|
@ -45,9 +45,13 @@ bool MessageManager::postMessageToSystemQueue (Message* message)
|
|||
|
||||
JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, deliverMessage, void, (jobject activity, jlong value))
|
||||
{
|
||||
Message* const message = (Message*) (pointer_sized_uint) value;
|
||||
MessageManager::getInstance()->deliverMessage (message);
|
||||
JUCE_TRY
|
||||
{
|
||||
MessageManager::MessageBase* const message = (MessageManager::MessageBase*) (pointer_sized_uint) value;
|
||||
message->messageCallback();
|
||||
message->decReferenceCount();
|
||||
}
|
||||
JUCE_CATCH_EXCEPTION
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -58,45 +58,27 @@ bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor)
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
struct MessageDispatchSystem
|
||||
{
|
||||
MessageDispatchSystem()
|
||||
: juceCustomMessageHandler (nil)
|
||||
{
|
||||
juceCustomMessageHandler = [[JuceCustomMessageHandler alloc] init];
|
||||
}
|
||||
|
||||
~MessageDispatchSystem()
|
||||
{
|
||||
[[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget: juceCustomMessageHandler];
|
||||
[juceCustomMessageHandler release];
|
||||
}
|
||||
|
||||
JuceCustomMessageHandler* juceCustomMessageHandler;
|
||||
MessageQueue messageQueue;
|
||||
};
|
||||
|
||||
static ScopedPointer<MessageDispatchSystem> dispatcher;
|
||||
static ScopedPointer<MessageQueue> messageQueue;
|
||||
|
||||
void MessageManager::doPlatformSpecificInitialisation()
|
||||
{
|
||||
if (dispatcher == nullptr)
|
||||
dispatcher = new MessageDispatchSystem();
|
||||
if (messageQueue == nullptr)
|
||||
messageQueue = new MessageQueue();
|
||||
}
|
||||
|
||||
void MessageManager::doPlatformSpecificShutdown()
|
||||
{
|
||||
dispatcher = nullptr;
|
||||
messageQueue = nullptr;
|
||||
}
|
||||
|
||||
bool MessageManager::postMessageToSystemQueue (Message* message)
|
||||
bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* const message)
|
||||
{
|
||||
if (dispatcher != nullptr)
|
||||
dispatcher->messageQueue.post (message);
|
||||
if (messageQueue != nullptr)
|
||||
messageQueue->post (message);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MessageManager::broadcastMessage (const String& value)
|
||||
void MessageManager::broadcastMessage (const String&)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ public:
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
void postMessage (Message* msg)
|
||||
void postMessage (MessageManager::MessageBase* const msg)
|
||||
{
|
||||
const int maxBytesInSocketQueue = 128;
|
||||
|
||||
|
|
@ -133,7 +133,7 @@ public:
|
|||
|
||||
private:
|
||||
CriticalSection lock;
|
||||
ReferenceCountedArray <Message> queue;
|
||||
ReferenceCountedArray <MessageManager::MessageBase> queue;
|
||||
int fd[2];
|
||||
int bytesInSocket;
|
||||
int totalEventCount;
|
||||
|
|
@ -173,7 +173,7 @@ private:
|
|||
return true;
|
||||
}
|
||||
|
||||
Message::Ptr popNextMessage()
|
||||
MessageManager::MessageBase::Ptr popNextMessage()
|
||||
{
|
||||
const ScopedLock sl (lock);
|
||||
|
||||
|
|
@ -192,12 +192,17 @@ private:
|
|||
|
||||
bool dispatchNextInternalMessage()
|
||||
{
|
||||
const Message::Ptr msg (popNextMessage());
|
||||
const MessageManager::MessageBase::Ptr msg (popNextMessage());
|
||||
|
||||
if (msg == nullptr)
|
||||
return false;
|
||||
|
||||
MessageManager::getInstance()->deliverMessage (msg);
|
||||
JUCE_TRY
|
||||
{
|
||||
msg->messageCallback();
|
||||
}
|
||||
JUCE_CATCH_EXCEPTION
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
|
@ -346,7 +351,7 @@ void MessageManager::doPlatformSpecificShutdown()
|
|||
}
|
||||
}
|
||||
|
||||
bool MessageManager::postMessageToSystemQueue (Message* message)
|
||||
bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* const message)
|
||||
{
|
||||
if (LinuxErrorHandling::errorOccurred)
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ public:
|
|||
delete this;
|
||||
}
|
||||
|
||||
void postMessage (Message* const m)
|
||||
void postMessage (MessageManager::MessageBase* const m)
|
||||
{
|
||||
messageQueue.post (m);
|
||||
}
|
||||
|
|
@ -360,7 +360,7 @@ void MessageManager::doPlatformSpecificShutdown()
|
|||
}
|
||||
}
|
||||
|
||||
bool MessageManager::postMessageToSystemQueue (Message* message)
|
||||
bool MessageManager::postMessageToSystemQueue (MessageBase* message)
|
||||
{
|
||||
juceAppDelegate->redirector->postMessage (message);
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ public:
|
|||
CFRelease (runLoopSource);
|
||||
}
|
||||
|
||||
void post (Message* const message)
|
||||
void post (MessageManager::MessageBase* const message)
|
||||
{
|
||||
messages.add (message);
|
||||
CFRunLoopSourceSignal (runLoopSource);
|
||||
|
|
@ -61,20 +61,26 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
ReferenceCountedArray <Message, CriticalSection> messages;
|
||||
ReferenceCountedArray <MessageManager::MessageBase, CriticalSection> messages;
|
||||
CriticalSection lock;
|
||||
CFRunLoopRef runLoop;
|
||||
CFRunLoopSourceRef runLoopSource;
|
||||
|
||||
bool deliverNextMessage()
|
||||
{
|
||||
const Message::Ptr nextMessage (messages.removeAndReturn (0));
|
||||
const MessageManager::MessageBase::Ptr nextMessage (messages.removeAndReturn (0));
|
||||
|
||||
if (nextMessage == nullptr)
|
||||
return false;
|
||||
|
||||
JUCE_AUTORELEASEPOOL
|
||||
MessageManager::getInstance()->deliverMessage (nextMessage);
|
||||
|
||||
JUCE_TRY
|
||||
{
|
||||
nextMessage->messageCallback();
|
||||
}
|
||||
JUCE_CATCH_EXCEPTION
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,34 +37,43 @@ namespace WindowsMessageHelpers
|
|||
const TCHAR messageWindowName[] = _T("JUCEWindow");
|
||||
ScopedPointer<HiddenMessageWindow> messageWindow;
|
||||
|
||||
void dispatchMessageFromLParam (LPARAM lParam)
|
||||
{
|
||||
MessageManager::MessageBase* const message = reinterpret_cast <MessageManager::MessageBase*> (lParam);
|
||||
|
||||
JUCE_TRY
|
||||
{
|
||||
message->messageCallback();
|
||||
}
|
||||
JUCE_CATCH_EXCEPTION
|
||||
|
||||
message->decReferenceCount();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
LRESULT CALLBACK messageWndProc (HWND h, const UINT message, const WPARAM wParam, const LPARAM lParam) noexcept
|
||||
{
|
||||
JUCE_TRY
|
||||
{
|
||||
if (h == juce_messageWindowHandle)
|
||||
{
|
||||
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
|
||||
// dispatch loop and not calling our version
|
||||
|
||||
Message* const message = reinterpret_cast <Message*> (lParam);
|
||||
MessageManager::getInstance()->deliverMessage (message);
|
||||
message->decReferenceCount();
|
||||
// (These are trapped early in our dispatch loop, but must also be checked
|
||||
// here in case some 3rd-party code is running the dispatch loop).
|
||||
dispatchMessageFromLParam (lParam);
|
||||
return 0;
|
||||
}
|
||||
else if (message == broadcastId)
|
||||
{
|
||||
const ScopedPointer <String> messageString ((String*) lParam);
|
||||
const ScopedPointer<String> messageString ((String*) lParam);
|
||||
MessageManager::getInstance()->deliverBroadcastMessage (*messageString);
|
||||
return 0;
|
||||
}
|
||||
else if (message == WM_COPYDATA && ((const COPYDATASTRUCT*) lParam)->dwData == broadcastId)
|
||||
else if (message == WM_COPYDATA)
|
||||
{
|
||||
const COPYDATASTRUCT* data = (COPYDATASTRUCT*) lParam;
|
||||
const COPYDATASTRUCT* const data = reinterpret_cast <const COPYDATASTRUCT*> (lParam);
|
||||
|
||||
if (data->dwData == broadcastId)
|
||||
{
|
||||
const String messageString (CharPointer_UTF32 ((const CharPointer_UTF32::CharType*) data->lpData),
|
||||
data->cbData / sizeof (CharPointer_UTF32::CharType));
|
||||
|
||||
|
|
@ -73,7 +82,6 @@ namespace WindowsMessageHelpers
|
|||
}
|
||||
}
|
||||
}
|
||||
JUCE_CATCH_EXCEPTION
|
||||
|
||||
return DefWindowProc (h, message, wParam, lParam);
|
||||
}
|
||||
|
|
@ -100,14 +108,13 @@ bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPend
|
|||
{
|
||||
if (m.message == specialId && m.hwnd == juce_messageWindowHandle)
|
||||
{
|
||||
Message* const message = reinterpret_cast <Message*> (m.lParam);
|
||||
MessageManager::getInstance()->deliverMessage (message);
|
||||
message->decReferenceCount();
|
||||
dispatchMessageFromLParam (m.lParam);
|
||||
}
|
||||
else if (m.message == WM_QUIT)
|
||||
{
|
||||
if (JUCEApplicationBase::getInstance() != nullptr)
|
||||
JUCEApplicationBase::getInstance()->systemRequestedQuit();
|
||||
JUCEApplicationBase* const app = JUCEApplicationBase::getInstance();
|
||||
if (app != nullptr)
|
||||
app->systemRequestedQuit();
|
||||
}
|
||||
else if (isEventBlockedByModalComps == nullptr || ! isEventBlockedByModalComps (m))
|
||||
{
|
||||
|
|
@ -130,7 +137,7 @@ bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPend
|
|||
return true;
|
||||
}
|
||||
|
||||
bool MessageManager::postMessageToSystemQueue (Message* message)
|
||||
bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* const message)
|
||||
{
|
||||
message->incReferenceCount();
|
||||
return PostMessage (juce_messageWindowHandle, WindowsMessageHelpers::specialId, 0, (LPARAM) message) != 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue