|
@@ -31,8 +31,8 @@ public class Compaction implements AlgorithmStage{
|
|
|
private LayeredGraphNode graph;
|
|
|
private int vIndex;
|
|
|
|
|
|
- private ArrayList< StackFrame > stack;
|
|
|
- private ArrayList< BackwardAction > actions;
|
|
|
+ private ArrayList< StackFrame > stack; // TODO: evtl richtigen "Stack" benutzen
|
|
|
+ private ArrayList< BackwardAction > actions; // TODO: evtl richtigen "Stack" benutzen
|
|
|
private LayoutType layout;
|
|
|
|
|
|
public Compaction( LayeredGraphNode graph, LayoutType layout )
|
|
@@ -40,7 +40,7 @@ public class Compaction implements AlgorithmStage{
|
|
|
this.layout = layout;
|
|
|
this.graph = graph;
|
|
|
state = CompactionState.PLACE_BLOCKS;
|
|
|
- stack = new ArrayList<>();
|
|
|
+ stack = new ArrayList<>(); // der call-stack des rekursiven algorithmus
|
|
|
vIndex = 0;
|
|
|
actions = new ArrayList<>();
|
|
|
}
|
|
@@ -56,13 +56,15 @@ public class Compaction implements AlgorithmStage{
|
|
|
@Override
|
|
|
public StageStatus forwardStep() {
|
|
|
int acSize = actions.size();
|
|
|
- if( state == CompactionState.PLACE_BLOCKS )
|
|
|
+ if( state == CompactionState.PLACE_BLOCKS ) // blöcke platzieren
|
|
|
{
|
|
|
- if( stack.size() == 0 )
|
|
|
+ if( stack.size() == 0 ) // äußere schleife, placeblocks bisher nicht aufgerufen
|
|
|
{
|
|
|
ArrayList< LayeredGraphNode > nodes = graph.getContainedNodes();
|
|
|
- boolean found = false;
|
|
|
- int oldVIndex = vIndex;
|
|
|
+ boolean found = false; // knoten mit v = root[v] gefunden?
|
|
|
+ int oldVIndex = vIndex; // nötig für "undo"
|
|
|
+
|
|
|
+ // suche knoten mit v = root[v] und undefiniertem x-Wert
|
|
|
for( ; vIndex < nodes.size(); vIndex++ )
|
|
|
{
|
|
|
if( nodes.get( vIndex ).isXUndefined( layout ) && nodes.get( vIndex ) == nodes.get( vIndex ).getRoot( layout ) )
|
|
@@ -71,8 +73,11 @@ public class Compaction implements AlgorithmStage{
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ // kein knoten gefunden
|
|
|
if( !found )
|
|
|
{
|
|
|
+ // wechsele in die phase des Blöckeshiftens
|
|
|
state = CompactionState.APPLY_SHIFT;
|
|
|
vIndex = 0;
|
|
|
actions.add( 0, ()-> {
|
|
@@ -80,15 +85,17 @@ public class Compaction implements AlgorithmStage{
|
|
|
state = CompactionState.PLACE_BLOCKS;
|
|
|
} );
|
|
|
}
|
|
|
- else
|
|
|
+ else // Knoten gefunden
|
|
|
{
|
|
|
- StackFrame f = new StackFrame();
|
|
|
+ StackFrame f = new StackFrame(); // enthält lokale variablen
|
|
|
f.v = nodes.get( vIndex );
|
|
|
- double oldX = f.v.getX( layout );
|
|
|
+ double oldX = f.v.getX( layout ); // nötig für "undo"
|
|
|
f.v.setX( 0, true, layout );
|
|
|
- f.v.setSelected( layout );
|
|
|
+ f.v.setSelected( layout ); // zeige knoten als aktiven knoten an
|
|
|
f.w = f.v;
|
|
|
stack.add( 0, f );
|
|
|
+
|
|
|
+ // die "undo"-action
|
|
|
actions.add( 0, ()-> {
|
|
|
stack.get( 0 ).v.setX( oldX, false, layout );
|
|
|
stack.get( 0 ).v.setSelected( layout );
|
|
@@ -98,23 +105,27 @@ public class Compaction implements AlgorithmStage{
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
- else
|
|
|
+ else // zurzeit innerhalb einer placeblock methode
|
|
|
{
|
|
|
StackFrame sf = stack.get( 0 );
|
|
|
- if( sf.u == null )
|
|
|
+ if( sf.u == null ) // zu beginn der placeblock methode
|
|
|
{
|
|
|
- if( graph.getContainedLayers().get( sf.w.getLayer() ).indexOf( sf.w ) >= 1 )
|
|
|
+ if( graph.getContainedLayers().get( sf.w.getLayer() ).indexOf( sf.w ) >= 1 ) // if pos[w] > 1"
|
|
|
{
|
|
|
+
|
|
|
sf.u = graph.getContainedLayers().get( sf.w.getLayer() ).get( graph.getContainedLayers().get( sf.w.getLayer() ).indexOf( sf.w ) - 1 ).getRoot( layout );
|
|
|
- if( sf.u.isXUndefined( layout ) )
|
|
|
- {
|
|
|
- StackFrame nsf = new StackFrame();
|
|
|
+
|
|
|
+ if( sf.u.isXUndefined( layout ) ) // nötig placeblock aufzurufen?
|
|
|
+ {// ja
|
|
|
+ StackFrame nsf = new StackFrame(); // enthält lokale variablen
|
|
|
nsf.v = sf.u;
|
|
|
- double oldX = nsf.v.getX( layout );
|
|
|
+ double oldX = nsf.v.getX( layout ); // nötig für "undo"
|
|
|
nsf.v.setX( 0, true, layout );
|
|
|
- nsf.v.setSelected( layout );
|
|
|
+ nsf.v.setSelected( layout ); // zeige knoten als aktiven knoten an
|
|
|
nsf.w = nsf.v;
|
|
|
stack.add( 0, nsf );
|
|
|
+
|
|
|
+ // die "undo"-action
|
|
|
actions.add( 0, ()-> {
|
|
|
stack.get( 0 ).v.setX( oldX, false, layout );
|
|
|
stack.get( 0 ).v.setSelected( layout );
|
|
@@ -122,21 +133,23 @@ public class Compaction implements AlgorithmStage{
|
|
|
stack.get( 0 ).u = null;
|
|
|
});
|
|
|
}
|
|
|
- else
|
|
|
+ else // nein
|
|
|
{
|
|
|
- sf.u.setSelected( layout );
|
|
|
+ // tue nix
|
|
|
+ sf.u.setSelected( layout );
|
|
|
actions.add( 0, ()-> {
|
|
|
stack.get( 0 ).u = null;
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
- else
|
|
|
- {
|
|
|
+ else
|
|
|
+ { // w = align[w]
|
|
|
LayeredGraphNode oldW = sf.w;
|
|
|
sf.v.setSelected( layout );
|
|
|
sf.w = sf.w.getAlignedTo( layout );
|
|
|
- if( sf.w == sf.v )
|
|
|
- {
|
|
|
+
|
|
|
+ if( sf.w == sf.v ) // schleifenabbruchbedingung
|
|
|
+ { //abbrechen, placeblock beendet
|
|
|
stack.remove( 0 );
|
|
|
actions.add( 0, ()-> {
|
|
|
stack.add( 0, sf );
|
|
@@ -145,7 +158,7 @@ public class Compaction implements AlgorithmStage{
|
|
|
});
|
|
|
}
|
|
|
else
|
|
|
- {
|
|
|
+ { //nur "undo aktion" hinzufügen
|
|
|
actions.add( 0, ()-> {
|
|
|
sf.w = oldW;
|
|
|
sf.v.setSelected( layout );
|
|
@@ -153,26 +166,39 @@ public class Compaction implements AlgorithmStage{
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- else
|
|
|
+ else // der Teil nach "placeBlock(u)"
|
|
|
{
|
|
|
- LayeredGraphNode oldSink = sf.v.getSink( layout );
|
|
|
- if( sf.v.getSink( layout ) == sf.v )
|
|
|
- sf.v.setSink( sf.u.getSink( layout ), layout );
|
|
|
+ // alte Werte merken für undo
|
|
|
+ LayeredGraphNode oldSink = sf.v.getSink( layout );
|
|
|
LayeredGraphNode sinkOfU = sf.u.getSink( layout );
|
|
|
double oldShift = sinkOfU.getShift( layout );
|
|
|
double oldX = sf.v.getX( layout );
|
|
|
boolean oldDef = !sf.v.isXUndefined( layout );
|
|
|
+
|
|
|
+ // v für visualisierung markieren
|
|
|
sf.v.setSelected( layout );
|
|
|
- if( sf.v.getSink( layout ) != sf.u.getSink( layout ) )
|
|
|
- sf.u.getSink( layout ).setShift( Math.min( sf.u.getSink( layout ).getShift( layout ), sf.v.getX( layout ) - sf.u.getX( layout ) - calcSpacing() ), layout );
|
|
|
+
|
|
|
+ if( sf.v.getSink( layout ) == sf.v ) // sink[v] = v?
|
|
|
+ sf.v.setSink( sf.u.getSink( layout ), layout ); // sink[v] := sink[u]
|
|
|
+
|
|
|
+ if( sf.v.getSink( layout ) != sf.u.getSink( layout ) ) // sink[v] != sink [u]?
|
|
|
+ sf.u.getSink( layout ).setShift( // shift[sink[u]] =
|
|
|
+ Math.min( sf.u.getSink( layout ).getShift( layout ), // min(shift[sink[u]]
|
|
|
+ sf.v.getX( layout ) - sf.u.getX( layout ) - calcSpacing() ), layout ); // y_v - y_u - s
|
|
|
else
|
|
|
+ // y_v = max {y_v, y_u + s}
|
|
|
sf.v.setX( Math.max( sf.v.getX( layout ), sf.u.getX( layout ) + calcSpacing() ), true, layout );
|
|
|
+
|
|
|
+
|
|
|
+ // alte Werte merken für undo
|
|
|
LayeredGraphNode oldW = sf.w;
|
|
|
- sf.w = sf.w.getAlignedTo( layout );
|
|
|
- LayeredGraphNode oldU = sf.u;
|
|
|
- sf.u = null;
|
|
|
- if( sf.w == sf.v )
|
|
|
- {
|
|
|
+ LayeredGraphNode oldU = sf.u;
|
|
|
+
|
|
|
+ sf.w = sf.w.getAlignedTo( layout ); // w = align[w]
|
|
|
+ sf.u = null; // u wird nächsten schleifendurchlauf neu gesetzt
|
|
|
+
|
|
|
+ if( sf.w == sf.v ) // schleifenabbruchbedingung
|
|
|
+ { //abbrechen, placeblock beendet
|
|
|
stack.remove( 0 );
|
|
|
actions.add( 0, ()-> {
|
|
|
stack.add( 0, sf );
|
|
@@ -185,7 +211,7 @@ public class Compaction implements AlgorithmStage{
|
|
|
});
|
|
|
}
|
|
|
else
|
|
|
- {
|
|
|
+ { //nur "undo aktion" hinzufügen
|
|
|
actions.add( 0, ()-> {
|
|
|
stack.get( 0 ).v.setSink( oldSink, layout );
|
|
|
sinkOfU.setShift( oldShift, layout );
|