swarm-support
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Event's Parameters


From: Marcus G. Daniels
Subject: Re: Event's Parameters
Date: 16 Jul 2001 11:49:08 -0600
User-agent: Gnus/5.070084 (Pterodactyl Gnus v0.84) Emacs/20.7

OJ> is it possible to pass parameters when I schedule an event.

Below is an example of an efficient way to handle arguments to Actions.
In particular, see the createCall method.  Here's a deconstruction of
that method:

  1) Create a `Selector' for the desired method.  By creating a
     Selector we are saying "go find me a method with this name".  In
     Objective C a Selector can be associated with any class, but in
     Java it is restricted to one class.  Selectors have restricted
     semantics compared to Java reflection.  Specifically, a Selector
     with some name and argument pattern is not polymorphic.  So, if
     you have two methods both named "step" with one having a double
     argument and another with an integer argument, and you try to
     make a Selector using the name "step", Selector will throw an
     exception you'll have to handle... that's why there's a try/catch
     around this.  If you give Selector a method name that doesn't
     exist you'll get a runtime error.  Java makes you trap these.
     
  2) The pattern of arguments for the call is described.

     To do this, we first create an FArguments instance using this idiom:
     
        FArgumentsC creating = new FArgumentsCImpl (new FArgumentsImpl ());
  
     [FArguments stands for "foreign arguments".  The idea is that using
     FArguments + FCall, Swarm can make calls to any sort of runtime 
     system.  Right now, Swarm has support for C, Objective C, and Java.
     It also has support for JavaScript, Python, and C++ by virtue of 
     the XPCOM.]

     Swarm interfaces have two `phases'.  The initial phase is
     Creating phase.  (That's the meaning of "C".)  Objects in
     Creating phase are awaiting methods that describe their
     structural, permanent characteristics.  For example, an array has
     a capacity.  In this case we have a call that will have a fixed
     argument pattern.  This idiom is connecting the initial Creating
     phase with the Using phase where the call will actually be used.
     The Creating phase takes the Using phase as an argument, and
     later uses this pointer to `jump' to the next phase when the time
     comes; when createEnd is called.

  3) Next, the Creating phase for the object is allocated. 
     (e.g. a caterpillar is born.)

        creating.createBegin (getZone ());

     All objects in Swarm live in a region, a Zone.

  4) In order to call a function or method correctly, the computer
     needs to know what the input and outputs are.  We can get this
     information from the Selector we made in step #1.  Although
     addDouble implies that the first argument will be a double, the
     first call sets up information that enforces that.  In addition,
     setSelector sets the return type (void), and sets information in
     the FArguments object that says what language environment will be
     destined.  (That's important in order to make the call in the
     right way and to correctly handle object lookups and type
     conversions.)

        creating.setSelector (sel);
        creating.addDouble (2.5);

  5) FArguments provides most of the information needed to make the
     call, and here we provide the additional fact of what target we
     want call ("this") by assembling a FCall instance from the FArguments
     object.

        return new FCallImpl (getZone (), this, sel,
                              (FArguments) creating.createEnd ());

     The createEnd makes the FArgumentsC class swtich to Using phase.
     (e.g. the caterpillar turns into a butterfly)

Finally, the returned object is scheduled like this:

        schedule = new ScheduleImpl (this, 1); 
        [..]
        schedule.at$createFAction (0, createCall ());

The result of all this is that "stepArg" gets called every time step
with an argument of 2.5.  

Earlier I said this was efficient.  The reason it is efficient is
because the call is laid-out in memory once (in step #5), and its
invocation cost is like a function call.  Now, if you want to _change_
the argument that is passed, you have two options:

   1) pass an object as an argument to the called method (or have some other
      reference available to the method), and ask for the new value inside
      the called method

or 2) recreate the call every time, e.g. keep making one-shot (dynamic),
      createFAction calls where there is an argument passed to createCall 
      (e.g. which would be passed down to the addDouble or addWhatever).
      

import swarm.objectbase.SwarmImpl;
import swarm.defobj.Zone;
import swarm.activity.Schedule;
import swarm.activity.ScheduleImpl;
import swarm.objectbase.Swarm;
import swarm.activity.Activity;
import swarm.defobj.FCallImpl;
import swarm.defobj.FCall;
import swarm.defobj.FArgumentsImpl;
import swarm.defobj.FArgumentsCImpl;
import swarm.defobj.FArguments;
import swarm.defobj.FArgumentsC;
import swarm.Selector;
import swarm.Globals;

public class TestFActionArgs extends SwarmImpl {
  TestFActionArgs (Zone aZone) {
    super (aZone);
  }
  Schedule schedule;
  Schedule stopSchedule;

  public void stepArg (float val) {
    System.out.println ("next @ " + Globals.env.getCurrentTime () + 
                        " val: " + val);
  }

  public void end () {
    getActivity ().terminate ();
  }
  
  FCall createCall () {
    try {
        Selector sel = new Selector (getClass (), "stepArg", false);
        FArgumentsC creating = new FArgumentsCImpl (new FArgumentsImpl ());
        
        creating.createBegin (getZone ());
        creating.setSelector (sel);
        creating.addDouble (2.5);
        return new FCallImpl (getZone (), this, sel,
                              (FArguments) creating.createEnd ());
    } catch (Exception e) {
        e.printStackTrace (System.err);
    }
    return null;
  }

  FCall createStopCall () {
    try {
      Selector sel = new Selector (getClass (), "end", false);
      return new FCallImpl (getZone (), this, sel,
                            new FArgumentsImpl (getZone (), sel));
    } catch (Exception e) {
      e.printStackTrace (System.err);
    }
    return null;
  }

  public Object buildActions () {
    super.buildActions ();
    
    schedule = new ScheduleImpl (this, 1);
    stopSchedule = new ScheduleImpl (this, true);
    schedule.at$createFAction (0, createCall ());
    stopSchedule.at$createFAction (10, createStopCall ());
    return this;
  }

  public Activity activateIn (Swarm swarmContext) {
    super.activateIn (swarmContext);

    schedule.activateIn (this);
    stopSchedule.activateIn (this);
    return getActivity ();
  }
  

  static void main (String[] args) {
    Globals.env.initSwarm ("TestFActionArgs", "0.0", "address@hidden",
                           args);
    
    TestFActionArgs swarm = new TestFActionArgs (Globals.env.globalZone);

    swarm.buildObjects ();
    swarm.buildActions ();
    swarm.activateIn (null).run ();
  }
}


                  ==================================
   Swarm-Support is for discussion of the technical details of the day
   to day usage of Swarm.  For list administration needs (esp.
   [un]subscribing), please send a message to <address@hidden>
   with "help" in the body of the message.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]