simjava-1.2 Design notes for developers



This document describes the design of version 1.2 of simjava and the companion packages simanim and simdiag.

It is intended for those interested in how the simulation package works. For information on using the packages see the simjava guide and simanim guide and simdiag guide.

Changes version 1.1 -> 1.2

Top level design notes

The initial design aim was to produce a text only discrete event simulation library for java, based on the existing HASE++ library for C++.

The next aim was to produce a package to provide an animation of a design model for minimal effort.

The final aim (for version 1.2 at least) was to produce program modules for displaying results.

These aims were realised in three separate java packages, simjava, simanim and simdiag. simjava may be used independently of the others. simanim depends on and augments simjava, and the javabeans in simdiag are currently driven from simanim, but could be hived off and used independently if required.

Directory structure

The files comprising the simjava-1.2 package are:-
  index.html		-- Top level html file
  makefile		-- Top level makefile
  makefile.config	-- included by all makefiles
  eduni/		-- Source code for packages
    eduni/		-- Packages named eduni/*
  jars/			-- Default location for jars
    simjava.jar		-- Bundles all packages
    README.txt		-- More info on examples
  doc/			-- Reference documents + guides
The packages are named "eduni.simjava" "eduni.simanim" "eduni.simdiag" to avoid name conflicts with other packages.

simjava design notes

The simulation is managed by a central class Sim_system which contains a list of all the Sim_entity objects in the system, an Evqueue to hold future events and one to hold deferred events.

Overview of classes


Manages a simjava simulation. Once initialisation is complete, it enters a run() loop which runs all entities as far as they can go, pops the next event off the future event queue, deals with it (which makes the destination entity concerned runnable), and repeats.

The run() method is implemented as follows:-

  static public void run() {
    while(run_tick()) { }

run_tick() runs a single simulation tick. It sets all runnable entities running, waits for them all to grind to a halt, then pops an event off the future queue.

Sim_system is an entirely static class, so doesn't need to be instantiated to be used.


The class from which all user simulation entities are derived. Its 'body()' method is called at simulation run time. The basic simulation operations (sim_schedule, sim_wait etc) are methods of Sim_entity. These methods make calls to the central Sim_system class which adds or removes corresponding events from its event queues. For example, a call to Sim_hold(123.0) calls Sim_system.hold(myid, 123.0) which is implemented as follows:
  static void hold(int src, double delay) {
    Sim_event e = new Sim_event(Sim_event.HOLD_DONE,clock+delay,src);
This creates a new event (of type HOLD_DONE), with the timestamp of current time + 123.0, adds it to the future event queue, and sets the state of the calling Sim_entity to HOLDING.

Sim_entity.sim_hold() then notifies Sim_system that it's about to stop and waits on its restart semaphore.

The figure below shows the interactions:-

Other Public Classes

Random number and output classes

simanim design notes

The classes making up the simanim package are:
Anim_applet       Anim_param        Param_type_list
Anim_entity       Anim_port         Sim_anim
Anim_event        Param_type
The important classes in the simanim package are Anim_applet and Sim_anim. Anim_entity, Anim_port and Anim_event store animation-specific details for the corresponding simjava classes Sim_entity, Sim_port and Sim_event. Anim_param, Param_type and Param_type_list store displayed parameters and types.
public abstract class Anim_applet extends Applet 
	implements Runnable, ActionListener, 
	AdjustmentListener, Traceable {
  public void anim_init() {}          
  public abstract void anim_layout();
  public final void init() {}

public class Sim_anim extends Canvas 
	implements Sim_output, Traceable {
  public void animate(Thread simThread) {...}
  public void println(String msg) {...}

The user's applet derives from Anim_applet, and provides versions of anim_init to create buttons and anim_layout to build the simulation. Anim_applet's init method creates the panel, creates an instance of Sim_anim, creates the control buttons, and calls the user's anim_init().

Sim_anim's animate() method controls the running of the simulation. The three Sim_system methods used are:-

    running = Sim_system.run_tick();

The standard Sim_system.link_ports() calls the Sim_anim version:-

  public void link_ports(String e1, String p1, String e2, String p2)

As the simulation runs, the interface between the user's simulation code and simanim is through the trace generated.

Where the simulation code calls:

  sim_trace(1, "P BUSY");
This calls:
  Sim_entity.sim_trace(1,"P BUSY");
which calls
  Sim_system.trace(entityid,"P BUSY");
which calls
  Sim_anim.println("u:sender at 1.23 : P BUSY");
which constructs an Anim_event from this, adds it to the events list and forwards the trace to any trace event listeners.

simdiag design notes

simdiag provides a collection of useful classes for displaying timing diagrams and 2D graphs. A JavaBeans style event interface is provided, so graph objects 'listen' to a stream of incoming events and display them as they see fit. This means that graphs can be controlled by any object by wiring the output of that object to the input of the graph. The timing diagram class responds to a stream of TraceEventObjects, and the graph class responds to a stream of GraphEventObjects.

Timing diagrams

The TimingDiagram takes as input a stream of TraceEventObjects and produces a timing diagram. The objects are: An example timing diagram is shown below.

The standard generator of EventObjects is the Sim_anim class, which generates a stream of events from the trace produced by the user's simulation. These may be connected to the input of any number of TimingDiagram objects in order to display the trace as a timing diagram. The trace stream may also be saved to a file using the TraceSaver class.

The figure below shows Sim_anim connected to a TimingDiagram which is in turn connected to a TraceSaver which stores the trace in a file.

These connections were made by calling addTraceListener() from anim_init():

  // Add a timing diagram
  TimingWindow tw = new TimingWindow();
  trace_out.addTraceListener( tw.getDiag() );

  // Add a trace saver
  tw.getDiag().addTraceListener( new TraceSaver("tracefile") );

See the example for all the code. The trace file is split into sections to denote the data types, names of bars to display, and finally the events themselves. An example is shown below:
p[0] State
p[1] State
u:p[0] at 1.234: P IDLE
u:p[1] at 4.567: P BUSY
This declares the type State to have one of the four values listed, says there are to be two bars on the timing diagram (named p[0] and p[1]) both of type State, then lists the timestamped events. The format of the event is

u:entity name at timestamp: P parameter value

2D Graphs

A graph JavaBean is so useful that it ought to be supplied as standard along with the JDK. However it isn't yet, so one is included in the simdiag package. An example is shown below.

The Graph object implements the GraphListener interface in order to update its display:-

public interface GraphListener extends EventListener {
  void handleGraph(GraphEventObject teo);
The GraphEventObjects are:- The Graph beans provided are:- An example shows how a graph may be connected to the results of repeated simulation runs.

Known bugs and problems

Fred Howell -
Department of Computer Science
University of Edinburgh