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.