remade traffic visualizer: buffers old radio connections + friendlier api
This commit is contained in:
parent
b1afe2257b
commit
83b87c630b
|
@ -26,14 +26,15 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: VisTraffic.java,v 1.2 2006/10/05 15:13:48 fros4943 Exp $
|
* $Id: VisTraffic.java,v 1.3 2006/10/11 10:37:06 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.plugins;
|
package se.sics.cooja.plugins;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.image.BufferedImage;
|
import java.util.*;
|
||||||
import java.util.Observable;
|
import javax.swing.SwingUtilities;
|
||||||
import java.util.Observer;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import se.sics.cooja.*;
|
import se.sics.cooja.*;
|
||||||
import se.sics.cooja.interfaces.Position;
|
import se.sics.cooja.interfaces.Position;
|
||||||
|
@ -49,18 +50,21 @@ import se.sics.cooja.interfaces.Position;
|
||||||
@ClassDescription("Traffic Visualizer")
|
@ClassDescription("Traffic Visualizer")
|
||||||
@VisPluginType(VisPluginType.SIM_PLUGIN)
|
@VisPluginType(VisPluginType.SIM_PLUGIN)
|
||||||
public class VisTraffic extends Visualizer2D {
|
public class VisTraffic extends Visualizer2D {
|
||||||
|
private boolean USE_ALPHA = false;
|
||||||
|
|
||||||
|
private boolean USE_HISTORY = true;
|
||||||
|
|
||||||
|
private int MAX_PAINTED_CONNS = 50;
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private static Logger logger = Logger.getLogger(VisTraffic.class);
|
||||||
|
|
||||||
private RadioMedium radioMedium;
|
private RadioMedium radioMedium;
|
||||||
|
|
||||||
/**
|
public Vector<PaintedConnection> allPaintedConnections = new Vector<PaintedConnection>();
|
||||||
* The image painted on screen at repaint().
|
|
||||||
*/
|
|
||||||
public BufferedImage image;
|
|
||||||
|
|
||||||
private Position oldSmallPosition = null;
|
|
||||||
private Position oldBigPosition = null;
|
|
||||||
private Simulation simulation;
|
private Simulation simulation;
|
||||||
private int oldNrMotes;
|
|
||||||
|
|
||||||
private Observer radioObserver = null;
|
private Observer radioObserver = null;
|
||||||
|
|
||||||
|
@ -74,97 +78,86 @@ public class VisTraffic extends Visualizer2D {
|
||||||
super(simulationToVisualize);
|
super(simulationToVisualize);
|
||||||
setTitle("Traffic Visualizer");
|
setTitle("Traffic Visualizer");
|
||||||
simulation = simulationToVisualize;
|
simulation = simulationToVisualize;
|
||||||
oldNrMotes = simulation.getMotesCount();
|
|
||||||
|
|
||||||
radioMedium = simulationToVisualize.getRadioMedium();
|
radioMedium = simulationToVisualize.getRadioMedium();
|
||||||
|
|
||||||
// Repaint when radio medium has sent data
|
// Listen to radio medium and paint any new data transfers
|
||||||
simulationToVisualize.getRadioMedium().addRadioMediumObserver(radioObserver = new Observer() {
|
simulationToVisualize.getRadioMedium().addRadioMediumObserver(
|
||||||
public void update(Observable obs, Object obj) {
|
radioObserver = new Observer() {
|
||||||
Graphics2D g2d = image.createGraphics();
|
public void update(Observable obs, Object obj) {
|
||||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f));
|
if (radioMedium == null)
|
||||||
if (radioMedium != null && radioMedium.getLastTickConnections() != null) {
|
return;
|
||||||
for (RadioConnection conn: radioMedium.getLastTickConnections()) {
|
|
||||||
if (conn != null)
|
|
||||||
paintConnection(conn, g2d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
getCurrentCanvas().repaint();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
final RadioConnection[] connsToAdd = radioMedium
|
||||||
|
.getLastTickConnections();
|
||||||
|
if (connsToAdd != null && connsToAdd.length > 0) {
|
||||||
|
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
if (!USE_HISTORY)
|
||||||
|
allPaintedConnections.clear();
|
||||||
|
|
||||||
|
for (RadioConnection conn : connsToAdd) {
|
||||||
|
if (conn != null) {
|
||||||
|
Color connColor = getColorOf(conn);
|
||||||
|
int duration = getDurationOf(conn);
|
||||||
|
if (connColor != null && duration > 0)
|
||||||
|
allPaintedConnections.add(0, new PaintedConnection(
|
||||||
|
conn, duration, connColor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getCurrentCanvas().repaint();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Paints given connection on given graphics.
|
* Paints given connection on given graphics.
|
||||||
*
|
*
|
||||||
* @param connection Connection
|
* @param connection
|
||||||
* @param g2d Graphics to paint on
|
* Connection
|
||||||
|
* @param g2d
|
||||||
|
* Graphics to paint on
|
||||||
*/
|
*/
|
||||||
protected void paintConnection(RadioConnection connection, Graphics g2d) {
|
protected void paintConnection(PaintedConnection connection, Graphics g2d) {
|
||||||
Point sourcePixelPosition = transformPositionToPixel(connection.getSourcePosition());
|
Point sourcePixelPosition = transformPositionToPixel(connection.radioConnection
|
||||||
for (Position destPosition: connection.getDestinationPositons()) {
|
.getSourcePosition());
|
||||||
|
g2d.setColor(connection.getColor(simulation.isRunning()));
|
||||||
|
for (Position destPosition : connection.radioConnection
|
||||||
|
.getDestinationPositons()) {
|
||||||
Point destPixelPosition = transformPositionToPixel(destPosition);
|
Point destPixelPosition = transformPositionToPixel(destPosition);
|
||||||
g2d.setColor(getColorOf(connection));
|
|
||||||
g2d.drawLine(sourcePixelPosition.x, sourcePixelPosition.y,
|
g2d.drawLine(sourcePixelPosition.x, sourcePixelPosition.y,
|
||||||
destPixelPosition.x, destPixelPosition.y);
|
destPixelPosition.x, destPixelPosition.y);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns color a specific connection should be painted in.
|
* Returns color the given connection should be painted in. If returned color
|
||||||
|
* is null, the connection will not be painted.
|
||||||
*
|
*
|
||||||
* @param connection Connection
|
* @param connection
|
||||||
|
* Connection
|
||||||
|
* @return Color
|
||||||
*/
|
*/
|
||||||
protected Color getColorOf(RadioConnection connection) {
|
protected Color getColorOf(RadioConnection connection) {
|
||||||
return Color.BLACK;
|
return Color.BLACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void calculateTransformations() {
|
/**
|
||||||
super.calculateTransformations();
|
* Returns duration the given connection should be visible. If negative, the
|
||||||
Dimension imageDimension = getCurrentCanvas().getPreferredSize();
|
* connection will not be painted. Observe that the duration is the number of
|
||||||
if (imageDimension.height <= 0 || imageDimension.width <= 0)
|
* repaints, not related to time.
|
||||||
return;
|
*
|
||||||
|
* @param connection
|
||||||
// Recreate image if ..
|
* Connection
|
||||||
if (
|
* @return Duration in repaints
|
||||||
// .. it hasn't been painted before
|
*/
|
||||||
oldSmallPosition == null ||
|
protected int getDurationOf(RadioConnection connection) {
|
||||||
oldBigPosition == null ||
|
return 10;
|
||||||
image == null ||
|
|
||||||
simulation == null ||
|
|
||||||
|
|
||||||
// .. mote changes may have changed the transformation.
|
|
||||||
simulation.getMotesCount() != oldNrMotes ||
|
|
||||||
|
|
||||||
// .. visualization window has changed the transformation.
|
|
||||||
imageDimension.height != image.getHeight() ||
|
|
||||||
imageDimension.width != image.getWidth()
|
|
||||||
) {
|
|
||||||
if (simulation != null)
|
|
||||||
oldNrMotes = simulation.getMotesCount();
|
|
||||||
|
|
||||||
BufferedImage oldImage = image;
|
|
||||||
image = new BufferedImage(imageDimension.width, imageDimension.height, BufferedImage.TYPE_4BYTE_ABGR);
|
|
||||||
image.createGraphics().setColor(Color.WHITE);
|
|
||||||
image.createGraphics().fillRect(0, 0, imageDimension.width, imageDimension.height);
|
|
||||||
|
|
||||||
// If old data exists, keep it
|
|
||||||
if (oldSmallPosition != null && oldBigPosition != null) {
|
|
||||||
Point oldSmallPixelPos = transformPositionToPixel(oldSmallPosition);
|
|
||||||
Point oldBigPixelPos = transformPositionToPixel(oldBigPosition);
|
|
||||||
image.createGraphics().drawImage(oldImage,
|
|
||||||
oldSmallPixelPos.x,
|
|
||||||
oldSmallPixelPos.y,
|
|
||||||
oldBigPixelPos.x-oldSmallPixelPos.x,
|
|
||||||
oldBigPixelPos.y-oldSmallPixelPos.y,
|
|
||||||
null);
|
|
||||||
}
|
|
||||||
|
|
||||||
oldSmallPosition = transformPixelToPositon(new Point(0,0));
|
|
||||||
oldBigPosition = transformPixelToPositon(new Point(imageDimension.width, imageDimension.height));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void closePlugin() {
|
public void closePlugin() {
|
||||||
|
@ -179,7 +172,68 @@ public class VisTraffic extends Visualizer2D {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void visualizeSimulation(Graphics g) {
|
protected void visualizeSimulation(Graphics g) {
|
||||||
g.drawImage(image, 0, 0, null);
|
|
||||||
|
// Clean up old connections
|
||||||
|
Vector<PaintedConnection> newPaintedConnections = new Vector<PaintedConnection>();
|
||||||
|
for (PaintedConnection conn : allPaintedConnections)
|
||||||
|
if (!conn.shouldBeRemoved())
|
||||||
|
newPaintedConnections.add(conn);
|
||||||
|
allPaintedConnections = newPaintedConnections;
|
||||||
|
if (allPaintedConnections.size() > MAX_PAINTED_CONNS)
|
||||||
|
allPaintedConnections.setSize(MAX_PAINTED_CONNS);
|
||||||
|
|
||||||
|
for (PaintedConnection conn : allPaintedConnections)
|
||||||
|
paintConnection(conn, (Graphics2D) g);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PaintedConnection {
|
||||||
|
public RadioConnection radioConnection;
|
||||||
|
|
||||||
|
private int duration;
|
||||||
|
|
||||||
|
private int colorVal;
|
||||||
|
|
||||||
|
private int repaintsLeft;
|
||||||
|
|
||||||
|
private Color staticColor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param conn
|
||||||
|
* Radio connection to visualize
|
||||||
|
* @param duration
|
||||||
|
* Number of repaints
|
||||||
|
* @param color
|
||||||
|
* Base color of painted connection
|
||||||
|
*/
|
||||||
|
public PaintedConnection(RadioConnection conn, int duration, Color color) {
|
||||||
|
radioConnection = conn;
|
||||||
|
colorVal = color.getRGB() & 0xffffff;
|
||||||
|
repaintsLeft = duration;
|
||||||
|
this.duration = duration;
|
||||||
|
staticColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get color this connection should be painted in.
|
||||||
|
*
|
||||||
|
* @param isRunning
|
||||||
|
* True if current simulation is running
|
||||||
|
* @return Color
|
||||||
|
*/
|
||||||
|
public Color getColor(boolean isRunning) {
|
||||||
|
if (isRunning)
|
||||||
|
repaintsLeft--;
|
||||||
|
|
||||||
|
if (!USE_ALPHA)
|
||||||
|
return staticColor;
|
||||||
|
|
||||||
|
int alpha = 127 + 128 * repaintsLeft / duration;
|
||||||
|
return new Color(colorVal | (alpha << 24), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean shouldBeRemoved() {
|
||||||
|
return repaintsLeft <= 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue