refactored the boat message to not use boats
#story[778]
This commit is contained in:
@@ -0,0 +1,215 @@
|
||||
package seng302;
|
||||
|
||||
|
||||
import seng302.Model.Boat;
|
||||
import seng302.Networking.BinaryMessageEncoder;
|
||||
import seng302.Networking.MessageEncoders.RaceVisionByteEncoder;
|
||||
import seng302.Networking.MessageEncoders.XMLMessageEncoder;
|
||||
import seng302.Networking.Utils.BoatLocationMessage;
|
||||
import seng302.Networking.Utils.MessageType;
|
||||
import seng302.Networking.Utils.RaceStatus;
|
||||
import seng302.Networking.Utils.XMLMessage;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
|
||||
/**
|
||||
* TCP client to recive information from AC35 data source
|
||||
*/
|
||||
public class MockOutput implements Runnable
|
||||
{
|
||||
private long lastHeartbeatTime;
|
||||
private RaceVisionByteEncoder messageEncoder = new RaceVisionByteEncoder();
|
||||
|
||||
//socket port 5003 as 4940 is ac35 live port and 4941 is ac35 test port
|
||||
private ServerSocket serverSocket;
|
||||
private Socket mockSocket;
|
||||
private DataOutputStream outToVisualiser;
|
||||
|
||||
//a buffer that contains items that are waiting to be sent
|
||||
private ArrayBlockingQueue<byte[]> messagesToSendBuffer = new ArrayBlockingQueue<>(99999999);
|
||||
|
||||
private short messageNumber = 1;
|
||||
private short xmlSequenceNumber = 1;
|
||||
private int heartbeatSequenceNum = 1;
|
||||
private int boatLocationSequenceNumber = 1;
|
||||
private int raceStatusSequenceNumber = 1;
|
||||
|
||||
public MockOutput() throws IOException {
|
||||
lastHeartbeatTime = System.currentTimeMillis();
|
||||
serverSocket = new ServerSocket(4942);
|
||||
}
|
||||
/**
|
||||
* calculates the time since last heartbeat
|
||||
* @return time since last heartbeat
|
||||
*/
|
||||
private double timeSinceHeartbeat() {
|
||||
long now = System.currentTimeMillis();
|
||||
return (now - lastHeartbeatTime) / 1000.0;
|
||||
}
|
||||
|
||||
//returns the heartbeat message
|
||||
private byte[] heartbeat(){
|
||||
byte[] heartbeatMessage = messageEncoder.heartBeat(heartbeatSequenceNum);
|
||||
heartbeatSequenceNum++;
|
||||
BinaryMessageEncoder binaryMessageEncoder = new BinaryMessageEncoder(MessageType.HEARTBEAT, System.currentTimeMillis(), messageNumber, (short)heartbeatMessage.length, heartbeatMessage);
|
||||
messageNumber++;
|
||||
return binaryMessageEncoder.getFullMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to give the mockOutput an xml string to be made into a message and sent
|
||||
* @param xmlString the xml string to send
|
||||
* @param messageType the kind of xml string, values given in AC35 spec (5 regatta, 6 race, 7 boat)
|
||||
*/
|
||||
public synchronized void parseXMLString(String xmlString, int messageType){
|
||||
XMLMessageEncoder encoder = new XMLMessageEncoder(messageNumber, System.currentTimeMillis(), messageType, xmlSequenceNumber,(short) xmlString.length(), xmlString);
|
||||
//iterates the sequence numbers
|
||||
xmlSequenceNumber++;
|
||||
byte[] encodedXML = encoder.encode();
|
||||
|
||||
BinaryMessageEncoder binaryMessageEncoder = new BinaryMessageEncoder(MessageType.XMLMESSAGE, System.currentTimeMillis(), messageNumber, (short)encodedXML.length, encodedXML);
|
||||
//iterates the message number
|
||||
messageNumber++;
|
||||
|
||||
addMessageToBufferToSend(binaryMessageEncoder.getFullMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to give the mocOutput information about boat location to be made into a message and sent
|
||||
*/
|
||||
public synchronized void parseBoatLocation(int sourceID, double lat, double lon){
|
||||
BoatLocationMessage boatLocationMessage = new BoatLocationMessage(sourceID, lat, lon, boatLocationSequenceNumber);
|
||||
//iterates the sequence number
|
||||
boatLocationSequenceNumber++;
|
||||
|
||||
//encodeds the messages
|
||||
byte[] encodedBoatLoc = messageEncoder.boatLocation(boatLocationMessage);
|
||||
|
||||
//encodeds the full message with header
|
||||
BinaryMessageEncoder binaryMessageEncoder = new BinaryMessageEncoder(MessageType.BOATLOCATION, System.currentTimeMillis(), messageNumber, (short)encodedBoatLoc.length,
|
||||
encodedBoatLoc);
|
||||
|
||||
//iterates the message number
|
||||
messageNumber++;
|
||||
|
||||
addMessageToBufferToSend(binaryMessageEncoder.getFullMessage());
|
||||
}
|
||||
|
||||
|
||||
public synchronized void parseRaceStatus(RaceStatus raceStatus){
|
||||
|
||||
//iterates the sequence number
|
||||
raceStatusSequenceNumber++;
|
||||
|
||||
//encodeds the messages
|
||||
byte[] encodedRaceStatus = messageEncoder.raceStatus(raceStatus);
|
||||
|
||||
//encodeds the full message with header
|
||||
BinaryMessageEncoder binaryMessageEncoder = new BinaryMessageEncoder(MessageType.RACESTATUS, System.currentTimeMillis(), messageNumber, (short)encodedRaceStatus.length,
|
||||
encodedRaceStatus);
|
||||
|
||||
//iterates the message number
|
||||
messageNumber++;
|
||||
|
||||
addMessageToBufferToSend(binaryMessageEncoder.getFullMessage());
|
||||
|
||||
}
|
||||
|
||||
private synchronized void addMessageToBufferToSend(byte[] messagesToSendBuffer) {
|
||||
this.messagesToSendBuffer.add(messagesToSendBuffer);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
||||
try {
|
||||
while (true){
|
||||
mockSocket = serverSocket.accept();
|
||||
outToVisualiser = new DataOutputStream(mockSocket.getOutputStream());
|
||||
|
||||
/*******************************Test********************************/
|
||||
|
||||
StringBuilder xmlString1;
|
||||
|
||||
BufferedReader br1 = new BufferedReader(new InputStreamReader(
|
||||
this.getClass().getResourceAsStream(("/raceXML/Boats.xml"))));
|
||||
|
||||
String line1;
|
||||
xmlString1 = new StringBuilder();
|
||||
while((line1=br1.readLine())!= null){
|
||||
xmlString1.append(line1.trim());
|
||||
}
|
||||
|
||||
parseXMLString(xmlString1.toString(), XMLMessage.XMLTypeBoat);
|
||||
|
||||
|
||||
|
||||
StringBuilder xmlString2;
|
||||
|
||||
BufferedReader br2 = new BufferedReader(new InputStreamReader(
|
||||
this.getClass().getResourceAsStream(("/raceXML/Race.xml"))));
|
||||
|
||||
String line2;
|
||||
xmlString2 = new StringBuilder();
|
||||
while((line2=br2.readLine())!= null){
|
||||
xmlString2.append(line2.trim());
|
||||
}
|
||||
|
||||
parseXMLString(xmlString2.toString(), XMLMessage.XMLTypeRace);
|
||||
|
||||
|
||||
|
||||
StringBuilder xmlString;
|
||||
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(
|
||||
this.getClass().getResourceAsStream(("/raceXML/Regatta.xml"))));
|
||||
|
||||
String line;
|
||||
xmlString = new StringBuilder();
|
||||
while((line=br.readLine())!= null){
|
||||
xmlString.append(line.trim());
|
||||
}
|
||||
|
||||
parseXMLString(xmlString.toString(), XMLMessage.XMLTypeRegatta);
|
||||
|
||||
/*******************************Test********************************/
|
||||
|
||||
while(true) {
|
||||
try {
|
||||
//sends a heartbeat every 5 seconds
|
||||
if (timeSinceHeartbeat() >= 5.00) {
|
||||
outToVisualiser.write(heartbeat());
|
||||
lastHeartbeatTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
//checks the buffer to see if there is anything to send
|
||||
if (messagesToSendBuffer.size() > 0) {
|
||||
for (byte[] binaryMessage : messagesToSendBuffer) {
|
||||
//sends the message to the visualiser
|
||||
outToVisualiser.write(binaryMessage);
|
||||
}
|
||||
//cleans out buffer
|
||||
messagesToSendBuffer.clear();
|
||||
}
|
||||
}catch(SocketException e){
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void main(String argv[]) throws Exception
|
||||
{
|
||||
MockOutput client = new MockOutput();
|
||||
client.run();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,14 +8,9 @@ import seng302.DataInput.RegattaDataSource;
|
||||
import seng302.Exceptions.InvalidBoatDataException;
|
||||
import seng302.Exceptions.InvalidRaceDataException;
|
||||
import seng302.Exceptions.InvalidRegattaDataException;
|
||||
import seng302.Networking.MessageEncoders.XMLMessageEncoder;
|
||||
import seng302.Networking.MockOutput;
|
||||
import seng302.Networking.Utils.XMLMessage;
|
||||
import seng302.MockOutput;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,7 +9,7 @@ import org.geotools.referencing.GeodeticCalculator;
|
||||
|
||||
import seng302.Constants;
|
||||
import seng302.DataInput.RaceDataSource;
|
||||
import seng302.Networking.MockOutput;
|
||||
import seng302.MockOutput;
|
||||
import seng302.Networking.Utils.BoatStatusMessage;
|
||||
import seng302.Networking.Utils.Enums.BoatStatus;
|
||||
import seng302.Networking.Utils.RaceStatus;
|
||||
@@ -176,7 +176,7 @@ public class Race implements Runnable {
|
||||
//Update position.
|
||||
updatePosition(boat, Math.round(1000 / lastFPS) > 20 ? 15 : Math.round(1000 / lastFPS));
|
||||
checkPosition(boat, totalTimeElapsed);
|
||||
mockOutput.parseBoatLocation(boat);
|
||||
mockOutput.parseBoatLocation(boat.getSourceID(), boat.getCurrentPosition().getLatitude(), boat.getCurrentPosition().getLongitude());
|
||||
System.out.println("Sending boat status");
|
||||
boatStatusMessages.add(new BoatStatusMessage(boat.getSourceID(),
|
||||
boat.getCurrentLeg().getLegNumber() >= 0 ? BoatStatus.RACING : BoatStatus.DNF, boat.getCurrentLeg().getLegNumber()));
|
||||
|
||||
Reference in New Issue
Block a user