newton
Class Callback

java.lang.Object
  |
  +--newton.Callback

public abstract class Callback
extends Object

A Callback is a class which makes it easy to wrap a Java method appear as a NewtonScript function. Most commonly this is used to make callback functions -- for example, protoTextButton's ButtonClickScript, or an Endpoint's callback function when data has arrived.

The method you'll wrap is Ref call(Ref[] args), which gets passed its arguments as an array of Refs, and returns a Ref as the return value back to NewtonScript. You need to create a callback which subclasses from the Callback class, and implement this method. The simplest way to do this is with a Java anonymous class. Here's an example template for you. The call() method will be called when NewtonScript calls the callback function.

Callback mycallback = new Callback()
    {
    public Ref call(Ref[] args)
        {
        // if this is a one-shot callback, I should remove myself from
        // the mailbox here.  Otherwise if the callback will be called
        // several times, then you'll need
        // to remember to remove the callback sometime in the future.
        // If the callback is to be called repeatedly for the life of
        // the application, you don't even need to bother with this;
        // when the app quits, the callback will be removed.
        remove();

        // do your stuff here.

        // Lastly, you need to return the return value of the callback.
        // To return nil, you could simply do:
        return new Ref();
        }
    };

Next you need to generate the NewtonScript wrapper callback function, telling it how many args to have. You also need to register the callback in the mailbox. Let's say you have 4 arguments in your callback function. Then you'd say:

Ref myfunc = mycallback.func(4);  // registered.  myfunc is the NS wrapper function.

Now you can pass in myfunc as a Ref representing a 4-argument function. If you didn't remove your callback from the mailbox by calling remove() during your call() code, you should remember to remove it later. You can keep the callback in the mailbox as long as you like -- and it will continue to get called every time NewtonScript tries to call it. If you remove it from the mailbox, it will cease to be called (though NewtonScript may continue to try unless you've told it to stop!!)

Do NOT make a callback with more than 10 arguments -- Waba will limit it to 10.

Also, beware of recursion! Within your call() code, you cannot call a function which will recursively call you back again, unless you have made a copy of your args first (they'll get overwritten).


Constructor Summary
Callback()
          Makes a callback function of 0 arguments
 
Method Summary
abstract  Ref call(Ref[] args)
          Called when a callback function hits this mailbox.
 void clearAll()
          Removes all callbacks from the mailbox.
 Ref func(int numArgs)
          Creates an NS function, if not already done, and registers the callback in the mailbox, if not already done.
 void remove()
          Removes the callback from the mailbox if it's there.
static Ref sendInherited(String functionName, Ref frame, Ref[] args)
          Calls an inherited version of the function functionName in the frame frame, passing it the arguments in the array args, bypassing any declared version of the function directly stored in a slot in frame.
 
Methods inherited from class java.lang.Object
equals, hashCode, toString
 

Constructor Detail

Callback

public Callback()
Makes a callback function of 0 arguments
Method Detail

func

public Ref func(int numArgs)
Creates an NS function, if not already done, and registers the callback in the mailbox, if not already done. If the mailbox has been cleared, or the function was removed from the mailbox, then func(args) will add the function back into the mailbox. Once you have called func(args), the number of arguments is immutable -- you cannot call it again with a different number of arguments. If numArgs is > 10, the number of arguments will be set to 10 and no more. If numArgs is < 0, the number of arguments will be set to 0 and no fewer.

remove

public void remove()
Removes the callback from the mailbox if it's there. It will no longer be able to receive messages if it's removed!

clearAll

public void clearAll()
Removes all callbacks from the mailbox.

call

public abstract Ref call(Ref[] args)
Called when a callback function hits this mailbox. You should return a Ref as the return value of the NS function call.

sendInherited

public static final Ref sendInherited(String functionName,
                                      Ref frame,
                                      Ref[] args)
Calls an inherited version of the function functionName in the frame frame, passing it the arguments in the array args, bypassing any declared version of the function directly stored in a slot in frame. This is done by searching the _proto inheritance chain for the first implementation of a function of this name, then removing it, then sending the message, then restoring the function If there was no first implementation at all, this method returns null, else it returns the return value of the inherited function. If a NewtonScript exception is raised by this call, then the symbol form of the exception will be returned instead of the expected return value. One possible reason for an exception to be raised is if there actually isn't any inherited version of the function. This isn't a particularly efficient procedure -- do it only if you have to. As you might guess, this will only work on writable frames; you can't remove a slot from a read-only frame, even temporarily. args may be null -- this is considered to be an empty argument array.

This method is found in Callback because it is likely to be used almost solely by Callback functions. Let's say you're making a protoPopupButton (a button which pops up a list). The Callback you're implementing is PickActionScript(index), which gets called when item #index in the list is chosen by the user. The documentation says that you are required to call inherited:?PickActionScript(index) within the body of your NewtonScript code implementing PickActionScript. But you don't have NewtonScript code. How do you do it? In a way something like this:

// assume an instance member variable called button is already declared...
template = NS.frameWithProto("protoPopupButton");
template.setSlot("PickActionScript",
    new Callback()
        {
        public Ref call(Ref[] args)
            {
            Ref gotback = Callback.sendInherited("PickActionScript",button,args);
            // ... do your PickActionScript stuff here, maybe using gotback
            }
        }.func(1));
// create the button from the template.  In this example we will do so by
// adding it as a stepview to our Waba window.
button = Ref.call("AddStepView", NS.object(NS.WINDOW), template);