BLooper: Add DispatchExternalMessage()
* This is primarily a service method for ports of widget tool kits that require single-threaded GUI. DispatchExternalMessage() calls DispatchMessage(), but also sets fLastMessage, so that [Detach]CurrentMessage() work correctly. This allows to detach a message in DispatchMessage() when called from the window thread, add it to a global queue, and later process the queued messages in a different thread that calls DispatchExternalMessage(). * BLooper/BWindow: Make sure fLastMessage is accessed only when locked.
This commit is contained in:
@@ -52,6 +52,8 @@ public:
|
|||||||
virtual void MessageReceived(BMessage* message);
|
virtual void MessageReceived(BMessage* message);
|
||||||
BMessage* CurrentMessage() const;
|
BMessage* CurrentMessage() const;
|
||||||
BMessage* DetachCurrentMessage();
|
BMessage* DetachCurrentMessage();
|
||||||
|
void DispatchExternalMessage(BMessage* message,
|
||||||
|
BHandler* handler, bool& _detached);
|
||||||
BMessageQueue* MessageQueue() const;
|
BMessageQueue* MessageQueue() const;
|
||||||
bool IsMessageWaiting() const;
|
bool IsMessageWaiting() const;
|
||||||
|
|
||||||
|
|||||||
+26
-6
@@ -300,6 +300,22 @@ BLooper::DetachCurrentMessage()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BLooper::DispatchExternalMessage(BMessage* message, BHandler* handler,
|
||||||
|
bool& _detached)
|
||||||
|
{
|
||||||
|
AssertLocked();
|
||||||
|
|
||||||
|
BMessage* previousMessage = fLastMessage;
|
||||||
|
fLastMessage = message;
|
||||||
|
|
||||||
|
DispatchMessage(message, handler);
|
||||||
|
|
||||||
|
_detached = fLastMessage == NULL;
|
||||||
|
fLastMessage = previousMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BMessageQueue*
|
BMessageQueue*
|
||||||
BLooper::MessageQueue() const
|
BLooper::MessageQueue() const
|
||||||
{
|
{
|
||||||
@@ -1115,11 +1131,14 @@ BLooper::task_looper()
|
|||||||
bool dispatchNextMessage = true;
|
bool dispatchNextMessage = true;
|
||||||
while (!fTerminating && dispatchNextMessage) {
|
while (!fTerminating && dispatchNextMessage) {
|
||||||
PRINT(("LOOPER: inner loop\n"));
|
PRINT(("LOOPER: inner loop\n"));
|
||||||
// Get next message from queue (assign to fLastMessage)
|
// Get next message from queue (assign to fLastMessage after
|
||||||
fLastMessage = fDirectTarget->Queue()->NextMessage();
|
// locking)
|
||||||
|
BMessage* message = fDirectTarget->Queue()->NextMessage();
|
||||||
|
|
||||||
Lock();
|
Lock();
|
||||||
|
|
||||||
|
fLastMessage = message;
|
||||||
|
|
||||||
if (!fLastMessage) {
|
if (!fLastMessage) {
|
||||||
// No more messages: Unlock the looper and terminate the
|
// No more messages: Unlock the looper and terminate the
|
||||||
// dispatch loop.
|
// dispatch loop.
|
||||||
@@ -1173,14 +1192,15 @@ BLooper::task_looper()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message = fLastMessage;
|
||||||
|
fLastMessage = NULL;
|
||||||
|
|
||||||
// Unlock the looper
|
// Unlock the looper
|
||||||
Unlock();
|
Unlock();
|
||||||
|
|
||||||
// Delete the current message (fLastMessage)
|
// Delete the current message (fLastMessage)
|
||||||
if (fLastMessage) {
|
if (message != NULL)
|
||||||
delete fLastMessage;
|
delete message;
|
||||||
fLastMessage = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Are any messages on the port?
|
// Are any messages on the port?
|
||||||
if (port_count(fMsgPort) > 0) {
|
if (port_count(fMsgPort) > 0) {
|
||||||
|
|||||||
@@ -3037,12 +3037,17 @@ BWindow::task_looper()
|
|||||||
|
|
||||||
bool dispatchNextMessage = true;
|
bool dispatchNextMessage = true;
|
||||||
while (!fTerminating && dispatchNextMessage) {
|
while (!fTerminating && dispatchNextMessage) {
|
||||||
// Get next message from queue (assign to fLastMessage)
|
// Get next message from queue (assign to fLastMessage after
|
||||||
fLastMessage = fDirectTarget->Queue()->NextMessage();
|
// locking)
|
||||||
|
BMessage* message = fDirectTarget->Queue()->NextMessage();
|
||||||
|
|
||||||
// Lock the looper
|
// Lock the looper
|
||||||
if (!Lock())
|
if (!Lock()) {
|
||||||
|
delete message;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fLastMessage = message;
|
||||||
|
|
||||||
if (fLastMessage == NULL) {
|
if (fLastMessage == NULL) {
|
||||||
// No more messages: Unlock the looper and terminate the
|
// No more messages: Unlock the looper and terminate the
|
||||||
|
|||||||
Reference in New Issue
Block a user