Merge branch 'develop' into 38b_LayLines

# Conflicts:
#	src/main/java/seng302/App.java
#	src/main/java/seng302/models/Yacht.java
#	src/main/java/seng302/models/stream/StreamParser.java
This commit is contained in:
Kusal Ekanayake
2017-05-25 14:16:55 +12:00
8 changed files with 57 additions and 41 deletions
+5 -7
View File
@@ -5,7 +5,6 @@ import javafx.fxml.FXMLLoader;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.stage.Stage; import javafx.stage.Stage;
import seng302.models.PolarTable;
import seng302.models.stream.StreamParser; import seng302.models.stream.StreamParser;
import seng302.models.stream.StreamReceiver; import seng302.models.stream.StreamReceiver;
import seng302.server.ServerThread; import seng302.server.ServerThread;
@@ -14,8 +13,6 @@ public class App extends Application {
@Override @Override
public void start(Stage primaryStage) throws Exception { public void start(Stage primaryStage) throws Exception {
PolarTable.parsePolarFile(getClass().getResource("/config/acc_polars.csv").getFile());
Parent root = FXMLLoader.load(getClass().getResource("/views/MainView.fxml")); Parent root = FXMLLoader.load(getClass().getResource("/views/MainView.fxml"));
primaryStage.setTitle("RaceVision"); primaryStage.setTitle("RaceVision");
primaryStage.setScene(new Scene(root, 1530, 960)); primaryStage.setScene(new Scene(root, 1530, 960));
@@ -57,7 +54,7 @@ public class App extends Application {
sr = new StreamReceiver("localhost", 4949, "RaceStream"); sr = new StreamReceiver("localhost", 4949, "RaceStream");
break; break;
case "staffserver": case "staffserver":
sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4942, "RaceStream"); sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941, "RaceStream");
break; break;
case "official": case "official":
sr = new StreamReceiver("livedata.americascup.com", 4941, "RaceStream"); sr = new StreamReceiver("livedata.americascup.com", 4941, "RaceStream");
@@ -65,11 +62,11 @@ public class App extends Application {
} }
} }
//Change the StreamReceiver in this else block to change the default data source. //Change the StreamReceiver in this else block to change the default data source.
else { else{
// sr = new StreamReceiver("localhost", 4949, "RaceStream"); sr = new StreamReceiver("localhost", 4949, "RaceStream");
// sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941, "RaceStream"); // sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941, "RaceStream");
sr = new StreamReceiver("livedata.americascup.com", 4941, "RaceStream");
// sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4942, "RaceStream"); // sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4942, "RaceStream");
// sr = new StreamReceiver("livedata.americascup.com", 4941, "RaceStream");
} }
sr.start(); sr.start();
@@ -77,6 +74,7 @@ public class App extends Application {
streamParser.start(); streamParser.start();
launch(args); launch(args);
} }
} }
@@ -214,7 +214,7 @@ public class CanvasController {
for (BoatGroup boatGroup : boatGroups) { for (BoatGroup boatGroup : boatGroups) {
// some raceObjects will have multiple ID's (for instance gate marks) // some raceObjects will have multiple ID's (for instance gate marks)
//checking if the current "ID" has any updates associated with it //checking if the current "ID" has any updates associated with it
if (StreamParser.boatPositions.containsKey(boatGroup.getRaceId())) { if (StreamParser.boatLocations.containsKey(boatGroup.getRaceId())) {
if (boatGroup.isStopped()) { if (boatGroup.isStopped()) {
updateBoatGroup(boatGroup); updateBoatGroup(boatGroup);
} }
@@ -223,7 +223,7 @@ public class CanvasController {
} }
for (MarkGroup markGroup : markGroups) { for (MarkGroup markGroup : markGroups) {
for (Long id : markGroup.getRaceIds()) { for (Long id : markGroup.getRaceIds()) {
if (StreamParser.markPositions.containsKey(id)) { if (StreamParser.markLocations.containsKey(id)) {
updateMarkGroup(id, markGroup); updateMarkGroup(id, markGroup);
} }
} }
@@ -240,7 +240,7 @@ public class CanvasController {
} }
private void updateBoatGroup(BoatGroup boatGroup) { private void updateBoatGroup(BoatGroup boatGroup) {
PriorityBlockingQueue<BoatPositionPacket> movementQueue = StreamParser.boatPositions.get(boatGroup.getRaceId()); PriorityBlockingQueue<BoatPositionPacket> movementQueue = StreamParser.boatLocations.get(boatGroup.getRaceId());
// giving the movementQueue a 5 packet buffer to account for slightly out of order packets // giving the movementQueue a 5 packet buffer to account for slightly out of order packets
if (movementQueue.size() > 0){ if (movementQueue.size() > 0){
try { try {
@@ -256,7 +256,7 @@ public class CanvasController {
} }
void updateMarkGroup (long raceId, MarkGroup markGroup) { void updateMarkGroup (long raceId, MarkGroup markGroup) {
PriorityBlockingQueue<BoatPositionPacket> movementQueue = StreamParser.markPositions.get(raceId); PriorityBlockingQueue<BoatPositionPacket> movementQueue = StreamParser.markLocations.get(raceId);
if (movementQueue.size() > 0){ if (movementQueue.size() > 0){
try { try {
BoatPositionPacket positionPacket = movementQueue.take(); BoatPositionPacket positionPacket = movementQueue.take();
@@ -34,6 +34,6 @@ public class Controller implements Initializable {
public void initialize(URL location, ResourceBundle resources) { public void initialize(URL location, ResourceBundle resources) {
contentPane.getStylesheets().add(getClass().getResource("/css/master.css").toString()); contentPane.getStylesheets().add(getClass().getResource("/css/master.css").toString());
setContentPane("/views/StartScreenView.fxml"); setContentPane("/views/StartScreenView.fxml");
StreamParser.boatPositions.clear(); StreamParser.boatLocations.clear();
} }
} }
@@ -74,7 +74,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
@FXML @FXML
private CanvasController includedCanvasController; private CanvasController includedCanvasController;
private ArrayList<Yacht> startingBoats = new ArrayList<>(); private static ArrayList<Yacht> startingBoats = new ArrayList<>();
private boolean displayFps; private boolean displayFps;
private Timeline timerTimeline; private Timeline timerTimeline;
private Stage stage; private Stage stage;
@@ -227,7 +227,6 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
} }
}); });
// Adds the new data series to the sparkline (and set the colour of the series) // Adds the new data series to the sparkline (and set the colour of the series)
raceSparkLine.setCreateSymbols(false); raceSparkLine.setCreateSymbols(false);
positions.stream().filter(spark -> !raceSparkLine.getData().contains(spark)).forEach(spark -> { positions.stream().filter(spark -> !raceSparkLine.getData().contains(spark)).forEach(spark -> {
@@ -138,7 +138,7 @@ public class StartScreenController implements Initializable {
} }
public void switchToRaceView() { public void switchToRaceView() {
StreamParser.boatPositions.clear(); StreamParser.boatLocations.clear();
switchedToRaceView = true; switchedToRaceView = true;
setContentPane("/views/RaceView.fxml"); setContentPane("/views/RaceView.fxml");
} }
+1
View File
@@ -6,6 +6,7 @@ import seng302.controllers.RaceViewController;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import seng302.models.stream.StreamParser;
import seng302.models.stream.XMLParser.RaceXMLObject.Corner; import seng302.models.stream.XMLParser.RaceXMLObject.Corner;
/** /**
@@ -9,7 +9,6 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.TreeMap; import java.util.TreeMap;
@@ -35,8 +34,8 @@ import seng302.models.stream.packets.StreamPacket;
*/ */
public class StreamParser extends Thread { public class StreamParser extends Thread {
public static ConcurrentHashMap<Long, PriorityBlockingQueue<BoatPositionPacket>> markPositions = new ConcurrentHashMap<>(); public static ConcurrentHashMap<Long, PriorityBlockingQueue<BoatPositionPacket>> markLocations = new ConcurrentHashMap<>();
public static ConcurrentHashMap<Long, PriorityBlockingQueue<BoatPositionPacket>> boatPositions = new ConcurrentHashMap<>(); public static ConcurrentHashMap<Long, PriorityBlockingQueue<BoatPositionPacket>> boatLocations = new ConcurrentHashMap<>();
private String threadName; private String threadName;
private Thread t; private Thread t;
private static boolean newRaceXmlReceived = false; private static boolean newRaceXmlReceived = false;
@@ -46,7 +45,7 @@ public class StreamParser extends Thread {
private static boolean streamStatus = false; private static boolean streamStatus = false;
private static long timeSinceStart = -1; private static long timeSinceStart = -1;
private static Map<Integer, Yacht> boats = new ConcurrentHashMap<>(); private static Map<Integer, Yacht> boats = new ConcurrentHashMap<>();
private static Map<Long, Yacht> boatsPos = new ConcurrentSkipListMap<>(); private static Map<Integer, Yacht> boatsPos = new ConcurrentSkipListMap<>();
private static double windDirection = 0; private static double windDirection = 0;
private static Double windSpeed = 0d; private static Double windSpeed = 0d;
private static Long currentTimeLong; private static Long currentTimeLong;
@@ -151,6 +150,7 @@ public class StreamParser extends Thread {
} }
} catch (NullPointerException e) { } catch (NullPointerException e) {
System.out.println("Error parsing packet"); System.out.println("Error parsing packet");
e.printStackTrace();
} }
} }
@@ -225,13 +225,12 @@ public class StreamParser extends Thread {
int noBoats = payload[22]; int noBoats = payload[22];
int raceType = payload[23]; int raceType = payload[23];
boatsPos = new TreeMap<>();
for (int i = 0; i < noBoats; i++) { for (int i = 0; i < noBoats; i++) {
long boatStatusSourceID = bytesToLong( long boatStatusSourceID = bytesToLong(
Arrays.copyOfRange(payload, 24 + (i * 20), 28 + (i * 20))); Arrays.copyOfRange(payload, 24 + (i * 20), 28 + (i * 20)));
Yacht boat = boats.get((int) boatStatusSourceID); Yacht boat = boats.get((int) boatStatusSourceID);
boat.setBoatStatus((int) payload[28 + (i * 20)]); boat.setBoatStatus((int) payload[28 + (i * 20)]);
boat.setLegNumber((int) payload[29 + (i * 20)]); setBoatLegPosition(boat, (int) payload[29 + (i * 20)]);
boat.setPenaltiesAwarded((int) payload[30 + (i * 20)]); boat.setPenaltiesAwarded((int) payload[30 + (i * 20)]);
boat.setPenaltiesServed((int) payload[31 + (i * 20)]); boat.setPenaltiesServed((int) payload[31 + (i * 20)]);
Long estTimeAtNextMark = bytesToLong( Long estTimeAtNextMark = bytesToLong(
@@ -240,7 +239,7 @@ public class StreamParser extends Thread {
Long estTimeAtFinish = bytesToLong( Long estTimeAtFinish = bytesToLong(
Arrays.copyOfRange(payload, 38 + (i * 20), 44 + (i * 20))); Arrays.copyOfRange(payload, 38 + (i * 20), 44 + (i * 20)));
boat.setEstimateTimeAtFinish(estTimeAtFinish); boat.setEstimateTimeAtFinish(estTimeAtFinish);
boatsPos.put(estTimeAtFinish, boat); // boatsPos.put(estTimeAtFinish, boat);
// String boatStatus = "SourceID: " + boatStatusSourceID; // String boatStatus = "SourceID: " + boatStatusSourceID;
// boatStatus += "\nBoat Status: " + (int)payload[28 + (i * 20)]; // boatStatus += "\nBoat Status: " + (int)payload[28 + (i * 20)];
// boatStatus += "\nLegNumber: " + (int)payload[29 + (i * 20)]; // boatStatus += "\nLegNumber: " + (int)payload[29 + (i * 20)];
@@ -250,16 +249,34 @@ public class StreamParser extends Thread {
// boatStatus += "\nEstTimeAtFinish: " + bytesToLong(Arrays.copyOfRange(payload,37 + (i * 20),43+ (i * 20))); // boatStatus += "\nEstTimeAtFinish: " + bytesToLong(Arrays.copyOfRange(payload,37 + (i * 20),43+ (i * 20)));
// boatStatuses.add(boatStatus); // boatStatuses.add(boatStatus);
} }
if (isRaceStarted()) { // if (isRaceStarted()) {
int pos = 1; // int pos = 1;
for (Yacht yacht : boatsPos.values()) { // for (Yacht yacht : boatsPos.values()) {
yacht.setPosition(String.valueOf(pos)); // yacht.setPosition(String.valueOf(pos));
pos++; // pos++;
} // }
} else { // } else {
for (Yacht yacht : boatsPos.values()) { // for (Yacht yacht : boatsPos.values()) {
yacht.setPosition("-"); // yacht.setPosition("-");
// }
// }
}
private static void setBoatLegPosition(Yacht updatingBoat, Integer leg){
Integer placing = 1;
if (leg != updatingBoat.getLegNumber() && (raceStarted || raceFinished)) {
for (Yacht boat : boats.values()) {
if (boat.getLegNumber() != null && leg <= boat.getLegNumber()){
placing += 1;
}
} }
updatingBoat.setPosition(placing.toString());
updatingBoat.setLegNumber(leg);
boatsPos.putIfAbsent(placing, updatingBoat);
boatsPos.replace(placing, updatingBoat);
} else if(updatingBoat.getLegNumber() == null){
updatingBoat.setPosition("1");
updatingBoat.setLegNumber(leg);
} }
} }
@@ -403,9 +420,9 @@ public class StreamParser extends Thread {
BoatPositionPacket boatPacket = new BoatPositionPacket(boatId, timeValid, lat, lon, BoatPositionPacket boatPacket = new BoatPositionPacket(boatId, timeValid, lat, lon,
heading, groundSpeed); heading, groundSpeed);
//add a new priority que to the boatPositions HashMap //add a new priority que to the boatLocations HashMap
if (!boatPositions.containsKey(boatId)) { if (!boatLocations.containsKey(boatId)) {
boatPositions.put(boatId, boatLocations.put(boatId,
new PriorityBlockingQueue<>(256, new Comparator<BoatPositionPacket>() { new PriorityBlockingQueue<>(256, new Comparator<BoatPositionPacket>() {
@Override @Override
public int compare(BoatPositionPacket p1, BoatPositionPacket p2) { public int compare(BoatPositionPacket p1, BoatPositionPacket p2) {
@@ -413,14 +430,14 @@ public class StreamParser extends Thread {
} }
})); }));
} }
boatPositions.get(boatId).put(boatPacket); boatLocations.get(boatId).put(boatPacket);
} else if (deviceType == 3) { } else if (deviceType == 3) {
BoatPositionPacket markPacket = new BoatPositionPacket(boatId, timeValid, lat, lon, BoatPositionPacket markPacket = new BoatPositionPacket(boatId, timeValid, lat, lon,
heading, groundSpeed); heading, groundSpeed);
//add a new priority que to the boatPositions HashMap //add a new priority que to the boatLocations HashMap
if (!markPositions.containsKey(boatId)) { if (!markLocations.containsKey(boatId)) {
markPositions.put(boatId, markLocations.put(boatId,
new PriorityBlockingQueue<>(256, new Comparator<BoatPositionPacket>() { new PriorityBlockingQueue<>(256, new Comparator<BoatPositionPacket>() {
@Override @Override
public int compare(BoatPositionPacket p1, BoatPositionPacket p2) { public int compare(BoatPositionPacket p1, BoatPositionPacket p2) {
@@ -428,7 +445,7 @@ public class StreamParser extends Thread {
} }
})); }));
} }
markPositions.get(boatId).put(markPacket); markLocations.get(boatId).put(markPacket);
} }
} }
@@ -615,7 +632,8 @@ public class StreamParser extends Thread {
* *
* @return a map of time to finish and boat. * @return a map of time to finish and boat.
*/ */
public static Map<Long, Yacht> getBoatsPos() { public static Map<Integer, Yacht> getBoatsPos() {
return boatsPos; return boatsPos;
} }
+1 -1
View File
@@ -25,7 +25,7 @@
<Label layoutX="11.0" layoutY="14.0" text="Timer" textFill="WHITE" /> <Label layoutX="11.0" layoutY="14.0" text="Timer" textFill="WHITE" />
<Label layoutX="11.0" layoutY="88.0" text="Wind direction" textFill="WHITE" /> <Label layoutX="11.0" layoutY="88.0" text="Wind direction" textFill="WHITE" />
<Circle fx:id="windBackgroundCircle" blendMode="DARKEN" fill="#3dcdc8" layoutX="110.0" layoutY="166.0" radius="35.0" stroke="#d7d7d7" strokeType="INSIDE" strokeWidth="3.0" /> <Circle fx:id="windBackgroundCircle" blendMode="DARKEN" fill="#3dcdc8" layoutX="110.0" layoutY="166.0" radius="35.0" stroke="#d7d7d7" strokeType="INSIDE" strokeWidth="3.0" />
<Text fx:id="windArrowText" fill="#a8a8a8" layoutX="86.0" layoutY="186.0" strokeType="OUTSIDE" strokeWidth="0.0" text=""> <Text fx:id="windArrowText" fill="#a8a8a8" layoutX="86.0" layoutY="186.0" strokeType="OUTSIDE" strokeWidth="0.0" text="">
<font> <font>
<Font name="AdobeArabic-Regular" size="55.0" /> <Font name="AdobeArabic-Regular" size="55.0" />
</font> </font>