blob: 26fe28276cbf389923ea67ce8b48301531a2ebbc [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014, 2019 École Polytechnique de Montréal and others.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Bernd Hufmann - Initial API and implementation in TmfXYChartViewer
* Geneviève Bastien - Moved methods from TmfXYChartViewer to this interface
*******************************************************************************/
package org.eclipse.tracecompass.tmf.ui.viewers;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
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.TmfTraceRangeUpdatedSignal;
import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal;
import org.eclipse.tracecompass.tmf.core.signal.TmfTraceUpdatedSignal;
import org.eclipse.tracecompass.tmf.core.signal.TmfWindowRangeUpdatedSignal;
import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceContext;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
import org.eclipse.tracecompass.tmf.ui.signal.TmfUiSignalThrottler;
import org.eclipse.tracecompass.tmf.ui.views.ITmfPinnable;
/**
* Abstract class that extends {@link TmfViewer} that adds methods to
* synchronize with a trace's time information.
*
* This class will be extended by viewers who require time information to update
* their content.
*
* <pre>
* It provides three times of data:
* - start and end time of the trace (available)
* - start, end and duration of the current time window, ie the visible time range
* - start and end of the time range selected
* </pre>
*
* @author Bernd Hufmann
* @author Geneviève Bastien
*/
public abstract class TmfTimeViewer extends TmfViewer implements ITmfTimeProvider, ITmfPinnable {
/** Start time of trace */
private long fStartTime;
/** End time of trace */
private long fEndTime;
/** Start time of current time range */
private long fWindowStartTime;
/** End time of current time range */
private long fWindowEndTime;
/** Current begin time of selection range */
private long fSelectionBeginTime;
/** Current end of selection range */
private long fSelectionEndTime;
/** The trace that is displayed by this viewer */
private ITmfTrace fTrace;
/** A signal throttler for range updates */
private final TmfUiSignalThrottler fTimeRangeSyncThrottle = new TmfUiSignalThrottler(this, 200);
/**
* Default constructor.
*/
public TmfTimeViewer() {
super();
}
/**
* Constructor that initializes the parent of the viewer
*
* @param parent
* The parent composite that holds this viewer
*/
public TmfTimeViewer(Composite parent) {
this(parent, ""); //$NON-NLS-1$
}
/**
* Constructor that initializes the parent of the viewer and that sets the
* name of the viewer
*
* @param parent
* The parent composite that holds this viewer
* @param name
* The name of the viewer
*/
public TmfTimeViewer(Composite parent, String name) {
init(parent, name);
}
// ------------------------------------------------------------------------
// Getter/Setters
// ------------------------------------------------------------------------
/**
* Sets the start time of the trace
*
* @param startTime
* The start time to set
*/
protected void setStartTime(long startTime) {
fStartTime = startTime;
}
/**
* Sets the end time of the trace
*
* @param endTime
* The start time to set
*/
protected void setEndTime(long endTime) {
fEndTime = endTime;
}
/**
* Sets the start time and end of the current time range window (visible
* range)
*
* @param windowStartTime
* The start time to set
* @param windowEndTime
* The start time to set
* @since 1.0
*/
protected void setWindowRange(long windowStartTime, long windowEndTime) {
fWindowStartTime = windowStartTime;
fWindowEndTime = windowEndTime;
}
/**
* Sets the begin and end time of the selected range without sending the
* {@link TmfSelectionRangeUpdatedSignal} signal.
*
* @param selectionBeginTime
* The begin time to set
* @param selectionEndTime
* The end time to set
*
* @since 1.0
*/
protected void setSelectionRange(long selectionBeginTime, long selectionEndTime) {
fSelectionBeginTime = selectionBeginTime;
fSelectionEndTime = selectionEndTime;
}
/**
* Sets the trace that is displayed by this viewer.
*
* @param trace
* The trace to set
*/
protected void setTrace(ITmfTrace trace) {
fTrace = trace;
}
/**
* Gets the trace that is displayed by this viewer.
*
* @return the trace
* @since 3.3
*/
@Override
public ITmfTrace getTrace() {
return fTrace;
}
// ------------------------------------------------------------------------
// ITmfTimeProvider
// ------------------------------------------------------------------------
@Override
public long getStartTime() {
return fStartTime;
}
@Override
public long getEndTime() {
return fEndTime;
}
@Override
public long getWindowStartTime() {
return fWindowStartTime;
}
@Override
public long getWindowEndTime() {
return fWindowEndTime;
}
@Override
public long getWindowDuration() {
return getWindowEndTime() - getWindowStartTime();
}
@Override
public long getSelectionBeginTime() {
return fSelectionBeginTime;
}
@Override
public long getSelectionEndTime() {
return fSelectionEndTime;
}
@Override
public void updateSelectionRange(final long currentBeginTime, final long currentEndTime) {
if (fTrace != null) {
setSelectionRange(currentBeginTime, currentEndTime);
final ITmfTimestamp startTimestamp = TmfTimestamp.fromNanos(getSelectionBeginTime());
final ITmfTimestamp endTimestamp = TmfTimestamp.fromNanos(getSelectionEndTime());
TmfSelectionRangeUpdatedSignal signal = new TmfSelectionRangeUpdatedSignal(this, startTimestamp, endTimestamp, getTrace());
broadcast(signal);
}
}
@Override
public void updateWindow(long windowStartTime, long windowEndTime) {
setWindowRange(windowStartTime, windowEndTime);
// Build the new time range; keep the current time
TmfTimeRange timeRange = new TmfTimeRange(
TmfTimestamp.fromNanos(getWindowStartTime()),
TmfTimestamp.fromNanos(getWindowEndTime()));
// Send the signal
TmfWindowRangeUpdatedSignal signal = new TmfWindowRangeUpdatedSignal(this, timeRange, getTrace());
fTimeRangeSyncThrottle.queue(signal);
}
// ------------------------------------------------------------------------
// Operations
// ------------------------------------------------------------------------
/**
* A Method to load a trace into the viewer.
*
* @param trace
* A trace to apply in the viewer
*/
public void loadTrace(ITmfTrace trace) {
fTrace = trace;
if (trace == null) {
return;
}
TmfTraceContext ctx = TmfTraceManager.getInstance().getTraceContext(trace);
long selectionStart = ctx.getSelectionRange().getStartTime().toNanos();
long selectionEnd = ctx.getSelectionRange().getEndTime().toNanos();
TmfTimeRange windowRange = ctx.getWindowRange();
long windowStartTime = windowRange.getStartTime().toNanos();
long windowEndTime = windowRange.getEndTime().toNanos();
long startTime = fTrace.getStartTime().toNanos();
long endTime = fTrace.getEndTime().toNanos();
setSelectionRange(selectionStart, selectionEnd);
setStartTime(startTime);
setWindowRange(windowStartTime, windowEndTime);
setEndTime(endTime);
}
/**
* Resets the content of the viewer
*/
public void reset() {
// Reset the internal data
setSelectionRange(0, 0);
setStartTime(0);
setWindowRange(0, 0);
setEndTime(0);
setTrace(null);
}
@Override
public synchronized void setPinned(ITmfTrace trace) {
if (trace != null) {
/* Ignore relevant inbound signals */
TmfSignalManager.addIgnoredInboundSignal(this, TmfTraceOpenedSignal.class);
TmfSignalManager.addIgnoredInboundSignal(this, TmfTraceSelectedSignal.class);
if (!trace.equals(fTrace)) {
loadTrace(trace);
}
} else {
/* Handle relevant inbound signals */
TmfSignalManager.removeIgnoredInboundSignal(this, TmfTraceOpenedSignal.class);
TmfSignalManager.removeIgnoredInboundSignal(this, TmfTraceSelectedSignal.class);
ITmfTrace activeTrace = TmfTraceManager.getInstance().getActiveTrace();
if (activeTrace != null && !activeTrace.equals(fTrace)) {
loadTrace(activeTrace);
} else {
refresh();
}
}
}
// ------------------------------------------------------------------------
// Signal Handler
// ------------------------------------------------------------------------
/**
* Signal handler for handling of the trace opened signal.
*
* @param signal
* The trace opened signal {@link TmfTraceOpenedSignal}
*/
@TmfSignalHandler
public void traceOpened(TmfTraceOpenedSignal signal) {
fTrace = signal.getTrace();
loadTrace(getTrace());
}
/**
* Signal handler for handling of the trace selected signal.
*
* @param signal
* The trace selected signal {@link TmfTraceSelectedSignal}
*/
@TmfSignalHandler
public void traceSelected(TmfTraceSelectedSignal signal) {
if (fTrace != signal.getTrace()) {
fTrace = signal.getTrace();
loadTrace(getTrace());
}
}
/**
* Signal handler for handling of the trace closed signal.
*
* @param signal
* The trace closed signal {@link TmfTraceClosedSignal}
*/
@TmfSignalHandler
public void traceClosed(@Nullable TmfTraceClosedSignal signal) {
if (signal == null || signal.getTrace() != fTrace) {
return;
}
// Reset the internal data
fTrace = null;
reset();
}
/**
* Signal handler for handling of the selected range signal.
*
* @param signal
* The {@link TmfSelectionRangeUpdatedSignal}
* @since 1.0
*/
@TmfSignalHandler
public void selectionRangeUpdated(@Nullable TmfSelectionRangeUpdatedSignal signal) {
final ITmfTrace trace = fTrace;
if (signal != null && (signal.getSource() != this) && (trace != null)) {
TmfTraceContext ctx = TmfTraceManager.getInstance().getTraceContext(trace);
long selectedTime = ctx.getSelectionRange().getStartTime().toNanos();
long selectedEndTime = ctx.getSelectionRange().getEndTime().toNanos();
setSelectionRange(selectedTime, selectedEndTime);
}
}
/**
* Signal handler for handling of the window range signal.
*
* @param signal
* The {@link TmfWindowRangeUpdatedSignal}
* @since 1.0
*/
@TmfSignalHandler
public void windowRangeUpdated(@Nullable TmfWindowRangeUpdatedSignal signal) {
final ITmfTrace trace = fTrace;
if (signal != null && trace != null) {
TmfTraceContext ctx = TmfTraceManager.getInstance().getTraceContext(trace);
// Validate the time range
TmfTimeRange range = ctx.getWindowRange().getIntersection(trace.getTimeRange());
if (range == null) {
return;
}
if (signal.getSource() != this) {
// Update the time range
long windowStartTime = range.getStartTime().toNanos();
long windowEndTime = range.getEndTime().toNanos();
setWindowRange(windowStartTime, windowEndTime);
}
}
}
/**
* Signal handler for handling of the trace range updated signal.
*
* @param signal
* The trace range signal {@link TmfTraceRangeUpdatedSignal}
*/
@TmfSignalHandler
public void traceRangeUpdated(@Nullable TmfTraceRangeUpdatedSignal signal) {
if (signal == null || signal.getTrace() != fTrace) {
return;
}
TmfTimeRange fullRange = signal.getRange();
long traceStartTime = fullRange.getStartTime().toNanos();
long traceEndTime = fullRange.getEndTime().toNanos();
setStartTime(traceStartTime);
setEndTime(traceEndTime);
}
/**
* Signal handler for handling of the trace updated signal.
*
* @param signal
* The trace updated signal {@link TmfTraceUpdatedSignal}
*/
@TmfSignalHandler
public void traceUpdated(@Nullable TmfTraceUpdatedSignal signal) {
if (signal == null || signal.getTrace() != fTrace) {
return;
}
TmfTimeRange fullRange = signal.getTrace().getTimeRange();
long traceStartTime = fullRange.getStartTime().toNanos();
long traceEndTime = fullRange.getEndTime().toNanos();
setStartTime(traceStartTime);
setEndTime(traceEndTime);
}
}