tmf: Allow time graph zoomed event list to be built incrementally
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / widgets / timegraph / model / TimeGraphEntry.java
1 /*******************************************************************************
2 * Copyright (c) 2012, 2015 Ericsson, École Polytechnique de Montréal
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Patrick Tasse - Initial API and implementation
11 * Geneviève Bastien - Move code to provide base classes for time graph view
12 *******************************************************************************/
13
14 package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model;
15
16 import java.util.ArrayList;
17 import java.util.Arrays;
18 import java.util.Comparator;
19 import java.util.Iterator;
20 import java.util.List;
21 import java.util.concurrent.CopyOnWriteArrayList;
22
23 import org.eclipse.jdt.annotation.NonNull;
24 import org.eclipse.swt.SWT;
25
26 /**
27 * An entry for use in the time graph views
28 */
29 public class TimeGraphEntry implements ITimeGraphEntry {
30
31 /** Entry's parent */
32 private ITimeGraphEntry fParent = null;
33
34 /** List of child entries */
35 private final List<ITimeGraphEntry> fChildren = new CopyOnWriteArrayList<>();
36
37 /** Name of this entry (text to show) */
38 private String fName;
39 private long fStartTime = SWT.DEFAULT;
40 private long fEndTime = SWT.DEFAULT;
41 private @NonNull List<ITimeEvent> fEventList = new ArrayList<>();
42 private @NonNull List<ITimeEvent> fZoomedEventList = new ArrayList<>();
43 private Comparator<ITimeGraphEntry> fComparator;
44
45 /**
46 * Constructor
47 *
48 * @param name
49 * The name of this entry
50 * @param startTime
51 * The start time of this entry
52 * @param endTime
53 * The end time of this entry
54 */
55 public TimeGraphEntry(String name, long startTime, long endTime) {
56 fName = name;
57 fStartTime = startTime;
58 fEndTime = endTime;
59 }
60
61 // ---------------------------------------------
62 // Getters and setters
63 // ---------------------------------------------
64
65 @Override
66 public ITimeGraphEntry getParent() {
67 return fParent;
68 }
69
70 /**
71 * Sets the entry's parent
72 *
73 * @param entry The new parent entry
74 */
75 /*
76 * TODO: This method can be removed in the next major API version.
77 */
78 protected void setParent(TimeGraphEntry entry) {
79 fParent = entry;
80 }
81
82 /**
83 * Sets the entry's parent
84 *
85 * @param entry The new parent entry
86 */
87 /*
88 * TODO: This method should be added to the interface in the next major API version.
89 */
90 protected void setParent(ITimeGraphEntry entry) {
91 fParent = entry;
92 }
93
94 @Override
95 public synchronized boolean hasChildren() {
96 return fChildren.size() > 0;
97 }
98
99 @Override
100 public synchronized List<? extends ITimeGraphEntry> getChildren() {
101 return fChildren;
102 }
103
104 @Override
105 public String getName() {
106 return fName;
107 }
108
109 /**
110 * Update the entry name
111 *
112 * @param name
113 * the updated entry name
114 */
115 public void setName(String name) {
116 fName = name;
117 }
118
119 @Override
120 public long getStartTime() {
121 return fStartTime;
122 }
123
124 @Override
125 public long getEndTime() {
126 return fEndTime;
127 }
128
129 /**
130 * Updates the end time
131 *
132 * @param endTime
133 * the end time
134 */
135 public void updateEndTime(long endTime) {
136 fEndTime = Math.max(endTime, fEndTime);
137 }
138
139 @Override
140 public boolean hasTimeEvents() {
141 return true;
142 }
143
144 @Override
145 public Iterator<ITimeEvent> getTimeEventsIterator() {
146 if (hasTimeEvents()) {
147 return new EventIterator(fEventList, fZoomedEventList);
148 }
149 return null;
150 }
151
152 @Override
153 public Iterator<ITimeEvent> getTimeEventsIterator(long startTime, long stopTime, long visibleDuration) {
154 if (!hasTimeEvents()) {
155 return null;
156 }
157 return new EventIterator(fEventList, fZoomedEventList, startTime, stopTime);
158 }
159
160 /**
161 * Add an event to this entry's event list. If necessary, update the start
162 * and end time of the entry. If the event list's last event starts at the
163 * same time as the event to add, it is replaced by the new event.
164 *
165 * @param event
166 * The time event to add
167 */
168 public void addEvent(ITimeEvent event) {
169 long start = event.getTime();
170 long end = start + event.getDuration();
171 int lastIndex = fEventList.size() - 1;
172 if (lastIndex >= 0 && fEventList.get(lastIndex).getTime() == event.getTime()) {
173 fEventList.set(lastIndex, event);
174 } else {
175 fEventList.add(event);
176 }
177 if (fStartTime == SWT.DEFAULT || start < fStartTime) {
178 fStartTime = start;
179 }
180 if (fEndTime == SWT.DEFAULT || end > fEndTime) {
181 fEndTime = end;
182 }
183 }
184
185 /**
186 * Set the general event list of this entry. The list should be modifiable
187 * but will only increase in size over time.
188 *
189 * @param eventList
190 * The modifiable list of time events, or null to clear the list
191 */
192 public void setEventList(List<ITimeEvent> eventList) {
193 if (eventList != null) {
194 fEventList = eventList;
195 } else {
196 fEventList = new ArrayList<>();
197 }
198 }
199
200 /**
201 * Set the zoomed event list of this entry. The list should be modifiable
202 * but will only increase in size over time.
203 *
204 * @param eventList
205 * The modifiable list of time events, or null to clear the list
206 */
207 public void setZoomedEventList(List<ITimeEvent> eventList) {
208 if (eventList != null) {
209 fZoomedEventList = eventList;
210 } else {
211 fZoomedEventList = new ArrayList<>();
212 }
213 }
214
215 /**
216 * Add an event to this entry's zoomed event list. If necessary, update the
217 * start and end time of the entry. If the zoomed event list's last event
218 * starts at the same time as the event to add, it is replaced by the new
219 * event. If the new event starts before the zoomed event list's last event,
220 * the new event is ignored and is assumed to be already part of the list.
221 *
222 * @param event
223 * The time event to add
224 * @since 2.0
225 */
226 public void addZoomedEvent(ITimeEvent event) {
227 long start = event.getTime();
228 long end = start + event.getDuration();
229 int lastIndex = fZoomedEventList.size() - 1;
230 long lastStart = lastIndex >= 0 ? fZoomedEventList.get(lastIndex).getTime() : Long.MIN_VALUE;
231 if (start > lastStart) {
232 fZoomedEventList.add(event);
233 } else if (start == lastStart) {
234 fZoomedEventList.set(lastIndex, event);
235 }
236 if (fStartTime == SWT.DEFAULT || start < fStartTime) {
237 fStartTime = start;
238 }
239 if (fEndTime == SWT.DEFAULT || end > fEndTime) {
240 fEndTime = end;
241 }
242 }
243
244 /**
245 * Add a child entry to this one
246 *
247 * @param child
248 * The child entry
249 */
250 /*
251 * TODO: This method can be removed in the next major API version.
252 */
253 public synchronized void addChild(TimeGraphEntry child) {
254 addChild((ITimeGraphEntry) child);
255 }
256
257 /**
258 * Add a child entry to this one. If a comparator was previously set with
259 * {@link #sortChildren(Comparator)}, the entry will be inserted in its
260 * sort-order position. Otherwise it will be added to the end of the list.
261 *
262 * @param child
263 * The child entry
264 */
265 public synchronized void addChild(ITimeGraphEntry child) {
266 /*
267 * TODO: Use setParent() once it is added to the interface.
268 */
269 if (child instanceof TimeGraphEntry) {
270 ((TimeGraphEntry) child).fParent = this;
271 }
272 if (fComparator == null) {
273 fChildren.add(child);
274 } else {
275 int i;
276 for (i = 0; i < fChildren.size(); i++) {
277 ITimeGraphEntry entry = fChildren.get(i);
278 if (fComparator.compare(child, entry) < 0) {
279 break;
280 }
281 }
282 fChildren.add(i, child);
283 }
284 }
285
286 /**
287 * Add a child entry to this one at the specified position
288 *
289 * @param index
290 * Index at which the specified entry is to be inserted
291 * @param child
292 * The child entry
293 */
294 public synchronized void addChild(int index, ITimeGraphEntry child) {
295 /*
296 * TODO: Use setParent() once it is added to the interface.
297 */
298 if (child instanceof TimeGraphEntry) {
299 ((TimeGraphEntry) child).fParent = this;
300 }
301 fChildren.add(index, child);
302 }
303
304 /**
305 * Sort the children of this entry using the provided comparator. Subsequent
306 * calls to {@link #addChild(ITimeGraphEntry)} will use this comparator to
307 * maintain the sort order.
308 *
309 * @param comparator
310 * The entry comparator
311 */
312 public synchronized void sortChildren(Comparator<ITimeGraphEntry> comparator) {
313 fComparator = comparator;
314 if (comparator == null) {
315 return;
316 }
317 ITimeGraphEntry[] array = fChildren.toArray(new ITimeGraphEntry[0]);
318 Arrays.sort(array, comparator);
319 fChildren.clear();
320 fChildren.addAll(Arrays.asList(array));
321 }
322
323 @Override
324 public String toString() {
325 return getClass().getSimpleName() + '(' + fName + ')';
326 }
327
328 }
This page took 0.038612 seconds and 6 git commands to generate.