FlexManager.java 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. package ui.controller;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import java.util.stream.Collectors;
  6. import classes.AbstractCanvasObject;
  7. import classes.GroupNode;
  8. import classes.Flexibility;
  9. import classes.HolonElement;
  10. import classes.HolonObject;
  11. import ui.model.Model;
  12. /**
  13. * Class to Manage to flexibilities.
  14. * To order, view Flexibilities.
  15. * @author tom
  16. *
  17. */
  18. public class FlexManager {
  19. private int timeStep;
  20. private List<Flexibility> allFlexModels;
  21. private List<Flexibility> allFlexesOrderedThisTimeStep = new ArrayList<Flexibility>();
  22. private HashMap<HolonElement, List<FlexWrapper>> accessOtherFlex = new HashMap<HolonElement, List<FlexWrapper>>();
  23. private HashMap<Flexibility, FlexWrapper> accessFlexMap = new HashMap<Flexibility, FlexWrapper>();
  24. public FlexManager(Model model, int timeStep, FlexManager timestepBefore){
  25. //Thread.dumpStack();
  26. this.timeStep = timeStep;
  27. allFlexModels = getAllFlexFromModel(model);
  28. //fill accessFlexMap
  29. allFlexModels.stream().map(flex -> new FlexWrapper(flex, timeStep, (timestepBefore != null)?timestepBefore.getFlexWrapper(flex):null)).forEach(flexWrapper -> {
  30. accessFlexMap.put(flexWrapper.getFlex(), flexWrapper);
  31. HolonElement ele = flexWrapper.getFlex().getElement();
  32. if(accessOtherFlex.containsKey(ele)) {
  33. accessOtherFlex.get(ele).add(flexWrapper);
  34. }else {
  35. ArrayList<FlexWrapper> toAdd = new ArrayList<FlexWrapper>();
  36. toAdd.add(flexWrapper);
  37. accessOtherFlex.put(ele, new ArrayList<FlexWrapper>(toAdd));
  38. }
  39. });
  40. //because when added not all flexes can see others
  41. accessFlexMap.values().stream().forEach(flexWrapper -> flexWrapper.revalidateState());
  42. }
  43. public FlexManager(List<HolonObject> objects, int timeStep, FlexManager timestepBefore){
  44. //Thread.dumpStack();
  45. this.timeStep = timeStep;
  46. allFlexModels = objects.stream()
  47. .flatMap(hObject -> hObject.getElements().stream())
  48. .flatMap(hElement -> hElement.flexList.stream())
  49. .collect(Collectors.toList());
  50. //fill accessFlexMap
  51. allFlexModels.stream().map(flex -> new FlexWrapper(flex, timeStep, (timestepBefore != null)?timestepBefore.getFlexWrapper(flex):null)).forEach(flexWrapper -> {
  52. accessFlexMap.put(flexWrapper.getFlex(), flexWrapper);
  53. HolonElement ele = flexWrapper.getFlex().getElement();
  54. if(accessOtherFlex.containsKey(ele)) {
  55. accessOtherFlex.get(ele).add(flexWrapper);
  56. }else {
  57. ArrayList<FlexWrapper> toAdd = new ArrayList<FlexWrapper>();
  58. toAdd.add(flexWrapper);
  59. accessOtherFlex.put(ele, new ArrayList<FlexWrapper>(toAdd));
  60. }
  61. });
  62. //because when added not all flexes can see others
  63. accessFlexMap.values().stream().forEach(flexWrapper -> flexWrapper.revalidateState());
  64. }
  65. private FlexWrapper getFlexWrapper(Flexibility flex) {
  66. return accessFlexMap.getOrDefault(flex, null);
  67. }
  68. public List<FlexWrapper> getAllFlexWrapper() {
  69. return accessFlexMap.values().stream().collect(Collectors.toList());
  70. }
  71. public List<FlexWrapper> getAllFlexWrapperWithState(FlexState state) {
  72. return accessFlexMap.values().stream().filter(flexWrapper -> (flexWrapper.getState() == state)).collect(Collectors.toList());
  73. }
  74. private List<Flexibility> getAllFlexFromModel(Model model) {
  75. return createListOfHolonObjects(model.getObjectsOnCanvas()).stream().flatMap(hObject -> hObject.getElements().stream()).flatMap(hElement -> hElement.flexList.stream()).collect(Collectors.toList());
  76. }
  77. private List<HolonObject> createListOfHolonObjects(List<AbstractCanvasObject> objectsOnCanvas) {
  78. List<HolonObject> list = new ArrayList<HolonObject>();
  79. for(AbstractCanvasObject aCps : objectsOnCanvas) {
  80. if(aCps instanceof HolonObject) list.add((HolonObject) aCps);
  81. else if(aCps instanceof GroupNode)list.addAll(createListOfHolonObjects(((GroupNode)aCps).getNodes()));
  82. }
  83. return list;
  84. }
  85. public int getTimeStep() {
  86. return timeStep;
  87. }
  88. public List<Flexibility> getAllFlexesOrderedThisTimeStep() {
  89. return allFlexesOrderedThisTimeStep;
  90. }
  91. public void orderFlexFromList(List<Flexibility> flexList) {
  92. flexList.stream().forEach(flex -> {
  93. FlexWrapper flexToOrder = accessFlexMap.get(flex);
  94. if(flexToOrder!=null)flexToOrder.order();
  95. });
  96. }
  97. public void orderFlex(Flexibility flex) {
  98. FlexWrapper flexToOrder = accessFlexMap.get(flex);
  99. if(flexToOrder!=null)flexToOrder.order();
  100. }
  101. public boolean isAFlexInUseOfHolonElement(HolonElement ele) {
  102. return ele.flexList.stream().filter(flex -> this.accessFlexMap.containsKey(flex)).anyMatch(flex -> (this.accessFlexMap.get(flex).getState() == FlexState.IN_USE));
  103. }
  104. /**
  105. * Or Return null
  106. * @param flex
  107. * @return
  108. */
  109. public FlexWrapper getFlexWrapperFromFlexibility(Flexibility flex) {
  110. return accessFlexMap.get(flex);
  111. }
  112. public static enum FlexState{
  113. IN_USE, ON_COOLDOWN, OFFERED, NOT_OFFERED, UNAVAILABLE
  114. }
  115. //Classes
  116. public class FlexWrapper{
  117. private Flexibility flex;
  118. private FlexState state;
  119. int timeStep;
  120. int durationEndTime = -1;
  121. int coolDownEndTime = -1;
  122. public FlexWrapper(Flexibility flex, int timeStep, FlexWrapper old) {
  123. this.flex = flex;
  124. this.timeStep = timeStep;
  125. if(old == null) {
  126. state = flex.fulfillsConstrains()?(flex.offered?FlexState.OFFERED:FlexState.NOT_OFFERED):FlexState.UNAVAILABLE;
  127. }else {
  128. durationEndTime = old.durationEndTime;
  129. coolDownEndTime = old.coolDownEndTime;
  130. revalidateState();
  131. }
  132. }
  133. public void revalidateState() {
  134. if(remainingTimeTillActivation() == 0) state = (flex.fulfillsConstrains() && !otherFlexInUseOrOnCooldown())?(flex.offered?FlexState.OFFERED:FlexState.NOT_OFFERED):FlexState.UNAVAILABLE;
  135. else if(remainingDuration()== 0) state = FlexState.ON_COOLDOWN;
  136. else state = FlexState.IN_USE;
  137. }
  138. public Flexibility getFlex() {
  139. return flex;
  140. }
  141. public FlexState getState() {
  142. return state;
  143. }
  144. public boolean canOrder() {
  145. return (state == FlexState.OFFERED) && //Right state
  146. !otherFlexInUseOrOnCooldown(); //No other flex of this ele in use
  147. }
  148. private boolean otherFlexInUseOrOnCooldown() {
  149. if(accessOtherFlex.get(this.getFlex().getElement()) == null) return false;
  150. return accessOtherFlex.get(this.getFlex().getElement()).stream().anyMatch(flexWrapper -> flexWrapper != this && (flexWrapper.getState() == FlexState.IN_USE || flexWrapper.getState() == FlexState.ON_COOLDOWN));
  151. }
  152. public boolean order() {
  153. if(canOrder()) {
  154. state=FlexState.IN_USE;
  155. allFlexesOrderedThisTimeStep.add(flex);
  156. durationEndTime = timeStep + flex.getDuration();
  157. coolDownEndTime = durationEndTime + flex.getCooldown();
  158. //accessFlexMap.values().stream().filter(flexWrapper -> (flexWrapper.getFlex().getElement() == flex.getElement() && flexWrapper != this)).forEach(otherFlex -> otherFlex.revalidateState());
  159. accessOtherFlex.get(this.getFlex().getElement()).stream().filter(flexWrapper -> (flexWrapper != this)).forEach(otherFlex -> otherFlex.revalidateState());
  160. return true;
  161. }
  162. return false;
  163. }
  164. public boolean cancel() {
  165. if(allFlexesOrderedThisTimeStep.contains(flex)) {
  166. state=FlexState.OFFERED;
  167. durationEndTime = -1;
  168. coolDownEndTime = -1;
  169. allFlexesOrderedThisTimeStep.remove(flex);
  170. accessOtherFlex.get(this.getFlex().getElement()).stream().filter(flexWrapper -> (flexWrapper != this)).forEach(otherFlex -> otherFlex.revalidateState());
  171. return true;
  172. }
  173. return false;
  174. }
  175. public int remainingTimeTillActivation() {
  176. return Math.max(0, coolDownEndTime - timeStep);
  177. }
  178. public int remainingDuration() {
  179. return Math.max(0, durationEndTime - timeStep);
  180. }
  181. }
  182. public void reset() {
  183. getAllFlexWrapper().forEach(flexWrapper -> flexWrapper.cancel());
  184. }
  185. }