use of org.lflang.generator.PortInstance in project lingua-franca by lf-lang.
the class CTriggerObjectsGenerator method deferredCreateDefaultTokens.
/**
* For each output of the specified reactor that has a token type
* (type* or type[]), create a default token and put it on the self struct.
* @param parent The reactor.
*/
private static String deferredCreateDefaultTokens(ReactorInstance reactor, CTypes types) {
var code = new CodeBuilder();
// Look for outputs with token types.
for (PortInstance output : reactor.outputs) {
var type = ASTUtils.getInferredType(output.getDefinition());
if (CUtil.isTokenType(type, types)) {
// Create the template token that goes in the trigger struct.
// Its reference count is zero, enabling it to be used immediately.
var rootType = CUtil.rootType(types.getTargetType(type));
// If the rootType is 'void', we need to avoid generating the code
// 'sizeof(void)', which some compilers reject.
var size = (rootType.equals("void")) ? "0" : "sizeof(" + rootType + ")";
code.startChannelIteration(output);
code.pr(CUtil.portRef(output) + ".token = _lf_create_token(" + size + ");");
code.endChannelIteration(output);
}
}
return code.toString();
}
use of org.lflang.generator.PortInstance 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());
}
use of org.lflang.generator.PortInstance in project lingua-franca by lf-lang.
the class RangeTests method createRange.
@Test
public void createRange() throws Exception {
Reactor main = factory.createReactor();
ReactorInstance maini = new ReactorInstance(main, reporter);
Reactor a = factory.createReactor();
a.setName("A");
ReactorInstance ai = new ReactorInstance(a, maini, reporter);
ai.setWidth(2);
Reactor b = factory.createReactor();
b.setName("B");
ReactorInstance bi = new ReactorInstance(b, ai, reporter);
bi.setWidth(2);
Port p = factory.createPort();
p.setName("P");
PortInstance pi = new PortInstance(p, bi, reporter);
pi.setWidth(2);
Assertions.assertEquals(".A.B.P", pi.getFullName());
RuntimeRange<PortInstance> range = new RuntimeRange.Port(pi, 3, 4, null);
Assertions.assertEquals(8, range.maxWidth);
Assertions.assertEquals(".A.B.P(3,4)", range.toString());
// The results expected below are derived from the class comment for RuntimeRange,
// which includes this example.
List<Integer> instances = range.instances();
Assertions.assertEquals(List.of(3, 4, 5, 6), instances);
Set<Integer> parents = range.parentInstances(1);
Assertions.assertEquals(Set.of(1, 2, 3), parents);
parents = range.parentInstances(2);
Assertions.assertEquals(Set.of(0, 1), parents);
// Test startMR().getDigits.
Assertions.assertEquals(List.of(1, 1, 0), range.startMR().getDigits());
// Create a SendRange sending from and to this range.
SendRange sendRange = new SendRange(pi, 3, 4, null, null);
sendRange.destinations.add(range);
// Test getNumberOfDestinationReactors.
Assertions.assertEquals(3, sendRange.getNumberOfDestinationReactors());
// Make first interleaved version.
range = range.toggleInterleaved(bi);
instances = range.instances();
Assertions.assertEquals(List.of(3, 4, 6, 5), instances);
// Test startMR().getDigits.
Assertions.assertEquals(List.of(1, 1, 0), range.startMR().getDigits());
// Make second interleaved version.
range = range.toggleInterleaved(ai);
instances = range.instances();
Assertions.assertEquals(List.of(6, 1, 5, 3), instances);
// Test startMR().getDigits.
Assertions.assertEquals(List.of(0, 1, 1), range.startMR().getDigits());
// Test instances of the parent.
Assertions.assertEquals(Set.of(3, 0, 2, 1), range.parentInstances(1));
// Add this range to the sendRange destinations and verify
// that the number of destination reactors becomes 4.
sendRange.addDestination(range);
Assertions.assertEquals(4, sendRange.getNumberOfDestinationReactors());
// Make third interleaved version.
range = range.toggleInterleaved(bi);
instances = range.instances();
Assertions.assertEquals(List.of(5, 2, 6, 3), instances);
// Test startMR().getDigits.
Assertions.assertEquals(List.of(1, 0, 1), range.startMR().getDigits());
}
use of org.lflang.generator.PortInstance in project lingua-franca by lf-lang.
the class LinguaFrancaSynthesis method transformReactorNetwork.
private Collection<KNode> transformReactorNetwork(ReactorInstance reactorInstance, Map<PortInstance, KPort> parentInputPorts, Map<PortInstance, KPort> parentOutputPorts, Map<ReactorInstance, KNode> allReactorNodes) {
List<KNode> nodes = new ArrayList<>();
Table<ReactorInstance, PortInstance, KPort> inputPorts = HashBasedTable.create();
Table<ReactorInstance, PortInstance, KPort> outputPorts = HashBasedTable.create();
Map<ReactionInstance, KNode> reactionNodes = new HashMap<>();
Map<KPort, KNode> directConnectionDummyNodes = new HashMap<>();
Multimap<ActionInstance, KPort> actionDestinations = HashMultimap.create();
Multimap<ActionInstance, KPort> actionSources = HashMultimap.create();
Map<TimerInstance, KNode> timerNodes = new HashMap<>();
KNode startupNode = _kNodeExtensions.createNode();
boolean startupUsed = false;
KNode shutdownNode = _kNodeExtensions.createNode();
boolean shutdownUsed = false;
// Transform instances
int index = 0;
for (ReactorInstance child : reactorInstance.children) {
Boolean expansionState = MemorizingExpandCollapseAction.getExpansionState(child);
Collection<KNode> rNodes = createReactorNode(child, expansionState != null ? expansionState : false, inputPorts, outputPorts, allReactorNodes);
nodes.addAll(rNodes);
index++;
}
// Create timers
for (TimerInstance timer : reactorInstance.timers) {
KNode node = associateWith(_kNodeExtensions.createNode(), timer.getDefinition());
NamedInstanceUtil.linkInstance(node, timer);
_utilityExtensions.setID(node, timer.uniqueID());
nodes.add(node);
Iterables.addAll(nodes, createUserComments(timer.getDefinition(), node));
timerNodes.put(timer, node);
_linguaFrancaShapeExtensions.addTimerFigure(node, timer);
}
// Create reactions
for (ReactionInstance reaction : reactorInstance.reactions) {
int idx = reactorInstance.reactions.indexOf(reaction);
KNode node = associateWith(_kNodeExtensions.createNode(), reaction.getDefinition());
NamedInstanceUtil.linkInstance(node, reaction);
_utilityExtensions.setID(node, reaction.uniqueID());
nodes.add(node);
Iterables.addAll(nodes, createUserComments(reaction.getDefinition(), node));
reactionNodes.put(reaction, node);
setLayoutOption(node, CoreOptions.PORT_CONSTRAINTS, PortConstraints.FIXED_SIDE);
// try order reactions vertically if in one layer (+1 to account for startup)
setLayoutOption(node, LayeredOptions.POSITION, new KVector(0, idx + 1));
var figure = _linguaFrancaShapeExtensions.addReactionFigure(node, reaction);
int inputSize = Stream.concat(reaction.triggers.stream(), reaction.sources.stream()).collect(Collectors.toSet()).size();
int outputSize = reaction.effects.size();
if (!getBooleanValue(REACTIONS_USE_HYPEREDGES) && (inputSize > 1 || outputSize > 1)) {
// If this node will have more than one input/output port, the port positions must be adjusted to the
// pointy shape. However, this is only possible after the layout.
ReactionPortAdjustment.apply(node, figure);
}
// connect input
KPort port = null;
for (TriggerInstance<?> trigger : reaction.triggers) {
// Create new port if there is no previous one or each dependency should have its own one
if (port == null || !getBooleanValue(REACTIONS_USE_HYPEREDGES)) {
port = addInvisiblePort(node);
setLayoutOption(port, CoreOptions.PORT_SIDE, PortSide.WEST);
if (getBooleanValue(REACTIONS_USE_HYPEREDGES) || inputSize == 1) {
// manual adjustment disabling automatic one
setLayoutOption(port, CoreOptions.PORT_BORDER_OFFSET, (double) -LinguaFrancaShapeExtensions.REACTION_POINTINESS);
}
}
if (trigger.isStartup()) {
connect(createDependencyEdge(((TriggerInstance.BuiltinTriggerVariable) trigger.getDefinition()).definition), startupNode, port);
startupUsed = true;
} else if (trigger.isShutdown()) {
connect(createDelayEdge(((TriggerInstance.BuiltinTriggerVariable) trigger.getDefinition()).definition), shutdownNode, port);
shutdownUsed = true;
} else if (trigger instanceof ActionInstance) {
actionDestinations.put(((ActionInstance) trigger), port);
} else if (trigger instanceof PortInstance) {
KPort src = null;
PortInstance triggerAsPort = (PortInstance) trigger;
if (triggerAsPort.getParent() == reactorInstance) {
src = parentInputPorts.get(trigger);
} else {
src = outputPorts.get(triggerAsPort.getParent(), trigger);
}
if (src != null) {
connect(createDependencyEdge(triggerAsPort.getDefinition()), src, port);
}
} else if (trigger instanceof TimerInstance) {
KNode src = timerNodes.get(trigger);
if (src != null) {
connect(createDependencyEdge(trigger.getDefinition()), src, port);
}
}
}
// connect dependencies
for (TriggerInstance<?> dep : reaction.sources) {
// skip
if (reaction.triggers.contains(dep))
continue;
// Create new port if there is no previous one or each dependency should have its own one
if (port == null || !getBooleanValue(REACTIONS_USE_HYPEREDGES)) {
port = addInvisiblePort(node);
setLayoutOption(port, CoreOptions.PORT_SIDE, PortSide.WEST);
if (getBooleanValue(REACTIONS_USE_HYPEREDGES) || inputSize == 1) {
// manual adjustment disabling automatic one
setLayoutOption(port, CoreOptions.PORT_BORDER_OFFSET, (double) -LinguaFrancaShapeExtensions.REACTION_POINTINESS);
}
}
if (dep instanceof PortInstance) {
KPort src = null;
PortInstance depAsPort = (PortInstance) dep;
if (dep.getParent() == reactorInstance) {
src = parentInputPorts.get(dep);
} else {
src = outputPorts.get(depAsPort.getParent(), dep);
}
if (src != null) {
connect(createDependencyEdge(dep.getDefinition()), src, port);
}
}
}
// connect outputs
// enforce new ports for outputs
port = null;
Set<TriggerInstance<?>> iterSet = reaction.effects != null ? reaction.effects : new HashSet<>();
for (TriggerInstance<?> effect : iterSet) {
// Create new port if there is no previous one or each dependency should have its own one
if (port == null || !getBooleanValue(REACTIONS_USE_HYPEREDGES)) {
port = addInvisiblePort(node);
setLayoutOption(port, CoreOptions.PORT_SIDE, PortSide.EAST);
}
if (effect instanceof ActionInstance) {
actionSources.put((ActionInstance) effect, port);
} else if (effect instanceof PortInstance) {
KPort dst = null;
PortInstance effectAsPort = (PortInstance) effect;
if (effectAsPort.isOutput()) {
dst = parentOutputPorts.get(effect);
} else {
dst = inputPorts.get(effectAsPort.getParent(), effect);
}
if (dst != null) {
connect(createDependencyEdge(effect), port, dst);
}
}
}
}
// Connect actions
Set<ActionInstance> actions = new HashSet<>();
actions.addAll(actionSources.keySet());
actions.addAll(actionDestinations.keySet());
for (ActionInstance action : actions) {
KNode node = associateWith(_kNodeExtensions.createNode(), action.getDefinition());
NamedInstanceUtil.linkInstance(node, action);
_utilityExtensions.setID(node, action.uniqueID());
nodes.add(node);
Iterables.addAll(nodes, createUserComments(action.getDefinition(), node));
setLayoutOption(node, CoreOptions.PORT_CONSTRAINTS, PortConstraints.FIXED_SIDE);
Pair<KPort, KPort> ports = _linguaFrancaShapeExtensions.addActionFigureAndPorts(node, action.isPhysical() ? "P" : "L");
// TODO handle variables?
if (action.getMinDelay() != null && action.getMinDelay() != ActionInstance.DEFAULT_MIN_DELAY) {
_kLabelExtensions.addOutsideBottomCenteredNodeLabel(node, String.format("min delay: %s", action.getMinDelay().toString()), 7);
}
// TODO default value?
if (action.getDefinition().getMinSpacing() != null) {
_kLabelExtensions.addOutsideBottomCenteredNodeLabel(node, String.format("min spacing: %s", action.getMinSpacing().toString()), 7);
}
if (!StringExtensions.isNullOrEmpty(action.getDefinition().getPolicy())) {
_kLabelExtensions.addOutsideBottomCenteredNodeLabel(node, String.format("policy: %s", action.getPolicy().toString()), 7);
}
// connect source
for (KPort source : actionSources.get(action)) {
connect(createDelayEdge(action), source, ports.getKey());
}
// connect targets
for (KPort target : actionDestinations.get(action)) {
connect(createDelayEdge(action), ports.getValue(), target);
}
}
// Transform connections.
// First, collect all the source ports.
List<PortInstance> sourcePorts = new LinkedList<>(reactorInstance.inputs);
for (ReactorInstance child : reactorInstance.children) {
sourcePorts.addAll(child.outputs);
}
for (PortInstance leftPort : sourcePorts) {
KPort source = leftPort.getParent() == reactorInstance ? parentInputPorts.get(leftPort) : outputPorts.get(leftPort.getParent(), leftPort);
for (SendRange sendRange : leftPort.getDependentPorts()) {
for (RuntimeRange<PortInstance> rightRange : sendRange.destinations) {
PortInstance rightPort = rightRange.instance;
KPort target = rightPort.getParent() == reactorInstance ? parentOutputPorts.get(rightPort) : inputPorts.get(rightPort.getParent(), rightPort);
// There should be a connection, but skip if not.
Connection connection = sendRange.connection;
if (connection != null) {
KEdge edge = createIODependencyEdge(connection, (leftPort.isMultiport() || rightPort.isMultiport()));
if (connection.getDelay() != null) {
KLabel delayLabel = _kLabelExtensions.addCenterEdgeLabel(edge, ASTUtils.toOriginalText(connection.getDelay()));
associateWith(delayLabel, connection.getDelay());
if (connection.isPhysical()) {
_linguaFrancaStyleExtensions.applyOnEdgePysicalDelayStyle(delayLabel, reactorInstance.isMainOrFederated() ? Colors.WHITE : Colors.GRAY_95);
} else {
_linguaFrancaStyleExtensions.applyOnEdgeDelayStyle(delayLabel);
}
} else if (connection.isPhysical()) {
KLabel physicalConnectionLabel = _kLabelExtensions.addCenterEdgeLabel(edge, "---");
_linguaFrancaStyleExtensions.applyOnEdgePysicalStyle(physicalConnectionLabel, reactorInstance.isMainOrFederated() ? Colors.WHITE : Colors.GRAY_95);
}
if (source != null && target != null) {
// check for inside loop (direct in -> out connection with delay)
if (parentInputPorts.values().contains(source) && parentOutputPorts.values().contains(target)) {
// edge.setLayoutOption(CoreOptions.INSIDE_SELF_LOOPS_YO, true) // Does not work as expected
// Introduce dummy node to enable direct connection (that is also hidden when collapsed)
KNode dummy = _kNodeExtensions.createNode();
if (directConnectionDummyNodes.containsKey(target)) {
dummy = directConnectionDummyNodes.get(target);
} else {
nodes.add(dummy);
directConnectionDummyNodes.put(target, dummy);
_kRenderingExtensions.addInvisibleContainerRendering(dummy);
_kNodeExtensions.setNodeSize(dummy, 0, 0);
KEdge extraEdge = createIODependencyEdge(null, (leftPort.isMultiport() || rightPort.isMultiport()));
connect(extraEdge, dummy, target);
}
connect(edge, source, dummy);
} else {
connect(edge, source, target);
}
}
}
}
}
}
// Add startup/shutdown
if (startupUsed) {
_linguaFrancaShapeExtensions.addStartupFigure(startupNode);
_utilityExtensions.setID(startupNode, reactorInstance.uniqueID() + "_startup");
startupNode.setProperty(REACTION_SPECIAL_TRIGGER, true);
// add at the start (ordered first)
nodes.add(0, startupNode);
// try to order with reactions vertically if in one layer
setLayoutOption(startupNode, LayeredOptions.POSITION, new KVector(0, 0));
setLayoutOption(startupNode, LayeredOptions.LAYERING_LAYER_CONSTRAINT, LayerConstraint.FIRST);
if (getBooleanValue(REACTIONS_USE_HYPEREDGES)) {
KPort port = addInvisiblePort(startupNode);
startupNode.getOutgoingEdges().forEach(it -> {
it.setSourcePort(port);
});
}
}
if (shutdownUsed) {
_linguaFrancaShapeExtensions.addShutdownFigure(shutdownNode);
_utilityExtensions.setID(shutdownNode, reactorInstance.uniqueID() + "_shutdown");
shutdownNode.setProperty(REACTION_SPECIAL_TRIGGER, true);
// add at the end (ordered last)
nodes.add(shutdownNode);
// try to order with reactions vertically if in one layer
setLayoutOption(shutdownNode, LayeredOptions.POSITION, new KVector(0, reactorInstance.reactions.size() + 1));
if (getBooleanValue(REACTIONS_USE_HYPEREDGES)) {
// connect all edges to one port
KPort port = addInvisiblePort(shutdownNode);
shutdownNode.getOutgoingEdges().forEach(it -> {
it.setSourcePort(port);
});
}
}
// Postprocess timer nodes
if (getBooleanValue(REACTIONS_USE_HYPEREDGES)) {
// connect all edges to one port
for (KNode timerNode : timerNodes.values()) {
KPort port = addInvisiblePort(timerNode);
timerNode.getOutgoingEdges().forEach(it -> {
it.setSourcePort(port);
});
}
}
// Add reaction order edges (add last to have them on top of other edges)
if (reactorInstance.reactions.size() > 1) {
KNode prevNode = reactionNodes.get(IterableExtensions.head(reactorInstance.reactions));
Iterable<KNode> iterList = IterableExtensions.map(IterableExtensions.drop(reactorInstance.reactions, 1), reactionNodes::get);
for (KNode node : iterList) {
KEdge edge = createOrderEdge();
edge.setSource(prevNode);
edge.setTarget(node);
edge.setProperty(CoreOptions.NO_LAYOUT, true);
// Do not remove them, as they are needed for cycle detection
KRendering edgeRendering = _kRenderingExtensions.getKRendering(edge);
_kRenderingExtensions.setInvisible(edgeRendering, !getBooleanValue(SHOW_REACTION_ORDER_EDGES));
_kRenderingExtensions.getInvisible(edgeRendering).setPropagateToChildren(true);
// TODO this does not work work with incremental update (https://github.com/kieler/KLighD/issues/37)
// if (!getBooleanValue(SHOW_REACTION_ORDER_EDGES)) edge.initiallyHide()
prevNode = node;
}
}
_modeDiagrams.handleModes(nodes, reactorInstance);
return nodes;
}
use of org.lflang.generator.PortInstance 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 if (!getBooleanValue(SHOW_ALL_REACTORS)) {
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
reactorNodes.add(0, IterableExtensions.head(rootNode.getChildren()));
int index = 0;
for (KNode node : reactorNodes) {
// Element could be null if there is no main reactor and Show All Reactors is checked.
if (node == null)
continue;
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;
}
Aggregations