Overview | Package | Class | Tree | Deprecated | Index | Help
PREV CLASS NEXT CLASS | FRAMES NO FRAMES
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD

## sim.engine
Class Schedule

    java.lang.Object
      sim.engine.Schedule

All Implemented Interfaces:
  java.io.Serializable

public class Schedule
extends java.lang.Object
implements java.io.Serializable

Schedule defines a scheduling queue in which events can be scheduled to occur after some number of "ticks" of a clock which the schedule maintains. The current tick is given by the time() method. If the current tick is `BEFORE_SIMULATION` (0), then the schedule is set to the "time before time" (the schedule hasn't started running yet). If the current tick is `AFTER_SIMULATION` (9218868437227405312), then the schedule has run out of time. `EPOCH` (1) is defined as the first timestep after `BEFORE_SIMULATION` -- it's the first timestep for which you can legally schedule a value.

An event is defined as a Steppable object. You can schedule events to either occur a single time or to occur repeatedly at some interval. If the event occurs repeatedly, the schedule will provide you with a Stoppable object on which you can call stop() to cancel all future repeats of the event.

The schedule is pulsed by calling its step(...) method. Each pulse, the schedule finds the next tick in which events are scheduled, moves ahead to that tick, and then calls all the events scheduled at that tick. Multiple events may be scheduled for the same clock tick. Events at a tick are further subdivided and scheduled according to their ordering. You specify the number of orderings in the constructor, and can't change them thereafter. If you specify N orderings, then the ordering values are 0 ... N-1. Objects for scheduled for lower orderings in a given time tick will be executed before objects with higher orderings for the same time tick. If objects are scheduled for the same time tick and have the same ordering value, their execution will be randomly ordered with respect to one another.

You may not schedule events to occur on or before `BEFORE_SIMULATION` (tick 0). Likewise, you may not schedule events to occur on or after `AFTER_SIMULATION` (tick 9218868437227405312). This gives you 9,218,868,437,227,405,311 timesteps to play with; we hope that's sufficient resolution for your simulation.

Schedule is synchronized and threadsafe. It's easy enough to de-synchronize the schedule by hand if you would like to. In the worst case (schedule a single repeated steppable that does nothing), a synchronized schedule runs at 2/3 the speed of an unsynchronized schedule. In a typical case (such as HeatBugs), the difference between a synchronized and an unsynchronized schedule is less than 5% efficiency loss if it's visible at all.

You can get the number of times that step(...) has been called on the schedule by calling the getSteps() method. This value is incremented just as the Schedule exits its step(...) method and only if the method returned true. Additionally, you can get a string version of the current time with the getTimestamp(...) method.

### Using a Real-Valued Schedule

Schedule also has rudimentary facilities for use in pseudo-"real-valued" timesteps rather than discrete ones. This means that you can submit and receive time values as doubles rather than as longs. In this case, BEFORE_SIMULATION = 0.0 and AFTER_SIMULATION = +infinity. You schedule values in "real time" by converting your desired double-valued "times" to and from long ticks using toReals(...) and fromReals(...). These will come up with equivalent long values for your double such that if d1 < d2, then fromReals(d1) < fromReals(d2). Understand that this is not a cast: for example, fromReals(9.0) == 4621256167635550208. Your only guarantee is that if you convert your timestamps toReals() and fromReals(), they'll be ordered in the same way that your real-valued "desired" timestamps are ordered. Also note that NaN will always be an invalid timestamp.

You have to be careful using a real-valued schedule. Notably, you should not use any variant of scheduleRepeating(...) as they will not work correctly. To schedule events to occur repeatedly, the events will have to reschedule themselves. Further, take care to note that real values lose resolution as time goes by. Thus while you can distinguish between 0.000001 and 0.000002, you cannot distinguish between C+0.000001 and C+0.000002, where C is some large constant. This mostly will bite you if you schedule for a real-valued event at time T+1.0, but it turns out that T+1.0 rounds to T (the current time) in the schedule. In this case the event will not be scheduled. So be careful to check to make certain that your schedule(...) calls always return true.

See Also:
  Serialized Form

Field Summary
`static long` | `AFTER_SIMULATION`
`static long` | `BEFORE_SIMULATION`
`static long` | `EPOCH`
`protected Steppable[][]` | `next`
`protected int[]` | `numNext`
`protected int[]` | `numSubsteps`
`protected Heap[]` | `queue`
`protected long` | `steps`
`protected Steppable[][]` | `substeps`
`protected long` | `time`

Constructor Summary
`Schedule()` Creates a Schedule with a single order
`Schedule(int numOrders)`

Method Summary
`protected boolean` | `_scheduleComplete()`
`long` | `fromReals(double time)` Converts the reals "time" value into a long tick value -- this is NOT a cast.
`long` | `getSteps()`
`java.lang.String` | `getTimestamp(java.lang.String beforeSimulationString, java.lang.String afterSimulationString)` Returns the current time in string format.
`protected Steppable[]` | `increaseSubsteps(Steppable[] substeps)`
`protected Steppable[]` | `increaseSubsteps(Steppable[] substeps, int n)`
`void` | `reset()` Empties out the schedule and resets it to a pristine state BEFORE_SIMULATION, with steps = 0.
`protected void` | `resetQueues(int numOrders)`
`boolean` | `scheduleComplete()` Returns true if the schedule has nothing left to do.
`boolean` | `scheduleOnce(long time, int ordering, Steppable event)` If the current time is less than the time requested, and the event is valid, schedules the event to occur at the requested time, placed in the 'first' queue, and returns TRUE.
`boolean` | `scheduleOnce(long time, Steppable event)` If the current time is less than the time requested, 0 ordering, and the event is valid, schedules the event to occur at the requested time and returns TRUE.
`boolean` | `scheduleOnce(Steppable event)` Schedules the event to occur at the next clock tick, 0 ordering.
`Stoppable` | `scheduleRepeating(long time, int ordering, Steppable event)` If the event is valid, and the current time is less than time, schedules the event to occur once every clock tick starting at time, with the given ordering, and returns TRUE, else returns FALSE.
`Stoppable` | `scheduleRepeating(long time, int ordering, Steppable event, long interval)` If the event is valid, and the current time is less than time, schedules the event to occur once every interval's worth of clock ticks starting at time, with the given ordering, and returns TRUE, else returns FALSE.
`Stoppable` | `scheduleRepeating(long time, Steppable event)` If the event is valid, and the current time is less than time, schedules the event to occur once every clock tick starting at time, 0 ordering, and returns TRUE, else returns FALSE.
`Stoppable` | `scheduleRepeating(long time, Steppable event, long interval)` If the event is valid, and the current time is less than time, schedules the event to occur once every interval's worth of clock ticks starting at time, 0 ordering, and returns TRUE, else returns FALSE.
`Stoppable` | `scheduleRepeating(Steppable event)` If the event is valid, and the current time is valid, schedules the event to occur once every clock tick starting at the next clock tick, 0 ordering, and returns TRUE, else returns FALSE.
`Stoppable` | `scheduleRepeating(Steppable event, long interval)` If the event is valid, and the current time is valid, schedules the event to occur once every interval's worth of clock ticks starting at the next clock tick, 0 ordering, and returns TRUE, else returns FALSE.
`boolean` | `step(SimState state)` Steps the schedule, gathering and ordering all the items to step on the next time step (skipping blank time steps), and then stepping all of them in the decided order.
`long` | `time()`
`double` | `toReals(long time)` Converts the long tick value into a reals "time" value (as a double) -- this is NOT a cast.

Methods inherited from class java.lang.Object
`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

Field Detail

### BEFORE_SIMULATION

    public static final long BEFORE_SIMULATION

See Also:
  Constant Field Values

### EPOCH

    public static final long EPOCH

See Also:
  Constant Field Values

### AFTER_SIMULATION

    public static final long AFTER_SIMULATION

See Also:
  Constant Field Values

### queue

    protected Heap[] queue

### next

    protected Steppable[][] next

### numNext

    protected int[] numNext

### substeps

    protected Steppable[][] substeps

### numSubsteps

    protected int[] numSubsteps

### time

    protected long time

### steps

    protected long steps

Constructor Detail

### Schedule

    public Schedule(int numOrders)

### Schedule

    public Schedule()

  Creates a Schedule with a single order

Method Detail

### resetQueues

    protected void resetQueues(int numOrders)

### time

    public long time()

### getTimestamp

    public java.lang.String getTimestamp(java.lang.String beforeSimulationString,
                                         java.lang.String afterSimulationString)

  Returns the current time in string format. If the time is BEFORE_SIMULATION, then beforeSimulationString is returned. If the time is AFTER_SIMULATION, then afterSimulationString is returned. Otherwise a numerical representation of the time is returned.

### getSteps

    public long getSteps()

### toReals

    public final double toReals(long time)

  Converts the long tick value into a reals "time" value (as a double) -- this is NOT a cast. If you use doubles, you should ONLY use doubles -- do not mix them with longs. See the warning in the class documentation. We can just convert bits to bits because the half-open long range (0 ... 9218868437227405312L] is equivalent to the half-open double range (0 ... +infinity]. NaN values exist outside this range, so they're not a problem.

### fromReals

    public final long fromReals(double time)

  Converts the reals "time" value into a long tick value -- this is NOT a cast. If you use doubles, you should ONLY use doubles -- do not mix them with longs. See the warning in the class documentation. We can just convert bits to bits because the half-open long range (0 ... 9218868437227405312L] is equivalent to the half-open double range (0 ... +infinity]. NaN values exist outside this range, so they're not a problem.

### increaseSubsteps

    protected Steppable[] increaseSubsteps(Steppable[] substeps)

### increaseSubsteps

    protected Steppable[] increaseSubsteps(Steppable[] substeps,
                                           int n)

### reset

    public void reset()

  Empties out the schedule and resets it to a pristine state BEFORE_SIMULATION, with steps = 0.

### scheduleComplete

    public boolean scheduleComplete()

  Returns true if the schedule has nothing left to do.

### _scheduleComplete

    protected boolean _scheduleComplete()

### step

    public boolean step(SimState state)

  Steps the schedule, gathering and ordering all the items to step on the next time step (skipping blank time steps), and then stepping all of them in the decided order. Returns FALSE if nothing was stepped -- the schedule is exhausted or time has run out.

### scheduleOnce

    public final boolean scheduleOnce(Steppable event)

  Schedules the event to occur at the next clock tick, 0 ordering. If this is a valid time and event, schedules the event and returns TRUE, else returns FALSE.

### scheduleOnce

    public final boolean scheduleOnce(long time,
                                      Steppable event)

  If the current time is less than the time requested, 0 ordering, and the event is valid, schedules the event to occur at the requested time and returns TRUE. Else returns FALSE.

### scheduleOnce

    public boolean scheduleOnce(long time,
                                int ordering,
                                Steppable event)

  If the current time is less than the time requested, and the event is valid, schedules the event to occur at the requested time, placed in the 'first' queue, and returns TRUE. Else returns FALSE.

### scheduleRepeating

    public final Stoppable scheduleRepeating(Steppable event)

  If the event is valid, and the current time is valid, schedules the event to occur once every clock tick starting at the next clock tick, 0 ordering, and returns TRUE, else returns FALSE. Returns a Stoppable which you can use to stop the repeated scheduling from occuring any more.

  Note that calling stop() on the Stoppable will not only stop the repeating, but will also make the Schedule completely forget (lose the pointer to) the Steppable scheduled here. This is particularly useful if you need to make the Schedule NOT serialize certain Steppable objects. Do not use this with a real-valued schedule.

### scheduleRepeating

    public final Stoppable scheduleRepeating(Steppable event,
                                             long interval)

  If the event is valid, and the current time is valid, schedules the event to occur once every interval's worth of clock ticks starting at the next clock tick, 0 ordering, and returns TRUE, else returns FALSE. Returns a Stoppable which you can use to stop the repeated scheduling from occuring any more.

  Note that calling stop() on the Stoppable will not only stop the repeating, but will also make the Schedule completely forget (lose the pointer to) the Steppable scheduled here. This is particularly useful if you need to make the Schedule NOT serialize certain Steppable objects. Do not use this with a real-valued schedule.

### scheduleRepeating

    public final Stoppable scheduleRepeating(long time,
                                             Steppable event)

  If the event is valid, and the current time is less than time, schedules the event to occur once every clock tick starting at time, 0 ordering, and returns TRUE, else returns FALSE. Returns a Stoppable which you can use to stop the repeated scheduling from occuring any more.

  Note that calling stop() on the Stoppable will not only stop the repeating, but will also make the Schedule completely forget (lose the pointer to) the Steppable scheduled here. This is particularly useful if you need to make the Schedule NOT serialize certain Steppable objects. Do not use this with a real-valued schedule.

### scheduleRepeating

    public final Stoppable scheduleRepeating(long time,
                                             Steppable event,
                                             long interval)

  If the event is valid, and the current time is less than time, schedules the event to occur once every interval's worth of clock ticks starting at time, 0 ordering, and returns TRUE, else returns FALSE. Returns a Stoppable which you can use to stop the repeated scheduling from occuring any more.

  Note that calling stop() on the Stoppable will not only stop the repeating, but will also make the Schedule completely forget (lose the pointer to) the Steppable scheduled here. This is particularly useful if you need to make the Schedule NOT serialize certain Steppable objects. Do not use this with a real-valued schedule.

### scheduleRepeating

    public Stoppable scheduleRepeating(long time,
                                       int ordering,
                                       Steppable event)

  If the event is valid, and the current time is less than time, schedules the event to occur once every clock tick starting at time, with the given ordering, and returns TRUE, else returns FALSE. Returns a Stoppable which you can use to stop the repeated scheduling from occuring any more.

  Note that calling stop() on the Stoppable will not only stop the repeating, but will also make the Schedule completely forget (lose the pointer to) the Steppable scheduled here. This is particularly useful if you need to make the Schedule NOT serialize certain Steppable objects. Do not use this with a real-valued schedule.

### scheduleRepeating

    public Stoppable scheduleRepeating(long time,
                                       int ordering,
                                       Steppable event,
                                       long interval)

  If the event is valid, and the current time is less than time, schedules the event to occur once every interval's worth of clock ticks starting at time, with the given ordering, and returns TRUE, else returns FALSE. Returns a Stoppable which you can use to stop the repeated scheduling from occuring any more.

  Note that calling stop() on the Stoppable will not only stop the repeating, but will also make the Schedule completely forget (lose the pointer to) the Steppable scheduled here. This is particularly useful if you need to make the Schedule NOT serialize certain Steppable objects. Do not use this with a real-valued schedule.

Overview | Package | Class | Tree | Deprecated | Index | Help
PREV CLASS NEXT CLASS | FRAMES NO FRAMES
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD