mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
deleted a whole bunch of legacy code, primarily the old controllers and old parsers #story[923]
This commit is contained in:
@@ -62,7 +62,7 @@ public class App extends Application
|
||||
}
|
||||
//Change the StreamReceiver in this else block to change the default data source.
|
||||
else{
|
||||
sr = new StreamReceiver("localhost", 4949, "RaceStream");
|
||||
sr = new StreamReceiver("livedata.americascup.com", 4941, "RaceStream");
|
||||
}
|
||||
|
||||
sr.start();
|
||||
|
||||
@@ -59,7 +59,6 @@ public class CanvasController {
|
||||
private Mark maxLonPoint;
|
||||
private double referencePointX;
|
||||
private double referencePointY;
|
||||
private double metersToPixels;
|
||||
private List<RaceObject> raceObjects = new ArrayList<>();
|
||||
private List<Mark> raceMarks = new ArrayList<>();
|
||||
|
||||
@@ -179,57 +178,6 @@ public class CanvasController {
|
||||
gc.fillPolygon(xBoundaryPoints,yBoundaryPoints,yBoundaryPoints.length);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds the course marks to the canvas, taken from the XMl file
|
||||
*
|
||||
* NOTE: This is quite confusing as objects are grabbed from the XMLParser such as Mark and CompoundMark which are
|
||||
* named the same as those in the model package but are, however not the same, so they do not have things such as
|
||||
* a type and must be derived from the number of marks in a compound mark etc..
|
||||
*/
|
||||
private void addCourseMarks() {
|
||||
XMLParser.RaceXMLObject raceXMLObject = StreamParser.getXmlObject().getRaceXML();
|
||||
ArrayList<CompoundMark> compoundMarks = raceXMLObject.getCompoundMarks();
|
||||
RaceObject markGroup;
|
||||
|
||||
for (CompoundMark compoundMark : compoundMarks) {
|
||||
|
||||
//If the compound mark has 2 marks then its a gate mark
|
||||
if (compoundMark.getMarks().size() == 2) {
|
||||
CompoundMark.Mark mark1 = compoundMark.getMarks().get(0);
|
||||
CompoundMark.Mark mark2 = compoundMark.getMarks().get(1);
|
||||
SingleMark singleMark1 = new SingleMark(mark1.getMarkName(), mark1.getTargetLat(), mark1.getTargetLng(), mark1.getSourceID());
|
||||
SingleMark singleMark2 = new SingleMark(mark1.getMarkName(), mark2.getTargetLat(), mark2.getTargetLng(), mark2.getSourceID());
|
||||
GateMark thisGateMark = new GateMark(compoundMark.getcMarkName(),
|
||||
(compoundMark.getMarkID().equals(1)) ? MarkType.OPEN_GATE : MarkType.CLOSED_GATE,
|
||||
singleMark1,
|
||||
singleMark2,
|
||||
singleMark1.getLatitude(),
|
||||
singleMark1.getLongitude());
|
||||
|
||||
markGroup = new MarkGroup(thisGateMark,
|
||||
findScaledXY(thisGateMark.getSingleMark1()),
|
||||
findScaledXY(thisGateMark.getSingleMark2()));
|
||||
|
||||
raceObjects.add(markGroup);
|
||||
raceMarks.add(thisGateMark);
|
||||
|
||||
//Otherwise its a single mark
|
||||
} else {
|
||||
CompoundMark.Mark singleMark = compoundMark.getMarks().get(0);
|
||||
Mark thisSingleMark = new SingleMark(singleMark.getMarkName(),
|
||||
singleMark.getTargetLat(),
|
||||
singleMark.getTargetLng(),
|
||||
singleMark.getSourceID());
|
||||
|
||||
markGroup = new MarkGroup(thisSingleMark, findScaledXY(thisSingleMark));
|
||||
raceObjects.add(markGroup);
|
||||
raceMarks.add(thisSingleMark);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateRaceObjects(){
|
||||
for (RaceObject raceObject : raceObjects) {
|
||||
raceObject.updatePosition(1000 / 60);
|
||||
@@ -325,15 +273,15 @@ public class CanvasController {
|
||||
// Map<Boat, TimelineInfo> timelineInfos = raceViewController.getTimelineInfos();
|
||||
// List<Boat> boats = raceViewController.getStartingBoats();
|
||||
Map<Integer, Yacht> boats = StreamParser.getBoats();
|
||||
Double startingX = raceObjects.get(0).getLayoutX();
|
||||
Double startingY = raceObjects.get(0).getLayoutY();
|
||||
// Double startingX = raceObjects.get(0).getLayoutX();
|
||||
// Double startingY = raceObjects.get(0).getLayoutY();
|
||||
Group boatAnnotations = new Group();
|
||||
|
||||
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.moveTo(startingX, startingY, 0d);
|
||||
//boatGroup.setStage(raceViewController.getStage());
|
||||
raceObjects.add(boatGroup);
|
||||
boatAnnotations.getChildren().add(boatGroup.getLowPriorityAnnotations());
|
||||
@@ -349,9 +297,8 @@ public class CanvasController {
|
||||
findMinMaxPoint();
|
||||
double minLonToMaxLon = scaleRaceExtremities();
|
||||
calculateReferencePointLocation(minLonToMaxLon);
|
||||
givePointsXY();
|
||||
//givePointsXY();
|
||||
addRaceBorder();
|
||||
findMetersToPixels();
|
||||
}
|
||||
|
||||
|
||||
@@ -448,25 +395,25 @@ public class CanvasController {
|
||||
* Give all markers in the course an x,y location relative to a given reference with a known x,y location. Distances
|
||||
* are scaled according to the distanceScaleFactor variable.
|
||||
*/
|
||||
private void givePointsXY() {
|
||||
List<Mark> allPoints = new ArrayList<>(raceViewController.getRace().getCourse());
|
||||
List<Mark> processed = new ArrayList<>();
|
||||
RaceObject markGroup;
|
||||
|
||||
for (Mark mark : allPoints) {
|
||||
if (!processed.contains(mark)) {
|
||||
if (mark.getMarkType() != MarkType.SINGLE_MARK) {
|
||||
GateMark gateMark = (GateMark) mark;
|
||||
markGroup = new MarkGroup(mark, findScaledXY(gateMark.getSingleMark1()), findScaledXY(gateMark.getSingleMark2()));
|
||||
raceObjects.add(markGroup);
|
||||
} else {
|
||||
markGroup = new MarkGroup(mark, findScaledXY(mark));
|
||||
raceObjects.add(markGroup);
|
||||
}
|
||||
processed.add(mark);
|
||||
}
|
||||
}
|
||||
}
|
||||
// private void givePointsXY() {
|
||||
// List<Mark> allPoints = new ArrayList<>(raceViewController.getRace().getCourse());
|
||||
// List<Mark> processed = new ArrayList<>();
|
||||
// RaceObject markGroup;
|
||||
//
|
||||
// for (Mark mark : allPoints) {
|
||||
// if (!processed.contains(mark)) {
|
||||
// if (mark.getMarkType() != MarkType.SINGLE_MARK) {
|
||||
// GateMark gateMark = (GateMark) mark;
|
||||
// markGroup = new MarkGroup(mark, findScaledXY(gateMark.getSingleMark1()), findScaledXY(gateMark.getSingleMark2()));
|
||||
// raceObjects.add(markGroup);
|
||||
// } else {
|
||||
// markGroup = new MarkGroup(mark, findScaledXY(mark));
|
||||
// raceObjects.add(markGroup);
|
||||
// }
|
||||
// processed.add(mark);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
private Point2D findScaledXY (Mark unscaled) {
|
||||
return findScaledXY (minLatPoint.getLatitude(), minLatPoint.getLongitude(),
|
||||
@@ -501,35 +448,6 @@ public class CanvasController {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Find the number of meters per pixel.
|
||||
*/
|
||||
private void findMetersToPixels () {
|
||||
Double angularDistance;
|
||||
Double angle;
|
||||
Double straightLineDistance;
|
||||
if (scaleDirection == ScaleDirection.HORIZONTAL) {
|
||||
angularDistance = Mark.calculateDistance(minLonPoint, maxLonPoint);
|
||||
angle = Mark.calculateHeadingRad(minLonPoint, maxLonPoint);
|
||||
if (angle > Math.PI / 2) {
|
||||
straightLineDistance = Math.cos(angle - Math.PI) * angularDistance;
|
||||
} else {
|
||||
straightLineDistance = Math.cos(angle) * angularDistance;
|
||||
}
|
||||
metersToPixels = (CANVAS_WIDTH - RHS_BUFFER - LHS_BUFFER) / straightLineDistance;
|
||||
} else {
|
||||
angularDistance = Mark.calculateDistance(minLatPoint, maxLatPoint);
|
||||
angle = Mark.calculateHeadingRad(minLatPoint, maxLatPoint);
|
||||
if (angle < Math.PI / 2) {
|
||||
straightLineDistance = Math.cos(angle) * angularDistance;
|
||||
} else {
|
||||
straightLineDistance = Math.cos(-angle + Math.PI * 2) * angularDistance;
|
||||
}
|
||||
metersToPixels = (CANVAS_HEIGHT - TOP_BUFFER - BOT_BUFFER) / straightLineDistance;
|
||||
}
|
||||
}
|
||||
|
||||
private Point2D latLonToXY (double latitude, double longitude) {
|
||||
return findScaledXY(minLatPoint.getLatitude(), minLatPoint.getLongitude(), latitude, longitude);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ import java.util.ResourceBundle;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class Controller implements Initializable {
|
||||
public class Controller {
|
||||
@FXML
|
||||
private AnchorPane contentPane;
|
||||
@FXML
|
||||
@@ -66,13 +66,6 @@ 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("GMT-8"));
|
||||
//realTime.setText(format.format(new Date()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Running a timer to update the livestream status on welcome screen. Update interval is 1 second.
|
||||
*/
|
||||
@@ -147,18 +140,9 @@ 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);
|
||||
// }
|
||||
// }
|
||||
|
||||
teamList.refresh();
|
||||
|
||||
// posCol.setSortType(TableColumn.SortType.ASCENDING);
|
||||
// teamList.getSortOrder().add(posCol);
|
||||
// posCol.setSortable(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
package seng302.controllers;
|
||||
|
||||
import seng302.models.Race;
|
||||
import seng302.models.Yacht;
|
||||
import seng302.models.parsers.ConfigParser;
|
||||
import seng302.models.parsers.CourseParser;
|
||||
import seng302.models.parsers.StreamParser;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Created by zyt10 on 17/03/17.
|
||||
* run before CanvasController to initialize race events
|
||||
* the CanvasController then uses the event data to make the animations
|
||||
*/
|
||||
public class RaceController {
|
||||
Race race = null;
|
||||
|
||||
public void initializeRace() {
|
||||
String raceConfigFile = "/config/config.xml";
|
||||
String teamsConfigFile = "/config/teams.xml";
|
||||
|
||||
try {
|
||||
race = createRace(raceConfigFile, teamsConfigFile);
|
||||
} catch (Exception e) {
|
||||
System.out.println("There was an error creating the race.");
|
||||
}
|
||||
|
||||
if (race != null) {
|
||||
race.startRace();
|
||||
} else {
|
||||
System.out.println("There was an error creating the race. Exiting.");
|
||||
}
|
||||
}
|
||||
|
||||
public Race createRace(String configFile, String teamsConfigFile) throws Exception {
|
||||
Race race = new Race();
|
||||
// StreamParser.xmlObject
|
||||
// Read team names from file
|
||||
// TeamsParser tp = new TeamsParser(teamsConfigFile);
|
||||
|
||||
// Read course from file
|
||||
// ConfigParser config = new ConfigParser(configFile);
|
||||
|
||||
ArrayList<String> boatNames = new ArrayList<>();
|
||||
// ArrayList<Boat> teams = tp.getBoats();
|
||||
Map<Long, Yacht> teams = StreamParser.getBoatsPos();
|
||||
|
||||
//get race size
|
||||
int numberOfBoats = teams.size();
|
||||
|
||||
//get time scale
|
||||
// double timeScale = config.getTimeScale();
|
||||
// race.setTimeScale(timeScale);
|
||||
|
||||
for (Yacht boat : teams.values()) {
|
||||
boatNames.add(boat.getBoatName());
|
||||
race.addBoat(boat);
|
||||
}
|
||||
|
||||
// Shuffle team names
|
||||
long seed = System.nanoTime();
|
||||
Collections.shuffle(boatNames, new Random(seed));
|
||||
|
||||
if (numberOfBoats > Array.getLength(boatNames.toArray())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
CourseParser course = new CourseParser("/config/course.xml");
|
||||
race.addCourse(course.getCourse());
|
||||
|
||||
return race;
|
||||
}
|
||||
|
||||
public Race getRace() {
|
||||
return race;
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package seng302.controllers;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.text.Text;
|
||||
import seng302.models.Race;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* Created by ptg19 on 20/03/17.
|
||||
*/
|
||||
public class RaceResultController implements Initializable{
|
||||
@FXML private AnchorPane window;
|
||||
@FXML private VBox resultsVBox;
|
||||
private Race race;
|
||||
|
||||
RaceResultController(Race race){
|
||||
this.race = race;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
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].getBoatName()));
|
||||
boatPosition--;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,9 @@
|
||||
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;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.control.CheckBox;
|
||||
@@ -16,11 +13,9 @@ import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.util.Duration;
|
||||
import javafx.util.StringConverter;
|
||||
import seng302.models.*;
|
||||
import seng302.models.parsers.ConfigParser;
|
||||
import seng302.models.parsers.StreamParser;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -48,36 +43,16 @@ public class RaceViewController extends Thread{
|
||||
private ArrayList<Yacht> startingBoats = new ArrayList<>();
|
||||
private boolean displayFps;
|
||||
private Timeline timerTimeline;
|
||||
private Map<Yacht, TimelineInfo> timelineInfos = new HashMap<>();
|
||||
private ArrayList<Yacht> boatOrder = new ArrayList<>();
|
||||
private Race race;
|
||||
private Stage stage;
|
||||
|
||||
public void initialize() {
|
||||
|
||||
RaceController raceController = new RaceController();
|
||||
raceController.initializeRace();
|
||||
race = raceController.getRace();
|
||||
for (Yacht boat : race.getBoats()) {
|
||||
startingBoats.add(boat);
|
||||
}
|
||||
// try{
|
||||
// initializeTimelines();
|
||||
// }
|
||||
// catch (Exception e){
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
|
||||
includedCanvasController.setup(this);
|
||||
includedCanvasController.initializeCanvas();
|
||||
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));
|
||||
// windArrowText.setRotate(windDirection);
|
||||
includedCanvasController.timer.start();
|
||||
}
|
||||
|
||||
@@ -163,7 +138,6 @@ public class RaceViewController extends Thread{
|
||||
}
|
||||
|
||||
private void initialisePositionVBox() {
|
||||
|
||||
Timeline posVBoxTimeline = new Timeline();
|
||||
posVBoxTimeline.setCycleCount(Timeline.INDEFINITE);
|
||||
posVBoxTimeline.getKeyFrames().add(
|
||||
@@ -173,143 +147,12 @@ public class RaceViewController extends Thread{
|
||||
})
|
||||
);
|
||||
posVBoxTimeline.playFromStart();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates time line for each boat, and stores time time into timelineInfos hash map
|
||||
*/
|
||||
private void initializeTimelines() {
|
||||
HashMap<Yacht, List> boat_events = race.getEvents();
|
||||
for (Yacht boat : boat_events.keySet()) {
|
||||
startingBoats.add(boat);
|
||||
// // x, y are the real time coordinates
|
||||
// DoubleProperty x = new SimpleDoubleProperty();
|
||||
// DoubleProperty y = new SimpleDoubleProperty();
|
||||
//
|
||||
// List<KeyFrame> keyFrames = new ArrayList<>();
|
||||
// List<Event> events = boat_events.get(boat);
|
||||
//
|
||||
// // iterates all events and convert each event to keyFrame, then add them into a list
|
||||
// for (Event event : events) {
|
||||
// if (event.getIsFinishingEvent()) {
|
||||
// keyFrames.add(
|
||||
// new KeyFrame(Duration.seconds(event.getTime()),
|
||||
// onFinished -> {race.setBoatFinished(boat); handleEvent(event);},
|
||||
// new KeyValue(x, event.getThisMark().getLatitude()),
|
||||
// new KeyValue(y, event.getThisMark().getLongitude())
|
||||
// )
|
||||
// );
|
||||
// } else {
|
||||
// keyFrames.add(
|
||||
// new KeyFrame(Duration.seconds(event.getTime()),
|
||||
// onFinished ->{
|
||||
// handleEvent(event);
|
||||
// boat.setHeading(event.getBoatHeading());
|
||||
// },
|
||||
// new KeyValue(x, event.getThisMark().getLatitude()),
|
||||
// new KeyValue(y, event.getThisMark().getLongitude())
|
||||
// )
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// timelineInfos.put(boat, new TimelineInfo(new Timeline(keyFrames.toArray(new KeyFrame[keyFrames.size()])), x, y));
|
||||
}
|
||||
setRaceDuration();
|
||||
}
|
||||
|
||||
private void setRaceDuration(){
|
||||
Double maxDuration = 0.0;
|
||||
Timeline maxTimeline = null;
|
||||
|
||||
for (TimelineInfo timelineInfo : timelineInfos.values()) {
|
||||
|
||||
Timeline timeline = timelineInfo.getTimeline();
|
||||
if (timeline.getTotalDuration().toMillis() >= maxDuration) {
|
||||
maxDuration = timeline.getTotalDuration().toMillis();
|
||||
maxTimeline = timeline;
|
||||
}
|
||||
|
||||
// Timelines are paused by default
|
||||
timeline.play();
|
||||
timeline.pause();
|
||||
}
|
||||
|
||||
maxTimeline.setOnFinished(event -> {
|
||||
race.setRaceFinished();
|
||||
loadRaceResultView();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Play each boats timerTimeline
|
||||
*/
|
||||
public void playTimelines(){
|
||||
for (TimelineInfo timelineInfo : timelineInfos.values()){
|
||||
Timeline timeline = timelineInfo.getTimeline();
|
||||
|
||||
if (timeline.getStatus() == Animation.Status.PAUSED){
|
||||
timeline.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pause each boats timerTimeline
|
||||
*/
|
||||
public void pauseTimelines(){
|
||||
for (TimelineInfo timelineInfo : timelineInfos.values()){
|
||||
Timeline timeline = timelineInfo.getTimeline();
|
||||
|
||||
if (timeline.getStatus() == Animation.Status.RUNNING){
|
||||
timeline.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the list of boats in the order they finished the race
|
||||
*/
|
||||
private void loadRaceResultView() {
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/views/FinishView.fxml"));
|
||||
loader.setController(new RaceResultController(race));
|
||||
|
||||
try {
|
||||
contentAnchorPane.getChildren().removeAll();
|
||||
contentAnchorPane.getChildren().clear();
|
||||
contentAnchorPane.getChildren().addAll((Pane) loader.load());
|
||||
|
||||
} catch (javafx.fxml.LoadException e) {
|
||||
System.err.println(e.getCause());
|
||||
} catch (IOException e) {
|
||||
System.err.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void handleEvent(Event event) {
|
||||
Yacht boat = event.getBoat();
|
||||
boatOrder.remove(boat);
|
||||
boat.setMarkLastPast(event.getMarkPosInRace());
|
||||
boatOrder.add(boat);
|
||||
boatOrder.sort(new Comparator<Yacht>() {
|
||||
@Override
|
||||
public int compare(Yacht b1, Yacht b2) {
|
||||
return b2.getMarkLastPast() - b1.getMarkLastPast();
|
||||
}
|
||||
});
|
||||
showOrder();
|
||||
}
|
||||
|
||||
private void showOrder() {
|
||||
positionVbox.getChildren().clear();
|
||||
positionVbox.getChildren().removeAll();
|
||||
|
||||
// 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)"));
|
||||
@@ -354,30 +197,10 @@ public class RaceViewController extends Thread{
|
||||
return timerString;
|
||||
}
|
||||
|
||||
public void stopTimer() {
|
||||
timerTimeline.stop();
|
||||
}
|
||||
public void startTimer() {
|
||||
timerTimeline.play();
|
||||
}
|
||||
|
||||
public boolean isDisplayFps() {
|
||||
return displayFps;
|
||||
}
|
||||
|
||||
public Race getRace() {
|
||||
return race;
|
||||
}
|
||||
|
||||
public Map<Yacht, TimelineInfo> getTimelineInfos() {
|
||||
return timelineInfos;
|
||||
}
|
||||
|
||||
public ArrayList<Yacht> getStartingBoats(){
|
||||
return startingBoats;
|
||||
}
|
||||
|
||||
|
||||
private void setAnnotations(Integer annotationLevel) {
|
||||
switch (annotationLevel) {
|
||||
case 0:
|
||||
@@ -426,12 +249,4 @@ public class RaceViewController extends Thread{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void setStage (Stage stage) {
|
||||
this.stage = stage;
|
||||
}
|
||||
|
||||
Stage getStage () {
|
||||
return stage;
|
||||
}
|
||||
}
|
||||
@@ -1,198 +0,0 @@
|
||||
package seng302.models;
|
||||
|
||||
import seng302.models.mark.Mark;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Race class containing the boats and legs in the race
|
||||
* Created by mra106 on 8/3/2017.
|
||||
*/
|
||||
public class Race {
|
||||
|
||||
private ArrayList<Yacht> boats; // The boats in the race
|
||||
private ArrayList<Yacht> finishingOrder; // The order in which the boats finish the race
|
||||
private HashMap<Yacht, List> events = new HashMap<>(); // The events that occur in the race
|
||||
private List<Mark> course; // Marks in the race
|
||||
private long startTime = 0;
|
||||
private double timeScale = 1;
|
||||
private boolean raceFinished = false; // Race is finished
|
||||
private int raceTime = -2; // Current time in the race
|
||||
|
||||
/**
|
||||
* Race class containing the boats and legs in the race
|
||||
*/
|
||||
public Race() {
|
||||
this.boats = new ArrayList<>();
|
||||
this.finishingOrder = new ArrayList<>();
|
||||
this.course = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a boat to the race
|
||||
*
|
||||
* @param boat, the boat to add
|
||||
*/
|
||||
public void addBoat(Yacht boat) {
|
||||
boats.add(boat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of boats in a random order
|
||||
*
|
||||
* @return a list of boats
|
||||
*/
|
||||
public Yacht[] getShuffledBoats() {
|
||||
// Shuffle the list of boats
|
||||
long seed = System.nanoTime();
|
||||
Collections.shuffle(this.boats, new Random(seed));
|
||||
|
||||
return boats.toArray(new Yacht[boats.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of boats in the order that they
|
||||
* finished the race (position 0 is first place)
|
||||
*
|
||||
* @return a list of boats
|
||||
*/
|
||||
public Yacht[] getFinishedBoats() {
|
||||
return this.finishingOrder.toArray(new Yacht[this.finishingOrder.size()]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of boats in the race
|
||||
*
|
||||
* @return a list of the boats competing in the race
|
||||
*/
|
||||
public Yacht[] getBoats() {
|
||||
return boats.toArray(new Yacht[boats.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets time scale
|
||||
*
|
||||
* @param timeScale
|
||||
*/
|
||||
public void setTimeScale(double timeScale) {
|
||||
this.timeScale = timeScale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate all events that will happen during the race.
|
||||
*/
|
||||
private void generateEvents() {
|
||||
|
||||
for (Yacht boat : this.boats) {
|
||||
double totalDistance = 0;
|
||||
int numberOfMarks = this.course.size();
|
||||
|
||||
for (int i = 0; i < numberOfMarks; i++) {
|
||||
Double time = (totalDistance / boat.getVelocity() / timeScale);
|
||||
|
||||
// If there are singleMarks after this event
|
||||
if (i < numberOfMarks - 1) {
|
||||
Event event = new Event(time, boat, course.get(i), course.get(i + 1), i);
|
||||
|
||||
try {
|
||||
events.get(boat).add(event);
|
||||
|
||||
} catch (NullPointerException e) {
|
||||
events.put(boat, new ArrayList<>(Arrays.asList(event)));
|
||||
}
|
||||
totalDistance += event.getDistanceBetweenMarks();
|
||||
//System.out.println(totalDistance);
|
||||
//System.out.println(boat.getVelocity());
|
||||
}
|
||||
|
||||
// There are no more marks after this event
|
||||
|
||||
else{
|
||||
Event event = new Event(time, boat, course.get(i), i);
|
||||
events.get(boat).add(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Starts a race and generates all events for the race.
|
||||
*/
|
||||
public void startRace() {
|
||||
// record start time.
|
||||
this.startTime = System.currentTimeMillis();
|
||||
generateEvents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the race course
|
||||
* @param course a list of marks in the course
|
||||
*/
|
||||
public void addCourse(List<Mark> course) {
|
||||
this.course = course;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of marks in the course
|
||||
* @return
|
||||
*/
|
||||
public List<Mark> getCourse() {
|
||||
return course;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a map of the events in the race
|
||||
* @return
|
||||
*/
|
||||
public HashMap<Yacht, List> getEvents() {
|
||||
return events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a boat as finished
|
||||
* @param boat The boat that has finished the race/home/cosc/student/wmu16
|
||||
*/
|
||||
public void setBoatFinished(Yacht boat){
|
||||
this.finishingOrder.add(boat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the race as finished
|
||||
*/
|
||||
public void setRaceFinished(){
|
||||
this.raceFinished = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether or not the race is finished
|
||||
* @return true if the race is finished
|
||||
*/
|
||||
public boolean isRaceFinished(){
|
||||
return this.raceFinished;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the race time
|
||||
* @param raceTime the race time in seconds
|
||||
*/
|
||||
public void setRaceTime(int raceTime){
|
||||
this.raceTime = raceTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the race time
|
||||
* @return the race time in seconds
|
||||
*/
|
||||
public int getRaceTime(){
|
||||
return this.raceTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the race time by one second
|
||||
*/
|
||||
public void incrementRaceTime(){
|
||||
this.raceTime += this.timeScale;
|
||||
}
|
||||
}
|
||||
@@ -53,8 +53,8 @@ public class MarkGroup extends RaceObject {
|
||||
};
|
||||
super.getChildren().add(markCircle);
|
||||
} else {
|
||||
marks.add(((GateMark) mark).getSingleMark1());
|
||||
marks.add(((GateMark) mark).getSingleMark2());
|
||||
// marks.add(((GateMark) mark).getSingleMark1());
|
||||
// marks.add(((GateMark) mark).getSingleMark2());
|
||||
nodePixelVelocitiesX = new double[]{0d,0d};
|
||||
nodePixelVelocitiesY = new double[]{0d,0d};
|
||||
nodeDestinations = new Point2D[2];
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
package seng302.models.parsers;
|
||||
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import java.util.DoubleSummaryStatistics;
|
||||
|
||||
public class ConfigParser extends FileParser {
|
||||
|
||||
private Document doc;
|
||||
|
||||
public ConfigParser(String path) {
|
||||
super(path);
|
||||
this.doc = this.parseFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets wind direction from config file.
|
||||
*
|
||||
* @return a double type degree, or 0 if no value or invalid value is found
|
||||
*/
|
||||
public double getWindDirection() {
|
||||
return getDoubleByTagName("wind-direction", 0.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a non negative time scale for the race
|
||||
*
|
||||
* @return a double type scale, or 0 if no scale or invalid scale is found
|
||||
*/
|
||||
public double getTimeScale() {
|
||||
return getDoubleByTagName("time-scale", 1.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a double type number by given tag name found in xml file
|
||||
*
|
||||
* @param tagName a string of tag name
|
||||
* @param defaultVal value returned if no value or invalid value is found
|
||||
* @return value found
|
||||
*/
|
||||
public double getDoubleByTagName(String tagName, double defaultVal) {
|
||||
double val = defaultVal;
|
||||
try {
|
||||
Node node = this.doc.getElementsByTagName(tagName).item(0);
|
||||
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element element = (Element) node;
|
||||
val = Double.valueOf(element.getTextContent());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} finally {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string by given tag name found in xml file
|
||||
*
|
||||
* @param tagName a string of tag name
|
||||
* @param defaultVal a string returned if no value or invalid value is found
|
||||
* @return string found
|
||||
*/
|
||||
public String getStringByTagName(String tagName, String defaultVal) {
|
||||
String string = defaultVal;
|
||||
try {
|
||||
Node node = this.doc.getElementsByTagName(tagName).item(0);
|
||||
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element element = (Element) node;
|
||||
string = element.getTextContent();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} finally {
|
||||
return string;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
package seng302.models.parsers;
|
||||
|
||||
import org.w3c.dom.*;
|
||||
import seng302.models.mark.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* parse a course xml file
|
||||
* Created by Haoming Yin (hyi25) on 16/3/2017
|
||||
*/
|
||||
public class CourseParser extends FileParser {
|
||||
|
||||
private Document doc;
|
||||
private HashMap<String, Mark> marks = new HashMap<>();
|
||||
|
||||
public CourseParser(String path) {
|
||||
super(path);
|
||||
this.doc = this.parseFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* create a mark by given node
|
||||
*
|
||||
* @param node
|
||||
* @return a mark, or null if fails to create a mark
|
||||
*/
|
||||
private SingleMark generateSingleMark(Node node) {
|
||||
try {
|
||||
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element element = (Element) node;
|
||||
String name = element.getElementsByTagName("name").item(0).getTextContent();
|
||||
double lat = Double.valueOf(element.getElementsByTagName("latitude").item(0).getTextContent());
|
||||
double lon = Double.valueOf(element.getElementsByTagName("longitude").item(0).getTextContent());
|
||||
int id = Integer.valueOf(element.getElementsByTagName("id").item(0).getTextContent());
|
||||
SingleMark singleMark = new SingleMark(name, lat, lon, id);
|
||||
return singleMark;
|
||||
} else {
|
||||
throw new NoSuchElementException("Cannot generate a mark by given node.");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* generate an arrayList of gates
|
||||
*
|
||||
* @return an arrayList of gates, or null if no gate has been found.
|
||||
*/
|
||||
private void generateGateMarks() {
|
||||
ArrayList<GateMark> gateMarks = new ArrayList<>();
|
||||
|
||||
try {
|
||||
NodeList nodes = doc.getElementsByTagName("gate");
|
||||
|
||||
for (int i = 0; i < nodes.getLength(); i++) {
|
||||
Node node = nodes.item(i);
|
||||
|
||||
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element element = (Element) node;
|
||||
String name = element.getElementsByTagName("name").item(0).getTextContent();
|
||||
SingleMark mark1 = generateSingleMark(element.getElementsByTagName("mark").item(0));
|
||||
SingleMark mark2 = generateSingleMark(element.getElementsByTagName("mark").item(1));
|
||||
GateMark gateMark;
|
||||
if (name.equals("Start") || name.equals("Finish"))
|
||||
gateMark = new GateMark(name, MarkType.CLOSED_GATE, mark1, mark2, mark1.getLatitude(), mark1.getLongitude());
|
||||
else
|
||||
gateMark = new GateMark(name, MarkType.OPEN_GATE, mark1, mark2, mark1.getLatitude(), mark1.getLongitude());
|
||||
marks.put(name, gateMark);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* generate an arrayList of marks
|
||||
*
|
||||
* @return an arrayList of marks, or null if no gate has been found.
|
||||
*/
|
||||
private void generateSingleMarks() {
|
||||
ArrayList<SingleMark> singleMarks = new ArrayList<>();
|
||||
|
||||
try {
|
||||
// find the "marks" tag
|
||||
Node node = doc.getElementsByTagName("marks").item(0);
|
||||
// iterate all "marks"'s children
|
||||
for (Node n = node.getFirstChild(); n != null; n = n.getNextSibling()) {
|
||||
// if node's tag name is "mark"
|
||||
if (n.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element element = (Element) n;
|
||||
if (element.getNodeName() == "mark") {
|
||||
Mark mark = generateSingleMark(n);
|
||||
marks.put(mark.getName(), mark);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return the order of all the marks along a course
|
||||
*
|
||||
* @return an arrayList of the names of ordered course marks
|
||||
*/
|
||||
private ArrayList<String> getOrder() {
|
||||
ArrayList<String> markOrder = new ArrayList<>();
|
||||
|
||||
try {
|
||||
Node orderNode = doc.getElementsByTagName("order").item(0);
|
||||
for (Node node = orderNode.getFirstChild(); node != null; node = node.getNextSibling()) {
|
||||
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element element = (Element) node;
|
||||
String name = element.getTextContent();
|
||||
markOrder.add(name);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return markOrder;
|
||||
}
|
||||
|
||||
public ArrayList<Mark> getCourse() {
|
||||
generateSingleMarks();
|
||||
generateGateMarks();
|
||||
ArrayList<Mark> course = new ArrayList<>();
|
||||
try {
|
||||
for (String mark : getOrder()) {
|
||||
course.add(marks.get(mark));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return course;
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package seng302.models.parsers;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringReader;
|
||||
|
||||
/**
|
||||
* Created by Haoming Yin (hyi25) on 16/3/2017
|
||||
*/
|
||||
public abstract class FileParser {
|
||||
|
||||
private String filePath;
|
||||
|
||||
public FileParser() {}
|
||||
|
||||
public FileParser(String path) {
|
||||
this.filePath = path;
|
||||
}
|
||||
|
||||
protected Document parseFile() {
|
||||
try {
|
||||
InputStream is = getClass().getResourceAsStream(this.filePath);
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||
Document doc = builder.parse(is);
|
||||
// optional, in order to recover info from broken line.
|
||||
doc.getDocumentElement().normalize();
|
||||
return doc;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected Document parseFile(String xmlString) {
|
||||
try {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||
Document doc = builder.parse(new InputSource(new StringReader(xmlString)));
|
||||
// optional, in order to recover info from broken line.
|
||||
doc.getDocumentElement().normalize();
|
||||
return doc;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
//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<Yacht> getBoats() {
|
||||
// ArrayList<Yacht> 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;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
//}
|
||||
//
|
||||
@@ -5,6 +5,7 @@ import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import seng302.models.Yacht;
|
||||
import seng302.models.mark.MarkType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -301,6 +302,7 @@ public class XMLParser {
|
||||
public class CompoundMark {
|
||||
private Integer markID;
|
||||
private String cMarkName;
|
||||
private MarkType markType;
|
||||
private ArrayList<Mark> marks;
|
||||
|
||||
CompoundMark(Node compoundMark) {
|
||||
@@ -308,6 +310,12 @@ public class XMLParser {
|
||||
this.markID = getNodeAttributeInt(compoundMark, "CompoundMarkID");
|
||||
this.cMarkName = getNodeAttributeString(compoundMark, "Name");
|
||||
NodeList childMarks = compoundMark.getChildNodes();
|
||||
if (childMarks.getLength() > 1){
|
||||
markType = MarkType.OPEN_GATE;
|
||||
} else {
|
||||
markType = MarkType.SINGLE_MARK;
|
||||
}
|
||||
|
||||
for (int i = 0; i < childMarks.getLength(); i++) {
|
||||
Node markNode = childMarks.item(i);
|
||||
if (markNode.getNodeName().equals("Mark")) {
|
||||
|
||||
Reference in New Issue
Block a user