Commit 947c6209 authored by Manuel Schrick's avatar Manuel Schrick
Browse files

removed code smells: RoutesLayoutCalculator

parent 823a815d
......@@ -26,4 +26,7 @@ public interface DrawingConstants {
int ROW_SPACING = 40;
int BUS_LINE_WIDTH = 6;
String NAME_ROOT_IN = "root_in";
String NAME_ROOT_OUT = "root_out";
}
package de.monticore.lang.montiarc.svggenerator.calculators.helper;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.PortSymbol;
import de.monticore.lang.montiarc.svggenerator.calculators.RoutesLayoutState;
import de.monticore.lang.montiarc.svggenerator.calculators.detour.BusDetour;
import de.monticore.lang.montiarc.svggenerator.calculators.detour.ConnectorDetourHolder;
import de.monticore.lang.montiarc.svggenerator.calculators.routes.*;
import de.monticore.lang.montiarc.svggenerator.calculators.symbols.LayoutSymbol;
import javafx.util.Pair;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Peters Notebook on 07.11.2017.
*/
public class BusHandler {
public static void insertBuses(RoutesLayoutState layoutState) {
List<Route> routes = layoutState.routes;
List<Pair<Node, Node>> decomposedBusses = new ArrayList<>();
for (Pair<Node, Node> connection : layoutState.busses.keySet()) {
Node source = connection.getKey();
Node target = connection.getValue();
Bus bus = layoutState.busses.get(connection);
Route route = RoutesUtils.getRouteForConnection(source, target, layoutState);
BackConnector backConnector = layoutState.backConnectors.get(connection);
if (route != null && backConnector == null) {
if (bus.sourceBusColumn == bus.targetBusColumn - 1) {
decomposeBus(bus, layoutState);
decomposedBusses.add(connection);
continue;
}
boolean shouldDecomposeBus = true;
if (bus.getSourceOutputPorts().size() > 2 || bus.getTargetInputPorts().size() > 2) {
for (int i = layoutState.nodeOrder.indexOf(source) + 1; i < layoutState.nodeOrder.indexOf(target); i++) {
if (!layoutState.nodeOrder.get(i).isTemporary) {
shouldDecomposeBus = false;
break;
}
}
}
if (shouldDecomposeBus) {
decomposeBus(bus, layoutState);
decomposedBusses.add(connection);
continue;
}
}
if (route != null && backConnector == null) {
System.out.println("\ninsert bus routes: " + source.compName + " -> " + target.compName);
Node tempNodeSource = new Node(null, NodeNameGenerator.nextTempNodesName(source), true);
Node tempNodeTarget = new Node(null, NodeNameGenerator.nextTempNodesName(target), true);
bus.sourceBusNode = tempNodeSource;
bus.targetBusNode = tempNodeTarget;
layoutState.nodeOrder.add(layoutState.nodeOrder.indexOf(source) + 1, tempNodeSource);
layoutState.nodeOrder.add(layoutState.nodeOrder.indexOf(target), tempNodeTarget);
int indexTempNodeSource = layoutState.nodeOrder.indexOf(tempNodeSource);
int indexTempNodeTarget = layoutState.nodeOrder.indexOf(tempNodeTarget);
for (Route r : routes) {
if (indexTempNodeSource < indexTempNodeTarget) {
r.expandAt(indexTempNodeSource);
r.expandAt(indexTempNodeTarget);
} else {
r.expandAt(indexTempNodeTarget);
r.expandAt(indexTempNodeSource);
}
}
PortSymbol sourceOutputPort = source.getFirstPortForOutput(target);
PortSymbol targetInputPort = target.getFirstPortForInput(source);
route.set(layoutState.nodeOrder.indexOf(source), source, route.getNodeInputPort(source), sourceOutputPort);
route.set(layoutState.nodeOrder.indexOf(tempNodeSource), tempNodeSource, DummyPort.create(), DummyPort.create());
route.set(layoutState.nodeOrder.indexOf(tempNodeTarget), tempNodeTarget, DummyPort.create(), DummyPort.create());
route.set(layoutState.nodeOrder.indexOf(target), target, targetInputPort, route.getNodeOutputPort(target));
Pair<PortSymbol, PortSymbol> portPair = new Pair<>(sourceOutputPort, targetInputPort);
ConnectorDetourHolder detourHolder = layoutState.detourHolders.getOrDefault(portPair, new ConnectorDetourHolder(connection, portPair));
BusDetour busDetour = detourHolder.getBusDetour();
busDetour.setTempSource(tempNodeSource);
busDetour.setTempTarget(tempNodeTarget);
detourHolder.addDetour(busDetour);
layoutState.detourHolders.put(portPair, detourHolder);
int routeIndexAbove = routes.indexOf(route) - 1;
int routeIndexBelow = routes.indexOf(route) + 1;
int sourceIndex = layoutState.nodeOrder.indexOf(source);
int targetIndex = layoutState.nodeOrder.indexOf(target);
for (int i = 1; i < bus.portConnections.size(); i++) {
sourceOutputPort = bus.portConnections.get(i).getKey();
targetInputPort = bus.portConnections.get(i).getValue();
source.addOutput(tempNodeSource, sourceOutputPort);
tempNodeSource.addInput(source, DummyPort.create());
tempNodeSource.addOutput(tempNodeTarget, null);
tempNodeTarget.addInput(tempNodeSource, null);
tempNodeTarget.addOutput(target, DummyPort.create());
target.addInput(tempNodeTarget, targetInputPort);
Route routeAbove = routeIndexAbove >= 0 ? routes.get(routeIndexAbove) : null;
Route routeBelow = routeIndexBelow < routes.size() ? routes.get(routeIndexBelow) : null;
Route temp;
boolean routeAboveIsFree = routeAbove != null && routeAbove.isFreeBetweenNodes(sourceIndex, targetIndex);
boolean routeBelowIsFree = routeBelow != null && routeBelow.isFreeBetweenNodes(sourceIndex, targetIndex);
boolean routeAboveContainsNodes = routeAbove != null && routeAbove.columnIndexOf(source) >= 0 && routeAbove.columnIndexOf(target) >= 0;
if (routeAboveIsFree && routeAboveContainsNodes || routeAboveIsFree && !routeBelowIsFree) {
System.out.println("route " + routeAbove.id + " is free");
temp = routeAbove;
routeIndexAbove -= 1;
} else if (routeBelowIsFree) {
System.out.println("route " + routeBelow.id + " is free");
temp = routeBelow;
routeIndexBelow += 1;
} else {
System.out.println("new route above " + route.id);
temp = RoutesUtils.addRowAt(routes.indexOf(route), layoutState);
routeIndexAbove += 1;
}
temp.set(layoutState.nodeOrder.indexOf(source), source, temp.getNodeInputPort(source), sourceOutputPort);
temp.set(layoutState.nodeOrder.indexOf(tempNodeSource), tempNodeSource, DummyPort.create(), null);
temp.set(layoutState.nodeOrder.indexOf(tempNodeTarget), tempNodeTarget, null, DummyPort.create());
temp.set(layoutState.nodeOrder.indexOf(target), target, targetInputPort, temp.getNodeOutputPort(target));
portPair = new Pair<>(sourceOutputPort, targetInputPort);
detourHolder = layoutState.detourHolders.getOrDefault(portPair, new ConnectorDetourHolder(connection, portPair));
busDetour = detourHolder.getBusDetour(new BusDetour());
busDetour.setTempSource(tempNodeSource);
busDetour.setTempTarget(tempNodeTarget);
detourHolder.addDetour(busDetour);
layoutState.detourHolders.put(portPair, detourHolder);
}
} else if (backConnector != null) {
insertBusWithBackConnector(bus, backConnector, layoutState);
} else {
System.err.println("There is no Route for the bus from " + source.compName + " to " + target.compName);
}
}
for (Pair<Node, Node> connection : decomposedBusses) {
layoutState.busses.remove(connection);
}
}
private static void decomposeBus(Bus bus, RoutesLayoutState layoutState) {
List<Route> routes = layoutState.routes;
Node source = bus.source;
Node target = bus.target;
Route route = routes.stream()
.filter(r -> r.containsConnection(source, target))
.findFirst()
.orElse(null);
System.out.println("\ndecompose: " + source.compName + " -> " + target.compName);
int routeIndexAbove = routes.indexOf(route) - 1;
int routeIndexBelow = routes.indexOf(route) + 1;
int sourceIndex = layoutState.nodeOrder.indexOf(source);
int targetIndex = layoutState.nodeOrder.indexOf(target);
for (int i = 1; i < bus.portConnections.size(); i++) {
Route routeAbove = routeIndexAbove >= 0 ? routes.get(routeIndexAbove) : null;
Route routeBelow = routeIndexBelow < routes.size() ? routes.get(routeIndexBelow) : null;
Route temp;
if (routeAbove != null && routeAbove.isFreeBetweenNodes(sourceIndex, targetIndex)) {
System.out.println("route " + routeAbove.id + " is free");
temp = routeAbove;
routeIndexAbove -= 1;
} else if (routeBelow != null && routeBelow.isFreeBetweenNodes(sourceIndex, targetIndex)) {
System.out.println("route " + routeBelow.id + " is free");
temp = routeBelow;
routeIndexBelow += 1;
} else {
System.out.println("new route above " + route.id);
temp = route.copyNodesOnly();
routes.add(routes.indexOf(route), temp);
routeIndexAbove += 1;
}
for (int j = sourceIndex + 1; j < targetIndex; j++) {
temp.set(j, RouteState.ROUTE);
}
PortSymbol sourceOutputPort = source.getAllPortsForOutput(target).get(i);
PortSymbol targetInputPort = target.getAllPortsForInput(source).get(i);
temp.set(sourceIndex, source, null, sourceOutputPort);
temp.set(targetIndex, target, targetInputPort, null);
}
}
private static void insertBusWithBackConnector(Bus bus, BackConnector backConnector, RoutesLayoutState layoutState) {
List<Route> routes = layoutState.routes;
Node source = backConnector.source;
Node target = backConnector.target;
Route sourceRoute = routes.stream().filter(r -> r.containsConnection(source, backConnector.tempSource)).findFirst().orElse(null);
Route targetRoute = routes.stream().filter(r -> r.containsConnection(backConnector.tempTarget, target)).findFirst().orElse(null);
for (int i = 1; i < bus.getSourceOutputPorts().size(); i++) {
source.addOutput(backConnector.tempSource, bus.getSourceOutputPorts().get(i));
backConnector.tempSource.addInput(source, DummyPort.create());
Route temp = sourceRoute.copyNodesOnly();
temp.set(layoutState.nodeOrder.indexOf(source), source, null, source.getAllPortsForOutput(target).get(i));
temp.set(layoutState.nodeOrder.indexOf(backConnector.tempSource), backConnector.tempSource, DummyPort.create(), null);
routes.add(routes.indexOf(sourceRoute), temp);
}
for (int i = 1; i < bus.getTargetInputPorts().size(); i++) {
backConnector.tempTarget.addOutput(target, DummyPort.create());
target.addInput(backConnector.tempTarget, bus.getTargetInputPorts().get(i));
Route temp = targetRoute.copyNodesOnly();
temp.set(layoutState.nodeOrder.indexOf(backConnector.tempTarget), backConnector.tempTarget, null, DummyPort.create());
temp.set(layoutState.nodeOrder.indexOf(target), target, target.getAllPortsForInput(source).get(i), null);
routes.add(routes.indexOf(targetRoute), temp);
}
bus.sourceBusNode = new Node(null, "unused");
bus.targetBusNode = new Node(null, "unused");
Pair<Node, Node> nodePair = new Pair<>(source, target);
for (Pair<PortSymbol, PortSymbol> portPair: bus.portConnections) {
ConnectorDetourHolder detourHolder = layoutState.detourHolders.getOrDefault(portPair, new ConnectorDetourHolder(nodePair, portPair));
BusDetour busDetour = detourHolder.getBusDetour(new BusDetour());
busDetour.setTempSource(backConnector.tempSource);
busDetour.setTempTarget(backConnector.tempTarget);
detourHolder.addDetour(busDetour);
}
}
}
package de.monticore.lang.montiarc.svggenerator.calculators.helper;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.ExpandedComponentInstanceSymbol;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.PortSymbol;
import de.monticore.lang.montiarc.svggenerator.calculators.DrawingConstants;
import de.monticore.lang.montiarc.svggenerator.calculators.RoutesLayoutState;
import de.monticore.lang.montiarc.svggenerator.calculators.routes.*;
import de.monticore.lang.montiarc.svggenerator.calculators.symbols.*;
import javafx.util.Pair;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Peters Notebook on 07.11.2017.
*/
public class ComponentCoordinatesHandler implements DrawingConstants {
public static void assignComponentCoordinates(ExpandedComponentInstanceSymbol enclosingComponent, List<Route> routes) {
int length = routes.stream().mapToInt(Route::size).max().orElse(0);
int tableWidth = RoutesUtils.getTableWidth(routes);
int tableHeight = RoutesUtils.getTableHeight(routes);
enclosingComponent.addTag(new CanvasLayoutSymbol(IdGenerator.getUniqueId(), CANVAS_OUTER_MARGIN, CANVAS_OUTER_MARGIN, tableWidth, tableHeight));
for (int columnIndex = 0; columnIndex < length; columnIndex++) {
Node currentNode = null;
List<PortSymbol> ports = new ArrayList<>();
int startRowIndex = -1;
int endRowIndex = -1;
for (int rowIndex = 0; rowIndex < routes.size(); rowIndex++) {
Route route = routes.get(rowIndex);
if (route.getState(columnIndex) == RouteState.NODE) {
Node node = route.getNode(columnIndex);
PortSymbol inputPort = route.getNodeInputPort(node);
PortSymbol outputPort = route.getNodeOutputPort(node);
boolean hasNewPorts = inputPort != null && !ports.contains(inputPort) || outputPort != null && !ports.contains(outputPort);
if (!hasNewPorts) {
if (!node.isConnected()) {
assignComponentCoordinates(node, columnIndex, rowIndex, rowIndex, routes);
}
continue;
}
if (inputPort != null) {
ports.add(inputPort);
}
if (outputPort != null) {
ports.add(outputPort);
}
if (currentNode == null) {
currentNode = node;
startRowIndex = rowIndex;
} else if (!currentNode.equals(node)) {
assignComponentCoordinates(currentNode, columnIndex, startRowIndex, endRowIndex, routes);
currentNode = node;
startRowIndex = rowIndex;
}
endRowIndex = rowIndex;
} else if (currentNode != null) {
if (!currentNode.compName.equals(NAME_ROOT_IN) && !currentNode.compName.equals(NAME_ROOT_OUT)) {
assignComponentCoordinates(currentNode, columnIndex, startRowIndex, endRowIndex, routes);
}
currentNode = null;
startRowIndex = -1;
endRowIndex = -1;
}
}
if (currentNode != null) {
assignComponentCoordinates(currentNode, columnIndex, startRowIndex, endRowIndex, routes);
}
}
}
public static void assignComponentCoordinates(Node node, int column, int startRow, int endRow, List<Route> routes) {
ExpandedComponentInstanceSymbol component = node.getComponent();
if (component == null) {
return;
}
int left = RoutesUtils.getColumnLeft(column, routes);
int top = RoutesUtils.getRowTop(startRow, routes);
int width = RoutesUtils.getColumnRight(column, routes) - left;
int height = RoutesUtils.getRowBottom(endRow, routes) - top;
component.addTag(new ComponentLayoutSymbol(IdGenerator.getUniqueId(), left, top, width, height, LayoutPosition.LEFT, 10));
}
}
......@@ -2,6 +2,7 @@ package de.monticore.lang.montiarc.svggenerator.calculators.helper;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.ExpandedComponentInstanceSymbol;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.PortSymbol;
import de.monticore.lang.montiarc.svggenerator.calculators.DrawingConstants;
import de.monticore.lang.montiarc.svggenerator.calculators.routes.Node;
import java.util.ArrayList;
......@@ -11,9 +12,7 @@ import java.util.List;
/**
* Created by Peters Notebook on 04.11.2017.
*/
public class ComponentTranslater {
private final static String NAME_ROOT_IN = "root_in";
private final static String NAME_ROOT_OUT = "root_out";
public class ComponentTranslater implements DrawingConstants {
public static List<Node> translateComponent(ExpandedComponentInstanceSymbol instance) {
HashMap<String, Node> nodes = new HashMap<>();
......
package de.monticore.lang.montiarc.svggenerator.calculators.helper;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.ConnectorSymbol;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.ExpandedComponentInstanceSymbol;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.PortSymbol;
import de.monticore.lang.montiarc.svggenerator.calculators.DrawingConstants;
import de.monticore.lang.montiarc.svggenerator.calculators.RoutesLayoutState;
import de.monticore.lang.montiarc.svggenerator.calculators.routes.*;
import de.monticore.lang.montiarc.svggenerator.calculators.symbols.CanvasPortLayoutSymbol;
import de.monticore.lang.montiarc.svggenerator.calculators.symbols.ConnectorLayoutSymbol;
import de.monticore.lang.montiarc.svggenerator.calculators.symbols.IdGenerator;
import de.monticore.lang.montiarc.svggenerator.calculators.symbols.PortLayoutSymbol;
import javafx.util.Pair;
import java.awt.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
/**
* Created by Peters Notebook on 07.11.2017.
*/
public class ConnectorCoordinatesHandler implements DrawingConstants {
public static void assignConnectorCoordinates(ExpandedComponentInstanceSymbol enclosingComponent, RoutesLayoutState layoutState) {
List<Route> routes = layoutState.routes;
HashMap<Pair<Node, Node>, List<ConnectorSymbol>> backAndBusConnectors = new HashMap<>();
HashMap<Pair<Node, Node>, ConnectorSymbol> splitConnectors = new HashMap<>();
enclosingComponent.getConnectors().stream()
.filter(connector -> !connector.getSourcePort().getTags(PortLayoutSymbol.KIND).isEmpty() || !connector.getSourcePort().getTags(CanvasPortLayoutSymbol.KIND).isEmpty())
.filter(connector -> !connector.getTargetPort().getTags(PortLayoutSymbol.KIND).isEmpty() || !connector.getTargetPort().getTags(CanvasPortLayoutSymbol.KIND).isEmpty())
.forEach(connector -> {
PortSymbol sourcePort = connector.getSourcePort();
PortSymbol targetPort = connector.getTargetPort();
ExpandedComponentInstanceSymbol sourceComp = sourcePort.getComponentInstance().get();
ExpandedComponentInstanceSymbol targetComp = targetPort.getComponentInstance().get();
Node source = null;
Node target = null;
for (Node node : layoutState.nodeOrder) {
if (node.getComponent() == null) {
continue;
}
if (sourceComp.equals(enclosingComponent)) {
if (node.compName.equals(NAME_ROOT_IN)) {
source = node;
}
} else if (node.getComponent().equals(sourceComp)) {
source = node;
}
if (targetComp.equals(enclosingComponent)) {
if (node.compName.equals(NAME_ROOT_OUT)) {
target = node;
}
} else if (node.getComponent().equals(targetComp)) {
target = node;
}
}
Pair<Node, Node> nodePair = new Pair<>(source, target);
if (layoutState.busses.containsKey(nodePair) || layoutState.backConnectors.containsKey(nodePair)) {
List<ConnectorSymbol> connectors = backAndBusConnectors.getOrDefault(nodePair, new ArrayList<>());
connectors.add(connector);
backAndBusConnectors.put(nodePair, connectors);
} else if (layoutState.splitConnectors.containsKey(nodePair)) {
splitConnectors.put(nodePair, connector);
} else {
assignNormalConnectorCoordinates(connector, enclosingComponent);
}
});
List<Pair<Node, Node>> assignedPairs = new ArrayList<>();
for (Pair<Node, Node> pair : layoutState.busses.keySet()) {
Bus bus = layoutState.busses.get(pair);
List<ConnectorSymbol> connectors = backAndBusConnectors.getOrDefault(pair, new ArrayList<>());
if (layoutState.backConnectors.containsKey(pair)) {
BackConnector backConnector = layoutState.backConnectors.get(pair);
assignBusAndBackConnectorCoordinates(connectors, bus, backConnector, routes);
} else {
assignBusConnectorCoordinates(connectors, bus, routes);
}
assignedPairs.add(pair);
}
for (Pair<Node, Node> pair : layoutState.backConnectors.keySet()) {
if (!assignedPairs.contains(pair)) {
List<ConnectorSymbol> connectors = backAndBusConnectors.getOrDefault(pair, new ArrayList<>());
BackConnector backConnector = layoutState.backConnectors.get(pair);
assignBackConnectorCoordinates(connectors, backConnector, routes);
}
}
for (Pair<Node, Node> pair : splitConnectors.keySet()) {
assignSplitConnectorCoordinates(splitConnectors.get(pair), layoutState.splitConnectors.get(pair), routes);
}
}
private static void assignNormalConnectorCoordinates(ConnectorSymbol connector, ExpandedComponentInstanceSymbol enclosingComponent) {
int startX;
int endX;
int startY;
int endY;
Optional<ExpandedComponentInstanceSymbol> optSourceComp = connector.getSourcePort().getComponentInstance();
Optional<ExpandedComponentInstanceSymbol> optTargetComp = connector.getTargetPort().getComponentInstance();
if (optSourceComp.isPresent() && optSourceComp.get().equals(enclosingComponent)) {
if (connector.getSourcePort().getTags(CanvasPortLayoutSymbol.KIND).isEmpty()) {
System.err.println(connector.getSourcePort().getFullName() + " has no CanvasPortLayoutSymbol");
return;
}
CanvasPortLayoutSymbol sourcePortLayoutSymbol = connector.getSourcePort().<CanvasPortLayoutSymbol>getTags(CanvasPortLayoutSymbol.KIND).iterator().next();
startX = sourcePortLayoutSymbol.getX() + (int) (PORT_WIDTH / 2.0);
startY = sourcePortLayoutSymbol.getY() + (int) (PORT_HEIGHT / 2.0);
} else {
PortLayoutSymbol sourcePortLayoutSymbol = connector.getSourcePort().<PortLayoutSymbol>getTags(PortLayoutSymbol.KIND).iterator().next();
startX = sourcePortLayoutSymbol.getX() + (int) (PORT_WIDTH / 2.0);
startY = sourcePortLayoutSymbol.getY() + (int) (PORT_HEIGHT / 2.0);
}
if (optTargetComp.isPresent() && optTargetComp.get().equals(enclosingComponent)) {
if (connector.getTargetPort().getTags(CanvasPortLayoutSymbol.KIND).isEmpty()) {
System.err.println(connector.getTargetPort().getFullName() + " has no CanvasPortLayoutSymbol");
return;
}
CanvasPortLayoutSymbol targetPortLayoutSymbol = connector.getTargetPort().<CanvasPortLayoutSymbol>getTags(CanvasPortLayoutSymbol.KIND).iterator().next();
endX = targetPortLayoutSymbol.getX();
endY = targetPortLayoutSymbol.getY() + (int) (PORT_HEIGHT / 2.0);
} else {
PortLayoutSymbol targetPortLayoutSymbol = connector.getTargetPort().<PortLayoutSymbol>getTags(PortLayoutSymbol.KIND).iterator().next();
endX = targetPortLayoutSymbol.getX();
endY = targetPortLayoutSymbol.getY() + (int) (PORT_HEIGHT / 2.0);
}
Point start = new Point(startX, startY);
Point end = new Point(endX, endY);
Point portSpacingBypassPoint = new Point(endX + (int) (PORT_WIDTH / 2.0), endY);
Point[] points;
if (startY == endY) {
points = new Point[]{start, end};