package ui.controller; import java.util.ArrayList; import classes.CpsEdge; import classes.CpsNode; import classes.CpsObject; import classes.HolonElement; import classes.HolonObject; import classes.HolonSwitch; import classes.subNet; import ui.model.Model; import ui.view.MyCanvas; public class SimulationManager { private Model model; private ArrayList objectsToHandle; private ArrayList subNets; private MyCanvas canvas; private int timeStep; public SimulationManager(Model m){ canvas = null; model = m; subNets = new ArrayList(); } /** * calculates the flow of the edges and the supply for objects * @param x */ public void calculateStateForTimeStep(int x){ timeStep = x; searchForSubNets(); for(subNet singleSubNet: subNets){ float production = calculateEnergy("prod", singleSubNet, x); float consumption = calculateEnergy("cons", singleSubNet, x); float minConsumption = calculateMinimumEnergy( singleSubNet, x); for(CpsEdge e: singleSubNet.getEdges()){ e.setFlow(0); } setFlow(singleSubNet); for(HolonObject hl: singleSubNet.getObjects()){ if(!(hl.getState() == 0) && !(hl.getState() == 3)){ for(int i = 0; i < hl.getConnections().size(); i++){ CpsEdge edge = hl.getConnectedTo().get(i); if(edge.getState() && edge.getFlow() > 0){ // 0 = no energy, 1 = not supplied, 2 = supplied if((production + consumption) >= 0){ hl.setState(2); } if((production + consumption) < 0){ if((production + minConsumption) >= 0){ hl.setState(4); }else{ hl.setState(1); } } break; } hl.setState(1); } } } } //printNet(); canvas.repaint(); } public void setFlow(subNet sN){ for(HolonObject hl: sN.getObjects()){ if(hl.getCurrentEnergyAtTimeStep(timeStep) > 0){ fillConnectionsFor(hl, new ArrayList(), new ArrayList(), hl.getCurrentEnergyAtTimeStep(timeStep)); } } } public void fillConnectionsFor(CpsObject cps, ArrayList visitedObj, ArrayList visitedEdges ,float energy ){ visitedObj.add(cps.getID()); for(CpsEdge e: cps.getConnections()){ if(!(visitedEdges.contains(e))){ e.setFlow(e.getFlow() + energy); if(e.getState()){ visitedEdges.add(e); if(!(visitedObj.contains(e.getA().getID()))){ fillConnectionsFor(e.getA(), visitedObj, visitedEdges, energy); } if(!(visitedObj.contains(e.getB().getID()))){ fillConnectionsFor(e.getB(), visitedObj, visitedEdges, energy); } } } } } /** * calculates the energy of either all producers or consumers * @param type * @param sN * @return */ public float calculateEnergy(String type, subNet sN, int x){ float energy = 0; for(HolonObject hl: sN.getObjects()){ if(type.equals("prod")){ if(hl.getCurrentEnergyAtTimeStep(x) > 0){ energy = energy + hl.getCurrentEnergyAtTimeStep(x); hl.setState(3); } } if(type.equals("cons")){ if(hl.getCurrentEnergyAtTimeStep(x) < 0){ energy = energy + hl.getCurrentEnergyAtTimeStep(x); hl.setState(1); } } if(hl.getCurrentEnergyAtTimeStep(x) == 0){ hl.setState(0); } } return energy; } public float calculateMinimumEnergy(subNet sN, int x){ float min = 0; float minElement = 0; for(HolonObject hl: sN.getObjects()){ if(hl.getElements().size() > 0 && hl.getElements().get(0).getTotalEnergyAtTimeStep(x) < 0 ){ minElement = hl.getElements().get(0).getTotalEnergyAtTimeStep(x); } for(HolonElement he: hl.getElements()){ if(minElement < he.getTotalEnergyAtTimeStep(x) && he.getTotalEnergyAtTimeStep(x) < 0){ minElement = he.getTotalEnergyAtTimeStep(x); } } min = min + minElement; } return min; } /** * generates all subNets from all objectsToHandle */ public void searchForSubNets(){ subNets = new ArrayList(); boolean end = false; int i = 0; CpsObject cps; if(objectsToHandle.size() > 0){ while(!end){ cps = objectsToHandle.get(i); subNet singleSubNet = new subNet(new ArrayList(), new ArrayList(), new ArrayList()); singleSubNet = buildSubNet(cps, new ArrayList(), singleSubNet); if(singleSubNet.getObjects().size() != 0){ subNets.add(singleSubNet); } if(0 == objectsToHandle.size()){ end = true; } } } } /** * recursivly generates a subnet of all objects, that one specific object is connected to * @param cps * @param visited * @param sN * @return */ public subNet buildSubNet(CpsObject cps, ArrayList visited, subNet sN){ visited.add(cps.getID()); if(cps instanceof HolonObject){ sN.getObjects().add((HolonObject) cps); } if(cps instanceof HolonSwitch){ sN.getSwitches().add((HolonSwitch) cps); } removeFromToHandle(cps.getID()); CpsObject A; CpsObject B; for(CpsEdge edge: cps.getConnections()){ A = edge.getA(); B = edge.getB(); if(!(cps instanceof HolonSwitch)){ if(!(sN.getEdges().contains(edge))){ sN.getEdges().add(edge); } } if(!visited.contains(A.getID()) && legitState(A, cps)){ sN = buildSubNet(A, visited, sN); } if(!visited.contains(B.getID()) && legitState(B, cps)){ sN = buildSubNet(B, visited, sN); } } return sN; } public boolean legitState(CpsObject neighbor, CpsObject current){ if(current instanceof HolonSwitch){ if(((HolonSwitch) current).getActiveAt()[timeStep]){ if(neighbor instanceof HolonSwitch){ if(((HolonSwitch) neighbor).getActiveAt()[timeStep]){ return true; }else{ return false; } } }else{ return false; } } return true; } /** * removes an Object that already has been handled with * @param id */ public void removeFromToHandle(int id){ for(int i = 0; i < objectsToHandle.size(); i++){ if(objectsToHandle.get(i).getID() == id){ objectsToHandle.remove(i); } } } /** * ensures that objectsToHandle only contains HolonObjects */ public void cleanObjectsToHandle(){ for(int i = 0; i < objectsToHandle.size(); i++){ if(!(objectsToHandle.get(i) instanceof HolonObject)){ objectsToHandle.remove(i); } } } /** * copies the data of an array of Objects * @param toCopy */ public void copyObjects(ArrayList toCopy){ objectsToHandle = new ArrayList(); for(CpsObject cps: toCopy){ objectsToHandle.add(cps); } } /** * Prints the Components auf all subnets */ public void printNet(){ for(int i = 0; i < subNets.size(); i++){ System.out.println("SUBNET NR:" + i); System.out.println(" Objects:"); for(int j = 0; j < subNets.get(i).getObjects().size(); j++){ HolonObject hl = subNets.get(i).getObjects().get(j); System.out.println(" " + hl.getName() + " " + hl.getID()); } System.out.println(" Edges:"); for(int j = 0; j < subNets.get(i).getEdges().size(); j++){ CpsEdge edge = subNets.get(i).getEdges().get(j); System.out.println(" " + edge.getA().getName() + " connected To " + edge.getB().getName()); } System.out.println(" Switches:"); for(int j = 0; j < subNets.get(i).getSwitches().size(); j++){ HolonSwitch sw = subNets.get(i).getSwitches().get(j); System.out.println(" " + sw.getName() + " " + sw.getID() + " State:" + sw.getActiveAt()[timeStep]); } } } public void setCanvas(MyCanvas can){ canvas = can; } public void reset(){ copyObjects(model.getObjectsOnCanvas()); } }