| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- package bk;
- import java.awt.Color;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.List;
- import javax.swing.JTree;
- import animation.CodeLine;
- import animation.ControlFlow;
- import animation.Memory;
- import animation.Memory.MemoryType;
- import animation.Memory.ReadOnlyMemory;
- import animation.PseudoCodeNode;
- import codelines.DeclareVariable;
- import codelines.ForEachLoop;
- import codelines.FunctionDefinition;
- import codelines.SetVariable;
- import graph.LayeredGraphNode;
- /**
- * The stage of the combination of the four extremal layouts.
- * @author kolja
- *
- */
- public class Combine {
- public static PseudoCodeNode combine( JTree tree ) {
- String[] vars = { "graph", "l", "l_min", "v", "positions" };
- @SuppressWarnings("serial")
- PseudoCodeNode root = new PseudoCodeNode( "function combine( graph )", vars, tree, new FunctionDefinition( new String[]{ "graph" } ) ){
- @Override
- public String getDebugOutput( Memory m )
- {
- if( m.isSomewhereDefined( "v", MemoryType.LOCAL ) )
- m.<LayeredGraphNode>read( "v", MemoryType.LOCAL).setSelected( null );
- return super.getDebugOutput( m );
- }
- };
- root.add( new PseudoCodeNode( "-- Align all Layouts to the one with the smallest width --", vars, tree, new CodeLine() {
- @Override
- public ControlFlow runForward(Memory m) {
- LayeredGraphNode graph = m.read( "graph", MemoryType.LOCAL );
- if( graph.parent() == null )
- graph.setColor( Color.BLACK, null );
- actions.add( (Memory mem) -> {
- if( graph.parent() == null )
- graph.setColor( null, null );
- });
- return new ControlFlow( ControlFlow.STEP_OVER );
- }
- }));
- PseudoCodeNode firstLoop = new PseudoCodeNode( "foreach l in ['DOWN_RIGHT', 'DOWN_LEFT', 'UP_RIGHT', 'UP_LEFT'] do", vars, tree, new ForEachLoop<String>( "l" ) {
- @Override
- protected List<String> list(ReadOnlyMemory m) {
- ArrayList< String > list = new ArrayList<String>();
- list.add( "DOWN_RIGHT" );
- list.add( "DOWN_LEFT" );
- list.add( "UP_RIGHT" );
- list.add( "UP_LEFT" );
- return list;
- }
- });
- root.add( firstLoop );
- firstLoop.add( new PseudoCodeNode( "min[l] = minimum x coordinate in l;", vars, tree, new CodeLine() {
- @Override
- public ControlFlow runForward(Memory m) {
- String layout = m.read( "l", MemoryType.LOCAL );
- m.declare( "min[" + layout + "]", calcMinX( m.read( "graph", MemoryType.LOCAL ), LayoutType.fromString( layout ) ), MemoryType.GLOBAL );
- actions.add( (Memory mem) -> {
- mem.undeclare( "min[" + layout + "]", MemoryType.GLOBAL );
- });
- return new ControlFlow( ControlFlow.STEP_OVER );
- }
- }));
- firstLoop.add( new PseudoCodeNode( "max[l] = maximum x coordinate in l;", vars, tree, new CodeLine() {
- @Override
- public ControlFlow runForward(Memory m) {
- String layout = m.read( "l", MemoryType.LOCAL );
- m.declare( "max[" + layout + "]", calcMaxX( m.read( "graph", MemoryType.LOCAL ), LayoutType.fromString( layout ) ), MemoryType.GLOBAL );
- actions.add( (Memory mem) -> {
- mem.undeclare( "max[" + layout + "]", MemoryType.GLOBAL );
- });
- return new ControlFlow( ControlFlow.STEP_OVER );
- }
- }));
- firstLoop.add( new PseudoCodeNode( "width[l] = max[l] - min[l];", vars, tree, new CodeLine() {
- @Override
- public ControlFlow runForward(Memory m) {
- String layout = m.read( "l", MemoryType.LOCAL );
- m.declare( "width[" + layout + "]", m.<Integer>read( "max[" + layout + "]", MemoryType.GLOBAL ) - m.<Integer>read( "min[" + layout + "]", MemoryType.GLOBAL ), MemoryType.GLOBAL );
- actions.add( (Memory mem) -> {
- mem.undeclare( "width[" + layout + "]", MemoryType.GLOBAL );
- });
- return new ControlFlow( ControlFlow.STEP_OVER );
- }
- }));
- root.add( new PseudoCodeNode( "l_min = l with width[l] == min(width);", vars, tree, new DeclareVariable<String>( "l_min" ) {
- @Override
- protected String value(ReadOnlyMemory m) {
- String min = "DOWN_RIGHT";
- int minW = m.read( "width[DOWN_RIGHT]", MemoryType.GLOBAL );
- for( String l : new String[]{ "DOWN_LEFT", "UP_RIGHT", "UP_LEFT" } )
- {
- if( minW > m.<Integer>read( "width[" + l + "]", MemoryType.GLOBAL ) )
- {
- minW = m.<Integer>read( "width[" + l + "]", MemoryType.GLOBAL );
- min = l;
- }
- }
- return min;
- }
- }));
- PseudoCodeNode secondLoop = new PseudoCodeNode( "foreach l in ['DOWN_RIGHT', 'DOWN_LEFT', 'UP_RIGHT', 'UP_LEFT'] do", vars, tree, new ForEachLoop<String>( "l" ) {
- @Override
- protected List<String> list(ReadOnlyMemory m) {
- ArrayList< String > list = new ArrayList<String>();
- list.add( "DOWN_RIGHT" );
- list.add( "DOWN_LEFT" );
- list.add( "UP_RIGHT" );
- list.add( "UP_LEFT" );
- return list;
- }
- });
- root.add( secondLoop );
- secondLoop.add( new PseudoCodeNode( "shift[l] = l.contains('RIGHT') ? min[l_min] - min[l] : max[l_min] - max[l];", vars, tree, new CodeLine() {
- @Override
- public ControlFlow runForward(Memory m) {
- String layout = m.read( "l", MemoryType.LOCAL );
- String lMin = m.read( "l_min", MemoryType.LOCAL );
- if( layout.contains( "RIGHT" ) )
- m.declare( "shift[" + layout + "]", m.<Integer>read( "min[" + lMin + "]", MemoryType.GLOBAL ) - m.<Integer>read( "min[" + layout + "]", MemoryType.GLOBAL ), MemoryType.GLOBAL );
- else
- m.declare( "shift[" + layout + "]", m.<Integer>read( "max[" + lMin + "]", MemoryType.GLOBAL ) - m.<Integer>read( "max[" + layout + "]", MemoryType.GLOBAL ), MemoryType.GLOBAL );
- actions.add( (Memory mem) -> {
- mem.undeclare( "shift[" + layout + "]", MemoryType.GLOBAL );
- });
- return new ControlFlow( ControlFlow.STEP_OVER );
- }
- }));
- PseudoCodeNode thirdLoop = new PseudoCodeNode( "foreach v in graph do", vars, tree, new ForEachLoop<LayeredGraphNode>( "v" ) {
- @Override
- protected List<LayeredGraphNode> list(ReadOnlyMemory m) {
- return m.<LayeredGraphNode>read( "graph", MemoryType.LOCAL ).getContainedNodes();
- }
- });
- root.add( thirdLoop );
- thirdLoop.add( new PseudoCodeNode( "positions = [];", vars, tree, new DeclareVariable<ArrayList<Integer>>( "positions") {
- @Override
- protected ArrayList<Integer> value(ReadOnlyMemory m) {
- return new ArrayList<Integer>();
- }
- }));
- PseudoCodeNode innerLoop = new PseudoCodeNode( "foreach l in ['DOWN_RIGHT', 'DOWN_LEFT', 'UP_RIGHT', 'UP_LEFT'] do", vars, tree, new ForEachLoop<String>( "l" ) {
- @Override
- protected List<String> list(ReadOnlyMemory m) {
- ArrayList< String > list = new ArrayList<String>();
- list.add( "DOWN_RIGHT" );
- list.add( "DOWN_LEFT" );
- list.add( "UP_RIGHT" );
- list.add( "UP_LEFT" );
- return list;
- }
- });
- innerLoop.add( new PseudoCodeNode( "positions.add(x[v] in l);", vars, tree, new CodeLine() {
- @Override
- public ControlFlow runForward(Memory m) {
- String layout = m.read( "l", MemoryType.LOCAL );
- ArrayList<Integer> positions = m.read( "positions", MemoryType.LOCAL );
- positions.add( (int)m.<LayeredGraphNode>read( "v", MemoryType.LOCAL ).getX( LayoutType.fromString( layout ) ) + m.<Integer>read( "shift[" + layout + "]", MemoryType.GLOBAL ) );
- actions.add( (Memory mem) -> {
- positions.remove( positions.size() - 1 );
- });
- return new ControlFlow( ControlFlow.STEP_OVER );
- }
- }));
- thirdLoop.add( innerLoop );
- thirdLoop.add( new PseudoCodeNode( "positions = sort( positions );", vars, tree, new SetVariable<ArrayList<Integer>>( "positions" ) {
- @Override
- public ArrayList<Integer> value(ReadOnlyMemory m) {
- ArrayList<Integer> positions = m.read( "positions", MemoryType.LOCAL );
- ArrayList<Integer> neu = new ArrayList<Integer>();
- for( int p : positions )
- neu.add( p );
- Collections.sort( neu );
- return neu;
- }
- }));
- thirdLoop.add( new PseudoCodeNode( "x[v] = (positions[1]+positions[2]) / 2;", vars, tree, new CodeLine() {
- @Override
- public ControlFlow runForward(Memory m) {
- ArrayList<Integer> positions = m.read( "positions", MemoryType.LOCAL );
- LayeredGraphNode v = m.read( "v", MemoryType.LOCAL );
- double old = v.getX( LayoutType.COMBINED );
- v.setX( (positions.get( 1 ) + positions.get( 2 )) / 2.0, true, LayoutType.COMBINED );
- actions.add( (Memory mem) -> {
- v.setX( old, false, LayoutType.COMBINED );
- });
- return new ControlFlow( ControlFlow.STEP_OVER );
- }
- }));
- return root;
- }
- private static int calcMinX( LayeredGraphNode graph, LayoutType layout )
- {
- int minX = 0;
- if( graph.getContainedNodes().size() > 0 )
- minX = (int)graph.getContainedNodes().get( 0 ).getX( layout );
- for( LayeredGraphNode n : graph.getContainedNodes() )
- minX = Math.min( minX, (int)n.getX( layout ) );
- return minX;
- }
- private static int calcMaxX( LayeredGraphNode graph, LayoutType layout )
- {
- int maxX = 0;
- if( graph.getContainedNodes().size() > 0 )
- maxX = (int)graph.getContainedNodes().get( 0 ).getX( layout );
- for( LayeredGraphNode n : graph.getContainedNodes() )
- maxX = Math.max( maxX, (int)n.getX( layout ) );
- return maxX;
- }
- }
|