diff --git a/src/main/java/seng302/App.java b/src/main/java/seng302/App.java index 80163138..df036566 100644 --- a/src/main/java/seng302/App.java +++ b/src/main/java/seng302/App.java @@ -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")); @@ -39,15 +39,15 @@ public class App extends Application e.printStackTrace(); } - if (args.length == 1 && args[0].equals("-standalone")){ + if (args.length == 1 && args[0].equals("-standalone")) { return; } - if (args.length == 3 && args[0].equals("-server")){ + if (args.length == 3 && args[0].equals("-server")) { sr = new StreamReceiver(args[1], Integer.valueOf(args[2]), "RaceStream"); - } else if(args.length == 2 && args[0].equals("-server")){ + } else if (args.length == 2 && args[0].equals("-server")) { switch (args[1]) { case "internal": sr = new StreamReceiver("localhost", 4949, "RaceStream"); @@ -62,8 +62,6 @@ public class App extends Application } //Change the StreamReceiver in this else block to change the default data source. else{ -// sr = new StreamReceiver("livedata.americascup.com", 4941, "RaceStream"); - sr = new StreamReceiver("localhost", 4949, "RaceStream"); } @@ -73,8 +71,6 @@ public class App extends Application launch(args); - - } } diff --git a/src/main/java/seng302/controllers/CanvasController.java b/src/main/java/seng302/controllers/CanvasController.java index 4d57559b..9a2a9797 100644 --- a/src/main/java/seng302/controllers/CanvasController.java +++ b/src/main/java/seng302/controllers/CanvasController.java @@ -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); diff --git a/src/main/java/seng302/models/parsers/PacketType.java b/src/main/java/seng302/models/parsers/PacketType.java deleted file mode 100644 index 66b86207..00000000 --- a/src/main/java/seng302/models/parsers/PacketType.java +++ /dev/null @@ -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; - } - - -} diff --git a/src/main/java/seng302/models/parsers/StreamPacket.java b/src/main/java/seng302/models/parsers/StreamPacket.java deleted file mode 100644 index 5c2c0706..00000000 --- a/src/main/java/seng302/models/parsers/StreamPacket.java +++ /dev/null @@ -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; - } -} diff --git a/src/main/java/seng302/models/parsers/StreamParser.java b/src/main/java/seng302/models/parsers/StreamParser.java index c1fcd6ec..63019c3d 100644 --- a/src/main/java/seng302/models/parsers/StreamParser.java +++ b/src/main/java/seng302/models/parsers/StreamParser.java @@ -31,6 +31,7 @@ public class StreamParser extends Thread{ public static ConcurrentHashMap> 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; @@ -123,6 +124,7 @@ public class StreamParser extends Thread{ extractDisplayMessage(packet); break; case XML_MESSAGE: + newRaceXmlReceived = true; extractXmlMessage(packet); break; case RACE_START_STATUS: @@ -296,9 +298,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(); @@ -315,6 +316,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; + } } /** @@ -593,5 +597,20 @@ public class StreamParser extends Thread{ 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; + } + } } diff --git a/src/main/java/seng302/server/ServerThread.java b/src/main/java/seng302/server/ServerThread.java index c09eb8dc..094845ab 100644 --- a/src/main/java/seng302/server/ServerThread.java +++ b/src/main/java/seng302/server/ServerThread.java @@ -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) arg).size()) { - startSendingRaceFinishedBoatPostions(); + startSendingRaceFinishedBoatPositions(); } } diff --git a/src/main/resources/server_config/courseLimits.xml b/src/main/resources/server_config/courseLimits.xml new file mode 100644 index 00000000..646f6ade --- /dev/null +++ b/src/main/resources/server_config/courseLimits.xml @@ -0,0 +1,105 @@ + + +2015-08-29T13:12:40+02:00 + +15082901 +Fleet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/server_config/race.xml b/src/main/resources/server_config/race.xml index 845f2044..06f4f626 100644 --- a/src/main/resources/server_config/race.xml +++ b/src/main/resources/server_config/race.xml @@ -1,6 +1,6 @@ - 2015-08-29T13:12:40+02:00 + 2015-08-29T11:27:15+02:00 15082901 Fleet @@ -80,6 +80,8 @@ - + + + \ No newline at end of file diff --git a/src/test/java/seng302/models/parsers/StreamReceiverTest.java b/src/test/java/seng302/models/parsers/StreamReceiverTest.java index c7951e3b..698ee3c0 100644 --- a/src/test/java/seng302/models/parsers/StreamReceiverTest.java +++ b/src/test/java/seng302/models/parsers/StreamReceiverTest.java @@ -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;