Search in sources :

Example 6 with KEdge

use of de.cau.cs.kieler.klighd.kgraph.KEdge in project lingua-franca by lf-lang.

the class CycleVisualization method detectAndHighlightCycles.

/**
 * Performs cycle detection based on the diagram's graph structure and applies given highlighting to the included elements
 */
public boolean detectAndHighlightCycles(ReactorInstance rootReactorInstance, Map<ReactorInstance, KNode> allReactorNodes, Consumer<KGraphElement> highlighter) {
    if (rootReactorInstance.hasCycles() && highlighter != null) {
        // Highlight cycles
        // A cycle consists of reactions and ports.
        HashMultimap<ReactorInstance, NamedInstance<?>> cycleElementsByReactor = HashMultimap.create();
        Set<NamedInstance<?>> cycles = rootReactorInstance.getCycles();
        for (NamedInstance<?> element : cycles) {
            // First find the involved reactor instances
            if (element instanceof ReactorInstance) {
                cycleElementsByReactor.put((ReactorInstance) element, element);
            } else {
                cycleElementsByReactor.put(element.getParent(), element);
            }
        }
        for (ReactorInstance reactor : cycleElementsByReactor.keySet()) {
            KNode node = allReactorNodes.get(reactor);
            if (node != null) {
                node.setProperty(DEPENDENCY_CYCLE, true);
                highlighter.accept(node);
                Set<NamedInstance<?>> reactorContentInCycle = cycleElementsByReactor.get(reactor);
                // Reactor edges
                for (KEdge edge : node.getOutgoingEdges()) {
                    if (connectsCycleElements(edge, cycles)) {
                        edge.setProperty(DEPENDENCY_CYCLE, true);
                        highlighter.accept(edge);
                    }
                }
                // Reactor ports
                for (KPort port : node.getPorts()) {
                    if (reactorContentInCycle.contains(NamedInstanceUtil.getLinkedInstance(port))) {
                        port.setProperty(DEPENDENCY_CYCLE, true);
                        highlighter.accept(port);
                    }
                }
                // Child Nodes
                for (KNode childNode : node.getChildren()) {
                    if (reactorContentInCycle.contains(NamedInstanceUtil.getLinkedInstance(childNode)) && !_utilityExtensions.sourceIsReactor(childNode)) {
                        childNode.setProperty(DEPENDENCY_CYCLE, true);
                        highlighter.accept(childNode);
                        for (KEdge edge : childNode.getOutgoingEdges()) {
                            if (connectsCycleElements(edge, cycles)) {
                                edge.setProperty(DEPENDENCY_CYCLE, true);
                                highlighter.accept(edge);
                            }
                        }
                    }
                }
            }
        }
        return true;
    }
    return false;
}
Also used : ReactorInstance(org.lflang.generator.ReactorInstance) KEdge(de.cau.cs.kieler.klighd.kgraph.KEdge) KPort(de.cau.cs.kieler.klighd.kgraph.KPort) KNode(de.cau.cs.kieler.klighd.kgraph.KNode) NamedInstance(org.lflang.generator.NamedInstance)

Example 7 with KEdge

use of de.cau.cs.kieler.klighd.kgraph.KEdge in project lingua-franca by lf-lang.

the class LinguaFrancaSynthesis method createIODependencyEdge.

private KEdge createIODependencyEdge(Object associate, boolean multiport) {
    KEdge edge = _kEdgeExtensions.createEdge();
    if (associate != null) {
        associateWith(edge, associate);
    }
    KPolyline line = _kEdgeExtensions.addPolyline(edge);
    _linguaFrancaStyleExtensions.boldLineSelectionStyle(line);
    _kPolylineExtensions.addJunctionPointDecorator(line);
    if (multiport) {
        // Render multiport connections and bank connections in bold.
        _kRenderingExtensions.setLineWidth(line, 2.2f);
        _kRenderingExtensions.setLineCap(line, LineCap.CAP_SQUARE);
        // Adjust junction point size
        _kPolylineExtensions.setJunctionPointDecorator(line, line.getJunctionPointRendering(), 6, 6);
    }
    return edge;
}
Also used : KEdge(de.cau.cs.kieler.klighd.kgraph.KEdge) KPolyline(de.cau.cs.kieler.klighd.krendering.KPolyline)

Example 8 with KEdge

use of de.cau.cs.kieler.klighd.kgraph.KEdge in project lingua-franca by lf-lang.

the class LinguaFrancaSynthesis method transform.

// -------------------------------------------------------------------------
@Override
public KNode transform(final Model model) {
    KNode rootNode = _kNodeExtensions.createNode();
    try {
        // Find main
        Reactor main = IterableExtensions.findFirst(model.getReactors(), _utilityExtensions::isMainOrFederated);
        if (main != null) {
            ReactorInstance reactorInstance = new ReactorInstance(main, new SynthesisErrorReporter());
            rootNode.getChildren().addAll(createReactorNode(reactorInstance, true, null, null, new HashMap<>()));
        } else {
            KNode messageNode = _kNodeExtensions.createNode();
            _linguaFrancaShapeExtensions.addErrorMessage(messageNode, TEXT_NO_MAIN_REACTOR, null);
            rootNode.getChildren().add(messageNode);
        }
        // Show all reactors
        if (main == null || getBooleanValue(SHOW_ALL_REACTORS)) {
            List<KNode> reactorNodes = new ArrayList<>();
            for (Reactor reactor : model.getReactors()) {
                if (reactor == main)
                    continue;
                ReactorInstance reactorInstance = new ReactorInstance(reactor, new SynthesisErrorReporter(), new HashSet<>());
                reactorNodes.addAll(createReactorNode(reactorInstance, main == null, HashBasedTable.<ReactorInstance, PortInstance, KPort>create(), HashBasedTable.<ReactorInstance, PortInstance, KPort>create(), new HashMap<>()));
            }
            if (!reactorNodes.isEmpty()) {
                // To allow ordering, we need box layout but we also need layered layout for ports thus wrap all node
                // TODO use rect packing in the future
                reactorNodes.add(0, IterableExtensions.head(rootNode.getChildren()));
                int index = 0;
                for (KNode node : reactorNodes) {
                    if (node.getProperty(CoreOptions.COMMENT_BOX))
                        continue;
                    KNode child = _kNodeExtensions.createNode();
                    child.getChildren().add(node);
                    // Add comment nodes
                    for (KEdge edge : node.getIncomingEdges()) {
                        if (!edge.getSource().getProperty(CoreOptions.COMMENT_BOX))
                            continue;
                        child.getChildren().add(edge.getSource());
                    }
                    _kRenderingExtensions.addInvisibleContainerRendering(child);
                    setLayoutOption(child, CoreOptions.ALGORITHM, LayeredOptions.ALGORITHM_ID);
                    setLayoutOption(child, CoreOptions.PADDING, new ElkPadding(0));
                    // Order!
                    setLayoutOption(child, CoreOptions.PRIORITY, reactorNodes.size() - index);
                    rootNode.getChildren().add(child);
                    index++;
                }
                setLayoutOption(rootNode, CoreOptions.ALGORITHM, BoxLayouterOptions.ALGORITHM_ID);
                setLayoutOption(rootNode, CoreOptions.SPACING_NODE_NODE, 25.0);
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
        KNode messageNode = _kNodeExtensions.createNode();
        _linguaFrancaShapeExtensions.addErrorMessage(messageNode, "Error in Diagram Synthesis", e.getClass().getSimpleName() + " occurred. Could not create diagram.");
        rootNode.getChildren().add(messageNode);
    }
    return rootNode;
}
Also used : PortInstance(org.lflang.generator.PortInstance) SynthesisErrorReporter(org.lflang.diagram.synthesis.util.SynthesisErrorReporter) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) KEdge(de.cau.cs.kieler.klighd.kgraph.KEdge) KPort(de.cau.cs.kieler.klighd.kgraph.KPort) KNode(de.cau.cs.kieler.klighd.kgraph.KNode) SizeConstraint(org.eclipse.elk.core.options.SizeConstraint) LayerConstraint(org.eclipse.elk.alg.layered.options.LayerConstraint) ReactorInstance(org.lflang.generator.ReactorInstance) Reactor(org.lflang.lf.Reactor) ElkPadding(org.eclipse.elk.core.math.ElkPadding)

Example 9 with KEdge

use of de.cau.cs.kieler.klighd.kgraph.KEdge in project lingua-franca by lf-lang.

the class ReactionPortAdjustment method adjustPositions.

public void adjustPositions(Iterable<Pair<Integer, KPort>> indexedPorts, int count, boolean input) {
    float segments = LinguaFrancaShapeExtensions.REACTION_POINTINESS * 2 / (count + 1);
    for (Pair<Integer, KPort> indexedPort : indexedPorts) {
        KPort port = indexedPort.getValue();
        int idx = indexedPort.getKey();
        float offset = 0;
        if (count % 2 != 0 && idx == count / 2) {
            offset += LinguaFrancaShapeExtensions.REACTION_POINTINESS;
        } else if (idx < count / 2) {
            offset += segments * (idx + 1);
        } else {
            offset += segments * (count - idx);
        }
        if (!input) {
            // reverse
            offset -= LinguaFrancaShapeExtensions.REACTION_POINTINESS;
        }
        // apply
        port.setPos(port.getXpos() + offset, port.getYpos());
        for (KEdge edge : port.getEdges()) {
            if (input) {
                edge.setTargetPoint(adjustedKPoint(edge.getTargetPoint(), offset));
            } else {
                edge.setSourcePoint(adjustedKPoint(edge.getSourcePoint(), offset));
            }
        }
    }
}
Also used : KEdge(de.cau.cs.kieler.klighd.kgraph.KEdge) KPort(de.cau.cs.kieler.klighd.kgraph.KPort) KPoint(de.cau.cs.kieler.klighd.kgraph.KPoint)

Example 10 with KEdge

use of de.cau.cs.kieler.klighd.kgraph.KEdge in project lingua-franca by lf-lang.

the class LinguaFrancaSynthesis method addErrorComment.

private KNode addErrorComment(KNode node, String message) {
    KNode comment = _kNodeExtensions.createNode();
    setLayoutOption(comment, CoreOptions.COMMENT_BOX, true);
    KRoundedRectangle commentFigure = _linguaFrancaShapeExtensions.addCommentFigure(comment, message);
    _linguaFrancaStyleExtensions.errorStyle(commentFigure);
    _kRenderingExtensions.setBackground(commentFigure, Colors.PEACH_PUFF_2);
    // connect
    KEdge edge = _kEdgeExtensions.createEdge();
    edge.setSource(comment);
    edge.setTarget(node);
    _linguaFrancaStyleExtensions.errorStyle(_linguaFrancaShapeExtensions.addCommentPolyline(edge));
    return comment;
}
Also used : KEdge(de.cau.cs.kieler.klighd.kgraph.KEdge) KNode(de.cau.cs.kieler.klighd.kgraph.KNode) KRoundedRectangle(de.cau.cs.kieler.klighd.krendering.KRoundedRectangle)

Aggregations

KEdge (de.cau.cs.kieler.klighd.kgraph.KEdge)15 KNode (de.cau.cs.kieler.klighd.kgraph.KNode)8 KPolyline (de.cau.cs.kieler.klighd.krendering.KPolyline)6 KPort (de.cau.cs.kieler.klighd.kgraph.KPort)5 HashMap (java.util.HashMap)4 KRendering (de.cau.cs.kieler.klighd.krendering.KRendering)3 KRoundedRectangle (de.cau.cs.kieler.klighd.krendering.KRoundedRectangle)3 KText (de.cau.cs.kieler.klighd.krendering.KText)3 HashSet (java.util.HashSet)3 ElkPadding (org.eclipse.elk.core.math.ElkPadding)3 ReactorInstance (org.lflang.generator.ReactorInstance)3 Iterables (com.google.common.collect.Iterables)2 KLabel (de.cau.cs.kieler.klighd.kgraph.KLabel)2 KRectangle (de.cau.cs.kieler.klighd.krendering.KRectangle)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 LayerConstraint (org.eclipse.elk.alg.layered.options.LayerConstraint)2 SizeConstraint (org.eclipse.elk.core.options.SizeConstraint)2 Property (org.eclipse.elk.graph.properties.Property)2 IterableExtensions (org.eclipse.xtext.xbase.lib.IterableExtensions)2