Added LatestMessages to network.Messages. This is an object that encapsulates the latest up to date set of race messages.

Race stores a reference to it. MockRace writes to it, and eventually, VisualiserRace will read from it.
Updated MockRace, MockOutput, Event to use it.

Angle now implements hashCode().
main
fjc40 9 years ago
parent 3a0b81834f
commit 8e18ad62ca

@ -3,6 +3,7 @@ package mock.app;
import mock.model.MockRace;
import mock.model.Polars;
import network.Messages.Enums.MessageType;
import network.Messages.LatestMessages;
import org.xml.sax.SAXException;
import shared.dataInput.*;
import shared.exceptions.InvalidBoatDataException;
@ -28,6 +29,8 @@ public class Event {
private String boatXML;
private Polars boatPolars;
private MockOutput mockOutput;
private LatestMessages latestMessages;
public Event(String raceXML, String regattaXML, String boatXML, Polars boatPolars) {
@ -36,9 +39,13 @@ public class Event {
this.regattaXML = regattaXML;
this.boatPolars = boatPolars;
this.latestMessages = new LatestMessages();
try {
mockOutput = new MockOutput();
this.mockOutput = new MockOutput(this.latestMessages);
new Thread(mockOutput).start();
} catch (IOException e) {
e.printStackTrace();
}
@ -57,7 +64,7 @@ public class Event {
RegattaDataSource regattaDataSource = new RegattaXMLReader(this.regattaXML);
//Create and start race.
MockRace newRace = new MockRace(boatDataSource, raceDataSource, regattaDataSource, this.boatPolars, this.mockOutput);
MockRace newRace = new MockRace(boatDataSource, raceDataSource, regattaDataSource, this.boatPolars, this.latestMessages);
new Thread(newRace).start();

@ -7,6 +7,7 @@ import network.MessageEncoders.RaceVisionByteEncoder;
import network.MessageEncoders.XMLMessageEncoder;
import network.Messages.BoatLocation;
import network.Messages.Enums.MessageType;
import network.Messages.LatestMessages;
import network.Messages.RaceStatus;
import network.Messages.XMLMessage;
@ -37,8 +38,14 @@ public class MockOutput implements Runnable
///Output stream which wraps around mockSocket outstream.
private DataOutputStream outToVisualiser;
///A queue that contains items that are waiting to be sent.
private ArrayBlockingQueue<byte[]> messagesToSendQueue = new ArrayBlockingQueue<>(99999999);
/**
* An object containing the set of latest messages to send.
* Every server frame, MockOutput reads messages from this, and send them.
*/
private LatestMessages latestMessages;
///Sequence numbers used in messages.
private short messageNumber = 1;
@ -56,11 +63,15 @@ public class MockOutput implements Runnable
/**
* Ctor.
* @param latestMessages The collection of messages to send to connected clients.
* @throws IOException if server socket cannot be opened.
*/
public MockOutput() throws IOException {
lastHeartbeatTime = System.currentTimeMillis();
serverSocket = new ServerSocket(serverPort);
public MockOutput(LatestMessages latestMessages) throws IOException {
this.lastHeartbeatTime = System.currentTimeMillis();
this.serverSocket = new ServerSocket(serverPort);
this.latestMessages = latestMessages;
}
/**
@ -91,78 +102,93 @@ public class MockOutput implements Runnable
* @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);
public synchronized byte[] 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);
BinaryMessageEncoder binaryMessageEncoder = new BinaryMessageEncoder(
MessageType.XMLMESSAGE,
System.currentTimeMillis(),
messageNumber,
(short)encodedXML.length,
encodedXML);
//iterates the message number
messageNumber++;
addMessageToBufferToSend(binaryMessageEncoder.getFullMessage());
return binaryMessageEncoder.getFullMessage();
}
/**
* Used to give the mocOutput information about boat location to be made into a message and sent
* @param sourceID id of the boat
* @param lat latitude of boat
* @param lon longitude of boat
* @param heading heading of boat
* @param speed speed of boat
* @param time historical time of race
* Encodes/serialises a BoatLocation message, and returns it.
* @param boatLocation The BoatLocation message to serialise.
* @return The BoatLocation message in a serialised form.
*/
public synchronized void parseBoatLocation(int sourceID, double lat, double lon, double heading, double speed, long time){
private synchronized byte[] parseBoatLocation(BoatLocation boatLocation){
BoatLocation boatLocation = new BoatLocation(sourceID, lat, lon, boatLocationSequenceNumber, heading, speed, time);
//iterates the sequence number
boatLocationSequenceNumber++;
//encodeds the messages
//Encodes the message.
byte[] encodedBoatLoc = RaceVisionByteEncoder.boatLocation(boatLocation);
//encodeds the full message with header
BinaryMessageEncoder binaryMessageEncoder = new BinaryMessageEncoder(MessageType.BOATLOCATION, System.currentTimeMillis(), messageNumber, (short)encodedBoatLoc.length,
encodedBoatLoc);
//Encodes 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());
return binaryMessageEncoder.getFullMessage();
}
/**
* Parse the race status data and add it to the buffer to be sent
* @param raceStatus race status to parses
* Encodes/serialises a RaceStatus message, and returns it.
* @param raceStatus The RaceStatus message to serialise.
* @return The RaceStatus message in a serialised form.
*/
public synchronized void parseRaceStatus(RaceStatus raceStatus){
private synchronized byte[] parseRaceStatus(RaceStatus raceStatus){
//iterates the sequence number
raceStatusSequenceNumber++;
//encodeds the messages
//Encodes the messages.
byte[] encodedRaceStatus = RaceVisionByteEncoder.raceStatus(raceStatus);
//encodeds the full message with header
BinaryMessageEncoder binaryMessageEncoder = new BinaryMessageEncoder(MessageType.RACESTATUS, System.currentTimeMillis(), messageNumber, (short)encodedRaceStatus.length,
encodedRaceStatus);
//Encodes 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());
return binaryMessageEncoder.getFullMessage();
}
/**
* Add a message to the buffer to be sent
* @param messagesToSendBuffer message to add to the buffer
*/
private synchronized void addMessageToBufferToSend(byte[] messagesToSendBuffer) {
this.messagesToSendQueue.add(messagesToSendBuffer);
}
/**
* Sending loop of the Server
*/
@ -175,7 +201,7 @@ public class MockOutput implements Runnable
outToVisualiser = new DataOutputStream(mockSocket.getOutputStream());
if (boatsXml == null || regattaXml == null || raceXml == null){
if (boatsXml == null || regattaXml == null || raceXml == null) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
@ -184,34 +210,91 @@ public class MockOutput implements Runnable
continue;
}
parseXMLString(raceXml, XMLMessage.XMLTypeRace);
parseXMLString(regattaXml, XMLMessage.XMLTypeRegatta);
parseXMLString(boatsXml, XMLMessage.XMLTypeBoat);
//Encode xml files. We send them inside the loop, depending on the sentXMLs boolean.
byte[] raceXMLBlob = parseXMLString(raceXml, XMLMessage.XMLTypeRace);
byte[] regattaXMLBlob = parseXMLString(regattaXml, XMLMessage.XMLTypeRegatta);
byte[] boatsXMLBlob = parseXMLString(boatsXml, XMLMessage.XMLTypeBoat);
long previousFrameTime = System.currentTimeMillis();
boolean sentXMLs = false;
while(true) {
try {
//Sends a heartbeat every so often.
if (timeSinceHeartbeat() >= heartbeatPeriod) {
outToVisualiser.write(heartbeat());
lastHeartbeatTime = System.currentTimeMillis();
}
//Checks the buffer to see if there is anything to send.
while (messagesToSendQueue.size() > 0) {
//Grabs message from head of queue.
byte[] binaryMessage = messagesToSendQueue.remove();
long currentFrameTime = System.currentTimeMillis();
//This is the time elapsed, in milliseconds, since the last server "frame".
long framePeriod = currentFrameTime - previousFrameTime;
//We only attempt to send packets every X milliseconds.
long minimumFramePeriod = 16;
if (framePeriod >= minimumFramePeriod) {
//Sends a heartbeat every so often.
if (timeSinceHeartbeat() >= heartbeatPeriod) {
outToVisualiser.write(heartbeat());
lastHeartbeatTime = System.currentTimeMillis();
}
//Send XML messages.
if (!sentXMLs) {
outToVisualiser.write(raceXMLBlob);
outToVisualiser.write(regattaXMLBlob);
outToVisualiser.write(boatsXMLBlob);
sentXMLs = true;
}
//Sens the RaceStatus message.
if (this.latestMessages.getRaceStatus() != null) {
byte[] raceStatusBlob = this.parseRaceStatus(this.latestMessages.getRaceStatus());
this.outToVisualiser.write(raceStatusBlob);
}
//sends the message to the visualiser
outToVisualiser.write(binaryMessage);
//Send all of the BoatLocation messages.
for (int sourceID : this.latestMessages.getBoatLocationMap().keySet()) {
//Get the message.
BoatLocation boatLocation = this.latestMessages.getBoatLocation(sourceID);
if (boatLocation != null) {
//Encode.
byte[] boatLocationBlob = this.parseBoatLocation(boatLocation);
//Write it.
this.outToVisualiser.write(boatLocationBlob);
}
}
previousFrameTime = currentFrameTime;
} else {
//Wait until the frame period will be large enough.
long timeToWait = minimumFramePeriod - framePeriod;
try {
Thread.sleep(timeToWait);
} catch (InterruptedException e) {
//If we get interrupted, exit the function.
e.printStackTrace();
//Re-set the interrupt flag.
Thread.currentThread().interrupt();
return;
}
}
}catch(SocketException e){
} catch (SocketException e) {
break;
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
@ -247,7 +330,7 @@ public class MockOutput implements Runnable
public static void main(String argv[]) throws Exception
{
MockOutput client = new MockOutput();
MockOutput client = new MockOutput(new LatestMessages());
client.run();
}

@ -2,8 +2,10 @@ package mock.model;
import javafx.animation.AnimationTimer;
import mock.app.MockOutput;
import network.Messages.BoatLocation;
import network.Messages.BoatStatus;
import network.Messages.Enums.BoatStatusEnum;
import network.Messages.LatestMessages;
import network.Messages.RaceStatus;
import network.Utils.AC35UnitConverter;
import shared.dataInput.BoatDataSource;
@ -52,12 +54,6 @@ public class MockRace extends Race {
private int dnfChance = 0;
/**
* The mockOutput to send messages to.
*/
private MockOutput mockOutput;
/**
* Used to generate random numbers when changing the wind direction.
@ -88,13 +84,12 @@ public class MockRace extends Race {
* @param raceDataSource Data source for race related data (participating boats, legs, etc...).
* @param regattaDataSource Data source for race related data (course name, location, timezone, etc...).
* @param polars The polars table to be used for boat simulation.
* @param mockOutput The mockOutput to send events to.
* @param latestMessages The LatestMessages to send events to.
*/
public MockRace(BoatDataSource boatDataSource, RaceDataSource raceDataSource, RegattaDataSource regattaDataSource, Polars polars, MockOutput mockOutput) {
public MockRace(BoatDataSource boatDataSource, RaceDataSource raceDataSource, RegattaDataSource regattaDataSource, Polars polars, LatestMessages latestMessages) {
super(boatDataSource, raceDataSource, regattaDataSource);
super(boatDataSource, raceDataSource, regattaDataSource, latestMessages);
this.mockOutput = mockOutput;
this.boats = this.generateMockBoats(boatDataSource.getBoats(), raceDataSource.getParticipants(), polars);
@ -175,14 +170,20 @@ public class MockRace extends Race {
*/
private void parseIndividualMark(Mark mark) {
this.mockOutput.parseBoatLocation(
//Create message.
BoatLocation boatLocation = new BoatLocation(
mark.getSourceID(),
mark.getPosition().getLatitude(),
mark.getPosition().getLongitude(),
0,
0,
this.totalTimeElapsed + this.startTime
);
boatLocationSequenceNumber,
0, 0,
totalTimeElapsed + startTime);
//Iterates the sequence number.
boatLocationSequenceNumber++;
this.latestMessages.setBoatLocation(boatLocation);
}
@ -206,14 +207,19 @@ public class MockRace extends Race {
*/
private void parseIndividualBoatLocation(MockBoat boat) {
this.mockOutput.parseBoatLocation(
BoatLocation boatLocation = new BoatLocation(
boat.getSourceID(),
boat.getCurrentPosition().getLatitude(),
boat.getCurrentPosition().getLongitude(),
boatLocationSequenceNumber,
boat.getBearing().degrees(),
boat.getCurrentSpeed(),
startTime + totalTimeElapsed
);
startTime + totalTimeElapsed);
//Iterates the sequence number.
boatLocationSequenceNumber++;
this.latestMessages.setBoatLocation(boatLocation);
}
@ -272,7 +278,6 @@ public class MockRace extends Race {
boatStatuses.add(boatStatus);
}
//TODO REFACTOR for consistency, could send parameters to mockOutput instead of the whole racestatus. This will also fix the sequence number issue.
//Convert wind direction and speed to ints. //TODO this conversion should be done inside the racestatus class.
int windDirectionInt = AC35UnitConverter.encodeHeading(this.windDirection.degrees());
@ -283,12 +288,14 @@ public class MockRace extends Race {
System.currentTimeMillis(),
this.raceId,
this.getRaceStatusEnum().getValue(),
this.startTime, windDirectionInt,
this.startTime,
windDirectionInt,
windSpeedInt,
this.getRaceType().getValue(),
boatStatuses );
boatStatuses);
mockOutput.parseRaceStatus(raceStatus);
this.latestMessages.setRaceStatus(raceStatus);
}
@ -427,7 +434,6 @@ public class MockRace extends Race {
parseRaceStatus();
if (iters > 500) {
mockOutput.stop();
stop();
}
iters++;

@ -0,0 +1,142 @@
package network.Messages;
import java.util.HashMap;
import java.util.Map;
/**
* This class contains a set of the latest messages received (e.g., the latest RaceStatus, the latest BoatLocation for each boat, etc...).
*/
public class LatestMessages {
/**
* The latest RaceStatus message.
*/
private RaceStatus raceStatus;
/**
* A map of the last BoatStatus message received, for each boat.
*/
private final Map<Integer, BoatStatus> boatStatusMap = new HashMap<>();
/**
* A map of the last BoatLocation message received, for each boat.
*/
private final Map<Integer, BoatLocation> boatLocationMap = new HashMap<>();
/**
* The last AverageWind message received.
*/
private AverageWind averageWind;
/**
* The last CourseWinds message received.
*/
private CourseWinds courseWinds;
/**
* Ctor.
*/
public LatestMessages() {
}
/**
* Gets the latest RaceStatus message received.
* @return The latest RaceStatus message received.
*/
public RaceStatus getRaceStatus() {
return raceStatus;
}
/**
* Sets the latest RaceStatus message received.
* @param raceStatus The new RaceStatus message to store.
*/
public void setRaceStatus(RaceStatus raceStatus) {
this.raceStatus = raceStatus;
}
/**
* Returns the latest BoatStatus message received for a given boat.
* @param sourceID Source ID of the boat.
* @return The latest BoatStatus message for the specified boat.
*/
public BoatStatus getBoatStatus(int sourceID) {
return boatStatusMap.get(sourceID);
}
/**
* Inserts a BoatStatus message for a given boat.
* @param boatStatus The BoatStatus message to set.
*/
public void setBoatStatus(BoatStatus boatStatus) {
boatStatusMap.put(boatStatus.getSourceID(), boatStatus);
}
/**
* Returns the latest BoatLocation message received for a given boat.
* @param sourceID Source ID of the boat.
* @return The latest BoatLocation message for the specified boat.
*/
public BoatLocation getBoatLocation(int sourceID) {
return boatLocationMap.get(sourceID);
}
/**
* Inserts a BoatLocation message for a given boat.
* @param boatLocation The BoatLocation message to set.
*/
public void setBoatLocation(BoatLocation boatLocation) {
//TODO should compare the sequence number of the new boatLocation with the existing boatLocation for this boat (if it exists), and use the newer one.
boatLocationMap.put(boatLocation.getSourceID(), boatLocation);
}
/**
* Gets the latest AverageWind message received.
* @return The latest AverageWind message received.
*/
public AverageWind getAverageWind() {
return averageWind;
}
/**
* Sets the latest AverageWind message received.
* @param averageWind The new AverageWind message to store.
*/
public void setAverageWind(AverageWind averageWind) {
this.averageWind = averageWind;
}
/**
* Gets the latest CourseWinds message received.
* @return The latest CourseWinds message received.
*/
public CourseWinds getCourseWinds() {
return courseWinds;
}
/**
* Sets the latest CourseWinds message received.
* @param courseWinds The new CourseWinds message to store.
*/
public void setCourseWinds(CourseWinds courseWinds) {
this.courseWinds = courseWinds;
}
public Map<Integer, BoatLocation> getBoatLocationMap() {
return boatLocationMap;
}
}

@ -84,6 +84,13 @@ public class Angle implements Comparable<Angle> {
}
@Override
public int hashCode() {
return Double.hashCode(this.degrees);
}
/**
* Returns an int describing the ordering between this angle object, and another.
* @param o Other angle to compare to.

@ -335,12 +335,12 @@ public class GPSCoordinate {
//Get the bearing between two adjacent points.
Bearing bearing = GPSCoordinate.calculateBearing(firstPoint, secondPoint);
//Calculate angle perpendicular to bearing.
Bearing perpendicularBearing = Bearing.fromDegrees(bearing.degrees() + (90d * clockwiseScaleFactor));
//Calculate angle perpindicular to bearing.
Bearing perpindicularBearing = Bearing.fromDegrees(bearing.degrees() + (90d * clockwiseScaleFactor));
//Translate both first and second point by 50m, using this bearing. These form our inwards shifted edge.
GPSCoordinate firstPointTranslated = GPSCoordinate.calculateNewPosition(firstPoint, shrinkDistance, Azimuth.fromBearing(perpendicularBearing));
GPSCoordinate secondPointTranslated = GPSCoordinate.calculateNewPosition(secondPoint, shrinkDistance, Azimuth.fromBearing(perpendicularBearing));
GPSCoordinate firstPointTranslated = GPSCoordinate.calculateNewPosition(firstPoint, shrinkDistance, Azimuth.fromBearing(perpindicularBearing));
GPSCoordinate secondPointTranslated = GPSCoordinate.calculateNewPosition(secondPoint, shrinkDistance, Azimuth.fromBearing(perpindicularBearing));
//Add edge to list.
shrunkEdges.add(new Pair<>(firstPointTranslated, secondPointTranslated));
@ -355,12 +355,12 @@ public class GPSCoordinate {
//Get the bearing between two adjacent points.
Bearing bearing = GPSCoordinate.calculateBearing(firstPoint, secondPoint);
//Calculate angle perpendicular to bearing.
Bearing perpendicularBearing = Bearing.fromDegrees(bearing.degrees() + (90d * clockwiseScaleFactor));
//Calculate angle perpindicular to bearing.
Bearing perpindicularBearing = Bearing.fromDegrees(bearing.degrees() + (90d * clockwiseScaleFactor));
//Translate both first and second point by 50m, using this bearing. These form our inwards shifted edge.
GPSCoordinate firstPointTranslated = GPSCoordinate.calculateNewPosition(firstPoint, shrinkDistance, Azimuth.fromBearing(perpendicularBearing));
GPSCoordinate secondPointTranslated = GPSCoordinate.calculateNewPosition(secondPoint, shrinkDistance, Azimuth.fromBearing(perpendicularBearing));
GPSCoordinate firstPointTranslated = GPSCoordinate.calculateNewPosition(firstPoint, shrinkDistance, Azimuth.fromBearing(perpindicularBearing));
GPSCoordinate secondPointTranslated = GPSCoordinate.calculateNewPosition(secondPoint, shrinkDistance, Azimuth.fromBearing(perpindicularBearing));
//Add edge to list.
shrunkEdges.add(new Pair<>(firstPointTranslated, secondPointTranslated));

@ -5,6 +5,7 @@ import javafx.collections.FXCollections;
import mock.model.VMG;
import network.Messages.Enums.RaceStatusEnum;
import network.Messages.Enums.RaceTypeEnum;
import network.Messages.LatestMessages;
import shared.dataInput.BoatDataSource;
import shared.dataInput.RaceDataSource;
import shared.dataInput.RegattaDataSource;
@ -40,6 +41,18 @@ public abstract class Race implements Runnable {
*/
protected RegattaDataSource regattaDataSource;
/**
* The collection of latest race messages.
* Can be either read from or written to.
*/
protected LatestMessages latestMessages;
/**
* The sequence number of the latest boatLocation message sent or received.
*/
protected int boatLocationSequenceNumber = 1;
/**
* A list of compound marks in the race.
@ -102,14 +115,17 @@ public abstract class Race implements Runnable {
* @param boatDataSource Data source for boat related data (yachts and marker boats).
* @param raceDataSource Data source for race related data (participating boats, legs, etc...).
* @param regattaDataSource Data source for race related data (course name, location, timezone, etc...).
* @param latestMessages The collection of latest messages, which can be written to, or read from.
*/
public Race(BoatDataSource boatDataSource, RaceDataSource raceDataSource, RegattaDataSource regattaDataSource) {
public Race(BoatDataSource boatDataSource, RaceDataSource raceDataSource, RegattaDataSource regattaDataSource, LatestMessages latestMessages) {
//Keep a reference to data sources.
this.raceDataSource = raceDataSource;
this.boatDataSource = boatDataSource;
this.regattaDataSource = regattaDataSource;
this.latestMessages = latestMessages;
this.compoundMarks = raceDataSource.getCompoundMarks();

@ -11,10 +11,9 @@ import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
import seng302.Mock.StreamedCourse;
import seng302.Model.Boat;
import seng302.Model.RaceClock;
import seng302.VisualiserInput;
import visualiser.app.VisualiserInput;
import visualiser.model.RaceClock;
import visualiser.model.VisualiserBoat;
import java.io.IOException;
import java.net.Socket;
@ -35,18 +34,16 @@ public class StartController extends Controller implements Observer {
@FXML private Label raceTitleLabel;
@FXML private Label raceStartLabel;
@FXML private TableView<Boat> boatNameTable;
@FXML private TableColumn<Boat, String> boatNameColumn;
@FXML private TableColumn<Boat, String> boatCodeColumn;
@FXML private TableView<VisualiserBoat> boatNameTable;
@FXML private TableColumn<VisualiserBoat, String> boatNameColumn;
@FXML private TableColumn<VisualiserBoat, String> boatCodeColumn;
@FXML private Label timeZoneTime;
@FXML private Label timer;
@FXML private Label raceStatusLabel;
//@FXML Button fifteenMinButton;
private RaceClock raceClock;
private StreamedCourse raceData;
private int raceStat;
private VisualiserInput visualiserInput;
@ -80,8 +77,8 @@ public class StartController extends Controller implements Observer {
* Initiliases the tables that are to be shown on the pane
*/
private void initialiseTables() {
List<Boat> boats = raceData.getBoats();
ObservableList<Boat> observableBoats = FXCollections.observableArrayList(boats);
List<VisualiserBoat> boats = raceData.getBoats();
ObservableList<VisualiserBoat> observableBoats = FXCollections.observableArrayList(boats);
boatNameTable.setItems(observableBoats);
boatNameColumn.setCellValueFactory(cellData -> cellData.getValue().getName());

@ -1,8 +1,7 @@
package visualiser.app;
import javafx.application.Platform;
import network.Messages.*;
import org.xml.sax.SAXException;
import seng302.Networking.BinaryMessageDecoder;
import seng302.Networking.Exceptions.InvalidMessageException;
import javax.xml.parsers.ParserConfigurationException;
import java.io.DataInputStream;
@ -13,12 +12,9 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import static seng302.Networking.Utils.ByteConverter.bytesToShort;
/**
* TCP client which receives packets/messages from a race data source
* (e.g., mock source, official source), and exposes them to any observers.
* @see seng302.Mock.StreamedCourse
*/
public class VisualiserInput implements Runnable {
@ -30,8 +26,6 @@ public class VisualiserInput implements Runnable {
///The socket that we have connected to.
private Socket connectionSocket;
///Object to store parsed course data. //TODO comment?
private StreamedCourse course;
///The last RaceStatus message received.
private RaceStatus raceStatus;

Loading…
Cancel
Save