diff --git a/src/main/java/seng302/App.java b/src/main/java/seng302/App.java index dd58de7c..0d0d9e69 100644 --- a/src/main/java/seng302/App.java +++ b/src/main/java/seng302/App.java @@ -19,8 +19,10 @@ public class App extends Application primaryStage.setMaximized(true); primaryStage.show(); - primaryStage.setOnCloseRequest(e -> { + StreamParser.appClose(); + StreamReceiver.noMoreBytes(); + System.out.println("[CLIENT] Exiting program"); System.exit(0); }); @@ -39,8 +41,7 @@ public class App extends Application 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", 8085, "RaceStream"); @@ -56,6 +57,8 @@ public class App extends Application //Change the StreamReceiver in this else block to change the default data source. else{ sr = new StreamReceiver("localhost", 8085, "RaceStream"); +// sr = new StreamReceiver("livedata.americascup.com", 4941, "RaceStream"); +// sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941, "RaceStream"); } sr.start(); diff --git a/src/main/java/seng302/controllers/CanvasController.java b/src/main/java/seng302/controllers/CanvasController.java index f7071edb..afd9e4d8 100644 --- a/src/main/java/seng302/controllers/CanvasController.java +++ b/src/main/java/seng302/controllers/CanvasController.java @@ -11,12 +11,10 @@ import javafx.scene.canvas.GraphicsContext; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.Pane; import javafx.scene.paint.Color; +import javafx.scene.shape.Polygon; import javafx.scene.text.Font; import javafx.stage.Stage; -import seng302.models.Boat; -import seng302.models.BoatGroup; -import seng302.models.Colors; -import seng302.models.RaceObject; +import seng302.models.*; import seng302.models.mark.*; import seng302.models.parsers.StreamParser; import seng302.models.parsers.packets.BoatPositionPacket; @@ -151,9 +149,10 @@ public class CanvasController { private void addRaceBorder() { XMLParser.RaceXMLObject raceXMLObject = StreamParser.getXmlObject().getRaceXML(); ArrayList courseLimits = raceXMLObject.getCourseLimit(); - gc.setStroke(Color.DARKRED); + gc.setStroke(Color.DARKBLUE); gc.setLineWidth(3); - + double[] xBoundaryPoints = new double[courseLimits.size()]; + double[] yBoundaryPoints = new double[courseLimits.size()]; for (int i = 0; i < courseLimits.size() - 1; i++) { Limit thisPoint1 = courseLimits.get(i); SingleMark thisMark1 = new SingleMark("", thisPoint1.getLat(), thisPoint1.getLng(), thisPoint1.getSeqID()); @@ -163,18 +162,21 @@ public class CanvasController { Point2D borderPoint2 = findScaledXY(thisMark2); gc.strokeLine(borderPoint1.getX(), borderPoint1.getY(), borderPoint2.getX(), borderPoint2.getY()); - + xBoundaryPoints[i] = borderPoint1.getX(); + yBoundaryPoints[i] = borderPoint1.getY(); } - Limit thisPoint1 = courseLimits.get(courseLimits.size()-1); SingleMark thisMark1 = new SingleMark("", thisPoint1.getLat(), thisPoint1.getLng(), thisPoint1.getSeqID()); Limit thisPoint2 = courseLimits.get(0); SingleMark thisMark2 = new SingleMark("", thisPoint2.getLat(), thisPoint2.getLng(), thisPoint2.getSeqID()); Point2D borderPoint1 = findScaledXY(thisMark1); Point2D borderPoint2 = findScaledXY(thisMark2); - gc.strokeLine(borderPoint1.getX(), borderPoint1.getY(), borderPoint2.getX(), borderPoint2.getY()); + xBoundaryPoints[courseLimits.size()-1] = borderPoint1.getX(); + yBoundaryPoints[courseLimits.size()-1] = borderPoint1.getY(); + gc.setFill(Color.LIGHTBLUE); + gc.fillPolygon(xBoundaryPoints,yBoundaryPoints,yBoundaryPoints.length); } @@ -321,13 +323,16 @@ public class CanvasController { */ private void drawBoats() { // Map timelineInfos = raceViewController.getTimelineInfos(); - List boats = raceViewController.getStartingBoats(); +// List boats = raceViewController.getStartingBoats(); + Map boats = StreamParser.getBoats(); Double startingX = raceObjects.get(0).getLayoutX(); Double startingY = raceObjects.get(0).getLayoutY(); Group boatAnnotations = new Group(); - for (Boat boat : boats) { - BoatGroup boatGroup = new BoatGroup(boat, Colors.getColor()); + for (Yacht boat : boats.values()) { +// for (Boat boat : boats) { + boat.setColour(Colors.getColor()); + BoatGroup boatGroup = new BoatGroup(boat, boat.getColour()); boatGroup.moveTo(startingX, startingY, 0d); //boatGroup.setStage(raceViewController.getStage()); raceObjects.add(boatGroup); diff --git a/src/main/java/seng302/controllers/Controller.java b/src/main/java/seng302/controllers/Controller.java index 97ee324e..847f5603 100644 --- a/src/main/java/seng302/controllers/Controller.java +++ b/src/main/java/seng302/controllers/Controller.java @@ -65,9 +65,7 @@ public class Controller implements Initializable { @Override public void initialize(URL location, ResourceBundle resources) { - DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); - format.setTimeZone(TimeZone.getTimeZone("UTC")); - realTime.setText(format.format(System.currentTimeMillis())); + } /** @@ -144,14 +142,14 @@ public class Controller implements Initializable { posCol.setCellValueFactory( new PropertyValueFactory<>("position") ); - if (StreamParser.isRaceStarted()) { - data.addAll(StreamParser.getBoatsPos().values()); - } else { - for (Yacht boat : StreamParser.getBoats().values()) { - boat.setPosition("-"); - data.add(boat); - } - } +// if (StreamParser.isRaceStarted()) { + data.addAll(StreamParser.getBoatsPos().values()); +// } else { +// for (Yacht boat : StreamParser.getBoats().values()) { +// boat.setPosition("-"); +// data.add(boat); +// } +// } teamList.refresh(); // posCol.setSortType(TableColumn.SortType.ASCENDING); diff --git a/src/main/java/seng302/controllers/RaceController.java b/src/main/java/seng302/controllers/RaceController.java index f595e5e9..d0ea0d42 100644 --- a/src/main/java/seng302/controllers/RaceController.java +++ b/src/main/java/seng302/controllers/RaceController.java @@ -1,15 +1,15 @@ package seng302.controllers; -import seng302.models.Boat; import seng302.models.Race; +import seng302.models.Yacht; import seng302.models.parsers.ConfigParser; import seng302.models.parsers.CourseParser; import seng302.models.parsers.StreamParser; -import seng302.models.parsers.TeamsParser; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Collections; +import java.util.Map; import java.util.Random; /** @@ -41,23 +41,24 @@ public class RaceController { Race race = new Race(); // StreamParser.xmlObject // Read team names from file - TeamsParser tp = new TeamsParser(teamsConfigFile); +// TeamsParser tp = new TeamsParser(teamsConfigFile); // Read course from file - ConfigParser config = new ConfigParser(configFile); +// ConfigParser config = new ConfigParser(configFile); ArrayList boatNames = new ArrayList<>(); - ArrayList teams = tp.getBoats(); +// ArrayList teams = tp.getBoats(); + Map teams = StreamParser.getBoatsPos(); //get race size int numberOfBoats = teams.size(); //get time scale - double timeScale = config.getTimeScale(); - race.setTimeScale(timeScale); +// double timeScale = config.getTimeScale(); +// race.setTimeScale(timeScale); - for (Boat boat : teams) { - boatNames.add(boat.getTeamName()); + for (Yacht boat : teams.values()) { + boatNames.add(boat.getBoatName()); race.addBoat(boat); } diff --git a/src/main/java/seng302/controllers/RaceResultController.java b/src/main/java/seng302/controllers/RaceResultController.java index 7378fa68..bff697ed 100644 --- a/src/main/java/seng302/controllers/RaceResultController.java +++ b/src/main/java/seng302/controllers/RaceResultController.java @@ -27,7 +27,7 @@ public class RaceResultController implements Initializable{ int boatPosition = this.race.getFinishedBoats().length; for (int i = this.race.getFinishedBoats().length - 1; i >= 0; i--){ - resultsVBox.getChildren().add(0, new Text(boatPosition + ": " + this.race.getFinishedBoats()[i].getTeamName())); + resultsVBox.getChildren().add(0, new Text(boatPosition + ": " + this.race.getFinishedBoats()[i].getBoatName())); boatPosition--; } diff --git a/src/main/java/seng302/controllers/RaceViewController.java b/src/main/java/seng302/controllers/RaceViewController.java index 4bcb9079..3b7ee6b5 100644 --- a/src/main/java/seng302/controllers/RaceViewController.java +++ b/src/main/java/seng302/controllers/RaceViewController.java @@ -1,5 +1,6 @@ package seng302.controllers; +import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer; import javafx.animation.Animation; import javafx.animation.KeyFrame; import javafx.animation.Timeline; @@ -44,11 +45,11 @@ public class RaceViewController extends Thread{ @FXML private CanvasController includedCanvasController; - private ArrayList startingBoats = new ArrayList<>(); + private ArrayList startingBoats = new ArrayList<>(); private boolean displayFps; private Timeline timerTimeline; - private Map timelineInfos = new HashMap<>(); - private ArrayList boatOrder = new ArrayList<>(); + private Map timelineInfos = new HashMap<>(); + private ArrayList boatOrder = new ArrayList<>(); private Race race; private Stage stage; @@ -57,7 +58,7 @@ public class RaceViewController extends Thread{ RaceController raceController = new RaceController(); raceController.initializeRace(); race = raceController.getRace(); - for (Boat boat : race.getBoats()) { + for (Yacht boat : race.getBoats()) { startingBoats.add(boat); } // try{ @@ -72,6 +73,7 @@ public class RaceViewController extends Thread{ initializeTimer(); initializeSettings(); initialiseWindDirection(); + initialisePositionVBox(); //set wind direction!!!!!!! can't find another place to put my code --haoming // double windDirection = new ConfigParser("/config/config.xml").getWindDirection(); // windDirectionText.setText(String.format("%.1f°", windDirection)); @@ -160,12 +162,26 @@ public class RaceViewController extends Thread{ windDirTimeline.playFromStart(); } + private void initialisePositionVBox() { + + Timeline posVBoxTimeline = new Timeline(); + posVBoxTimeline.setCycleCount(Timeline.INDEFINITE); + posVBoxTimeline.getKeyFrames().add( + new KeyFrame(Duration.seconds(1), + event -> { + showOrder(); + }) + ); + posVBoxTimeline.playFromStart(); + + } + /** * Generates time line for each boat, and stores time time into timelineInfos hash map */ private void initializeTimelines() { - HashMap boat_events = race.getEvents(); - for (Boat boat : boat_events.keySet()) { + HashMap boat_events = race.getEvents(); + for (Yacht boat : boat_events.keySet()) { startingBoats.add(boat); // // x, y are the real time coordinates // DoubleProperty x = new SimpleDoubleProperty(); @@ -271,13 +287,13 @@ public class RaceViewController extends Thread{ } public void handleEvent(Event event) { - Boat boat = event.getBoat(); + Yacht boat = event.getBoat(); boatOrder.remove(boat); boat.setMarkLastPast(event.getMarkPosInRace()); boatOrder.add(boat); - boatOrder.sort(new Comparator() { + boatOrder.sort(new Comparator() { @Override - public int compare(Boat b1, Boat b2) { + public int compare(Yacht b1, Yacht b2) { return b2.getMarkLastPast() - b1.getMarkLastPast(); } }); @@ -288,8 +304,20 @@ public class RaceViewController extends Thread{ positionVbox.getChildren().clear(); positionVbox.getChildren().removeAll(); - for (Boat boat : boatOrder) { - positionVbox.getChildren().add(new Text(boat.getShortName() + " " + boat.getSpeedInKnots() + " Knots")); +// for (Boat boat : boatOrder) { +// positionVbox.getChildren().add(new Text(boat.getShortName() + " " + boat.getSpeedInKnots() + " Knots")); +// } + + for (Yacht boat : StreamParser.getBoatsPos().values()) { + System.out.println(boat.getBoatStatus()); + if (boat.getBoatStatus() == 3) { // 3 is finish status + positionVbox.getChildren().add(new Text(boat.getPosition() + ". " + + boat.getShortName() + " (Finished)")); + } else { + positionVbox.getChildren().add(new Text(boat.getPosition() + ". " + + boat.getShortName() + " ")); + } + } } @@ -341,11 +369,11 @@ public class RaceViewController extends Thread{ return race; } - public Map getTimelineInfos() { + public Map getTimelineInfos() { return timelineInfos; } - public ArrayList getStartingBoats(){ + public ArrayList getStartingBoats(){ return startingBoats; } diff --git a/src/main/java/seng302/models/Boat.java b/src/main/java/seng302/models/Boat.java deleted file mode 100644 index 0ea427fd..00000000 --- a/src/main/java/seng302/models/Boat.java +++ /dev/null @@ -1,147 +0,0 @@ -package seng302.models; - -import javafx.geometry.Point2D; -import javafx.scene.paint.Color; -import javafx.scene.shape.Polygon; -import javafx.scene.text.Text; -import javafx.scene.transform.Rotate; -import javafx.scene.transform.Translate; -import javafx.util.Pair; - -/** -* Represents a boat in the race. -*/ -public class Boat { - - private String teamName; - private double velocity; - private double lat; - private double lon; - private double heading; - private int markLastPast; - private String shortName; - private int id; - - /** - * For testing only. - * @param teamName Boat team name. - */ - public Boat(String teamName) { - this.teamName = teamName; - this.velocity = 10; // Default velocity - this.lat = 0.0; - this.lon = 0.0; - this.shortName = ""; - } - - - /** - * Represents a boat in the race. - * - * @param teamName The name of the team sailing the boat - * @param boatVelocity The speed of the boat in meters/second - * @param shortName A shorter version of the teams name - */ - public Boat(String teamName, double boatVelocity, String shortName, int id) { - this.teamName = teamName; - this.velocity = boatVelocity; - this.shortName = shortName; - this.id = id; - } - - /** - * Returns the name of the team sailing the boat - * - * @return The name of the team - */ - public String getTeamName() { - return this.teamName; - } - - /** - * Sets the name of the team sailing the boat - * - * @param teamName The name of the team - */ - public void setTeamName(String teamName) { - this.teamName = teamName; - } - - /** - * Gets velocity of the boat - * - * @return a float number of the boat velocity - */ - public double getVelocity() { - return this.velocity; - } - - /** - * Sets velocity of the boat - * - * @param velocity The velocity of boat - */ - public void setVelocity(double velocity) { - this.velocity = velocity; - } - - /** - * Sets the boats location - * - * @param lat, the boats latitude - * @param lon, the boats longitude - */ - public void setLocation(double lat, double lon) { - this.lat = lat; - this.lon = lon; - } - - public Pair getLocation () - { - return new Pair<>(this.lat, this.lon); - } - - public double getLatitude(){ - return this.lat; - } - - public double getLongitude(){ - return this.lon; - } - - public void setLatitude (double latitude) { - this.lat = latitude; - } - - public void setlongitude (double longitude) { - this.lon =longitude; - } - - public double getSpeedInKnots(){ - return Math.round((this.velocity * 1.94384) * 100d) / 100d; - } - - public void setMarkLastPast(int markLastPast) { - this.markLastPast = markLastPast; - } - - public int getMarkLastPast() { - return markLastPast; - } - - public double getHeading(){ - return this.heading; - } - - public void setHeading(double heading) { - this.heading = heading; - } - - public String getShortName(){ - return this.shortName; - } - - public int getId() { - return id; - } -} \ No newline at end of file diff --git a/src/main/java/seng302/models/BoatGroup.java b/src/main/java/seng302/models/BoatGroup.java index 78af2408..57dd48db 100644 --- a/src/main/java/seng302/models/BoatGroup.java +++ b/src/main/java/seng302/models/BoatGroup.java @@ -33,7 +33,7 @@ public class BoatGroup extends RaceObject{ private int wakeGenerationDelay = 10; private double distanceTravelled; //Graphical objects - private Boat boat; + private Yacht boat; private Group lineGroup = new Group(); private Polygon boatPoly; private Text teamNameObject; @@ -54,7 +54,7 @@ public class BoatGroup extends RaceObject{ * BoatGroup to update. * @param color The colour of the boat polygon and the trailing line. */ - public BoatGroup (Boat boat, Color color){ + public BoatGroup (Yacht boat, Color color){ this.boat = boat; initChildren(color); } @@ -66,7 +66,7 @@ public class BoatGroup extends RaceObject{ * @param color The colour of the boat polygon and the trailing line. * @param points An array of co-ordinates x1,y1,x2,y2,x3,y3... that will make up the boat polygon. */ - public BoatGroup (Boat boat, Color color, double... points) + public BoatGroup (Yacht boat, Color color, double... points) { this.boat = boat; initChildren(color, points); @@ -295,7 +295,7 @@ public class BoatGroup extends RaceObject{ wake.setVisible(visible); } - public Boat getBoat() { + public Yacht getBoat() { return boat; } @@ -307,7 +307,7 @@ public class BoatGroup extends RaceObject{ */ public boolean hasRaceId (int... raceIds) { for (int id : raceIds) { - if (id == boat.getId()) + if (id == boat.getSourceID()) return true; } return false; @@ -319,7 +319,7 @@ public class BoatGroup extends RaceObject{ * @return An array containing all ID's associated with this RaceObject. */ public int[] getRaceIds () { - return new int[] {boat.getId()}; + return new int[] {boat.getSourceID()}; } /** diff --git a/src/main/java/seng302/models/Event.java b/src/main/java/seng302/models/Event.java index 3cef1e6b..80f688c7 100644 --- a/src/main/java/seng302/models/Event.java +++ b/src/main/java/seng302/models/Event.java @@ -11,7 +11,7 @@ import java.util.Date; */ public class Event { private Double time; // Time the event occurs - private Boat boat; + private Yacht boat; private boolean isFinishingEvent = false; // This event occurs when a boat finishes the race private Mark mark1; // This mark private Mark mark2; // Next mark @@ -28,7 +28,7 @@ public class Event { * @param eventTime, what time the event happens * @param eventBoat, the boat that the event belongs to */ - public Event(Double eventTime, Boat eventBoat, Mark mark1, Mark mark2, int markPosInRace) { + public Event(Double eventTime, Yacht eventBoat, Mark mark1, Mark mark2, int markPosInRace) { this.time = eventTime; this.boat = eventBoat; this.mark1 = mark1; @@ -45,7 +45,7 @@ public class Event { * @param eventTime, what time the event happens * @param eventBoat, the boat that the event belongs to */ - public Event(Double eventTime, Boat eventBoat, Mark mark1, int markPosInRace) { + public Event(Double eventTime, Yacht eventBoat, Mark mark1, int markPosInRace) { this.time = eventTime; this.boat = eventBoat; this.mark1 = mark1; @@ -70,11 +70,11 @@ public class Event { return (new SimpleDateFormat("mm:ss:SSS")).format(new Date(time.longValue())); } - public Boat getBoat() { + public Yacht getBoat() { return this.boat; } - public void setBoat(Boat eventBoat) { + public void setBoat(Yacht eventBoat) { this.boat = eventBoat; } @@ -90,10 +90,10 @@ public class Event { public String getEventString() { // This event is a boat finishing the race if (this.isFinishingEvent) { - return (this.getTimeString() + ", " + this.getBoat().getTeamName() + " finished the race"); + return (this.getTimeString() + ", " + this.getBoat().getBoatName() + " finished the race"); } // System.out.println(this.getDistanceBetweenMarks()); - return (this.getTimeString() + ", " + this.getBoat().getTeamName() + " passed " + this.mark1.getName() + " going heading " + this.getBoatHeading() + "°"); + return (this.getTimeString() + ", " + this.getBoat().getBoatName() + " passed " + this.mark1.getName() + " going heading " + this.getBoatHeading() + "°"); } /** diff --git a/src/main/java/seng302/models/Race.java b/src/main/java/seng302/models/Race.java index 67988cf5..e78b602a 100644 --- a/src/main/java/seng302/models/Race.java +++ b/src/main/java/seng302/models/Race.java @@ -10,9 +10,9 @@ import java.util.*; */ public class Race { - private ArrayList boats; // The boats in the race - private ArrayList finishingOrder; // The order in which the boats finish the race - private HashMap events = new HashMap<>(); // The events that occur in the race + private ArrayList boats; // The boats in the race + private ArrayList finishingOrder; // The order in which the boats finish the race + private HashMap events = new HashMap<>(); // The events that occur in the race private List course; // Marks in the race private long startTime = 0; private double timeScale = 1; @@ -33,7 +33,7 @@ public class Race { * * @param boat, the boat to add */ - public void addBoat(Boat boat) { + public void addBoat(Yacht boat) { boats.add(boat); } @@ -42,12 +42,12 @@ public class Race { * * @return a list of boats */ - public Boat[] getShuffledBoats() { + public Yacht[] getShuffledBoats() { // Shuffle the list of boats long seed = System.nanoTime(); Collections.shuffle(this.boats, new Random(seed)); - return boats.toArray(new Boat[boats.size()]); + return boats.toArray(new Yacht[boats.size()]); } /** @@ -56,8 +56,8 @@ public class Race { * * @return a list of boats */ - public Boat[] getFinishedBoats() { - return this.finishingOrder.toArray(new Boat[this.finishingOrder.size()]); + public Yacht[] getFinishedBoats() { + return this.finishingOrder.toArray(new Yacht[this.finishingOrder.size()]); } @@ -66,8 +66,8 @@ public class Race { * * @return a list of the boats competing in the race */ - public Boat[] getBoats() { - return boats.toArray(new Boat[boats.size()]); + public Yacht[] getBoats() { + return boats.toArray(new Yacht[boats.size()]); } /** @@ -84,7 +84,7 @@ public class Race { */ private void generateEvents() { - for (Boat boat : this.boats) { + for (Yacht boat : this.boats) { double totalDistance = 0; int numberOfMarks = this.course.size(); @@ -146,7 +146,7 @@ public class Race { * Get a map of the events in the race * @return */ - public HashMap getEvents() { + public HashMap getEvents() { return events; } @@ -154,7 +154,7 @@ public class Race { * Set a boat as finished * @param boat The boat that has finished the race/home/cosc/student/wmu16 */ - public void setBoatFinished(Boat boat){ + public void setBoatFinished(Yacht boat){ this.finishingOrder.add(boat); } diff --git a/src/main/java/seng302/models/Yacht.java b/src/main/java/seng302/models/Yacht.java index 9a8959c1..68970268 100644 --- a/src/main/java/seng302/models/Yacht.java +++ b/src/main/java/seng302/models/Yacht.java @@ -1,5 +1,7 @@ package seng302.models; +import javafx.scene.paint.Color; + import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -10,6 +12,10 @@ import java.text.SimpleDateFormat; * also done outside Boat class because some old variables are not used anymore. */ public class Yacht { + private Color colour; + private double velocity; + private Integer markLastPast; + private String boatType; private Integer sourceID; private String hullID; //matches HullNum in the XML spec. @@ -25,6 +31,29 @@ public class Yacht { private Long estimateTimeAtFinish; private String position; + /** + * Used in EventTest and RaceTest. + * + * @param boatName Create a yacht object with name. + */ + public Yacht (String boatName) { + this.boatName = boatName; + } + + /** + * Used in BoatGroupTest. + * + * @param boatName The name of the team sailing the boat + * @param boatVelocity The speed of the boat in meters/second + * @param shortName A shorter version of the teams name + */ + public Yacht(String boatName, double boatVelocity, String shortName, int id) { + this.boatName = boatName; + this.velocity = boatVelocity; + this.shortName = shortName; + this.sourceID = id; + } + public Yacht(String boatType, Integer sourceID, String hullID, String shortName, String boatName, String country) { this.boatType = boatType; this.sourceID = sourceID; @@ -111,4 +140,28 @@ public class Yacht { public void setPosition(String position) { this.position = position; } + + public Color getColour() { + return colour; + } + + public void setColour(Color colour) { + this.colour = colour; + } + + public double getVelocity() { + return velocity; + } + + public void setVelocity(double velocity) { + this.velocity = velocity; + } + + public Integer getMarkLastPast() { + return markLastPast; + } + + public void setMarkLastPast(Integer markLastPast) { + this.markLastPast = markLastPast; + } } diff --git a/src/main/java/seng302/models/parsers/StreamParser.java b/src/main/java/seng302/models/parsers/StreamParser.java index 5613485a..a8c7b9d4 100644 --- a/src/main/java/seng302/models/parsers/StreamParser.java +++ b/src/main/java/seng302/models/parsers/StreamParser.java @@ -32,7 +32,7 @@ public class StreamParser extends Thread{ private String threadName; private Thread t; private static boolean raceStarted = false; - public static XMLParser xmlObject; + private static XMLParser xmlObject; private static boolean raceFinished = false; private static boolean streamStatus = false; private static long timeSinceStart = -1; @@ -40,6 +40,7 @@ public class StreamParser extends Thread{ private static Map boatsPos = new TreeMap<>(); private static double windDirection = 0; private static String currentTimeString; + private static boolean appRunning; /** * Used to initialise the thread name and stream parser object so a thread can be executed @@ -56,6 +57,7 @@ public class StreamParser extends Thread{ * */ public void run(){ + appRunning = true; try { System.out.println("[CLIENT] Start of stream"); streamStatus = true; @@ -63,7 +65,7 @@ public class StreamParser extends Thread{ while (StreamReceiver.packetBuffer == null || StreamReceiver.packetBuffer.size() < 1) { Thread.sleep(1); } - while (true){ + while (appRunning){ StreamPacket packet = StreamReceiver.packetBuffer.peek(); //this code adds a delay to reading from the packetBuffer so //out of order packets have time to order themselves in the queue @@ -105,7 +107,7 @@ public class StreamParser extends Thread{ * Looks at the type of the packet then sends it to the appropriate parser to extract the * specific data associated with that packet type * - * @param packet the packet to be looked at + * @param packet the packet to be looked at and processed */ private static void parsePacket(StreamPacket packet) { try{ @@ -229,10 +231,16 @@ public class StreamParser extends Thread{ // boatStatus += "\nEstTimeAtFinish: " + bytesToLong(Arrays.copyOfRange(payload,37 + (i * 20),43+ (i * 20))); // boatStatuses.add(boatStatus); } - int pos = 1; - for (Yacht yacht : boatsPos.values()) { - yacht.setPosition(String.valueOf(pos)); - pos++; + if (isRaceStarted()) { + int pos = 1; + for (Yacht yacht : boatsPos.values()) { + yacht.setPosition(String.valueOf(pos)); + pos++; + } + } else { + for (Yacht yacht : boatsPos.values()) { + yacht.setPosition("-"); + } } } @@ -370,6 +378,7 @@ public class StreamParser extends Thread{ //type 1 is a racing yacht and type 3 is a mark, needed for updating positions of the mark and boat if (deviceType == 1 || deviceType == 3){ BoatPositionPacket boatPacket = new BoatPositionPacket(boatId, timeValid, lat, lon, heading, groundSpeed); + //add a new priority que to the boatPositions HashMap if (!boatPositions.containsKey(boatId)){ boatPositions.put(boatId, new PriorityBlockingQueue(256, new Comparator() { @@ -379,6 +388,7 @@ public class StreamParser extends Thread{ } })); } + //Adding the boatPacket to the priority que boatPositions.get(boatId).put(boatPacket); } } @@ -543,5 +553,10 @@ public class StreamParser extends Thread{ public static Map getBoatsPos() { return boatsPos; } + + public static void appClose(){ + appRunning = false; + System.out.println("[CLIENT] Shutting down stream parser"); + } } diff --git a/src/main/java/seng302/models/parsers/StreamReceiver.java b/src/main/java/seng302/models/parsers/StreamReceiver.java index 5eb66d78..65d7c525 100644 --- a/src/main/java/seng302/models/parsers/StreamReceiver.java +++ b/src/main/java/seng302/models/parsers/StreamReceiver.java @@ -21,6 +21,7 @@ public class StreamReceiver extends Thread { private Thread t; private String threadName; public static PriorityBlockingQueue packetBuffer; + private static boolean moreBytes; public StreamReceiver(String hostAddress, int hostPort, String threadName) { this.threadName = threadName; @@ -69,7 +70,7 @@ public class StreamReceiver extends Thread { int sync1; int sync2; - boolean moreBytes = true; + moreBytes = true; while(moreBytes) { try { crcBuffer = new ByteArrayOutputStream(); @@ -121,7 +122,6 @@ public class StreamReceiver extends Thread { return bytes; } - private void skipBytes(long n) throws Exception{ for (int i=0; i < n; i++){ readByte(); @@ -147,7 +147,6 @@ public class StreamReceiver extends Thread { return partialLong; } - public static void main(String[] args) { StreamReceiver sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941,"TestThread1"); @@ -155,4 +154,9 @@ public class StreamReceiver extends Thread { sr.start(); } + + public static void noMoreBytes(){ + moreBytes = false; + System.out.println("[CLIENT] Shutting down stream receiver"); + } } diff --git a/src/main/java/seng302/models/parsers/TeamsParser.java b/src/main/java/seng302/models/parsers/TeamsParser.java index afa31410..fae0a743 100644 --- a/src/main/java/seng302/models/parsers/TeamsParser.java +++ b/src/main/java/seng302/models/parsers/TeamsParser.java @@ -1,64 +1,64 @@ -package seng302.models.parsers; - -import org.w3c.dom.*; -import seng302.models.Boat; - -import java.util.ArrayList; -import java.util.NoSuchElementException; - -public class TeamsParser extends FileParser { - - private Document doc; - - public TeamsParser(String path) { - super(path); - this.doc = this.parseFile(); - } - - /** - * Create a boat instance by a given team node - * @param node a boat node containing name, alias and velocity - * @return an instance of Boat - */ - private Boat parseBoat(Node node) { - try { - if (node.getNodeType() == Node.ELEMENT_NODE) { - Element element = (Element) node; - String name = element.getElementsByTagName("name").item(0).getTextContent(); - String alias = element.getElementsByTagName("alias").item(0).getTextContent(); - double velocity = Double.valueOf(element.getElementsByTagName("velocity").item(0).getTextContent()); - int id = Integer.valueOf(element.getElementsByTagName("id").item(0).getTextContent()); - Boat boat = new Boat(name, velocity, alias, id); - return boat; - } else { - throw new NoSuchElementException("Cannot generate a boat by given node"); - } - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - /** - * Create an arraylist of boats instance. - * @return an arraylist of boats in teams file - */ - public ArrayList getBoats() { - ArrayList boats = new ArrayList<>(); - - try { - NodeList nodes = this.doc.getElementsByTagName("team"); - for (int i = 0; i < nodes.getLength(); i++) { - Node node = nodes.item(i); - boats.add(parseBoat(node)); - } - return boats; - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - -} - +//package seng302.models.parsers; +// +//import org.w3c.dom.*; +//import seng302.models.Yacht; +// +//import java.util.ArrayList; +//import java.util.NoSuchElementException; +// +//public class TeamsParser extends FileParser { +// +// private Document doc; +// +// public TeamsParser(String path) { +// super(path); +// this.doc = this.parseFile(); +// } +// +// /** +// * Create a boat instance by a given team node +// * @param node a boat node containing name, alias and velocity +// * @return an instance of Boat +// */ +// private Yacht parseBoat(Node node) { +// try { +// if (node.getNodeType() == Node.ELEMENT_NODE) { +// Element element = (Element) node; +// String name = element.getElementsByTagName("name").item(0).getTextContent(); +// String alias = element.getElementsByTagName("alias").item(0).getTextContent(); +// double velocity = Double.valueOf(element.getElementsByTagName("velocity").item(0).getTextContent()); +// int id = Integer.valueOf(element.getElementsByTagName("id").item(0).getTextContent()); +// Yacht boat = new Yacht(name, velocity, alias, id); +// return boat; +// } else { +// throw new NoSuchElementException("Cannot generate a boat by given node"); +// } +// } catch (Exception e) { +// e.printStackTrace(); +// return null; +// } +// } +// +// /** +// * Create an arraylist of boats instance. +// * @return an arraylist of boats in teams file +// */ +// public ArrayList getBoats() { +// ArrayList boats = new ArrayList<>(); +// +// try { +// NodeList nodes = this.doc.getElementsByTagName("team"); +// for (int i = 0; i < nodes.getLength(); i++) { +// Node node = nodes.item(i); +// boats.add(parseBoat(node)); +// } +// return boats; +// } catch (Exception e) { +// e.printStackTrace(); +// return null; +// } +// } +// +// +//} +// diff --git a/src/main/java/seng302/server/simulator/Boat.java b/src/main/java/seng302/server/simulator/Boat.java index 093b153c..1768402b 100644 --- a/src/main/java/seng302/server/simulator/Boat.java +++ b/src/main/java/seng302/server/simulator/Boat.java @@ -120,6 +120,6 @@ public class Boat { } public long getEstimatedTimeTillFinish(){ - return (long) (getSpeed()) + System.currentTimeMillis(); + return (long) (-getSpeed()) + System.currentTimeMillis(); } } diff --git a/src/test/java/seng302/BoatTest.java b/src/test/java/seng302/BoatTest.java index c415c046..d1a88daf 100644 --- a/src/test/java/seng302/BoatTest.java +++ b/src/test/java/seng302/BoatTest.java @@ -1,35 +1,35 @@ -package seng302; - -import org.junit.Test; -import seng302.models.Boat; - -import static org.junit.Assert.assertEquals; - -/** - * Unit test for the Team class. - */ -public class BoatTest { - - @Test - public void testBoatCreation() { - Boat boat1 = new Boat("Team 1"); - assertEquals(boat1.getTeamName(), "Team 1"); - assertEquals(boat1.getVelocity(), (double) 10.0, 1e-15); - } - - @Test - public void testChangeTeamName() { - Boat boat1 = new Boat("Team 1"); - boat1.setTeamName("Team 2"); - assertEquals(boat1.getTeamName(), "Team 2"); - } - - @Test - public void testSetVelocity() { - Boat boat1 = new Boat("Team 1", 29.0, "", 100); - assertEquals(boat1.getVelocity(), (double) 29.0, 1e-15); - - boat1.setVelocity(12.0); - assertEquals(boat1.getVelocity(), (double)12.0, 1e-15); - } -} +//package seng302; +// +//import org.junit.Test; +//import seng302.models.Boat; +// +//import static org.junit.Assert.assertEquals; +// +///** +// * Unit test for the Team class. +// */ +//public class BoatTest { +// +// @Test +// public void testBoatCreation() { +// Boat boat1 = new Boat("Team 1"); +// assertEquals(boat1.getTeamName(), "Team 1"); +// assertEquals(boat1.getVelocity(), (double) 10.0, 1e-15); +// } +// +// @Test +// public void testChangeTeamName() { +// Boat boat1 = new Boat("Team 1"); +// boat1.setTeamName("Team 2"); +// assertEquals(boat1.getTeamName(), "Team 2"); +// } +// +// @Test +// public void testSetVelocity() { +// Boat boat1 = new Boat("Team 1", 29.0, "", 100); +// assertEquals(boat1.getVelocity(), (double) 29.0, 1e-15); +// +// boat1.setVelocity(12.0); +// assertEquals(boat1.getVelocity(), (double)12.0, 1e-15); +// } +//} diff --git a/src/test/java/seng302/EventTest.java b/src/test/java/seng302/EventTest.java index 2d53c8a3..4c98ddd6 100644 --- a/src/test/java/seng302/EventTest.java +++ b/src/test/java/seng302/EventTest.java @@ -1,8 +1,8 @@ package seng302; import org.junit.Test; -import seng302.models.Boat; import seng302.models.Event; +import seng302.models.Yacht; import seng302.models.mark.SingleMark; import static org.junit.Assert.assertEquals; @@ -15,14 +15,14 @@ public class EventTest { @Test public void getTimeString() throws Exception { - Boat boat = new Boat("testBoat"); + Yacht boat = new Yacht("testBoat"); Event event = new Event(1231242.2, boat, new SingleMark("mark1"), new SingleMark("mark2"), 0); assertEquals("20:31:242", event.getTimeString()); } @Test public void testBoatHeading() throws Exception { - Boat boat = new Boat("testBoat"); + Yacht boat = new Yacht("testBoat"); Event event = new Event(1231242.2, boat, new SingleMark("mark1", 142.5, 122.1, 1), new SingleMark("mark2", 121.9,99.2, 2), 0); assertEquals(event.getBoatHeading(), 228.0266137055349, 1e-15); @@ -30,7 +30,7 @@ public class EventTest { @Test public void testDistanceBetweenMarks() throws Exception { - Boat boat = new Boat("testBoat"); + Yacht boat = new Yacht("testBoat"); Event event = new Event(1231242.2, boat, new SingleMark("mark1", 142.5, 122.1, 1), new SingleMark("mark2", 121.9,99.2, 2), 0); assertEquals(event.getDistanceBetweenMarks(), 339059.653830461, 1e-15); diff --git a/src/test/java/seng302/RaceTest.java b/src/test/java/seng302/RaceTest.java index ab318331..2784cd47 100644 --- a/src/test/java/seng302/RaceTest.java +++ b/src/test/java/seng302/RaceTest.java @@ -1,8 +1,8 @@ package seng302; import org.junit.Test; -import seng302.models.Boat; import seng302.models.Race; +import seng302.models.Yacht; import java.lang.reflect.Array; @@ -17,8 +17,8 @@ public class RaceTest { */ @Test public void testAddingBoatsToRace() { - Boat boat1 = new Boat("Team 1"); - Boat boat2 = new Boat("Team 2"); + Yacht boat1 = new Yacht("Team 1"); + Yacht boat2 = new Yacht("Team 2"); Race race = new Race(); race.addBoat(boat1); @@ -29,8 +29,8 @@ public class RaceTest { @Test public void testGetShuffledBoats(){ - Boat boat1 = new Boat("Team 1"); - Boat boat2 = new Boat("Team 2"); + Yacht boat1 = new Yacht("Team 1"); + Yacht boat2 = new Yacht("Team 2"); Race race = new Race(); race.addBoat(boat1); diff --git a/src/test/java/seng302/models/BoatGroupTest.java b/src/test/java/seng302/models/BoatGroupTest.java index cbac5707..60c18cc7 100644 --- a/src/test/java/seng302/models/BoatGroupTest.java +++ b/src/test/java/seng302/models/BoatGroupTest.java @@ -1,100 +1,98 @@ -// TODO: 4/05/17 cir27 - Find out why this test is causing build failures +package seng302.models; +import seng302.*; +import javafx.scene.paint.*; +import javafx.scene.paint.Color; +import javafx.scene.shape.Polygon; +import javafx.scene.transform.Rotate; +import javafx.scene.transform.Transform; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; -//package seng302.models; -//import seng302.*; -//import javafx.scene.paint.*; -//import javafx.scene.paint.Color; -//import javafx.scene.shape.Polygon; -//import javafx.scene.transform.Rotate; -//import javafx.scene.transform.Transform; -//import org.junit.Assert; -//import org.junit.Before; -//import org.junit.Test; -// -///** -// * Created by cir27 on 4/05/17. -// */ -//public class BoatGroupTest { -// BoatGroup boatGroup; -// @Before -// public void setUp () { -// Boat b = new Boat("TEST", 0.0, "T" ,0); -// boatGroup = new BoatGroup(b, Color.BLACK); -// } -// -// @Test -// public void setDestinationFirstUseForcesLocationUpdate () { -// boatGroup.setDestination(10, 10, 90, 0); -// Polygon bp = (Polygon) boatGroup.getChildren().get(2); -// Assert.assertTrue(10 == bp.getLayoutX()); -// Assert.assertTrue(10 == bp.getLayoutY()); -// } -// -// @Test -// public void setDestinationFutureUseDoesntForce () { -// for (int i = 0; i < 60; i++) { -// boatGroup.setDestination(200, 200, 90, 0); -// } -// boatGroup.setDestination(210, 210, 90, 0); -// Polygon bp = (Polygon) boatGroup.getChildren().get(2); -// Assert.assertTrue(200 == bp.getLayoutX()); -// Assert.assertTrue(200 == bp.getLayoutY()); -// } -// -// @Test -// public void setDestinationUnrealisticMovementForceUpdate () { -// Polygon bp = (Polygon) boatGroup.getChildren().get(2); -// double xLocation = bp.getLayoutX(); -// double yLocation = bp.getLayoutY(); -// boatGroup.setDestination(xLocation + 500, yLocation + 500, 90, 0); -// Assert.assertTrue(xLocation + 500 == bp.getLayoutX()); -// Assert.assertTrue(yLocation + 500 == bp.getLayoutY()); -// } -// -// @Test -// public void setDestinationUnrealisticNegativeForceUpdate () { -// Polygon bp = (Polygon) boatGroup.getChildren().get(2); -// double xLocation = bp.getLayoutX(); -// double yLocation = bp.getLayoutY(); -// boatGroup.setDestination(xLocation - 500, yLocation - 500, 90, 0); -// Assert.assertTrue(xLocation - 500 == bp.getLayoutX()); -// Assert.assertTrue(yLocation - 500 == bp.getLayoutY()); -// } -// -// @Test -// public void updatePositionGeneratesExpectedMovement () { -// Polygon bp = (Polygon) boatGroup.getChildren().get(2); -// double xLocation = bp.getLayoutX(); -// double yLocation = bp.getLayoutY(); -// int movement = 10; -// double delay = RaceObject.getExpectedUpdateInterval(); -// double defaultTimePeriod = 1000 / 60; -// double expectedMovement = movement / delay * defaultTimePeriod; -// for (int i = 0; i < 60; i++) { -// boatGroup.setDestination(xLocation, yLocation, 90, 0); -// } -// boatGroup.setDestination(xLocation + 10, yLocation + 10, 90, 0); -// boatGroup.updatePosition(1000/60); -// Assert.assertEquals(expectedMovement, bp.getLayoutX() - xLocation, 0.0); -// } -// -// @Test -// public void correctRaceID () { -// Assert.assertTrue(boatGroup.hasRaceId(0)); -// } -// -// @Test -// public void incorrectRaceID () { -// Assert.assertTrue(!boatGroup.hasRaceId(2)); -// } -// -// @Test -// public void nothingOnWrongId () { -// Polygon bp = (Polygon) boatGroup.getChildren().get(2); -// double originalX = bp.getLayoutX(); -// double originalY = bp.getLayoutY(); -// boatGroup.setDestination(10, 10, 90, 12); -// Assert.assertTrue(originalX == bp.getLayoutX()); -// Assert.assertTrue(originalY == bp.getLayoutY()); -// } -//} +/** + * Created by cir27 on 4/05/17. + */ +public class BoatGroupTest { + BoatGroup boatGroup; + @Before + public void setUp () { + Boat b = new Boat("TEST", 0.0, "T" ,0); + boatGroup = new BoatGroup(b, Color.BLACK); + } + + @Test + public void setDestinationFirstUseForcesLocationUpdate () { + boatGroup.setDestination(10, 10, 90, 0); + Polygon bp = (Polygon) boatGroup.getChildren().get(2); + Assert.assertTrue(10 == bp.getLayoutX()); + Assert.assertTrue(10 == bp.getLayoutY()); + } + + @Test + public void setDestinationFutureUseDoesntForce () { + for (int i = 0; i < 60; i++) { + boatGroup.setDestination(200, 200, 90, 0); + } + boatGroup.setDestination(210, 210, 90, 0); + Polygon bp = (Polygon) boatGroup.getChildren().get(2); + Assert.assertTrue(200 == bp.getLayoutX()); + Assert.assertTrue(200 == bp.getLayoutY()); + } + + @Test + public void setDestinationUnrealisticMovementForceUpdate () { + Polygon bp = (Polygon) boatGroup.getChildren().get(2); + double xLocation = bp.getLayoutX(); + double yLocation = bp.getLayoutY(); + boatGroup.setDestination(xLocation + 500, yLocation + 500, 90, 0); + Assert.assertTrue(xLocation + 500 == bp.getLayoutX()); + Assert.assertTrue(yLocation + 500 == bp.getLayoutY()); + } + + @Test + public void setDestinationUnrealisticNegativeForceUpdate () { + Polygon bp = (Polygon) boatGroup.getChildren().get(2); + double xLocation = bp.getLayoutX(); + double yLocation = bp.getLayoutY(); + boatGroup.setDestination(xLocation - 500, yLocation - 500, 90, 0); + Assert.assertTrue(xLocation - 500 == bp.getLayoutX()); + Assert.assertTrue(yLocation - 500 == bp.getLayoutY()); + } + + @Test + public void updatePositionGeneratesExpectedMovement () { + Polygon bp = (Polygon) boatGroup.getChildren().get(2); + double xLocation = bp.getLayoutX(); + double yLocation = bp.getLayoutY(); + int movement = 10; + double delay = RaceObject.getExpectedUpdateInterval(); + double defaultTimePeriod = 1000 / 60; + double expectedMovement = movement / delay * defaultTimePeriod; + for (int i = 0; i < 60; i++) { + boatGroup.setDestination(xLocation, yLocation, 90, 0); + } + boatGroup.setDestination(xLocation + 10, yLocation + 10, 90, 0); + boatGroup.updatePosition(1000/60); + Assert.assertEquals(expectedMovement, bp.getLayoutX() - xLocation, 0.0); + } + + @Test + public void correctRaceID () { + Assert.assertTrue(boatGroup.hasRaceId(0)); + } + + @Test + public void incorrectRaceID () { + Assert.assertTrue(!boatGroup.hasRaceId(2)); + } + + @Test + public void nothingOnWrongId () { + Polygon bp = (Polygon) boatGroup.getChildren().get(2); + double originalX = bp.getLayoutX(); + double originalY = bp.getLayoutY(); + boatGroup.setDestination(10, 10, 90, 12); + Assert.assertTrue(originalX == bp.getLayoutX()); + Assert.assertTrue(originalY == bp.getLayoutY()); + } +} diff --git a/src/test/java/seng302/models/parsers/TeamsParserTest.java b/src/test/java/seng302/models/parsers/TeamsParserTest.java index 3c31b519..60cf52e8 100644 --- a/src/test/java/seng302/models/parsers/TeamsParserTest.java +++ b/src/test/java/seng302/models/parsers/TeamsParserTest.java @@ -1,35 +1,36 @@ -package seng302.models.parsers; - -import org.junit.Before; -import org.junit.Test; -import seng302.models.Boat; - -import java.util.ArrayList; - -import static org.junit.Assert.*; - -/** - * Created by Haoming on 18/03/17. - */ -public class TeamsParserTest { - - private TeamsParser tp; - @Before - public void readFile() { - tp = new TeamsParser("/config/teams.xml"); - } - - @Test - public void getBoats() throws Exception { - ArrayList boats = tp.getBoats(); - - assertEquals(6, boats.size(), 1e-10); - - assertEquals("Oracle Team USA", boats.get(0).getTeamName()); - //assertEquals(30.9, boats.get(0).getVelocity(), 1e-10); - - assertEquals("Groupama Team France", boats.get(5).getTeamName()); - //assertEquals(45.6, boats.get(5).getVelocity(), 1e-10); - } - -} \ No newline at end of file +//package seng302.models.parsers; +// +//import org.junit.Before; +//import org.junit.Test; +//import seng302.models.Boat; +//import seng302.models.Yacht; +// +//import java.util.ArrayList; +// +//import static org.junit.Assert.*; +// +///** +// * Created by Haoming on 18/03/17. +// */ +//public class TeamsParserTest { +// +// private TeamsParser tp; +// @Before +// public void readFile() { +// tp = new TeamsParser("/config/teams.xml"); +// } +// +// @Test +// public void getBoats() throws Exception { +// ArrayList boats = tp.getBoats(); +// +// assertEquals(6, boats.size(), 1e-10); +// +// assertEquals("Oracle Team USA", boats.get(0).getBoatName()); +// //assertEquals(30.9, boats.get(0).getVelocity(), 1e-10); +// +// assertEquals("Groupama Team France", boats.get(5).getBoatName()); +// //assertEquals(45.6, boats.get(5).getVelocity(), 1e-10); +// } +// +//} \ No newline at end of file