|
@@ -0,0 +1,139 @@
|
|
|
+package ui.controller;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+import classes.AbstractCpsObject;
|
|
|
+import classes.CpsUpperNode;
|
|
|
+import classes.Flexibility;
|
|
|
+import classes.HolonElement;
|
|
|
+import classes.HolonObject;
|
|
|
+import ui.model.Model;
|
|
|
+
|
|
|
+
|
|
|
+ * Class to Manage to flexibilities.
|
|
|
+ * To order, view Flexibilities.
|
|
|
+ * @author tom
|
|
|
+ *
|
|
|
+ */
|
|
|
+public class FlexManager {
|
|
|
+ private int timeStep;
|
|
|
+ private List<Flexibility> allFlexModels;
|
|
|
+ private List<Flexibility> allFlexesOrderedThisTimeStep = new ArrayList<Flexibility>();
|
|
|
+ private HashMap<Flexibility, FlexWrapper> accessFlexMap = new HashMap<Flexibility, FlexWrapper>();
|
|
|
+ public FlexManager(Model model, int timeStep, FlexManager timestepBefore){
|
|
|
+ this.timeStep = timeStep;
|
|
|
+ allFlexModels = getAllFlexFromModel(model);
|
|
|
+
|
|
|
+ allFlexModels.stream().map(flex -> new FlexWrapper(flex, timeStep, (timestepBefore != null)?timestepBefore.getFlexWrapper(flex):null)).forEach(flexWrapper -> accessFlexMap.put(flexWrapper.getFlex(), flexWrapper));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private FlexWrapper getFlexWrapper(Flexibility flex) {
|
|
|
+ return accessFlexMap.getOrDefault(flex, null);
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<FlexWrapper> getAllFlexWrapper() {
|
|
|
+ return accessFlexMap.values().stream().collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<FlexWrapper> getAllFlexWrapperWithState(FlexState state) {
|
|
|
+ return accessFlexMap.values().stream().filter(flexWrapper -> (flexWrapper.getState() == state)).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private List<Flexibility> getAllFlexFromModel(Model model) {
|
|
|
+ return createListOfHolonObjects(model.getObjectsOnCanvas()).stream().flatMap(hObject -> hObject.getElements().stream()).flatMap(hElement -> hElement.flexList.stream()).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<HolonObject> createListOfHolonObjects(List<AbstractCpsObject> objectsOnCanvas) {
|
|
|
+ List<HolonObject> list = new ArrayList<HolonObject>();
|
|
|
+ for(AbstractCpsObject aCps : objectsOnCanvas) {
|
|
|
+ if(aCps instanceof HolonObject) list.add((HolonObject) aCps);
|
|
|
+ else list.addAll(createListOfHolonObjects(((CpsUpperNode)aCps).getNodes()));
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public int getTimeStep() {
|
|
|
+ return timeStep;
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<Flexibility> getAllFlexesOrderedThisTimeStep() {
|
|
|
+ return allFlexesOrderedThisTimeStep;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void orderFlexFromList(List<Flexibility> flexList) {
|
|
|
+ flexList.stream().forEach(flex -> {
|
|
|
+ FlexWrapper flexToOrder = accessFlexMap.get(flex);
|
|
|
+ if(flexToOrder!=null)flexToOrder.order();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean isAFlexInUseOfHolonElement(HolonElement ele) {
|
|
|
+ return ele.flexList.stream().filter(flex -> this.accessFlexMap.containsKey(flex)).anyMatch(flex -> (this.accessFlexMap.get(flex).getState() == FlexState.IN_USE));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public static enum FlexState{
|
|
|
+ IN_USE, ON_COOLDOWN, OFFERED, NOT_OFFERED, UNAVAILABLE
|
|
|
+ }
|
|
|
+
|
|
|
+ public class FlexWrapper{
|
|
|
+ private Flexibility flex;
|
|
|
+ private FlexState state;
|
|
|
+ int timeStep;
|
|
|
+ int durationEndTime = -1;
|
|
|
+ int coolDownEndTime = -1;
|
|
|
+ public FlexWrapper(Flexibility flex, int timeStep, FlexWrapper old) {
|
|
|
+ this.flex = flex;
|
|
|
+ this.timeStep = timeStep;
|
|
|
+ if(old == null) {
|
|
|
+ state = flex.fulfillsConstrains()?(flex.offered?FlexState.OFFERED:FlexState.NOT_OFFERED):FlexState.UNAVAILABLE;
|
|
|
+ }else {
|
|
|
+ durationEndTime = old.durationEndTime;
|
|
|
+ coolDownEndTime = old.coolDownEndTime;
|
|
|
+ if(remainingTimeTillActivation() == 0) state = flex.fulfillsConstrains()?(flex.offered?FlexState.OFFERED:FlexState.NOT_OFFERED):FlexState.UNAVAILABLE;
|
|
|
+ else if(remainingDuration()== 0) state = FlexState.ON_COOLDOWN;
|
|
|
+ else state = FlexState.IN_USE;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+ public Flexibility getFlex() {
|
|
|
+ return flex;
|
|
|
+ }
|
|
|
+ public FlexState getState() {
|
|
|
+ return state;
|
|
|
+ }
|
|
|
+ public boolean canOrder() {
|
|
|
+ return (state == FlexState.OFFERED) &&
|
|
|
+ !accessFlexMap.values().stream().anyMatch(flexWrapper -> (flexWrapper.getFlex().getElement() == flex.getElement() && flexWrapper != this && (flexWrapper.getState() == FlexState.IN_USE || flexWrapper.getState() == FlexState.ON_COOLDOWN)));
|
|
|
+ }
|
|
|
+ public boolean order() {
|
|
|
+ if(canOrder()) {
|
|
|
+ state=FlexState.IN_USE;
|
|
|
+ allFlexesOrderedThisTimeStep.add(flex);
|
|
|
+ durationEndTime = timeStep + flex.getDuration();
|
|
|
+ coolDownEndTime = durationEndTime + flex.getCooldown();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ public int remainingTimeTillActivation() {
|
|
|
+ return Math.max(0, coolDownEndTime - timeStep);
|
|
|
+ }
|
|
|
+ public int remainingDuration() {
|
|
|
+ return Math.max(0, durationEndTime - timeStep);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+}
|