| /******************************************************************************* |
| * Copyright (c) 2017, 2020 Dortmund University of Applied Sciences and Arts and others. |
| * |
| * This program and the accompanying materials are made |
| * available under the terms of the Eclipse Public License 2.0 |
| * which is available at https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Dortmund University of Applied Sciences and Arts - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.app4mc.multicore.execution.ui.simmenu.wizards; |
| |
| import java.awt.Frame; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.stream.Collectors; |
| |
| import org.eclipse.app4mc.amalthea.model.ConstraintsModel; |
| import org.eclipse.app4mc.multicore.execution.logic.openmapping.MalformedModelException; |
| import org.eclipse.app4mc.multicore.execution.logic.openmapping.OMAllocation; |
| import org.eclipse.app4mc.multicore.execution.logic.openmapping.OMCore; |
| import org.eclipse.app4mc.multicore.execution.logic.openmapping.OMEdge; |
| import org.eclipse.app4mc.multicore.execution.logic.openmapping.OMMapping; |
| import org.eclipse.app4mc.multicore.execution.logic.openmapping.OMTask; |
| import org.eclipse.app4mc.multicore.execution.logic.openmapping.OMUtil; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.wizard.WizardPage; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.awt.SWT_AWT; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Label; |
| |
| import com.mxgraph.layout.hierarchical.mxHierarchicalLayout; |
| import com.mxgraph.swing.mxGraphComponent; |
| import com.mxgraph.util.mxConstants; |
| import com.mxgraph.view.mxGraph; |
| |
| public class TaskVisuDependencyPage extends WizardPage { |
| private mxGraph graph; |
| private mxGraphComponent graphView; |
| |
| private Button cbConsiderPrecedence; |
| |
| private OMMapping model; |
| |
| private final Set<Object> consideredGraphEdges = new HashSet<>(); |
| |
| private List<OMAllocation> allocationList; |
| private List<OMTask> tasklist; |
| |
| private Collection<OMEdge> consideredEdges; |
| |
| protected TaskVisuDependencyPage(final String pageName) { |
| super(pageName); |
| } |
| |
| public TaskVisuDependencyPage(final OMMapping model, final ConstraintsModel cm) { |
| super("Task Visualisation: Task Dependencies"); |
| setTitle("Task Visualisation: Task Dependencies"); |
| this.model = model; |
| } |
| |
| @Override |
| public void createControl(final Composite parent) { |
| final Composite container = new Composite(parent, SWT.NONE); |
| final GridLayout layout = new GridLayout(); |
| layout.numColumns = 2; |
| container.setLayout(layout); |
| |
| try { |
| this.allocationList = this.model.getAllocationList(); |
| this.tasklist = this.allocationList.stream().map(OMAllocation::getTask).collect(Collectors.toList()); |
| |
| createGraph(); |
| final Composite embeddedComposite = new Composite(container, SWT.EMBEDDED | SWT.NO_BACKGROUND); |
| final GridData embedGraphData = new GridData(SWT.FILL, SWT.FILL, true, true); |
| embedGraphData.verticalSpan = 2; |
| embeddedComposite.setLayoutData(embedGraphData); |
| final Frame frame = SWT_AWT.new_Frame(embeddedComposite); |
| frame.add(this.graphView); |
| frame.setVisible(true); |
| |
| this.cbConsiderPrecedence = new Button(container, SWT.CHECK); |
| this.cbConsiderPrecedence.setText("Consider task precedence!\n"); |
| final Label filterinfo = new Label(container, SWT.WRAP | SWT.BORDER | SWT.LEFT); |
| filterinfo.setText("Relations filter: " + "\n- No edges with unequal periods of pre- and post-task." |
| + "\n- No edges with same pre- and post-task (selftransition)." |
| + "\n- If there are multiple edges between two tasks the edge " |
| + "\n with the highest release time is chosen."); |
| |
| this.cbConsiderPrecedence.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(final SelectionEvent e) { |
| |
| if (!OMUtil.isDAG(TaskVisuDependencyPage.this.consideredEdges)) { |
| MessageDialog.openInformation(getShell(), "Task Visualization", |
| "Directed cylic Graphs are not supported!"); |
| TaskVisuDependencyPage.this.cbConsiderPrecedence.setSelection(false); |
| return; |
| } |
| |
| if (TaskVisuDependencyPage.this.cbConsiderPrecedence.getSelection()) { |
| TaskVisuDependencyPage.this.graph.setCellStyles(mxConstants.STYLE_STROKECOLOR, "red", |
| TaskVisuDependencyPage.this.consideredGraphEdges.toArray()); |
| } |
| else { |
| TaskVisuDependencyPage.this.graph.setCellStyles(mxConstants.STYLE_STROKECOLOR, "blue", |
| TaskVisuDependencyPage.this.consideredGraphEdges.toArray()); |
| } |
| } |
| }); |
| |
| } |
| catch (final Exception e) { |
| e.printStackTrace(); |
| } |
| |
| setControl(container); |
| setPageComplete(true); |
| } |
| |
| private void createGraph() { |
| this.graph = new mxGraph(); |
| |
| this.graph.setCellsEditable(false); |
| addModelDataToGraph(); |
| |
| layoutGraph(); |
| this.graphView = new mxGraphComponent(this.graph); |
| this.graphView.setConnectable(false); |
| } |
| |
| private void addModelDataToGraph() { |
| |
| final Object parent = this.graph.getDefaultParent(); |
| final Map<OMTask, Object> celllist = new HashMap<>(); |
| |
| for (final OMAllocation alloc : this.allocationList) { |
| final OMTask task = alloc.getTask(); |
| final Object x = this.graph.insertVertex(parent, null, task.getTaskRef().getName(), 0, 0, 80, 30); |
| celllist.put(task, x); |
| } |
| |
| final Map<OMEdge, Object> edgemap = new HashMap<>(); |
| |
| for (final OMAllocation alloc : this.allocationList) { |
| final OMTask pre = alloc.getTask(); |
| final OMCore core = alloc.getCore(); |
| |
| for (final OMEdge postEdge : pre.getPosts()) { |
| |
| final OMTask post = postEdge.getPost(); |
| final long instruction = postEdge.getReleaseInstruction(); |
| |
| long time; |
| try { |
| time = OMUtil.getProcessingTime(core, instruction); |
| final Object edge = this.graph.insertEdge(parent, null, "" + time + " ps", celllist.get(pre), |
| celllist.get(post)); |
| edgemap.put(postEdge, edge); |
| } |
| catch (final MalformedModelException e) { |
| e.printStackTrace(); |
| } |
| |
| } |
| } |
| this.consideredEdges = Util.getConsideredEdges(this.tasklist); |
| |
| for (final OMEdge edge : this.consideredEdges) { |
| this.consideredGraphEdges.add(edgemap.get(edge)); |
| } |
| |
| } |
| |
| public boolean considerTaskPrecedence() { |
| if (this.cbConsiderPrecedence != null) { |
| return this.cbConsiderPrecedence.getSelection(); |
| } |
| return false; |
| } |
| |
| public Collection<OMEdge> getTaskPrecedences() { |
| return this.consideredEdges; |
| } |
| |
| private void layoutGraph() { |
| |
| new mxHierarchicalLayout(this.graph).execute(this.graph.getDefaultParent()); |
| } |
| |
| } |