View Javadoc

    1   /*
    2    * @(#)Simulator.java Aug 18, 2003
    3    *
    4    * Copyright (c) 2003 Delft University of Technology Jaffalaan 5, 2628 BX Delft,
    5    * the Netherlands All rights reserved.
    6    *
    7    * This software is proprietary information of Delft University of Technology
    8    * The code is published under the General Public License
    9    */
    10  package nl.tudelft.simulation.dsol.simulators;
    11
    12  import java.rmi.RemoteException;
    13
    14  import nl.tudelft.simulation.dsol.SimRuntimeException;
    15  import nl.tudelft.simulation.dsol.experiment.Replication;
    16  import nl.tudelft.simulation.event.Event;
    17  import nl.tudelft.simulation.event.EventProducer;
    18  import nl.tudelft.simulation.jstats.statistics.StatisticsObject;
    19  import nl.tudelft.simulation.language.concurrent.WorkerThread;
    20  import nl.tudelft.simulation.logger.Logger;
    21
    22  /***
    23   * The Simulator class is an abstract implementation of the SimulatorInterface.
    24   * <p>
    25   * (c) copyright 2003 <a href="http://www.simulation.tudelft.nl">Delft
    26   * University of Technology </a>, the Netherlands. <br>
    27   * See for project information <a href="http://www.simulation.tudelft.nl">
    28   * www.simulation.tudelft.nl </a> <br>
    29   * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
    30   * License (GPL) </a>, no warranty <br>
    31   *
    32   * @author <a href="http://www.simulation.tudelft.nl/people/jacobs.html">Peter
    33   *         Jacobs </a>
    34   * @version 1.13 2004-03-18
    35   * @since 1.0
    36   */
    37  public abstract class Simulator extends EventProducer implements
    38  		SimulatorInterface, Runnable
    39  {
    40
    41  	/***
    42  	 * simulatorTime represents the simulationTime
    43  	 *
    44  	 * @uml.property name="simulatorTime"
    45  	 */
    46  	protected double simulatorTime = Double.NaN;
    47
    48  	/***
    49  	 * running represents the binary state of the simulator
    50  	 *
    51  	 * @uml.property name="running"
    52  	 */
    53  	protected boolean running = false;
    54
    55  	/***
    56  	 * replication represents the currently active replication
    57  	 *
    58  	 * @uml.property name="replication"
    59  	 */
    60  	protected Replication replication = null;
    61
    62
    63  	/*** a worker */
    64  	protected WorkerThread worker = null;
    65
    66  	/*** the simulatorSemaphore */
    67  	protected Object semaphore = new Object();
    68
    69  	/***
    70  	 * constructs a new Simulator
    71  	 */
    72  	public Simulator()
    73  	{
    74  		this.worker = new WorkerThread(this.getClass().getName(), this);
    75  	}
    76
    77  	/***
    78  	 * @see nl.tudelft.simulation.dsol.simulators.SimulatorInterface
    79  	 *      #getSimulatorTime()
    80  	 *
    81  	 * @uml.property name="simulatorTime"
    82  	 */
    83  	public double getSimulatorTime()
    84  	{
    85  		return this.simulatorTime;
    86  	}
    87
    88  	/***
    89  	 * @see nl.tudelft.simulation.dsol.simulators.SimulatorInterface
    90  	 *      #getReplication()
    91  	 *
    92  	 * @uml.property name="replication"
    93  	 */
    94  	public Replication getReplication()
    95  	{
    96  		return this.replication;
    97  	}
    98
    99
    100 	/***
    101 	 * @see nl.tudelft.simulation.dsol.simulators.SimulatorInterface
    102 	 *      #initialize(Replication)
    103 	 */
    104 	public void initialize(final Replication replication)
    105 			throws RemoteException, SimRuntimeException
    106 	{
    107 		if (replication == null)
    108 		{
    109 			throw new IllegalArgumentException("replication == null ?");
    110 		}
    111 		if (this.isRunning())
    112 		{
    113 			throw new SimRuntimeException(
    114 					"Cannot initialize a running simulator");
    115 		}
    116 		synchronized (this.semaphore)
    117 		{
    118 			this.removeAllListeners(StatisticsObject.class);
    119 			this.replication = replication;
    120 			this.simulatorTime = 0.0;
    121 			this.fireEvent(SimulatorInterface.START_REPLICATION_EVENT, null,
    122 					((SimulatorInterface) this).getSimulatorTime());
    123 			this.fireEvent(SimulatorInterface.TIME_CHANGED_EVENT,
    124 					this.simulatorTime, this.simulatorTime);
    125 			Logger.finer(this, "initialize", "OK");
    126 		}
    127 	}
    128
    129 	/***
    130 	 * @see nl.tudelft.simulation.dsol.simulators.SimulatorInterface#isRunning()
    131 	 *
    132 	 * @uml.property name="running"
    133 	 */
    134 	public boolean isRunning()
    135 	{
    136 		return this.running;
    137 	}
    138
    139 	/***
    140 	 * The run method defines the actual time step mechanism of the simulator.
    141 	 * The implementation of this method depends on the formalism. Where
    142 	 * discrete event formalisms loop over an eventlist continuous simulators
    143 	 * take pre-defined time steps.
    144 	 *
    145 	 */
    146 	public abstract void run();
    147
    148 	/***
    149 	 * @see nl.tudelft.simulation.dsol.simulators.SimulatorInterface#start()
    150 	 */
    151 	public void start() throws SimRuntimeException, RemoteException
    152 	{
    153 		if (this.isRunning())
    154 		{
    155 			throw new SimRuntimeException("Cannot start a running simulator");
    156 		}
    157 		if (this.replication == null)
    158 		{
    159 			throw new SimRuntimeException("Cannot start a simulator"
    160 					+ " without replication details");
    161 		}
    162 		if (this.simulatorTime >= this.replication.getRunControl()
    163 				.getRunLength())
    164 		{
    165 			throw new SimRuntimeException("Cannot start simulator : "
    166 					+ "simulatorTime = runLength");
    167 		}
    168 		synchronized (this.semaphore)
    169 		{
    170 			this.running = true;
    171 			this.fireEvent(START_EVENT, null);
    172 			this.fireEvent(SimulatorInterface.TIME_CHANGED_EVENT,
    173 					this.simulatorTime, this.simulatorTime);
    174 			Logger.finer(this, "start", "OK");
    175 			if (!Thread.currentThread().getName().equals(this.worker.getName()))
    176 			{
    177 				this.worker.interrupt();
    178 			} else
    179 			{
    180 				this.run();
    181 			}
    182 		}
    183 	}
    184
    185 	/***
    186 	 * @see nl.tudelft.simulation.dsol.simulators.SimulatorInterface#step()
    187 	 */
    188 	public void step() throws SimRuntimeException
    189 	{
    190 		if (this.isRunning())
    191 		{
    192 			throw new SimRuntimeException("Cannot step a running simulator");
    193 		}
    194 		if (this.replication == null)
    195 		{
    196 			throw new SimRuntimeException("Cannot step a simulator "
    197 					+ "without replication details");
    198 		}
    199 		if (this.simulatorTime >= this.replication.getRunControl()
    200 				.getRunLength())
    201 		{
    202 			throw new SimRuntimeException("Cannot step simulator: "
    203 					+ "SimulatorTime = runControl.runLength");
    204 		}
    205 		Logger.finer(this, "step", "OK");
    206 		this.fireEvent(SimulatorInterface.STEP_EVENT, null);
    207 	}
    208
    209 	/***
    210 	 * @see nl.tudelft.simulation.dsol.simulators.SimulatorInterface#stop()
    211 	 */
    212 	public void stop()
    213 	{
    214 		if (this.isRunning())
    215 		{
    216 			this.running = false;
    217 			Logger.finer(this, "stop", "OK");
    218 			if (this.simulatorTime >= this.getReplication().getRunControl()
    219 					.getRunLength())
    220 			{
    221 				this
    222 						.fireEvent(new Event(
    223 								SimulatorInterface.END_OF_REPLICATION_EVENT,
    224 								this, null));
    225 			}
    226 			this.fireEvent(SimulatorInterface.STOP_EVENT, null);
    227 		}
    228 	}
    229 }