SimulationManager.java 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. package de.tu_darmstadt.tk.SmartHomeNetworkSim.core;
  2. import java.util.LinkedList;
  3. import java.util.Observable;
  4. import javax.swing.Timer;
  5. import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.Controller;
  6. import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.scheduler.Schedulable;
  7. import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.scheduler.Scheduler;
  8. /**
  9. * Manages the Simulation by calling the relevant methods.
  10. *
  11. * @author Andreas T. Meyer-Berg
  12. */
  13. public class SimulationManager extends Observable {
  14. /**
  15. * Model which should be simulated
  16. */
  17. private Model model;
  18. /**
  19. * Controller for manipulationAlgorithms
  20. */
  21. private Controller controller;
  22. /**
  23. * Whether the model status changed during the last simulation and the panel
  24. * should be repainted
  25. */
  26. private boolean statusChanged = false;
  27. /**
  28. * Timer which triggers each simulation step
  29. */
  30. private Timer timer;
  31. /**
  32. * First Timestep of the simulation
  33. */
  34. private long startTime = 0L;
  35. /**
  36. * Last Timestep of the simulation
  37. */
  38. private long endTime = 1000L;
  39. /**
  40. * Current TimeStep in the simulation
  41. */
  42. private long currentTime = 0L;
  43. /**
  44. * Duration of the simulation
  45. */
  46. private long duration = 100L;
  47. /**
  48. * ManipulationAlgorithm Instances, which should run in each timestep
  49. */
  50. private LinkedList<NetworkManipulationAlgorithm> algos = new LinkedList<NetworkManipulationAlgorithm>();
  51. /**
  52. * PacketCollectionManager which manages the collection of packets
  53. */
  54. private PacketCollectionManager collectionMan;
  55. /**
  56. * PacketExportManager which handles packet export
  57. */
  58. private PacketExportManager exportMan;
  59. /*
  60. * Peformance Eval
  61. */
  62. //private long perfStart = 0;
  63. /**
  64. * Scheduler which stores the event queue and enables scheduling and running of further events
  65. */
  66. private static Scheduler scheduler;
  67. /**
  68. * Creates a new Simulationmanager
  69. *
  70. * @param model
  71. * Model that should be simulated
  72. */
  73. public SimulationManager(Model model) {
  74. this.model = model;
  75. this.controller = null;
  76. this.collectionMan = new PacketCollectionManager(model);
  77. this.exportMan = new PacketExportManager(model);
  78. timer = new Timer(0, t -> simulateTimeStep());
  79. scheduler = new Scheduler();
  80. }
  81. /**
  82. * Simulate the next Timestep
  83. */
  84. private void simulateTimeStep() {
  85. // Just simulate if timer is running
  86. if (endTime <= currentTime){
  87. stopSimulation();
  88. return;
  89. }
  90. if (currentTime + duration <= endTime) {
  91. simulateTimeIntervall(currentTime, duration);
  92. currentTime += duration;
  93. notifyPanels();
  94. } else {
  95. simulateTimeIntervall(currentTime, endTime - currentTime);
  96. currentTime = endTime;
  97. stopSimulation();
  98. }
  99. }
  100. /**
  101. * Simulates one time step at a given time for a given duration
  102. *
  103. * @param startTime
  104. * Time the simulation interval starts in
  105. * System.currentTimeMillis() time
  106. * @param duration
  107. * Duration of the simulation interval in milliseconds
  108. */
  109. public void simulateTimeIntervall(long startTime, long duration) {
  110. scheduler.setMinTime(startTime);
  111. //TODO: Fill Queue
  112. //TODO: Simulate Schedule
  113. //TODO: Export
  114. //Simulates the network
  115. boolean oldWay = false;
  116. if(oldWay)
  117. simulateNetwork(startTime, duration);
  118. else{
  119. long maxTime = startTime + duration;
  120. scheduler.scheduleAll(model);
  121. for(Connection con:model.getConnections()){
  122. Link l = con.getLink();
  123. if(l!=null){
  124. l.getPackets().clear();
  125. l.addPackets(con.getTerminationPackages(startTime));
  126. }
  127. }
  128. while(scheduler.hasNext(maxTime)){
  129. Schedulable currentEvent = scheduler.getAndRemoveFirst();
  130. //System.out.println("Event time: "+currentEvent.getEventTime());
  131. currentEvent.simulateEvent(currentEvent.getEventTime());
  132. }
  133. // Simulate SmartDevices - if they need some logic -> TODO: Insert as schedulable
  134. model.getDevices().forEach(d -> d.simulateTimeStep(startTime, duration));
  135. }
  136. runAlgorithms(startTime+duration);
  137. collectionMan.collectPackets();
  138. //Run all
  139. collectionMan.runPacketAlgorithms();
  140. //Export Packets
  141. exportMan.exportPacketsOfLastTimeStep();
  142. }
  143. /**
  144. * Simulates one time step of the network at a given time for a given duration
  145. *
  146. * @param startTime
  147. * Time the simulation interval starts in
  148. * System.currentTimeMillis() time
  149. * @param duration
  150. * Duration of the simulation interval in milliseconds
  151. */
  152. private void simulateNetwork(long startTime, long duration){
  153. //TODO: Implement Event Schedule
  154. // Nothing changed so far
  155. statusChanged = false;
  156. // Simulate all Links, and their connections
  157. model.getConnectionNetworks().forEach(d -> {
  158. d.simulateTimeInterval(startTime, duration);
  159. if (d.getStatusChanged()) {
  160. for (Connection c : d.getConnections()) {
  161. if (c.getStatus() == Connection.DONE) {
  162. model.getConnections().remove(c);
  163. }
  164. }
  165. statusChanged = true;
  166. }
  167. });
  168. // Simulate SmartDevices - if they need some logic
  169. model.getDevices().forEach(d -> d.simulateTimeStep(startTime, duration));
  170. // Store Packages/Export Packages etc. (for debug purposes)
  171. if (statusChanged) {
  172. model.setChanged();
  173. model.notifyObservers();
  174. }
  175. }
  176. /**
  177. * Start the simulation
  178. */
  179. public void startSimulation() {
  180. //perfStart=System.currentTimeMillis();
  181. timer.start();
  182. notifyPanels();
  183. }
  184. /**
  185. * Stop the simulation
  186. */
  187. public void stopSimulation() {
  188. timer.stop();
  189. /*
  190. long perfEnd = System.currentTimeMillis();
  191. long duration = perfEnd - perfStart;
  192. System.out.println("Duration: "+duration/1000.0);
  193. */
  194. notifyPanels();
  195. }
  196. /**
  197. * Resets the Simulation to the start time
  198. */
  199. public void resetSimulation() {
  200. timer.stop();
  201. timer = new Timer(0, a -> simulateTimeStep());
  202. currentTime = startTime;
  203. resetSimulation(currentTime);
  204. notifyPanels();
  205. }
  206. /**
  207. * Reset Simulation
  208. *
  209. * @param timestep new timestep of ports after the reset
  210. */
  211. private void resetSimulation(long timestep) {
  212. for (SmartDevice d : model.getDevices())
  213. for (Port p : d.getPorts())
  214. if (p.getLastTrigger() > timestep)
  215. p.setLastTrigger(timestep);
  216. scheduler.reset(timestep);
  217. /**
  218. for(Connection c: model.getConnections())
  219. for(Port p: c.getParticipants())
  220. if (p.getLastTrigger() > timestep)
  221. System.out.println("P without owner: "+p.toString());*/
  222. }
  223. /**
  224. * Returns true if the simulation is running, false if not
  225. *
  226. * @return true if running
  227. */
  228. public boolean isRunning() {
  229. return timer.isRunning();
  230. }
  231. /**
  232. * Returns the StartTime of the simulation
  233. *
  234. * @return startTime
  235. */
  236. public long getStartTime() {
  237. return startTime;
  238. }
  239. /**
  240. * Sets the new startTime
  241. *
  242. * @param startTime
  243. * time the simulations starts
  244. */
  245. public void setStartTime(long startTime) {
  246. this.startTime = startTime;
  247. notifyPanels();
  248. }
  249. /**
  250. * Returns the end time of the simulation
  251. *
  252. * @return End time of the simulation
  253. */
  254. public long getEndTime() {
  255. return endTime;
  256. }
  257. /**
  258. * Sets the new startTime
  259. * @param endTime new EndTime
  260. */
  261. public void setEndTime(long endTime) {
  262. this.endTime = endTime;
  263. notifyPanels();
  264. }
  265. /**
  266. * @return the currentTime
  267. */
  268. public long getCurrentTime() {
  269. return currentTime;
  270. }
  271. /**
  272. * @param currentTime
  273. * the currentTime to set
  274. */
  275. public void setCurrentTime(long currentTime) {
  276. this.currentTime = currentTime;
  277. notifyPanels();
  278. }
  279. /**
  280. * Returns the simulation step duration in milliseconds
  281. *
  282. * @return duration of each simulation step in milliseconds
  283. */
  284. public long getStepDuration() {
  285. return duration;
  286. }
  287. /**
  288. * Sets the duration of simulation steps
  289. *
  290. * @param duration
  291. * duration in milliseconds of a step
  292. */
  293. public void setStepDuration(long duration) {
  294. if(duration>0)
  295. this.duration = duration;
  296. else
  297. this.duration = 1;
  298. notifyPanels();
  299. }
  300. /**
  301. * Notify the panels, which could update their GUI
  302. */
  303. public void notifyPanels() {
  304. this.setChanged();
  305. this.notifyObservers();
  306. }
  307. /**
  308. * Runs all registered algorithms at the currentTimeStep
  309. * @param time currentTime of the simulation
  310. */
  311. public void runAlgorithms(long time) {
  312. /**
  313. * Run all Algorithms
  314. */
  315. for(NetworkManipulationAlgorithm algo:algos){
  316. algo.runAlgorithm(controller, time);
  317. }
  318. }
  319. /**
  320. * Returns all registered algorithms of the simulation
  321. * @return all registered algorithms
  322. */
  323. public LinkedList<NetworkManipulationAlgorithm> getAlgorithms(){
  324. return algos;
  325. }
  326. /**
  327. * Adds an algorithm, which should be executed each timestep
  328. * @param algo new algorithm
  329. */
  330. public void addAlgorithm(NetworkManipulationAlgorithm algo, Controller controller){
  331. this.controller = controller;
  332. if(algo!=null)
  333. algos.add(algo);
  334. }
  335. /**
  336. * Removes algorithms from the simulation
  337. * @param algo algorithm to be removed
  338. */
  339. public void removeAlgo(NetworkManipulationAlgorithm algo){
  340. algos.remove(algo);
  341. }
  342. /**
  343. * Returns the PacketCollectionManager of the simulation
  344. * @return PacketCollectionManager, which contains all the different packet collectors
  345. */
  346. public PacketCollectionManager getPacketCollectionManager(){
  347. return collectionMan;
  348. }
  349. /**
  350. * Returns the PacketExportManager
  351. * @return the exportMan
  352. */
  353. public PacketExportManager getPacketExportManager(){
  354. return exportMan;
  355. }
  356. /**
  357. * Adds an event to the event queue, which will be simulated later. Returns falls, if it could not be added (e.g. timestep to low)
  358. * @param event event which should be scheduled
  359. * @return true if it was scheduled, false if not
  360. */
  361. public static boolean scheduleEvent(Schedulable event){
  362. return scheduler.scheduleEvent(event);
  363. }
  364. /**
  365. * Removes an event from the global event queue
  366. * @param event Event which should be removed
  367. * @return true, if it was removed, false if not
  368. */
  369. public static boolean removeEvent(Schedulable event){
  370. return scheduler.removeEvent(event);
  371. }
  372. }