Search in sources :

Example 1 with ReactorInstance

use of org.lflang.generator.ReactorInstance in project lingua-franca by lf-lang.

the class ModelInfo method update.

/**
 * Redo all analysis based on the given model.
 *
 * @param model the model to analyze.
 */
public void update(Model model, ErrorReporter reporter) {
    this.updated = true;
    this.model = model;
    this.instantiationGraph = new InstantiationGraph(model, true);
    if (this.instantiationGraph.getCycles().size() == 0) {
        List<ReactorInstance> topLevelReactorInstances = new LinkedList<>();
        var main = model.getReactors().stream().filter(it -> it.isMain() || it.isFederated()).findFirst();
        if (main.isPresent()) {
            var inst = new ReactorInstance(main.get(), reporter);
            topLevelReactorInstances.add(inst);
        } else {
            model.getReactors().forEach(it -> topLevelReactorInstances.add(new ReactorInstance(it, reporter)));
        }
        // don't store the graph into a field, only the cycles.
        for (ReactorInstance top : topLevelReactorInstances) {
            this.topologyCycles.addAll(top.getCycles());
        }
    }
    // may be null if the target is invalid
    var target = Target.forName(model.getTarget().getName()).orElse(null);
    // Perform C-specific traversals.
    if (target == Target.C) {
        this.collectOverflowingNodes();
    }
}
Also used : Model(org.lflang.lf.Model) Deadline(org.lflang.lf.Deadline) IteratorExtensions.toIterable(org.eclipse.xtext.xbase.lib.IteratorExtensions.toIterable) Set(java.util.Set) IterableExtensions.filter(org.eclipse.xtext.xbase.lib.IterableExtensions.filter) NamedInstance(org.lflang.generator.NamedInstance) STP(org.lflang.lf.STP) HashSet(java.util.HashSet) ReactorInstance(org.lflang.generator.ReactorInstance) Parameter(org.lflang.lf.Parameter) List(java.util.List) Reactor(org.lflang.lf.Reactor) Assignment(org.lflang.lf.Assignment) Instantiation(org.lflang.lf.Instantiation) LinkedList(java.util.LinkedList) LinkedHashSet(java.util.LinkedHashSet) InstantiationGraph(org.lflang.graph.InstantiationGraph) ReactorInstance(org.lflang.generator.ReactorInstance) InstantiationGraph(org.lflang.graph.InstantiationGraph) LinkedList(java.util.LinkedList)

Example 2 with ReactorInstance

use of org.lflang.generator.ReactorInstance in project lingua-franca by lf-lang.

the class PortInstanceTests method createRange.

@Test
public void createRange() throws Exception {
    Reactor main = factory.createReactor();
    ReactorInstance maini = new ReactorInstance(main, reporter);
    ReactorInstance a = newReactor("A", maini);
    ReactorInstance b = newReactor("B", maini);
    ReactorInstance c = newReactor("C", maini);
    PortInstance p = newOutputPort("p", a);
    PortInstance q = newInputPort("q", b);
    PortInstance r = newInputPort("r", c);
    Assertions.assertEquals(".A.p", p.getFullName());
    connect(p, q);
    connect(p, r);
    List<SendRange> sr = p.eventualDestinations();
    // Destinations should be empty because there are no reactions.
    Assertions.assertEquals("[]", sr.toString());
    // Clear caches to make a mutation.
    maini.clearCaches();
    newReaction(q);
    // Re-retrieve destinations.
    sr = p.eventualDestinations();
    Assertions.assertEquals("[.A.p(0,1)->[.B.q(0,1)]]", sr.toString());
    maini.clearCaches();
    newReaction(r);
    // Re-retrieve destinations.
    sr = p.eventualDestinations();
    Assertions.assertEquals("[.A.p(0,1)->[.B.q(0,1), .C.r(0,1)]]", sr.toString());
    // Now test multiports.
    p.setWidth(3);
    r.setWidth(2);
    // Have to redo the connections.
    clearConnections(maini);
    maini.clearCaches();
    connect(p, 0, 1, q, 0, 1);
    connect(p, 1, 2, r, 0, 2);
    // Re-retrieve destinations.
    sr = p.eventualDestinations();
    Assertions.assertEquals("[.A.p(0,1)->[.B.q(0,1)], .A.p(1,2)->[.C.r(0,2)]]", sr.toString());
    // More complicated multiport connection.
    clearConnections(maini);
    maini.clearCaches();
    ReactorInstance d = newReactor("D", maini);
    PortInstance v = newOutputPort("v", d);
    v.setWidth(2);
    q.setWidth(3);
    connect(v, 0, 2, q, 0, 2);
    connect(p, 0, 1, q, 2, 1);
    connect(p, 1, 2, r, 0, 2);
    sr = p.eventualDestinations();
    Assertions.assertEquals("[.A.p(0,1)->[.B.q(2,1)], .A.p(1,2)->[.C.r(0,2)]]", sr.toString());
    // Additional multicast connection.
    maini.clearCaches();
    ReactorInstance e = newReactor("E", maini);
    PortInstance s = newPort("s", e);
    s.setWidth(3);
    newReaction(s);
    connect(p, s);
    sr = p.eventualDestinations();
    Assertions.assertEquals("[.A.p(0,1)->[.B.q(2,1), .E.s(0,1)], .A.p(1,2)->[.C.r(0,2), .E.s(1,2)]]", sr.toString());
    // Add hierarchical reactors that further split the ranges.
    maini.clearCaches();
    ReactorInstance f = newReactor("F", e);
    PortInstance t = newPort("t", f);
    newReaction(t);
    ReactorInstance g = newReactor("G", e);
    PortInstance u = newPort("u", g);
    u.setWidth(2);
    newReaction(u);
    connect(s, 0, 1, t, 0, 1);
    connect(s, 1, 2, u, 0, 2);
    sr = p.eventualDestinations();
    // FIXME: Multicast destinations should be able to be reported in arbitrary order.
    Assertions.assertEquals("[.A.p(0,1)->[.E.F.t(0,1), .E.s(0,1), .B.q(2,1)], .A.p(1,2)->[.E.G.u(0,2), .E.s(1,2), .C.r(0,2)]]", sr.toString());
}
Also used : PortInstance(org.lflang.generator.PortInstance) ReactorInstance(org.lflang.generator.ReactorInstance) Reactor(org.lflang.lf.Reactor) SendRange(org.lflang.generator.SendRange) Test(org.junit.jupiter.api.Test)

Example 3 with ReactorInstance

use of org.lflang.generator.ReactorInstance in project lingua-franca by lf-lang.

the class PythonReactorGenerator method generatePythonClass.

/**
 * Generate a Python class corresponding to decl
 * @param instance The reactor instance to be generated
 * @param pythonClasses The class definition is appended to this code builder
 * @param federate The federate instance for the reactor instance
 * @param instantiatedClasses A list of visited instances to avoid generating duplicates
 */
public static String generatePythonClass(ReactorInstance instance, FederateInstance federate, List<String> instantiatedClasses, ReactorInstance main, PythonTypes types) {
    CodeBuilder pythonClasses = new CodeBuilder();
    ReactorDecl decl = instance.getDefinition().getReactorClass();
    Reactor reactor = ASTUtils.toDefinition(decl);
    String className = instance.getDefinition().getReactorClass().getName();
    if (instance != main && !federate.contains(instance) || instantiatedClasses == null || // Do not generate code for delay reactors in Python
    className.contains(GeneratorBase.GEN_DELAY_CLASS_NAME)) {
        return "";
    }
    if (federate.contains(instance) && !instantiatedClasses.contains(className)) {
        pythonClasses.pr(generatePythonClassHeader(className));
        // Generate preamble code
        pythonClasses.indent();
        pythonClasses.pr(PythonPreambleGenerator.generatePythonPreambles(reactor.getPreambles()));
        // Handle runtime initializations
        pythonClasses.pr(generatePythonConstructor(decl, types));
        pythonClasses.pr(PythonParameterGenerator.generatePythonGetters(decl));
        List<Reaction> reactionToGenerate = ASTUtils.allReactions(reactor);
        if (reactor.isFederated()) {
            // Filter out reactions that are automatically generated in C in the top level federated reactor
            reactionToGenerate.removeIf(it -> !federate.contains(it) || federate.networkReactions.contains(it));
        }
        pythonClasses.pr(PythonReactionGenerator.generatePythonReactions(reactor, reactionToGenerate));
        pythonClasses.unindent();
        instantiatedClasses.add(className);
    }
    for (ReactorInstance child : instance.children) {
        pythonClasses.pr(generatePythonClass(child, federate, instantiatedClasses, main, types));
    }
    return pythonClasses.getCode();
}
Also used : ReactorInstance(org.lflang.generator.ReactorInstance) ReactorDecl(org.lflang.lf.ReactorDecl) Reactor(org.lflang.lf.Reactor) Reaction(org.lflang.lf.Reaction) CodeBuilder(org.lflang.generator.CodeBuilder)

Example 4 with ReactorInstance

use of org.lflang.generator.ReactorInstance in project lingua-franca by lf-lang.

the class PythonReactorGenerator method generateListsToHoldClassInstances.

/**
 * Generate code to instantiate a Python list that will hold the Python
 * class instance of reactor <code>instance<code>. Will recursively do
 * the same for the children of <code>instance<code> as well.
 *
 * @param instance The reactor instance for which the Python list will be created.
 * @param federate Will check if <code>instance<code> (or any of its children) belong to
 *  <code>federate<code> before generating code for them.
 */
public static String generateListsToHoldClassInstances(ReactorInstance instance, FederateInstance federate) {
    CodeBuilder code = new CodeBuilder();
    if (federate != null && !federate.contains(instance)) {
        return "";
    }
    code.pr(PyUtil.reactorRefName(instance) + " = [None] * " + instance.getTotalWidth());
    for (ReactorInstance child : instance.children) {
        code.pr(generateListsToHoldClassInstances(child, federate));
    }
    return code.toString();
}
Also used : ReactorInstance(org.lflang.generator.ReactorInstance) CodeBuilder(org.lflang.generator.CodeBuilder)

Example 5 with ReactorInstance

use of org.lflang.generator.ReactorInstance in project lingua-franca by lf-lang.

the class LinguaFrancaShapeExtensions method addReactorFigure.

/**
 * Creates the visual representation of a reactor node
 */
public ReactorFigureComponents addReactorFigure(KNode node, ReactorInstance reactorInstance, String text) {
    int padding = getBooleanValue(LinguaFrancaSynthesis.SHOW_HYPERLINKS) ? 8 : 6;
    Function1<KRoundedRectangle, KRendering> style = r -> {
        _kRenderingExtensions.setLineWidth(r, 1);
        _kRenderingExtensions.setForeground(r, Colors.GRAY);
        _kRenderingExtensions.setBackground(r, Colors.GRAY_95);
        return _linguaFrancaStyleExtensions.boldLineSelectionStyle(r);
    };
    KRoundedRectangle figure = _kRenderingExtensions.addRoundedRectangle(node, 8, 8, 1);
    _kContainerRenderingExtensions.setGridPlacement(figure, 1);
    style.apply(figure);
    figure.setProperty(REACTOR_CONTENT_CONTAINER, true);
    // minimal node size is necessary if no text will be added
    List<Float> minSize = List.of(2 * figure.getCornerWidth(), 2 * figure.getCornerHeight());
    _kNodeExtensions.setMinimalNodeSize(node, minSize.get(0), minSize.get(1));
    // Add parent container
    KRectangle parentContainer = _kContainerRenderingExtensions.addRectangle(figure);
    _kRenderingExtensions.setInvisible(parentContainer, true);
    setGridPlacementDataFromPointToPoint(parentContainer, LEFT, padding, 0, TOP, padding, 0, RIGHT, padding, 0, BOTTOM, _utilityExtensions.hasContent(reactorInstance) ? 4 : padding, 0);
    // Add centered child container
    KRectangle childContainer = _kContainerRenderingExtensions.addRectangle(parentContainer);
    _kRenderingExtensions.setInvisible(childContainer, true);
    _kRenderingExtensions.setPointPlacementData(childContainer, _kRenderingExtensions.LEFT, 0, 0.5f, _kRenderingExtensions.TOP, 0, 0.5f, _kRenderingExtensions.H_CENTRAL, _kRenderingExtensions.V_CENTRAL, 0, 0, 0, 0);
    KGridPlacement placement = _kContainerRenderingExtensions.setGridPlacement(childContainer, 1);
    KText childText = _kContainerRenderingExtensions.addText(childContainer, text);
    DiagramSyntheses.suppressSelectability(childText);
    _linguaFrancaStyleExtensions.underlineSelectionStyle(childText);
    if (!_utilityExtensions.isRoot(reactorInstance) && reactorInstance.getDefinition().getHost() != null) {
        KRendering cloudUploadIcon = _linguaFrancaStyleExtensions.addCloudUploadIcon(childContainer);
        setGridPlacementDataFromPointToPoint(cloudUploadIcon, LEFT, 3, 0, TOP, 0, 0, RIGHT, 0, 0, BOTTOM, 0, 0);
        placement.setNumColumns(2);
        if (getBooleanValue(LinguaFrancaSynthesis.SHOW_REACTOR_HOST)) {
            KText reactorHostText = _kContainerRenderingExtensions.addText(childContainer, _utilityExtensions.toText(reactorInstance.getDefinition().getHost()));
            DiagramSyntheses.suppressSelectability(reactorHostText);
            _linguaFrancaStyleExtensions.underlineSelectionStyle(reactorHostText);
            setGridPlacementDataFromPointToPoint(reactorHostText, LEFT, 3, 0, TOP, 0, 0, RIGHT, 0, 0, BOTTOM, 0, 0);
            placement.setNumColumns(3);
        }
    }
    if (reactorInstance.isBank()) {
        List<KRendering> bank = new ArrayList<>();
        KContainerRendering container = _kRenderingExtensions.addInvisibleContainerRendering(node);
        // TODO handle unresolved width
        KRoundedRectangle banks;
        banks = _kContainerRenderingExtensions.addRoundedRectangle(container, 8, 8, 1);
        style.apply(banks);
        setGridPlacementDataFromPointToPoint(banks, LEFT, BANK_FIGURE_X_OFFSET_SUM, 0, TOP, BANK_FIGURE_Y_OFFSET_SUM, 0, RIGHT, 0, 0, BOTTOM, 0, 0);
        if (reactorInstance.getWidth() == 3) {
            banks = _kContainerRenderingExtensions.addRoundedRectangle(container, 8, 8, 1);
            style.apply(banks);
            setGridPlacementDataFromPointToPoint(banks, LEFT, BANK_FIGURE_X_OFFSET_SUM / 2, 0, TOP, BANK_FIGURE_Y_OFFSET_SUM / 2, 0, RIGHT, BANK_FIGURE_X_OFFSET_SUM / 2, 0, BOTTOM, BANK_FIGURE_Y_OFFSET_SUM / 2, 0);
        } else if (reactorInstance.getWidth() != 2 && reactorInstance.getWidth() != 3) {
            banks = _kContainerRenderingExtensions.addRoundedRectangle(container, 8, 8, 1);
            style.apply(banks);
            setGridPlacementDataFromPointToPoint(banks, LEFT, 2 * BANK_FIGURE_X_OFFSET_SUM / 3, 0, TOP, 2 * BANK_FIGURE_Y_OFFSET_SUM / 3, 0, RIGHT, BANK_FIGURE_X_OFFSET_SUM / 3, 0, BOTTOM, BANK_FIGURE_Y_OFFSET_SUM / 3, 0);
            banks = _kContainerRenderingExtensions.addRoundedRectangle(container, 8, 8, 1);
            style.apply(banks);
            setGridPlacementDataFromPointToPoint(banks, LEFT, BANK_FIGURE_X_OFFSET_SUM / 3, 0, TOP, BANK_FIGURE_Y_OFFSET_SUM / 3, 0, RIGHT, 2 * BANK_FIGURE_X_OFFSET_SUM / 3, 0, BOTTOM, 2 * BANK_FIGURE_Y_OFFSET_SUM / 3, 0);
        }
        container.getChildren().add(figure);
        setGridPlacementDataFromPointToPoint(figure, LEFT, 0, 0, TOP, 0, 0, RIGHT, BANK_FIGURE_X_OFFSET_SUM, 0, BOTTOM, BANK_FIGURE_Y_OFFSET_SUM, 0);
        bank.addAll(container.getChildren());
        KRectangle widthLabelContainer = _kContainerRenderingExtensions.addRectangle(container);
        _kRenderingExtensions.setInvisible(widthLabelContainer, true);
        setGridPlacementDataFromPointToPoint(widthLabelContainer, LEFT, 12, 0, BOTTOM, 9, 0, RIGHT, 6, 0, BOTTOM, 0.5f, 0);
        // Handle unresolved width.
        String widthLabel = reactorInstance.getWidth() >= 0 ? Integer.toString(reactorInstance.getWidth()) : "?";
        KText widthLabelText = _kContainerRenderingExtensions.addText(widthLabelContainer, widthLabel);
        _kRenderingExtensions.setHorizontalAlignment(widthLabelText, HorizontalAlignment.LEFT);
        _kRenderingExtensions.setVerticalAlignment(widthLabelText, VerticalAlignment.BOTTOM);
        _kRenderingExtensions.setFontSize(widthLabelText, 6);
        _linguaFrancaStyleExtensions.noSelectionStyle(widthLabelText);
        associateWith(widthLabelText, reactorInstance.getDefinition().getWidthSpec());
        return new ReactorFigureComponents(container, figure, bank);
    } else {
        return new ReactorFigureComponents(figure, figure, List.of(figure));
    }
}
Also used : CoreOptions(org.eclipse.elk.core.options.CoreOptions) KArc(de.cau.cs.kieler.klighd.krendering.KArc) Arc(de.cau.cs.kieler.klighd.krendering.Arc) PortSide(org.eclipse.elk.core.options.PortSide) KLabelExtensions(de.cau.cs.kieler.klighd.krendering.extensions.KLabelExtensions) Extension(org.eclipse.xtext.xbase.lib.Extension) AbstractSynthesisExtensions(org.lflang.diagram.synthesis.AbstractSynthesisExtensions) KEdgeExtensions(de.cau.cs.kieler.klighd.krendering.extensions.KEdgeExtensions) KAreaPlacementData(de.cau.cs.kieler.klighd.krendering.KAreaPlacementData) KContainerRenderingExtensions(de.cau.cs.kieler.klighd.krendering.extensions.KContainerRenderingExtensions) KRenderingExtensions(de.cau.cs.kieler.klighd.krendering.extensions.KRenderingExtensions) KDecoratorPlacementData(de.cau.cs.kieler.klighd.krendering.KDecoratorPlacementData) KPolyline(de.cau.cs.kieler.klighd.krendering.KPolyline) LineStyle(de.cau.cs.kieler.klighd.krendering.LineStyle) VerticalAlignment(de.cau.cs.kieler.klighd.krendering.VerticalAlignment) LinguaFrancaSynthesis(org.lflang.diagram.synthesis.LinguaFrancaSynthesis) PositionReferenceY(de.cau.cs.kieler.klighd.krendering.extensions.PositionReferenceY) PositionReferenceX(de.cau.cs.kieler.klighd.krendering.extensions.PositionReferenceX) DiagramSyntheses(de.cau.cs.kieler.klighd.syntheses.DiagramSyntheses) KPolygon(de.cau.cs.kieler.klighd.krendering.KPolygon) KEdge(de.cau.cs.kieler.klighd.kgraph.KEdge) KPolylineExtensions(de.cau.cs.kieler.klighd.krendering.extensions.KPolylineExtensions) KPortExtensions(de.cau.cs.kieler.klighd.krendering.extensions.KPortExtensions) KEllipse(de.cau.cs.kieler.klighd.krendering.KEllipse) List(java.util.List) UtilityExtensions(org.lflang.diagram.synthesis.util.UtilityExtensions) KColorExtensions(de.cau.cs.kieler.klighd.krendering.extensions.KColorExtensions) Pair(org.eclipse.xtext.xbase.lib.Pair) StringExtensions(org.eclipse.xtext.xbase.lib.StringExtensions) KGridPlacement(de.cau.cs.kieler.klighd.krendering.KGridPlacement) KPosition(de.cau.cs.kieler.klighd.krendering.KPosition) KNodeExtensions(de.cau.cs.kieler.klighd.krendering.extensions.KNodeExtensions) ReactionPortAdjustment(org.lflang.diagram.synthesis.postprocessor.ReactionPortAdjustment) ArrayList(java.util.ArrayList) Inject(javax.inject.Inject) KlighdConstants(de.cau.cs.kieler.klighd.KlighdConstants) KRendering(de.cau.cs.kieler.klighd.krendering.KRendering) TimerInstance(org.lflang.generator.TimerInstance) KText(de.cau.cs.kieler.klighd.krendering.KText) KNode(de.cau.cs.kieler.klighd.kgraph.KNode) KPort(de.cau.cs.kieler.klighd.kgraph.KPort) KRoundedRectangle(de.cau.cs.kieler.klighd.krendering.KRoundedRectangle) Property(org.eclipse.elk.graph.properties.Property) KRenderingFactory(de.cau.cs.kieler.klighd.krendering.KRenderingFactory) KContainerRendering(de.cau.cs.kieler.klighd.krendering.KContainerRendering) ReactionInstance(org.lflang.generator.ReactionInstance) ReactorInstance(org.lflang.generator.ReactorInstance) IterableExtensions(org.eclipse.xtext.xbase.lib.IterableExtensions) ViewSynthesisShared(de.cau.cs.kieler.klighd.krendering.ViewSynthesisShared) KRectangle(de.cau.cs.kieler.klighd.krendering.KRectangle) Colors(de.cau.cs.kieler.klighd.krendering.Colors) HorizontalAlignment(de.cau.cs.kieler.klighd.krendering.HorizontalAlignment) Function1(org.eclipse.xtext.xbase.lib.Functions.Function1) ArrayList(java.util.ArrayList) KContainerRendering(de.cau.cs.kieler.klighd.krendering.KContainerRendering) KRoundedRectangle(de.cau.cs.kieler.klighd.krendering.KRoundedRectangle) KGridPlacement(de.cau.cs.kieler.klighd.krendering.KGridPlacement) KRectangle(de.cau.cs.kieler.klighd.krendering.KRectangle) KText(de.cau.cs.kieler.klighd.krendering.KText) KRendering(de.cau.cs.kieler.klighd.krendering.KRendering)

Aggregations

ReactorInstance (org.lflang.generator.ReactorInstance)16 Reactor (org.lflang.lf.Reactor)10 PortInstance (org.lflang.generator.PortInstance)7 KEdge (de.cau.cs.kieler.klighd.kgraph.KEdge)6 KNode (de.cau.cs.kieler.klighd.kgraph.KNode)6 KPort (de.cau.cs.kieler.klighd.kgraph.KPort)6 SendRange (org.lflang.generator.SendRange)6 KRendering (de.cau.cs.kieler.klighd.krendering.KRendering)5 ArrayList (java.util.ArrayList)5 KPolyline (de.cau.cs.kieler.klighd.krendering.KPolyline)4 KRectangle (de.cau.cs.kieler.klighd.krendering.KRectangle)4 KText (de.cau.cs.kieler.klighd.krendering.KText)4 KLabel (de.cau.cs.kieler.klighd.kgraph.KLabel)3 Colors (de.cau.cs.kieler.klighd.krendering.Colors)3 HorizontalAlignment (de.cau.cs.kieler.klighd.krendering.HorizontalAlignment)3 KContainerRendering (de.cau.cs.kieler.klighd.krendering.KContainerRendering)3 KRoundedRectangle (de.cau.cs.kieler.klighd.krendering.KRoundedRectangle)3 LineStyle (de.cau.cs.kieler.klighd.krendering.LineStyle)3 EObject (org.eclipse.emf.ecore.EObject)3 Model (org.lflang.lf.Model)3