|
@@ -11,97 +11,182 @@ import animation.PseudoCodeNode.CodeAction;
|
|
|
import graph.LayeredGraphEdge;
|
|
|
import graph.LayeredGraphNode;
|
|
|
|
|
|
+/**
|
|
|
+ * the preprocessing stage of the bk node placement algorithm
|
|
|
+ *
|
|
|
+ * @author kolja and eren
|
|
|
+ *
|
|
|
+ */
|
|
|
public class ConflictDetection implements AlgorithmStage {
|
|
|
|
|
|
private LayeredGraphNode graph;
|
|
|
- private ArrayList< BackwardAction > actions;
|
|
|
-
|
|
|
+ private ArrayList<BackwardAction> actions;
|
|
|
+
|
|
|
private int i;
|
|
|
private int l1;
|
|
|
+ private int k0;
|
|
|
+ private int k1;
|
|
|
+ private int l;
|
|
|
+ private int k;
|
|
|
+ private int hidden_k;
|
|
|
+ /**
|
|
|
+ * line number in Carstens' pseudocode listing 3.1
|
|
|
+ */
|
|
|
+ private int pseudo_line;
|
|
|
private PseudoCodeNode markNode;
|
|
|
-
|
|
|
- public ConflictDetection( LayeredGraphNode graph )
|
|
|
- {
|
|
|
+
|
|
|
+ public ConflictDetection(LayeredGraphNode graph) {
|
|
|
this.graph = graph;
|
|
|
actions = new ArrayList<>();
|
|
|
- i = 1;
|
|
|
- l1 = 0;
|
|
|
+ i = 0; // will be increased before first iteration
|
|
|
+ l1 = -1; // will be increased before first iteration
|
|
|
+ k0 = 0;
|
|
|
+ k1 = 0;
|
|
|
+ l = 0;
|
|
|
+ k = 0;
|
|
|
+ hidden_k = 0;
|
|
|
+ pseudo_line = 1;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ // TODO: im psuedocode anzeigen
|
|
|
+ // TODO: knoten highlighten
|
|
|
+ // TODO: rekursion auf subgraphen
|
|
|
+ // TODO: backwards actions
|
|
|
@Override
|
|
|
public StageStatus forwardStep() {
|
|
|
+ // the line numbers are from Carstens
|
|
|
+ switch (pseudo_line) {
|
|
|
+ case 1:
|
|
|
+ i += 1;
|
|
|
+ pseudo_line += 1;
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ k0 = 0;
|
|
|
+ l = 0;
|
|
|
+ pseudo_line += 1;
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ l1 += 1;
|
|
|
+ pseudo_line += 1;
|
|
|
+ break;
|
|
|
+ case 4:
|
|
|
+ if (graph.getContainedLayers().get(i + 1).size() == l1 || incidentToInnerSegmentBetweenLiPlusOneAndLi()) {
|
|
|
+ pseudo_line += 1;
|
|
|
+ } else {
|
|
|
+ pseudo_line = 3; // yes, that's a goto
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 5:
|
|
|
+ k1 = graph.getContainedLayers().get(i + 1).size() - 1;
|
|
|
+ pseudo_line += 1;
|
|
|
+ break;
|
|
|
+ case 6:
|
|
|
+ if (incidentToInnerSegmentBetweenLiPlusOneAndLi()) {
|
|
|
+ pseudo_line += 1;
|
|
|
+ } else {
|
|
|
+ pseudo_line = 9;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 7:
|
|
|
+ k1 = graph.getContainedLayers().get(i).indexOf(
|
|
|
+ graph.getContainedLayers().get(i + 1).get(l1).getSortedIncomingEdges().get(0).getSources().get(0));
|
|
|
+ break;
|
|
|
+ case 9:
|
|
|
+ if (l <= l1) {
|
|
|
+ pseudo_line += 1;
|
|
|
+ // initialize the for loop o next line
|
|
|
+ hidden_k -= 1; // because it will be increased next line
|
|
|
+ } else {
|
|
|
+ pseudo_line = 15; // yes, that's a goto
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 10:
|
|
|
+ hidden_k += 1;
|
|
|
+ if (graph.getContainedLayers().get(i + 1).get(l).getSortedIncomingEdges().size() < hidden_k) {
|
|
|
+ k = graph.getContainedLayers().get(i).indexOf(graph.getContainedLayers().get(i + 1).get(l)
|
|
|
+ .getSortedIncomingEdges().get(hidden_k).getSources().get(0));
|
|
|
+ pseudo_line += 1;
|
|
|
+ } else {
|
|
|
+ pseudo_line = 13;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 11:
|
|
|
+ hidden_k += 1;
|
|
|
+ if (graph.getContainedLayers().get(i + 1).get(l).getSortedIncomingEdges().size() < hidden_k) {
|
|
|
+ k = graph.getContainedLayers().get(i).indexOf(graph.getContainedLayers().get(i + 1).get(l)
|
|
|
+ .getSortedIncomingEdges().get(hidden_k).getSources().get(0));
|
|
|
+ pseudo_line += 1;
|
|
|
+ } else {
|
|
|
+ pseudo_line = 13;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
int oldI = i;
|
|
|
int oldL1 = l1;
|
|
|
- ((PseudoCodeNode)markNode.getParent()).setSelected( true );
|
|
|
- CodeAction action = markNode.setSelected( true );
|
|
|
+ ((PseudoCodeNode) markNode.getParent()).setSelected(true);
|
|
|
+ CodeAction action = markNode.setSelected(true);
|
|
|
boolean breakPoint = action == CodeAction.STOP;
|
|
|
- if( i + 1 >= graph.getContainedLayers().size() - 1 )
|
|
|
- {
|
|
|
- ((PseudoCodeNode)markNode.getParent()).setSelected( false );
|
|
|
- markNode.setSelected( false );
|
|
|
+
|
|
|
+ // last layer? finished?
|
|
|
+ if (i + 1 >= graph.getContainedLayers().size() - 1) {
|
|
|
+ ((PseudoCodeNode) markNode.getParent()).setSelected(false);
|
|
|
+ markNode.setSelected(false);
|
|
|
return StageStatus.FINISHED;
|
|
|
}
|
|
|
- LayeredGraphNode curr = graph.getContainedLayers().get( i + 1 ).get( l1 );
|
|
|
- curr.setSelected( null );
|
|
|
- ArrayList< LayeredGraphEdge > edges = curr.getIncomingEdges();
|
|
|
+
|
|
|
+ LayeredGraphNode curr = graph.getContainedLayers().get(i + 1).get(l1);
|
|
|
+ curr.setSelected(null);
|
|
|
+ ArrayList<LayeredGraphEdge> edges = curr.getIncomingEdges();
|
|
|
LayeredGraphEdge dummyEdge = null;
|
|
|
- for( LayeredGraphEdge e : edges )
|
|
|
- {
|
|
|
- if( e.isDummyEdge() )
|
|
|
- {
|
|
|
+ for (LayeredGraphEdge e : edges) {
|
|
|
+ if (e.isDummyEdge()) {
|
|
|
dummyEdge = e;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
- ArrayList< LayeredGraphEdge > conflicts = new ArrayList<>();
|
|
|
- if( dummyEdge != null )
|
|
|
- {
|
|
|
- for( LayeredGraphEdge e : edges )
|
|
|
- {
|
|
|
- if( e.isDummyEdge() )
|
|
|
- {
|
|
|
- ArrayList< LayeredGraphEdge > conf = e.calcEdgeCrossings();
|
|
|
- for( LayeredGraphEdge ce : conf )
|
|
|
- {
|
|
|
- if( !ce.isDummyEdge() )
|
|
|
- conflicts.add( ce );
|
|
|
+
|
|
|
+ ArrayList<LayeredGraphEdge> conflicts = new ArrayList<>();
|
|
|
+ if (dummyEdge != null) {
|
|
|
+ for (LayeredGraphEdge e : edges) {
|
|
|
+ if (e.isDummyEdge()) {
|
|
|
+ ArrayList<LayeredGraphEdge> conf = e.calcEdgeCrossings();
|
|
|
+ for (LayeredGraphEdge ce : conf) {
|
|
|
+ if (!ce.isDummyEdge())
|
|
|
+ conflicts.add(ce);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- for( LayeredGraphEdge c : conflicts )
|
|
|
- c.setConflicted( true, null );
|
|
|
- StageStatus status = calcNextStatus();
|
|
|
- actions.add( 0, ()->{
|
|
|
+ for (LayeredGraphEdge c : conflicts)
|
|
|
+ c.setConflicted(true, null);
|
|
|
+ StageStatus status = calcNextStatus();
|
|
|
+ actions.add(0, () -> {
|
|
|
i = oldI;
|
|
|
l1 = oldL1;
|
|
|
- if( i + 1 < graph.getContainedLayers().size() - 1 && l1 > 0 )
|
|
|
- {
|
|
|
- LayeredGraphNode layde = graph.getContainedLayers().get( i + 1 ).get( l1 - 1 );
|
|
|
- layde.setSelected( null );
|
|
|
+ if (i + 1 < graph.getContainedLayers().size() - 1 && l1 > 0) {
|
|
|
+ LayeredGraphNode layde = graph.getContainedLayers().get(i + 1).get(l1 - 1);
|
|
|
+ layde.setSelected(null);
|
|
|
}
|
|
|
- for( LayeredGraphEdge c : conflicts )
|
|
|
- c.setConflicted( false, null );
|
|
|
+ for (LayeredGraphEdge c : conflicts)
|
|
|
+ c.setConflicted(false, null);
|
|
|
});
|
|
|
- if( status != StageStatus.FINISHED && breakPoint )
|
|
|
+ if (status != StageStatus.FINISHED && breakPoint)
|
|
|
return StageStatus.BREAKPOINT;
|
|
|
- if( action == CodeAction.SKIP && status != StageStatus.FINISHED )
|
|
|
+ if (action == CodeAction.SKIP && status != StageStatus.FINISHED)
|
|
|
return forwardStep();
|
|
|
return status;
|
|
|
}
|
|
|
-
|
|
|
- private StageStatus calcNextStatus()
|
|
|
- {
|
|
|
+
|
|
|
+ private StageStatus calcNextStatus() {
|
|
|
l1++;
|
|
|
- if( l1 >= graph.getContainedLayers().get( i + 1 ).size() )
|
|
|
- {
|
|
|
+ if (l1 >= graph.getContainedLayers().get(i + 1).size()) {
|
|
|
i++;
|
|
|
- if( i >= graph.getContainedLayers().size() - 2 )
|
|
|
- {
|
|
|
+ if (i >= graph.getContainedLayers().size() - 2) {
|
|
|
i--;
|
|
|
l1--;
|
|
|
- ((PseudoCodeNode)markNode.getParent()).setSelected( false );
|
|
|
- markNode.setSelected( false );
|
|
|
+ ((PseudoCodeNode) markNode.getParent()).setSelected(false);
|
|
|
+ markNode.setSelected(false);
|
|
|
return StageStatus.FINISHED;
|
|
|
}
|
|
|
l1 = 0;
|
|
@@ -111,31 +196,32 @@ public class ConflictDetection implements AlgorithmStage {
|
|
|
|
|
|
@Override
|
|
|
public StageStatus backwardStep() {
|
|
|
- ((PseudoCodeNode)markNode.getParent()).setSelected( true );
|
|
|
- CodeAction action = markNode.setSelected( true );
|
|
|
+ ((PseudoCodeNode) markNode.getParent()).setSelected(true);
|
|
|
+ CodeAction action = markNode.setSelected(true);
|
|
|
boolean breakPoint = action == CodeAction.STOP;
|
|
|
- if( actions.size() == 0 )
|
|
|
- {
|
|
|
- ((PseudoCodeNode)markNode.getParent()).setSelected( false );
|
|
|
- markNode.setSelected( false );
|
|
|
+ if (actions.size() == 0) {
|
|
|
+ ((PseudoCodeNode) markNode.getParent()).setSelected(false);
|
|
|
+ markNode.setSelected(false);
|
|
|
return StageStatus.FINISHED;
|
|
|
}
|
|
|
- actions.get( 0 ).reverse();
|
|
|
- actions.remove( 0 );
|
|
|
- if( breakPoint )
|
|
|
+ actions.get(0).reverse();
|
|
|
+ actions.remove(0);
|
|
|
+ if (breakPoint)
|
|
|
return StageStatus.BREAKPOINT;
|
|
|
- if( action == CodeAction.SKIP )
|
|
|
+ if (action == CodeAction.SKIP)
|
|
|
return backwardStep();
|
|
|
return StageStatus.UNFINISHED;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public PseudoCodeNode createPseudocodeTree( JTree tree ) {
|
|
|
- PseudoCodeNode root = new PseudoCodeNode( "Preprocessing (mark type 1 conflicts)", tree );
|
|
|
- PseudoCodeNode loopNode = new PseudoCodeNode( "Loop through all nodes...", tree );
|
|
|
- markNode = new PseudoCodeNode( "If non-inner segment crosses an inner segment whose target is this node, mark the non-inner segment as conflicted", tree );
|
|
|
- loopNode.add( markNode );
|
|
|
- root.add( loopNode );
|
|
|
+ public PseudoCodeNode createPseudocodeTree(JTree tree) {
|
|
|
+ PseudoCodeNode root = new PseudoCodeNode("Preprocessing (mark type 1 conflicts)", tree);
|
|
|
+ PseudoCodeNode loopNode = new PseudoCodeNode("Loop through all nodes...", tree);
|
|
|
+ markNode = new PseudoCodeNode(
|
|
|
+ "If non-inner segment crosses an inner segment whose target is this node, mark the non-inner segment as conflicted",
|
|
|
+ tree);
|
|
|
+ loopNode.add(markNode);
|
|
|
+ root.add(loopNode);
|
|
|
return root;
|
|
|
}
|
|
|
|
|
@@ -147,7 +233,7 @@ public class ConflictDetection implements AlgorithmStage {
|
|
|
@Override
|
|
|
public StageStatus forwardStepOut() {
|
|
|
StageStatus status = StageStatus.UNFINISHED;
|
|
|
- while( status == StageStatus.UNFINISHED )
|
|
|
+ while (status == StageStatus.UNFINISHED)
|
|
|
status = forwardStep();
|
|
|
return status;
|
|
|
}
|
|
@@ -160,14 +246,28 @@ public class ConflictDetection implements AlgorithmStage {
|
|
|
@Override
|
|
|
public StageStatus backwardStepOut() {
|
|
|
StageStatus status = StageStatus.UNFINISHED;
|
|
|
- while( status == StageStatus.UNFINISHED )
|
|
|
+ while (status == StageStatus.UNFINISHED)
|
|
|
status = backwardStep();
|
|
|
return status;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public String getDebugString()
|
|
|
- {
|
|
|
+ public String getDebugString() {
|
|
|
return "";
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * part of line 4 and 6 in the pseudocode
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private boolean incidentToInnerSegmentBetweenLiPlusOneAndLi() {
|
|
|
+ LayeredGraphNode curr = graph.getContainedLayers().get(i + 1).get(l1);
|
|
|
+ for (LayeredGraphEdge e : curr.getIncomingEdges()) {
|
|
|
+ if (e.isDummyEdge()) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
}
|