Merge branch '1124b_Fixing_Update_Order' into 'develop'

Updating Yacht Positions / Finish Screen

# Change Log 
* Yachts now update their position on the side bar as they pass marks 
* Finish screen is now displayed correctly at end of race, populated by races 

# Testing 
* Manual test log performed


See merge request !63
This commit is contained in:
Zhi You Tan
2017-08-17 00:11:13 +12:00
9 changed files with 83 additions and 36 deletions
@@ -437,6 +437,7 @@ public class GameState implements Runnable {
} }
if (hasProgressed) { if (hasProgressed) {
yacht.incrementLegNumber();
sendMarkRoundingMessage(yacht); sendMarkRoundingMessage(yacht);
logMarkRounding(yacht); logMarkRounding(yacht);
yacht.setHasPassedLine(false); yacht.setHasPassedLine(false);
@@ -227,7 +227,8 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
for (Player player : GameState.getPlayers()) { for (Player player : GameState.getPlayers()) {
ServerYacht y = player.getYacht(); ServerYacht y = player.getYacht();
BoatSubMessage m = new BoatSubMessage(y.getSourceId(), y.getBoatStatus(), 0, BoatSubMessage m = new BoatSubMessage(y.getSourceId(), y.getBoatStatus(),
y.getLegNumber(),
0, 0, 1234L, 0, 0, 1234L,
1234L); 1234L);
boatSubMessages.add(m); boatSubMessages.add(m);
+9 -2
View File
@@ -31,13 +31,13 @@ public class ClientYacht extends Observable {
private Logger logger = LoggerFactory.getLogger(ClientYacht.class); private Logger logger = LoggerFactory.getLogger(ClientYacht.class);
//BOTH AFAIK
private String boatType; private String boatType;
private Integer sourceId; private Integer sourceId;
private String hullID; //matches HullNum in the XML spec. private String hullID; //matches HullNum in the XML spec.
private String shortName; private String shortName;
private String boatName; private String boatName;
private String country; private String country;
private Integer position;
private Long estimateTimeAtFinish; private Long estimateTimeAtFinish;
private Boolean sailIn = true; private Boolean sailIn = true;
@@ -50,7 +50,6 @@ public class ClientYacht extends Observable {
private Integer boatStatus; private Integer boatStatus;
private Double currentVelocity; private Double currentVelocity;
//CLIENT SIDE
private List<YachtLocationListener> locationListeners = new ArrayList<>(); private List<YachtLocationListener> locationListeners = new ArrayList<>();
private ReadOnlyDoubleWrapper velocityProperty = new ReadOnlyDoubleWrapper(); private ReadOnlyDoubleWrapper velocityProperty = new ReadOnlyDoubleWrapper();
private ReadOnlyLongWrapper timeTillNextProperty = new ReadOnlyLongWrapper(); private ReadOnlyLongWrapper timeTillNextProperty = new ReadOnlyLongWrapper();
@@ -189,6 +188,14 @@ public class ClientYacht extends Observable {
return location; return location;
} }
public Integer getPosition() {
return position;
}
public void setPosition(Integer position) {
this.position = position;
}
public void toggleSail() { public void toggleSail() {
sailIn = !sailIn; sailIn = !sailIn;
} }
@@ -2,7 +2,13 @@ package seng302.model;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Observable;
import java.util.TimeZone; import java.util.TimeZone;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import seng302.model.stream.parser.RaceStartData; import seng302.model.stream.parser.RaceStartData;
import seng302.model.stream.parser.RaceStatusData; import seng302.model.stream.parser.RaceStatusData;
@@ -21,8 +27,10 @@ public class RaceState {
private long expectedStartTime; private long expectedStartTime;
private boolean isRaceStarted = false; private boolean isRaceStarted = false;
long timeTillStart; long timeTillStart;
private ObservableList<ClientYacht> playerPositions;
public RaceState() { public RaceState() {
playerPositions = FXCollections.observableArrayList();
} }
public void updateState (RaceStatusData data) { public void updateState (RaceStatusData data) {
@@ -69,4 +77,17 @@ public class RaceState {
public boolean isRaceStarted () { public boolean isRaceStarted () {
return isRaceStarted; return isRaceStarted;
} }
public void setBoats(Collection<ClientYacht> clientYachts) {
playerPositions.setAll(clientYachts);
}
public void sortPlayers() {
playerPositions.sort((yacht1, yacht2) -> Integer.compare(yacht2.getLegNumber(),
yacht1.getLegNumber()));
}
public ObservableList<ClientYacht> getPlayerPositions() {
return playerPositions;
}
} }
@@ -40,6 +40,7 @@ public class ServerYacht extends Observable {
private Double currentVelocity; private Double currentVelocity;
private Boolean isAuto; private Boolean isAuto;
private Double autoHeading; private Double autoHeading;
private Integer legNumber;
//Mark Rounding //Mark Rounding
private Integer currentMarkSeqID; private Integer currentMarkSeqID;
@@ -65,6 +66,7 @@ public class ServerYacht extends Observable {
this.heading = 120.0; //In degrees this.heading = 120.0; //In degrees
this.currentVelocity = 0d; //in mms-1 this.currentVelocity = 0d; //in mms-1
this.currentMarkSeqID = 0; this.currentMarkSeqID = 0;
this.legNumber = 0;
this.hasEnteredRoundingZone = false; this.hasEnteredRoundingZone = false;
this.hasPassedLine = false; this.hasPassedLine = false;
@@ -381,5 +383,12 @@ public class ServerYacht extends Observable {
return hasPassedLine; return hasPassedLine;
} }
public void incrementLegNumber() {
legNumber++;
}
public Integer getLegNumber() {
return legNumber;
}
} }
@@ -95,13 +95,8 @@ public class StreamParser {
boatID = bytesToLong( boatID = bytesToLong(
Arrays.copyOfRange(payload, 24 + (i * 20), 28 + (i * 20))); Arrays.copyOfRange(payload, 24 + (i * 20), 28 + (i * 20)));
boatStatus = (int) payload[28 + (i * 20)]; boatStatus = (int) payload[28 + (i * 20)];
// setBoatLegPosition(boat, (int) payload[29 + (i * 20)]);
// boat.setPenaltiesAwarded((int) payload[30 + (i * 20)]);
// boat.setPenaltiesServed((int) payload[31 + (i * 20)]);
estTimeAtNextMark = bytesToLong( estTimeAtNextMark = bytesToLong(
Arrays.copyOfRange(payload, 32 + (i * 20), 38 + (i * 20))); Arrays.copyOfRange(payload, 32 + (i * 20), 38 + (i * 20)));
// boat.setEstimateTimeTillNextMark(estTimeAtNextMark);
estTimeAtFinish = bytesToLong( estTimeAtFinish = bytesToLong(
Arrays.copyOfRange(payload, 38 + (i * 20), 44 + (i * 20))); Arrays.copyOfRange(payload, 38 + (i * 20), 44 + (i * 20)));
leg = (int) payload[29 + (i * 20)]; leg = (int) payload[29 + (i * 20)];
@@ -15,6 +15,7 @@ import javafx.scene.layout.Pane;
import seng302.gameServer.GameState; import seng302.gameServer.GameState;
import seng302.gameServer.MainServerThread; import seng302.gameServer.MainServerThread;
import seng302.gameServer.server.messages.BoatAction; import seng302.gameServer.server.messages.BoatAction;
import seng302.gameServer.server.messages.BoatStatus;
import seng302.model.ClientYacht; import seng302.model.ClientYacht;
import seng302.model.RaceState; import seng302.model.RaceState;
import seng302.model.stream.packets.StreamPacket; import seng302.model.stream.packets.StreamPacket;
@@ -27,6 +28,7 @@ import seng302.model.stream.xml.parser.RaceXMLData;
import seng302.model.stream.xml.parser.RegattaXMLData; import seng302.model.stream.xml.parser.RegattaXMLData;
import seng302.utilities.StreamParser; import seng302.utilities.StreamParser;
import seng302.utilities.XMLParser; import seng302.utilities.XMLParser;
import seng302.visualiser.controllers.FinishScreenViewController;
import seng302.visualiser.controllers.LobbyController; import seng302.visualiser.controllers.LobbyController;
import seng302.visualiser.controllers.LobbyController.CloseStatus; import seng302.visualiser.controllers.LobbyController.CloseStatus;
import seng302.visualiser.controllers.RaceViewController; import seng302.visualiser.controllers.RaceViewController;
@@ -195,6 +197,9 @@ public class GameClient {
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
FinishScreenViewController controller = fxmlLoader.getController();
controller.setFinishers(raceState.getPlayerPositions());
} }
private void parsePackets() { private void parsePackets() {
@@ -239,6 +244,7 @@ public class GameClient {
allBoatsMap.forEach((id, boat) -> allBoatsMap.forEach((id, boat) ->
clientLobbyList.add(id + " " + boat.getBoatName()) clientLobbyList.add(id + " " + boat.getBoatName())
); );
raceState.setBoats(allBoatsMap.values());
break; break;
case RACE_START_STATUS: case RACE_START_STATUS:
@@ -315,32 +321,34 @@ public class GameClient {
} }
boolean raceFinished = true; boolean raceFinished = true;
for (ClientYacht yacht : allBoatsMap.values()) { for (ClientYacht yacht : allBoatsMap.values()) {
if (yacht.getBoatStatus() != 3) { if (yacht.getBoatStatus() != BoatStatus.FINISHED.getCode()) {
raceFinished = false; raceFinished = false;
} }
} }
if (raceFinished == true) {
close();
loadFinishScreenView();
}
for (long[] boatData : data.getBoatData()) { for (long[] boatData : data.getBoatData()) {
ClientYacht clientYacht = allBoatsMap.get((int) boatData[0]); ClientYacht clientYacht = allBoatsMap.get((int) boatData[0]);
clientYacht.setEstimateTimeTillNextMark(raceState.getRaceTime() - boatData[1]); clientYacht.setEstimateTimeTillNextMark(raceState.getRaceTime() - boatData[1]);
clientYacht.setEstimateTimeAtFinish(boatData[2]); clientYacht.setEstimateTimeAtFinish(boatData[2]);
int legNumber = (int) boatData[3]; int legNumber = (int) boatData[3];
clientYacht.setLegNumber(legNumber);
clientYacht.setBoatStatus((int) boatData[4]); clientYacht.setBoatStatus((int) boatData[4]);
if (legNumber != clientYacht.getLegNumber()) { if (legNumber != clientYacht.getLegNumber()) {
int placing = 1; clientYacht.setLegNumber(legNumber);
for (ClientYacht otherClientYacht : allBoatsMap.values()) { updatePlayerPositions();
if (otherClientYacht.getSourceId() != boatData[0] &&
clientYacht.getLegNumber() <= otherClientYacht.getLegNumber())
placing++;
}
clientYacht.setPositionInteger(placing);
} }
} }
if (raceFinished) {
close();
loadFinishScreenView();
}
}
}
private void updatePlayerPositions() {
raceState.sortPlayers();
for (ClientYacht yacht : raceState.getPlayerPositions()) {
yacht.setPosition(raceState.getPlayerPositions().indexOf(yacht) + 1);
} }
} }
@@ -3,6 +3,7 @@ package seng302.visualiser.controllers;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.ResourceBundle; import java.util.ResourceBundle;
@@ -61,7 +62,7 @@ public class FinishScreenViewController implements Initializable {
finishOrderTable.refresh(); finishOrderTable.refresh();
} }
public void setFinishers(List<ClientYacht> participants) { public void setFinishers(Collection<ClientYacht> participants) {
List<ClientYacht> sorted = new ArrayList<>(participants); List<ClientYacht> sorted = new ArrayList<>(participants);
sorted.sort(Comparator.comparingInt(ClientYacht::getPositionInteger)); sorted.sort(Comparator.comparingInt(ClientYacht::getPositionInteger));
finishOrderTable.getItems().setAll(sorted); finishOrderTable.getItems().setAll(sorted);
@@ -11,6 +11,8 @@ import java.util.concurrent.TimeUnit;
import javafx.animation.Timeline; import javafx.animation.Timeline;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.geometry.Point2D; import javafx.geometry.Point2D;
@@ -117,6 +119,15 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
initialiseBoatSelectionComboBox(); initialiseBoatSelectionComboBox();
initialiseSparkLine(); initialiseSparkLine();
raceState.getPlayerPositions().addListener((ListChangeListener<ClientYacht>) c -> {
while (c.next()) {
if (c.wasPermutated()) {
updateOrder(raceState.getPlayerPositions());
}
}
});
updateOrder(raceState.getPlayerPositions());
gameView = new GameView(); gameView = new GameView();
gameView.setFrameRateFXText(fpsDisplay); gameView.setFrameRateFXText(fpsDisplay);
Platform.runLater(() -> contentAnchorPane.getChildren().add(0, gameView)); Platform.runLater(() -> contentAnchorPane.getChildren().add(0, gameView));
@@ -318,7 +329,6 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
public void run() { public void run() {
updateRaceTime(); updateRaceTime();
updateWind(); updateWind();
updateOrder();
// updateSparkLine(); // updateSparkLine();
} }
}, 0, 1000); }, 0, 1000);
@@ -381,26 +391,20 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
* Updates the order of the yachts as from the StreamParser and sets them in the yacht order * Updates the order of the yachts as from the StreamParser and sets them in the yacht order
* section * section
*/ */
private void updateOrder() { private void updateOrder(ObservableList<ClientYacht> yachts) {
// positionVbox.getChildren().removeAll();
// positionVbox.getStylesheets().add(getClass().getResource("/css/master.css").toString());
// list of racing yacht id
List<ClientYacht> sorted = new ArrayList<>(participants.values());
sorted.sort(Comparator.comparingInt(ClientYacht::getPositionInteger));
List<Text> vboxEntries = new ArrayList<>(); List<Text> vboxEntries = new ArrayList<>();
for (ClientYacht clientYacht : sorted) { for (int i = 0; i < yachts.size(); i++) {
// System.out.println("yacht == null " + String.valueOf(yacht == null)); // System.out.println("yacht == null " + String.valueOf(yacht == null));
if (clientYacht.getBoatStatus() == 3) { // 3 is finish status if (yachts.get(i).getBoatStatus() == 3) { // 3 is finish status
Text textToAdd = new Text(clientYacht.getPositionInteger() + ". " + Text textToAdd = new Text(i + 1 + ". " +
clientYacht.getShortName() + " (Finished)"); yachts.get(i).getShortName() + " (Finished)");
textToAdd.setFill(Paint.valueOf("#d3d3d3")); textToAdd.setFill(Paint.valueOf("#d3d3d3"));
vboxEntries.add(textToAdd); vboxEntries.add(textToAdd);
} else { } else {
Text textToAdd = new Text(clientYacht.getPositionInteger() + ". " + Text textToAdd = new Text(i + 1 + ". " +
clientYacht.getShortName() + " "); yachts.get(i).getShortName() + " ");
textToAdd.setFill(Paint.valueOf("#d3d3d3")); textToAdd.setFill(Paint.valueOf("#d3d3d3"));
textToAdd.setStyle(""); textToAdd.setStyle("");
vboxEntries.add(textToAdd); vboxEntries.add(textToAdd);