Ver Fonte

Fixes various bugs

* ConcurrentModificationException while painting & adding devices
* Fixes NullPointer, when pressing SimulationReset, without starting b4
* Fixes Panel not repainting, after terminating packets were sent
* Adds status boolean, which is true, if repaint is needed
* Fixes terminated connections not being removed from the model
Andreas T. Meyer-Berg há 5 anos atrás
pai
commit
44de5de44d

+ 9 - 3
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/control/Controller.java

@@ -202,11 +202,17 @@ public class Controller {
 		for (Port p : toDelete.getPorts()) {
 			//Skip ports that are not connected
 			if(p.getConnection()==null)continue;
+			/**
+			 * Connection of the current port
+			 */
 			Connection c = p.getConnection();
-			//remove from connect
-			c.removeSmartDevice(p);
+			
 			//remove from protocol
-			if(c.getProtocol()!=null)c.getProtocol().removeDevice(p);
+			if(c.getProtocol()!=null)
+				c.getProtocol().removeDevice(p);
+			
+			//remove from connection
+			c.removeSmartDevice(p);
 			if (c.getStatus()==Connection.FINISHED||c.getStatus()==Connection.TERMINATED) {
 				//if connection terminated - remove rest of ports
 				for (Port sd : c.getParticipants()) {

+ 7 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/Connection.java

@@ -146,4 +146,11 @@ public interface Connection {
 	 * @return probability of packet loss (between 0.0 and 1.0
 	 */
 	public double getPacketLossProbability();
+	
+	/**
+	 * Returns true if the status, or participants changed during the last simulation time step
+	 * 
+	 * @return true, if status changed
+	 */
+	public boolean getStatusChanged();
 }

+ 7 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/ConnectionImplementation.java

@@ -11,6 +11,7 @@ public class ConnectionImplementation implements Connection {
 	private Protocol protocol;
 	private double packetLossRate;
 	private byte status;
+	private boolean changed = false;
 	
 	public ConnectionImplementation(Link l, Protocol p) {
 		link = l;
@@ -69,6 +70,7 @@ public class ConnectionImplementation implements Connection {
 
 	@Override
 	public Collection<Packet> getTerminationPackages(long startTime) {
+		changed=!removedParticipants.isEmpty();
 		removedParticipants.clear();
 		return protocol.generateNextPakets(null, startTime, false);
 	}
@@ -104,4 +106,9 @@ public class ConnectionImplementation implements Connection {
 		return packetLossRate;
 	}
 
+	@Override
+	public boolean getStatusChanged() {
+		return changed;
+	}
+
 }

+ 6 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/Link.java

@@ -71,4 +71,10 @@ public interface Link {
 	 * @return packets, which were sent during the last time step
 	 */
 	public Collection<Packet> getPackets();
+	
+	/**
+	 * Returns true if one or more connections have changed, and the Panel might have to be repainted
+	 * @return true if changed
+	 */
+	public boolean getStatusChanged();
 }

+ 2 - 3
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/Model.java

@@ -1,6 +1,5 @@
 package de.tu_darmstadt.tk.SmartHomeNetworkSim.core;
 
-import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Observable;
@@ -51,8 +50,8 @@ public class Model extends Observable{
 		setHeight(480);
 		setDepth(480);
 		
-		devices = new ArrayList<SmartDevice>();
-		connectionNetworks = new ArrayList<Link>();
+		devices = new LinkedList<SmartDevice>();
+		connectionNetworks = new LinkedList<Link>();
 		connections = new LinkedList<Connection>();
 	}
 

+ 30 - 2
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/SimulationManager.java

@@ -15,11 +15,22 @@ public class SimulationManager {
 	 * Model which should be simulated
 	 */
 	Model model;
+	
 	/**
 	 * True if packets should be printed
 	 */
 	boolean printPackets = false;
+	
+	/**
+	 * Whether the model status changed during the last simulation and the panel should be repainted
+	 */
+	boolean statusChanged = false;
+	
+	/**
+	 * Writer to write the packets to a file
+	 */
 	BufferedWriter writer;
+	
 	/**
 	 * Creates a new Simulationmanager
 	 * 
@@ -39,12 +50,27 @@ public class SimulationManager {
 	 *            Duration of the simulation interval in milliseconds
 	 */
 	public void simulateTimeIntervall(long startTime, long duration) {
+		//Nothing changed so far
+		statusChanged = false;
 		//Simulate all Links, and their connections
-		model.getConnectionNetworks().forEach(d -> d.simulateTimeInterval(startTime, duration));
+		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();
+		}
 		if(printPackets){
 			try {
 				File f = new File("testPackets.log");
@@ -73,6 +99,8 @@ public class SimulationManager {
 		}
 		
 		
+		
+		
 	}
 
 	/**

+ 4 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/protocols/MQTT_protocol.java

@@ -93,6 +93,10 @@ public class MQTT_protocol implements Protocol {
 		 * Update the lastTime the port was triggered
 		 */
 		port.setLastTrigger(timestep);
+		/**
+		 * if port null, skip this step
+		 */
+		if(broker==null)return returnPackets;
 		
 		/**
 		 * Generate new Packets regarding to their class

+ 17 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/simpleImplementation/SimpleConnection.java

@@ -44,6 +44,12 @@ public class SimpleConnection implements Connection {
 	 */
 	private byte status = Connection.ACTIVE;
 	
+	/**
+	 * True if the status of the connection changed during the last simulation step
+	 */
+	private boolean statusChanged = false;
+	
+	
 	/**
 	 * Probability of packet loss. (default: 0.0 -> no packets are lost. 1.0 -> all packets are lost)
 	 */
@@ -78,6 +84,11 @@ public class SimpleConnection implements Connection {
 	public Collection<Packet> simulateTimeInterval(long startTime, long duration) {
 		LinkedList<Packet> list = new LinkedList<Packet>();
 		if(status != ACTIVE)return list;
+		list.addAll(getTerminationPackages(startTime));
+		if(list.isEmpty())
+			statusChanged = true;
+		else 
+			statusChanged = false;
 		//Generate packets by source
 		if(source.getLastTrigger()+source.getTriggerInterval()<startTime && source.getStatus()==Port.SENDING){
 			list.addAll(p.generateNextPakets(source, startTime,Math.random()<packetLossProbability));
@@ -118,6 +129,7 @@ public class SimpleConnection implements Connection {
 
 	@Override
 	public Collection<Packet> getTerminationPackages(long startTime) {
+		if(status!=TERMINATED&&status!=FINISHED)return new LinkedList<Packet>();
 		status = DONE;
 		return new LinkedList<Packet>(Arrays.asList((Packet) new SimplePacket(
 				startTime, srcOfTermination,
@@ -161,4 +173,9 @@ public class SimpleConnection implements Connection {
 		return packetLossProbability;
 	}
 
+	@Override
+	public boolean getStatusChanged() {
+		return statusChanged;
+	}
+
 }

+ 12 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/simpleImplementation/SimpleLink.java

@@ -37,6 +37,11 @@ public class SimpleLink implements Link {
 	 * after termination
 	 */
 	private LinkedList<Packet> packets;
+	
+	/**
+	 * whether the status changed during the last simulation step
+	 */
+	private boolean statusChanged;
 
 	/**
 	 * Initializes a simple Link with name and an empty devices list.
@@ -102,6 +107,7 @@ public class SimpleLink implements Link {
 	@Override
 	public void simulateTimeInterval(long startTime, long duration) {
 		packets.clear();
+		statusChanged = false;
 		for (Connection c : connections) {
 			if (c.getLink() != this)
 				continue;
@@ -112,6 +118,7 @@ public class SimpleLink implements Link {
 					|| c.getStatus() == Connection.TERMINATED)
 				//Produce Termination packages
 				packets.addAll(c.getTerminationPackages(startTime));
+			statusChanged|=c.getStatusChanged();
 		}
 	}
 
@@ -134,4 +141,9 @@ public class SimpleLink implements Link {
 	public void removeConnection(Connection connection) {
 		connections.remove(connection);
 	}
+
+	@Override
+	public boolean getStatusChanged() {
+		return statusChanged;
+	}
 }

+ 1 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/SimulationConfigurator.java

@@ -122,6 +122,7 @@ public class SimulationConfigurator extends JFrame {
 	}
 	
 	private void resetAction(){
+		if(timer == null)return;
 		timer.stop();
 		try {
 			currentTime = Long.parseLong(tfStartTimeLong.getText());

+ 7 - 1
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/VisualisationPanel.java

@@ -5,6 +5,7 @@ import java.awt.Graphics;
 import java.awt.event.ComponentEvent;
 import java.awt.event.ComponentListener;
 import java.util.Collection;
+import java.util.Iterator;
 import java.util.Observable;
 import java.util.Observer;
 
@@ -105,7 +106,8 @@ public class VisualisationPanel extends JPanel implements Observer {
 	 */
 	public void paintDevices(Graphics g) {
 
-		for (SmartDevice s : model.getDevices()) {
+		for (Iterator<SmartDevice> it = model.getDevices().iterator();it.hasNext();) {
+			SmartDevice s = it.next();
 			int x = s.getX();
 			int y = s.getY();
 			if (s == interactor.dragged) {
@@ -155,6 +157,10 @@ public class VisualisationPanel extends JPanel implements Observer {
 			 * All Devices that are part of the connection
 			 */
 			Collection<Port> d = c.getParticipants();
+			if(d.size()==0){
+				System.out.println("WARNING: Empty, undeleted Connection:"+c.toString());
+				continue;
+			}
 			if(c.getProtocol() instanceof MQTT_protocol){
 				Port broker = c.getProtocol().getDevicesWithRole(0).iterator().next();
 				int broker_x = 0, broker_y = 0;