Basic Examples of how to use SH_NAME_ONSUCCESS
Example 1: Detecting when your network connections have been successfully
set up.
// For this example, we will add one child,
named "Joe", to the root node.
BMessage msg(SH_COMMAND_ADDCOMPONENTS);
msg.AddString(SH_NAME_TO, "/");
msg.AddFlat(SH_NAME_CHILDREN, &SHNodeSpec("Joe",
"beos.sockhop.com"));
// Since we want to know when it succeeds,
we add a BMessage to it that will be sent back to us...
BMessage onSuccessMsg('sxss');
// choose any 'what' value here that you will recognize later
// Address the success message to ourself.
Remember that it will be posted
// from the parent of the newly created
node.
onSuccessMsg.AddString(SH_NAME_TO, "/..");
// Finally, add the on-success BMessage
to the original BMessage before sending it.
msg.AddMessage(SH_NAME_ONSUCCESS, &onSuccessMsg);
root->PostMessage(&msg);
[... meanwhile, in your target BLooper's MessageReceived()
method...]
void MyLooper :: MessageReceived(BMessage
* msg)
{
if (msg->what
== 'sxss')
{
printf("Got a success message back! Our connection must have succeeded!\n");
// We can find out exactly who it was who succeeded this way:
SHNodeSpec whoWasIt;
if (msg->FindFlat(SH_NAME_REGARDING, &whoWasIt) == B_NO_ERROR)
{
printf("The child who was created successfully is:\n");
whoWasIt.PrintToStream();
}
}
}
Example 2: Detecting when your add-on worker has started running
on a remote node:
// Okay, let's start a TestWorker object
running on the node "/Joe"
// ("/Joe" is assumed to already be set
up and running in your node tree)
BMessage msg(SH_COMMAND_ADDCOMPONENTS);
msg.AddString(SH_NAME_TO, "/Joe");
// Create a worker, capture his soul into
a BMessage, and add him to our request BMessage.
TestWorker worker;
BMessage archive;
worker.Archive(&archive);
msg.AddMessage(SH_NAME_WORKERS, &archive);
// Now create a self-addressed, stamped
BMessage that will be posted by "/Joe"
// as soon as the TestWorker is running
there.
BMessage onSuccess('SuCC');
onSuccess.AddString(SH_NAME_TO, "/..");
msg.AddMessage(SH_NAME_ONSUCCESS, &onSuccess);
root->PostMessage(&msg);
Fancy Examples of SH_NAME_ONSUCCESS
Example 3: "Daisy-chaining" a BMessage. Imagine you have
three nodes in your tree, "/Peter", "/Paul", and "/Mary." Imagine
that you (for some reason) want to send a BMessage that travels to each
of these nodes, in succession. That is, it should go to Peter,
then Paul, then Mary. (Contrast this example to routing
the BMessage to all three nodes in parallel, where it would be a simple
matter of giving the BMessage an SH_NAME_TO field like "/*") Because
a user-level BMessage succeeds exactly once on each node it is received
by, you can use SH_NAME_ONSUCCESS to accomplish this behavior:
// First, here is the BMessage we want
each node to receive.
BMessage toPeter('Helo');
// Some user BMessage, doesn't matter what.
// Will be received by the SHWorkers on "/Peter".
// (toPeter) will go to "/Peter".
toPeter.AddString(SH_NAME_TO, "/Peter");
// When it arrives at Peter, it will post
its success BMessage. That BMessage will go to Paul.
BMessage toPaul('Helo');
toPaul.AddString(SH_NAME_TO, "/Paul");
// And when (toPaul) arrives at Paul, it
should post (toMary).
BMessage toMary('Helo');
toMary.AddString(SH_NAME_TO, "/Mary");
// Now we compose the BMessages together,
innermost first (order matters!)
toPaul.AddMessage(SH_NAME_ONSUCCESS, &toMary);
toPeter.AddMessage(SH_NAME_ONSUCCESS,
&toPaul);
// And off we go!
root->PostMessage(&toPeter);
// For extra fun, you could add an SH_NAME_ONSUCCESS
field to Mary, containing a
// BMessage addressed to "/..".
That way you would be notified when the BMessage
// had finished making the rounds.