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 }