Forráskód Böngészése

block calculation added (unchecked)

Kolja Strohm 6 éve
szülő
commit
be0b0a69bf

+ 143 - 1
src/bk/BlockCalc.java

@@ -1,16 +1,24 @@
 package bk;
 
 import java.util.ArrayList;
+import java.util.List;
 
 import javax.swing.JTree;
 
 import animation.AlgorithmStage;
+import animation.CodeLine;
+import animation.ControlFlow;
+import animation.Memory;
 import animation.PseudoCodeNode;
 import animation.Memory.MemoryType;
 import animation.Memory.ReadOnlyMemory;
 import codelines.AbstractForLoop;
 import codelines.DeclareVariable;
+import codelines.ForEachLoop;
 import codelines.FunctionDefinition;
+import codelines.IfLoop;
+import codelines.SetVariable;
+import graph.LayeredGraphEdge;
 import graph.LayeredGraphNode;
 import lib.TextLayoutHelper;
 
@@ -23,7 +31,7 @@ public class BlockCalc implements AlgorithmStage {
 
     @Override
     public PseudoCodeNode createPseudocodeTree( JTree tree ) {
-        String[] vars = { "graph", "L", "v", "r", "neighbors", "layout" };
+        String[] vars = { "graph", "L", "r", "neighbors", "layout", "m", "i", "k", "mids" };
         PseudoCodeNode root = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "function calculateBlockGraph( graph, layout )", vars ), tree, new FunctionDefinition( new String[]{ "graph", "layout" } ) );
         root.add( new PseudoCodeNode(TextLayoutHelper.setupPseudoCode( "L = graph.getContainedLayers();", vars), tree, new DeclareVariable<ArrayList<ArrayList<LayeredGraphNode>>>( "L" ) {
             @Override
@@ -80,7 +88,141 @@ public class BlockCalc implements AlgorithmStage {
                 return m.<Integer>read( "k", MemoryType.LOCAL ) >= 0;
             }
         });
+        nodeLoop.add( new PseudoCodeNode(TextLayoutHelper.setupPseudoCode( "neighbors = layout.contains('DOWN') ? L[i][k].predecessors : L[i][k].successors", vars), tree, new DeclareVariable<ArrayList<LayeredGraphNode>>( "neighbors" ) {
+            @Override
+            protected ArrayList<LayeredGraphNode> value(ReadOnlyMemory m) {
+                ArrayList<LayeredGraphEdge> list = m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).get( m.read( "i", MemoryType.LOCAL ) ).get( m.read( "k", MemoryType.LOCAL ) ).getSortedOutgoingEdges();
+                if( m.<String>read( "layout", MemoryType.LOCAL ).contains( "DOWN" ) )
+                    list = m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).get( m.read( "i", MemoryType.LOCAL ) ).get( m.read( "k", MemoryType.LOCAL ) ).getSortedIncomingEdges();
+                ArrayList<LayeredGraphNode> result = new ArrayList<LayeredGraphNode>();
+                for( LayeredGraphEdge e : list )
+                {
+                    if( m.<String>read( "layout", MemoryType.LOCAL ).contains( "DOWN" ) )
+                        result.add( e.getSources().get( 0 ) );
+                    else
+                        result.add( e.getTargets().get( 0 ) );
+                }
+                return result;
+            }
+        } ) );
         layerLoop.add( nodeLoop );
+        nodeLoop.add( new PseudoCodeNode(TextLayoutHelper.setupPseudoCode( "neighbors = layout.contains('RIGHT') ? neighbors : reverse( neighbors )", vars), tree, new SetVariable<ArrayList<LayeredGraphNode>>( "neighbors" ) {
+            @Override
+            protected ArrayList<LayeredGraphNode> value(ReadOnlyMemory m) {
+                ArrayList<LayeredGraphNode> list = m.read( "neighbors", MemoryType.LOCAL );
+                if( m.<String>read( "layout", MemoryType.LOCAL ).contains( "RIGHT" ) )
+                    return list;
+                else
+                {
+                    ArrayList<LayeredGraphNode> result = new ArrayList<LayeredGraphNode>();
+                    for( int i = list.size() - 1; i >= 0; i-- )
+                        result.add( list.get( i ) );
+                    return result;
+                }
+            }
+        } ) );
+        PseudoCodeNode ifNeighbors = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "if |neighbors| > 0 then", vars ), tree, new IfLoop() {
+            @Override
+            protected boolean condition( ReadOnlyMemory m) {
+                return m.<ArrayList<LayeredGraphNode>>read( "neighbors", MemoryType.LOCAL ).size() > 0;
+            }
+        });
+        nodeLoop.add( ifNeighbors );
+        ifNeighbors.add( new PseudoCodeNode(TextLayoutHelper.setupPseudoCode( "mids = [roundDown((|neighbors|-1)/2),roundUp((|neighbors|-1)/2)]", vars), tree, new DeclareVariable<ArrayList<Integer>>( "mids" ) {
+            @Override
+            protected ArrayList<Integer> value(ReadOnlyMemory m) {
+                int size = m.<ArrayList<LayeredGraphNode>>read( "neighbors", MemoryType.LOCAL ).size() - 1;
+                int m1 = size / 2, m2 = (int)(size / 2.0 + 0.5);
+                ArrayList<Integer> list = new ArrayList<Integer>();
+                list.add( m1 );
+                if( m1 != m2 )
+                    list.add( m2 );
+                return list;
+            }
+        } ) );
+        PseudoCodeNode midLoop = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "foreach m in mids do", vars ), tree, new ForEachLoop<Integer>( "m" ) {
+            @Override
+            protected List<Integer> list(ReadOnlyMemory m) {
+                return m.read( "neighbors", MemoryType.LOCAL );
+            }
+        } );
+        ifNeighbors.add( midLoop );
+        PseudoCodeNode ifAlign = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "if align( L[i][k] ) == L[i][k] then", vars ), tree, new IfLoop() {
+            @Override
+            protected boolean condition(ReadOnlyMemory m) {
+                LayeredGraphNode n = m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).get( m.read( "i", MemoryType.LOCAL ) ).get( m.read( "k", MemoryType.LOCAL ) );
+                return n.getAlign( LayoutType.fromString( m.read( "layout", MemoryType.LOCAL ) ) ) == n;
+            }
+        });
+        midLoop.add( ifAlign );
+        PseudoCodeNode ifMarked = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "if (neighbors[m],L[i][k]) not conflicted and ((r < pos(neighbors[m]) and layout.contains('RIGHT')) or (r > pos(neighbors[m]) and layout.contains('LEFT'))) ", vars ), tree, new IfLoop() {
+            @Override
+            protected boolean condition(ReadOnlyMemory m) {
+                LayeredGraphEdge e = m.<LayeredGraphNode>read( "graph", MemoryType.LOCAL ).findEdgeBetween( 
+                        m.<ArrayList<LayeredGraphNode>>read( "neighbors", MemoryType.LOCAL ).get( m.read( "m", MemoryType.LOCAL ) ), 
+                        m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).get( m.read( "i", MemoryType.LOCAL ) ).get( m.read( "k", MemoryType.LOCAL ) ) );
+                ArrayList<LayeredGraphNode> layerBefore;
+                if( m.<String>read( "layout", MemoryType.LOCAL ).contains( "DOWN" ) )
+                    layerBefore = m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).get( m.<Integer>read( "i", MemoryType.LOCAL ) - 1 );
+                else
+                    layerBefore = m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).get( m.<Integer>read( "i", MemoryType.LOCAL ) + 1 );
+                int posU = layerBefore.indexOf( m.<ArrayList<LayeredGraphNode>>read( "neighbors", MemoryType.LOCAL ).get( m.read( "m", MemoryType.LOCAL ) ) );
+                return e.isConflicted( LayoutType.fromString( m.read( "layout", MemoryType.LOCAL ) ) ) && 
+                        ( ( m.<Integer>read( "r", MemoryType.LOCAL ) < posU && m.<String>read( "layout", MemoryType.LOCAL ).contains( "RIGHT" ) ) || 
+                                ( m.<Integer>read( "r", MemoryType.LOCAL ) > posU && m.<String>read( "layout", MemoryType.LOCAL ).contains( "LEFT" ) ) );
+            }
+        });
+        ifAlign.add( ifMarked );
+        ifMarked.add( new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "align( neighbors[m] ) = L[i][k];", vars ), tree, new CodeLine() {
+            @Override
+            public ControlFlow runForward(Memory m) {
+                LayeredGraphNode u = m.<ArrayList<LayeredGraphNode>>read( "neighbors", MemoryType.LOCAL ).get( m.read( "m", MemoryType.LOCAL ) );
+                LayeredGraphNode v = m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).get( m.read( "i", MemoryType.LOCAL ) ).get( m.read( "k", MemoryType.LOCAL ) );
+                LayeredGraphNode old = u.getAlign( LayoutType.fromString( m.read( "layout", MemoryType.LOCAL ) ) );
+                u.setAlign( v, LayoutType.fromString( m.read( "layout", MemoryType.LOCAL ) ) );
+                actions.push( (Memory mem) -> {
+                    u.setAlign( old, LayoutType.fromString( mem.read( "layout", MemoryType.LOCAL ) ) );
+                });
+                return new ControlFlow( ControlFlow.STEP_OVER );
+            }
+        }) );
+        ifMarked.add( new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "root( L[i][k] ) = root( neighbors[m] );", vars ), tree, new CodeLine() {
+            @Override
+            public ControlFlow runForward(Memory m) {
+                LayeredGraphNode u = m.<ArrayList<LayeredGraphNode>>read( "neighbors", MemoryType.LOCAL ).get( m.read( "m", MemoryType.LOCAL ) );
+                LayeredGraphNode v = m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).get( m.read( "i", MemoryType.LOCAL ) ).get( m.read( "k", MemoryType.LOCAL ) );
+                LayeredGraphNode old = v.getRoot( LayoutType.fromString( m.read( "layout", MemoryType.LOCAL ) ) );
+                v.setRoot( u.getRoot( LayoutType.fromString( m.read( "layout", MemoryType.LOCAL ) ) ), LayoutType.fromString( m.read( "layout", MemoryType.LOCAL ) ) );
+                actions.push( (Memory mem) -> {
+                    v.setRoot( old, LayoutType.fromString( m.read( "layout", MemoryType.LOCAL ) ) );
+                });
+                return new ControlFlow( ControlFlow.STEP_OVER );
+            }
+        }) );
+        ifMarked.add( new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "align( L[i][k] ) = root( L[i][k] );", vars ), tree, new CodeLine() {
+            @Override
+            public ControlFlow runForward(Memory m) {
+                LayeredGraphNode v = m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).get( m.read( "i", MemoryType.LOCAL ) ).get( m.read( "k", MemoryType.LOCAL ) );
+                LayeredGraphNode old = v.getAlign( LayoutType.fromString( m.read( "layout", MemoryType.LOCAL ) ) );
+                v.setAlign( v.getAlign( LayoutType.fromString( m.read( "layout", MemoryType.LOCAL ) ) ), LayoutType.fromString( m.read( "layout", MemoryType.LOCAL ) ) );
+                actions.push( (Memory mem) -> {
+                    v.setAlign( old, LayoutType.fromString( m.read( "layout", MemoryType.LOCAL ) ) );
+                });
+                return new ControlFlow( ControlFlow.STEP_OVER );
+            }
+        }) );
+        ifMarked.add( new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "r = pos( neighbors[m] );", vars ), tree, new SetVariable<Integer>( "r" ) {
+            @Override
+            protected Integer value(ReadOnlyMemory m) {
+                ArrayList<LayeredGraphNode> layerBefore;
+                if( m.<String>read( "layout", MemoryType.LOCAL ).contains( "DOWN" ) )
+                    layerBefore = m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).get( m.<Integer>read( "i", MemoryType.LOCAL ) - 1 );
+                else
+                    layerBefore = m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).get( m.<Integer>read( "i", MemoryType.LOCAL ) + 1 );
+                LayeredGraphNode u = m.<ArrayList<LayeredGraphNode>>read( "neighbors", MemoryType.LOCAL ).get( m.read( "m", MemoryType.LOCAL ) );
+                return layerBefore.indexOf( u );
+            }
+        }) );
         return root;
     }
 }

+ 16 - 1
src/bk/LayoutType.java

@@ -11,5 +11,20 @@ public enum LayoutType{
     TOP_BOTTOM_RIGHT,
     BOTTOM_TOP_LEFT,
     BOTTOM_TOP_RIGHT,
-    COMBINED
+    COMBINED;
+    
+    public static LayoutType fromString( String s )
+    {
+        switch( s ) {
+        case "DOWN_RIGHT":
+            return TOP_BOTTOM_LEFT;
+        case "DOWN_LEFT":
+            return TOP_BOTTOM_RIGHT;
+        case "UP_RIGHT":
+            return BOTTOM_TOP_LEFT;
+        case "UP_LEFT":
+            return BOTTOM_TOP_RIGHT;
+        }
+        return null;
+    }
 }

+ 8 - 0
src/graph/LayeredGraphNode.java

@@ -408,6 +408,14 @@ public interface LayeredGraphNode {
    */
   public ArrayList<LayeredGraphEdge> getSortedIncomingEdges(LayeredGraphNode n);
 
+  /**
+   * Ermittelt die Kante zwischen zwei Knoten
+   * @param source Der Source Knoten der Kante
+   * @param target Der Target Knoten der Kante
+   * @return noll, falls die Kante nicht existiert. Sonst die Kante von source nach target
+   */
+  public LayeredGraphEdge findEdgeBetween( LayeredGraphNode source, LayeredGraphNode target );
+  
   /**
    * F�gt einen neuen Knoten zum Subgraph hinzu
    * 

+ 11 - 0
src/graph/LayeredNode.java

@@ -891,6 +891,17 @@ public class LayeredNode implements LayeredGraphNode {
         }
         return result;
     }
+    
+    @Override
+    public LayeredGraphEdge findEdgeBetween( LayeredGraphNode source, LayeredGraphNode target )
+    {
+        for( LayeredGraphEdge e : edges )
+        {
+            if( e.getSources().contains( source ) && e.getTargets().contains( target ) )
+                return e;
+        }
+        return null;
+    }
 
     @Override
     public LayeredGraphNode createNode(ElkNode original) {