| 1 |
/* |
|---|
| 2 |
* Copyright 2007, Haiku, Inc. All Rights Reserved. |
|---|
| 3 |
* Distributed under the terms of the MIT License. |
|---|
| 4 |
* |
|---|
| 5 |
* Authors: |
|---|
| 6 |
* Niels Sascha Reedijk, niels.reedijk@gmail.com |
|---|
| 7 |
*/ |
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 |
/*! |
|---|
| 11 |
\page app_messaging Messaging Foundations |
|---|
| 12 |
|
|---|
| 13 |
One of the foundations of the Haiku API is the messaging system. This |
|---|
| 14 |
framework is the basis for the efficient multithreaded Haiku applications, |
|---|
| 15 |
because it solves one of the fundamental issues of multithreading: it |
|---|
| 16 |
allows you to easily and securely communicate between threads. The |
|---|
| 17 |
framework allows inter-application messaging as well as |
|---|
| 18 |
intra-application messaging, and it will always use the most effective |
|---|
| 19 |
mechanism for the communication automatically. |
|---|
| 20 |
|
|---|
| 21 |
This page will introduce you to the subject of messaging. It is meant as a |
|---|
| 22 |
broad overview to the classes, rather than a tutorial. If you are looking |
|---|
| 23 |
for effective messaging techniques or a tutorial on messaging, have a look |
|---|
| 24 |
at the developer section of the Haiku website. |
|---|
| 25 |
|
|---|
| 26 |
<b>Table of contents</b> |
|---|
| 27 |
- Overview of the Messaging Classes |
|---|
| 28 |
- Receiving and Handling Messages |
|---|
| 29 |
- Sending messages |
|---|
| 30 |
|
|---|
| 31 |
\section app_messaging_overview Overview of the Messaging Classes |
|---|
| 32 |
|
|---|
| 33 |
\subsection app_messaging_overview_bmessage BMessage |
|---|
| 34 |
|
|---|
| 35 |
The BMessage class is the class that is in the center of all the messenger |
|---|
| 36 |
operations, because it represents a message. A message is nothing more than |
|---|
| 37 |
an object that contains: |
|---|
| 38 |
- The \c what member, an \c uint32 that determines the type of message. |
|---|
| 39 |
Some constants are defined by the Haiku API, for example B_MOUSE_DOWN or |
|---|
| 40 |
B_QUIT_REQUESTED. |
|---|
| 41 |
- Zero or more data objects. BMessage is a powerful data container that |
|---|
| 42 |
keeps track of different sorts of data. BMessage provides many convenient |
|---|
| 43 |
Add*() methods, for example BMessage::AddBool(). With the corresponding |
|---|
| 44 |
Find*() method (in this example, |
|---|
| 45 |
\link BMessage::FindBool(const char *, int32, bool *) const FindBool() \endlink) |
|---|
| 46 |
you can retrieve the data. |
|---|
| 47 |
|
|---|
| 48 |
BMessage itself is generic, its syntax and semantics are determined by the |
|---|
| 49 |
context. The Haiku API defines several messages and their required data |
|---|
| 50 |
members. Several applications provide a scripting interface with defined |
|---|
| 51 |
message syntax. You can do the same for your application. |
|---|
| 52 |
|
|---|
| 53 |
\subsection app_messaging_overview_blooper BLooper |
|---|
| 54 |
|
|---|
| 55 |
Objects of the BLooper type are objects that run message loops. Every |
|---|
| 56 |
object runs in its own thread. The BLooper objects continually check for |
|---|
| 57 |
incoming messages. To process the messages, the looper looks for message |
|---|
| 58 |
handlers that handle the messages within the thread's context. Message |
|---|
| 59 |
handling within a looper is synchronous. |
|---|
| 60 |
|
|---|
| 61 |
BLooper inherits BHandler, the base class for message handling. However, it |
|---|
| 62 |
is possible to chain additional handlers to the object. For example, if you |
|---|
| 63 |
have an application that understands different networking protocols, and |
|---|
| 64 |
you support extensions that understand the base protocol, these extensions |
|---|
| 65 |
can provide handlers that you can chain in your general message parser |
|---|
| 66 |
thread. See AddHandler() and SetPreferredHandler() for information on |
|---|
| 67 |
handlers. |
|---|
| 68 |
|
|---|
| 69 |
Messages can be posted to the looper by using the object's PostMessage() |
|---|
| 70 |
method. This method puts the message in the BMessageQueue of the looper. |
|---|
| 71 |
Since PostMessage() is asynchronous, the message might not be handled |
|---|
| 72 |
immediately. See \ref app_messaging_overview_bmessenger "BMessenger" |
|---|
| 73 |
for a synchronous implementation. |
|---|
| 74 |
|
|---|
| 75 |
Loopers can have a generic filter that discards messages based on |
|---|
| 76 |
user-definable characteristics. The BMessageFilter class provides the |
|---|
| 77 |
foundation for the qualifying of messages. See AddCommonFilterList() and |
|---|
| 78 |
SetCommonFilterList() for more information. |
|---|
| 79 |
|
|---|
| 80 |
To get the most out of the functionality of BLooper, it is usually |
|---|
| 81 |
subclassed to create a self-contained event 'machine'. Most of the time, |
|---|
| 82 |
these subclasses also perform the message handling, which is possible |
|---|
| 83 |
due to the fact that it is also a subclass of BHandler. |
|---|
| 84 |
|
|---|
| 85 |
In the Haiku API, there are two major classes that inherit BLooper: |
|---|
| 86 |
the base application class, BApplication, and the window class, BWindow. |
|---|
| 87 |
Because they inherit BLooper, each application and each window has its |
|---|
| 88 |
own message loop. This makes every window quick and responsive. To keep |
|---|
| 89 |
your applications running smoothly, it is advisable to make sure that |
|---|
| 90 |
event handling that requires more processing power, is done within its own |
|---|
| 91 |
BLooper context. Networking usually qualifies as a candidate for its own |
|---|
| 92 |
thread. |
|---|
| 93 |
|
|---|
| 94 |
\subsection app_messaging_overview_bhandler BHandler |
|---|
| 95 |
|
|---|
| 96 |
Objects of the BHandler type are associated to BLoopers. When they are |
|---|
| 97 |
created, they should be passed to the BLooper::AddHandler() method of the |
|---|
| 98 |
looper they want to handle messages for. They can then either be set as |
|---|
| 99 |
preferred handlers (by chaining them with BLooper::SetPreferredHandler()), |
|---|
| 100 |
or they can be added to other BHandlers with the SetNextHandler() method. |
|---|
| 101 |
|
|---|
| 102 |
The magic of the class happens in the MessageReceived() method. In your |
|---|
| 103 |
subclasses you override this method, to check the incoming BMessage. |
|---|
| 104 |
Usually, you check the \c what member of the message in a switch statement. |
|---|
| 105 |
If your handler cannot handle the object, it will pass the message on to |
|---|
| 106 |
the parent class. |
|---|
| 107 |
|
|---|
| 108 |
\warning Don't forget to actuall call the MessageReceived() method of the |
|---|
| 109 |
base class. Failing to do this will mean that the message chain will |
|---|
| 110 |
not completely be followed, which can lead to unhandled messages. There |
|---|
| 111 |
might be some internal system messages that the Haiku API classes |
|---|
| 112 |
handle, and not actually handling these messages could lead to |
|---|
| 113 |
inconsistent internal behavior. |
|---|
| 114 |
|
|---|
| 115 |
\subsection app_messaging_overview_bmessenger BMessenger |
|---|
| 116 |
|
|---|
| 117 |
BMessenger objects can send messages to both local and remote targets. For |
|---|
| 118 |
local targets, a BMessenger provides an advantage over directly calling |
|---|
| 119 |
the BLooper::PostMessage() method: some variants of the |
|---|
| 120 |
BMessenger::SendMessage() methods allow for synchronous replies. So, the |
|---|
| 121 |
call will actually verify the handling thread processes the message, and |
|---|
| 122 |
reply to the sender. |
|---|
| 123 |
|
|---|
| 124 |
The other feature of BMessenger is that it is able to be constructed with |
|---|
| 125 |
the signature of another application as argument. This allows the messenger |
|---|
| 126 |
to pass messages to other applications. It facilitates inter-application |
|---|
| 127 |
communication. |
|---|
| 128 |
|
|---|
| 129 |
\subsection app_messaging-overview-other Other messaging classes |
|---|
| 130 |
|
|---|
| 131 |
There are several convenience classes supplied with the application kit, |
|---|
| 132 |
which can make your life easier in some specific cases. |
|---|
| 133 |
|
|---|
| 134 |
- BInvoker binds together a message and a target. By calling |
|---|
| 135 |
BInvoker::Invoke(), the message will be sent. This class is inherited by |
|---|
| 136 |
the controls in the interface kit, such as BButton. |
|---|
| 137 |
- A BMessageRunner object will send messages to a specified target with |
|---|
| 138 |
specified intervals in between. |
|---|
| 139 |
- BMessageQueue is a class that is also internally used by BLooper. It |
|---|
| 140 |
provides a queue of messages, with convenience functions of managing |
|---|
| 141 |
this queue. |
|---|
| 142 |
- BMessageFilter is the base class of the filters. Filters can be applied |
|---|
| 143 |
to BLoopers to filter all incoming messages, or to BHandlers to filter |
|---|
| 144 |
messages that could be handled by that object. The filter object can be |
|---|
| 145 |
subclassed and extended by overriding the \link BMessageFilter::Filter() |
|---|
| 146 |
Filter() \endlink method. |
|---|
| 147 |
|
|---|
| 148 |
\section app-messaging-receiving Receiving Messages |
|---|
| 149 |
|
|---|
| 150 |
To do... |
|---|
| 151 |
|
|---|
| 152 |
\section app-messaging-sending Sending Messages |
|---|
| 153 |
|
|---|
| 154 |
To do... |
|---|
| 155 |
|
|---|
| 156 |
*/ |
|---|
| 157 |
|
|---|