SimulationManager.java 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  1. package ui.controller;
  2. import classes.*;
  3. import classes.comparator.EnergyMinToMaxComparator;
  4. import classes.comparator.MinEnergyComparator;
  5. import classes.comparator.TotalEnergyComparator;
  6. import ui.model.Model;
  7. import ui.view.FlexiblePane;
  8. import ui.view.MyCanvas;
  9. import java.util.ArrayList;
  10. import java.util.HashMap;
  11. /**
  12. * Controller for Simulation.
  13. *
  14. * @author Gruppe14
  15. */
  16. public class SimulationManager {
  17. int global = 0;
  18. private Model model;
  19. private ArrayList<AbstractCpsObject> objectsToHandle;
  20. // private ArrayList<CpsEdge> allConnections;
  21. private ArrayList<SubNet> subNets;
  22. private ArrayList<CpsEdge> brokenEdges;
  23. private MyCanvas canvas;
  24. private int timeStep;
  25. private HashMap<Integer, Float> tagTable = new HashMap<>();
  26. private FlexiblePane flexPane;
  27. private HashMap<HolonElement, Float> flexDevicesTurnedOnThisTurn = new HashMap<>();
  28. /**
  29. * Constructor.
  30. *
  31. * @param m Model
  32. */
  33. SimulationManager(Model m) {
  34. canvas = null;
  35. model = m;
  36. subNets = new ArrayList<>();
  37. brokenEdges = new ArrayList<>();
  38. }
  39. /**
  40. * calculates the flow of the edges and the supply for objects.
  41. *
  42. * @param x current Iteration
  43. */
  44. void calculateStateForTimeStep(int x) {
  45. reset();
  46. timeStep = x;
  47. searchForSubNets();
  48. for (SubNet singleSubNet : subNets) {
  49. resetConnections(singleSubNet.getObjects().get(0), new ArrayList<>(), new ArrayList<>());
  50. }
  51. for (SubNet singleSubNet : subNets) {
  52. float production = calculateEnergyWithoutFlexDevices("prod", singleSubNet, timeStep);
  53. float consumption = calculateEnergyWithoutFlexDevices("cons", singleSubNet, timeStep);
  54. // surplus of energy is computed by sum, since consumption is a negative value
  55. float energySurplus = production + consumption;
  56. float minConsumption = calculateMinimumEnergy(singleSubNet, timeStep);
  57. // --------------- use flexible devices ---------------
  58. if (energySurplus != 0 && model.useFlexibleDevices()) {
  59. turnOnFlexibleDevices(singleSubNet, energySurplus, x);
  60. // if (!flexDevicesTurnedOnThisTurn.isEmpty()) {
  61. // System.out.println("The following devices were turned on in this turn: ");
  62. // System.out.println(flexDevicesTurnedOnThisTurn.toString());
  63. // }
  64. // recompute after having examined/turned on all flexible devices
  65. production = calculateEnergyWithFlexDevices("prod", singleSubNet, timeStep);
  66. consumption = calculateEnergyWithFlexDevices("cons", singleSubNet, timeStep);
  67. energySurplus = production + consumption;
  68. }
  69. // --------------- set flow simulation ---------------
  70. setFlowSimulation(singleSubNet);
  71. // --------------- visualise graph ---------------
  72. /**
  73. * production of subnets, that might be partially turned on/off
  74. */
  75. float currentProduction = production;
  76. /**
  77. * HolonObjects that can be partially Supplied but might be fully Supplied
  78. */
  79. ArrayList<HolonObject> partiallySuppliedList = new ArrayList<HolonObject>();
  80. /**
  81. * supply Buildings with minimal Energy first, if conflicts happen
  82. */
  83. singleSubNet.getObjects().sort(new MinEnergyComparator(x));
  84. for (HolonObject hl : singleSubNet.getObjects()) {
  85. if (hl.getState() != HolonObject.NO_ENERGY
  86. && hl.getState() != HolonObject.PRODUCER) {
  87. for (int i = 0; i < hl.getConnections().size(); i++) {
  88. CpsEdge edge = hl.getConnectedTo().get(i);
  89. if (edge.isWorking() && edge.getFlow() > 0
  90. || edge.getCapacity() == CpsEdge.CAPACITY_INFINITE) {
  91. if ((production + consumption) >= 0) {
  92. if (energySurplus > 0) {
  93. hl.setState(HolonObject.OVER_SUPPLIED);
  94. } else {
  95. hl.setState(HolonObject.SUPPLIED);
  96. }
  97. } else {
  98. if ((production + minConsumption) >= 0) {
  99. hl.setState(HolonObject.PARTIALLY_SUPPLIED);
  100. currentProduction += hl.getMinEnergy(x);
  101. partiallySuppliedList.add(hl);
  102. } else if (hl.checkIfPartiallySupplied(timeStep)) {
  103. hl.setState(HolonObject.PARTIALLY_SUPPLIED);
  104. currentProduction += hl.getMinEnergy(x);
  105. partiallySuppliedList.add(hl);
  106. } else {
  107. /**
  108. * Case that only some HolonObjects can be supplied
  109. */
  110. if(-hl.getCurrentEnergyAtTimeStep(x)<=currentProduction){
  111. hl.setState(HolonObject.PARTIALLY_SUPPLIED);
  112. currentProduction += hl.getMinEnergy(x);
  113. partiallySuppliedList.add(hl);
  114. }else if(-hl.getMinEnergy(x)<=currentProduction){
  115. hl.setState(HolonObject.PARTIALLY_SUPPLIED);
  116. currentProduction += hl.getMinEnergy(x);
  117. partiallySuppliedList.add(hl);
  118. }else{
  119. hl.setState(HolonObject.NOT_SUPPLIED);
  120. //currentProduction += hl.getCurrentEnergyAtTimeStep(x);
  121. }
  122. }
  123. }
  124. break;
  125. }
  126. }
  127. /**
  128. * check if some object cn self supply itself
  129. */
  130. if (hl.checkIfPartiallySupplied(timeStep)
  131. && hl.getState() != HolonObject.SUPPLIED
  132. && hl.getState() != HolonObject.OVER_SUPPLIED) {
  133. hl.setState(HolonObject.PARTIALLY_SUPPLIED);
  134. }
  135. }
  136. }
  137. /**
  138. * check if some partially supplied building might be fully supplied.
  139. */
  140. partiallySuppliedList.sort(new EnergyMinToMaxComparator(x));
  141. for(HolonObject part: partiallySuppliedList){
  142. currentProduction -= part.getMinEnergy(x);
  143. /*
  144. * if possible, supply fully
  145. */
  146. if(-part.getCurrentEnergyAtTimeStep(x)<=currentProduction){
  147. part.setState(HolonObject.SUPPLIED);
  148. currentProduction += part.getCurrentEnergyAtTimeStep(x);
  149. }else{
  150. currentProduction += part.getMinEnergy(x);
  151. }
  152. }
  153. }
  154. canvas.repaint();
  155. flexPane.recalculate();
  156. }
  157. /**
  158. * search for all flexible devices in the network and turn them on, until energy surplus = 0
  159. * or all devices have been examined.
  160. *
  161. * This code could be compressed (cases inside over- and underproduction are the same), but we decided that it
  162. * is better readable this way
  163. *
  164. * @param subNet the subnet
  165. * @param energySurplus the current surplus of energy
  166. */
  167. private void turnOnFlexibleDevices(SubNet subNet, float energySurplus, int timestep) {
  168. for (HolonObject holonOb : subNet.getObjects()) {
  169. for (HolonElement holonEl : holonOb.getElements()) {
  170. // if this element is flexible and active (can be considered for calculations)
  171. if (holonEl.isFlexible() && holonEl.isActive()) {
  172. float energyAvailableSingle = holonEl.getAvailableEnergyAt(timestep);
  173. float energyAvailableMultiple = energyAvailableSingle * holonEl.getAmount();
  174. // ------------- flexible consumer / OVERPRODUCTION -------------
  175. if (energyAvailableMultiple < 0 && energySurplus > 0) {
  176. // if there is more wasted energy than energy that this device can give, give all energy available
  177. if (Math.abs(energyAvailableMultiple) <= Math.abs(energySurplus)) {
  178. energySurplus += energyAvailableMultiple;
  179. // set the new energy consumption to the maximum
  180. holonEl.setEnergyPerElement(energyAvailableSingle);
  181. flexDevicesTurnedOnThisTurn.put(holonEl, energyAvailableMultiple);
  182. }
  183. // else: we just need to turn on part of the flexible energy available
  184. else {
  185. float energyNeeded = -energySurplus;
  186. energySurplus += energyNeeded; // should give 0, but was kept this was for consistency
  187. // the energy needed divided through the amount of elements
  188. holonEl.setEnergyPerElement(energyNeeded / holonEl.getAmount());
  189. flexDevicesTurnedOnThisTurn.put(holonEl, energyNeeded);
  190. }
  191. }
  192. // ------------- flexible producer / UNDERPRODUCTION -------------
  193. else if (energyAvailableMultiple > 0 && energySurplus < 0) {
  194. // if there is more energy needed than this device can give, give all the energy available
  195. if (Math.abs(energyAvailableMultiple) <= Math.abs(energySurplus)) {
  196. energySurplus += energyAvailableMultiple;
  197. // set the new energy consumption to the maximum
  198. holonEl.setEnergyPerElement(energyAvailableSingle);
  199. flexDevicesTurnedOnThisTurn.put(holonEl, energyAvailableMultiple);
  200. }
  201. // else: we just need to turn on part of the flexible energy available
  202. else {
  203. float energyNeeded = -energySurplus;
  204. int i = 0;
  205. energySurplus += energyNeeded; // should give 0, but was kept this was for consistency
  206. // the energy needed divided through the amount of elements
  207. holonEl.setEnergyPerElement(energyNeeded / holonEl.getAmount());
  208. flexDevicesTurnedOnThisTurn.put(holonEl, energyNeeded);
  209. }
  210. }
  211. }
  212. if (energySurplus == 0) {
  213. break;
  214. }
  215. }
  216. if (energySurplus == 0) {
  217. break;
  218. }
  219. }
  220. }
  221. /**
  222. * Set Flow Simulation.
  223. *
  224. * @param sN Subnet
  225. */
  226. private void setFlowSimulation(SubNet sN) {
  227. ArrayList<AbstractCpsObject> producers = new ArrayList<>();
  228. AbstractCpsObject tmp = null;
  229. tagTable = new HashMap<>();
  230. // traverse all objects in this subnet
  231. for (HolonObject hl : sN.getObjects()) {
  232. float energy = hl.getCurrentEnergyAtTimeStep(timeStep);
  233. // if their production is higher than their consumption
  234. if (energy > 0) {
  235. tagTable.put(hl.getId(), energy);
  236. hl.addTag(hl.getId());
  237. for (CpsEdge edge : hl.getConnections()) {
  238. if (edge.isWorking()) {
  239. // set other end of edge as tmp-object
  240. // and add this end to the other end's tag-list
  241. AbstractCpsObject a = edge.getA();
  242. AbstractCpsObject b = edge.getB();
  243. if (a.getId() == hl.getId()) {
  244. b.addTag(hl.getId());
  245. tmp = b;
  246. }
  247. if (b.getId() == hl.getId()) {
  248. a.addTag(hl.getId());
  249. tmp = a;
  250. }
  251. edge.setFlow(edge.getFlow() + energy);
  252. edge.calculateState();
  253. edge.addTag(hl.getId());
  254. if (edge.isWorking() && !producers.contains(tmp)) {
  255. if (tmp instanceof HolonSwitch) {
  256. if (((HolonSwitch) tmp).getState(timeStep)) {
  257. producers.add(tmp);
  258. }
  259. } else if (!(tmp instanceof CpsUpperNode)) {
  260. producers.add(tmp);
  261. }
  262. }
  263. }
  264. }
  265. }
  266. }
  267. setFlowSimRec(producers, 0);
  268. }
  269. /**
  270. * Set Flow Simulation Rec.
  271. *
  272. * @param nodes the nodes
  273. * @param iter the Iteration
  274. */
  275. private void setFlowSimRec(ArrayList<AbstractCpsObject> nodes, int iter) {
  276. ArrayList<AbstractCpsObject> newNodes = new ArrayList<>();
  277. ArrayList<CpsEdge> changedEdges = new ArrayList<>();
  278. AbstractCpsObject tmp;
  279. if (nodes.size() != 0) {
  280. for (AbstractCpsObject cps : nodes) {
  281. // check whether the cps is in a legit state if it is a switch
  282. if (legitState(cps)) {
  283. for (CpsEdge edge : cps.getConnections()) {
  284. // is edge working
  285. // and does the edge's tag-list not (yet) contain all tags of the cps
  286. if (edge.isWorking()
  287. && (!(edge.containsTags(edge.getTags(), cps.getTag())))) {
  288. if (edge.getA().getId() == cps.getId()) {
  289. tmp = edge.getB();
  290. } else {
  291. tmp = edge.getA();
  292. }
  293. for (Integer tag : cps.getTag()) {
  294. if (!(edge.getTags().contains(tag))
  295. && !(edge.getPseudoTags().contains(tag))) {
  296. edge.setFlow(edge.getFlow() + tagTable.get(tag));
  297. edge.addTag(tag);
  298. }
  299. }
  300. // uppernodes do not spread energy
  301. if (!(tmp instanceof CpsUpperNode)) {
  302. for (Integer tag : tmp.getTag()) {
  303. if (!(edge.getTags().contains(tag))
  304. && tagTable.get(tag) != null
  305. && !(edge.getPseudoTags().contains(tag))) {
  306. edge.setFlow(edge.getFlow() + tagTable.get(tag));
  307. edge.addPseudoTag(tag);
  308. changedEdges.add(edge);
  309. }
  310. }
  311. }
  312. edge.calculateState();
  313. if (edge.isWorking()
  314. && !(tmp instanceof CpsUpperNode)) {
  315. tmp.addAllPseudoTags(cps.getTag());
  316. if (!newNodes.contains(tmp)) {
  317. newNodes.add(tmp);
  318. }
  319. }
  320. }
  321. }
  322. }
  323. }
  324. setPseudoTags(newNodes, changedEdges);
  325. setFlowSimRec(newNodes, iter + 1);
  326. }
  327. }
  328. /**
  329. * Set the Pseudo Tags.
  330. *
  331. * @param nodes Array of AbstractCpsObjects
  332. */
  333. private void setPseudoTags(ArrayList<AbstractCpsObject> nodes, ArrayList<CpsEdge> edges) {
  334. for (AbstractCpsObject node : nodes) {
  335. node.recalculateTags();
  336. node.setPseudoTags(new ArrayList<>());
  337. }
  338. for (CpsEdge edge : edges) {
  339. edge.recalculateTags();
  340. edge.setPseudoTag(new ArrayList<>());
  341. }
  342. }
  343. /**
  344. * Reset the Connection.
  345. *
  346. * @param cps CpsObject
  347. * @param visitedObj the visited Objects
  348. * @param visitedEdges the visited Edges
  349. */
  350. private void resetConnections(AbstractCpsObject cps, ArrayList<Integer> visitedObj,
  351. ArrayList<CpsEdge> visitedEdges) {
  352. visitedObj.add(cps.getId());
  353. cps.resetTags();
  354. for (CpsEdge e : cps.getConnections()) {
  355. if (!(visitedEdges.contains(e))) {
  356. e.setFlow(0);
  357. e.calculateState();
  358. e.setTags(new ArrayList<>());
  359. visitedEdges.add(e);
  360. if (!(visitedObj.contains(e.getA().getId()))) {
  361. resetConnections(e.getA(), visitedObj, visitedEdges);
  362. e.getA().resetTags();
  363. }
  364. if (!(visitedObj.contains(e.getB().getId()))) {
  365. resetConnections(e.getB(), visitedObj, visitedEdges);
  366. e.getB().resetTags();
  367. }
  368. }
  369. }
  370. }
  371. /**
  372. * calculates the energy of either all producers or consumers.
  373. * Flexible devices are filtered out
  374. *
  375. * @param type Type
  376. * @param sN Subnet
  377. * @param x Integer
  378. * @return The Energy
  379. */
  380. private float calculateEnergyWithoutFlexDevices(String type, SubNet sN, int x) {
  381. float energy = 0;
  382. for (HolonObject hl : sN.getObjects()) {
  383. float currentEnergyWithoutFlexibles = hl.getCurrentEnergyAtTimeStepWithoutFlexiblesAndResetFlexibles(x);
  384. if (type.equals("prod")) {
  385. if (currentEnergyWithoutFlexibles > 0) {
  386. energy += currentEnergyWithoutFlexibles;
  387. hl.setState(HolonObject.PRODUCER);
  388. }
  389. }
  390. if (type.equals("cons")) {
  391. if (currentEnergyWithoutFlexibles < 0) {
  392. energy = energy + currentEnergyWithoutFlexibles;
  393. hl.setState(HolonObject.NOT_SUPPLIED);
  394. }
  395. }
  396. if (currentEnergyWithoutFlexibles == 0) {
  397. hl.setState(HolonObject.NO_ENERGY);
  398. }
  399. }
  400. return energy;
  401. }
  402. /**
  403. * calculates the energy of either all producers or consumers.
  404. * Flexible devices are filtered out
  405. *
  406. * @param type Type
  407. * @param sN Subnet
  408. * @param x Integer
  409. * @return The Energy
  410. */
  411. private float calculateEnergyWithFlexDevices(String type, SubNet sN, int x) {
  412. float energy = 0;
  413. for (HolonObject hl : sN.getObjects()) {
  414. float currentEnergy = hl.getCurrentEnergyAtTimeStep(x);
  415. if (type.equals("prod")) {
  416. if (currentEnergy > 0) {
  417. energy += currentEnergy;
  418. hl.setState(HolonObject.PRODUCER);
  419. }
  420. }
  421. if (type.equals("cons")) {
  422. if (currentEnergy < 0) {
  423. energy = energy + currentEnergy;
  424. hl.setState(HolonObject.NOT_SUPPLIED);
  425. }
  426. }
  427. if (currentEnergy == 0) {
  428. hl.setState(HolonObject.NO_ENERGY);
  429. }
  430. }
  431. return energy;
  432. }
  433. /**
  434. * Calculate the Minimum Energy.
  435. *
  436. * @param sN Subnet
  437. * @param x Integer
  438. * @return the Calculated minimum Energy
  439. */
  440. private float calculateMinimumEnergy(SubNet sN, int x) {
  441. float min = 0;
  442. float minElement = 0;
  443. for (HolonObject hl : sN.getObjects()) {
  444. if (hl.getElements().size() > 0 && hl.getElements().get(0).getOverallEnergyAtTimeStep(x) < 0) {
  445. minElement = hl.getElements().get(0).getOverallEnergyAtTimeStep(x);
  446. }
  447. for (HolonElement he : hl.getElements()) {
  448. float overallEnergy = he.getOverallEnergyAtTimeStep(x);
  449. if (minElement < overallEnergy && overallEnergy < 0) {
  450. minElement = overallEnergy;
  451. }
  452. }
  453. min = min + minElement;
  454. }
  455. return min;
  456. }
  457. /**
  458. * generates all subNets from all objectsToHandle.
  459. */
  460. private void searchForSubNets() {
  461. subNets = new ArrayList<>();
  462. brokenEdges.clear();
  463. boolean end = false;
  464. int i = 0;
  465. AbstractCpsObject cps;
  466. if (objectsToHandle.size() > 0) {
  467. while (!end) {
  468. cps = objectsToHandle.get(i);
  469. SubNet singleSubNet = new SubNet(new ArrayList<>(), new ArrayList<>(),
  470. new ArrayList<>());
  471. singleSubNet = buildSubNet(cps, new ArrayList<>(), singleSubNet);
  472. if (singleSubNet.getObjects().size() != 0) {
  473. subNets.add(singleSubNet);
  474. }
  475. if (0 == objectsToHandle.size()) {
  476. end = true;
  477. }
  478. }
  479. }
  480. }
  481. /**
  482. * recursivly generates a subnet of all objects, that one specific object is
  483. * connected to.
  484. *
  485. * @param cps AbstractCpsObject
  486. * @param visited visited Array of Integer
  487. * @param sN Subnets
  488. * @return Subnet
  489. */
  490. private SubNet buildSubNet(AbstractCpsObject cps, ArrayList<Integer> visited, SubNet sN) {
  491. visited.add(cps.getId());
  492. if (cps instanceof HolonObject) {
  493. sN.getObjects().add((HolonObject) cps);
  494. }
  495. if (cps instanceof HolonSwitch) {
  496. sN.getSwitches().add((HolonSwitch) cps);
  497. }
  498. removeFromToHandle(cps.getId());
  499. AbstractCpsObject a;
  500. AbstractCpsObject b;
  501. for (CpsEdge edge : cps.getConnections()) {
  502. if (edge.isWorking()) {
  503. a = edge.getA();
  504. b = edge.getB();
  505. if (!(cps instanceof HolonSwitch)) {
  506. if (!(sN.getEdges().contains(edge))) {
  507. sN.getEdges().add(edge);
  508. }
  509. }
  510. if (cps instanceof HolonSwitch && ((HolonSwitch) cps).getState(timeStep)) {
  511. if (!(sN.getEdges().contains(edge))) {
  512. sN.getEdges().add(edge);
  513. }
  514. }
  515. if (!visited.contains(a.getId()) && legitState(cps) && !(a instanceof CpsUpperNode)) {
  516. sN = buildSubNet(a, visited, sN);
  517. }
  518. if (!visited.contains(b.getId()) && legitState(cps) && !(b instanceof CpsUpperNode)) {
  519. sN = buildSubNet(b, visited, sN);
  520. }
  521. if (a instanceof CpsUpperNode && a.getId() != cps.getId()) {
  522. edge.setConnected(CpsEdge.CON_UPPER_NODE_NOT_INSIDE);
  523. checkForConnectedStates(b, (CpsUpperNode) a, edge);
  524. }
  525. if (b instanceof CpsUpperNode && b.getId() != cps.getId()) {
  526. edge.setConnected(CpsEdge.CON_UPPER_NODE_NOT_INSIDE);
  527. checkForConnectedStates(a, (CpsUpperNode) b, edge);
  528. }
  529. } else {
  530. brokenEdges.add(edge);
  531. }
  532. }
  533. return sN;
  534. }
  535. /**
  536. * is the Switch in a legitimate State.
  537. *
  538. * @param current AbstractCpsObject
  539. * @return boolean
  540. */
  541. private boolean legitState(AbstractCpsObject current) {
  542. return !(current instanceof HolonSwitch)
  543. || ((HolonSwitch) current).getState(timeStep);
  544. }
  545. // /**
  546. // * ensures that objectsToHandle only contains HolonObjects.
  547. // */
  548. // public void cleanObjectsToHandle() {
  549. // for (int i = 0; i < objectsToHandle.size(); i++) {
  550. // if (!(objectsToHandle.get(i) instanceof HolonObject)) {
  551. // objectsToHandle.remove(i);
  552. // }
  553. // }
  554. // }
  555. /**
  556. * removes an Object that already has been handled.
  557. *
  558. * @param id the Object ID
  559. */
  560. private void removeFromToHandle(int id) {
  561. for (int i = 0; i < objectsToHandle.size(); i++) {
  562. if (objectsToHandle.get(i).getId() == id) {
  563. objectsToHandle.remove(i);
  564. }
  565. }
  566. }
  567. /**
  568. * copies the data of an array of Objects.
  569. *
  570. * @param toCopy the ArrayList of CpsObjects co Copy
  571. */
  572. private void copyObjects(ArrayList<AbstractCpsObject> toCopy) {
  573. for (AbstractCpsObject cps : toCopy) {
  574. if (cps instanceof CpsUpperNode) {
  575. copyObjects(((CpsUpperNode) cps).getNodes());
  576. } else {
  577. objectsToHandle.add(cps);
  578. }
  579. }
  580. }
  581. /**
  582. * Prints the Components auf all subnets.
  583. */
  584. private void printNetsToConsole() {
  585. for (int i = 0; i < subNets.size(); i++) {
  586. SubNet subNet = subNets.get(i);
  587. System.out.println("SUBNET NR:" + i);
  588. subNet.toString(timeStep);
  589. }
  590. }
  591. /**
  592. * Set the Canvas.
  593. *
  594. * @param can the Canvas
  595. */
  596. public void setCanvas(MyCanvas can) {
  597. canvas = can;
  598. }
  599. /**
  600. * Reset all Data to the current state of the Model.
  601. */
  602. public void reset() {
  603. objectsToHandle = new ArrayList<>();
  604. copyObjects(model.getObjectsOnCanvas());
  605. flexDevicesTurnedOnThisTurn = new HashMap<>();
  606. }
  607. /**
  608. * Resets the State of all Edges
  609. */
  610. private void resetEdges() {
  611. for (CpsEdge e : brokenEdges) {
  612. e.setWorkingState(true);
  613. }
  614. }
  615. /**
  616. * Resets the State for the whole Simulation Model
  617. */
  618. void resetSimulation() {
  619. reset();
  620. resetEdges();
  621. }
  622. /**
  623. * Get all Subnets.
  624. *
  625. * @return all Subnets
  626. */
  627. public ArrayList<SubNet> getSubNets() {
  628. return subNets;
  629. }
  630. /**
  631. * Get broken Edges
  632. */
  633. // public ArrayList<CpsEdge> getBrokenEdges() {
  634. // return brokenEdges;
  635. // }
  636. /**
  637. * checks whether a given object is connected to an object inside the upperNode.
  638. * if yes, the state for the edge is changed in "connected" or "not connected"
  639. */
  640. private void checkForConnectedStates(AbstractCpsObject cps, CpsUpperNode cUNode, CpsEdge theEdge) {
  641. AbstractCpsObject tmp;
  642. for (CpsEdge edge : cps.getConnections()) {
  643. if (edge.getA().getId() == cps.getId()) {
  644. tmp = edge.getB();
  645. } else {
  646. tmp = edge.getA();
  647. }
  648. if (cUNode.getNodes().contains(tmp)) {
  649. if (tmp instanceof CpsUpperNode) {
  650. checkForConnectedStates(cps, (CpsUpperNode) tmp, theEdge);
  651. } else {
  652. theEdge.setConnected(CpsEdge.CON_UPPER_NODE_AND_INSIDE);
  653. break;
  654. }
  655. }
  656. }
  657. }
  658. public FlexiblePane getFlexiblePane() {
  659. return flexPane;
  660. }
  661. void setFlexiblePane(FlexiblePane fp) {
  662. flexPane = fp;
  663. }
  664. }