source: tmcsimulator-scriptbuilder/trunk/src/scriptbuilder/structures/TimeSlice.java @ 142

Revision 142, 8.9 KB checked in by bmcguffin, 8 years ago (diff)

Band-aid fix for defect #68. CadData? object in TimeSlice? is now initialized in constructor.

Line 
1package scriptbuilder.structures;
2
3import java.text.SimpleDateFormat;
4import java.util.ArrayList;
5import java.util.Collections;
6import java.util.Date;
7import java.util.List;
8import java.util.TimeZone;
9import scriptbuilder.gui.ScriptBuilderGuiConstants;
10import scriptbuilder.structures.events.*;
11import scriptbuilder.structures.events.I_ScriptEvent;
12
13/**
14 * An instance in time in the simulation. Each timeslice has a start time, an X
15 * position on the GUI timeline, and a list of ScriptEvents which occur at that
16 * time.
17 *
18 * @author Greg Eddington <geddingt@calpoly.edu>
19 * @author Bryan McGuffin
20 * @version 2017/06/30
21 */
22public class TimeSlice implements Comparable, I_XML_Writable
23{
24
25    /**
26     * Cad data object for this timeslice. Can be overwritten by call from
27     * parent incident.
28     */
29    CadData cadData = null;
30
31    /**
32     * Reference to the incident which contains this timeslice.
33     */
34    private ScriptIncident thisIncident;
35
36    /**
37     * List of Script Events which begin at this instance.
38     */
39    public List<I_ScriptEvent> events;
40    //Absolute start time of this time slice
41    private int seconds;
42
43    /**
44     * Constructor.
45     *
46     * @param seconds Number of seconds from the beginning of the simulation
47     * that this timeslice occurs
48     * @param inc the incident to which this timeslice belongs.
49     */
50    public TimeSlice(int seconds, ScriptIncident inc)
51    {
52        this.seconds = seconds;
53        events = new ArrayList<I_ScriptEvent>();
54        thisIncident = inc;
55        cadData = new CadData();
56    }
57
58    /**
59     * Add a new script event to this time slice. Sort events by event type.
60     *
61     * @param event the ScriptEvent to be added
62     */
63    public void addEvent(I_ScriptEvent event)
64    {
65        event.assignTimeSlice(this);
66        events.add(event);
67        Collections.sort(events);
68    }
69
70    /**
71     * Get the X position of this timeslice on the GUI timeline. Affected by
72     * zoom level.
73     *
74     * @return Screen distance from the start of the timeline that this
75     * timeslice occurs
76     */
77    public int getX()
78    {
79        return seconds / ScriptBuilderGuiConstants.HORIZONTAL_TICK_RESOLUTION
80                * ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK;
81    }
82
83    /**
84     * Get the start time of this timeSlice.
85     *
86     * @return the start time of the timeslice in seconds, from the beginning of
87     * the simulation
88     */
89    public int getTime()
90    {
91        return seconds;
92    }
93
94    /**
95     * Shift the start position of this timeslice to the right by some amount.
96     *
97     * @param amnt the number of seconds forward in time to push this slice
98     */
99    public void shift(int amnt)
100    {
101        seconds += amnt;
102    }
103
104    /**
105     * Get the number of seconds that events which start in this timeslice are
106     * active.
107     *
108     * @return The duration of the longest-lasting event in this slice.
109     */
110    public int getEffectiveDuration()
111    {
112        int dur = 0;
113        for (I_ScriptEvent evt : events)
114        {
115            // save the largest of current dur or this evt length
116            dur = Math.max(dur, evt.getLength());
117        }
118        return dur;
119    }
120
121    /**
122     * Get the text to be displayed when hovering over this timeSlice.
123     *
124     * @param y the y-position of the cursor on the GUI
125     * @return The text to be displayed: all events are listed if we're on the
126     * main incident line, but only one event is listed if we're hovering over
127     * that particular event
128     */
129    public String getToolTipText(int y)
130    {
131        int i = (y - ScriptBuilderGuiConstants.SCRIPT_EVENT_ICON_TOP_MARGIN);
132        if (i < 0)
133        {
134            if (i > (-1 * ScriptBuilderGuiConstants.SCRIPT_EVENT_ICON_STEP))
135            {
136                String s = toString();
137                if (s.equals(""))
138                {
139                    return null;
140                }
141
142                return "<html>" + s.replace("\n", "<br/>") + "</html>";
143            }
144            else
145            {
146                return null;
147            }
148        }
149
150        i /= ScriptBuilderGuiConstants.SCRIPT_EVENT_ICON_STEP;
151        if (i < events.size())
152        {
153            return events.get(i).toString();
154        }
155        return null;
156    }
157
158    /**
159     * List all the events attached to this timeslice, with line breaks between.
160     *
161     * @return A list of the form: event1_type - event1_description event2_type
162     * - event2_description ...
163     */
164    @Override
165    public String toString()
166    {
167        StringBuilder sb = new StringBuilder();
168
169        for (I_ScriptEvent event : events)
170        {
171            sb.append(event.toString());
172            sb.append('\n');
173        }
174
175        return sb.toString();
176    }
177
178    /**
179     * Order the timeslices by start time. Earlier start times come first.
180     *
181     * @param o the other timeSlice to be compared
182     * @return -1, 0 , or 1 depending on if this timeSlice comes before,
183     * simultaneously, or after the other
184     */
185    @Override
186    public int compareTo(Object o)
187    {
188        if (o instanceof TimeSlice)
189        {
190            TimeSlice other = (TimeSlice) o;
191            if (this.getTime() < other.getTime())
192            {
193                return -1;
194            }
195            else if (this.getTime() > other.getTime())
196            {
197                return 1;
198            }
199        }
200        return 0;
201    }
202
203    /**
204     * Converts the contents of this timeslice to a correctly formatted
205     * <ScriptEvent> XML element.
206     *
207     * @return XML conversion of this timeslice.
208     */
209    @Override
210    public String toXML()
211    {
212        ArrayList<I_ScriptEvent> eventsCopy = new ArrayList<I_ScriptEvent>();
213        ArrayList<I_ScriptEvent> eventsCopy2 = new ArrayList<I_ScriptEvent>();
214
215        for (I_ScriptEvent e : events)
216        {
217            eventsCopy.add(e);
218        }
219
220        String output = XMLWriter.openTag(ELEMENT.SCRIPT_EVENT.tag);
221        SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
222        df.setTimeZone(TimeZone.getTimeZone("GMT"));
223        output += XMLWriter.openTag(ELEMENT.TIME_INDEX.tag) + df.format(new Date(seconds * 1000))
224                + XMLWriter.closeTag(ELEMENT.TIME_INDEX.tag);
225
226        output += XMLWriter.openTag(ELEMENT.INCIDENT.tag + " LogNum=\"" + thisIncident.number + "\"");
227        output += thisIncident.name + XMLWriter.closeTag(ELEMENT.INCIDENT.tag);
228        output += XMLWriter.emptyTag(ELEMENT.COLOR.tag
229                + " r=\"" + thisIncident.color.getRed() + "\""
230                + " g=\"" + thisIncident.color.getGreen() + "\""
231                + " b=\"" + thisIncident.color.getBlue() + "\"");
232
233        if ((cadData != null && cadData.hasCadData()) || containsCADIncidentEvent())
234        {
235            output += XMLWriter.openTag(ELEMENT.CAD_DATA.tag);
236            if (cadData != null)
237            {
238                output += cadData.toXML();
239            }
240
241            if (containsCADIncidentEvent())
242            {
243                output += XMLWriter.openTag(ELEMENT.CAD_INCIDENT_EVENT.tag);
244                for (I_ScriptEvent ev : eventsCopy)
245                {
246                    if (ev instanceof I_XML_Writable && isCADIncidentEvent(ev))
247                    {
248                        I_XML_Writable ex = (I_XML_Writable) ev;
249                        output += ex.toXML();
250                    }
251                    else
252                    {
253                        eventsCopy2.add(ev);
254                    }
255                }
256
257                eventsCopy = eventsCopy2;
258                output += XMLWriter.closeTag(ELEMENT.CAD_INCIDENT_EVENT.tag);
259            }
260
261            output += XMLWriter.closeTag(ELEMENT.CAD_DATA.tag);
262        }
263
264        if (cadData != null && cadData.hasGeneralInfo())
265        {
266            output += XMLWriter.openTag(ELEMENT.GENERAL_INFO.tag);
267
268            output += XMLWriter.simpleTag(cadData.General_Title, ELEMENT.TITLE);
269
270            output += XMLWriter.simpleTag(cadData.General_Text, ELEMENT.TEXT);
271
272            output += XMLWriter.closeTag(ELEMENT.GENERAL_INFO.tag);
273
274        }
275
276        for (I_ScriptEvent ev : eventsCopy)
277        {
278            if (ev instanceof I_XML_Writable)
279            {
280                I_XML_Writable ex = (I_XML_Writable) ev;
281                output += ex.toXML();
282            }
283        }
284        output += XMLWriter.closeTag(ELEMENT.SCRIPT_EVENT.tag);
285        return output;
286    }
287
288    private boolean containsCADIncidentEvent()
289    {
290        for (I_ScriptEvent ev : events)
291        {
292            if (isCADIncidentEvent(ev))
293            {
294                return true;
295            }
296        }
297        return false;
298    }
299
300    private boolean isCADIncidentEvent(I_ScriptEvent ev)
301    {
302        return ev instanceof AudioEvent || ev instanceof UnitEvent
303                || ev instanceof ParamicsEvent || ev instanceof TowEvent
304                || ev instanceof WitnessEvent || ev instanceof CADEvent;
305    }
306
307    public void checkEmpty()
308    {
309        if (this.events.isEmpty())
310        {
311            this.thisIncident.removeTimeSlice(this.seconds);
312        }
313    }
314}
Note: See TracBrowser for help on using the repository browser.