# Conflicts:
#	visualiser/src/main/java/seng302/Controllers/MainController.java
#	visualiser/src/main/java/seng302/Controllers/StartController.java
#	visualiser/src/main/java/seng302/Model/Race.java
main
David Wu 9 years ago
commit 61ecdc2269

@ -47,6 +47,10 @@ public class RaceStatus extends AC35Data{
return raceID; return raceID;
} }
/**
* @deprecated use status booleans
* @return race status number
*/
public int getRaceStatus() public int getRaceStatus()
{ {
return raceStatus; return raceStatus;
@ -76,4 +80,48 @@ public class RaceStatus extends AC35Data{
{ {
return boatStatusMessages; return boatStatusMessages;
} }
public boolean isNotActive() {
return raceStatus == 0;
}
public boolean isWarning() {
return raceStatus == 1;
}
public boolean isPreparatory() {
return raceStatus == 2;
}
public boolean isStarted() {
return raceStatus == 3;
}
public boolean isFinished() {
return raceStatus == 4;
}
public boolean isRetired() {
return raceStatus == 5;
}
public boolean isAbandoned() {
return raceStatus == 6;
}
public boolean isPostponed() {
return raceStatus == 7;
}
public boolean isTerminated() {
return raceStatus == 8;
}
public boolean isStartTimeSet() {
return raceStatus != 9;
}
public boolean isPrestart() {
return raceStatus == 10;
}
} }

@ -5,6 +5,7 @@ import javafx.fxml.FXML;
import javafx.scene.layout.AnchorPane; import javafx.scene.layout.AnchorPane;
import seng302.Model.Boat; import seng302.Model.Boat;
import seng302.Model.BoatInRace; import seng302.Model.BoatInRace;
import seng302.Model.RaceClock;
import seng302.RaceDataSource; import seng302.RaceDataSource;
import seng302.VisualiserInput; import seng302.VisualiserInput;
@ -25,8 +26,8 @@ public class MainController extends Controller {
@FXML @FXML
FinishController finishController; FinishController finishController;
public void beginRace(VisualiserInput visualiserInput) { public void beginRace(VisualiserInput visualiserInput, RaceClock raceClock) {
raceController.startRace(visualiserInput); raceController.startRace(visualiserInput, raceClock);
} }
public void enterLobby(Socket socket) { public void enterLobby(Socket socket) {

@ -123,7 +123,7 @@ public class RaceController extends Controller {
* *
* @param visualiserInput input from network * @param visualiserInput input from network
*/ */
public void startRace(VisualiserInput visualiserInput) { public void startRace(VisualiserInput visualiserInput, RaceClock raceClock) {
StreamedRace newRace = new StreamedRace(visualiserInput, this); StreamedRace newRace = new StreamedRace(visualiserInput, this);
//newRace.initialiseBoats(); //newRace.initialiseBoats();
@ -148,8 +148,8 @@ public class RaceController extends Controller {
race.setVisible(true); race.setVisible(true);
//Initialize save annotation array, fps listener, and annotation listeners //Initialize save annotation array, fps listener, and annotation listeners
RaceClock raceClock = new RaceClock(visualiserInput.getCourse().getZonedDateTime());
timeZone.setText(raceClock.getTimeZone()); timeZone.setText(raceClock.getTimeZone());
timer.textProperty().bind(raceClock.durationProperty());
initializeFPS(); initializeFPS();
initializeAnnotations(); initializeAnnotations();
@ -168,7 +168,7 @@ public class RaceController extends Controller {
* @param time time that the label will be updated to * @param time time that the label will be updated to
*/ */
public void setTimer(String time) { public void setTimer(String time) {
timer.setText(time); //timer.setText(time);
} }
/** /**

@ -22,6 +22,8 @@ import java.net.Socket;
import java.net.URL; import java.net.URL;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.*; import java.util.*;
@ -41,14 +43,14 @@ public class StartController extends Controller implements Observer {
@FXML private Label timeZoneTime; @FXML private Label timeZoneTime;
@FXML private Label timer; @FXML private Label timer;
@FXML private Label raceStatusLabel; @FXML private Label raceStatusLabel;
@FXML private int PRERACE_TIME = 10;
private ZonedDateTime startingTime;
//@FXML Button fifteenMinButton; //@FXML Button fifteenMinButton;
private RaceClock raceClock; private RaceClock raceClock;
private StreamedCourse raceData; private StreamedCourse raceData;
private long timeLeft = 1;
private int raceStat; private int raceStat;
private VisualiserInput visualiserInput; private VisualiserInput visualiserInput;
@ -86,47 +88,21 @@ public class StartController extends Controller implements Observer {
boatCodeColumn.setCellValueFactory(new PropertyValueFactory<>("abbrev")); boatCodeColumn.setCellValueFactory(new PropertyValueFactory<>("abbrev"));
} }
/**
* Updates the calculated time to the timer label
*
* @param time The calculated time from calcTimer() method
*/
protected void updateTime(String time) {
Platform.runLater(() -> {
timer.setText(time);
});
}
/** /**
* Countdown timer until race starts. * Countdown timer until race starts.
*/ */
protected void countdownTimer() { protected void countdownTimer() {
new AnimationTimer() { new AnimationTimer() {
long currentTime = System.currentTimeMillis();
long startTime = currentTime + PRERACE_TIME;
DateFormat timerFormat = new SimpleDateFormat("'Race Clock:' -HH:mm:ss");
@Override @Override
public void handle(long arg0) { public void handle(long arg0) {
System.out.println(raceStat);
timeLeft = startTime - currentTime;
raceStat = visualiserInput.getRaceStatus().getRaceStatus(); raceStat = visualiserInput.getRaceStatus().getRaceStatus();
raceStatusLabel.setText("Race Status: " + visualiserInput.getRaceStatus().getRaceStatus()); raceStatusLabel.setText("Race Status: " + visualiserInput.getRaceStatus().getRaceStatus());
if (raceStat==2 || raceStat == 3) { if (raceStat==2 || raceStat == 3) {
updateTime("Race is starting...");
stop(); stop();
parent.beginRace(visualiserInput); parent.beginRace(visualiserInput, raceClock);
startWrapper.setVisible(false); startWrapper.setVisible(false);
start.setVisible(false); start.setVisible(false);
} }
else if (raceStat==4 || raceStat==8) {
updateTime("Race has ended. Waiting for next race.");
}
else if (raceStat==10 || raceStat==1){
updateTime(timerFormat.format(currentTime));
}
currentTime = System.currentTimeMillis();
} }
}.start(); }.start();
} }
@ -134,26 +110,22 @@ public class StartController extends Controller implements Observer {
private void setRaceClock() { private void setRaceClock() {
raceClock = new RaceClock(raceData.getZonedDateTime()); raceClock = new RaceClock(raceData.getZonedDateTime());
timeZoneTime.textProperty().bind(raceClock.timeStringProperty()); timeZoneTime.textProperty().bind(raceClock.timeStringProperty());
raceClock.run();
new AnimationTimer() {
@Override
public void handle(long arg0) {
raceClock.updateTime();
}
}.start();
} }
private void setStartingTime() { private void setStartingTime() {
String dateFormat = "'Starting time:' HH:mm dd/MM/YYYY"; String dateFormat = "'Starting time:' HH:mm dd/MM/YYYY";
Platform.runLater(()-> { Platform.runLater(()-> {
long utcTime = visualiserInput.getRaceStatus().getExpectedStartTime(); long utcTime = visualiserInput.getRaceStatus().getExpectedStartTime();
raceStartLabel.setText(DateTimeFormatter.ofPattern(dateFormat).format(raceClock.getLocalTime(utcTime))); raceClock.setStartingTime(raceClock.getLocalTime(utcTime));
raceStartLabel.setText(DateTimeFormatter.ofPattern(dateFormat).format(raceClock.getStartingTime()));
timer.textProperty().bind(raceClock.durationProperty());
}); });
} }
private void setCurrentTime() { private void setCurrentTime() {
Platform.runLater(()-> Platform.runLater(()->
raceClock.setTime(raceClock.getLocalTime(visualiserInput.getRaceStatus().getCurrentTime())) raceClock.setUTCTime(visualiserInput.getRaceStatus().getCurrentTime())
); );
} }
@ -168,8 +140,8 @@ public class StartController extends Controller implements Observer {
} }
if (((StreamedCourse) o).hasReadCourse()) { if (((StreamedCourse) o).hasReadCourse()) {
Platform.runLater(() -> { Platform.runLater(() -> {
while(visualiserInput.getRaceStatus() == null);
setRaceClock(); setRaceClock();
while(visualiserInput.getRaceStatus() == null); // TODO - replace with observer on VisualiserInput
setStartingTime(); setStartingTime();
setCurrentTime(); setCurrentTime();
}); });

@ -65,7 +65,9 @@ public class StreamedRace extends Race {
boat.setCurrentLeg(legs.get(legNumber)); boat.setCurrentLeg(legs.get(legNumber));
} }
if (boatStatus == BoatStatus.DNF) { if (boatStatus == BoatStatus.RACING) {
boat.addTrackPoint(boat.getCurrentPosition());
} else if (boatStatus == BoatStatus.DNF) {
boat.setDnf(true); boat.setDnf(true);
} else if (boatStatus == BoatStatus.FINISHED || legNumber == raceData.getLegs().size()) { } else if (boatStatus == BoatStatus.FINISHED || legNumber == raceData.getLegs().size()) {
boatsFinished++; boatsFinished++;

@ -22,7 +22,6 @@ import java.util.Random;
* Created by fwy13 on 3/03/17. * Created by fwy13 on 3/03/17.
*/ */
public abstract class Race implements Runnable { public abstract class Race implements Runnable {
//protected Boat[] startingBoats;
protected ObservableList<Boat> startingBoats; protected ObservableList<Boat> startingBoats;
protected List<Leg> legs; protected List<Leg> legs;
protected RaceController controller; protected RaceController controller;
@ -32,8 +31,6 @@ public abstract class Race implements Runnable {
protected int scaleFactor; protected int scaleFactor;
private int lastFPS = 20; private int lastFPS = 20;
private int PRERACE_TIME = 0; //time in milliseconds to pause during pre-race
private boolean timerEnabled = true; //boolean to determine if timer is ran
/** /**
* Initailiser for Race * Initailiser for Race
@ -105,81 +102,7 @@ public abstract class Race implements Runnable {
public void run() { public void run() {
setControllerListeners(); setControllerListeners();
initialiseBoats(); initialiseBoats();
if (timerEnabled) countdownTimer(); simulateRace();
//simulateRace();
}
/**
* Disable the timer
*/
public void disableTimer() {
timerEnabled = false;
}
/**
* Countdown timer until race starts. Use PRERACE_TIME to set countdown duration.
*/
protected void countdownTimer() {
new AnimationTimer() {
long currentTime = System.currentTimeMillis();
long startTime = currentTime + (PRERACE_TIME/scaleFactor);
long minutes;
long currentTimeInSeconds;
long remainingSeconds;
long hours;
long timeLeft;
@Override
public void handle(long arg0) {
timeLeft = startTime - currentTime;
if (timeLeft <= 0 && controller != null) {
updateTime("Race is starting...");
stop();
simulateRace();
} else {
currentTimeInSeconds = (timeLeft*scaleFactor) / 1000;
minutes = currentTimeInSeconds / 60;
remainingSeconds = currentTimeInSeconds % 60;
hours = minutes / 60;
minutes = minutes % 60;
if (controller != null) {
updateTime(String.format("Race clock: -%02d:%02d:%02d", hours, minutes, remainingSeconds));
}
}
currentTime = System.currentTimeMillis();
}
}.start();
}
/**
* Takes total time elapsed and format to hour:minute:second
*
* @return Formatted time as string
*/
protected String calcTimer() {
long minutes;
long currentTimeInSeconds;
long remainingSeconds;
long hours;
currentTimeInSeconds = (totalTimeElapsed * scaleFactor) / 1000;
minutes = currentTimeInSeconds / 60;
remainingSeconds = currentTimeInSeconds % 60;
hours = minutes / 60;
minutes = minutes % 60;
return String.format("Race clock: %02d:%02d:%02d", hours, minutes, remainingSeconds);
}
/**
* Updates the calculated time to the timer label
*
* @param time The calculated time from calcTimer() method
*/
protected void updateTime(String time) {
Platform.runLater(() -> {
controller.setTimer(time);
});
} }
@ -222,15 +145,12 @@ public abstract class Race implements Runnable {
if (boat != null && !boat.isFinished()) { if (boat != null && !boat.isFinished()) {
updatePosition(boat, Math.round(1000 / lastFPS) > 20 ? 15 : Math.round(1000 / lastFPS)); updatePosition(boat, Math.round(1000 / lastFPS) > 20 ? 15 : Math.round(1000 / lastFPS));
checkPosition(boat, totalTimeElapsed); checkPosition(boat, totalTimeElapsed);
boat.addTrackPoint(boat.getCurrentPosition());
} }
if (boat.isFinished()){ if (boat.isFinished()){
boatsFinished++; boatsFinished++;
} }
} }
//System.out.println(boatsFinished + ":" + startingBoats.size()); //System.out.println(boatsFinished + ":" + startingBoats.size());
if (timerEnabled)
updateTime(calcTimer());
} else { } else {
controller.finishRace(startingBoats); controller.finishRace(startingBoats);
stop(); stop();
@ -266,7 +186,6 @@ public abstract class Race implements Runnable {
*/ */
protected void setControllerListeners() { protected void setControllerListeners() {
if (controller != null) controller.setInfoTable(this); if (controller != null) controller.setInfoTable(this);
//if (finishController != null) finishController.setFinishTable(this);
} }
/** /**

@ -2,6 +2,7 @@ package seng302.Model;
import com.github.bfsmith.geotimezone.TimeZoneLookup; import com.github.bfsmith.geotimezone.TimeZoneLookup;
import com.github.bfsmith.geotimezone.TimeZoneResult; import com.github.bfsmith.geotimezone.TimeZoneResult;
import javafx.animation.AnimationTimer;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
import seng302.GPSCoordinate; import seng302.GPSCoordinate;
@ -17,15 +18,18 @@ import java.util.Date;
/** /**
* Created by Gondr on 19/04/2017. * Created by Gondr on 19/04/2017.
*/ */
public class RaceClock { public class RaceClock implements Runnable {
private long lastTime; private long lastTime;
private ZoneId zoneId; private ZoneId zoneId;
private ZonedDateTime time; private ZonedDateTime time;
private ZonedDateTime startingTime;
private StringProperty timeString; private StringProperty timeString;
private StringProperty duration;
public RaceClock(ZonedDateTime zonedDateTime) { public RaceClock(ZonedDateTime zonedDateTime) {
this.zoneId = zonedDateTime.getZone(); this.zoneId = zonedDateTime.getZone();
this.timeString = new SimpleStringProperty(); this.timeString = new SimpleStringProperty();
this.duration = new SimpleStringProperty();
this.time = zonedDateTime; this.time = zonedDateTime;
setTime(time); setTime(time);
} }
@ -44,6 +48,15 @@ public class RaceClock {
return LocalDateTime.now(zone).atZone(zone); return LocalDateTime.now(zone).atZone(zone);
} }
public void run() {
new AnimationTimer() {
@Override
public void handle(long now) {
updateTime();
}
}.start();
}
/** /**
* Sets time to arbitrary zoned time. * Sets time to arbitrary zoned time.
* *
@ -53,6 +66,13 @@ public class RaceClock {
this.time = time; this.time = time;
this.timeString.set(DateTimeFormatter.ofPattern("HH:mm:ss dd/MM/YYYY Z").format(time)); this.timeString.set(DateTimeFormatter.ofPattern("HH:mm:ss dd/MM/YYYY Z").format(time));
this.lastTime = System.currentTimeMillis(); this.lastTime = System.currentTimeMillis();
if(startingTime != null) {
long seconds = Duration.between(startingTime.toLocalDateTime(), time.toLocalDateTime()).getSeconds();
if(seconds < 0)
duration.set(String.format(String.format("Starting in: %02d:%02d:%02d", -seconds/3600, -(seconds%3600)/60, -seconds%60)));
else
duration.set(String.format(String.format("Time: %02d:%02d:%02d", seconds/3600, (seconds%3600)/60, seconds%60)));
}
} }
/** /**
@ -64,6 +84,14 @@ public class RaceClock {
setTime(utcTime.toInstant().atZone(this.zoneId)); setTime(utcTime.toInstant().atZone(this.zoneId));
} }
public ZonedDateTime getStartingTime() {
return startingTime;
}
public void setStartingTime(ZonedDateTime startingTime) {
this.startingTime = startingTime;
}
/** /**
* Get ZonedDateTime corresponding to local time zone and given UTC time. * Get ZonedDateTime corresponding to local time zone and given UTC time.
* @param time time in mills * @param time time in mills
@ -83,6 +111,14 @@ public class RaceClock {
setTime(time); setTime(time);
} }
public String getDuration() {
return duration.get();
}
public StringProperty durationProperty() {
return duration;
}
public String getTimeZone() { public String getTimeZone() {
return zoneId.toString(); return zoneId.toString();
} }

@ -203,10 +203,12 @@ public class ResizableRaceCanvas extends ResizableCanvas {
public void drawMarkers() { public void drawMarkers() {
for(Marker marker: markers) { for(Marker marker: markers) {
GraphCoordinate mark1 = this.map.convertGPS(marker.getMark1()); GraphCoordinate mark1 = this.map.convertGPS(marker.getMark1());
// removed drawing of lines between the marks as only
// the start and finish line should have a line drawn
if(marker.isCompoundMark()) { if(marker.isCompoundMark()) {
GraphCoordinate mark2 = this.map.convertGPS(marker.getMark2()); GraphCoordinate mark2 = this.map.convertGPS(marker.getMark2());
// TODO - improve colour coding of markers displayPoint(mark1, Color.LIMEGREEN);
displayLine(mark1, mark2, Color.GREEN); displayPoint(mark2, Color.LIMEGREEN);
} else { } else {
displayPoint(mark1, Color.GREEN); displayPoint(mark1, Color.GREEN);
} }

Loading…
Cancel
Save