diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/EquationSimplification.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/EquationSimplification.xtend index ca31dec3f5..e04ba5f8e5 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/EquationSimplification.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/EquationSimplification.xtend @@ -706,7 +706,7 @@ class EquationSimplification { private def isLocalValuedObject(KNode node) { val element = node.sourceElement if (element instanceof ValuedObjectReference) { - return currentRegion.declarations.contains((element as ValuedObjectReference).valuedObject.declaration) + return currentRegions.peek.declarations.contains((element as ValuedObjectReference).valuedObject.declaration) } return false } diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/EquationSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/EquationSynthesis.xtend index 6c5ad02332..11bc10238a 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/EquationSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/EquationSynthesis.xtend @@ -30,6 +30,7 @@ import de.cau.cs.kieler.kexpressions.Value import de.cau.cs.kieler.kexpressions.ValueType import de.cau.cs.kieler.kexpressions.ValuedObject import de.cau.cs.kieler.kexpressions.ValuedObjectReference +import de.cau.cs.kieler.kexpressions.VariableDeclaration import de.cau.cs.kieler.kexpressions.VectorValue import de.cau.cs.kieler.kexpressions.extensions.KExpressionsCreateExtensions import de.cau.cs.kieler.kexpressions.extensions.KExpressionsDeclarationExtensions @@ -41,6 +42,7 @@ import de.cau.cs.kieler.kexpressions.kext.extensions.KExtDeclarationExtensions import de.cau.cs.kieler.kicool.ui.synthesis.KGTLoader import de.cau.cs.kieler.kicool.ui.synthesis.colors.AbstractColorStore.GeneralColor import de.cau.cs.kieler.klighd.SynthesisOption +import de.cau.cs.kieler.klighd.internal.util.KlighdInternalProperties import de.cau.cs.kieler.klighd.kgraph.KIdentifier import de.cau.cs.kieler.klighd.kgraph.KNode import de.cau.cs.kieler.klighd.kgraph.KPort @@ -50,7 +52,6 @@ import de.cau.cs.kieler.klighd.krendering.KBackground import de.cau.cs.kieler.klighd.krendering.KContainerRendering import de.cau.cs.kieler.klighd.krendering.KEllipse import de.cau.cs.kieler.klighd.krendering.KForeground -import de.cau.cs.kieler.klighd.krendering.KPolygon import de.cau.cs.kieler.klighd.krendering.KPolyline import de.cau.cs.kieler.klighd.krendering.KRectangle import de.cau.cs.kieler.klighd.krendering.KRendering @@ -97,10 +98,10 @@ import org.eclipse.emf.ecore.EObject import static de.cau.cs.kieler.sccharts.ide.synthesis.EquationSynthesisProperties.* import static de.cau.cs.kieler.sccharts.ui.synthesis.styles.ColorStore.Color.* +import static extension com.google.common.collect.Iterables.concat import static extension de.cau.cs.kieler.annotations.ide.klighd.CommonSynthesisUtil.* import static extension de.cau.cs.kieler.klighd.syntheses.DiagramSyntheses.* import static extension org.eclipse.emf.ecore.util.EcoreUtil.* -import static extension com.google.common.collect.Iterables.concat /** * @author ssm @@ -308,7 +309,7 @@ class EquationSynthesis extends SubSynthesis { combineAllDataAccessNodes = COMBINE_ALL_DATA_ACCESS.booleanValue showArrows = SHOW_ARROWS.booleanValue - currentRegion = rootNode.sourceElement as DataflowRegion + currentRegions.push(rootNode.sourceElement as DataflowRegion) var nodes = newLinkedList val List lastKNodes = newArrayList for (assignment : elements) { @@ -340,6 +341,7 @@ class EquationSynthesis extends SubSynthesis { var finalNodes = nodes.reWireInlining finalNodes.addMissingReferenceInputs + currentRegions.pop finalNodes.applyColors() return finalNodes @@ -915,7 +917,6 @@ class EquationSynthesis extends SubSynthesis { ] target.ports.add(targetPort) } - edge.setLayoutOption(LayeredOptions.INSIDE_SELF_LOOPS_YO, true) edge.source = source edge.sourcePort = sourcePort edge.target = target @@ -1012,7 +1013,6 @@ class EquationSynthesis extends SubSynthesis { ] after.ports.add(targetPort) } - edge.setLayoutOption(LayeredOptions.INSIDE_SELF_LOOPS_YO, true) edge.source = before edge.sourcePort = sourcePort edge.target = after @@ -1146,24 +1146,33 @@ class EquationSynthesis extends SubSynthesis { val inputNames = newHashMap for (inputNode : child.children.filter(KNode).filter[getProperty(INPUT_FLAG)]) { - val name = inputNode.data.filter(KPolygon).head.children.filter(KText).head.text - inputNames.put(name, inputNode) + val valuedObjectRef = inputNode.properties.get(KlighdInternalProperties.MODEL_ELEMENT) + // only care for inputs that have a valued object as a reference, ignore others such as constants. + if (valuedObjectRef instanceof ValuedObjectReference) { + val name = valuedObjectRef.valuedObject.name + inputNames.put(name, inputNode) + } } val outputNames = newHashMap for (outputNode : child.children.filter(KNode).filter[getProperty(OUTPUT_FLAG)]) { - val name = outputNode.data.filter(KPolygon).head.children.filter(KText).head.text - outputNames.put(name, outputNode) + val valuedObjectRef = outputNode.properties.get(KlighdInternalProperties.MODEL_ELEMENT) + if (valuedObjectRef instanceof ValuedObjectReference) { + val name = valuedObjectRef.valuedObject.name + outputNames.put(name, outputNode) + } } + // go through all ports, but the non-east ones in reverse. Avoids accitental Swastika in many examples. for (port : node.ports.immutableCopy.reverseView) { - val portName = port.labels.head?.text val portSide = port.portSide - val newPort = port.copy - - newPort.addLayoutParam(CoreOptions::PORT_BORDER_OFFSET, 0d) - child.ports += newPort - if (portSide != PortSide.EAST) { + val reference = port.properties.get(KlighdInternalProperties.MODEL_ELEMENT) + val portName = if(reference instanceof ValuedObjectReference) reference.valuedObject.name else "" + val newPort = port.copy + + newPort.addLayoutParam(CoreOptions::PORT_BORDER_OFFSET, 0d) + child.ports += newPort + for (edge : node.incomingEdges.immutableCopy.filter[targetPort == port]) { edge.target = child edge.targetPort = newPort @@ -1178,7 +1187,17 @@ class EquationSynthesis extends SubSynthesis { inputNode.remove } } - } else if (portSide == PortSide.EAST) { + } + } + for (port : node.ports.immutableCopy) { + val portSide = port.portSide + if (portSide == PortSide.EAST) { + val reference = port.properties.get(KlighdInternalProperties.MODEL_ELEMENT) + val portName = if(reference instanceof ValuedObjectReference) reference.valuedObject.name else "" + val newPort = port.copy + + newPort.addLayoutParam(CoreOptions::PORT_BORDER_OFFSET, 0d) + child.ports += newPort for (edge : node.outgoingEdges.immutableCopy.filter[sourcePort == port]) { edge.source = child edge.sourcePort = newPort @@ -1200,6 +1219,30 @@ class EquationSynthesis extends SubSynthesis { for (node : inlinedNodes) { nodes.betterRemove(node, null) } + + + // activate inside self loops on inlined reference nodes that directly connect an input to an output. + for (refNode : nodes.filter [properties.get(KlighdInternalProperties.MODEL_ELEMENT) instanceof DataflowRegion]) { + // inside self loops go directly from an input to an output. + val insideSelfLoops = refNode.outgoingEdges.filter[ + val sourceElement = it.sourcePort.properties.get(KlighdInternalProperties.MODEL_ELEMENT) + val targetElement = it.targetPort.properties.get(KlighdInternalProperties.MODEL_ELEMENT) + return refNode.incomingEdges.contains(it) + && sourceElement instanceof ValuedObjectReference + && targetElement instanceof ValuedObjectReference + && (sourceElement as ValuedObjectReference).valuedObject.eContainer instanceof VariableDeclaration + && (targetElement as ValuedObjectReference).valuedObject.eContainer instanceof VariableDeclaration + && ((sourceElement as ValuedObjectReference).valuedObject.eContainer as VariableDeclaration).isInput + && ((targetElement as ValuedObjectReference).valuedObject.eContainer as VariableDeclaration).isOutput + ] + insideSelfLoops.forEach [ + addLayoutParam(LayeredOptions.INSIDE_SELF_LOOPS_YO, true) + ] + if (!insideSelfLoops.empty) { + refNode.addLayoutParam(LayeredOptions.INSIDE_SELF_LOOPS_ACTIVATE, true) + } + } + return nodes } diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/EquationSynthesisHelper.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/EquationSynthesisHelper.xtend index 9d885a962d..62f42d31dc 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/EquationSynthesisHelper.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/EquationSynthesisHelper.xtend @@ -42,6 +42,7 @@ import de.cau.cs.kieler.sccharts.ui.synthesis.styles.EquationStyles import de.cau.cs.kieler.sccharts.ui.synthesis.styles.TransitionStyles import java.util.Comparator import java.util.List +import java.util.Stack import org.eclipse.elk.alg.layered.options.LayeredOptions import org.eclipse.elk.core.options.CoreOptions import org.eclipse.elk.core.options.PortSide @@ -75,7 +76,11 @@ class EquationSynthesisHelper { protected var showWireLabels = false protected var combineAllDataAccessNodes = false protected var showArrows = false - protected var DataflowRegion currentRegion = null + /* + * only contains a single element with the current region during transformation. If automatic inline is on, this + * is a stack of the processed regions, with the top region being the current one. + */ + protected var Stack currentRegions = new Stack /** * removes a node from the list and from the graph @@ -337,7 +342,6 @@ class EquationSynthesisHelper { return } val edge = createEdge - DiagramSyntheses.setLayoutOption(edge, LayeredOptions.INSIDE_SELF_LOOPS_YO, true) edge.source = source.node edge.sourcePort = source edge.target = target.node diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/hooks/DeclarationsHook.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/hooks/DeclarationsHook.xtend index a9fa464877..dfcd02c9be 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/hooks/DeclarationsHook.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/hooks/DeclarationsHook.xtend @@ -64,10 +64,10 @@ class DeclarationsHook extends SynthesisHook { val parent = node.regionExtendedContainer val declarations = parent?.getProperty(ControlflowRegionStyles.DECLARATIONS_CONTAINER) if (declarations !== null) { - val container = declarations.eContainer as KContainerRendering + val container = declarations.eContainer.eContainer.eContainer as KContainerRendering // Hide declarations if (declarations !== null && container !== null) { - container.children.remove(declarations) + container.children.removeIf([true]) } } }