Merge remote-tracking branch 'origin/develop' into 38a_Select_Boats

# Conflicts:
#	src/main/java/seng302/controllers/RaceViewController.java
#	src/main/java/seng302/models/BoatGroup.java
This commit is contained in:
William Muir
2017-05-17 09:53:18 +12:00
15 changed files with 337 additions and 180 deletions
+2 -4
View File
@@ -9,8 +9,8 @@ import seng302.models.parsers.StreamParser;
import seng302.models.parsers.StreamReceiver;
import seng302.server.ServerThread;
public class App extends Application
{
public class App extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("/views/MainView.fxml"));
@@ -73,8 +73,6 @@ public class App extends Application
launch(args);
}
}
@@ -240,6 +240,17 @@ public class CanvasController {
}
}
}
checkForCourseChanges();
}
private void checkForCourseChanges() {
if (StreamParser.isNewRaceXmlReceived()){
gc.setFill(Color.SKYBLUE);
gc.fillRect(0,0, CANVAS_WIDTH, CANVAS_HEIGHT);
gc.restore();
addRaceBorder();
canvas.toBack();
}
}
private void move(long id, RaceObject raceObject){
@@ -345,6 +356,8 @@ public class CanvasController {
* Calculates x and y location for every marker that fits it to the canvas the race will be drawn on.
*/
private void fitMarksToCanvas() {
//Check is called once to avoid unnecessarily change the course limits once the race is running
StreamParser.isNewRaceXmlReceived();
findMinMaxPoint();
double minLonToMaxLon = scaleRaceExtremities();
calculateReferencePointLocation(minLonToMaxLon);
@@ -58,7 +58,6 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
private ArrayList<Yacht> startingBoats = new ArrayList<>();
private boolean displayFps;
private Timeline timerTimeline;
private Map<Yacht, TimelineInfo> timelineInfos = new HashMap<>();
private Race race;
private Stage stage;
@@ -91,7 +90,6 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
/**
* The important annotations have been changed, update this view
*
* @param importantAnnotationsState The current state of the selected annotations
*/
public void importantAnnotationsChanged(ImportantAnnotationsState importantAnnotationsState) {
@@ -344,7 +342,6 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
/**
* Display the important annotations for a specific BoatGroup
*
* @param bg The boat group to set the annotations for
*/
private void setBoatGroupImportantAnnotations(BoatGroup bg) {
@@ -371,6 +368,18 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
} else {
bg.setWakeVisible(false);
}
if (importantAnnotations.getAnnotationState(Annotation.ESTTIMETONEXTMARK)) {
bg.setEstTimeToNextMarkObjectVisible(true);
} else {
bg.setEstTimeToNextMarkObjectVisible(false);
}
if (importantAnnotations.getAnnotationState(Annotation.LEGTIME)) {
bg.setLegTimeObjectVisible(true);
} else {
bg.setLegTimeObjectVisible(false);
}
}
private void setAnnotations(Integer annotationLevel) {
@@ -382,6 +391,8 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
BoatGroup bg = (BoatGroup) ro;
bg.setTeamNameObjectVisible(false);
bg.setVelocityObjectVisible(false);
bg.setEstTimeToNextMarkObjectVisible(false);
bg.setLegTimeObjectVisible(false);
bg.setLineGroupVisible(false);
bg.setWakeVisible(false);
}
@@ -403,6 +414,8 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
BoatGroup bg = (BoatGroup) ro;
bg.setTeamNameObjectVisible(true);
bg.setVelocityObjectVisible(true);
bg.setEstTimeToNextMarkObjectVisible(true);
bg.setLegTimeObjectVisible(true);
bg.setLineGroupVisible(true);
bg.setWakeVisible(true);
}
@@ -7,5 +7,7 @@ public enum Annotation {
SPEED,
WAKE,
TRACK,
NAME
NAME,
ESTTIMETONEXTMARK,
LEGTIME
}
@@ -15,6 +15,7 @@ import java.util.Map;
import java.util.ResourceBundle;
public class ImportantAnnotationController implements Initializable {
/*
* JavaFX Outlets
*/
@@ -30,6 +31,12 @@ public class ImportantAnnotationController implements Initializable {
@FXML
private CheckBox boatNameSelect;
@FXML
private CheckBox boatEstTimeToNextMarkSelect;
@FXML
private CheckBox boatElapsedTimeSelect;
@FXML
private AnchorPane annotationSelectWindow;
@@ -49,6 +56,7 @@ public class ImportantAnnotationController implements Initializable {
/**
* Sets whether or not an annotation is considered important, then
* sends an update to the delegate
*
* @param annotation The annotation
* @param isSet True if annotation is important
*/
@@ -67,6 +75,7 @@ public class ImportantAnnotationController implements Initializable {
/**
* Load the current state of the 'important annotations'
*
* @param currentState hashmap containing the states of each annotation
*/
public void loadState(ImportantAnnotationsState currentState) {
@@ -76,21 +85,34 @@ public class ImportantAnnotationController implements Initializable {
for (Annotation annotation : importantAnnotationsState.getAnnotations()) {
switch (annotation) {
case WAKE:
boatWakeSelect.setSelected(importantAnnotationsState.getAnnotationState(annotation));
boatWakeSelect
.setSelected(importantAnnotationsState.getAnnotationState(annotation));
break;
case SPEED:
boatSpeedSelect.setSelected(importantAnnotationsState.getAnnotationState(annotation));
boatSpeedSelect
.setSelected(importantAnnotationsState.getAnnotationState(annotation));
break;
case TRACK:
boatTrackSelect.setSelected(importantAnnotationsState.getAnnotationState(annotation));
boatTrackSelect
.setSelected(importantAnnotationsState.getAnnotationState(annotation));
break;
case NAME:
boatNameSelect.setSelected(importantAnnotationsState.getAnnotationState(annotation));
boatNameSelect
.setSelected(importantAnnotationsState.getAnnotationState(annotation));
break;
case ESTTIMETONEXTMARK:
boatEstTimeToNextMarkSelect
.setSelected(importantAnnotationsState.getAnnotationState(annotation));
break;
case LEGTIME:
boatElapsedTimeSelect
.setSelected(importantAnnotationsState.getAnnotationState(annotation));
default:
break;
}
@@ -99,15 +121,24 @@ public class ImportantAnnotationController implements Initializable {
/**
* View did load
*
* @param location .
* @param resources .
*/
@Override
public void initialize(URL location, ResourceBundle resources) {
boatWakeSelect.setOnAction(event -> setAnnotation(Annotation.WAKE, boatWakeSelect.isSelected()));
boatSpeedSelect.setOnAction(event -> setAnnotation(Annotation.SPEED, boatSpeedSelect.isSelected()));
boatTrackSelect.setOnAction(event -> setAnnotation(Annotation.TRACK, boatTrackSelect.isSelected()));
boatNameSelect.setOnAction(event -> setAnnotation(Annotation.NAME, boatNameSelect.isSelected()));
boatWakeSelect
.setOnAction(event -> setAnnotation(Annotation.WAKE, boatWakeSelect.isSelected()));
boatSpeedSelect
.setOnAction(event -> setAnnotation(Annotation.SPEED, boatSpeedSelect.isSelected()));
boatTrackSelect
.setOnAction(event -> setAnnotation(Annotation.TRACK, boatTrackSelect.isSelected()));
boatNameSelect
.setOnAction(event -> setAnnotation(Annotation.NAME, boatNameSelect.isSelected()));
boatEstTimeToNextMarkSelect.setOnAction(event -> setAnnotation(Annotation.ESTTIMETONEXTMARK,
boatEstTimeToNextMarkSelect.isSelected()));
boatElapsedTimeSelect.setOnAction(
event -> setAnnotation(Annotation.LEGTIME, boatElapsedTimeSelect.isSelected()));
closeButton.setOnAction(event -> stage.close());
}
+65 -36
View File
@@ -1,17 +1,17 @@
package seng302.models;
import javafx.event.EventHandler;
import javafx.geometry.Point2D;
import javafx.scene.Group;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.shape.Polygon;
import javafx.scene.text.Text;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
import seng302.controllers.RaceViewController;
import seng302.models.parsers.StreamParser;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
@@ -27,9 +27,13 @@ public class BoatGroup extends RaceObject {
//Constants for drawing
private static final double TEAMNAME_X_OFFSET = 10d;
private static final double TEAMNAME_Y_OFFSET = -15d;
private static final double TEAMNAME_Y_OFFSET = -29d;
private static final double VELOCITY_X_OFFSET = 10d;
private static final double VELOCITY_Y_OFFSET = -5d;
private static final double VELOCITY_Y_OFFSET = -17d;
private static final double ESTTIMETONEXTMARK_X_OFFSET = 10d;
private static final double ESTTIMETONEXTMARK_Y_OFFSET = -5d;
private static final double LEGTIME_X_OFFSET = 10d;
private static final double LEGTIME_Y_OFFSET = 7d;
private static final double BOAT_HEIGHT = 15d;
private static final double BOAT_WIDTH = 10d;
//Variables for boat logic.
@@ -42,8 +46,9 @@ public class BoatGroup extends RaceObject {
private Polygon boatPoly;
private Text teamNameObject;
private Text velocityObject;
private Text estTimeToNextMarkObject;
private Text legTimeObject;
private Wake wake;
private boolean isSelected = true; //Boats annotations are visible by default at the start
//Handles boat moving when connecting to a stream
private boolean setToInitialLocation = false;
private boolean destinationSet;
@@ -90,12 +95,20 @@ public class BoatGroup extends RaceObject {
private void initChildren(Color color, double... points) {
boatPoly = new Polygon(points);
boatPoly.setFill(color);
boatPoly.setOnMouseEntered(event -> boatPoly.setFill(Color.FLORALWHITE));
boatPoly.setOnMouseExited(event -> boatPoly.setFill(color));
boatPoly.setOnMouseClicked(event -> setIsSelected(!isSelected));
teamNameObject = new Text(boat.getShortName());
velocityObject = new Text(String.valueOf(boat.getVelocity()));
DateFormat format = new SimpleDateFormat("mm:ss");
String timeToNextMark = format
.format(boat.getEstimateTimeAtNextMark() - StreamParser.getCurrentTimeLong());
estTimeToNextMarkObject = new Text("Next mark: " + timeToNextMark);
if (boat.getMarkRoundingTime() != null) {
String elapsedTime = format
.format(StreamParser.getCurrentTimeLong() - boat.getMarkRoundingTime());
legTimeObject = new Text("Last mark: " + elapsedTime);
} else {
legTimeObject = new Text("Last mark: -");
}
teamNameObject.setX(TEAMNAME_X_OFFSET);
teamNameObject.setY(TEAMNAME_Y_OFFSET);
@@ -106,8 +119,19 @@ public class BoatGroup extends RaceObject {
velocityObject.relocate(velocityObject.getX(), velocityObject.getY());
destinationSet = false;
estTimeToNextMarkObject.setX(ESTTIMETONEXTMARK_X_OFFSET);
estTimeToNextMarkObject.setY(ESTTIMETONEXTMARK_Y_OFFSET);
estTimeToNextMarkObject
.relocate(estTimeToNextMarkObject.getX(), estTimeToNextMarkObject.getY());
legTimeObject.setX(LEGTIME_X_OFFSET);
legTimeObject.setY(LEGTIME_Y_OFFSET);
legTimeObject.relocate(legTimeObject.getX(), legTimeObject.getY());
wake = new Wake(0, -BOAT_HEIGHT);
super.getChildren().addAll(teamNameObject, velocityObject, boatPoly);
super.getChildren()
.addAll(teamNameObject, velocityObject, boatPoly, estTimeToNextMarkObject,
legTimeObject);
}
/**
@@ -136,6 +160,10 @@ public class BoatGroup extends RaceObject {
teamNameObject.setLayoutY(teamNameObject.getLayoutY() + dy);
velocityObject.setLayoutX(velocityObject.getLayoutX() + dx);
velocityObject.setLayoutY(velocityObject.getLayoutY() + dy);
estTimeToNextMarkObject.setLayoutX(estTimeToNextMarkObject.getLayoutX() + dx);
estTimeToNextMarkObject.setLayoutY(estTimeToNextMarkObject.getLayoutY() + dy);
legTimeObject.setLayoutX(legTimeObject.getLayoutX() + dx);
legTimeObject.setLayoutY(legTimeObject.getLayoutY() + dy);
wake.setLayoutX(wake.getLayoutX() + dx);
wake.setLayoutY(wake.getLayoutY() + dy);
rotateTo(rotation + currentRotation);
@@ -166,6 +194,10 @@ public class BoatGroup extends RaceObject {
teamNameObject.setLayoutY(y);
velocityObject.setLayoutX(x);
velocityObject.setLayoutY(y);
estTimeToNextMarkObject.setLayoutX(x);
estTimeToNextMarkObject.setLayoutY(y);
legTimeObject.setLayoutX(x);
legTimeObject.setLayoutY(y);
wake.setLayoutX(x);
wake.setLayoutY(y);
wake.rotate(currentRotation);
@@ -196,7 +228,7 @@ public class BoatGroup extends RaceObject {
boatPoly.getLayoutY()
);
l.getStrokeDashArray().setAll(3d, 7d);
l.setStroke(boat.getColour());
l.setStroke(boatPoly.getFill());
lineGroup.getChildren().add(l);
}
if (destinationSet) { //Only begin drawing after the first destination is set
@@ -248,6 +280,19 @@ public class BoatGroup extends RaceObject {
boat.getVelocity());
}
velocityObject.setText(String.format("%.2f m/s", boat.getVelocity()));
DateFormat format = new SimpleDateFormat("mm:ss");
// estimate time to next mark
String timeToNextMark = format
.format(boat.getEstimateTimeAtNextMark() - StreamParser.getCurrentTimeLong());
estTimeToNextMarkObject.setText("Next mark: " + timeToNextMark);
// elapsed time
if (boat.getMarkRoundingTime() != null) {
String elapsedTime = format
.format(StreamParser.getCurrentTimeLong() - boat.getMarkRoundingTime());
legTimeObject.setText("Last mark: " + elapsedTime);
} else {
legTimeObject.setText("Last mark: -");
}
} else {
setToInitialLocation = true;
rotationalGoal = rotation;
@@ -304,10 +349,6 @@ public class BoatGroup extends RaceObject {
wake.rotate(rotationalGoal);
}
public void paintBoat(Color color) {
boatPoly.setFill(color);
}
public void setTeamNameObjectVisible(Boolean visible) {
teamNameObject.setVisible(visible);
}
@@ -316,6 +357,14 @@ public class BoatGroup extends RaceObject {
velocityObject.setVisible(visible);
}
public void setEstTimeToNextMarkObjectVisible(Boolean visible) {
estTimeToNextMarkObject.setVisible(visible);
}
public void setLegTimeObjectVisible(Boolean visible) {
legTimeObject.setVisible(visible);
}
public void setLineGroupVisible(Boolean visible) {
lineGroup.setVisible(visible);
}
@@ -328,21 +377,6 @@ public class BoatGroup extends RaceObject {
return boat;
}
/**
* This function sets the boats isSelected property AS WELL as actually acting upon the value of
* that selection. (Painting or not painting annotations)
*
* @param isSelected A Boolean indicating whether or not the boat is selected
*/
public void setIsSelected(Boolean isSelected) {
this.isSelected = isSelected;
setTeamNameObjectVisible(isSelected);
setVelocityObjectVisible(isSelected);
setLineGroupVisible(isSelected);
setWakeVisible(isSelected);
paintBoat((isSelected) ? Color.WHITE : boat.getColour());
}
/**
* Returns true if this BoatGroup contains at least one of the given IDs.
*
@@ -376,7 +410,7 @@ public class BoatGroup extends RaceObject {
*/
public Group getLowPriorityAnnotations() {
Group group = new Group();
group.getChildren().addAll(wake, lineGroup, teamNameObject, velocityObject);
group.getChildren().addAll(wake, lineGroup);
return group;
}
@@ -401,9 +435,4 @@ public class BoatGroup extends RaceObject {
}
});
}
@Override
public String toString() {
return boat.toString();
}
}
+7 -5
View File
@@ -12,9 +12,9 @@ import java.text.SimpleDateFormat;
* also done outside Boat class because some old variables are not used anymore.
*/
public class Yacht {
// Used in boat group
private Color colour;
private double velocity;
private Integer markLastPast;
private String boatType;
private Integer sourceID;
@@ -30,6 +30,8 @@ public class Yacht {
private Long estimateTimeAtNextMark;
private Long estimateTimeAtFinish;
private String position;
// Mark rounding
private Long markRoundingTime;
/**
* Used in EventTest and RaceTest.
@@ -157,12 +159,12 @@ public class Yacht {
this.velocity = velocity;
}
public Integer getMarkLastPast() {
return markLastPast;
public Long getMarkRoundingTime() {
return markRoundingTime;
}
public void setMarkLastPast(Integer markLastPast) {
this.markLastPast = markLastPast;
public void setMarkRoundingTime(Long markRoundingTime) {
this.markRoundingTime = markRoundingTime;
}
@Override
@@ -1,53 +0,0 @@
package seng302.models.parsers;
/**
* Created by Kusal on 4/24/2017.
*/
public enum PacketType {
HEARTBEAT,
RACE_STATUS,
DISPLAY_TEXT_MESSAGE,
XML_MESSAGE,
RACE_START_STATUS,
YACHT_EVENT_CODE,
YACHT_ACTION_CODE,
CHATTER_TEXT,
BOAT_LOCATION,
MARK_ROUNDING,
COURSE_WIND,
AVG_WIND,
OTHER;
static PacketType assignPacketType(int packetType){
switch(packetType){
case 1:
return HEARTBEAT;
case 12:
return RACE_STATUS;
case 20:
return DISPLAY_TEXT_MESSAGE;
case 26:
return XML_MESSAGE;
case 27:
return RACE_START_STATUS;
case 29:
return YACHT_EVENT_CODE;
case 31:
return YACHT_ACTION_CODE;
case 36:
return CHATTER_TEXT;
case 37:
return BOAT_LOCATION;
case 38:
return MARK_ROUNDING;
case 44:
return COURSE_WIND;
case 47:
return AVG_WIND;
default:
}
return OTHER;
}
}
@@ -1,44 +0,0 @@
package seng302.models.parsers;
/**
* Created by kre39 on 23/04/17.
*/
public class StreamPacket {
//Change int to an ENUM for the type
private PacketType type;
private long messageLength;
private long timeStamp;
private byte[] payload;
StreamPacket(int type, long messageLength, long timeStamp, byte[] payload) {
this.type = PacketType.assignPacketType(type);
this.messageLength = messageLength;
this.timeStamp = timeStamp;
this.payload = payload;
// System.out.println("type = " + this.type.toString());
//switch the packet type to deal with what ever specific packet you want to deal with
// if (this.type == PacketType.XML_MESSAGE){
// //System.out.println("--------");
// System.out.println(new String(payload));
// //StreamParser.parsePacket(this);
// }
}
PacketType getType() {
return type;
}
public long getMessageLength() {
return messageLength;
}
byte[] getPayload() {
return payload;
}
long getTimeStamp() {
return timeStamp;
}
}
@@ -30,6 +30,7 @@ public class StreamParser extends Thread{
public static ConcurrentHashMap<Long, PriorityBlockingQueue<BoatPositionPacket>> boatPositions = new ConcurrentHashMap<>();
private String threadName;
private Thread t;
private static boolean newRaceXmlReceived = false;
private static boolean raceStarted = false;
private static XMLParser xmlObject;
private static boolean raceFinished = false;
@@ -38,6 +39,7 @@ public class StreamParser extends Thread{
private static Map<Integer, Yacht> boats = new HashMap<>();
private static Map<Long, Yacht> boatsPos = new TreeMap<>();
private static double windDirection = 0;
private static Long currentTimeLong;
private static String currentTimeString;
private static boolean appRunning;
@@ -121,6 +123,7 @@ public class StreamParser extends Thread{
extractDisplayMessage(packet);
break;
case XML_MESSAGE:
newRaceXmlReceived = true;
extractXmlMessage(packet);
break;
case RACE_START_STATUS:
@@ -195,9 +198,11 @@ public class StreamParser extends Thread{
long currentTime = bytesToLong(Arrays.copyOfRange(payload,1,7));
long raceId = bytesToLong(Arrays.copyOfRange(payload,7,11));
int raceStatus = payload[11];
// System.out.println("raceStatus = " + raceStatus);
long expectedStartTime = bytesToLong(Arrays.copyOfRange(payload,12,18));
long windDir = bytesToLong(Arrays.copyOfRange(payload,18,20));
long windSpeed = bytesToLong(Arrays.copyOfRange(payload,20,22));
currentTimeLong = currentTime;
DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
if (xmlObject.getRegattaXML() != null) {
format.setTimeZone(TimeZone.getTimeZone(getTimeZoneString()));
@@ -205,7 +210,6 @@ public class StreamParser extends Thread{
}
long timeTillStart = ((new Date (expectedStartTime)).getTime() - (new Date (currentTime)).getTime())/1000;
if (timeTillStart > 0) {
timeSinceStart = timeTillStart;
//System.out.println("Time till start: " + timeTillStart + " Seconds");
@@ -222,10 +226,10 @@ public class StreamParser extends Thread{
//System.out.println("Time since start: " + -1 * timeTillStart + " Seconds");
timeSinceStart = timeTillStart;
}
long windDir = bytesToLong(Arrays.copyOfRange(payload,18,20));
double windDirFactor = 0x4000 / 90; //0x4000 is 90 degrees, 0x8000 is 180 degrees, etc...
windDirection = windDir / windDirFactor;
long windSpeed = bytesToLong(Arrays.copyOfRange(payload,20,22));
int noBoats = payload[22];
int raceType = payload[23];
// ArrayList<String> boatStatuses = new ArrayList<>();
@@ -235,11 +239,11 @@ public class StreamParser extends Thread{
Yacht boat = boats.get((int)(long) boatStatusSourceID);
boat.setBoatStatus((int)payload[28 + (i * 20)]);
boat.setLegNumber((int)payload[29 + (i * 20)]);
boat.setPenaltiesAwarded((int)payload[29 + (i * 20)]);
boat.setPenaltiesServed((int)payload[30 + (i * 20)]);
Long estTimeAtNextMark = bytesToLong(Arrays.copyOfRange(payload,31 + (i * 20),37+ (i * 20)));
boat.setPenaltiesAwarded((int)payload[30 + (i * 20)]);
boat.setPenaltiesServed((int)payload[31 + (i * 20)]);
Long estTimeAtNextMark = bytesToLong(Arrays.copyOfRange(payload,32 + (i * 20),38+ (i * 20)));
boat.setEstimateTimeAtNextMark(estTimeAtNextMark);
Long estTimeAtFinish = bytesToLong(Arrays.copyOfRange(payload,37 + (i * 20),43+ (i * 20)));
Long estTimeAtFinish = bytesToLong(Arrays.copyOfRange(payload,38 + (i * 20),44+ (i * 20)));
boat.setEstimateTimeAtFinish(estTimeAtFinish);
boatsPos.put(estTimeAtFinish, boat);
// String boatStatus = "SourceID: " + boatStatusSourceID;
@@ -293,9 +297,8 @@ public class StreamParser extends Thread{
byte[] payload = packet.getPayload();
int messageType = payload[9];
long messagelength = bytesToLong(Arrays.copyOfRange(payload,12,14));
String xmlMessage = new String((Arrays.copyOfRange(payload,14,(int) (14 + messagelength)))).trim();
//System.out.println("xmlMessage2 = " + xmlMessage);
long messageLength = bytesToLong(Arrays.copyOfRange(payload,12,14));
String xmlMessage = new String((Arrays.copyOfRange(payload,14,(int) (14 + messageLength)))).trim();
//Create XML document Object
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
@@ -312,6 +315,9 @@ public class StreamParser extends Thread{
if (messageType == 7) { //7 is the boat XML
boats = xmlObject.getBoatXML().getCompetingBoats();
}
if (messageType == 6) { //6 is race info xml
newRaceXmlReceived = true;
}
}
/**
@@ -428,6 +434,9 @@ public class StreamParser extends Thread{
int roundingSide = payload[18];
int markType = payload[19];
int markId = payload[20];
// assign mark rounding time to boat
boats.get((int)subjectId).setMarkRoundingTime(timeStamp);
}
/**
@@ -574,9 +583,33 @@ public class StreamParser extends Thread{
return boatsPos;
}
/**
* returns current time in stream in long
*
* @return a long value of current time
*/
public static Long getCurrentTimeLong() {
return currentTimeLong;
}
public static void appClose(){
appRunning = false;
System.out.println("[CLIENT] Shutting down stream parser");
}
/**
* Used to check if a new un-processed xml has been found, if so will return true before
* toggling off so that the next check will return false.
*
* @return the status of if new xml has been received
*/
public static boolean isNewRaceXmlReceived(){
if (newRaceXmlReceived){
newRaceXmlReceived = false;
return true;
} else {
return false;
}
}
}
+25 -2
View File
@@ -235,6 +235,28 @@ public class ServerThread implements Runnable, Observer {
}
}
/**
* Send the post-start race course information
*/
private void sendPostStartCourseXml(){
Timer t = new Timer();
t.schedule(new TimerTask() {
@Override
public void run() {
try {
Message raceData = getXmlMessage("/server_config/courseLimits.xml", XMLMessageSubType.RACE);
if (raceData != null) {
server.send(raceData);
serverLog("Sending race data", 0);
}
}catch (IOException e) {
serverLog("Couldn't send an XML Message: " + e.getMessage(), 0);
}
}
},25000);
//Delays the new course xml data for 25 seconds so the boats are able to pass the starting line
}
public void run() {
try{
server = new StreamingServerSocket(PORT_NUMBER);
@@ -252,12 +274,13 @@ public class ServerThread implements Runnable, Observer {
sendXml();
startSendingRaceStartStatusMessages();
startSendingRaceStatusMessages();
sendPostStartCourseXml();
}
/**
* Start sending static boat position updates when race has finished
*/
private void startSendingRaceFinishedBoatPostions(){
private void startSendingRaceFinishedBoatPositions(){
Timer t = new Timer();
t.schedule(new TimerTask() {
@Override
@@ -316,7 +339,7 @@ public class ServerThread implements Runnable, Observer {
}
if (numOfBoatsFinished == ((List<Boat>) arg).size()) {
startSendingRaceFinishedBoatPostions();
startSendingRaceFinishedBoatPositions();
}
}
@@ -0,0 +1,105 @@
<?xml version="1.0" encoding="utf-8"?>
<Race>
<CreationTimeDate>2015-08-29T13:12:40+02:00</CreationTimeDate>
<RaceStartTime Start="2015-08-29T13:10:00+02:00" Postpone="False"/>
<RaceID>15082901</RaceID>
<RaceType>Fleet</RaceType>
<Participants>
<Yacht SourceID="101"/>
<Yacht SourceID="102"/>
<Yacht SourceID="103"/>
<Yacht SourceID="104"/>
<Yacht SourceID="105"/>
<Yacht SourceID="106"/>
</Participants>
<Course>
<CompoundMark CompoundMarkID="1" Name="Mark0">
<Mark SeqID="1" Name="Start Line 1" TargetLat="57.6703330" TargetLng="11.8278330"
SourceID="122"/>
<Mark SeqID="2" Name="Start Line 2" TargetLat="57.6703330" TargetLng="11.8278330"
SourceID="123"/>
</CompoundMark>
<CompoundMark CompoundMarkID="2" Name="Mark1">
<Mark SeqID="1" Name="Mark1" TargetLat="57.6675700" TargetLng="11.8359880" SourceID="131"/>
</CompoundMark>
<CompoundMark CompoundMarkID="3" Name="Mark2">
<Mark SeqID="1" Name="Lee Gate 1" TargetLat="57.6708220" TargetLng="11.8433900"
SourceID="124"/>
<Mark SeqID="2" Name="Lee Gate 2" TargetLat="57.6708220" TargetLng="11.8433900"
SourceID="125"/>
</CompoundMark>
<CompoundMark CompoundMarkID="4" Name="Mark3">
<Mark SeqID="1" Name="Wind Gate 1" TargetLat="57.6650170" TargetLng="11.8279170"
SourceID="126"/>
<Mark SeqID="2" Name="Wind Gate 2" TargetLat="57.6650170" TargetLng="11.8279170"
SourceID="127"/>
</CompoundMark>
<CompoundMark CompoundMarkID="5" Name="Mark2">
<Mark SeqID="1" Name="Lee Gate 1" TargetLat="57.6708220" TargetLng="11.8433900"
SourceID="124"/>
<Mark SeqID="2" Name="Lee Gate 2" TargetLat="57.6708220" TargetLng="11.8433900"
SourceID="125"/>
</CompoundMark>
<CompoundMark CompoundMarkID="6" Name="Mark3">
<Mark SeqID="1" Name="Wind Gate 1" TargetLat="57.6650170" TargetLng="11.8279170"
SourceID="126"/>
<Mark SeqID="2" Name="Wind Gate 2" TargetLat="57.6650170" TargetLng="11.8279170"
SourceID="127"/>
</CompoundMark>
<CompoundMark CompoundMarkID="7" Name="Mark2">
<Mark SeqID="1" Name="Lee Gate 1" TargetLat="57.6708220" TargetLng="11.8433900"
SourceID="124"/>
<Mark SeqID="2" Name="Lee Gate 2" TargetLat="57.6708220" TargetLng="11.8433900"
SourceID="125"/>
</CompoundMark>
<CompoundMark CompoundMarkID="8" Name="Mark3">
<Mark SeqID="1" Name="Wind Gate 1" TargetLat="57.6650170" TargetLng="11.8279170"
SourceID="126"/>
<Mark SeqID="2" Name="Wind Gate 2" TargetLat="57.6650170" TargetLng="11.8279170"
SourceID="127"/>
</CompoundMark>
<CompoundMark CompoundMarkID="9" Name="Mark2">
<Mark SeqID="1" Name="Lee Gate 1" TargetLat="57.6708220" TargetLng="11.8433900"
SourceID="124"/>
<Mark SeqID="2" Name="Lee Gate 2" TargetLat="57.6708220" TargetLng="11.8433900"
SourceID="125"/>
</CompoundMark>
<CompoundMark CompoundMarkID="10" Name="Mark3">
<Mark SeqID="1" Name="Wind Gate 1" TargetLat="57.6650170" TargetLng="11.8279170"
SourceID="126"/>
<Mark SeqID="2" Name="Wind Gate 2" TargetLat="57.6650170" TargetLng="11.8279170"
SourceID="127"/>
</CompoundMark>
<CompoundMark CompoundMarkID="11" Name="Mark4">
<Mark SeqID="1" Name="Finish Line 1" TargetLat="57.6715240" TargetLng="11.8444950"
SourceID="128"/>
<Mark SeqID="2" Name="Finish Line 2" TargetLat="57.6715240" TargetLng="11.8444950"
SourceID="129"/>
</CompoundMark>
</Course>
<CompoundMarkSequence>
<Corner SeqID="1" CompoundMarkID="1" Rounding="PS" ZoneSize="3"/>
<Corner SeqID="2" CompoundMarkID="2" Rounding="Port" ZoneSize="3"/>
<Corner SeqID="3" CompoundMarkID="3" Rounding="SP" ZoneSize="3"/>
<Corner SeqID="4" CompoundMarkID="4" Rounding="PS" ZoneSize="3"/>
<Corner SeqID="5" CompoundMarkID="5" Rounding="SP" ZoneSize="3"/>
<Corner SeqID="6" CompoundMarkID="6" Rounding="PS" ZoneSize="3"/>
<Corner SeqID="7" CompoundMarkID="7" Rounding="SP" ZoneSize="3"/>
<Corner SeqID="8" CompoundMarkID="8" Rounding="PS" ZoneSize="3"/>
<Corner SeqID="9" CompoundMarkID="9" Rounding="SP" ZoneSize="3"/>
<Corner SeqID="10" CompoundMarkID="10" Rounding="PS" ZoneSize="3"/>
<Corner SeqID="11" CompoundMarkID="11" Rounding="PS" ZoneSize="3"/>
</CompoundMarkSequence>
<CourseLimit>
<Limit SeqID="1" Lat="57.6739450" Lon="11.8417100"/>
<Limit SeqID="2" Lat="57.6709520" Lon="11.8485010"/>
<Limit SeqID="3" Lat="57.6690260" Lon="11.8472790"/>
<Limit SeqID="4" Lat="57.6693140" Lon="11.8457610"/>
<Limit SeqID="5" Lat="57.6665370" Lon="11.8432910"/>
<Limit SeqID="6" Lat="57.6641400" Lon="11.8385840"/>
<Limit SeqID="7" Lat="57.6629430" Lon="11.8332030"/>
<Limit SeqID="8" Lat="57.6629480" Lon="11.8249660"/>
<Limit SeqID="9" Lat="57.6686890" Lon="11.8250920"/>
<Limit SeqID="10" Lat="57.6708220" Lon="11.8321340"/>
</CourseLimit>
</Race>
+4 -2
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Race>
<CreationTimeDate>2015-08-29T13:12:40+02:00</CreationTimeDate>
<CreationTimeDate>2015-08-29T11:27:15+02:00</CreationTimeDate>
<RaceStartTime Start="2015-08-29T13:10:00+02:00" Postpone="False" />
<RaceID>15082901</RaceID>
<RaceType>Fleet</RaceType>
@@ -80,6 +80,8 @@
<Limit SeqID="7" Lat="57.6629430" Lon="11.8332030" />
<Limit SeqID="8" Lat="57.6629480" Lon="11.8249660" />
<Limit SeqID="9" Lat="57.6686890" Lon="11.8250920" />
<Limit SeqID="10" Lat="57.6708220" Lon="11.8321340" />
<Limit SeqID="10" Lat="57.6692230" Lon="11.8231430" />
<Limit SeqID="11" Lat="57.6725370" Lon="11.8272480" />
<Limit SeqID="12" Lat="57.6708220" Lon="11.8321340" />
</CourseLimit>
</Race>
@@ -5,7 +5,7 @@
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<AnchorPane fx:id="annotationSelectWindow" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="248.0" prefWidth="469.0" styleClass="background-blue" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<AnchorPane fx:id="annotationSelectWindow" maxHeight="270.0" maxWidth="469.0" minHeight="270.0" minWidth="469.0" prefHeight="270.0" prefWidth="469.0" styleClass="background-blue" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Text fill="WHITE" layoutX="26.0" layoutY="52.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Select important annotations">
<font>
@@ -15,7 +15,8 @@
<CheckBox fx:id="boatWakeSelect" layoutX="26.0" layoutY="80.0" mnemonicParsing="false" style="-fx-border-width: 0; -fx-background-insets: 0;" text="Boat Wakes" textFill="#e7e7e7" />
<CheckBox fx:id="boatSpeedSelect" layoutX="26.0" layoutY="111.0" mnemonicParsing="false" text="Boat Speed" textFill="#e7e7e7" />
<CheckBox fx:id="boatTrackSelect" layoutX="26.0" layoutY="142.0" mnemonicParsing="false" text="Boat Tracks" textFill="#e7e7e7" />
<CheckBox fx:id="boatNameSelect" layoutX="26.0" layoutY="175.0" mnemonicParsing="false" text="Boat Name" textFill="#e7e7e7" />
<CheckBox fx:id="boatNameSelect" layoutX="26.0" layoutY="173.0" mnemonicParsing="false" text="Boat Name" textFill="#e7e7e7" />
<CheckBox fx:id="boatEstTimeToNextMarkSelect" layoutX="26.0" layoutY="204.0" mnemonicParsing="false" text="Boat Estimated Time To Next Mark" textFill="#e7e7e7" />
<Button fx:id="closeButton" layoutX="424.0" layoutY="-1.0" mnemonicParsing="false" prefHeight="11.0" prefWidth="49.0" style=": 0;" text="X" textFill="#ffffff4e">
<font>
<Font size="24.0" />
@@ -25,5 +26,6 @@
<String fx:value="clearExitButton" />
</styleClass>
</Button>
<CheckBox fx:id="boatElapsedTimeSelect" layoutX="26.0" layoutY="235.0" mnemonicParsing="false" text="Boat Elapsed Time Since Last Mark" textFill="#e7e7e7" />
</children>
</AnchorPane>
@@ -8,6 +8,7 @@ import java.lang.reflect.Method;
import java.net.Socket;
import java.util.Comparator;
import java.util.concurrent.PriorityBlockingQueue;
import seng302.models.parsers.packets.StreamPacket;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;