You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
184 lines
6.4 KiB
184 lines
6.4 KiB
package seng302.Controllers;
|
|
|
|
import javafx.animation.AnimationTimer;
|
|
import javafx.application.Platform;
|
|
import javafx.collections.FXCollections;
|
|
import javafx.collections.ObservableList;
|
|
import javafx.fxml.FXML;
|
|
import javafx.scene.control.Label;
|
|
import javafx.scene.control.TableColumn;
|
|
import javafx.scene.control.TableView;
|
|
import javafx.scene.control.cell.PropertyValueFactory;
|
|
import javafx.scene.layout.AnchorPane;
|
|
import javafx.scene.layout.GridPane;
|
|
import seng302.Mock.StreamedCourse;
|
|
import seng302.Model.Boat;
|
|
import seng302.Model.RaceClock;
|
|
import seng302.VisualiserInput;
|
|
|
|
import java.io.IOException;
|
|
import java.net.Socket;
|
|
import java.net.URL;
|
|
import java.time.format.DateTimeFormatter;
|
|
import java.util.List;
|
|
import java.util.Observable;
|
|
import java.util.Observer;
|
|
import java.util.ResourceBundle;
|
|
|
|
/**
|
|
* Created by esa46 on 6/04/17.
|
|
*/
|
|
public class StartController extends Controller implements Observer {
|
|
|
|
@FXML private GridPane start;
|
|
@FXML private AnchorPane startWrapper;
|
|
@FXML private Label raceTitleLabel;
|
|
@FXML private Label raceStartLabel;
|
|
|
|
@FXML private TableView<Boat> boatNameTable;
|
|
@FXML private TableColumn<Boat, String> boatNameColumn;
|
|
@FXML private TableColumn<Boat, String> boatCodeColumn;
|
|
@FXML private Label timeZoneTime;
|
|
@FXML private Label timer;
|
|
@FXML private Label raceStatusLabel;
|
|
|
|
//@FXML Button fifteenMinButton;
|
|
|
|
private RaceClock raceClock;
|
|
|
|
private StreamedCourse raceData;
|
|
private int raceStat;
|
|
|
|
private VisualiserInput visualiserInput;
|
|
|
|
///Tracks whether the race has been started (that is, has startRaceNoScaling() be called).
|
|
private boolean hasRaceStarted = false;
|
|
|
|
/**
|
|
* Begins the race with a scale factor of 1
|
|
*/
|
|
private void startRaceNoScaling() {
|
|
while(visualiserInput.getRaceStatus() == null);//TODO probably remove this.
|
|
|
|
countdownTimer();
|
|
}
|
|
|
|
@Override
|
|
public void initialize(URL location, ResourceBundle resources){
|
|
raceData = new StreamedCourse();
|
|
raceData.addObserver(this);
|
|
}
|
|
|
|
public AnchorPane startWrapper(){
|
|
return startWrapper;
|
|
}
|
|
|
|
private void initialiseTables() {
|
|
List<Boat> boats = raceData.getBoats();
|
|
ObservableList<Boat> observableBoats = FXCollections.observableArrayList(boats);
|
|
|
|
boatNameTable.setItems(observableBoats);
|
|
boatNameColumn.setCellValueFactory(cellData -> cellData.getValue().getName());
|
|
boatCodeColumn.setCellValueFactory(new PropertyValueFactory<>("abbrev"));
|
|
}
|
|
|
|
/**
|
|
* Countdown timer until race starts.
|
|
*/
|
|
private void countdownTimer() {
|
|
new AnimationTimer() {
|
|
@Override
|
|
public void handle(long arg0) {
|
|
raceStat = visualiserInput.getRaceStatus().getRaceStatus();
|
|
raceStatusLabel.setText("Race Status: " + visualiserInput.getRaceStatus().getRaceStatus());
|
|
if (raceStat==2 || raceStat == 3) {
|
|
System.out.println("countdown finished!");//TEMP DEBUG REMOVE
|
|
stop();
|
|
|
|
startWrapper.setVisible(false);
|
|
start.setVisible(false);
|
|
|
|
parent.beginRace(visualiserInput, raceClock);
|
|
}
|
|
}
|
|
}.start();
|
|
}
|
|
|
|
private void setRaceClock() {
|
|
raceClock = new RaceClock(raceData.getZonedDateTime());
|
|
timeZoneTime.textProperty().bind(raceClock.timeStringProperty());
|
|
raceClock.run();
|
|
}
|
|
|
|
private void setStartingTime() {
|
|
String dateFormat = "'Starting time:' HH:mm dd/MM/YYYY";
|
|
Platform.runLater(()-> {
|
|
long utcTime = visualiserInput.getRaceStatus().getExpectedStartTime();
|
|
raceClock.setStartingTime(raceClock.getLocalTime(utcTime));
|
|
raceStartLabel.setText(DateTimeFormatter.ofPattern(dateFormat).format(raceClock.getStartingTime()));
|
|
timer.textProperty().bind(raceClock.durationProperty());
|
|
});
|
|
}
|
|
|
|
private void setCurrentTime() {
|
|
Platform.runLater(()->
|
|
raceClock.setUTCTime(visualiserInput.getRaceStatus().getCurrentTime())
|
|
);
|
|
}
|
|
|
|
@Override
|
|
public void update(Observable o, Object arg) {
|
|
if(o instanceof StreamedCourse) {
|
|
StreamedCourse streamedCourse = (StreamedCourse) o;
|
|
if(streamedCourse.hasReadBoats()) {
|
|
initialiseTables();
|
|
}
|
|
if(streamedCourse.hasReadRegatta()) {
|
|
Platform.runLater(() -> raceTitleLabel.setText(streamedCourse.getRegattaName()));
|
|
}
|
|
if (streamedCourse.hasReadCourse()) {
|
|
Platform.runLater(() -> {
|
|
setRaceClock();
|
|
if(visualiserInput.getRaceStatus() == null){
|
|
return;//TEMP BUG FIX if the race isn't sending race status messages (our mock currently doesn't), then it would block the javafx thread with the previous while loop.
|
|
}// TODO - replace with observer on VisualiserInput
|
|
setStartingTime();
|
|
setCurrentTime();
|
|
});
|
|
}
|
|
|
|
//TODO this is a somewhat temporary fix for when not all of the race data (boats, course, regatta) is received in time.
|
|
//Previously, startRaceNoScaling was called in the enterLobby function after the visualiserInput was started, but when connecting to the official data source it sometimes didn't send all of the race data, causing startRaceNoScaling to start, even though we didn't have enough information to start it.
|
|
if (streamedCourse.hasReadBoats() && streamedCourse.hasReadCourse() && streamedCourse.hasReadRegatta()) {
|
|
Platform.runLater(() -> {
|
|
if (!this.hasRaceStarted) {
|
|
if(visualiserInput.getRaceStatus() == null) {
|
|
}
|
|
else {
|
|
this.hasRaceStarted = true;
|
|
startRaceNoScaling();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Show starting information for a race given a socket.
|
|
* @param socket network source of information
|
|
*/
|
|
public void enterLobby(Socket socket) {
|
|
startWrapper.setVisible(true);
|
|
try {
|
|
visualiserInput = new VisualiserInput(socket, raceData);
|
|
new Thread(visualiserInput).start();
|
|
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
}
|