[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.
Re: Event's Parameters, Olivier Jauze, 2001/07/17