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 allFlexModels; private List allFlexesOrderedThisTimeStep = new ArrayList(); private HashMap accessFlexMap = new HashMap(); public FlexManager(Model model, int timeStep, FlexManager timestepBefore){ this.timeStep = timeStep; allFlexModels = getAllFlexFromModel(model); //fill accessFlexMap 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 getAllFlexWrapper() { return accessFlexMap.values().stream().collect(Collectors.toList()); } public List getAllFlexWrapperWithState(FlexState state) { return accessFlexMap.values().stream().filter(flexWrapper -> (flexWrapper.getState() == state)).collect(Collectors.toList()); } private List getAllFlexFromModel(Model model) { return createListOfHolonObjects(model.getObjectsOnCanvas()).stream().flatMap(hObject -> hObject.getElements().stream()).flatMap(hElement -> hElement.flexList.stream()).collect(Collectors.toList()); } private List createListOfHolonObjects(List objectsOnCanvas) { List list = new ArrayList(); 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 getAllFlexesOrderedThisTimeStep() { return allFlexesOrderedThisTimeStep; } public void orderFlexFromList(List 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 } //Classes 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) && //Right state !accessFlexMap.values().stream().anyMatch(flexWrapper -> (flexWrapper.getFlex().getElement() == flex.getElement() && flexWrapper != this && (flexWrapper.getState() == FlexState.IN_USE || flexWrapper.getState() == FlexState.ON_COOLDOWN))); //No other flex of this ele in use } 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); } } }