www.pudn.com > JAVIS-0.3.zip > Packet.java
package animation;
import animation.VisualElement;
import math.Vector;
import util.Colour;
import java.awt.Graphics;
import java.awt.FontMetrics;
/**
Packet is the class that represents a network packet in Javis.
*/
public class Packet extends VisualElement {
// Values for m_status. These determine how the packet is being drawn
public final static int PACKET_FREE = 0;
public final static int PACKET_QUEUED = 1;
public final static int PACKET_DROPPED = 2;
int m_status; // One of the constants above
long m_size; // Packet size in bytes
int m_convid; // Conversation ID. Used for colouring
int m_packetid; // Packet ID (from IP)
double m_leaveTime; // Time when the packet left its source node
double m_arriveTime; // Time when the packet should arrive
double m_transmitTime; // Time it takes for the whole packet to go on
// the link (depends on packet size and bandw.)
String m_type; // Packet type (e.g. 'tcp')
Colour m_colour;
int m_src; // Node where the packet left
int m_dest; // Node the packet is heading for
double m_timeInc;
Vector m_start; // Start position when the packet left
Vector m_front; // Vectors with the front and tail coordinates of
Vector m_tail; // the packet, used in animation
Vector m_direction; // Distance vector between source and dest. node
Vector m_perp; // Perpendicular vector to direction, normalised
int m_polygon_x[]; // Polygon points for drawing
int m_polygon_y[];
int m_polygon_points; // Number of points in the polygon
Link m_link; // The link this packet is currently on
// -- The following are only used for animation when the packet is
// -- dropping !
final static int ROTATION_PHASES = 40;
final static double ROTATION_PACKET_SIZE = 4.0;
static double m_dropanim_x[]=null;
static double m_dropanim_y[]=null;
int m_dropanim_phase;
/**
Default constructor. Simply initialises everything.
*/
public Packet() {
m_front=new Vector();
m_tail=new Vector();
m_direction=new Vector();
m_start=new Vector();
m_perp=new Vector();
m_colour= new Colour("black");
m_polygon_x=new int[5];
m_polygon_y=new int[5];
m_polygon_points=4;
m_leaveTime=m_arriveTime=m_transmitTime=0;
m_status=PACKET_FREE;
m_size=0;
m_convid=0;
m_packetid=0;
m_type="";
m_src=0;
m_dest=0;
m_dropanim_phase=0;
precalculateAnimation();
}
/**
A private helper function that will calculate the static animation
tables first time it is called.
*/
private void precalculateAnimation() {
// If it has been done before, just return
if (m_dropanim_x!=null) return;
m_dropanim_x=new double[ROTATION_PHASES*4];
m_dropanim_y=new double[ROTATION_PHASES*4];
// Preset first frame of the animation
m_dropanim_x[0]=-ROTATION_PACKET_SIZE;
m_dropanim_y[0]=-ROTATION_PACKET_SIZE;
m_dropanim_x[1]=ROTATION_PACKET_SIZE;
m_dropanim_y[1]=-ROTATION_PACKET_SIZE;
m_dropanim_x[2]=ROTATION_PACKET_SIZE;
m_dropanim_y[2]=ROTATION_PACKET_SIZE;
m_dropanim_x[3]=-ROTATION_PACKET_SIZE;
m_dropanim_y[3]=ROTATION_PACKET_SIZE;
// Calculate the remaining frames
double angle=0.0;
for (int i=1;i10) {
m_polygon_points=5;
// Scale the values to screen size
m_front.m_value[0]=m_start.m_value[0]+
m_direction.m_value[0]*(front-6);
m_front.m_value[1]=m_start.m_value[1]+
m_direction.m_value[1]*(front-6);
m_tail.m_value[0]=m_start.m_value[0]+
m_direction.m_value[0]*tail;
m_tail.m_value[1]=m_start.m_value[1]+
m_direction.m_value[1]*tail;
// Fill in the values
m_polygon_x[0]=(int)m_front.m_value[0];
m_polygon_x[1]=(int)m_tail.m_value[0];
m_polygon_x[2]=(int)(m_tail.m_value[0]+
m_perp.m_value[0]*8.0);
m_polygon_x[3]=(int)(m_front.m_value[0]+
m_perp.m_value[0]*8.0);
m_polygon_x[4]=(int)(m_start.m_value[0]+
m_direction.m_value[0]*
front+
m_perp.m_value[0]*4.0);
m_polygon_y[0]=(int)m_front.m_value[1];
m_polygon_y[1]=(int)m_tail.m_value[1];
m_polygon_y[2]=(int)(m_tail.m_value[1]+
m_perp.m_value[1]*8.0);
m_polygon_y[3]=(int)(m_front.m_value[1]+
m_perp.m_value[1]*8.0);
m_polygon_y[4]=(int)(m_start.m_value[1]+
m_direction.m_value[1]*
front+
m_perp.m_value[1]*4.0);
}
else {
m_polygon_points=4;
// Polygon without an arrow
// Scale the values to screen size
m_front.m_value[0]=m_start.m_value[0]+
m_direction.m_value[0]*front;
m_front.m_value[1]=m_start.m_value[1]+
m_direction.m_value[1]*front;
m_tail.m_value[0]=m_start.m_value[0]+
m_direction.m_value[0]*tail;
m_tail.m_value[1]=m_start.m_value[1]+
m_direction.m_value[1]*tail;
// Fill in the values
m_polygon_x[0]=(int)m_front.m_value[0];
m_polygon_x[1]=(int)m_tail.m_value[0];
m_polygon_x[2]=(int)(m_tail.m_value[0]+
m_perp.m_value[0]*8.0);
m_polygon_x[3]=(int)(m_front.m_value[0]+
m_perp.m_value[0]*8.0);
m_polygon_y[0]=(int)m_front.m_value[1];
m_polygon_y[1]=(int)m_tail.m_value[1];
m_polygon_y[2]=(int)(m_tail.m_value[1]+
m_perp.m_value[1]*8.0);
m_polygon_y[3]=(int)(m_front.m_value[1]+
m_perp.m_value[1]*8.0);
}
break;
case PACKET_DROPPED:
m_tail.m_value[1]+=(m_timeInc*10000);
m_polygon_points=4;
// Copy the correct animation phase into our
// polygon
m_polygon_x[0]=(int)(m_dropanim_x[m_dropanim_phase+0]+m_tail.m_value[0]);
m_polygon_x[1]=(int)(m_dropanim_x[m_dropanim_phase+1]+m_tail.m_value[0]);
m_polygon_x[2]=(int)(m_dropanim_x[m_dropanim_phase+2]+m_tail.m_value[0]);
m_polygon_x[3]=(int)(m_dropanim_x[m_dropanim_phase+3]+m_tail.m_value[0]);
m_polygon_y[0]=(int)(m_dropanim_y[m_dropanim_phase+0]+m_tail.m_value[1]);
m_polygon_y[1]=(int)(m_dropanim_y[m_dropanim_phase+1]+m_tail.m_value[1]);
m_polygon_y[2]=(int)(m_dropanim_y[m_dropanim_phase+2]+m_tail.m_value[1]);
m_polygon_y[3]=(int)(m_dropanim_y[m_dropanim_phase+3]+m_tail.m_value[1]);
m_dropanim_phase=(m_dropanim_phase+4)%(ROTATION_PHASES*4);
break;
}
}
/**
isValid will return false if the packet is not actually in use anymore,
for example it has arrived at the destination.
@param time the time at which the packet validity is to be tested
@return false if the packet is not valid anymore
*/
public boolean isValid(double time) {
if(m_status==PACKET_DROPPED) return true;
if(m_status==PACKET_QUEUED) return true;
else return m_arriveTime>time;
}
/*
The following methods are utility functions to set various variables
inside the Packet.
*/
public void setStatus(int status) {
m_status=status;
}
public void setSize(long size) {
m_size=size;
}
public void setConvid (int convid) {
m_convid=convid;
}
public void setPacketid (int id) {
m_packetid= id;
}
public void setType (String type) {
m_type=type;
}
public void setPacketColour (Colour colour) {
m_colour.setColour(colour);
}
public Colour getPacketColour() {
return m_colour;
}
public void setLeaveTime (double time) {
m_leaveTime= time;
}
public void setArriveTime (double time) {
m_arriveTime=time;
}
public void setTransmitTime (double time) {
m_transmitTime=time;
}
public void setSource (int src) {
m_src=src;
}
public void setDestination (int dest) {
m_dest=dest;
}
public void setLink(Link l) {
m_link=l;
}
public void setStartPosition(double x,double y) {
m_start.m_value[0]=x;
m_start.m_value[1]=y;
}
public void setDropStart(double x, double y) {
m_tail.m_value[0]=x;
m_tail.m_value[1]=y;
}
public void setDirection(Vector v) {
m_direction=v;
m_direction.normalise();
}
public void setTimeInc(double inc) {
m_timeInc=inc;
}
public void readyToGo() {
// Generate perpendicular vector
m_perp.m_value[0]=-m_direction.m_value[1];
m_perp.m_value[1]=m_direction.m_value[0];
m_perp.normalise();
// Move the start point outwards a bit
m_start.m_value[0]+=m_perp.m_value[0]*3.0;
m_start.m_value[1]+=m_perp.m_value[1]*3.0;
}
/* The following methods are userd to return the values of the object
variables */
public int getStatus() {
return m_status;
}
public int getSource() {
return m_src;
}
public int getDestination() {
return m_dest;
}
public long getSize() {
return m_size;
}
public int getID() {
return m_packetid;
}
}