Commit | Line | Data |
---|---|---|
03c96217 BH |
1 | /****************************************************************************** |
2 | * Copyright (c) 2015 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 | * France Lapointe Nguyen - Initial API and implementation | |
11 | * Bernd Hufmann - Extracted abstract class from LatencyScatterGraphViewer | |
12 | *******************************************************************************/ | |
13 | ||
14 | package org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore; | |
15 | ||
16 | import java.util.ArrayList; | |
17 | import java.util.Collection; | |
18 | import java.util.Collections; | |
19 | import java.util.Iterator; | |
20 | import java.util.List; | |
21 | ||
22 | import org.eclipse.core.runtime.IProgressMonitor; | |
23 | import org.eclipse.core.runtime.IStatus; | |
24 | import org.eclipse.core.runtime.Status; | |
25 | import org.eclipse.core.runtime.jobs.Job; | |
26 | import org.eclipse.jdt.annotation.Nullable; | |
27 | import org.eclipse.swt.graphics.Point; | |
28 | import org.eclipse.swt.widgets.Composite; | |
29 | import org.eclipse.swt.widgets.Display; | |
30 | import org.eclipse.tracecompass.analysis.timing.core.segmentstore.AbstractSegmentStoreAnalysisModule; | |
31 | import org.eclipse.tracecompass.analysis.timing.core.segmentstore.IAnalysisProgressListener; | |
32 | import org.eclipse.tracecompass.common.core.NonNullUtils; | |
33 | import org.eclipse.tracecompass.internal.analysis.timing.ui.Activator; | |
34 | import org.eclipse.tracecompass.internal.analysis.timing.ui.views.segmentstore.Messages; | |
35 | import org.eclipse.tracecompass.segmentstore.core.ISegment; | |
36 | import org.eclipse.tracecompass.segmentstore.core.ISegmentStore; | |
37 | import org.eclipse.tracecompass.segmentstore.core.SegmentComparators; | |
38 | import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; | |
39 | import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; | |
40 | import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal; | |
41 | import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; | |
42 | import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; | |
43 | import org.eclipse.tracecompass.tmf.core.signal.TmfWindowRangeUpdatedSignal; | |
44 | import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; | |
45 | import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; | |
46 | import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; | |
47 | import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; | |
48 | import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentInfo; | |
49 | import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentSignal; | |
50 | import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.TmfChartTimeStampFormat; | |
51 | import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.linecharts.TmfCommonXLineChartViewer; | |
52 | import org.swtchart.Chart; | |
53 | import org.swtchart.IAxis; | |
54 | import org.swtchart.IAxisTick; | |
55 | import org.swtchart.ILineSeries; | |
56 | import org.swtchart.ILineSeries.PlotSymbolType; | |
57 | import org.swtchart.ISeries.SeriesType; | |
58 | import org.swtchart.ISeriesSet; | |
59 | import org.swtchart.LineStyle; | |
60 | import org.swtchart.Range; | |
61 | ||
62 | /** | |
63 | * Displays the segment store analysis data in a scatter graph | |
64 | * | |
65 | * @author France Lapointe Nguyen | |
66 | * @author Matthew Khouzam - reduced memory usage | |
67 | * @since 2.0 | |
68 | */ | |
69 | public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXLineChartViewer { | |
03c96217 BH |
70 | |
71 | private final class CompactingSegmentStoreQuery extends Job { | |
72 | private static final long MAX_POINTS = 1000; | |
73 | private final TmfTimeRange fCurrentRange; | |
74 | ||
75 | private CompactingSegmentStoreQuery(TmfTimeRange currentRange) { | |
76 | super(Messages.SegmentStoreScatterGraphViewer_compactTitle); | |
77 | fCurrentRange = currentRange; | |
78 | } | |
79 | ||
80 | @Override | |
81 | protected IStatus run(@Nullable IProgressMonitor monitor) { | |
82 | final IProgressMonitor statusMonitor = monitor; | |
83 | if (statusMonitor == null) { | |
84 | return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Monitor is null"); //$NON-NLS-1$ | |
85 | } | |
86 | ||
87 | AbstractSegmentStoreAnalysisModule module = getAnalysisModule(); | |
88 | final long startTimeInNanos = getTimeInNanos(fCurrentRange.getStartTime()); | |
89 | final long endTimeInNanos = getTimeInNanos(fCurrentRange.getEndTime()); | |
90 | if (module == null) { | |
91 | setWindowRange(startTimeInNanos, endTimeInNanos); | |
df2597e0 | 92 | redraw(statusMonitor, startTimeInNanos, startTimeInNanos, Collections.EMPTY_LIST); |
03c96217 BH |
93 | return new Status(IStatus.WARNING, Activator.PLUGIN_ID, "Analysis module not available"); //$NON-NLS-1$ |
94 | } | |
95 | ||
96 | final ISegmentStore<ISegment> results = module.getResults(); | |
97 | if (results == null) { | |
98 | setWindowRange(startTimeInNanos, endTimeInNanos); | |
df2597e0 | 99 | redraw(statusMonitor, startTimeInNanos, startTimeInNanos, Collections.EMPTY_LIST); |
03c96217 BH |
100 | return new Status(IStatus.INFO, Activator.PLUGIN_ID, "Analysis module does not have results"); //$NON-NLS-1$ |
101 | } | |
102 | ||
103 | final long startTime = fCurrentRange.getStartTime().getValue(); | |
104 | final long endTime = fCurrentRange.getEndTime().getValue(); | |
105 | fPixelStart = startTime; | |
106 | fPixelSize = (endTime - startTime) / MAX_POINTS; | |
107 | final Iterable<ISegment> intersectingElements = results.getIntersectingElements(startTime, endTime); | |
108 | ||
109 | final List<ISegment> list = convertIterableToList(intersectingElements, statusMonitor); | |
110 | final List<ISegment> displayData = (!list.isEmpty()) ? compactList(startTime, list, statusMonitor) : list; | |
111 | ||
112 | setWindowRange(startTimeInNanos, endTimeInNanos); | |
113 | redraw(statusMonitor, startTime, endTime, displayData); | |
114 | ||
115 | if (statusMonitor.isCanceled()) { | |
116 | return NonNullUtils.checkNotNull(Status.CANCEL_STATUS); | |
117 | } | |
118 | return NonNullUtils.checkNotNull(Status.OK_STATUS); | |
119 | ||
120 | } | |
121 | ||
122 | private void redraw(final IProgressMonitor statusMonitor, final long startTime, final long endTime, final List<ISegment> displayData) { | |
123 | fDisplayData = displayData; | |
124 | Display.getDefault().asyncExec(new Runnable() { | |
125 | ||
126 | @Override | |
127 | public void run() { | |
128 | updateData(startTime, endTime, displayData.size(), statusMonitor); | |
129 | } | |
130 | }); | |
131 | } | |
132 | ||
133 | private List<ISegment> compactList(final long startTime, final List<ISegment> listToCompact, final IProgressMonitor statusMonitor) { | |
134 | List<ISegment> displayData = new ArrayList<>(); | |
135 | ISegment last = listToCompact.get(0); | |
136 | if (last.getStart() >= startTime) { | |
137 | displayData.add(last); | |
138 | } | |
139 | for (ISegment next : listToCompact) { | |
140 | if (next.getStart() < startTime) { | |
141 | continue; | |
142 | } | |
143 | if (statusMonitor.isCanceled()) { | |
df2597e0 | 144 | return Collections.EMPTY_LIST; |
03c96217 BH |
145 | } |
146 | if (!overlaps(last, next)) { | |
147 | displayData.add(next); | |
148 | last = next; | |
149 | } | |
150 | } | |
151 | return displayData; | |
152 | } | |
153 | ||
154 | private List<ISegment> convertIterableToList(final Iterable<ISegment> iterable, final IProgressMonitor statusMonitor) { | |
155 | final List<ISegment> list = new ArrayList<>(); | |
156 | for (ISegment seg : iterable) { | |
157 | if (statusMonitor.isCanceled()) { | |
df2597e0 | 158 | return Collections.EMPTY_LIST; |
03c96217 BH |
159 | } |
160 | list.add(seg); | |
161 | } | |
162 | Collections.sort(list, SegmentComparators.INTERVAL_START_COMPARATOR); | |
163 | return list; | |
164 | } | |
165 | ||
166 | private boolean overlaps(ISegment last, ISegment next) { | |
167 | long timePerPix = fPixelSize; | |
168 | final long start = last.getStart(); | |
169 | final long pixelStart = fPixelStart; | |
170 | final long pixelDuration = start - pixelStart; | |
171 | long startPixBoundL = pixelDuration / timePerPix * timePerPix + pixelStart; | |
172 | long startPixBoundR = startPixBoundL + timePerPix; | |
173 | final long currentStart = next.getStart(); | |
174 | if (currentStart >= startPixBoundL && currentStart <= startPixBoundR) { | |
175 | long length = last.getLength(); | |
176 | long lengthNext = next.getLength(); | |
177 | long lengthLow = length / timePerPix * timePerPix; | |
178 | long lengthHigh = lengthLow + timePerPix; | |
179 | return (lengthNext >= lengthLow && lengthNext <= lengthHigh); | |
180 | } | |
181 | return false; | |
182 | } | |
183 | } | |
184 | ||
185 | // ------------------------------------------------------------------------ | |
186 | // Attributes | |
187 | // ------------------------------------------------------------------------ | |
188 | ||
189 | /** | |
190 | * Listener to update the model with the semgent store analysis results | |
191 | * once the analysis is fully completed | |
192 | */ | |
193 | private final class AnalysisProgressListener implements IAnalysisProgressListener { | |
194 | ||
195 | @Override | |
196 | public void onComplete(AbstractSegmentStoreAnalysisModule activeAnalysis, ISegmentStore<ISegment> results) { | |
197 | // Only update the model if trace that was analyzed is active trace | |
198 | if (activeAnalysis.equals(getAnalysisModule())) { | |
199 | updateModel(results); | |
200 | updateRange(TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange()); | |
201 | } | |
202 | } | |
203 | } | |
204 | ||
205 | private long fPixelSize = -1; | |
206 | ||
207 | private long fPixelStart = 0; | |
208 | /** | |
209 | * Data to display | |
210 | */ | |
df2597e0 | 211 | private Collection<ISegment> fDisplayData = Collections.EMPTY_LIST; |
03c96217 BH |
212 | |
213 | /** | |
214 | * Analysis completion listener | |
215 | */ | |
216 | private AnalysisProgressListener fListener; | |
217 | ||
218 | /** | |
219 | * Current analysis module | |
220 | */ | |
221 | private @Nullable AbstractSegmentStoreAnalysisModule fAnalysisModule; | |
222 | ||
223 | private @Nullable Job fCompactingJob; | |
224 | ||
225 | // ------------------------------------------------------------------------ | |
226 | // Constructor | |
227 | // ------------------------------------------------------------------------ | |
228 | ||
229 | /** | |
230 | * Constructor | |
231 | * | |
232 | * @param parent | |
233 | * parent composite | |
234 | * @param title | |
235 | * name of the graph | |
236 | * @param xLabel | |
237 | * name of the x axis | |
238 | * @param yLabel | |
239 | * name of the y axis | |
240 | */ | |
241 | public AbstractSegmentStoreScatterGraphViewer(Composite parent, String title, String xLabel, String yLabel) { | |
242 | super(parent, title, xLabel, yLabel); | |
a2de198a | 243 | setTooltipProvider(new SegmentStoreScatterGraphTooltipProvider(this)); |
03c96217 BH |
244 | fListener = new AnalysisProgressListener(); |
245 | ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace(); | |
246 | initializeModule(trace); | |
247 | getSwtChart().getLegend().setVisible(false); | |
248 | } | |
249 | ||
250 | private final void initializeModule(@Nullable ITmfTrace trace) { | |
251 | if (trace != null) { | |
252 | final AbstractSegmentStoreAnalysisModule analysisModuleOfClass = getSegmentStoreAnalysisModule(trace); | |
253 | if (analysisModuleOfClass != null) { | |
254 | analysisModuleOfClass.addListener(fListener); | |
255 | setData(analysisModuleOfClass); | |
256 | updateRange(TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange()); | |
257 | } | |
258 | } | |
259 | } | |
260 | ||
261 | // ------------------------------------------------------------------------ | |
262 | // Operations | |
263 | // ------------------------------------------------------------------------ | |
264 | ||
265 | /** | |
266 | * Update the data in the graph | |
267 | * | |
268 | * @param dataInput | |
269 | * new model | |
270 | */ | |
271 | public void updateModel(@Nullable ISegmentStore<ISegment> dataInput) { | |
272 | // Update new window range | |
273 | TmfTimeRange currentRange = TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange(); | |
274 | long currentStart = getTimeInNanos(currentRange.getStartTime()); | |
275 | long currentEnd = getTimeInNanos(currentRange.getEndTime()); | |
276 | if (dataInput == null) { | |
277 | if (!getDisplay().isDisposed()) { | |
278 | Display.getDefault().syncExec(new Runnable() { | |
279 | @Override | |
280 | public void run() { | |
281 | clearContent(); | |
282 | } | |
283 | }); | |
284 | } | |
df2597e0 | 285 | fDisplayData = Collections.EMPTY_LIST; |
03c96217 BH |
286 | } else { |
287 | Collection<ISegment> elements = (Collection<ISegment>) dataInput.getIntersectingElements(currentStart, currentEnd); | |
288 | // getIntersectingElements can return an unsorted iterable, make | |
289 | // sure our collection is sorted | |
290 | ArrayList<ISegment> list = new ArrayList<>(elements); | |
291 | Collections.sort(list, SegmentComparators.INTERVAL_START_COMPARATOR); | |
292 | fDisplayData = list; | |
293 | } | |
294 | setWindowRange(currentStart, currentEnd); | |
295 | updateRange(currentRange); | |
296 | } | |
297 | ||
298 | @Override | |
299 | protected void initializeDataSource() { | |
300 | ITmfTrace trace = getTrace(); | |
301 | initializeModule(trace); | |
302 | if (trace != null) { | |
303 | setData(getSegmentStoreAnalysisModule(trace)); | |
304 | } | |
305 | } | |
306 | ||
307 | @Override | |
308 | protected void updateData(final long start, final long end, int nb, @Nullable IProgressMonitor monitor) { | |
309 | // Third parameter is not used by implementation | |
310 | // Determine data that needs to be visible | |
311 | Collection<ISegment> data = fDisplayData; | |
312 | ||
313 | final int dataSize = (nb == 0) ? data.size() : nb; | |
314 | if (dataSize == 0 || end == start) { | |
315 | return; | |
316 | } | |
317 | ||
318 | final double[] xSeries = new double[dataSize]; | |
319 | final double[] ySeries = new double[dataSize]; | |
320 | // For each visible segments, add start time to x value and duration | |
321 | // for y value | |
322 | Iterator<ISegment> modelIter = data.iterator(); | |
323 | long maxTempY = 1; | |
324 | for (int i = 0; i < dataSize; i++) { | |
325 | if (modelIter.hasNext()) { | |
326 | ISegment segment = modelIter.next(); | |
327 | xSeries[i] = segment.getStart() - start; | |
328 | ySeries[i] = segment.getLength(); | |
329 | maxTempY = Math.max(maxTempY, segment.getLength()); | |
330 | } | |
331 | } | |
332 | final long maxY = maxTempY; | |
333 | setXAxis(xSeries); | |
334 | final Chart swtChart = getSwtChart(); | |
335 | if (swtChart.isDisposed() || xSeries.length < 1) { | |
336 | return; | |
337 | } | |
338 | swtChart.updateLayout(); | |
339 | setSeries(Messages.SegmentStoreScatterGraphViewer_legend, ySeries); // $NON-NLS-1$ | |
340 | final TmfChartTimeStampFormat tmfChartTimeStampFormat = new TmfChartTimeStampFormat(getTimeOffset()); | |
341 | ILineSeries series = (ILineSeries) swtChart.getSeriesSet().getSeries(Messages.SegmentStoreScatterGraphViewer_legend); | |
342 | if (series == null) { | |
343 | series = addSeries(Messages.SegmentStoreScatterGraphViewer_legend); | |
344 | } | |
345 | series.setXSeries(xSeries); | |
346 | /* Find the minimal and maximum values in this series */ | |
347 | series.setYSeries(ySeries); | |
348 | ||
349 | final IAxis xAxis = swtChart.getAxisSet().getXAxis(0); | |
350 | IAxisTick xTick = xAxis.getTick(); | |
351 | xTick.setFormat(tmfChartTimeStampFormat); | |
352 | xAxis.setRange(new Range(0.0, end - start)); | |
353 | if (maxY > 0.0) { | |
354 | swtChart.getAxisSet().getYAxis(0).setRange(new Range(0.0, maxY)); | |
355 | } | |
356 | swtChart.redraw(); | |
357 | ||
358 | if (isSendTimeAlignSignals()) { | |
359 | // The width of the chart might have changed and its | |
360 | // time axis might be misaligned with the other views | |
361 | Point viewPos = AbstractSegmentStoreScatterGraphViewer.this.getParent().getParent().toDisplay(0, 0); | |
362 | int axisPos = swtChart.toDisplay(0, 0).x + getPointAreaOffset(); | |
363 | int timeAxisOffset = axisPos - viewPos.x; | |
364 | TmfTimeViewAlignmentInfo timeAlignmentInfo = new TmfTimeViewAlignmentInfo(getControl().getShell(), viewPos, timeAxisOffset); | |
365 | TmfSignalManager.dispatchSignal(new TmfTimeViewAlignmentSignal(AbstractSegmentStoreScatterGraphViewer.this, timeAlignmentInfo, true)); | |
366 | } | |
367 | } | |
368 | ||
369 | @Override | |
370 | protected void setWindowRange(final long windowStartTime, final long windowEndTime) { | |
371 | super.setWindowRange(windowStartTime, windowEndTime); | |
372 | } | |
373 | ||
374 | @Override | |
375 | protected ILineSeries addSeries(@Nullable String seriesName) { | |
376 | ISeriesSet seriesSet = getSwtChart().getSeriesSet(); | |
377 | ILineSeries series = (ILineSeries) seriesSet.createSeries(SeriesType.LINE, seriesName); | |
378 | series.setVisible(true); | |
379 | series.enableArea(false); | |
380 | series.setLineStyle(LineStyle.NONE); | |
381 | series.setSymbolType(PlotSymbolType.DIAMOND); | |
382 | return series; | |
383 | } | |
384 | ||
385 | /** | |
386 | * Set the data into the viewer. Will update model is analysis is completed | |
387 | * or run analysis if not completed | |
388 | * | |
389 | * @param analysis | |
390 | * Segment store analysis module | |
391 | */ | |
392 | public void setData(@Nullable AbstractSegmentStoreAnalysisModule analysis) { | |
393 | if (analysis == null) { | |
394 | updateModel(null); | |
395 | return; | |
396 | } | |
397 | ISegmentStore<ISegment> results = analysis.getResults(); | |
398 | // If results are not null, then analysis is completed and model can be | |
399 | // updated | |
400 | if (results != null) { | |
401 | updateModel(results); | |
402 | setAnalysisModule(analysis); | |
403 | return; | |
404 | } | |
405 | updateModel(null); | |
406 | analysis.addListener(fListener); | |
407 | analysis.schedule(); | |
408 | setAnalysisModule(analysis); | |
409 | } | |
410 | ||
411 | /** | |
412 | * Returns the segment store analysis module | |
df2597e0 | 413 | * |
03c96217 BH |
414 | * @param trace |
415 | * The trace to consider | |
416 | * @return the analysis module | |
417 | */ | |
418 | protected @Nullable abstract AbstractSegmentStoreAnalysisModule getSegmentStoreAnalysisModule(ITmfTrace trace); | |
419 | ||
03c96217 BH |
420 | // ------------------------------------------------------------------------ |
421 | // Signal handlers | |
422 | // ------------------------------------------------------------------------ | |
423 | ||
424 | /** | |
425 | * @param signal | |
426 | * Signal received when a different trace is selected | |
427 | */ | |
428 | @Override | |
429 | @TmfSignalHandler | |
430 | public void traceSelected(@Nullable TmfTraceSelectedSignal signal) { | |
431 | super.traceSelected(signal); | |
432 | if (signal == null) { | |
433 | return; | |
434 | } | |
435 | ITmfTrace trace = signal.getTrace(); | |
436 | setTrace(trace); | |
437 | if (trace != null) { | |
438 | final TmfTimeRange timeRange = TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange(); | |
439 | setWindowRange( | |
440 | timeRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(), | |
441 | timeRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue()); | |
442 | setData(getSegmentStoreAnalysisModule(trace)); | |
443 | updateRange(timeRange); | |
444 | } | |
445 | } | |
446 | ||
447 | /** | |
448 | * @param signal | |
449 | * Signal received when trace is opened | |
450 | */ | |
451 | @Override | |
452 | @TmfSignalHandler | |
453 | public void traceOpened(@Nullable TmfTraceOpenedSignal signal) { | |
454 | super.traceOpened(signal); | |
455 | if (signal == null) { | |
456 | return; | |
457 | } | |
458 | ITmfTrace trace = signal.getTrace(); | |
459 | setTrace(trace); | |
460 | if (trace != null) { | |
461 | ||
462 | final AbstractSegmentStoreAnalysisModule analysisModuleOfClass = getSegmentStoreAnalysisModule(trace); | |
463 | final TmfTimeRange timeRange = TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange(); | |
464 | setWindowRange( | |
465 | getTimeInNanos(timeRange.getStartTime()), | |
466 | getTimeInNanos(timeRange.getEndTime())); | |
467 | setData(analysisModuleOfClass); | |
468 | } | |
469 | ||
470 | } | |
471 | ||
472 | private void updateRange(final @Nullable TmfTimeRange timeRange) { | |
473 | Job compactingJob = fCompactingJob; | |
474 | if (compactingJob != null && compactingJob.getState() == Job.RUNNING) { | |
475 | compactingJob.cancel(); | |
476 | } | |
477 | compactingJob = new CompactingSegmentStoreQuery(NonNullUtils.checkNotNull(timeRange)); | |
478 | fCompactingJob = compactingJob; | |
479 | compactingJob.schedule(); | |
480 | } | |
481 | ||
482 | /** | |
483 | * @param signal | |
484 | * Signal received when last opened trace is closed | |
485 | */ | |
486 | @Override | |
487 | @TmfSignalHandler | |
488 | public void traceClosed(@Nullable TmfTraceClosedSignal signal) { | |
489 | super.traceClosed(signal); | |
490 | if (signal != null) { | |
491 | // Check if there is no more opened trace | |
492 | if (TmfTraceManager.getInstance().getActiveTrace() == null) { | |
493 | AbstractSegmentStoreAnalysisModule analysis = getAnalysisModule(); | |
494 | if (analysis != null) { | |
76be6c00 | 495 | analysis.removeListener(fListener); |
03c96217 BH |
496 | } |
497 | clearContent(); | |
498 | } | |
499 | } | |
500 | refresh(); | |
501 | } | |
502 | ||
503 | /** | |
504 | * @param signal | |
505 | * Signal received when window range is updated | |
506 | */ | |
507 | @Override | |
508 | @TmfSignalHandler | |
509 | public void windowRangeUpdated(@Nullable TmfWindowRangeUpdatedSignal signal) { | |
510 | super.windowRangeUpdated(signal); | |
511 | if (signal == null) { | |
512 | return; | |
513 | } | |
514 | if (getTrace() != null) { | |
515 | final TmfTimeRange currentRange = signal.getCurrentRange(); | |
516 | updateRange(currentRange); | |
517 | } else { | |
518 | Activator.getDefault().logInfo("No Trace to update"); //$NON-NLS-1$ | |
519 | } | |
520 | } | |
521 | ||
522 | private @Nullable AbstractSegmentStoreAnalysisModule getAnalysisModule() { | |
523 | return fAnalysisModule; | |
524 | } | |
525 | ||
526 | private void setAnalysisModule(AbstractSegmentStoreAnalysisModule analysisModule) { | |
527 | fAnalysisModule = analysisModule; | |
528 | } | |
529 | ||
530 | private static long getTimeInNanos(final ITmfTimestamp currentTime) { | |
531 | return currentTime.normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); | |
532 | } | |
533 | } |