|
@@ -6,10 +6,12 @@ import java.util.Collections;
|
|
|
import javax.swing.JTree;
|
|
|
|
|
|
import animation.AlgorithmStage;
|
|
|
-import animation.BackwardAction;
|
|
|
+import animation.AnimatedAlgorithm;
|
|
|
+import animation.CodeLine;
|
|
|
+import animation.ControlFlow;
|
|
|
+import animation.Memory;
|
|
|
import animation.PseudoCodeNode;
|
|
|
import animation.PseudoCodeNode.CodeAction;
|
|
|
-import bk.ExtremalLayoutCalc.LayoutType;
|
|
|
import graph.LayeredGraphNode;
|
|
|
import lib.TextLayoutHelper;
|
|
|
|
|
@@ -20,530 +22,28 @@ import lib.TextLayoutHelper;
|
|
|
*/
|
|
|
public class Compaction implements AlgorithmStage{
|
|
|
|
|
|
- private enum CompactionState
|
|
|
- {
|
|
|
- PLACE_BLOCKS,
|
|
|
- APPLY_SHIFT
|
|
|
- }
|
|
|
-
|
|
|
- private class StackFrame
|
|
|
- {
|
|
|
- public LayeredGraphNode v;
|
|
|
- public LayeredGraphNode u;
|
|
|
- public LayeredGraphNode w;
|
|
|
- }
|
|
|
-
|
|
|
- private CompactionState state;
|
|
|
private LayeredGraphNode graph;
|
|
|
- private int vIndex;
|
|
|
+ private AnimatedAlgorithm alg;
|
|
|
|
|
|
- private ArrayList< StackFrame > stack; // TODO: evtl richtigen "Stack" benutzen
|
|
|
- private ArrayList< BackwardAction > actions; // TODO: evtl richtigen "Stack" benutzen
|
|
|
- private LayoutType layout;
|
|
|
- private PseudoCodeNode placeNode;
|
|
|
- private PseudoCodeNode placeLoopNode;
|
|
|
- private PseudoCodeNode applyNode;
|
|
|
- private PseudoCodeNode applyLoopNode;
|
|
|
- private boolean breakPoint;
|
|
|
- private boolean inside;
|
|
|
- private boolean skip;
|
|
|
|
|
|
-
|
|
|
- public Compaction( LayeredGraphNode graph, LayoutType layout )
|
|
|
+ public Compaction( LayeredGraphNode graph, AnimatedAlgorithm alg )
|
|
|
{
|
|
|
- this.layout = layout;
|
|
|
this.graph = graph;
|
|
|
- state = CompactionState.PLACE_BLOCKS;
|
|
|
- stack = new ArrayList<>(); // der call-stack des rekursiven algorithmus
|
|
|
- vIndex = 0;
|
|
|
- actions = new ArrayList<>();
|
|
|
- inside = false;
|
|
|
- skip = false;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * calculates the minimum spacing needed between two left borders of nodes.
|
|
|
- * @return the spacing
|
|
|
- */
|
|
|
- public double calcSpacing()
|
|
|
- {
|
|
|
- double max = 0;
|
|
|
- for( LayeredGraphNode n : graph.getContainedNodes() )
|
|
|
- max = Math.max( max, n.getWidth( layout ) );
|
|
|
- //return max + 25;
|
|
|
- return max + 5;
|
|
|
- }
|
|
|
-
|
|
|
- private LayeredGraphNode getNodeFromIndex( int index )
|
|
|
- {
|
|
|
- @SuppressWarnings("unchecked")
|
|
|
- ArrayList<ArrayList<LayeredGraphNode>> layer = (ArrayList<ArrayList<LayeredGraphNode>>) graph.getContainedLayers().clone();
|
|
|
- if( layout == LayoutType.BOTTOM_TOP_LEFT || layout == LayoutType.BOTTOM_TOP_RIGHT )
|
|
|
- Collections.reverse( layer );
|
|
|
- for( ArrayList< LayeredGraphNode > l : layer )
|
|
|
- {
|
|
|
- if( index >= l.size() )
|
|
|
- index -= l.size();
|
|
|
- else
|
|
|
- {
|
|
|
- if( layout == LayoutType.BOTTOM_TOP_LEFT || layout == LayoutType.TOP_BOTTOM_LEFT )
|
|
|
- return l.get( index );
|
|
|
- else
|
|
|
- return l.get( l.size() - index - 1 );
|
|
|
- }
|
|
|
- }
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public StageStatus forwardStep() {
|
|
|
- breakPoint = false;
|
|
|
- skip = false;
|
|
|
- int acSize = actions.size();
|
|
|
- if( state == CompactionState.PLACE_BLOCKS ) // blöcke platzieren
|
|
|
- {
|
|
|
- inside = true;
|
|
|
- boolean sel = placeNode.isSelected();
|
|
|
- CodeAction action = placeNode.setSelected( true );
|
|
|
- if( !sel )
|
|
|
- breakPoint = action == CodeAction.STOP;
|
|
|
- skip |= action == CodeAction.SKIP;
|
|
|
- action = placeLoopNode.setSelected( true );
|
|
|
- breakPoint |= action == CodeAction.STOP;
|
|
|
- skip |= action == CodeAction.SKIP;
|
|
|
- if( stack.size() == 0 ) // äußere schleife, placeblocks bisher nicht aufgerufen
|
|
|
- {
|
|
|
- ArrayList< LayeredGraphNode > nodes = graph.getContainedNodes();
|
|
|
- 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( getNodeFromIndex( vIndex ).isXUndefined( layout ) && getNodeFromIndex( vIndex ) == getNodeFromIndex( vIndex ).getRoot( layout ) )
|
|
|
- {
|
|
|
- found = true;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // kein knoten gefunden
|
|
|
- if( !found )
|
|
|
- {
|
|
|
- // wechsele in die phase des Blöckeshiftens
|
|
|
- placeNode.setSelected( false );
|
|
|
- placeLoopNode.setSelected( false );
|
|
|
- sel = applyNode.isSelected();
|
|
|
- action = applyNode.setSelected( true );
|
|
|
- if( !sel )
|
|
|
- breakPoint |= action == CodeAction.STOP;
|
|
|
- skip |= action == CodeAction.SKIP;
|
|
|
- action = applyLoopNode.setSelected( true );
|
|
|
- breakPoint |= action == CodeAction.STOP;
|
|
|
- skip |= action == CodeAction.SKIP;
|
|
|
- state = CompactionState.APPLY_SHIFT;
|
|
|
- inside = false;
|
|
|
- vIndex = 0;
|
|
|
- actions.add( 0, ()-> {
|
|
|
- applyNode.setSelected( false );
|
|
|
- applyLoopNode.setSelected( false );
|
|
|
- breakPoint = false;
|
|
|
- skip = false;
|
|
|
- boolean selected = placeNode.isSelected();
|
|
|
- CodeAction ac = placeNode.setSelected( true );
|
|
|
- if( !selected )
|
|
|
- breakPoint |= ac == CodeAction.STOP;
|
|
|
- skip |= ac == CodeAction.SKIP;
|
|
|
- ac = placeLoopNode.setSelected( true );
|
|
|
- breakPoint |= ac == CodeAction.STOP;
|
|
|
- skip |= ac == CodeAction.SKIP;
|
|
|
- vIndex = oldVIndex;
|
|
|
- inside = false;
|
|
|
- state = CompactionState.PLACE_BLOCKS;
|
|
|
- } );
|
|
|
- }
|
|
|
- else // Knoten gefunden
|
|
|
- {
|
|
|
- StackFrame f = new StackFrame(); // enthält lokale variablen
|
|
|
- f.v = getNodeFromIndex( vIndex );
|
|
|
- double oldX = f.v.getX( layout ); // nötig für "undo"
|
|
|
- f.v.setX( 0, true, layout );
|
|
|
- f.w = f.v;
|
|
|
- f.w.setSelected( layout ); // zeige knoten als aktiven knoten an
|
|
|
- System.out.println( "call place_block( " + f.v + " )" );
|
|
|
- stack.add( 0, f );
|
|
|
-
|
|
|
- // die "undo"-action
|
|
|
- actions.add( 0, ()-> {
|
|
|
- breakPoint = false;
|
|
|
- skip = false;
|
|
|
- boolean selected = placeNode.isSelected();
|
|
|
- CodeAction ac = placeNode.setSelected( true );
|
|
|
- if( !selected )
|
|
|
- breakPoint |= ac == CodeAction.STOP;
|
|
|
- skip |= ac == CodeAction.SKIP;
|
|
|
- ac = placeLoopNode.setSelected( true );
|
|
|
- breakPoint |= ac == CodeAction.STOP;
|
|
|
- skip |= ac == CodeAction.SKIP;
|
|
|
- inside = true;
|
|
|
- stack.get( 0 ).v.setX( oldX, false, layout );
|
|
|
- stack.get( 0 ).v.setSelected( layout );
|
|
|
- stack.remove( 0 );
|
|
|
- vIndex = oldVIndex;
|
|
|
- state = CompactionState.PLACE_BLOCKS;
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
- else // zurzeit innerhalb einer placeblock methode
|
|
|
- {
|
|
|
- StackFrame sf = stack.get( 0 );
|
|
|
- if( sf.u == null ) // zu beginn der placeblock methode
|
|
|
- {
|
|
|
- int posW = graph.getContainedLayers().get( sf.w.getLayer() ).indexOf( sf.w );
|
|
|
- if( (posW >= 1 && (layout == LayoutType.BOTTOM_TOP_LEFT || layout == LayoutType.TOP_BOTTOM_LEFT)) || (posW < graph.getContainedLayers().get( sf.w.getLayer() ).size() - 1 && (layout == LayoutType.BOTTOM_TOP_RIGHT || layout == LayoutType.TOP_BOTTOM_RIGHT)) ) // if pos[w] > 1"
|
|
|
- {
|
|
|
- int offset = -1;
|
|
|
- if( layout == LayoutType.BOTTOM_TOP_RIGHT || layout == LayoutType.TOP_BOTTOM_RIGHT )
|
|
|
- offset = 1;
|
|
|
- sf.u = graph.getContainedLayers().get( sf.w.getLayer() ).get( posW + offset ).getRoot( layout );
|
|
|
-
|
|
|
- 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 ); // nötig für "undo"
|
|
|
- nsf.v.setX( 0, true, layout );
|
|
|
- nsf.w = nsf.v;
|
|
|
- nsf.w.setSelected( layout ); // zeige knoten als aktiven knoten an
|
|
|
- System.out.println( "call place_block( " + nsf.v + " )" );
|
|
|
- stack.add( 0, nsf );
|
|
|
-
|
|
|
- // die "undo"-action
|
|
|
- actions.add( 0, ()-> {
|
|
|
- breakPoint = false;
|
|
|
- skip = false;
|
|
|
- boolean selected = placeNode.isSelected();
|
|
|
- CodeAction ac = placeNode.setSelected( true );
|
|
|
- if( !selected )
|
|
|
- breakPoint |= ac == CodeAction.STOP;
|
|
|
- skip |= ac == CodeAction.SKIP;
|
|
|
- ac = placeLoopNode.setSelected( true );
|
|
|
- breakPoint |= ac == CodeAction.STOP;
|
|
|
- skip |= ac == CodeAction.SKIP;
|
|
|
- inside = true;
|
|
|
- stack.get( 0 ).v.setX( oldX, false, layout );
|
|
|
- stack.get( 0 ).v.setSelected( layout );
|
|
|
- stack.remove( 0 );
|
|
|
- stack.get( 0 ).u = null;
|
|
|
- });
|
|
|
- }
|
|
|
- else // nein
|
|
|
- {
|
|
|
- // tue nix
|
|
|
- sf.w.setSelected( layout );
|
|
|
- actions.add( 0, ()-> {
|
|
|
- breakPoint = false;
|
|
|
- skip = false;
|
|
|
- boolean selected = placeNode.isSelected();
|
|
|
- CodeAction ac = placeNode.setSelected( true );
|
|
|
- if( !selected )
|
|
|
- breakPoint |= ac == CodeAction.STOP;
|
|
|
- skip |= ac == CodeAction.SKIP;
|
|
|
- ac = placeLoopNode.setSelected( true );
|
|
|
- breakPoint |= ac == CodeAction.STOP;
|
|
|
- skip |= ac == CodeAction.SKIP;
|
|
|
- inside = true;
|
|
|
- stack.get( 0 ).u = null;
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- { // w = align[w]
|
|
|
- LayeredGraphNode oldW = sf.w;
|
|
|
- sf.w = sf.w.getAlign( layout );
|
|
|
- sf.w.setSelected( layout );
|
|
|
- if( sf.w == sf.v ) // schleifenabbruchbedingung
|
|
|
- { //abbrechen, placeblock beendet
|
|
|
- System.out.println( "return place_block( " + sf.v + " )" );
|
|
|
- stack.remove( 0 );
|
|
|
- actions.add( 0, ()-> {
|
|
|
- breakPoint = false;
|
|
|
- skip = false;
|
|
|
- boolean selected = placeNode.isSelected();
|
|
|
- CodeAction ac = placeNode.setSelected( true );
|
|
|
- if( !selected )
|
|
|
- breakPoint |= ac == CodeAction.STOP;
|
|
|
- skip |= ac == CodeAction.SKIP;
|
|
|
- ac = placeLoopNode.setSelected( true );
|
|
|
- breakPoint |= ac == CodeAction.STOP;
|
|
|
- skip |= ac == CodeAction.SKIP;
|
|
|
- inside = true;
|
|
|
- stack.add( 0, sf );
|
|
|
- sf.w = oldW;
|
|
|
- sf.w.setSelected( layout );
|
|
|
- });
|
|
|
- }
|
|
|
- else
|
|
|
- { //nur "undo aktion" hinzufügen
|
|
|
- actions.add( 0, ()-> {
|
|
|
- breakPoint = false;
|
|
|
- skip = false;
|
|
|
- boolean selected = placeNode.isSelected();
|
|
|
- CodeAction ac = placeNode.setSelected( true );
|
|
|
- if( !selected )
|
|
|
- breakPoint |= ac == CodeAction.STOP;
|
|
|
- skip |= ac == CodeAction.SKIP;
|
|
|
- ac = placeLoopNode.setSelected( true );
|
|
|
- breakPoint |= ac == CodeAction.STOP;
|
|
|
- skip |= ac == CodeAction.SKIP;
|
|
|
- inside = true;
|
|
|
- sf.w = oldW;
|
|
|
- sf.w.setSelected( layout );
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- else // ein "placeBlock(u)" aufruf hat gerade returned
|
|
|
- {
|
|
|
- // 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.w.setSelected( layout );
|
|
|
-
|
|
|
- if( sf.v.getSink( layout ) == sf.v ) // sink[v] = v?
|
|
|
- sf.v.setSink( sf.u.getSink( layout ), layout ); // sink[v] := sink[u]
|
|
|
- int multiplyer = 1;
|
|
|
- if( layout == LayoutType.BOTTOM_TOP_RIGHT || layout == LayoutType.TOP_BOTTOM_RIGHT )
|
|
|
- multiplyer = -1;
|
|
|
-
|
|
|
- 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]]
|
|
|
- multiplyer * (Math.abs(sf.v.getX( layout )) - Math.abs(sf.u.getX( layout )) - calcSpacing()) ), layout ); // y_v - y_u - s
|
|
|
- else
|
|
|
- // y_v = max {y_v, y_u + s}
|
|
|
- sf.v.setX( multiplyer * Math.max( Math.abs( sf.v.getX( layout ) ), Math.abs( sf.u.getX( layout ) ) + calcSpacing() ), true, layout );
|
|
|
-
|
|
|
-
|
|
|
- // alte Werte merken für undo
|
|
|
- LayeredGraphNode oldW = sf.w;
|
|
|
- LayeredGraphNode oldU = sf.u;
|
|
|
-
|
|
|
- sf.w = sf.w.getAlign( layout ); // w = align[w]
|
|
|
- sf.u = null; // u wird nächsten schleifendurchlauf neu gesetzt
|
|
|
-
|
|
|
- if( sf.w == sf.v ) // schleifenabbruchbedingung
|
|
|
- { //abbrechen, placeblock beendet
|
|
|
- System.out.println( "return place_block( " + sf.v + " )" );
|
|
|
- stack.remove( 0 );
|
|
|
- actions.add( 0, ()-> {
|
|
|
- breakPoint = false;
|
|
|
- skip = false;
|
|
|
- boolean selected = placeNode.isSelected();
|
|
|
- CodeAction ac = placeNode.setSelected( true );
|
|
|
- if( !selected )
|
|
|
- breakPoint |= ac == CodeAction.STOP;
|
|
|
- skip |= ac == CodeAction.SKIP;
|
|
|
- ac = placeLoopNode.setSelected( true );
|
|
|
- breakPoint |= ac == CodeAction.STOP;
|
|
|
- skip |= ac == CodeAction.SKIP;
|
|
|
- inside = true;
|
|
|
- stack.add( 0, sf );
|
|
|
- stack.get( 0 ).v.setSink( oldSink, layout );
|
|
|
- sinkOfU.setShift( oldShift, layout );
|
|
|
- sf.u = oldU;
|
|
|
- sf.v.setX( oldX, oldDef, layout );
|
|
|
- sf.w = oldW;
|
|
|
- sf.w.setSelected( layout );
|
|
|
- });
|
|
|
- }
|
|
|
- else
|
|
|
- { //nur "undo aktion" hinzufügen
|
|
|
- actions.add( 0, ()-> {
|
|
|
- breakPoint = false;
|
|
|
- skip = false;
|
|
|
- boolean selected = placeNode.isSelected();
|
|
|
- CodeAction ac = placeNode.setSelected( true );
|
|
|
- if( !selected )
|
|
|
- breakPoint |= ac == CodeAction.STOP;
|
|
|
- skip |= ac == CodeAction.SKIP;
|
|
|
- ac = placeLoopNode.setSelected( true );
|
|
|
- breakPoint |= ac == CodeAction.STOP;
|
|
|
- skip |= ac == CodeAction.SKIP;
|
|
|
- inside = true;
|
|
|
- stack.get( 0 ).v.setSink( oldSink, layout );
|
|
|
- sinkOfU.setShift( oldShift, layout );
|
|
|
- sf.u = oldU;
|
|
|
- sf.v.setX( oldX, oldDef, layout );
|
|
|
- sf.w = oldW;
|
|
|
- sf.w.setSelected( layout );
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- else if( state == CompactionState.APPLY_SHIFT )// "Compute absolute coordinates"
|
|
|
- {
|
|
|
- inside = true;
|
|
|
- skip = false;
|
|
|
- boolean sel = placeNode.isSelected();
|
|
|
- CodeAction action = applyNode.setSelected( true );
|
|
|
- if( !sel )
|
|
|
- breakPoint |= action == CodeAction.STOP;
|
|
|
- skip |= action == CodeAction.SKIP;
|
|
|
- action = applyLoopNode.setSelected( true );
|
|
|
- breakPoint |= action == CodeAction.STOP;
|
|
|
- skip |= action == CodeAction.SKIP;
|
|
|
- if( vIndex >= graph.getContainedNodes().size() )
|
|
|
- {
|
|
|
- inside = false;
|
|
|
- applyNode.setSelected( false );
|
|
|
- applyLoopNode.setSelected( false );
|
|
|
- return StageStatus.FINISHED;
|
|
|
- }
|
|
|
- LayeredGraphNode v = getNodeFromIndex( vIndex );
|
|
|
- double oldX = v.getX( layout );
|
|
|
- boolean oldDef = !v.isXUndefined( layout );
|
|
|
-
|
|
|
- v.setSelected( layout );
|
|
|
- v.setX( v.getRoot( layout ).getX( layout ), true, layout ); // y_v = y_root[v]
|
|
|
- if( v == v.getRoot( layout ) && v.getSink( layout ).getShift( layout ) < Double.POSITIVE_INFINITY )
|
|
|
- v.setX( v.getX( layout ) + v.getSink( layout ).getShift( layout ), true, layout );
|
|
|
- actions.add( 0, ()-> {
|
|
|
- inside = true;
|
|
|
- breakPoint = false;
|
|
|
- skip = false;
|
|
|
- boolean selected = placeNode.isSelected();
|
|
|
- CodeAction ac = applyNode.setSelected( true );
|
|
|
- if( !selected )
|
|
|
- breakPoint |= ac == CodeAction.STOP;
|
|
|
- skip |= ac == CodeAction.SKIP;
|
|
|
- ac = applyLoopNode.setSelected( true );
|
|
|
- breakPoint |= ac == CodeAction.STOP;
|
|
|
- skip |= ac == CodeAction.SKIP;
|
|
|
- v.setX( oldX, oldDef, layout );
|
|
|
- v.setSelected( layout );
|
|
|
- vIndex--;
|
|
|
- } );
|
|
|
- vIndex++;
|
|
|
- if( vIndex >= graph.getContainedNodes().size() )
|
|
|
- {
|
|
|
- applyNode.setSelected( false );
|
|
|
- applyLoopNode.setSelected( false );
|
|
|
- return StageStatus.FINISHED;
|
|
|
- }
|
|
|
- }
|
|
|
- if( actions.size() != acSize + 1 )
|
|
|
- System.out.println( "ERROR" );
|
|
|
- if( breakPoint )
|
|
|
- return StageStatus.BREAKPOINT;
|
|
|
- if( skip )
|
|
|
- return forwardStep();
|
|
|
- return StageStatus.UNFINISHED;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public StageStatus backwardStep() {
|
|
|
- if( actions.size() == 0 )
|
|
|
- {
|
|
|
- inside = false;
|
|
|
- placeNode.setSelected( false );
|
|
|
- placeLoopNode.setSelected( false );
|
|
|
- return StageStatus.FINISHED;
|
|
|
- }
|
|
|
- actions.get( 0 ).reverse();
|
|
|
- actions.remove( 0 );
|
|
|
- if( breakPoint )
|
|
|
- return StageStatus.BREAKPOINT;
|
|
|
- if( skip )
|
|
|
- return backwardStep();
|
|
|
- return StageStatus.UNFINISHED;
|
|
|
+ this.alg = alg;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public PseudoCodeNode createPseudocodeTree( JTree tree ) {
|
|
|
- PseudoCodeNode root = new PseudoCodeNode( TextLayoutHelper.setupPseudoCodeStage("Horizontal compaction"), tree );
|
|
|
- placeNode = new PseudoCodeNode( TextLayoutHelper.setupPseudoCodeStage("Root coordinates relative to sink"), tree );
|
|
|
- placeLoopNode = new PseudoCodeNode( "Loop through root nodes...", tree );
|
|
|
- placeNode.add( placeLoopNode );
|
|
|
- applyNode = new PseudoCodeNode( TextLayoutHelper.setupPseudoCodeStage("Absolute coordinates"), tree );
|
|
|
- applyLoopNode = new PseudoCodeNode( "Loop through all nodes...", tree );
|
|
|
- applyNode.add( applyLoopNode );
|
|
|
- root.add( placeNode );
|
|
|
- root.add( applyNode );
|
|
|
+ PseudoCodeNode root = new PseudoCodeNode( TextLayoutHelper.setupPseudoCodeStage("Horizontal compaction"), tree, new CodeLine() {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ControlFlow runForward(Memory m) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ }, alg );
|
|
|
return root;
|
|
|
}
|
|
|
-
|
|
|
- @Override
|
|
|
- public StageStatus forwardStepOver() {
|
|
|
- if( !inside )
|
|
|
- {
|
|
|
- CompactionState oldState = state;
|
|
|
- StageStatus stage = StageStatus.UNFINISHED;
|
|
|
- while( state == oldState && stage == StageStatus.UNFINISHED )
|
|
|
- stage = forwardStep();
|
|
|
- return stage;
|
|
|
- }
|
|
|
- else
|
|
|
- return forwardStep();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public StageStatus forwardStepOut() {
|
|
|
- if( !inside )
|
|
|
- {
|
|
|
- StageStatus status = StageStatus.UNFINISHED;
|
|
|
- while( status == StageStatus.UNFINISHED )
|
|
|
- status = forwardStep();
|
|
|
- return status;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- CompactionState oldState = state;
|
|
|
- StageStatus stage = StageStatus.UNFINISHED;
|
|
|
- while( state == oldState && stage == StageStatus.UNFINISHED )
|
|
|
- stage = forwardStep();
|
|
|
- return stage;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public StageStatus backwardStepOver() {
|
|
|
- if( !inside )
|
|
|
- {
|
|
|
- CompactionState oldState = state;
|
|
|
- StageStatus stage = StageStatus.UNFINISHED;
|
|
|
- while( state == oldState && stage == StageStatus.UNFINISHED )
|
|
|
- stage = backwardStep();
|
|
|
- return stage;
|
|
|
- }
|
|
|
- else
|
|
|
- return backwardStep();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public StageStatus backwardStepOut() {
|
|
|
- if( !inside )
|
|
|
- {
|
|
|
- StageStatus status = StageStatus.UNFINISHED;
|
|
|
- while( status == StageStatus.UNFINISHED )
|
|
|
- status = backwardStep();
|
|
|
- return status;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- CompactionState oldState = state;
|
|
|
- StageStatus stage = StageStatus.UNFINISHED;
|
|
|
- while( state == oldState && stage == StageStatus.UNFINISHED )
|
|
|
- stage = backwardStep();
|
|
|
- return stage;
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
@Override
|
|
|
public String getDebugString()
|