tmf: Bug 496504: Fix duplicate child entries in Control Flow view
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / widgets / timegraph / model / TimeGraphEntry.java
CommitLineData
4999a196 1/*******************************************************************************
f8f46a52 2 * Copyright (c) 2012, 2016 Ericsson, École Polytechnique de Montréal
4999a196
GB
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
2bdf0193 14package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model;
4999a196
GB
15
16import java.util.ArrayList;
9ba941e9
PT
17import java.util.Arrays;
18import java.util.Comparator;
4999a196
GB
19import java.util.Iterator;
20import java.util.List;
1cf25311 21import java.util.concurrent.CopyOnWriteArrayList;
36299425 22import java.util.regex.Pattern;
4999a196 23
0b02f22a 24import org.eclipse.jdt.annotation.NonNull;
50d36521
PT
25import org.eclipse.swt.SWT;
26
4999a196
GB
27/**
28 * An entry for use in the time graph views
4999a196
GB
29 */
30public class TimeGraphEntry implements ITimeGraphEntry {
31
4999a196 32 /** Entry's parent */
f8f46a52 33 private TimeGraphEntry fParent = null;
4999a196
GB
34
35 /** List of child entries */
f8f46a52 36 private final List<@NonNull TimeGraphEntry> fChildren = new CopyOnWriteArrayList<>();
4999a196
GB
37
38 /** Name of this entry (text to show) */
39 private String fName;
50d36521
PT
40 private long fStartTime = SWT.DEFAULT;
41 private long fEndTime = SWT.DEFAULT;
0b02f22a
PT
42 private @NonNull List<ITimeEvent> fEventList = new ArrayList<>();
43 private @NonNull List<ITimeEvent> fZoomedEventList = new ArrayList<>();
9ba941e9 44 private Comparator<ITimeGraphEntry> fComparator;
4999a196
GB
45
46 /**
47 * Constructor
48 *
4999a196 49 * @param name
1d46dc38 50 * The name of this entry
4999a196 51 * @param startTime
1d46dc38 52 * The start time of this entry
4999a196 53 * @param endTime
1d46dc38 54 * The end time of this entry
4999a196 55 */
1d46dc38 56 public TimeGraphEntry(String name, long startTime, long endTime) {
4999a196
GB
57 fName = name;
58 fStartTime = startTime;
59 fEndTime = endTime;
60 }
61
62 // ---------------------------------------------
63 // Getters and setters
64 // ---------------------------------------------
65
4999a196 66 /**
f8f46a52 67 * @since 2.0
a3188982 68 */
f8f46a52
PT
69 @Override
70 public TimeGraphEntry getParent() {
71 return fParent;
4999a196
GB
72 }
73
a3188982
PT
74 /**
75 * Sets the entry's parent
76 *
77 * @param entry The new parent entry
f8f46a52 78 * @since 2.0
a3188982 79 */
f8f46a52 80 public void setParent(TimeGraphEntry entry) {
a3188982
PT
81 fParent = entry;
82 }
83
4999a196 84 @Override
9ba941e9 85 public synchronized boolean hasChildren() {
4999a196
GB
86 return fChildren.size() > 0;
87 }
88
89 @Override
f8f46a52 90 public synchronized List<@NonNull TimeGraphEntry> getChildren() {
4999a196
GB
91 return fChildren;
92 }
93
bf415887
MZ
94 /**
95 * Clear the children of the entry
96 *
97 * @since 2.0
98 */
3553c912 99 public synchronized void clearChildren() {
bf415887
MZ
100 fChildren.clear();
101 }
102
4999a196
GB
103 @Override
104 public String getName() {
105 return fName;
106 }
107
108 /**
109 * Update the entry name
110 *
111 * @param name
112 * the updated entry name
113 */
114 public void setName(String name) {
115 fName = name;
116 }
117
118 @Override
119 public long getStartTime() {
120 return fStartTime;
121 }
122
123 @Override
124 public long getEndTime() {
125 return fEndTime;
126 }
127
1cf25311
PT
128 /**
129 * Updates the end time
130 *
131 * @param endTime
132 * the end time
1cf25311
PT
133 */
134 public void updateEndTime(long endTime) {
135 fEndTime = Math.max(endTime, fEndTime);
136 }
137
4999a196
GB
138 @Override
139 public boolean hasTimeEvents() {
140 return true;
141 }
142
143 @Override
df2597e0 144 public Iterator<@NonNull ITimeEvent> getTimeEventsIterator() {
4999a196
GB
145 if (hasTimeEvents()) {
146 return new EventIterator(fEventList, fZoomedEventList);
147 }
148 return null;
149 }
150
151 @Override
df2597e0 152 public Iterator<@NonNull ITimeEvent> getTimeEventsIterator(long startTime, long stopTime, long visibleDuration) {
4999a196
GB
153 if (!hasTimeEvents()) {
154 return null;
155 }
156 return new EventIterator(fEventList, fZoomedEventList, startTime, stopTime);
157 }
158
159 /**
1d46dc38 160 * Add an event to this entry's event list. If necessary, update the start
1cf25311
PT
161 * and end time of the entry. If the event list's last event starts at the
162 * same time as the event to add, it is replaced by the new event.
4999a196
GB
163 *
164 * @param event
1cf25311 165 * The time event to add
4999a196
GB
166 */
167 public void addEvent(ITimeEvent event) {
168 long start = event.getTime();
169 long end = start + event.getDuration();
0b02f22a
PT
170 int lastIndex = fEventList.size() - 1;
171 if (lastIndex >= 0 && fEventList.get(lastIndex).getTime() == event.getTime()) {
172 fEventList.set(lastIndex, event);
173 } else {
174 fEventList.add(event);
175 }
cb982e03
PT
176 if (event instanceof NullTimeEvent) {
177 /* A NullTimeEvent should not affect the entry bounds */
178 return;
179 }
0b02f22a
PT
180 if (fStartTime == SWT.DEFAULT || start < fStartTime) {
181 fStartTime = start;
182 }
183 if (fEndTime == SWT.DEFAULT || end > fEndTime) {
184 fEndTime = end;
4999a196
GB
185 }
186 }
187
188 /**
0b02f22a
PT
189 * Set the general event list of this entry. The list should be modifiable
190 * but will only increase in size over time.
4999a196 191 *
4999a196 192 * @param eventList
0b02f22a 193 * The modifiable list of time events, or null to clear the list
4999a196
GB
194 */
195 public void setEventList(List<ITimeEvent> eventList) {
3ce8c834 196 if (eventList != null) {
0b02f22a 197 fEventList = eventList;
3ce8c834 198 } else {
507b1336 199 fEventList = new ArrayList<>();
3ce8c834 200 }
4999a196
GB
201 }
202
203 /**
0b02f22a
PT
204 * Set the zoomed event list of this entry. The list should be modifiable
205 * but will only increase in size over time.
4999a196 206 *
4999a196 207 * @param eventList
0b02f22a 208 * The modifiable list of time events, or null to clear the list
4999a196
GB
209 */
210 public void setZoomedEventList(List<ITimeEvent> eventList) {
3ce8c834 211 if (eventList != null) {
0b02f22a 212 fZoomedEventList = eventList;
3ce8c834 213 } else {
507b1336 214 fZoomedEventList = new ArrayList<>();
3ce8c834 215 }
4999a196
GB
216 }
217
0b02f22a
PT
218 /**
219 * Add an event to this entry's zoomed event list. If necessary, update the
220 * start and end time of the entry. If the zoomed event list's last event
221 * starts at the same time as the event to add, it is replaced by the new
222 * event. If the new event starts before the zoomed event list's last event,
223 * the new event is ignored and is assumed to be already part of the list.
9597a3b5
PT
224 * If the new event starts before the zoomed event list's first event, the
225 * list is assumed to be incomplete and is cleared, and the event is added.
0b02f22a
PT
226 *
227 * @param event
228 * The time event to add
0336f981 229 * @since 1.1
0b02f22a
PT
230 */
231 public void addZoomedEvent(ITimeEvent event) {
232 long start = event.getTime();
233 long end = start + event.getDuration();
234 int lastIndex = fZoomedEventList.size() - 1;
235 long lastStart = lastIndex >= 0 ? fZoomedEventList.get(lastIndex).getTime() : Long.MIN_VALUE;
236 if (start > lastStart) {
237 fZoomedEventList.add(event);
238 } else if (start == lastStart) {
239 fZoomedEventList.set(lastIndex, event);
9597a3b5
PT
240 } else if (start < fZoomedEventList.get(0).getTime()) {
241 fZoomedEventList.clear();
242 fZoomedEventList.add(event);
0b02f22a 243 }
cb982e03
PT
244 if (event instanceof NullTimeEvent) {
245 /* A NullTimeEvent should not affect the entry bounds */
246 return;
247 }
0b02f22a
PT
248 if (fStartTime == SWT.DEFAULT || start < fStartTime) {
249 fStartTime = start;
250 }
251 if (fEndTime == SWT.DEFAULT || end > fEndTime) {
252 fEndTime = end;
253 }
254 }
255
a3188982 256 /**
9ba941e9
PT
257 * Add a child entry to this one. If a comparator was previously set with
258 * {@link #sortChildren(Comparator)}, the entry will be inserted in its
259 * sort-order position. Otherwise it will be added to the end of the list.
a3188982
PT
260 *
261 * @param child
262 * The child entry
a3188982 263 */
f8f46a52 264 public synchronized void addChild(@NonNull TimeGraphEntry child) {
9ba941e9 265 if (fComparator == null) {
7c094b3e 266 addChild(fChildren.size(), child);
9ba941e9
PT
267 } else {
268 int i;
269 for (i = 0; i < fChildren.size(); i++) {
270 ITimeGraphEntry entry = fChildren.get(i);
271 if (fComparator.compare(child, entry) < 0) {
272 break;
273 }
274 }
7c094b3e 275 addChild(i, child);
9ba941e9 276 }
a3188982
PT
277 }
278
279 /**
280 * Add a child entry to this one at the specified position
281 *
282 * @param index
283 * Index at which the specified entry is to be inserted
284 * @param child
285 * The child entry
f8f46a52 286 * @since 2.0
a3188982 287 */
f8f46a52 288 public synchronized void addChild(int index, @NonNull TimeGraphEntry child) {
7c094b3e
PT
289 if (child.getParent() == this) {
290 return;
291 }
292 if (child.getParent() != null) {
293 child.getParent().removeChild(child);
294 }
f8f46a52 295 child.setParent(this);
a3188982
PT
296 fChildren.add(index, child);
297 }
298
3553c912
PT
299 /**
300 * Remove a child entry from this one.
301 *
302 * @param child
303 * The child entry
304 * @since 2.0
305 */
306 public synchronized void removeChild(@NonNull TimeGraphEntry child) {
7c094b3e
PT
307 if (child.getParent() == this) {
308 child.setParent(null);
309 }
3553c912
PT
310 fChildren.remove(child);
311 }
312
9ba941e9
PT
313 /**
314 * Sort the children of this entry using the provided comparator. Subsequent
f8f46a52 315 * calls to {@link #addChild(TimeGraphEntry)} will use this comparator to
9ba941e9
PT
316 * maintain the sort order.
317 *
318 * @param comparator
319 * The entry comparator
9ba941e9
PT
320 */
321 public synchronized void sortChildren(Comparator<ITimeGraphEntry> comparator) {
322 fComparator = comparator;
323 if (comparator == null) {
324 return;
325 }
f8f46a52 326 @NonNull TimeGraphEntry[] array = fChildren.toArray(new @NonNull TimeGraphEntry[0]);
9ba941e9
PT
327 Arrays.sort(array, comparator);
328 fChildren.clear();
329 fChildren.addAll(Arrays.asList(array));
330 }
331
b1b156f3
PT
332 @Override
333 public String toString() {
334 return getClass().getSimpleName() + '(' + fName + ')';
335 }
336
36299425
JCK
337 /**
338 * @since 2.0
339 */
340 @Override
341 public boolean matches(@NonNull Pattern pattern) {
342 // Default implementation
343 return pattern.matcher(fName).find();
344 }
345
4999a196 346}
This page took 0.105769 seconds and 5 git commands to generate.