Merge branch 'splitIntoTwoModules' of https://eng-git.canterbury.ac.nz/seng302-2017/team-7 into splitIntoTwoModules
This commit is contained in:
@@ -49,4 +49,7 @@ public class MarkRounding extends AC35Data{
|
||||
this.markID = markID;
|
||||
}
|
||||
|
||||
public int getSourceID() {
|
||||
return sourceID;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package seng302.Controllers;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import seng302.RaceDataSource;
|
||||
import seng302.VisualiserInput;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
@@ -16,8 +17,8 @@ public class MainController extends Controller {
|
||||
@FXML
|
||||
RaceController raceController;
|
||||
|
||||
public void beginRace(int scaleFactor, RaceDataSource raceData) {
|
||||
raceController.startRace(scaleFactor, raceData);
|
||||
public void beginRace(VisualiserInput visualiserInput) {
|
||||
raceController.startRace(visualiserInput);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import seng302.Mock.StreamedRace;
|
||||
import seng302.Model.*;
|
||||
import seng302.RaceDataSource;
|
||||
import seng302.RaceXMLReader;
|
||||
import seng302.VisualiserInput;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import java.io.IOException;
|
||||
@@ -114,13 +115,13 @@ public class RaceController extends Controller {
|
||||
* Initializes and runs the race, based on the user's chosen scale factor
|
||||
* Currently uses an example racecourse
|
||||
*
|
||||
* @param scaleFactor scale value of race
|
||||
* @param visualiserInput
|
||||
*/
|
||||
public void startRace(int scaleFactor, RaceDataSource raceData) {
|
||||
StreamedRace newRace = new StreamedRace(raceData, this, scaleFactor);
|
||||
public void startRace(VisualiserInput visualiserInput) {
|
||||
StreamedRace newRace = new StreamedRace(visualiserInput, this);
|
||||
//newRace.initialiseBoats();
|
||||
|
||||
raceMap = new ResizableRaceCanvas(raceData);
|
||||
raceMap = new ResizableRaceCanvas(visualiserInput.getCourse());
|
||||
raceMap.setMouseTransparent(true);
|
||||
raceMap.widthProperty().bind(canvasBase.widthProperty());
|
||||
raceMap.heightProperty().bind(canvasBase.heightProperty());
|
||||
@@ -133,8 +134,8 @@ public class RaceController extends Controller {
|
||||
|
||||
//Initialize save annotation array, fps listener, and annotation listeners
|
||||
//timezone
|
||||
RaceClock raceClock = new RaceClock(raceData.getZonedDateTime());
|
||||
timeZone.setText(raceClock.getTimeZone());
|
||||
// RaceClock raceClock = new RaceClock(visualiserInput.getCourse().getZonedDateTime());
|
||||
// timeZone.setText(raceClock.getTimeZone());
|
||||
initializeFPS();
|
||||
initializeAnnotations();
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@ import seng302.RaceDataSource;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.URL;
|
||||
import java.text.ParseException;
|
||||
import java.util.List;
|
||||
@@ -53,6 +55,8 @@ public class StartController extends Controller implements Observer {
|
||||
private StreamedCourse raceData;
|
||||
private long timeLeft = 1;
|
||||
|
||||
private VisualiserInput visualiserInput;
|
||||
|
||||
/**
|
||||
* Begins the race with a scale factor of 15
|
||||
*/
|
||||
@@ -88,7 +92,7 @@ public class StartController extends Controller implements Observer {
|
||||
try {
|
||||
raceData = new StreamedCourse();
|
||||
raceData.addObserver(this);
|
||||
VisualiserInput visualiserInput = new VisualiserInput(raceData);
|
||||
visualiserInput = new VisualiserInput(new Socket("livedata.americascup.com", 4941), raceData);
|
||||
new Thread(visualiserInput).start();
|
||||
// StreamedCourse streamedCourse = new StreamedCourse(new BoatXMLReader("mockXML/boatXML/boatTest.xml"));
|
||||
// streamedCourse.setStreamedCourseXMLReader(new StreamedCourseXMLReader("mockXML/raceXML/raceTest.xml"));
|
||||
@@ -150,7 +154,7 @@ public class StartController extends Controller implements Observer {
|
||||
if (timeLeft <= 0) {
|
||||
updateTime("Race is starting...");
|
||||
stop();
|
||||
parent.beginRace(scaleFactor, raceData);
|
||||
parent.beginRace(visualiserInput);
|
||||
startWrapper.setVisible(false);
|
||||
|
||||
} else {
|
||||
|
||||
@@ -80,12 +80,15 @@ public class StreamedCourseXMLReader extends XMLReader {
|
||||
private void readRace() throws ParseException {
|
||||
DateTimeFormatter dateFormat = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
|
||||
Element settings = (Element) doc.getElementsByTagName("Race").item(0);
|
||||
NamedNodeMap raceTimeTag = doc.getElementsByTagName("RaceStartTime").item(0).getAttributes();
|
||||
|
||||
if (raceTimeTag.getNamedItem("Time") != null) dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ");
|
||||
|
||||
|
||||
System.out.println(getTextValueOfNode(settings, "CreationTimeDate"));
|
||||
raceID = Integer.parseInt(getTextValueOfNode(settings, "RaceID"));
|
||||
raceType = getTextValueOfNode(settings, "RaceType");
|
||||
creationTimeDate = ZonedDateTime.parse(getTextValueOfNode(settings, "CreationTimeDate"), dateFormat);
|
||||
NamedNodeMap raceTimeTag = doc.getElementsByTagName("RaceStartTime").item(0).getAttributes();
|
||||
|
||||
if (raceTimeTag.getNamedItem("Time") != null) raceStartTime = ZonedDateTime.parse(raceTimeTag.getNamedItem("Time").getTextContent(), dateFormat);
|
||||
else raceStartTime = ZonedDateTime.parse(raceTimeTag.getNamedItem("Start").getTextContent(), dateFormat);
|
||||
postpone = Boolean.parseBoolean(raceTimeTag.getNamedItem("Postpone").getTextContent());
|
||||
@@ -180,10 +183,11 @@ public class StreamedCourseXMLReader extends XMLReader {
|
||||
private void readCompoundMarkSequence() throws StreamedCourseXMLException {
|
||||
Element nCompoundMarkSequence = (Element) doc.getElementsByTagName("CompoundMarkSequence").item(0);
|
||||
NodeList nCorners = nCompoundMarkSequence.getElementsByTagName("Corner");
|
||||
Marker lastMarker = getMarker(getCompoundMarkID((Element)nCorners.item(0)));
|
||||
String legName = getCompoundMarkName(getCompoundMarkID((Element)nCorners.item(0)));
|
||||
Element markXML = (Element)nCorners.item(0);
|
||||
Marker lastMarker = getMarker(getCompoundMarkID(markXML));
|
||||
String legName = getCompoundMarkName(getCompoundMarkID(markXML));
|
||||
for(int i = 1; i < nCorners.getLength(); i++) {
|
||||
Element markXML = (Element)nCorners.item(i);
|
||||
markXML = (Element)nCorners.item(i);
|
||||
Marker currentMarker = getMarker(getCompoundMarkID(markXML));
|
||||
legs.add(new Leg(legName, lastMarker, currentMarker, i-1));
|
||||
lastMarker = currentMarker;
|
||||
|
||||
@@ -6,7 +6,13 @@ import seng302.Constants;
|
||||
import seng302.Controllers.RaceController;
|
||||
import seng302.GPSCoordinate;
|
||||
import seng302.Model.*;
|
||||
import seng302.Networking.MessageDecoders.BoatLocationDecoder;
|
||||
import seng302.Networking.Utils.BoatStatusMessage;
|
||||
import seng302.Networking.Utils.ByteConverter;
|
||||
import seng302.Networking.Utils.Enums.BoatStatus;
|
||||
import seng302.Networking.Utils.BoatLocationMessage;
|
||||
import seng302.RaceDataSource;
|
||||
import seng302.VisualiserInput;
|
||||
|
||||
import java.awt.geom.Point2D;
|
||||
import java.util.*;
|
||||
@@ -15,12 +21,12 @@ import java.util.*;
|
||||
* Created by jjg64 on 21/04/17.
|
||||
*/
|
||||
public class StreamedRace extends Race {
|
||||
private RaceDataSource raceData;
|
||||
private VisualiserInput visualiserInput;
|
||||
private double MMPS_TO_KN = 0.001944;
|
||||
|
||||
public StreamedRace(RaceDataSource raceData, RaceController controller, int scaleFactor) {
|
||||
super(raceData.getBoats(), raceData.getLegs(), controller, scaleFactor);
|
||||
this.raceData = raceData;
|
||||
this.scaleFactor = 1; // There will be no scaling in a live streamed race
|
||||
public StreamedRace(VisualiserInput visualiserInput, RaceController controller) {
|
||||
super(visualiserInput.getCourse(), controller, 1);
|
||||
this.visualiserInput = visualiserInput;
|
||||
}
|
||||
|
||||
public void initialiseBoats() {
|
||||
@@ -48,18 +54,26 @@ public class StreamedRace extends Race {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the position of the boat, this updates the boats current position.
|
||||
* Checks the position of the boat.
|
||||
*
|
||||
* @param boat Boat that the position is to be updated for.
|
||||
* @param timeElapsed Time that has elapse since the start of the the race.
|
||||
* @see BoatInRace
|
||||
*/
|
||||
protected void checkPosition(Boat boat, long timeElapsed) {
|
||||
if (boat.getCurrentLeg().getName().toLowerCase().contains("finish")) {
|
||||
//boat has finished
|
||||
StreamedCourse raceData = visualiserInput.getCourse();
|
||||
BoatStatusMessage boatStatusMessage = visualiserInput.getBoatStatus().get(boat.getSourceID());
|
||||
BoatStatus boatStatus = BoatStatus.valueOf(boatStatusMessage.getBoatStatus());
|
||||
int legNumber = boatStatusMessage.getLegNumber();
|
||||
|
||||
if (boatStatus == BoatStatus.DNF) {
|
||||
boat.setDnf(true);
|
||||
} else if (boatStatus == BoatStatus.FINISHED || legNumber > raceData.getLegs().size()) {
|
||||
boatsFinished++;
|
||||
boat.setFinished(true);
|
||||
boat.setTimeFinished(timeElapsed);
|
||||
boat.setFinished(true);
|
||||
} else {
|
||||
boat.setCurrentLeg(raceData.getLegs().get(legNumber));
|
||||
}
|
||||
//Update the boat display table in the GUI to reflect the leg change
|
||||
updatePositions();
|
||||
@@ -72,8 +86,16 @@ public class StreamedRace extends Race {
|
||||
* @param millisecondsElapsed time since last update
|
||||
*/
|
||||
protected void updatePosition(Boat boat, int millisecondsElapsed) {
|
||||
//TODO Grab info from network
|
||||
// setPosition(boat, coordinate);
|
||||
int sourceID = boat.getSourceID();
|
||||
BoatLocationMessage boatLocationMessage = visualiserInput.getBoatLocationMessage(sourceID);
|
||||
if(boatLocationMessage != null) {
|
||||
System.out.println(sourceID);
|
||||
double lat = boatLocationMessage.getLatitudeDouble();
|
||||
double lon = boatLocationMessage.getLongitudeDouble();
|
||||
boat.setCurrentPosition(new GPSCoordinate(lat, lon));
|
||||
boat.setHeading(boatLocationMessage.getHeadingDegrees());
|
||||
boat.setVelocity(boatLocationMessage.getBoatSpeed() * MMPS_TO_KN);
|
||||
}
|
||||
}
|
||||
|
||||
protected void setPosition(Boat boat, GPSCoordinate coordinate) {
|
||||
|
||||
@@ -27,6 +27,7 @@ public class Boat {
|
||||
protected long timeFinished;
|
||||
protected StringProperty position;
|
||||
protected boolean started = false;
|
||||
protected boolean dnf = false;
|
||||
private double wakeScale = 1 / 50;
|
||||
private int sourceID;
|
||||
|
||||
@@ -234,4 +235,12 @@ public class Boat {
|
||||
public int getSourceID() {
|
||||
return this.sourceID;
|
||||
}
|
||||
|
||||
public boolean isDnf() {
|
||||
return dnf;
|
||||
}
|
||||
|
||||
public void setDnf(boolean dnf) {
|
||||
this.dnf = dnf;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.geotools.referencing.GeodeticCalculator;
|
||||
import seng302.Controllers.RaceController;
|
||||
import seng302.GPSCoordinate;
|
||||
import seng302.RaceDataSource;
|
||||
import seng302.VisualiserInput;
|
||||
|
||||
import java.awt.geom.Point2D;
|
||||
import java.util.ArrayList;
|
||||
@@ -31,7 +32,7 @@ public abstract class Race implements Runnable {
|
||||
|
||||
protected int scaleFactor;
|
||||
|
||||
protected int PRERACE_TIME = 120000; //time in milliseconds to pause during pre-race
|
||||
protected int PRERACE_TIME = 0; //time in milliseconds to pause during pre-race
|
||||
private boolean timerEnabled = true; //boolean to determine if timer is ran
|
||||
|
||||
/**
|
||||
@@ -69,6 +70,10 @@ public abstract class Race implements Runnable {
|
||||
this(Arrays.asList(startingBoats), legs, controller, scaleFactor);
|
||||
}
|
||||
|
||||
public void setController(RaceController controller) {
|
||||
this.controller = controller;
|
||||
}
|
||||
|
||||
public abstract void initialiseBoats();
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
package seng302;
|
||||
import org.opengis.style.Mark;
|
||||
import org.xml.sax.SAXException;
|
||||
import seng302.Mock.*;
|
||||
import seng302.Networking.BinaryMessageDecoder;
|
||||
@@ -41,14 +42,23 @@ public class VisualiserInput implements Runnable
|
||||
|
||||
private Map<Integer, BoatStatusMessage> boatStatus;
|
||||
|
||||
public VisualiserInput(StreamedCourse course) throws IOException{
|
||||
private AverageWind averageWind;
|
||||
|
||||
this.connectionSocket = new Socket(InetAddress.getLocalHost(), 4942);
|
||||
private CourseWinds courseWinds;
|
||||
|
||||
private Map<Integer, MarkRounding> markRounding;
|
||||
|
||||
private RaceStartStatus raceStartStatus;
|
||||
|
||||
public VisualiserInput(Socket socket, StreamedCourse course) throws IOException{
|
||||
|
||||
this.connectionSocket = socket;
|
||||
// this.connectionSocket = new Socket("livedata.americascup.com",4941);
|
||||
|
||||
this.course = course;
|
||||
this.boatLocation = new HashMap<>();
|
||||
this.boatStatus = new HashMap<>();
|
||||
this.markRounding = new HashMap<>();
|
||||
|
||||
|
||||
//start Time
|
||||
@@ -106,6 +116,30 @@ public class VisualiserInput implements Runnable
|
||||
return boatStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the average wind of the race
|
||||
* @return average wind in the race
|
||||
*/
|
||||
public AverageWind getAverageWind() {
|
||||
return averageWind;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns winds in the course
|
||||
* @return winds that are in the course
|
||||
*/
|
||||
public CourseWinds getCourseWinds() {
|
||||
return courseWinds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns get Mark Rounding Boat Source ID, MarkRound
|
||||
* @return
|
||||
*/
|
||||
public Map<Integer, MarkRounding> getMarkRounding() {
|
||||
return markRounding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes an inputStream and reads the first 15 bytes (the header) and gets the message length
|
||||
* for the whole message then reads that and returns the byte array
|
||||
@@ -154,7 +188,7 @@ public class VisualiserInput implements Runnable
|
||||
lastHeartbeatTime = System.currentTimeMillis();
|
||||
//note: if the program runs for over 340 years, this will crash.
|
||||
heartbeatSeqNum = ByteConverter.bytesToLong(testDecoder.getMessage());
|
||||
System.out.println("HeartBeat Message! " + heartbeatSeqNum);
|
||||
// System.out.println("HeartBeat Message! " + heartbeatSeqNum);
|
||||
break;
|
||||
case RACESTATUS:
|
||||
System.out.println("Race Status Message");
|
||||
@@ -193,6 +227,8 @@ public class VisualiserInput implements Runnable
|
||||
break;
|
||||
case RACESTARTSTATUS:
|
||||
//System.out.println("Race Start Status Message");
|
||||
RaceStartStatus rSS = (RaceStartStatus) data;
|
||||
raceStartStatus = rSS;
|
||||
break;
|
||||
case YACHTEVENTCODE:
|
||||
// System.out.println("Yacht Action Code!");
|
||||
@@ -207,6 +243,7 @@ public class VisualiserInput implements Runnable
|
||||
//no decoder
|
||||
break;
|
||||
case BOATLOCATION:
|
||||
System.out.println("Boat Location!");
|
||||
BoatLocationMessage msg = (BoatLocationMessage) data;
|
||||
if (boatLocation.containsKey(msg.getSourceID())){
|
||||
if (msg.getTime() > boatLocation.get(msg.getSourceID()).getTime()){
|
||||
@@ -219,12 +256,17 @@ public class VisualiserInput implements Runnable
|
||||
break;
|
||||
case MARKROUNDING:
|
||||
// System.out.println("Mark Rounding Message!");
|
||||
MarkRounding mkrounding = (MarkRounding) data;
|
||||
markRounding.put(mkrounding.getSourceID(), mkrounding);
|
||||
break;
|
||||
case COURSEWIND:
|
||||
// System.out.println("Course Wind Message!");
|
||||
courseWinds = (CourseWinds) data;
|
||||
break;
|
||||
case AVGWIND:
|
||||
// System.out.println("Average Wind Message!");
|
||||
AverageWind avgWind = (AverageWind) data;
|
||||
averageWind = avgWind;
|
||||
break;
|
||||
default:
|
||||
System.out.println("Broken Message!");
|
||||
@@ -245,7 +287,8 @@ public class VisualiserInput implements Runnable
|
||||
|
||||
public static void main(String argv[]) throws Exception
|
||||
{
|
||||
VisualiserInput receiver = new VisualiserInput(new StreamedCourse());
|
||||
Socket socket = new Socket(InetAddress.getLocalHost(), 4942);
|
||||
VisualiserInput receiver = new VisualiserInput(socket, new StreamedCourse());
|
||||
receiver.run();
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,9 @@ public class StreamedRaceTest {
|
||||
"M2",
|
||||
"Gate"
|
||||
};
|
||||
for(int i = 0; i < legs.size(); i++) assertEquals(expectedNames[i], legs.get(i).getName());
|
||||
for(int i = 0; i < legs.size(); i++) {
|
||||
assertEquals(expectedNames[i], legs.get(i).getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user