tmf: Drop generics from ITmfTrace and TmfExperiment
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / views / histogram / HistogramView.java
1 /*******************************************************************************
2 * Copyright (c) 2009, 2010, 2011, 2012 Ericsson
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 * William Bourque - Initial API and implementation
11 * Yuriy Vashchuk - GUI reorganisation, simplification and some related code improvements.
12 * Yuriy Vashchuk - Histograms optimisation.
13 * Yuriy Vashchuk - Histogram Canvas Heritage correction
14 * Francois Chouinard - Cleanup and refactoring
15 * Francois Chouinard - Moved from LTTng to TMF
16 *******************************************************************************/
17
18 package org.eclipse.linuxtools.tmf.ui.views.histogram;
19
20 import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
21 import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
22 import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
23 import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
24 import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest.ExecutionType;
25 import org.eclipse.linuxtools.tmf.core.request.TmfDataRequest;
26 import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentRangeUpdatedSignal;
27 import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentSelectedSignal;
28 import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentUpdatedSignal;
29 import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal;
30 import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
31 import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager;
32 import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal;
33 import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment;
34 import org.eclipse.linuxtools.tmf.ui.views.TmfView;
35 import org.eclipse.swt.SWT;
36 import org.eclipse.swt.layout.GridData;
37 import org.eclipse.swt.layout.GridLayout;
38 import org.eclipse.swt.widgets.Composite;
39
40 /**
41 * The purpose of this view is to provide graphical time distribution statistics about the experiment/trace events.
42 * <p>
43 * The view is composed of two histograms and two controls:
44 * <ul>
45 * <li>an event distribution histogram for the whole experiment;
46 * <li>an event distribution histogram for current time window (window span);
47 * <li>the timestamp of the currently selected event;
48 * <li>the window span (size of the time window of the smaller histogram).
49 * </ul>
50 * The histograms x-axis show their respective time range.
51 *
52 * @version 1.0
53 * @author Francois Chouinard
54 */
55 public class HistogramView extends TmfView {
56
57 // ------------------------------------------------------------------------
58 // Constants
59 // ------------------------------------------------------------------------
60
61 /**
62 * The view ID as defined in plugin.xml
63 */
64 public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.histogram"; //$NON-NLS-1$
65
66 /**
67 * The initial window span (in nanoseconds)
68 */
69 public static final long INITIAL_WINDOW_SPAN = (1L * 100 * 1000 * 1000); // .1sec
70
71 // Time scale
72 private final byte TIME_SCALE = Histogram.TIME_SCALE;
73
74 // ------------------------------------------------------------------------
75 // Attributes
76 // ------------------------------------------------------------------------
77
78 // Parent widget
79 private Composite fParent;
80
81 // The current experiment
82 private TmfExperiment fCurrentExperiment;
83
84 // Current timestamp/time window
85 private long fExperimentStartTime;
86 private long fExperimentEndTime;
87 private long fWindowStartTime;
88 private long fWindowEndTime;
89 private long fWindowSpan = INITIAL_WINDOW_SPAN;
90 private long fCurrentTimestamp;
91
92 // Time controls
93 private HistogramTextControl fCurrentEventTimeControl;
94 private HistogramTextControl fTimeSpanControl;
95
96 // Histogram/request for the full trace range
97 private static FullTraceHistogram fFullTraceHistogram;
98 private HistogramRequest fFullTraceRequest;
99
100 // Histogram/request for the selected time range
101 private static TimeRangeHistogram fTimeRangeHistogram;
102 private HistogramRequest fTimeRangeRequest;
103
104 // ------------------------------------------------------------------------
105 // Constructor
106 // ------------------------------------------------------------------------
107
108 /**
109 * Default constructor
110 */
111 public HistogramView() {
112 super(ID);
113 }
114
115 @Override
116 public void dispose() {
117 if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) {
118 fTimeRangeRequest.cancel();
119 }
120 if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) {
121 fFullTraceRequest.cancel();
122 }
123 fFullTraceHistogram.dispose();
124 fTimeRangeHistogram.dispose();
125 super.dispose();
126 }
127
128 // ------------------------------------------------------------------------
129 // TmfView
130 // ------------------------------------------------------------------------
131
132 @Override
133 public void createPartControl(Composite parent) {
134
135 fParent = parent;
136
137 // Control labels
138 final String currentEventLabel = Messages.HistogramView_currentEventLabel;
139 final String windowSpanLabel = Messages.HistogramView_windowSpanLabel;
140
141 // --------------------------------------------------------------------
142 // Set the HistogramView layout
143 // --------------------------------------------------------------------
144
145 Composite viewComposite = new Composite(fParent, SWT.FILL);
146 GridLayout gridLayout = new GridLayout();
147 gridLayout.numColumns = 2;
148 gridLayout.horizontalSpacing = 5;
149 gridLayout.verticalSpacing = 0;
150 gridLayout.marginHeight = 0;
151 gridLayout.marginWidth = 0;
152 viewComposite.setLayout(gridLayout);
153
154 // Use all available space
155 GridData gridData = new GridData();
156 gridData.horizontalAlignment = SWT.FILL;
157 gridData.verticalAlignment = SWT.FILL;
158 gridData.grabExcessHorizontalSpace = true;
159 viewComposite.setLayoutData(gridData);
160
161 // --------------------------------------------------------------------
162 // Time controls
163 // --------------------------------------------------------------------
164
165 Composite controlsComposite = new Composite(viewComposite, SWT.FILL);
166 gridLayout = new GridLayout();
167 gridLayout.numColumns = 2;
168 gridLayout.marginHeight = 0;
169 gridLayout.marginWidth = 0;
170 gridLayout.horizontalSpacing = 5;
171 gridLayout.verticalSpacing = 0;
172 gridLayout.makeColumnsEqualWidth = true;
173 gridLayout.marginLeft = 5;
174 gridLayout.marginRight = 5;
175 controlsComposite.setLayout(gridLayout);
176
177 // Current event time control
178 gridData = new GridData();
179 gridData.horizontalAlignment = SWT.CENTER;
180 gridData.verticalAlignment = SWT.CENTER;
181 fCurrentEventTimeControl = new HistogramCurrentTimeControl(this, controlsComposite, SWT.BORDER, SWT.NONE,
182 currentEventLabel, HistogramUtils.nanosecondsToString(0L));
183 fCurrentEventTimeControl.setLayoutData(gridData);
184
185 // Window span time control
186 gridData = new GridData();
187 gridData.horizontalAlignment = SWT.CENTER;
188 gridData.verticalAlignment = SWT.CENTER;
189 fTimeSpanControl = new HistogramTimeRangeControl(this, controlsComposite, SWT.BORDER, SWT.NONE,
190 windowSpanLabel, HistogramUtils.nanosecondsToString(0L));
191 fTimeSpanControl.setLayoutData(gridData);
192
193 // --------------------------------------------------------------------
194 // Time range histogram
195 // --------------------------------------------------------------------
196
197 Composite timeRangeComposite = new Composite(viewComposite, SWT.FILL);
198 gridLayout = new GridLayout();
199 gridLayout.numColumns = 1;
200 gridLayout.marginHeight = 0;
201 gridLayout.marginWidth = 0;
202 gridLayout.marginTop = 5;
203 gridLayout.horizontalSpacing = 0;
204 gridLayout.verticalSpacing = 0;
205 gridLayout.marginLeft = 5;
206 gridLayout.marginRight = 5;
207 timeRangeComposite.setLayout(gridLayout);
208
209 // Use remaining horizontal space
210 gridData = new GridData();
211 gridData.horizontalAlignment = SWT.FILL;
212 gridData.verticalAlignment = SWT.FILL;
213 gridData.grabExcessHorizontalSpace = true;
214 timeRangeComposite.setLayoutData(gridData);
215
216 // Histogram
217 fTimeRangeHistogram = new TimeRangeHistogram(this, timeRangeComposite);
218
219 // --------------------------------------------------------------------
220 // Full range histogram
221 // --------------------------------------------------------------------
222
223 Composite fullRangeComposite = new Composite(viewComposite, SWT.FILL);
224 gridLayout = new GridLayout();
225 gridLayout.numColumns = 1;
226 gridLayout.marginHeight = 0;
227 gridLayout.marginWidth = 0;
228 gridLayout.marginTop = 5;
229 gridLayout.horizontalSpacing = 0;
230 gridLayout.verticalSpacing = 0;
231 gridLayout.marginLeft = 5;
232 gridLayout.marginRight = 5;
233 fullRangeComposite.setLayout(gridLayout);
234
235 // Use remaining horizontal space
236 gridData = new GridData();
237 gridData.horizontalAlignment = SWT.FILL;
238 gridData.verticalAlignment = SWT.FILL;
239 gridData.horizontalSpan = 2;
240 gridData.grabExcessHorizontalSpace = true;
241 fullRangeComposite.setLayoutData(gridData);
242
243 // Histogram
244 fFullTraceHistogram = new FullTraceHistogram(this, fullRangeComposite);
245
246 // Load the experiment if present
247 fCurrentExperiment = TmfExperiment.getCurrentExperiment();
248 if (fCurrentExperiment != null) {
249 loadExperiment();
250 }
251 }
252
253 @Override
254 public void setFocus() {
255 TmfExperiment experiment = TmfExperiment.getCurrentExperiment();
256 if ((experiment != null) && (experiment != fCurrentExperiment)) {
257 fCurrentExperiment = experiment;
258 initializeHistograms();
259 }
260 fParent.redraw();
261 }
262
263 // ------------------------------------------------------------------------
264 // Accessors
265 // ------------------------------------------------------------------------
266
267 /**
268 * Returns the time range of the current selected window (base on default time scale).
269 *
270 * @return the time range of current selected window.
271 */
272 public TmfTimeRange getTimeRange() {
273 return new TmfTimeRange(new TmfTimestamp(fWindowStartTime, TIME_SCALE), new TmfTimestamp(fWindowEndTime,
274 TIME_SCALE));
275 }
276
277 // ------------------------------------------------------------------------
278 // Operations
279 // ------------------------------------------------------------------------
280
281 /**
282 * Broadcast TmfSignal about new current time value.
283 * @param newTime the new current time.
284 */
285 public void updateCurrentEventTime(long newTime) {
286 if (fCurrentExperiment != null) {
287 TmfTimeRange timeRange = new TmfTimeRange(new TmfTimestamp(newTime, TIME_SCALE), TmfTimestamp.BIG_CRUNCH);
288 HistogramRequest request = new HistogramRequest(fTimeRangeHistogram.getDataModel(), timeRange, 0, 1, 0, ExecutionType.FOREGROUND) {
289 @Override
290 public void handleData(ITmfEvent event) {
291 if (event != null) {
292 TmfTimeSynchSignal signal = new TmfTimeSynchSignal(this, event.getTimestamp());
293 TmfSignalManager.dispatchSignal(signal);
294 }
295 }
296 };
297 fCurrentExperiment.sendRequest(request);
298 }
299 }
300
301 /**
302 * Broadcast TmfSignal about new selected time range.
303 * @param startTime the new start time
304 * @param endTime the new end time
305 */
306 public void updateTimeRange(long startTime, long endTime) {
307 if (fCurrentExperiment != null) {
308 // Build the new time range; keep the current time
309 TmfTimeRange timeRange = new TmfTimeRange(new TmfTimestamp(startTime, TIME_SCALE), new TmfTimestamp(
310 endTime, TIME_SCALE));
311 TmfTimestamp currentTime = new TmfTimestamp(fCurrentTimestamp, TIME_SCALE);
312
313 fTimeSpanControl.setValue(endTime - startTime);
314
315 // Send the FW signal
316 TmfRangeSynchSignal signal = new TmfRangeSynchSignal(this, timeRange, currentTime);
317 TmfSignalManager.dispatchSignal(signal);
318 }
319 }
320
321 /**
322 * Broadcast TmfSignal about new selected time range.
323 * @param newDuration new duration (relative to current start time)
324 */
325 public synchronized void updateTimeRange(long newDuration) {
326 if (fCurrentExperiment != null) {
327 long delta = newDuration - fWindowSpan;
328 long newStartTime = fWindowStartTime + (delta / 2);
329 setNewRange(newStartTime, newDuration);
330 }
331 }
332
333 private void setNewRange(long startTime, long duration) {
334 if (startTime < fExperimentStartTime) {
335 startTime = fExperimentStartTime;
336 }
337
338 long endTime = startTime + duration;
339 if( endTime < startTime ) {
340 endTime = fExperimentEndTime;
341 startTime = fExperimentStartTime;
342 }
343 if (endTime > fExperimentEndTime) {
344 endTime = fExperimentEndTime;
345 if ((endTime - duration) > fExperimentStartTime) {
346 startTime = endTime - duration;
347 } else {
348 startTime = fExperimentStartTime;
349 }
350 }
351 updateTimeRange(startTime, endTime);
352 }
353
354 // ------------------------------------------------------------------------
355 // Signal handlers
356 // ------------------------------------------------------------------------
357
358 /**
359 * Handles experiment selected signal. Loads histogram if new experiment time range is not
360 * equal <code>TmfTimeRange.NULL_RANGE</code>
361 * @param signal the experiment selected signal
362 */
363 @TmfSignalHandler
364 public void experimentSelected(TmfExperimentSelectedSignal signal) {
365 assert (signal != null);
366 fCurrentExperiment = signal.getExperiment();
367 loadExperiment();
368 }
369
370 private void loadExperiment() {
371 initializeHistograms();
372 fParent.redraw();
373 }
374
375 /**
376 * Handles experiment range updated signal. Extends histogram according to the new time range. If a
377 * HistogramRequest is already ongoing, it will be cancelled and a new request with the new range
378 * will be issued.
379 *
380 * @param signal the experiment range updated signal
381 */
382 @TmfSignalHandler
383 public void experimentRangeUpdated(TmfExperimentRangeUpdatedSignal signal) {
384
385 if (signal.getExperiment() != fCurrentExperiment) {
386 return;
387 }
388
389 boolean drawTimeRangeHistogram = fExperimentStartTime == 0;
390 TmfTimeRange fullRange = signal.getRange();
391
392 fExperimentStartTime = fullRange.getStartTime().normalize(0, -9).getValue();
393 fExperimentEndTime = fullRange.getEndTime().normalize(0, -9).getValue();
394
395 fFullTraceHistogram.setFullRange(fExperimentStartTime, fExperimentEndTime);
396 fTimeRangeHistogram.setFullRange(fExperimentStartTime, fExperimentEndTime);
397
398 if (drawTimeRangeHistogram) {
399 fCurrentTimestamp = fExperimentStartTime;
400 fCurrentEventTimeControl.setValue(fCurrentTimestamp);
401 fFullTraceHistogram.setTimeRange(fExperimentStartTime, INITIAL_WINDOW_SPAN);
402 fTimeRangeHistogram.setTimeRange(fExperimentStartTime, INITIAL_WINDOW_SPAN);
403 sendTimeRangeRequest(fExperimentStartTime, fExperimentStartTime + INITIAL_WINDOW_SPAN);
404 }
405
406 sendFullRangeRequest(fullRange);
407 }
408
409 /**
410 * Handles the experiment updated signal. Used to update time limits (start and end time)
411 * @param signal the experiment updated signal
412 */
413 @TmfSignalHandler
414 public void experimentUpdated(TmfExperimentUpdatedSignal signal) {
415 if (signal.getExperiment() != fCurrentExperiment) {
416 return;
417 }
418 TmfTimeRange fullRange = signal.getExperiment().getTimeRange();
419 fExperimentStartTime = fullRange.getStartTime().normalize(0, -9).getValue();
420 fExperimentEndTime = fullRange.getEndTime().normalize(0, -9).getValue();
421
422 fFullTraceHistogram.setFullRange(fExperimentStartTime, fExperimentEndTime);
423 fTimeRangeHistogram.setFullRange(fExperimentStartTime, fExperimentEndTime);
424 }
425
426 /**
427 * Handles the current time updated signal. Sets the current time in the time range
428 * histogram as well as the full histogram.
429 *
430 * @param signal the signal to process
431 */
432 @TmfSignalHandler
433 public void currentTimeUpdated(TmfTimeSynchSignal signal) {
434 // Because this can't happen :-)
435 assert (signal != null);
436
437 // Update the selected event time
438 ITmfTimestamp currentTime = signal.getCurrentTime();
439 fCurrentTimestamp = currentTime.normalize(0, -9).getValue();
440
441 // Notify the relevant widgets
442 fFullTraceHistogram.setCurrentEvent(fCurrentTimestamp);
443 fTimeRangeHistogram.setCurrentEvent(fCurrentTimestamp);
444 fCurrentEventTimeControl.setValue(fCurrentTimestamp);
445 }
446
447 /**
448 * Updates the current time range in the time range histogram and full range histogram.
449 * @param signal the signal to process
450 */
451 @TmfSignalHandler
452 public void timeRangeUpdated(TmfRangeSynchSignal signal) {
453 // Because this can't happen :-)
454 assert (signal != null);
455
456 if (fCurrentExperiment != null) {
457 // Update the time range
458 fWindowStartTime = signal.getCurrentRange().getStartTime().normalize(0, -9).getValue();
459 fWindowEndTime = signal.getCurrentRange().getEndTime().normalize(0, -9).getValue();
460 fWindowSpan = fWindowEndTime - fWindowStartTime;
461
462 // Notify the relevant widgets
463 sendTimeRangeRequest(fWindowStartTime, fWindowEndTime);
464 fFullTraceHistogram.setTimeRange(fWindowStartTime, fWindowSpan);
465 fTimeSpanControl.setValue(fWindowSpan);
466 }
467 }
468
469 // ------------------------------------------------------------------------
470 // Helper functions
471 // ------------------------------------------------------------------------
472
473 private void initializeHistograms() {
474 TmfTimeRange fullRange = updateExperimentTimeRange(fCurrentExperiment);
475
476 fTimeRangeHistogram.clear();
477 fTimeRangeHistogram.setFullRange(fExperimentStartTime, fExperimentEndTime);
478 fTimeRangeHistogram.setTimeRange(fExperimentStartTime, INITIAL_WINDOW_SPAN);
479 fTimeRangeHistogram.setCurrentEvent(fExperimentStartTime);
480
481 fFullTraceHistogram.clear();
482 fFullTraceHistogram.setFullRange(fExperimentStartTime, fExperimentEndTime);
483 fFullTraceHistogram.setTimeRange(fExperimentStartTime, INITIAL_WINDOW_SPAN);
484 fFullTraceHistogram.setCurrentEvent(fExperimentStartTime);
485
486 fWindowStartTime = fExperimentStartTime;
487 fWindowSpan = INITIAL_WINDOW_SPAN;
488 fWindowEndTime = fWindowStartTime + fWindowSpan;
489
490 fCurrentEventTimeControl.setValue(fExperimentStartTime);
491 fTimeSpanControl.setValue(fWindowSpan);
492
493 if (!fullRange.equals(TmfTimeRange.NULL_RANGE)) {
494 sendTimeRangeRequest(fExperimentStartTime, fExperimentStartTime + fWindowSpan);
495 sendFullRangeRequest(fullRange);
496 }
497 }
498
499 private TmfTimeRange updateExperimentTimeRange(TmfExperiment experiment) {
500 fExperimentStartTime = 0;
501 fExperimentEndTime = 0;
502 fCurrentTimestamp = 0;
503
504 TmfTimeRange timeRange = fCurrentExperiment.getTimeRange();
505 if (!timeRange.equals(TmfTimeRange.NULL_RANGE)) {
506 fExperimentStartTime = timeRange.getStartTime().normalize(0, -9).getValue();
507 fExperimentEndTime = timeRange.getEndTime().normalize(0, -9).getValue();
508 fCurrentTimestamp = fExperimentStartTime;
509 }
510 return timeRange;
511 }
512
513 private void sendTimeRangeRequest(long startTime, long endTime) {
514 if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) {
515 fTimeRangeRequest.cancel();
516 }
517 TmfTimestamp startTS = new TmfTimestamp(startTime, TIME_SCALE);
518 TmfTimestamp endTS = new TmfTimestamp(endTime, TIME_SCALE);
519 TmfTimeRange timeRange = new TmfTimeRange(startTS, endTS);
520
521 fTimeRangeHistogram.clear();
522 fTimeRangeHistogram.setTimeRange(startTime, endTime - startTime);
523
524 int cacheSize = fCurrentExperiment.getCacheSize();
525 fTimeRangeRequest = new HistogramRequest(fTimeRangeHistogram.getDataModel(), timeRange, 0, TmfDataRequest.ALL_DATA, cacheSize, ExecutionType.FOREGROUND);
526 fCurrentExperiment.sendRequest(fTimeRangeRequest);
527 }
528
529 private void sendFullRangeRequest(TmfTimeRange fullRange) {
530 if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) {
531 fFullTraceRequest.cancel();
532 }
533 int cacheSize = fCurrentExperiment.getCacheSize();
534 fFullTraceRequest = new HistogramRequest(fFullTraceHistogram.getDataModel(), fullRange, (int) fFullTraceHistogram.fDataModel.getNbEvents(),
535 TmfDataRequest.ALL_DATA, cacheSize, ExecutionType.BACKGROUND);
536 fCurrentExperiment.sendRequest(fFullTraceRequest);
537 }
538
539 }
This page took 0.044421 seconds and 5 git commands to generate.