blob: 5332dfde1e0b570f450406e08a162856f87f501b [file] [log] [blame]
/**********************************************************************
* Copyright (c) 2019 École Polytechnique de Montréal
*
* 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
**********************************************************************/
package org.eclipse.tracecompass.incubator.internal.ros.ui.views.messageflow;
import java.util.Collections;
import java.util.Objects;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.tracecompass.incubator.internal.ros.core.analysis.AbstractRosStateProvider;
import org.eclipse.tracecompass.incubator.internal.ros.core.analysis.messageflow.RosMessageFlowAnalysis;
import org.eclipse.tracecompass.incubator.internal.ros.core.analysis.messageflow.RosMessageFlowDataProvider;
import org.eclipse.tracecompass.incubator.internal.ros.core.analysis.messageflow.RosMessageFlowSegmentEntryModel;
import org.eclipse.tracecompass.incubator.internal.ros.core.analysis.model.messageflow.RosMessageFlowSegment;
import org.eclipse.tracecompass.incubator.internal.ros.core.analysis.model.messageflow.RosMessageFlowSegment.SegmentType;
import org.eclipse.tracecompass.incubator.internal.ros.ui.Activator;
import org.eclipse.tracecompass.incubator.internal.ros.ui.views.AbstractRosView;
import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphEntryModel;
import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
import org.eclipse.tracecompass.tmf.core.signal.TmfStartAnalysisSignal;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeGraphEntry;
import org.eclipse.ui.IWorkbenchActionConstants;
/**
* View for {@link RosMessageFlowAnalysis}
*
* @author Christophe Bedard
*/
public class RosMessageFlowView extends AbstractRosView {
/** View ID suffix */
public static final String ID_SUFFIX = "messageflow"; //$NON-NLS-1$
private static final String[] TREE_COLUMNS = new String[] { "Node", "Type", "Topic", "Segment type" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
/**
* Constructor
*/
public RosMessageFlowView() {
super(ID_SUFFIX, new RosMessageFlowPresentationProvider(), RosMessageFlowDataProvider.getFullDataProviderId());
setTreeColumns(TREE_COLUMNS);
setTreeLabelProvider(new RosMessageFlowTreeLabelProvider());
// Enable view filter dialog
setFilterColumns(new String[] { StringUtils.EMPTY });
setFilterLabelProvider(new RosViewFilterLabelProvider());
}
private static class RosMessageFlowTreeLabelProvider extends TreeLabelProvider {
@Override
public String getColumnText(Object element, int columnIndex) {
TimeGraphEntry entry = (TimeGraphEntry) element;
ITimeGraphEntryModel model = entry.getModel();
if (model instanceof RosMessageFlowSegmentEntryModel) {
RosMessageFlowSegmentEntryModel segmentModel = (RosMessageFlowSegmentEntryModel) model;
RosMessageFlowSegment segment = segmentModel.getSegment();
if (columnIndex >= 0 && columnIndex < TREE_COLUMNS.length) {
if (columnIndex == 0) {
return segment.getNodeName();
} else if (columnIndex == 1) {
return getQueueTypeName(segment.getType());
} else if (columnIndex == 2) {
return segment.getTopicName();
} else if (columnIndex == 3) {
return segment.getType().name();
}
}
} else if (columnIndex == 0) {
// Experiment name
return entry.getName();
}
return StringUtils.EMPTY;
}
}
private static @Nullable String getQueueTypeName(SegmentType type) {
switch (type) {
case SUB_QUEUE: // Fallthrough
case SUB_CALLBACK:
return AbstractRosStateProvider.SUBSCRIBERS_LIST;
case PUB_QUEUE:
return AbstractRosStateProvider.PUBLISHERS_LIST;
case INVALID:
default:
return null;
}
}
private static class RosViewFilterLabelProvider extends TreeLabelProvider {
// Empty; only used to enable view filter dialog
}
@Override
protected void fillLocalToolBar(IToolBarManager manager) {
IDialogSettings settings = Objects.requireNonNull(Activator.getDefault()).getDialogSettings();
IDialogSettings section = settings.getSection(getClass().getName());
if (section == null) {
section = settings.addNewSection(getClass().getName());
}
IAction hideArrowsAction = getTimeGraphViewer().getHideArrowsAction(section);
manager.appendToGroup(IWorkbenchActionConstants.MB_ADDITIONS, hideArrowsAction);
// add a separator to local tool bar
manager.appendToGroup(IWorkbenchActionConstants.MB_ADDITIONS, new Separator());
super.fillLocalToolBar(manager);
}
/**
* Signal handler for analysis started, we need to rebuilt the entry list
* with updated statistics values for the current graph worker of the
* critical path module.
*
* @param signal
* The signal
*/
@TmfSignalHandler
public void analysisStarted(TmfStartAnalysisSignal signal) {
IAnalysisModule analysis = signal.getAnalysisModule();
if (analysis instanceof RosMessageFlowAnalysis) {
rebuild();
}
}
@Override
protected @NonNull Iterable<ITmfTrace> getTracesToBuild(@Nullable ITmfTrace trace) {
// The view only applies to the ROS experiment itself
return (trace != null) ? Collections.singleton(trace) : Collections.emptyList();
}
/**
* @return the full view ID
*/
public static String getFullViewId() {
return AbstractRosView.ID_PREFIX + ID_SUFFIX;
}
}