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