timing.ui: Add dirty conditions for SWTbot to scatter graph viewer
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.timing.ui / src / org / eclipse / tracecompass / analysis / timing / ui / views / segmentstore / scatter / AbstractSegmentStoreScatterGraphViewer.java
index 98f4c0c5726ec415b57c874a80b4ec7e46b43de3..e55fbe0780e7a09fec3144c9c7e3b988c6a592db 100644 (file)
@@ -19,17 +19,17 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Display;
-import org.eclipse.tracecompass.analysis.timing.core.segmentstore.AbstractSegmentStoreAnalysisModule;
 import org.eclipse.tracecompass.analysis.timing.core.segmentstore.IAnalysisProgressListener;
+import org.eclipse.tracecompass.analysis.timing.core.segmentstore.ISegmentStoreProvider;
 import org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.SubSecondTimeWithUnitFormat;
 import org.eclipse.tracecompass.common.core.NonNullUtils;
 import org.eclipse.tracecompass.internal.analysis.timing.ui.Activator;
@@ -38,8 +38,8 @@ import org.eclipse.tracecompass.internal.analysis.timing.ui.views.segmentstore.s
 import org.eclipse.tracecompass.segmentstore.core.ISegment;
 import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
 import org.eclipse.tracecompass.segmentstore.core.SegmentComparators;
+import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
-import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal;
 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal;
@@ -47,22 +47,17 @@ import org.eclipse.tracecompass.tmf.core.signal.TmfWindowRangeUpdatedSignal;
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
-import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentInfo;
-import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentSignal;
-import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.TmfChartTimeStampFormat;
 import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.linecharts.TmfCommonXLineChartViewer;
-import org.swtchart.Chart;
-import org.swtchart.IAxis;
-import org.swtchart.IAxisTick;
 import org.swtchart.ILineSeries;
 import org.swtchart.ILineSeries.PlotSymbolType;
 import org.swtchart.ISeries.SeriesType;
 import org.swtchart.ISeriesSet;
 import org.swtchart.LineStyle;
-import org.swtchart.Range;
+
+import com.google.common.primitives.Doubles;
 
 /**
- * Displays the segment store analysis data in a scatter graph
+ * Displays the segment store provider data in a scatter graph
  *
  * @author France Lapointe Nguyen
  * @author Matthew Khouzam - reduced memory usage
@@ -72,6 +67,8 @@ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXL
 
     private static final Format FORMAT = new SubSecondTimeWithUnitFormat();
 
+    private final AtomicInteger fDirty = new AtomicInteger();
+
     private final class CompactingSegmentStoreQuery extends Job {
         private static final long MAX_POINTS = 1000;
         private final TmfTimeRange fCurrentRange;
@@ -84,52 +81,70 @@ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXL
         @Override
         protected IStatus run(@Nullable IProgressMonitor monitor) {
             final IProgressMonitor statusMonitor = monitor;
-            if (statusMonitor == null) {
-                return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Monitor is null"); //$NON-NLS-1$
-            }
+            try {
+                if (statusMonitor == null) {
+                    return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Monitor is null"); //$NON-NLS-1$
+                }
 
-            AbstractSegmentStoreAnalysisModule module = getAnalysisModule();
-            final long startTimeInNanos = fCurrentRange.getStartTime().toNanos();
-            final long endTimeInNanos = fCurrentRange.getEndTime().toNanos();
-            if (module == null) {
-                setWindowRange(startTimeInNanos, endTimeInNanos);
-                redraw(statusMonitor, startTimeInNanos, startTimeInNanos, Collections.EMPTY_LIST);
-                return new Status(IStatus.WARNING, Activator.PLUGIN_ID, "Analysis module not available"); //$NON-NLS-1$
-            }
+                ISegmentStoreProvider segmentProvider = getSegmentProvider();
+                final long startTimeInNanos = fCurrentRange.getStartTime().toNanos();
+                final long endTimeInNanos = fCurrentRange.getEndTime().toNanos();
+                if (segmentProvider == null) {
+                    setWindowRange(startTimeInNanos, endTimeInNanos);
+                    redraw(statusMonitor, startTimeInNanos, startTimeInNanos, Collections.EMPTY_LIST);
+                    return new Status(IStatus.WARNING, Activator.PLUGIN_ID, "segment provider not available"); //$NON-NLS-1$
+                }
 
-            final ISegmentStore<ISegment> segStore = module.getSegmentStore();
-            if (segStore == null) {
-                setWindowRange(startTimeInNanos, endTimeInNanos);
-                redraw(statusMonitor, startTimeInNanos, startTimeInNanos, Collections.EMPTY_LIST);
-                return new Status(IStatus.INFO, Activator.PLUGIN_ID, "Analysis module does not have results"); //$NON-NLS-1$
-            }
+                final ISegmentStore<ISegment> segStore = segmentProvider.getSegmentStore();
+                if (segStore == null) {
+                    setWindowRange(startTimeInNanos, endTimeInNanos);
+                    redraw(statusMonitor, startTimeInNanos, startTimeInNanos, Collections.EMPTY_LIST);
+                    return new Status(IStatus.INFO, Activator.PLUGIN_ID, "Segment provider does not have segments"); //$NON-NLS-1$
+                }
 
-            final long startTime = fCurrentRange.getStartTime().getValue();
-            final long endTime = fCurrentRange.getEndTime().getValue();
-            fPixelStart = startTime;
-            fPixelSize = (endTime - startTime) / MAX_POINTS;
-            final Iterable<ISegment> intersectingElements = segStore.getIntersectingElements(startTime, endTime);
+                final long startTime = fCurrentRange.getStartTime().getValue();
+                final long endTime = fCurrentRange.getEndTime().getValue();
+                fPixelStart = startTime;
+                fPixelSize = Math.max(1, (endTime - startTime) / MAX_POINTS);
+                final Iterable<ISegment> intersectingElements = segStore.getIntersectingElements(startTime, endTime);
 
-            final List<ISegment> list = convertIterableToList(intersectingElements, statusMonitor);
-            final List<ISegment> displayData = (!list.isEmpty()) ? compactList(startTime, list, statusMonitor) : list;
+                final List<ISegment> list = convertIterableToList(intersectingElements, statusMonitor);
+                final List<ISegment> displayData = (!list.isEmpty()) ? compactList(startTime, list, statusMonitor) : list;
 
-            setWindowRange(startTimeInNanos, endTimeInNanos);
-            redraw(statusMonitor, startTime, endTime, displayData);
+                setWindowRange(startTimeInNanos, endTimeInNanos);
+                redraw(statusMonitor, startTime, endTime, displayData);
 
-            if (statusMonitor.isCanceled()) {
-                return NonNullUtils.checkNotNull(Status.CANCEL_STATUS);
+                if (statusMonitor.isCanceled()) {
+                    return Status.CANCEL_STATUS;
+                }
+                return Status.OK_STATUS;
+            } finally {
+                /*
+                 * fDirty should have been incremented before creating a job, so
+                 * we decrement it once the job is done
+                 */
+                fDirty.decrementAndGet();
             }
-            return NonNullUtils.checkNotNull(Status.OK_STATUS);
 
         }
 
         private void redraw(final IProgressMonitor statusMonitor, final long startTime, final long endTime, final List<ISegment> displayData) {
             fDisplayData = displayData;
+            /*
+             * Increment at every redraw, since the content of the view is not
+             * current
+             */
+            fDirty.incrementAndGet();
             Display.getDefault().asyncExec(new Runnable() {
 
                 @Override
                 public void run() {
-                    updateData(startTime, endTime, displayData.size(), statusMonitor);
+                    try {
+                        updateData(startTime, endTime, displayData.size(), statusMonitor);
+                    } finally {
+                        /* Decrement once the redraw is done */
+                        fDirty.decrementAndGet();
+                    }
                 }
             });
         }
@@ -191,17 +206,16 @@ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXL
     // ------------------------------------------------------------------------
 
     /**
-     * Listener to update the model with the semgent store analysis results
-     * once the analysis is fully completed
+     * Listener to update the model with the segment store provider results once
+     * its segment store is fully completed
      */
-    private final class AnalysisProgressListener implements IAnalysisProgressListener {
+    private final class SegmentStoreProviderProgressListener implements IAnalysisProgressListener {
 
         @Override
-        public void onComplete(AbstractSegmentStoreAnalysisModule activeAnalysis, ISegmentStore<ISegment> results) {
+        public void onComplete(ISegmentStoreProvider segmentProvider, ISegmentStore<ISegment> segmentStore) {
             // Only update the model if trace that was analyzed is active trace
-            if (activeAnalysis.equals(getAnalysisModule())) {
-                updateModel(results);
-                updateRange(TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange());
+            if (segmentProvider.equals(getSegmentProvider())) {
+                updateModel(segmentStore);
             }
         }
     }
@@ -215,14 +229,14 @@ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXL
     private Collection<ISegment> fDisplayData = Collections.EMPTY_LIST;
 
     /**
-     * Analysis completion listener
+     * Provider completion listener
      */
-    private AnalysisProgressListener fListener;
+    private SegmentStoreProviderProgressListener fListener;
 
     /**
-     * Current analysis module
+     * Current segment provider
      */
-    private @Nullable AbstractSegmentStoreAnalysisModule fAnalysisModule;
+    private @Nullable ISegmentStoreProvider fSegmentProvider;
 
     private @Nullable Job fCompactingJob;
 
@@ -245,20 +259,19 @@ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXL
     public AbstractSegmentStoreScatterGraphViewer(Composite parent, String title, String xLabel, String yLabel) {
         super(parent, title, xLabel, yLabel);
         setTooltipProvider(new SegmentStoreScatterGraphTooltipProvider(this));
-        fListener = new AnalysisProgressListener();
+        fListener = new SegmentStoreProviderProgressListener();
         ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace();
-        initializeModule(trace);
+        initializeProvider(trace);
         getSwtChart().getLegend().setVisible(false);
         getSwtChart().getAxisSet().getYAxis(0).getTick().setFormat(FORMAT);
     }
 
-    private final void initializeModule(@Nullable ITmfTrace trace) {
+    private final void initializeProvider(@Nullable ITmfTrace trace) {
         if (trace != null) {
-            final AbstractSegmentStoreAnalysisModule analysisModuleOfClass = getSegmentStoreAnalysisModule(trace);
-            if (analysisModuleOfClass != null) {
-                analysisModuleOfClass.addListener(fListener);
-                setData(analysisModuleOfClass);
-                updateRange(TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange());
+            final ISegmentStoreProvider segmentStoreProvider = getSegmentStoreProvider(trace);
+            if (segmentStoreProvider != null) {
+                segmentStoreProvider.addListener(fListener);
+                setData(segmentStoreProvider);
             }
         }
     }
@@ -303,9 +316,9 @@ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXL
     @Override
     protected void initializeDataSource() {
         ITmfTrace trace = getTrace();
-        initializeModule(trace);
+        initializeProvider(trace);
         if (trace != null) {
-            setData(getSegmentStoreAnalysisModule(trace));
+            setData(getSegmentStoreProvider(trace));
         }
     }
 
@@ -316,59 +329,23 @@ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXL
         Collection<ISegment> data = fDisplayData;
 
         final int dataSize = (nb == 0) ? data.size() : nb;
-        if (dataSize == 0 || end == start) {
+        if (end == start) {
             return;
         }
 
-        final double[] xSeries = new double[dataSize];
-        final double[] ySeries = new double[dataSize];
+        List<Double> xSeries = new ArrayList<>(dataSize);
+        List<Double> ySeries = new ArrayList<>(dataSize);
         // For each visible segments, add start time to x value and duration
         // for y value
         Iterator<ISegment> modelIter = data.iterator();
-        long maxTempY = 1;
-        for (int i = 0; i < dataSize; i++) {
-            if (modelIter.hasNext()) {
-                ISegment segment = modelIter.next();
-                xSeries[i] = segment.getStart() - start;
-                ySeries[i] = segment.getLength();
-                maxTempY = Math.max(maxTempY, segment.getLength());
-            }
-        }
-        final long maxY = maxTempY;
-        setXAxis(xSeries);
-        final Chart swtChart = getSwtChart();
-        if (swtChart.isDisposed() || xSeries.length < 1) {
-            return;
-        }
-        swtChart.updateLayout();
-        setSeries(Messages.SegmentStoreScatterGraphViewer_legend, ySeries); // $NON-NLS-1$
-        final TmfChartTimeStampFormat tmfChartTimeStampFormat = new TmfChartTimeStampFormat(getTimeOffset());
-        ILineSeries series = (ILineSeries) swtChart.getSeriesSet().getSeries(Messages.SegmentStoreScatterGraphViewer_legend);
-        if (series == null) {
-            series = addSeries(Messages.SegmentStoreScatterGraphViewer_legend);
-        }
-        series.setXSeries(xSeries);
-        /* Find the minimal and maximum values in this series */
-        series.setYSeries(ySeries);
-
-        final IAxis xAxis = swtChart.getAxisSet().getXAxis(0);
-        IAxisTick xTick = xAxis.getTick();
-        xTick.setFormat(tmfChartTimeStampFormat);
-        xAxis.setRange(new Range(0.0, end - start));
-        if (maxY > 0.0) {
-            swtChart.getAxisSet().getYAxis(0).setRange(new Range(0.0, maxY));
-        }
-        swtChart.redraw();
-
-        if (isSendTimeAlignSignals()) {
-            // The width of the chart might have changed and its
-            // time axis might be misaligned with the other views
-            Point viewPos = AbstractSegmentStoreScatterGraphViewer.this.getParent().getParent().toDisplay(0, 0);
-            int axisPos = swtChart.toDisplay(0, 0).x + getPointAreaOffset();
-            int timeAxisOffset = axisPos - viewPos.x;
-            TmfTimeViewAlignmentInfo timeAlignmentInfo = new TmfTimeViewAlignmentInfo(getControl().getShell(), viewPos, timeAxisOffset);
-            TmfSignalManager.dispatchSignal(new TmfTimeViewAlignmentSignal(AbstractSegmentStoreScatterGraphViewer.this, timeAlignmentInfo, true));
+        while (modelIter.hasNext()) {
+            ISegment segment = modelIter.next();
+            xSeries.add((double) (segment.getStart() - start));
+            ySeries.add((double) segment.getLength());
         }
+        setXAxis(Doubles.toArray(xSeries));
+        setSeries(Messages.SegmentStoreScatterGraphViewer_legend, Doubles.toArray(ySeries));
+        updateDisplay();
     }
 
     @Override
@@ -388,39 +365,42 @@ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXL
     }
 
     /**
-     * Set the data into the viewer. Will update model is analysis is completed
-     * or run analysis if not completed
+     * Set the data into the viewer. If the provider is an analysis, it will
+     * update the model if the analysis is completed or run the analysis if not
+     * completed
      *
-     * @param analysis
-     *            Segment store analysis module
+     * @param provider
+     *            Segment store provider
      */
-    public void setData(@Nullable AbstractSegmentStoreAnalysisModule analysis) {
-        if (analysis == null) {
+    public void setData(@Nullable ISegmentStoreProvider provider) {
+        if (provider == null) {
             updateModel(null);
             return;
         }
-        ISegmentStore<ISegment> segStore = analysis.getSegmentStore();
-        // If results are not null, then analysis is completed and model can be
-        // updated
+        ISegmentStore<ISegment> segStore = provider.getSegmentStore();
+        // If results are not null, then segment store is completed and model
+        // can be updated
         if (segStore != null) {
             updateModel(segStore);
-            setAnalysisModule(analysis);
+            setSegmentProvider(provider);
             return;
         }
         updateModel(null);
-        analysis.addListener(fListener);
-        analysis.schedule();
-        setAnalysisModule(analysis);
+        provider.addListener(fListener);
+        if (provider instanceof IAnalysisModule) {
+            ((IAnalysisModule) provider).schedule();
+        }
+        setSegmentProvider(provider);
     }
 
     /**
-     * Returns the segment store analysis module
+     * Returns the segment store provider
      *
      * @param trace
      *            The trace to consider
-     * @return the analysis module
+     * @return the segment store provider
      */
-    protected @Nullable abstract AbstractSegmentStoreAnalysisModule getSegmentStoreAnalysisModule(ITmfTrace trace);
+    protected @Nullable abstract ISegmentStoreProvider getSegmentStoreProvider(ITmfTrace trace);
 
     // ------------------------------------------------------------------------
     // Signal handlers
@@ -444,7 +424,7 @@ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXL
             setWindowRange(
                     timeRange.getStartTime().toNanos(),
                     timeRange.getEndTime().toNanos());
-            setData(getSegmentStoreAnalysisModule(trace));
+            setData(getSegmentStoreProvider(trace));
             updateRange(timeRange);
         }
     }
@@ -464,17 +444,22 @@ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXL
         setTrace(trace);
         if (trace != null) {
 
-            final AbstractSegmentStoreAnalysisModule analysisModuleOfClass = getSegmentStoreAnalysisModule(trace);
+            final ISegmentStoreProvider segmentStoreProvider = getSegmentStoreProvider(trace);
             final TmfTimeRange timeRange = TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange();
             setWindowRange(
                     timeRange.getStartTime().toNanos(),
                     timeRange.getEndTime().toNanos());
-            setData(analysisModuleOfClass);
+            setData(segmentStoreProvider);
         }
 
     }
 
     private void updateRange(final @Nullable TmfTimeRange timeRange) {
+        /*
+         * Update is request, content is not up to date, fDirty will be
+         * decremented in the compacting job
+         */
+        fDirty.incrementAndGet();
         Job compactingJob = fCompactingJob;
         if (compactingJob != null && compactingJob.getState() == Job.RUNNING) {
             compactingJob.cancel();
@@ -495,9 +480,9 @@ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXL
         if (signal != null) {
             // Check if there is no more opened trace
             if (TmfTraceManager.getInstance().getActiveTrace() == null) {
-                AbstractSegmentStoreAnalysisModule analysis = getAnalysisModule();
-                if (analysis != null) {
-                    analysis.removeListener(fListener);
+                ISegmentStoreProvider provider = getSegmentProvider();
+                if (provider != null) {
+                    provider.removeListener(fListener);
                 }
                 clearContent();
             }
@@ -524,11 +509,17 @@ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXL
         }
     }
 
-    private @Nullable AbstractSegmentStoreAnalysisModule getAnalysisModule() {
-        return fAnalysisModule;
+    private @Nullable ISegmentStoreProvider getSegmentProvider() {
+        return fSegmentProvider;
     }
 
-    private void setAnalysisModule(AbstractSegmentStoreAnalysisModule analysisModule) {
-        fAnalysisModule = analysisModule;
+    private void setSegmentProvider(ISegmentStoreProvider provider) {
+        fSegmentProvider = provider;
+    }
+
+    @Override
+    public boolean isDirty() {
+        /* Check the parent's or this view's own dirtiness */
+        return super.isDirty() || (fDirty.get() != 0);
     }
 }
\ No newline at end of file
This page took 0.032404 seconds and 5 git commands to generate.