The Be Book The Application Kit The Application Kit Index

BInvoker

Derived from: none
Declared in:  be/app/Invoker.h
Library: libbe.so
Summary:  more...


BInvoker is a convenience class that bundles up everything you need to create a handy message-sending package. The BInvoker contains: (a) a BMessage, (b) a BMessenger (that identifies a target handler), and (c) an optional BHandler that handles replies. You set these ingredients, invoke Invoke(), and off goes the message to the target. Replies are sent to the reply handler (be_app by default).

BInvoker uses BMessenger::SendMessage() to send its messages. The invocation is asynchronous, and there's no time limit on the reply.

BInvoker is mostly used as a mix-in class. A number of classes in the Interface Kit—notably BControl—derive from BInvoker.


Constructor and Destructor


BInvoker()

BInvoker(BMessage *message, BMessenger messenger)
BInvoker(BMessage *message, const BHandler *handler, const BLooper *looper = NULL)
BInvoker(void)

Initializes the BInvoker by setting its message and its messenger.

If you want a reply handler, you have to call SetHandlerForReply() after the constructor returns. You can reset the message and messenger through SetMessage() and SetTarget().


~BInvoker()

virtual ~BInvoker()

Deletes the object's BMessage.


Member Functions


BeginInvokeNotify() , EndInvokeNotify()

void BeginInvokeNotify(uint32 kind = B_CONTROL_INVOKED)
void EndInvokeNotify()

If for some reason you need to implement a method that emulates an InvokeNotify() call inside an Invoke() implementation, you should wrap the invocation code in these functions. They set up and tear down an InvokeNotify() context.


Command()  see SetMessage()
HandlerForReply()  see SetHandlerForReply()


Invoke() , InvokeNotify()

virtual status_t Invoke(BMessage *message = NULL)
status_t InvokeNotify(BMessage *message, uint32 kind = B_CONTROL_INVOKED)

Invoke() tells the BInvoker's messenger to send a message. If message is non-NULL, that message is sent, otherwise the object sends its default message (i.e. the BMessage that was passed in the constructor or in SetMessage()). The message is sent asynchronously with no time limit on the reply.

Regarding the use of the default message vs the argument, a common practice is to reserve the default message as a template, and pass a fine-tuned copy to Invoke():

/* Add the current system time to a copy of the default message. */
BMessage copy(invoker.Message());
copy.AddInt64("when", system_time());
invoker.Invoke(&copy);

The InvokeNotify() function sends the message to the target, using the notification change code specified by kind. If message is NULL, nothing gets sent to the target, but any watchers of the invoker's handler will receive their expected notifications. By default, the kind is B_CONTROL_INVOKED—the same kind sent by a straight Invoke().

In general, you should call InvokeNotify() instead of Invoke() in new BeOS applications that run under BeOS 5 and later. You can map old code to new like this:

BeOS 4.5.x BeOS 5
Invoke() InvokeNotify(Message())
Invoke(Message()) InvokeNotify(Message())
Invoke(ModificationMessage()) InvokeNotify(ModificationMessage(), B_CONTROL_MODIFIED)

Invoke() doesn't call SendNotices() by default; you'll have to implement code to do it yourself. Here's how:

status_t BControl::Invoke(BMessage *msg) {
   bool notify = false;
   uint32 kind = InvokeKind(&notify);
   
   BMessage clone(kind);
   status_t err = B_BAD_VALUE;
   
   if (!msg && !notify) {
      // If no message is supplied, pull it from the BInvoker.
      // However, ONLY do so if this is not an InvokeNotify()
      // context -- otherwise, this is not the default invocation
      // message, so we don't want it to get in the way here.
      // For example, a control may call InvokeNotify() with their
      // "modification" message... if that message isn't set,
      // we still want to send notification to any watchers, but
      // -don't- want to send a message through the invoker.
      msg = Message();
   }
   if (!msg) {
      // If not being watched, there is nothing to do.
      if( !IsWatched() ) return err;
   } else {
      clone = *msg;
   }

   clone.AddInt64("when", system_time());
   clone.AddPointer("source", this);
   clone.AddInt32("be:value",fValue);
   clone.AddMessenger(B_NOTIFICATION_SENDER, BMessenger(this));
   if( msg ) err = BInvoker::Invoke(&clone);
   
   // Also send invocation to any observers of this handler.
   SendNotices(kind, &clone);
   
   return err;
}

RETURN CODES


InvokeKind()

uint32 InvokeKind(bool *notify = NULL)

Returns the kind passed to InvokeNotify(). This should be called from within your implementation of Invoke() if you need to determine what kind was specified when InvokeNotify() was called. If you care whether Invoke() or InvokeNotify() was originally called, you can specify a pointer to a bool, notify, which is set to true if InvokeNotify() was called, or false if Invoke() was called.

This lets you fetch the InvokeNotify() arguments from your Invoke() code without breaking compatibility with older applications by adding arguments to Invoke().


InvokeNotify()  see Invoke()
IsTargetLocal()  see SetTarget()
Message()  see SetMessage()
Messenger()  see SetTarget()


SetHandlerForReply() , HandlerForReply()

virtual status_t SetHandlerForReply(BHandler *replyHandler)
BHandler *HandlerForReply(void) const

SetHandlerForReply() sets the BHandler object that handles replies that are sent back by the target. By default (or if replyHandler is NULL), replies are sent to the BApplication object.

HandlerForReply() returns the object set through SetHandlerForReply(). If the reply handler isn't set, this function returns NULL, it doesn't return be_app (even though be_app will be handling the reply).

RETURN CODES


SetMessage() , Message() , Command()

virtual status_t SetMessage(BMessage *message)
BMessage *Message(void) const
uint32 Command(void) const

SetMessage() sets the BInvoker's default message to point to message (the message is not copied). The previous default message (if any) is deleted; a NULL message deletes the previous message without setting a new one. The BInvoker owns the BMessage that you pass in; you mustn't delete it yourself.

Message() returns a pointer to the default message, and Command() returns its what data member. Lacking a default message, the functions return NULL.

RETURN CODES


SetTarget() , Target() , IsTargetLocal() , Messenger()

virtual status_t SetTarget(BMessenger messenger)
virtual status_t SetTarget(const BHandler *handler, const BLooper *looper = NULL)
BHandler *Target(BLooper **looper = NULL) const
bool IsTargetLocal(void) const
BMessenger Messenger(void) const

These functions set and query the BInvoker's target. This is the BHandler to which the object sends a message when Invoke() is called. The target is represented by a BMessenger object; you can set the BMessenger as a copy of messenger, or initialize it with looper and handler. See the BMessenger class for details on how a BMessenger identifies a target.

Target() returns the BHandler that's targeted by the object's messenger. If looper is non-NULL, the BLooper that owns the BHandler is returned by reference. If the target was set as a looper's preferred handler (i.e. SetTarget(NULL, looper)), or if the target hasn't been set yet, Target() returns NULL. The function returns NULL for both objects if the target is remote.

IsTargetLocal() returns true if the target lives within the BInvoker's application, and false if it belongs to some other app.

Messenger() returns a copy of the BMessenger object the BInvoker uses to send messages. If a target hasn't been set yet, the return will be invalid.

RETURN CODES

SetTarget() doesn't detect invalid BLoopers and BMessengers.


SetTimeout() , Timeout()

status_t SetTimeout(bigtime_t timeout)
bigtime_t Timeout(void) const

SetTimeout() sets the timeout that will be used when sending the invocation message to the invoker's target. By default this is B_INFINITE_TIMEOUT.

Timeout() returns the current setting for this value.

RETURN CODES


Target()  see SetTarget()
Timeout()  see SetTimeout()


The Be Book The Application Kit The Application Kit Index

The Be Book,
...in lovely HTML...
for BeOS Release 5.

Copyright © 2000 Be, Inc. All rights reserved..