Events Step by Step

Model Implementation (2)

The Truck Generator Event

   
 

Next we have to implement the events to finally define our model's behaviour. Let's start with the easiest one, the truck generator event. It just (i) generates a new truck, (ii) schedules a new truck arrival event for that truck, and (iii) determines the next arrival time and schedules itself again for this point in time. Refer to the conceptual model if you need to look up the details of its event routine again.

First of all, derive a class named TruckGeneratorEvent from ExternalEvent. As our truck does not yet exist, there is no entity the event has to refer to, which yield ExternalEvent the appropriate choice for this event: All other subclasses of ExternalEvent assume one more entities referred to. Don't forget to import the desmoj.core.simulator package. Add the constructor, which is equally straightforward as the one in our model class since it only passes all parameters to the constructor of the superclass.

import desmoj.core.simulator.*;
/**
 * This class represents an entity (and event) source, which continually generates
 * trucks (and their arrival events) in order to keep the simulation running.
 *
 * It will create a new truck, schedule its arrival at the terminal (i.e. create
 * and schedule an arrival event) and then schedule itself for the point in
 * time when the next truck arrival is due.
 */
public class TruckGeneratorEvent extends ExternalEvent {

   /**
    * Constructs a new TruckGeneratorEvent.
    *
    * @param owner the model this event belongs to
    * @param name this event's name
    * @param showInTrace flag to indicate if this event shall produce output
    *                    for the trace
    */
   public TruckGeneratorEvent(Model owner, String name, boolean showInTrace) {
      super(owner, name, showInTrace);
   }

   ...

}

Now all left to do is actually define what happens at the truck generator event, i.e. implement its eventRoutine() method.

   /**
    * The eventRoutine() describes the generating of a new truck.
    *
    * It creates a new truck, a new TruckArrivalEvent
    * and schedules itself again for the next new truck generation.
    */
   public void eventRoutine() {

      // get a reference to the model
      EventsExample model = (EventsExample)getModel();

      // create a new truck
      Truck truck = new Truck(model, "Truck", true);
      // create a new truck arrival event
      TruckArrivalEvent truckArrival = new TruckArrivalEvent(model,
                                              "TruckArrivalEvent", true);
      // and schedule it for the current point in time
      truckArrival.schedule(truck, new TimeSpan(0, TimeUnit.MINUTES));

      // schedule this truck generator again for the next truck arrival time
      schedule(new TimeSpan(model.getTruckArrivalTime(), TimeUnit.MINUTES));
      // from inside to outside...
      // draw a new inter-arrival time value
      // wrap it in a TimeSpan object
      // and schedule this event for the current point in time + the
      // inter-arrival time

   }

The actions performed are:

  1. Instantiate a new truck object by calling the constructor of our own Truck entity class.
  2. Instantiate a new truck arrival event object by calling the constructor of our own TruckArrivalEvent class (we will implement this later) ...
  3. and schedule it for the current point in time.
  4. Wait for the next truck to arrive by drawing a sample from the random number stream modelling inter-arrival times and scheduling the truck generator event for this time.

One detail remains to be explained: What is the purpose of the first statement inside the eventRoutine() method? The answer is simple: It's there to provide us with a convenient reference to the model so that we can access its static model components. In this case, we need to draw a sample from the truck arrival time distribution by calling the getTruckArrival() method of our model. To be able to do so, we need a reference to the model object. DESMO-J provides the getModel() method as a member of the ModelComponent class for this aim. All subclasses of ModelComponent like Event or Entity inherit this method. The problem we run into when using the method is that it returns an object of type Model while we need an object of the more specialised type EventsExample. Thus we are forced to perform a type cast, resulting in rather awkward code. For example, the schedule() statement for the truck generator event in the above event routine would look like this:

schedule(new TimeSpan(((EventsExample)getModel()).getTruckArrivalTime(), TimeUnit.MINUTES));

This is rather cumbersome to type, especially if we have to access model components more than once during an event routine, and doesn't make the code easy to read. So calling getModel() and performing the requested type cast once at the beginning of the eventRoutine() method provides for a good shortcut. Alternatively, you may add a field to the event class and assign it the associated model inside the constructor. We will use this approach in the two remaining classes.



   
  http://desmoj.sourceforge.net/tutorial/events/impl21.html