All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
Public Member Functions | Static Public Member Functions | List of all members
BHandler Class Reference

Handles messages that are passed on by a BLooper. More...

Inherits BArchivable.

Inherited by BLooper, BShelf, and BView.

Public Member Functions

 BHandler (const char *name=NULL)
 Construct a new handler with a name.
 
virtual ~BHandler ()
 Free the filters of this handler, as well as the list of observers.
 
virtual status_t Perform (perform_code d, void *arg)
 Perform some action (Internal method defined for binary compatibility purposes).
 
Archiving

BHandler inherits the BArchivable class, and as such implements support for archiving and unarchiving handlers.

 BHandler (BMessage *data)
 Construct a handler from an archived message.
 
virtual status_t Archive (BMessage *data, bool deep=true) const
 Archive a handler to a message.
 
Core Handler Functionality
virtual void MessageReceived (BMessage *message)
 Handle message that has been received by the associated looper.
 
BLooperLooper () const
 Return a pointer to the looper that this handler is associated with.
 
void SetName (const char *name)
 Set or change the name of this handler.
 
const char * Name () const
 Return the name of this handler.
 
virtual void SetNextHandler (BHandler *handler)
 Set the next handler in the chain that the message is passed on to if this handler cannot process it.
 
BHandlerNextHandler () const
 Return the next hander in the chain to which the message is passed on.
 
Message Filtering
virtual void AddFilter (BMessageFilter *filter)
 Add filter as a prerequisite to this handler.
 
virtual bool RemoveFilter (BMessageFilter *filter)
 Remove filter from the filter list.
 
virtual void SetFilterList (BList *filters)
 Set the internal list of filters to filters.
 
BListFilterList ()
 Return a pointer to the list of filters.
 
Locking

This class provides some utility functions to lock the looper associated with this handler.

bool LockLooper ()
 Lock the looper associated with this handler.
 
status_t LockLooperWithTimeout (bigtime_t timeout)
 Lock the looper associated with this handler, with a time out value.
 
void UnlockLooper ()
 Unlock the looper.
 
Scripting
virtual BHandlerResolveSpecifier (BMessage *message, int32 index, BMessage *specifier, int32 what, const char *property)
 Determine the proper handler for a scripting message.
 
virtual status_t GetSupportedSuites (BMessage *data)
 Reports the suites of messages and specifiers that derived classes understand.
 
Observing

Handlers can function as state machines, which emit messages to observers when the state changes. Use the following methods to subscribe to these notifications.

Note that there is a semantic difference between the two StartWatching() methods. The overloaded method that accepts a BHandler, expects as argument an observer that watches this handler. The method that accepts a BMessenger, expects a target that emits the state changes to this handler.

status_t StartWatching (BMessenger target, uint32 what)
 Subscribe this handler to watch a specific state change of a target.
 
status_t StartWatchingAll (BMessenger target)
 Subscribe this handler to watch a target for all events.
 
status_t StopWatching (BMessenger target, uint32 what)
 Unsubscribe this handler from watching a specific state.
 
status_t StopWatchingAll (BMessenger target)
 Unsubscribe this handler from watching all states.
 
status_t StartWatching (BHandler *observer, uint32 what)
 Subscribe an observer for a specific state change of this handler.
 
status_t StartWatchingAll (BHandler *observer)
 Subscribe an observer for a all state changes.
 
status_t StopWatching (BHandler *observer, uint32 what)
 Unsubscribe an observer from watching a specific state.
 
status_t StopWatchingAll (BHandler *observer)
 Unsubscribe an observer from watching all states.
 
Emitting State Changes

If your handler functions as a state machine, and it has observers (which subscribed using the StartWatching() method), you can emit these state changes.

virtual void SendNotices (uint32 what, const BMessage *notice=NULL)
 Emit a state change to the observers.
 
bool IsWatched () const
 Check if there are any observers watching this handler.
 
- Public Member Functions inherited from BArchivable
 BArchivable ()
 Constructor. Does nothing.
 
 BArchivable (BMessage *from)
 Constructor. Does important behind-the-scenes work in the unarchiving process.
 
virtual ~BArchivable ()
 Destructor. Does nothing.
 
virtual status_t AllArchived (BMessage *archive) const
 Method relating to the use of BArchiver.
 
virtual status_t AllUnarchived (const BMessage *archive)
 Method relating to the use of BUnarchiver.
 
virtual status_t Archive (BMessage *into, bool deep=true) const
 Archive the object into a BMessage.
 
virtual status_t Perform (perform_code d, void *arg)
 Perform some action (Internal method defined for binary compatibility purposes).
 

Static Public Member Functions

static BArchivableInstantiate (BMessage *data)
 Static method to instantiate a handler from an archived message.
 
- Static Public Member Functions inherited from BArchivable
static BArchivableInstantiate (BMessage *archive)
 Static member to restore objects from messages.
 

Detailed Description

Handles messages that are passed on by a BLooper.

The BHandler class implements two important pieces of functionality. It provides the foundations for handling messages, and it serves as a state machine that sends out notifications of the state changes.

The most common use of this class is to handle messages. Handlers can be tied to loopers, which are the objects that send and receive messages. As soon as a message is received, the looper passes through its list of associated handlers and tries them in a certain order until the message is handled, or the options are exhausted.

You should know that a looper is a subclass of a handler, and as such, loopers can be self-contained and do not need additional handlers. In many cases, this construction will suffice. You will simply subclass the looper, override its MessageReceived() hook and handle the messages you receive. In some cases, you might opt in for a more ingenious construction. A real-world example is the interface kit. Within that kit, the windows are represented by a BLooper, and all the views and controls in that kit are derived from BHandler. If you put a control in a window, then whenever messages such as clicks are received, the window loops the handlers until there is a handler that is at the screen position the click was in. It is not unlikely that you will some day want to use this functionality of the API.

If your handler is limited to a certain type of messages, you can set a filter that the looper will apply to your message before passing it on to your overridden MessageReceived() method. The BMessageFilter class provides the framework for the flexible filtering options, and using AddFilter() you can apply filters to this handler. Note that a filter object should only be applied to one handler. They cannot be shared.

For more information on the handling chain, have a look at the documentation of the BLooper class.

Using BHandler as a state machine is a second area of functionality. Since handlers process messages, and perform actions associated with those, they are the center of keeping track on the current state of things within an application. If you want to synchronize these states between different parts of your application, you could perform this manually by sending messages to the interested components, or you can use the more flexible approach with observers.

Observers watch a certain state. A handler can track one or more different states. Each state is represented by a four byte constant - just like the what property of a message. Using the StartWatching() methods, you can register observers both within your team, and in other applications. As an argument of that method, you can supply the state you want to watch, or you can register an observer using StartWatchingAll() to watch all the states the handler tracks. When the handler needs to emit a state change, you can use SendNotices(). You can specify the exact state change, and some data that you want to be send to the observers. This data is in the form of the very flexible BMessage, as such you are almost free to pass anything you want.

Whenever SendNotices() is called, all interested observers will receive a message of the B_OBSERVER_NOTICE_CHANGE type. Please note that the constant that is associated with the state itself is not transmitted. If you require this information, consider using the message that is passed on to describe the state change.

BHandler is a part of the chain in the eloquent messaging structure. For a proper understanding of all its facets, have a look at the messaging overview.

Since
BeOS R3

Constructor & Destructor Documentation

◆ BHandler() [1/2]

BHandler::BHandler ( const char *  name = NULL)

Construct a new handler with a name.

The newly constructed handler is not associated with a looper until you explicitly request this to happen. To associate this handler with a looper, use BLooper::AddHandler().

Since
BeOS R3

◆ ~BHandler()

BHandler::~BHandler ( )
virtual

Free the filters of this handler, as well as the list of observers.

This method does not remove the handler from the looper to which this handler is associated. You should do this yourself, using BLooper::RemoveHandler().

Warning
This constructor does no type check whatsoever. Since you can pass any BMessage, you should - if you are not sure about the exact type - use the Instantiate() method, which does check the type.
Since
BeOS R3

◆ BHandler() [2/2]

BHandler::BHandler ( BMessage data)

Construct a handler from an archived message.

This data has to be created using the BHandler::Archive() method. Note that only the name is stored. The filters, the associated looper and the observers are not stored, and should be manually added when you are using this object.

Since
BeOS R3

Member Function Documentation

◆ AddFilter()

void BHandler::AddFilter ( BMessageFilter filter)
virtual

Add filter as a prerequisite to this handler.

If the handler is associated with a looper, this looper needs to be locked in order for this operation to succeed.

Note that the filter is not copied, rather a pointer to the filter is stored. As such, you need to make sure that the filter object exists as long as it is added to this handler.

See also
RemoveFilter()
SetFilterList()
Since
BeOS R3

◆ Archive()

status_t BHandler::Archive ( BMessage data,
bool  deep = true 
) const
virtual

Archive a handler to a message.

Currently, only the name is archived. The filters, the associated looper and the observers are not stored.

Parameters
dataThe message to archive the object in.
deepThis parameter is ignored, as BHandler does not have children.
Returns
A status code.
Return values
B_OKArchiving succeeded.
B_BAD_VALUEThe data parameter is not a valid message.
See also
BHandler::Instantiate(BMessage* data)
Since
BeOS R3

Reimplemented from BArchivable.

Reimplemented in BBox, BMenu, BMenuBar, BMenuField, BOutlineListView, BPictureButton, BPopUpMenu, BScrollBar, BScrollView, BStatusBar, BStringView, BTextControl, BTextView, BView, BWindow, BApplication, BLooper, BDirectWindow, BAlert, BButton, BChannelControl, BCheckBox, BColorControl, BControl, BDragger, BListView, BRadioButton, BChannelSlider, BSeparatorView, BSplitView, and BTabView.

◆ FilterList()

BList * BHandler::FilterList ( )

Return a pointer to the list of filters.

Returns
A pointer to the list of filters. Do not manipulate the list of filters directly, but use the methods provided by this class, in order to maintain internal consistency.
See also
AddFilter()
RemoveFilter()
SetFilterList().
Since
BeOS R3

◆ GetSupportedSuites()

status_t BHandler::GetSupportedSuites ( BMessage data)
virtual

◆ Instantiate()

BArchivable * BHandler::Instantiate ( BMessage data)
static

Static method to instantiate a handler from an archived message.

Returns
A pointer to the instantiated handler, or NULL if the data is not a valid archived BHandler object.
See also
BHandler(BMessage* data)
Since
BeOS R3

◆ IsWatched()

bool BHandler::IsWatched ( ) const

Check if there are any observers watching this handler.

Since
BeOS R5

◆ LockLooper()

bool BHandler::LockLooper ( )

Lock the looper associated with this handler.

Returns
true if the looper is locked, false if there was an error acquiring the lock.
See also
LockLooperWithTimeout()
UnlockLooper()
Since
BeOS R4

◆ LockLooperWithTimeout()

status_t BHandler::LockLooperWithTimeout ( bigtime_t  timeout)

Lock the looper associated with this handler, with a time out value.

Parameters
timeoutThe time to wait for acquiring the lock in microseconds. You may also use B_INFINITE_TIMEOUT, in which this method will wait as long as it takes to acquire the lock.
Returns
A status code.
Return values
B_OKLocking succeeded.
B_BAD_VALUEThis handler is not associated with a looper (anymore).
B_TIMED_OUTThe time specified in timeout has passed without locking the looper.
See also
LockLooper()
UnlockLooper()
Since
BeOS R4

◆ Looper()

BLooper * BHandler::Looper ( ) const

Return a pointer to the looper that this handler is associated with.

Returns
If the handler is not yet associated with a looper, it will return NULL.
See also
BLooper::AddHandler()
LockLooper()
Since
BeOS R3

◆ MessageReceived()

void BHandler::MessageReceived ( BMessage message)
virtual

Handle message that has been received by the associated looper.

This method is reimplemented by subclasses. If the messages that have been received by a looper pass through the filters, then they end up in the MessageReceived() methods.

The example below shows a very common way to handle message. Usually, this involves parsing the BMessage::what constant and then perform an action based on that.

void
ShowImageApp::MessageReceived(BMessage *message)
{
switch (message->what) {
case MSG_FILE_OPEN:
fOpenPanel->Show();
break;
case B_CANCEL:
// File open panel was closed,
// start checking count of open windows.
StartPulse();
break;
default:
// We do not handle this message, pass it on to the base class.
break;
}
}
virtual void MessageReceived(BMessage *message)
A container that can be send and received using the Haiku messaging subsystem.
Definition: Message.h:56
uint32 what
A 4-byte constant that determines the type of message.
Definition: Message.h:58

If your handler cannot process this message, you should pass it on to the base class. Eventually, it will reach the base implementation, which will reply with B_MESSAGE_NOT_UNDERSTOOD.

Attention
If you want to keep or manipulate the message, have a look at BLooper::DetachCurrentMessage() to receive ownership of the message.
Parameters
messageThe message that needs to be handled.
Since
BeOS R3

Reimplemented in BApplication, BLooper, BDirectWindow, BAlert, BBox, BButton, BChannelControl, BChannelSlider, BCheckBox, BColorControl, BControl, BDragger, BListView, BMenu, BMenuBar, BMenuField, BOptionControl, BOptionPopUp, BOutlineListView, BPictureButton, BPopUpMenu, BRadioButton, BScrollBar, BScrollView, BSplitView, BStatusBar, BStringView, BTabView, BTextControl, BTextView, BView, and BWindow.

◆ Name()

const char * BHandler::Name ( ) const

Return the name of this handler.

See also
SetName()
Since
BeOS R3

◆ NextHandler()

BHandler * BHandler::NextHandler ( ) const

Return the next hander in the chain to which the message is passed on.

See also
SetNextHandler()
Since
BeOS R3

◆ Perform()

virtual status_t BHandler::Perform ( perform_code  d,
void *  arg 
)
virtual

◆ RemoveFilter()

bool BHandler::RemoveFilter ( BMessageFilter filter)
virtual

Remove filter from the filter list.

If the handler is associated with a looper, this looper needs to be locked in order for this operation to succeed.

Note that the filter is not deleted, merely removed from the list. You need to take care of the memory yourself.

Returns
true if the filter was in the filter list and is removed, false if the filter was not found in the filter list.
See also
AddFilter()
FilterList()
Since
BeOS R3

◆ ResolveSpecifier()

BHandler * BHandler::ResolveSpecifier ( BMessage message,
int32  index,
BMessage specifier,
int32  what,
const char *  property 
)
virtual

Determine the proper handler for a scripting message.

Parameters
messageThe scripting message to determine the handler.
indexThe index of the specifier.
specifierThe message which contains the specifier.
whatThe 'what' field of the specifier message.
propertyThe name of the target property.
Returns
A pointer to the proper BHandler for the given scripting message.
Since
BeOS R3

Reimplemented in BApplication, BAlert, BChannelSlider, BDragger, BMenu, BMenuBar, BMenuField, BPopUpMenu, BStringView, BTextView, BView, BLooper, BDirectWindow, BBox, BButton, BChannelControl, BCheckBox, BColorControl, BControl, BListView, BOutlineListView, BPictureButton, BRadioButton, BScrollBar, BScrollView, BStatusBar, BTabView, BTextControl, and BWindow.

◆ SendNotices()

void BHandler::SendNotices ( uint32  what,
const BMessage notice = NULL 
)
virtual

Emit a state change to the observers.

The actual state (specified by what) will not be transmitted. This is merely for internal bookkeeping. It is not entirely unimaginable that you still want to inform the observers of what actually took place. You can use the msg to transmit this, and any other data you want. Note that the message will be copied and slightly altered: the what member of the message will be B_OBSERVER_NOTICE_CHANGE, and the what constant you specified will be stored in the B_OBSERVE_ORIGINAL_WHAT label.

Parameters
whatThe identifier of the state.
noticeAny data associated with the state change. You retain ownership of this data, so make sure you dispose it when you are done.
Since
BeOS R5

◆ SetFilterList()

void BHandler::SetFilterList ( BList filters)
virtual

Set the internal list of filters to filters.

If the handler is associated with a looper, this looper needs to be locked in order for this operation to succeed.

The internal list will be replaced with the new list of filters. All the existing filters will be deleted.

See also
AddFilter(), FilterList()
Since
BeOS R3

◆ SetName()

void BHandler::SetName ( const char *  name)

Set or change the name of this handler.

See also
Name()
Since
BeOS R3

◆ SetNextHandler()

void BHandler::SetNextHandler ( BHandler handler)
virtual

Set the next handler in the chain that the message is passed on to if this handler cannot process it.

This method has three requirements:

  1. This handler should belong to a looper.
  2. The looper needs to be locked. See LockLooper().
  3. The handler that you pass must be associated with the same looper.

Failure to meet any of these requirements will result in your application crashing.

By default, the handlers are chained in order that they were associated to a looper with BLooper::AddHander().

See also
NextHandler()
Since
BeOS R3

◆ StartWatching() [1/2]

status_t BHandler::StartWatching ( BHandler observer,
uint32  what 
)

Subscribe an observer for a specific state change of this handler.

Use this method to subscribe observers to watch this handler. State changes of this handler that match the what argument, will be sent.

// Handler B wants to observe Handler A
BHandler A, B;
A.StartWatching(&B, kNetworkConnection);
Handles messages that are passed on by a BLooper.
Definition: Handler.h:29
status_t StartWatching(BMessenger target, uint32 what)
Subscribe this handler to watch a specific state change of a target.

Since pointers to handlers can only exist in the local namespace, have a look at StartWatching(BMessenger, uint32) for inter-team watching.

Parameters
observerThe observer for this handler.
whatThe state that needs to be watched.
Returns
During the call of this method, a notification will be transmitted using the observer. If this works, then this method will return B_OK.
See also
StartWatchingAll(BHandler*), StopWatching(BHandler*, uint32)
Since
BeOS R5

◆ StartWatching() [2/2]

status_t BHandler::StartWatching ( BMessenger  target,
uint32  what 
)

Subscribe this handler to watch a specific state change of a target.

Use this method to subscribe messengers to watch state changes in this handler, this also means that observers from other teams can be subscribed.

// Handler B watches Handler A
BHandler A, B;
BMessenger messengerA(&A)
B.StartWatching(messengerA, kNetworkConnection);
A class to send messages to a target BLooper or BHandler.
Definition: Messenger.h:20
Parameters
targetThe messenger from which the notifications would be received.
whatThe state that needs to be watched.
Returns
During the call of this method, a notification will be transmitted using the target. If this works, then this method will return B_OK.
See also
StartWatchingAll(BMessenger), StopWatching(BMessenger, uint32)
Since
BeOS R5

◆ StartWatchingAll() [1/2]

status_t BHandler::StartWatchingAll ( BHandler observer)

Subscribe an observer for a all state changes.

This method performs the same task as StartWatching(BHandler, uint32), but it will subscribe the observer to all the state changes this handler tracks.

See also
StartWatching(BHandler*, uint32), StopWatchingAll(BHandler*)
Since
BeOS R5

◆ StartWatchingAll() [2/2]

status_t BHandler::StartWatchingAll ( BMessenger  target)

Subscribe this handler to watch a target for all events.

This method performs the same task as StartWatching(BMessenger, uint32), but it will subscribe to all the state changes the target knows.

See also
StartWatching(BMessenger, uint32), StopWatchingAll(BMessenger)
Since
BeOS R5

◆ StopWatching() [1/2]

status_t BHandler::StopWatching ( BHandler handler,
uint32  what 
)

Unsubscribe an observer from watching a specific state.

This method will unsubscribe the handler from watching a specific event.

See also
StartWatching(BHandler*, uint32)
Since
BeOS R5

◆ StopWatching() [2/2]

status_t BHandler::StopWatching ( BMessenger  target,
uint32  what 
)

Unsubscribe this handler from watching a specific state.

This method will unsubscribe this handler from watching a specific event in a target.

See also
StartWatching(BMessenger, uint32)
Since
BeOS R5

◆ StopWatchingAll() [1/2]

status_t BHandler::StopWatchingAll ( BHandler handler)

Unsubscribe an observer from watching all states.

This method will unsubscribe the handler from watching all state changes.

See also
StartWatchingAll(BHandler*)
Since
BeOS R5

◆ StopWatchingAll() [2/2]

status_t BHandler::StopWatchingAll ( BMessenger  target)

Unsubscribe this handler from watching all states.

This method will unsubscribe the target from watching all state changes.

See also
StartWatchingAll(BMessenger)
Since
BeOS R5

◆ UnlockLooper()

void BHandler::UnlockLooper ( )

Unlock the looper.

Since
BeOS R4