123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414 |
- package de.tu_darmstadt.tk.SmartHomeNetworkSim.core;
- import java.util.LinkedList;
- import java.util.Observable;
- import javax.swing.Timer;
- import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.Controller;
- import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.scheduler.Schedulable;
- import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.scheduler.Scheduler;
- /**
- * Manages the Simulation by calling the relevant methods.
- *
- * @author Andreas T. Meyer-Berg
- */
- public class SimulationManager extends Observable {
- /**
- * Model which should be simulated
- */
- private Model model;
- /**
- * Controller for manipulationAlgorithms
- */
- private Controller controller;
- /**
- * Whether the model status changed during the last simulation and the panel
- * should be repainted
- */
- private boolean statusChanged = false;
-
- /**
- * Timer which triggers each simulation step
- */
- private Timer timer;
- /**
- * First Timestep of the simulation
- */
- private long startTime = 0L;
-
- /**
- * Last Timestep of the simulation
- */
- private long endTime = 1000L;
-
- /**
- * Current TimeStep in the simulation
- */
- private long currentTime = 0L;
-
- /**
- * Duration of the simulation
- */
- private long duration = 100L;
-
- /**
- * ManipulationAlgorithm Instances, which should run in each timestep
- */
- private LinkedList<NetworkManipulationAlgorithm> algos = new LinkedList<NetworkManipulationAlgorithm>();
-
- /**
- * PacketCollectionManager which manages the collection of packets
- */
- private PacketCollectionManager collectionMan;
-
- /**
- * PacketExportManager which handles packet export
- */
- private PacketExportManager exportMan;
-
- /*
- * Peformance Eval
- */
- //private long perfStart = 0;
-
- /**
- * Scheduler which stores the event queue and enables scheduling and running of further events
- */
- private static Scheduler scheduler;
-
- /**
- * Creates a new Simulationmanager
- *
- * @param model
- * Model that should be simulated
- */
- public SimulationManager(Model model) {
- this.model = model;
- this.controller = null;
- this.collectionMan = new PacketCollectionManager(model);
- this.exportMan = new PacketExportManager(model);
- timer = new Timer(0, t -> simulateTimeStep());
- scheduler = new Scheduler();
- }
- /**
- * Simulate the next Timestep
- */
- private void simulateTimeStep() {
- // Just simulate if timer is running
- if (endTime <= currentTime){
- stopSimulation();
- return;
- }
- if (currentTime + duration <= endTime) {
- simulateTimeIntervall(currentTime, duration);
- currentTime += duration;
- notifyPanels();
- } else {
- simulateTimeIntervall(currentTime, endTime - currentTime);
- currentTime = endTime;
- stopSimulation();
- }
- }
- /**
- * Simulates one time step at a given time for a given duration
- *
- * @param startTime
- * Time the simulation interval starts in
- * System.currentTimeMillis() time
- * @param duration
- * Duration of the simulation interval in milliseconds
- */
- public void simulateTimeIntervall(long startTime, long duration) {
- scheduler.setMinTime(startTime);
- //TODO: Fill Queue
- //TODO: Simulate Schedule
- //TODO: Export
-
- //Simulates the network
- boolean oldWay = false;
- if(oldWay)
- simulateNetwork(startTime, duration);
- else{
- long maxTime = startTime + duration;
- scheduler.scheduleAll(model);
- for(Connection con:model.getConnections()){
- Link l = con.getLink();
- if(l!=null){
- l.getPackets().clear();
- l.addPackets(con.getTerminationPackages(startTime));
- }
- }
- while(scheduler.hasNext(maxTime)){
- Schedulable currentEvent = scheduler.getAndRemoveFirst();
- //System.out.println("Event time: "+currentEvent.getEventTime());
- currentEvent.simulateEvent(currentEvent.getEventTime());
- }
- // Simulate SmartDevices - if they need some logic -> TODO: Insert as schedulable
- model.getDevices().forEach(d -> d.simulateTimeStep(startTime, duration));
- }
- runAlgorithms(startTime+duration);
- collectionMan.collectPackets();
- //Run all
- collectionMan.runPacketAlgorithms();
- //Export Packets
- exportMan.exportPacketsOfLastTimeStep();
- }
-
- /**
- * Simulates one time step of the network at a given time for a given duration
- *
- * @param startTime
- * Time the simulation interval starts in
- * System.currentTimeMillis() time
- * @param duration
- * Duration of the simulation interval in milliseconds
- */
- private void simulateNetwork(long startTime, long duration){
- //TODO: Implement Event Schedule
- // Nothing changed so far
- statusChanged = false;
- // Simulate all Links, and their connections
- model.getConnectionNetworks().forEach(d -> {
- d.simulateTimeInterval(startTime, duration);
- if (d.getStatusChanged()) {
- for (Connection c : d.getConnections()) {
- if (c.getStatus() == Connection.DONE) {
- model.getConnections().remove(c);
- }
- }
- statusChanged = true;
- }
- });
- // Simulate SmartDevices - if they need some logic
- model.getDevices().forEach(d -> d.simulateTimeStep(startTime, duration));
- // Store Packages/Export Packages etc. (for debug purposes)
- if (statusChanged) {
- model.setChanged();
- model.notifyObservers();
- }
- }
- /**
- * Start the simulation
- */
- public void startSimulation() {
- //perfStart=System.currentTimeMillis();
- timer.start();
- notifyPanels();
- }
- /**
- * Stop the simulation
- */
- public void stopSimulation() {
- timer.stop();
- /*
- long perfEnd = System.currentTimeMillis();
- long duration = perfEnd - perfStart;
- System.out.println("Duration: "+duration/1000.0);
- */
- notifyPanels();
- }
- /**
- * Resets the Simulation to the start time
- */
- public void resetSimulation() {
- timer.stop();
- timer = new Timer(0, a -> simulateTimeStep());
- currentTime = startTime;
- resetSimulation(currentTime);
- notifyPanels();
- }
- /**
- * Reset Simulation
- *
- * @param timestep new timestep of ports after the reset
- */
- private void resetSimulation(long timestep) {
- for (SmartDevice d : model.getDevices())
- for (Port p : d.getPorts())
- if (p.getLastTrigger() > timestep)
- p.setLastTrigger(timestep);
- scheduler.reset(timestep);
- /**
- for(Connection c: model.getConnections())
- for(Port p: c.getParticipants())
- if (p.getLastTrigger() > timestep)
- System.out.println("P without owner: "+p.toString());*/
- }
- /**
- * Returns true if the simulation is running, false if not
- *
- * @return true if running
- */
- public boolean isRunning() {
- return timer.isRunning();
- }
- /**
- * Returns the StartTime of the simulation
- *
- * @return startTime
- */
- public long getStartTime() {
- return startTime;
- }
- /**
- * Sets the new startTime
- *
- * @param startTime
- * time the simulations starts
- */
- public void setStartTime(long startTime) {
- this.startTime = startTime;
- notifyPanels();
- }
- /**
- * Returns the end time of the simulation
- *
- * @return End time of the simulation
- */
- public long getEndTime() {
- return endTime;
- }
- /**
- * Sets the new startTime
- * @param endTime new EndTime
- */
- public void setEndTime(long endTime) {
- this.endTime = endTime;
- notifyPanels();
- }
- /**
- * @return the currentTime
- */
- public long getCurrentTime() {
- return currentTime;
- }
- /**
- * @param currentTime
- * the currentTime to set
- */
- public void setCurrentTime(long currentTime) {
- this.currentTime = currentTime;
- notifyPanels();
- }
- /**
- * Returns the simulation step duration in milliseconds
- *
- * @return duration of each simulation step in milliseconds
- */
- public long getStepDuration() {
- return duration;
- }
- /**
- * Sets the duration of simulation steps
- *
- * @param duration
- * duration in milliseconds of a step
- */
- public void setStepDuration(long duration) {
- if(duration>0)
- this.duration = duration;
- else
- this.duration = 1;
- notifyPanels();
- }
- /**
- * Notify the panels, which could update their GUI
- */
- public void notifyPanels() {
- this.setChanged();
- this.notifyObservers();
- }
-
- /**
- * Runs all registered algorithms at the currentTimeStep
- * @param time currentTime of the simulation
- */
- public void runAlgorithms(long time) {
- /**
- * Run all Algorithms
- */
- for(NetworkManipulationAlgorithm algo:algos){
- algo.runAlgorithm(controller, time);
- }
- }
- /**
- * Returns all registered algorithms of the simulation
- * @return all registered algorithms
- */
- public LinkedList<NetworkManipulationAlgorithm> getAlgorithms(){
- return algos;
- }
- /**
- * Adds an algorithm, which should be executed each timestep
- * @param algo new algorithm
- */
- public void addAlgorithm(NetworkManipulationAlgorithm algo, Controller controller){
- this.controller = controller;
- if(algo!=null)
- algos.add(algo);
-
- }
-
- /**
- * Removes algorithms from the simulation
- * @param algo algorithm to be removed
- */
- public void removeAlgo(NetworkManipulationAlgorithm algo){
- algos.remove(algo);
- }
-
- /**
- * Returns the PacketCollectionManager of the simulation
- * @return PacketCollectionManager, which contains all the different packet collectors
- */
- public PacketCollectionManager getPacketCollectionManager(){
- return collectionMan;
- }
-
- /**
- * Returns the PacketExportManager
- * @return the exportMan
- */
- public PacketExportManager getPacketExportManager(){
- return exportMan;
- }
-
- /**
- * 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)
- * @param event event which should be scheduled
- * @return true if it was scheduled, false if not
- */
- public static boolean scheduleEvent(Schedulable event){
- return scheduler.scheduleEvent(event);
- }
-
- /**
- * Removes an event from the global event queue
- * @param event Event which should be removed
- * @return true, if it was removed, false if not
- */
- public static boolean removeEvent(Schedulable event){
- return scheduler.removeEvent(event);
- }
- }
|