Compaction.java 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. package Algorithms.Animated.BK;
  2. import java.util.ArrayList;
  3. import Algorithms.Animated.AlgorithmStage;
  4. import Algorithms.Animated.BackwardAction;
  5. import Model.LayeredGraphNode;
  6. /**
  7. * The stage of compacting the layout.
  8. * @author kolja
  9. *
  10. */
  11. public class Compaction implements AlgorithmStage{
  12. private enum CompactionState
  13. {
  14. PLACE_BLOCKS,
  15. APPLY_SHIFT
  16. }
  17. private class StackFrame
  18. {
  19. public LayeredGraphNode v;
  20. public LayeredGraphNode u;
  21. public LayeredGraphNode w;
  22. }
  23. private CompactionState state;
  24. private LayeredGraphNode graph;
  25. private int vIndex;
  26. private ArrayList< StackFrame > stack;
  27. private ArrayList< BackwardAction > actions;
  28. public Compaction( LayeredGraphNode graph )
  29. {
  30. this.graph = graph;
  31. state = CompactionState.PLACE_BLOCKS;
  32. stack = new ArrayList<>();
  33. vIndex = 0;
  34. actions = new ArrayList<>();
  35. }
  36. public double calcSpacing()
  37. {
  38. double max = 0;
  39. for( LayeredGraphNode n : graph.getContainedNodes() )
  40. max = Math.max( max, n.getWidth() );
  41. return max + 50;
  42. }
  43. @Override
  44. public StageStatus forwardStep() {
  45. int acSize = actions.size();
  46. if( state == CompactionState.PLACE_BLOCKS )
  47. {
  48. if( stack.size() == 0 )
  49. {
  50. ArrayList< LayeredGraphNode > nodes = graph.getContainedNodes();
  51. boolean found = false;
  52. int oldVIndex = vIndex;
  53. for( ; vIndex < nodes.size(); vIndex++ )
  54. {
  55. if( nodes.get( vIndex ).isXUndefined() && nodes.get( vIndex ) == nodes.get( vIndex ).getRoot() )
  56. {
  57. found = true;
  58. break;
  59. }
  60. }
  61. if( !found )
  62. {
  63. state = CompactionState.APPLY_SHIFT;
  64. vIndex = 0;
  65. actions.add( 0, ()-> {
  66. vIndex = oldVIndex;
  67. state = CompactionState.PLACE_BLOCKS;
  68. } );
  69. }
  70. else
  71. {
  72. StackFrame f = new StackFrame();
  73. f.v = nodes.get( vIndex );
  74. double oldX = f.v.getX();
  75. f.v.setX( 0, true );
  76. f.v.setSelected();
  77. f.w = f.v;
  78. stack.add( 0, f );
  79. actions.add( 0, ()-> {
  80. stack.get( 0 ).v.setX( oldX, false );
  81. stack.get( 0 ).v.setSelected();
  82. stack.remove( 0 );
  83. vIndex = oldVIndex;
  84. state = CompactionState.PLACE_BLOCKS;
  85. });
  86. }
  87. }
  88. else
  89. {
  90. StackFrame sf = stack.get( 0 );
  91. if( sf.u == null )
  92. {
  93. if( graph.getContainedLayers().get( sf.w.getLayer() ).indexOf( sf.w ) >= 1 )
  94. {
  95. sf.u = graph.getContainedLayers().get( sf.w.getLayer() ).get( graph.getContainedLayers().get( sf.w.getLayer() ).indexOf( sf.w ) - 1 ).getRoot();
  96. if( sf.u.isXUndefined() )
  97. {
  98. StackFrame nsf = new StackFrame();
  99. nsf.v = sf.u;
  100. double oldX = nsf.v.getX();
  101. nsf.v.setX( 0, true );
  102. nsf.v.setSelected();
  103. nsf.w = nsf.v;
  104. stack.add( 0, nsf );
  105. actions.add( 0, ()-> {
  106. stack.get( 0 ).v.setX( oldX, false );
  107. stack.get( 0 ).v.setSelected();
  108. stack.remove( 0 );
  109. stack.get( 0 ).u = null;
  110. });
  111. }
  112. else
  113. {
  114. sf.u.setSelected();
  115. actions.add( 0, ()-> {
  116. stack.get( 0 ).u = null;
  117. });
  118. }
  119. }
  120. else
  121. {
  122. LayeredGraphNode oldW = sf.w;
  123. sf.v.setSelected();
  124. sf.w = sf.w.getAlignedTo();
  125. if( sf.w == sf.v )
  126. {
  127. stack.remove( 0 );
  128. actions.add( 0, ()-> {
  129. stack.add( 0, sf );
  130. sf.v.setSelected();
  131. sf.w = oldW;
  132. });
  133. }
  134. else
  135. {
  136. actions.add( 0, ()-> {
  137. sf.w = oldW;
  138. sf.v.setSelected();
  139. });
  140. }
  141. }
  142. }
  143. else
  144. {
  145. LayeredGraphNode oldSink = sf.v.getSink();
  146. if( sf.v.getSink() == sf.v )
  147. sf.v.setSink( sf.u.getSink() );
  148. LayeredGraphNode sinkOfU = sf.u.getSink();
  149. double oldShift = sinkOfU.getShift();
  150. double oldX = sf.v.getX();
  151. boolean oldDef = !sf.v.isXUndefined();
  152. sf.v.setSelected();
  153. if( sf.v.getSink() != sf.u.getSink() )
  154. sf.u.getSink().setShift( Math.min( sf.u.getSink().getShift(), sf.v.getX() - sf.u.getX() - calcSpacing() ) );
  155. else
  156. sf.v.setX( Math.max( sf.v.getX(), sf.u.getX() + calcSpacing() ), true );
  157. LayeredGraphNode oldW = sf.w;
  158. sf.w = sf.w.getAlignedTo();
  159. LayeredGraphNode oldU = sf.u;
  160. sf.u = null;
  161. if( sf.w == sf.v )
  162. {
  163. stack.remove( 0 );
  164. actions.add( 0, ()-> {
  165. stack.add( 0, sf );
  166. stack.get( 0 ).v.setSink( oldSink );
  167. sinkOfU.setShift( oldShift );
  168. sf.u = oldU;
  169. sf.v.setX( oldX, oldDef );
  170. sf.v.setSelected();
  171. sf.w = oldW;
  172. });
  173. }
  174. else
  175. {
  176. actions.add( 0, ()-> {
  177. stack.get( 0 ).v.setSink( oldSink );
  178. sinkOfU.setShift( oldShift );
  179. sf.u = oldU;
  180. sf.v.setX( oldX, oldDef );
  181. sf.v.setSelected();
  182. sf.w = oldW;
  183. });
  184. }
  185. }
  186. }
  187. }
  188. else if( state == CompactionState.APPLY_SHIFT )
  189. {
  190. LayeredGraphNode v = graph.getContainedNodes().get( vIndex );
  191. double oldX = v.getX();
  192. boolean oldDef = !v.isXUndefined();
  193. v.setSelected();
  194. v.setX( v.getRoot().getX(), true );
  195. if( v == v.getRoot() && v.getSink().getShift() < Double.POSITIVE_INFINITY )
  196. v.setX( v.getX() + v.getSink().getShift(), true );
  197. actions.add( 0, ()-> {
  198. v.setX( oldX, oldDef );
  199. v.setSelected();
  200. vIndex--;
  201. } );
  202. vIndex++;
  203. if( vIndex >= graph.getContainedNodes().size() )
  204. return StageStatus.FINISHED;
  205. }
  206. if( actions.size() != acSize + 1 )
  207. System.out.println( "ERROR" );
  208. return StageStatus.UNFINISHED;
  209. }
  210. @Override
  211. public StageStatus backwardStep() {
  212. if( actions.size() == 0 )
  213. return StageStatus.FINISHED;
  214. actions.get( 0 ).reverse();
  215. actions.remove( 0 );
  216. return StageStatus.UNFINISHED;
  217. }
  218. }