View Javadoc

    1   /*
    2    * @(#) RealTimeClock.java Sep 6, 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
    11  package nl.tudelft.simulation.dsol.simulators;
    12
    13  import nl.tudelft.simulation.dsol.formalisms.devs.SimEventInterface;
    14  import nl.tudelft.simulation.event.EventType;
    15  import nl.tudelft.simulation.logger.Logger;
    16
    17  /***
    18   * The reference implementation of the realTimeClock. The realTime clock is a
    19   * DEVDESS simulator which runs at a ratio of realTime. If the executionTime
    20   * exceeds the timeStep, a catchup mechanism is triggered to make up lost time
    21   * in consecutive steps.
    22   * <p>
    23   * (c) copyright 2004 <a href="http://www.simulation.tudelft.nl">Delft
    24   * University of Technology </a>, the Netherlands. <br>
    25   * See for project information <a
    26   * href="http://www.simulation.tudelft.nl">www.simulation.tudelft.nl </a> <br>
    27   * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
    28   * License (GPL) </a>, no warranty <br>
    29   *
    30   * @author <a href="http://www.tbm.tudelft.nl/webstaf/peterja/index.htm">Peter
    31   *         Jacobs </a>
    32   * @version 1.1 Apr 13, 2004
    33   * @since 1.4
    34   */
    35  public class RealTimeClock extends Animator implements
    36  		DEVDESSSimulatorInterface
    37  {
    38  	/*** the backlog event */
    39  	public static final EventType BACKLOG_EVENT = new EventType("BACKLOG_EVENT");
    40
    41  	/*** the backLog of the clock */
    42  	private long backlog = 0L;
    43
    44  	/*** the starttime of the clock */
    45  	private long startTime = 0L;
    46
    47  	/***
    48  	 * constructs a new RealTimeClock
    49  	 */
    50  	public RealTimeClock()
    51  	{
    52  		super();
    53  	}
    54
    55  	/***
    56  	 * @see nl.tudelft.simulation.dsol.simulators.DEVSSimulator#run()
    57  	 */
    58  	public void run()
    59  	{
    60  		super.worker.setPriority(Thread.MAX_PRIORITY);
    61  		this.startTime = System.currentTimeMillis();
    62  		int count = 0;
    63  		long animationFactor = Math.round(this.animationDelay / this.timeStep);
    64  		while (this.isRunning()
    65  				&& !this.eventList.isEmpty()
    66  				&& this.simulatorTime <= this.replication.getRunControl()
    67  						.getRunLength())
    68  		{
    69  			long now = System.currentTimeMillis();
    70  			double runUntil = (now - this.startTime) + this.timeStep;
    71  			while (!this.eventList.isEmpty()
    72  					&& this.running
    73  					&& runUntil >= this.eventList.first()
    74  							.getAbsoluteExecutionTime())
    75  			{
    76  				synchronized (super.semaphore)
    77  				{
    78  					SimEventInterface event = this.eventList.removeFirst();
    79  					this.simulatorTime = event.getAbsoluteExecutionTime();
    80  					try
    81  					{
    82  						event.execute();
    83  					} catch (Exception exception)
    84  					{
    85  						Logger.severe(this, "run", exception);
    86  					}
    87  				}
    88  			}
    89  			if (this.running)
    90  			{
    91  				this.simulatorTime = runUntil;
    92  			}
    93  			this.fireEvent(SimulatorInterface.TIME_CHANGED_EVENT,
    94  					this.simulatorTime, this.simulatorTime);
    95  			if ((count % animationFactor) == 0)
    96  			{
    97  				this.fireEvent(AnimatorInterface.UPDATE_ANIMATION_EVENT,
    98  						this.simulatorTime, this.simulatorTime);
    99  			}
    100 			count++;
    101 			try
    102 			{
    103 				long used = System.currentTimeMillis() - now;
    104 				long delay = Math.round(this.timeStep - used);
    105 				if (delay >= 0)
    106 				{
    107 					long catchUp = Math.min(this.backlog, delay);
    108 					this.backlog = this.backlog - catchUp;
    109 					super.fireEvent(BACKLOG_EVENT, (-delay + catchUp));
    110 					Thread.sleep(delay - catchUp);
    111 				} else
    112 				{
    113 					this.backlog = this.backlog + (-1 * delay);
    114 					super.fireEvent(BACKLOG_EVENT, -1 * delay);
    115 				}
    116 			} catch (InterruptedException interruptedException)
    117 			{
    118 				//Nothing to be done.
    119 				interruptedException = null;
    120 			}
    121 		}
    122 	}
    123
    124 	/***
    125 	 * @see nl.tudelft.simulation.dsol.simulators.AnimatorInterface
    126 	 *      #getAnimationDelay()
    127 	 */
    128 	public long getAnimationDelay()
    129 	{
    130 		return this.animationDelay;
    131 	}
    132
    133 	/***
    134 	 * @see nl.tudelft.simulation.dsol.simulators.AnimatorInterface
    135 	 *      #setAnimationDelay(long)
    136 	 */
    137 	public void setAnimationDelay(final long animationDelay)
    138 	{
    139 		if (animationDelay < this.timeStep)
    140 		{
    141 			Logger
    142 					.warning(this, "setAnimationDelay",
    143 							"Be careful: it does not seem wise to have an animationdelay<timeStep");
    144 		}
    145 		this.animationDelay = animationDelay;
    146 	}
    147 }