Warning: Can't use blame annotator:
svn blame failed on trunk/src/scriptbuilder/structures/ScriptIncident.java: ("Can't find a temporary directory: Internal error", 20014)

source: tmcsimulator-scriptbuilder/trunk/src/scriptbuilder/structures/ScriptIncident.java @ 164

Revision 164, 15.2 KB checked in by sdanthin, 6 years ago (diff)

ScriptIncident?.java added if statement to create a correct AudioEvent? when an I_AudioEvent event is created.

RevLine 
1package scriptbuilder.structures;
2
3import java.awt.Color;
4import java.io.BufferedWriter;
5import java.io.File;
6import java.io.FileWriter;
7import java.util.ArrayList;
8import java.util.TreeMap;
9import scriptbuilder.structures.events.I_ScriptEvent;
10import scriptbuilder.structures.ScriptEvent.ScriptEventType;
11import scriptbuilder.structures.events.I_AudioEvent;
12import scriptbuilder.structures.events.AudioEvent;
13
14/**
15 * A script incident. It has an ID number, a name, and a description. It may
16 * contain several script events. It also has a color in the GUI window, and is
17 * collapsible. Incidents may start as soon as the script begins to run, or they
18 * can be offset from the start of the script.
19 *
20 * @author Greg Eddington <geddingt@calpoly.edu>
21 * @author Bryan McGuffin
22 * @version 2017/06/29
23 */
24public class ScriptIncident implements I_XML_Writable
25{
26
27    /**
28     * The moments in time which have associated events.
29     */
30    public TreeMap<Integer, TimeSlice> slices;
31
32    /**
33     * GUI display color of this slice.
34     */
35    public Color color;
36
37    /**
38     * ID number for this incident.
39     */
40    public int number;
41
42    /**
43     * Name of the incident.
44     */
45    public String name;
46
47    /**
48     * Description of the incident.
49     */
50    public String description;
51   
52    /**
53     * Length, in seconds, of the incident.
54     */
55    public int length = 0;
56
57    /**
58     * If true, incident appears minimized.
59     */
60    public boolean collapsed = false;
61
62    /**
63     * Number of seconds between start of simulation and start of this incident.
64     */
65    public int offset = 0;
66
67    /**
68     * Start position of the latest timeslice.
69     */
70    private int latestStart = 0;
71
72    /**
73     * Number of events in this incident.
74     */
75    public int eventCount = 0;
76   
77    public int audioEventCount = 0;
78
79    public SimulationScript script;
80
81    /**
82     * Basic constructor.
83     *
84     * @param number The incident ID number
85     * @param name The name of the incident
86     * @param description The description of the incident
87     * @param script The script object holding this incident
88     */
89    public ScriptIncident(int number, String name, String description,
90            SimulationScript script)
91    {
92        color = Color.BLACK;
93        this.number = number;
94        this.name = name;
95        this.description = description;
96        this.script = script;
97        slices = new TreeMap<Integer, TimeSlice>();
98    }
99
100    /**
101     * Constructor with color parameter.
102     *
103     * @param color The color to use in the GUI for this event
104     * @param number The incident ID number
105     * @param name The name of the incident
106     * @param description The description of the incident
107     * @param script The script object holding this incident
108     */
109    public ScriptIncident(Color color, int number, String name,
110            String description, SimulationScript script)
111    {
112        this.color = color;
113        this.number = number;
114        this.name = name;
115        this.description = description;
116        this.script = script;
117        slices = new TreeMap<Integer, TimeSlice>();
118    }
119
120    /**
121     * Constructor with color and offset parameters.
122     *
123     * @param color The color to use in the GUI for this event
124     * @param number The incident ID number
125     * @param name The name of the incident
126     * @param description The description of the incident
127     * @param script The script object holding this incident
128     * @param offset Number of seconds after 00:00:00 that this incident begins
129     */
130    public ScriptIncident(Color color, int number, String name,
131            String description, SimulationScript script,
132            int offset)
133    {
134        this.color = color;
135        this.number = number;
136        this.name = name;
137        this.description = description;
138        this.script = script;
139        slices = new TreeMap<Integer, TimeSlice>();
140        this.setOffset(offset);
141    }
142   
143//    /**
144//     * Constructor with type and location parameters.
145//     * @param color
146//     * @param number
147//     * @param name
148//     * @param description
149//     * @param script
150//     * @param offset
151//     * @param type
152//     * @param location
153//     */
154//    public ScriptIncident(Color color, int number, String name,
155//            String description, SimulationScript script,
156//            int offset, String type, String location)
157//    {
158//        this.color = color;
159//        this.number = number;
160//        this.name = name;
161//        this.description = description;
162//        this.script = script;
163//        slices = new TreeMap<Integer, TimeSlice>();
164//        this.setOffset(offset);
165//        this.location = location;
166//        this.type = type;
167//        insertCadData(offset, new CadData(type,location));
168//    }
169
170    /**
171     * Set whether or not the incident is fully visible or in a compacted state.
172     *
173     * @param collapsed True if the event is compacted
174     */
175    public void setCollapsed(boolean collapsed)
176    {
177        this.collapsed = collapsed;
178        script.update();
179    }
180
181    /**
182     * Set the delay time between the start of the script and the start of this
183     * incident.
184     *
185     * @param offset Number of seconds after 00:00:00 that this incident begins
186     */
187    public void setOffset(int offset)
188    {
189        int old = this.offset;
190        this.offset = offset;
191        TreeMap<Integer, TimeSlice> newSlices = new TreeMap<Integer, TimeSlice>();
192
193        int latest = 0;
194
195        for (Integer k : slices.keySet())
196        {
197            newSlices.put(k + (offset - old), slices.get(k));
198            latest = k + (offset - old);
199        }
200
201        latestStart = latest;
202
203        for (TimeSlice ts : newSlices.values())
204        {
205            ts.shift(offset - old);
206        }
207
208        slices = newSlices;
209        updateLength();
210        script.update();
211    }
212    /**
213     * shifts all timeslices over by timeAdd amount starting at offset
214     * @param offset amount of time preceding where we want to move all of the following events.
215     * @param timeAdd amount of time added after offset
216     */
217    public void moveAllFollowingEvents(int offset, int timeAdd)
218    {
219        //int old = this.offset;
220        TreeMap<Integer, TimeSlice> newSlices = new TreeMap<Integer, TimeSlice>();
221
222       
223
224        for (Integer k : slices.keySet())
225        {
226            if(k<offset)
227            {
228                newSlices.put(k, slices.get(k));
229            }else
230            {
231                if(k+timeAdd >0)
232                {
233                    newSlices.put(k+timeAdd, slices.get(k));
234                }else
235                {
236                    newSlices.put(0, slices.get(k));
237                }
238               
239            }
240           
241           
242        }
243        for (TimeSlice ts : newSlices.values())
244        {
245            if(ts.getTime()>offset )
246            {
247                if( ts.getTime()+timeAdd>=0)
248                {
249                    ts.shift(timeAdd);
250                }
251                else
252                {
253                    ts.shift(-ts.getTime());
254                }
255               
256            }
257           
258        }
259        latestStart = (latestStart + timeAdd>0) ? latestStart + timeAdd: 0;
260        slices = newSlices;
261        updateLength();
262        script.update();
263    }
264    /**
265     * Add a new script event to this incident.
266     *
267     * @param ev The new event
268     * @param start Start time of this event, in seconds, from the beginning of
269     * the simulation
270     */
271    public void addNewEvent(I_ScriptEvent ev, int start)
272    {
273        /*
274        int leftoverSeconds = start % 60;
275       
276        //round start time to the nearest minute
277        if(leftoverSeconds != 0)
278        {
279            if(leftoverSeconds > 30)
280            {
281                start += (60 - leftoverSeconds);
282            }
283            else
284            {
285                start -= leftoverSeconds;
286            }
287        }
288        */
289       
290        //Check to see if there's already a timeslice here
291        TimeSlice t = slices.get(start);
292        //logic to check if the added event needs to also have an associated audio event.
293       
294        //If not, make one; then, add the event to it
295        if (t == null)
296        {
297            t = new TimeSlice(start, this);
298            //t.addEvent(ev);
299            slices.put(start, t);
300        }
301        else
302        {
303            //t.addEvent(ev);
304        }
305        t.addEvent(ev);
306        if(ev instanceof I_AudioEvent){
307            //should make a path and a different filename fields for the file itself. Either that or deal with the string separation each time
308            //needs a check for when we move I_AudioEvents in the incident, as to not make duplicate events.
309            String fileName = number+"/"+number + "" + audioEventCount;
310            AudioEvent audio = (AudioEvent) ScriptEvent.factoryByType(ScriptEventType.AUDIO_EVENT);
311            ((I_AudioEvent) ev).setFileName(fileName);
312            audio.setAudioFilePathRelative(fileName);
313           
314            t.addEvent(audio);
315            audioEventCount++;
316        }
317        eventCount++;
318
319        //If this is the latest start time in the incident, update that number
320        if (start > latestStart)
321        {
322            latestStart = start;
323        }
324        //If this event is earlier than all previous events, or if there are
325        //no other events, the offset is equal to this event's start time
326        if (start < offset || eventCount == 1)
327        {
328            offset = start;
329            //System.out.println("Offset: " + offset);
330        }
331        updateLength();
332    }
333
334    /**
335     * Get an array of all valid timeSlices.
336     *
337     * @return List of timeSlices which are not null
338     */
339    public ArrayList<TimeSlice> getSlices()
340    {
341        ArrayList<TimeSlice> arr = new ArrayList<TimeSlice>();
342        for (int i = 0; i <= latestStart; i++)
343        {
344            TimeSlice ts = slices.get(i);
345            if (ts != null)
346            {
347                arr.add(ts);
348            }
349        }
350        return arr;
351    }
352
353    /**
354     * Write this incident, in proper XML form, to the file in question.
355     *
356     * @param f the destination savefile
357     */
358    public void saveIncidentToFile(File f)
359    {
360        try
361        {
362            f.createNewFile();
363
364            BufferedWriter bw = new BufferedWriter(new FileWriter(f));
365            bw.write(this.toXML());
366            bw.flush();
367            bw.close();
368
369        }
370        catch (Exception ex)
371        {
372            System.out.println("ERROR SAVING SCRIPT");
373            ex.printStackTrace();
374        }
375    }
376
377    @Override
378    public String toXML()
379    {
380        String output = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n";
381        output += XMLWriter.internalDTD();
382        output += XMLWriter.openTag(ELEMENT.TMC_SCRIPT.tag + " title=\"" + this.script.title + "\"");
383
384        for (TimeSlice slice : slices.values())
385        {
386            output += slice.toXML();
387        }
388        output += XMLWriter.closeTag(ELEMENT.TMC_SCRIPT.tag);
389        return output;
390    }
391
392    public void insertCadData(long currentEventTime, CadData cad)
393    {
394        int time = (int) currentEventTime;
395
396        TimeSlice slice;
397
398        if (slices.get(time) == null)
399        {
400            slices.put(time, new TimeSlice(time, this));
401        }
402        slice = slices.get(time);
403        slice.cadData = cad;
404    }
405   
406    public CadData getCadData(long currentEventTime)
407    {
408        int time = (int) currentEventTime;
409        TimeSlice slice;
410       
411        slice = slices.get(time);
412        return slice.cadData;
413    }
414
415    /**
416     * Update the offset and apparent length of this incident. The offset is the
417     * start time of the earliest event in the incident. The length is the time
418     * that the latest, longest-lasting event ends, minus the offset.
419     */
420    public void updateLength()
421    {
422        int lengthSoFar = 0;
423        for (int i = 0; i <= latestStart; i++)
424        {
425            TimeSlice ts = slices.get(i);
426            if (ts != null)
427            {
428                int reach = ts.getTime() + ts.getEffectiveDuration() - offset;
429                if (reach > lengthSoFar)
430                {
431                    lengthSoFar = reach;
432                }
433            }
434        }
435        length = lengthSoFar;
436    }
437
438    /**
439     * An event which is fired if the focused slice changes.
440     */
441    public static class SliceChangedEvent
442    {
443
444        /**
445         * The slice which has received focus in this event.
446         */
447        public TimeSlice slice;
448
449        SliceChangedEvent(TimeSlice slice)
450        {
451            this.slice = slice;
452        }
453    }
454
455    /**
456     * Update and cause the system to focus on the given timeslice.
457     *
458     * @param i Index of the slice to focus on
459     */
460    public void setSliceActive(int i)
461    {
462        if (this.slices.get(i) != null)
463        {
464            script.broadcastEvent(new SliceChangedEvent(this.slices.get(i)));
465        }
466    }
467
468    /**
469     * An event which is fired if the focused incident changes.
470     */
471    public static class IncidentFocusedEvent
472    {
473
474        /**
475         * The incident which has received focus in this event.
476         */
477        public ScriptIncident incident;
478
479        IncidentFocusedEvent(ScriptIncident i)
480        {
481            incident = i;
482        }
483    }
484
485    /**
486     * Update and cause the system to focus on this incident.
487     */
488    public void setIncidentActive()
489    {
490        script.broadcastEvent(new IncidentFocusedEvent(this));
491    }
492
493    /**
494     * String representation of this incident.
495     *
496     * @return String of the form "[Incident number] - [Incident name]"
497     */
498    @Override
499    public String toString()
500    {
501        return this.number + " - " + this.name;
502    }
503
504    /**
505     * Remove the timeslice at the given position.
506     *
507     * @param seconds absolute start time of the timeslice to remove.
508     */
509    public void removeTimeSlice(int seconds)
510    {
511        //remove the timeslice
512        this.slices.remove(seconds);
513
514        //offset is equivalent to start time of earliest slice
515        if (seconds == offset)
516        {
517            if (slices.size() > 0)
518            {
519                offset = slices.firstKey();
520            }
521            else
522            {
523                offset = 0;
524            }
525        }
526        this.updateLength();
527        script.update();
528    }
529
530    /**
531     * Shifts the start time of a given event in this incident. The first event
532     * in the incident cannot be shifted.
533     *
534     * @param evt the event to be relocated
535     * @param oldTime the current start time of the event
536     * @param newTime the destination start time of the event
537     * @return true if the event is shifted over properly
538     * @pre the event in question exists
539     * @pre oldTime != newTime
540     */
541    public boolean changeEventStart(I_ScriptEvent evt, int oldTime, int newTime)
542    {
543        if (!(oldTime == 0 && newTime > oldTime))
544        {
545            if(evt instanceof I_AudioEvent)
546            {
547                //todo: need to figure out how to remove the audioEvent tha corresponds with the
548                this.slices.get(oldTime).removeCorrespondingAudioEvent((I_AudioEvent)evt);
549                //this.addNewEvent(evt,newTime)
550            }
551            this.slices.get(oldTime).events.remove(evt);
552            this.addNewEvent(evt, newTime);
553            return true;
554        }
555        return false;
556    }
557}
Note: See TracBrowser for help on using the repository browser.