1
2
3
4
5
6
7
8
9
10
11
12
13 package org.gscg.common;
14
15 import java.io.IOException;
16 import java.io.ObjectOutputStream;
17
18 import nl.tudelft.simulation.dsol.formalisms.devs.SimEventInterface;
19 import nl.tudelft.simulation.dsol.simulators.AnimatorInterface;
20 import nl.tudelft.simulation.dsol.simulators.DEVDESSSimulator;
21 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
22 import nl.tudelft.simulation.language.concurrent.WorkerThread;
23 import nl.tudelft.simulation.logger.Logger;
24
25 /***
26 * A GameAnimator is used to synchronize between executing the events of the
27 * event list of the simulator underneath and the ThreadedEventProducers that
28 * are used for communication with remote clients. The event list of a
29 * ThreadedEventProducer must be empty before the animator may advance in time.
30 * <p>
31 * (c) copyright 2005 <a href="http://www.simulation.tudelft.nl">Delft
32 * University of Technology </a>, the Netherlands. <br>
33 * See for project information <a
34 * href="http://www.simulation.tudelft.nl">www.simulation.tudelft.nl </a> <br>
35 *
36 * Copyright (c) 2003-2005 Delft University of Technology, Jaffalaan 5, 2628 BX
37 * Delft, the Netherlands. All rights reserved.
38 *
39 * See for project information <a href="http://www.simulation.tudelft.nl/">
40 * www.simulation.tudelft.nl </a>.
41 *
42 * The source code and binary code of this software are proprietary information
43 * of Delft University of Technology.
44 *
45 * @author <a
46 * href="http://www.tbm.tudelft.nl/webstaf/stijnh/index.htm">Stijn-Pieter
47 * van Houten </a>
48 * @author <a
49 * href="http://www.tbm.tudelft.nl/webstaf/alexandv/index.htm">Alexander
50 * Verbraeck </a>
51 *
52 * @version $Revision: 1.1 $ $Date: 2005/06/16 12:33:54 $
53 * @since 1.1.3
54 */
55 public class GameAnimator extends DEVDESSSimulator implements AnimatorInterface
56 {
57 /*** the serial version uid */
58 private static final long serialVersionUID = 11L;
59
60 /*** the semaphore for the game */
61 public transient Object gameSemaphore = null;
62
63 /*** AnimationDelay refers to the delay in miliseconds between timeSteps */
64 protected long animationDelay = 100L;
65
66 /***
67 * constructs a new GameAnimator
68 */
69 public GameAnimator()
70 {
71 super();
72 this.gameSemaphore = new Object();
73 super.worker.setPriority(Thread.NORM_PRIORITY);
74 }
75
76 /***
77 * @see nl.tudelft.simulation.dsol.simulators.AnimatorInterface
78 * #getAnimationDelay()
79 */
80 public long getAnimationDelay()
81 {
82 return this.animationDelay;
83 }
84
85 /***
86 * @see nl.tudelft.simulation.dsol.simulators.AnimatorInterface
87 * #setAnimationDelay(long)
88 */
89 public void setAnimationDelay(final long animationDelay)
90 {
91 this.animationDelay = animationDelay;
92 Logger.finer(this, "setAnimationDelay", "set the animationDelay to "
93 + animationDelay);
94 this.fireEvent(ANIMATION_DELAY_CHANGED_EVENT, animationDelay);
95 }
96
97 /***
98 * @see nl.tudelft.simulation.dsol.simulators.DEVSSimulator#run()
99 */
100 public void run()
101 {
102 while (this.isRunning()
103 && !this.eventList.isEmpty()
104 && this.simulatorTime <= this.replication.getRunControl()
105 .getRunLength())
106 {
107 try
108 {
109 if (this.animationDelay > 0)
110 {
111 Thread.sleep(this.animationDelay);
112 }
113 } catch (Exception exception)
114 {
115 exception = null;
116
117 }
118 double runUntil = this.simulatorTime + this.timeStep;
119 while (!this.eventList.isEmpty()
120 && this.running
121 && runUntil >= this.eventList.first()
122 .getAbsoluteExecutionTime())
123 {
124 synchronized (this.gameSemaphore)
125 {
126 synchronized (super.semaphore)
127 {
128 SimEventInterface event = this.eventList.removeFirst();
129 this.simulatorTime = event.getAbsoluteExecutionTime();
130 this.fireEvent(SimulatorInterface.TIME_CHANGED_EVENT,
131 this.simulatorTime, this.simulatorTime);
132 try
133 {
134 event.execute();
135 } catch (Exception exception)
136 {
137 Logger.severe(this, "run", exception);
138 }
139 }
140 }
141 }
142 if (this.running)
143 {
144 this.simulatorTime = runUntil;
145 }
146 this.fireEvent(SimulatorInterface.TIME_CHANGED_EVENT,
147 this.simulatorTime, this.simulatorTime);
148 this.fireEvent(AnimatorInterface.UPDATE_ANIMATION_EVENT,
149 this.simulatorTime);
150 }
151 }
152
153 /***
154 * writes a serializable method to stream
155 *
156 * @param out the outputstream
157 * @throws IOException on IOException
158 */
159 private synchronized void writeObject(final ObjectOutputStream out)
160 throws IOException
161 {
162 out.defaultWriteObject();
163 }
164
165 /***
166 * reads a serializable method from stream
167 *
168 * @param in the inputstream
169 * @throws IOException on IOException
170 */
171 private synchronized void readObject(final java.io.ObjectInputStream in)
172 throws IOException
173 {
174 try
175 {
176 in.defaultReadObject();
177
178 this.gameSemaphore = new Object();
179 this.running = false;
180 this.semaphore = new Object();
181 this.worker = new WorkerThread(this.getClass().getName(), this);
182 } catch (Exception exception)
183 {
184 throw new IOException(exception.getMessage());
185 }
186 }
187 }