Added empty data sources, to be used by VisualiserRace.
Created FrameRateTracker which can be used to track framerate. Updated RequestToJoinEnum and JoinAcceptanceEnum to match the agreed connection API. Added AssignPlayerBoat message, which is used internally on the client to assign the player a source ID once they have connected. Fixed some race conditions in the MessageRouter. Updated ConnectionAcceptor.CheckClientConnection to wait slightly longer before removing connection (there was a slight race condition before). Race no longer has a reference to LatestMessages. LatestMessages no longer has specific messages types in it. Created RaceState class, which contains the state that is shared between VisualiserRaceState and MockRaceState (currently only used on visualiser). Split VisualiserRace into VisualiserRaceState and VisualiserRaceService. Added the VisualiserRace commands (BoatLocatonCommand, RaceStatusCommand, etc...). Slightly increased the preferred width of race.fxml table columns. issues #27 #37 #35 #story[1095]
This commit is contained in:
+6
-2
@@ -30,8 +30,12 @@ public class ConnectionToServerCommandFactory {
|
||||
|
||||
switch(joinAcceptance.getAcceptanceType()) {
|
||||
|
||||
case JOIN_SUCCESSFUL: return new JoinSuccessfulCommand(joinAcceptance, connectionToServer);
|
||||
case RACE_PARTICIPANTS_FULL: return new RaceParticipantsFullCommand(joinAcceptance, connectionToServer);
|
||||
case JOIN_SUCCESSFUL_PARTICIPANT: return new JoinSuccessParticipantCommand(joinAcceptance, connectionToServer);
|
||||
|
||||
case JOIN_SUCCESSFUL_SPECTATOR: return new JoinSuccessSpectatorCommand(joinAcceptance, connectionToServer);
|
||||
|
||||
case JOIN_FAILURE: return new JoinFailureCommand(joinAcceptance, connectionToServer);
|
||||
|
||||
case SERVER_FULL: return new ServerFullCommand(joinAcceptance, connectionToServer);
|
||||
|
||||
default: throw new CommandConstructionException("Could not create command for JoinAcceptance: " + joinAcceptance + ". Unknown JoinAcceptanceEnum.");
|
||||
|
||||
+3
-5
@@ -5,13 +5,11 @@ import network.Messages.JoinAcceptance;
|
||||
import visualiser.enums.ConnectionToServerState;
|
||||
import visualiser.network.ConnectionToServer;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
/**
|
||||
* Command created when a {@link network.Messages.Enums.JoinAcceptanceEnum#RACE_PARTICIPANTS_FULL} {@link JoinAcceptance} message is received.
|
||||
*/
|
||||
public class RaceParticipantsFullCommand implements Command {
|
||||
public class JoinFailureCommand implements Command {
|
||||
|
||||
/**
|
||||
* The message to operate on.
|
||||
@@ -25,11 +23,11 @@ public class RaceParticipantsFullCommand implements Command {
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new {@link RaceParticipantsFullCommand}, which operates on a given {@link ConnectionToServer}.
|
||||
* Creates a new {@link JoinFailureCommand}, which operates on a given {@link ConnectionToServer}.
|
||||
* @param joinAcceptance The message to operate on.
|
||||
* @param connectionToServer The context to operate on.
|
||||
*/
|
||||
public RaceParticipantsFullCommand(JoinAcceptance joinAcceptance, ConnectionToServer connectionToServer) {
|
||||
public JoinFailureCommand(JoinAcceptance joinAcceptance, ConnectionToServer connectionToServer) {
|
||||
this.joinAcceptance = joinAcceptance;
|
||||
this.connectionToServer = connectionToServer;
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package visualiser.Commands.ConnectionToServerCommands;
|
||||
|
||||
import mock.model.commandFactory.Command;
|
||||
import network.Messages.AssignPlayerBoat;
|
||||
import network.Messages.JoinAcceptance;
|
||||
import visualiser.enums.ConnectionToServerState;
|
||||
import visualiser.network.ConnectionToServer;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
||||
/**
|
||||
* Command created when a {@link network.Messages.Enums.JoinAcceptanceEnum#JOIN_SUCCESSFUL_PARTICIPANT} {@link network.Messages.JoinAcceptance} message is received.
|
||||
*/
|
||||
public class JoinSuccessParticipantCommand implements Command {
|
||||
|
||||
/**
|
||||
* The message to operate on.
|
||||
*/
|
||||
private JoinAcceptance joinAcceptance;
|
||||
|
||||
/**
|
||||
* The context to operate on.
|
||||
*/
|
||||
private ConnectionToServer connectionToServer;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new {@link JoinSuccessParticipantCommand}, which operates on a given {@link ConnectionToServer}.
|
||||
* @param joinAcceptance The message to operate on.
|
||||
* @param connectionToServer The context to operate on.
|
||||
*/
|
||||
public JoinSuccessParticipantCommand(JoinAcceptance joinAcceptance, ConnectionToServer connectionToServer) {
|
||||
this.joinAcceptance = joinAcceptance;
|
||||
this.connectionToServer = connectionToServer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
|
||||
connectionToServer.setJoinAcceptance(joinAcceptance);
|
||||
|
||||
connectionToServer.setConnectionState(ConnectionToServerState.CONNECTED);
|
||||
|
||||
|
||||
AssignPlayerBoat assignPlayerBoat = new AssignPlayerBoat(joinAcceptance.getSourceID());
|
||||
try {
|
||||
connectionToServer.send(assignPlayerBoat);
|
||||
} catch (InterruptedException e) {
|
||||
Logger.getGlobal().log(Level.WARNING, "JoinSuccessParticipantCommand: " + this + " was interrupted on thread: " + Thread.currentThread() + " while sending AssignPlayerBoat message.", e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+4
-6
@@ -5,13 +5,11 @@ import network.Messages.JoinAcceptance;
|
||||
import visualiser.enums.ConnectionToServerState;
|
||||
import visualiser.network.ConnectionToServer;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
/**
|
||||
* Command created when a {@link network.Messages.Enums.JoinAcceptanceEnum#JOIN_SUCCESSFUL} {@link network.Messages.JoinAcceptance} message is received.
|
||||
* Command created when a {@link network.Messages.Enums.JoinAcceptanceEnum#JOIN_SUCCESSFUL_PARTICIPANT} {@link JoinAcceptance} message is received.
|
||||
*/
|
||||
public class JoinSuccessfulCommand implements Command {
|
||||
public class JoinSuccessSpectatorCommand implements Command {
|
||||
|
||||
/**
|
||||
* The message to operate on.
|
||||
@@ -25,11 +23,11 @@ public class JoinSuccessfulCommand implements Command {
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new {@link JoinSuccessfulCommand}, which operates on a given {@link ConnectionToServer}.
|
||||
* Creates a new {@link JoinSuccessSpectatorCommand}, which operates on a given {@link ConnectionToServer}.
|
||||
* @param joinAcceptance The message to operate on.
|
||||
* @param connectionToServer The context to operate on.
|
||||
*/
|
||||
public JoinSuccessfulCommand(JoinAcceptance joinAcceptance, ConnectionToServer connectionToServer) {
|
||||
public JoinSuccessSpectatorCommand(JoinAcceptance joinAcceptance, ConnectionToServer connectionToServer) {
|
||||
this.joinAcceptance = joinAcceptance;
|
||||
this.connectionToServer = connectionToServer;
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package visualiser.Commands.VisualiserRaceCommands;
|
||||
|
||||
import mock.model.commandFactory.Command;
|
||||
import network.Messages.AssignPlayerBoat;
|
||||
import network.Messages.BoatLocation;
|
||||
import shared.exceptions.BoatNotFoundException;
|
||||
import shared.exceptions.MarkNotFoundException;
|
||||
import shared.model.GPSCoordinate;
|
||||
import shared.model.Mark;
|
||||
import visualiser.model.VisualiserBoat;
|
||||
import visualiser.model.VisualiserRaceState;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
||||
/**
|
||||
* Command created when a {@link AssignPlayerBoat} message is received.
|
||||
*/
|
||||
public class AssignPlayerBoatCommand implements Command {
|
||||
|
||||
/**
|
||||
* The message to operate on.
|
||||
*/
|
||||
private AssignPlayerBoat assignPlayerBoat;
|
||||
|
||||
/**
|
||||
* The context to operate on.
|
||||
*/
|
||||
private VisualiserRaceState visualiserRace;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new {@link AssignPlayerBoatCommand}, which operates on a given {@link VisualiserRaceState}.
|
||||
* @param assignPlayerBoat The message to operate on.
|
||||
* @param visualiserRace The context to operate on.
|
||||
*/
|
||||
public AssignPlayerBoatCommand(AssignPlayerBoat assignPlayerBoat, VisualiserRaceState visualiserRace) {
|
||||
this.assignPlayerBoat = assignPlayerBoat;
|
||||
this.visualiserRace = visualiserRace;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
|
||||
visualiserRace.setPlayerBoatID(assignPlayerBoat.getSourceID());
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
package visualiser.Commands.VisualiserRaceCommands;
|
||||
|
||||
import mock.model.commandFactory.Command;
|
||||
import network.Messages.BoatLocation;
|
||||
import network.Messages.Enums.BoatStatusEnum;
|
||||
import shared.exceptions.BoatNotFoundException;
|
||||
import shared.exceptions.MarkNotFoundException;
|
||||
import shared.model.GPSCoordinate;
|
||||
import shared.model.Mark;
|
||||
import visualiser.model.VisualiserBoat;
|
||||
import visualiser.model.VisualiserRaceEvent;
|
||||
import visualiser.model.VisualiserRaceState;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
||||
/**
|
||||
* Command created when a {@link BoatLocation} message is received.
|
||||
*/
|
||||
public class BoatLocationCommand implements Command {
|
||||
|
||||
/**
|
||||
* The message to operate on.
|
||||
*/
|
||||
private BoatLocation boatLocation;
|
||||
|
||||
/**
|
||||
* The context to operate on.
|
||||
*/
|
||||
private VisualiserRaceState visualiserRace;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new {@link BoatLocationCommand}, which operates on a given {@link VisualiserRaceState}.
|
||||
* @param boatLocation The message to operate on.
|
||||
* @param visualiserRace The context to operate on.
|
||||
*/
|
||||
public BoatLocationCommand(BoatLocation boatLocation, VisualiserRaceState visualiserRace) {
|
||||
this.boatLocation = boatLocation;
|
||||
this.visualiserRace = visualiserRace;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
|
||||
if (visualiserRace.isVisualiserBoat(boatLocation.getSourceID())) {
|
||||
updateBoatLocation();
|
||||
} else if (visualiserRace.isMark(boatLocation.getSourceID())) {
|
||||
updateMarkLocation();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the boat specified in the message.
|
||||
*/
|
||||
private void updateBoatLocation() {
|
||||
|
||||
try {
|
||||
VisualiserBoat boat = visualiserRace.getBoat(boatLocation.getSourceID());
|
||||
|
||||
//Get the new position.
|
||||
GPSCoordinate gpsCoordinate = new GPSCoordinate(
|
||||
boatLocation.getLatitude(),
|
||||
boatLocation.getLongitude());
|
||||
|
||||
boat.setCurrentPosition(gpsCoordinate);
|
||||
|
||||
//Bearing.
|
||||
boat.setBearing(boatLocation.getHeading());
|
||||
|
||||
|
||||
//Speed.
|
||||
boat.setCurrentSpeed(boatLocation.getBoatSpeedKnots());
|
||||
|
||||
|
||||
//Attempt to add a track point.
|
||||
attemptAddTrackPoint(boat);
|
||||
|
||||
|
||||
} catch (BoatNotFoundException e) {
|
||||
Logger.getGlobal().log(Level.WARNING, "BoatLocationCommand: " + this + " could not execute. Boat with sourceID: " + boatLocation.getSourceID() + " not found.", e);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attempts to add a track point to the boat. Only works if the boat is currently racing.
|
||||
* @param boat The boat to add a track point to.
|
||||
*/
|
||||
private void attemptAddTrackPoint(VisualiserBoat boat) {
|
||||
if (boat.getStatus() == BoatStatusEnum.RACING) {
|
||||
boat.addTrackPoint(boat.getCurrentPosition(), visualiserRace.getRaceClock().getCurrentTime());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the marker boat specified in message.
|
||||
*/
|
||||
private void updateMarkLocation() {
|
||||
|
||||
try {
|
||||
Mark mark = visualiserRace.getMark(boatLocation.getSourceID());
|
||||
|
||||
GPSCoordinate gpsCoordinate = new GPSCoordinate(
|
||||
boatLocation.getLatitude(),
|
||||
boatLocation.getLongitude());
|
||||
|
||||
mark.setPosition(gpsCoordinate);
|
||||
} catch (MarkNotFoundException e) {
|
||||
Logger.getGlobal().log(Level.WARNING, "BoatLocationCommand: " + this + " could not execute. Mark with sourceID: " + boatLocation.getSourceID() + " not found.", e);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package visualiser.Commands.VisualiserRaceCommands;
|
||||
|
||||
import mock.model.commandFactory.Command;
|
||||
import network.Messages.XMLMessage;
|
||||
import shared.dataInput.BoatDataSource;
|
||||
import shared.dataInput.BoatXMLReader;
|
||||
import shared.enums.XMLFileType;
|
||||
import shared.exceptions.InvalidBoatDataException;
|
||||
import shared.exceptions.XMLReaderException;
|
||||
import visualiser.model.VisualiserRaceEvent;
|
||||
import visualiser.model.VisualiserRaceState;
|
||||
|
||||
|
||||
/**
|
||||
* Command created when a {@link network.Messages.Enums.XMLMessageType#BOAT} {@link XMLMessage} message is received.
|
||||
*/
|
||||
public class BoatsXMLMessageCommand implements Command {
|
||||
|
||||
/**
|
||||
* The data source to operate on.
|
||||
*/
|
||||
private BoatDataSource boatDataSource;
|
||||
|
||||
/**
|
||||
* The context to operate on.
|
||||
*/
|
||||
private VisualiserRaceState visualiserRace;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new {@link BoatsXMLMessageCommand}, which operates on a given {@link VisualiserRaceEvent}.
|
||||
* @param boatDataSource The data source to operate on.
|
||||
* @param visualiserRace The context to operate on.
|
||||
*/
|
||||
public BoatsXMLMessageCommand(BoatDataSource boatDataSource, VisualiserRaceState visualiserRace) {
|
||||
this.boatDataSource = boatDataSource;
|
||||
this.visualiserRace = visualiserRace;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
|
||||
visualiserRace.setBoatDataSource(boatDataSource);
|
||||
|
||||
}
|
||||
}
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
package visualiser.Commands.VisualiserRaceCommands;
|
||||
|
||||
import mock.model.commandFactory.Command;
|
||||
import network.Messages.BoatStatus;
|
||||
import network.Messages.Enums.BoatStatusEnum;
|
||||
import network.Messages.RaceStatus;
|
||||
import shared.exceptions.BoatNotFoundException;
|
||||
import shared.model.Leg;
|
||||
import visualiser.model.VisualiserBoat;
|
||||
import visualiser.model.VisualiserRaceEvent;
|
||||
import visualiser.model.VisualiserRaceState;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
||||
/**
|
||||
* Command created when a {@link RaceStatus} message is received.
|
||||
*/
|
||||
public class RaceStatusCommand implements Command {
|
||||
|
||||
/**
|
||||
* The message to operate on.
|
||||
*/
|
||||
private RaceStatus raceStatus;
|
||||
|
||||
/**
|
||||
* The context to operate on.
|
||||
*/
|
||||
private VisualiserRaceState visualiserRace;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new {@link RaceStatusCommand}, which operates on a given {@link VisualiserRaceState}.
|
||||
* @param raceStatus The message to operate on.
|
||||
* @param visualiserRace The context to operate on.
|
||||
*/
|
||||
public RaceStatusCommand(RaceStatus raceStatus, VisualiserRaceState visualiserRace) {
|
||||
this.raceStatus = raceStatus;
|
||||
this.visualiserRace = visualiserRace;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
|
||||
//Race status enum.
|
||||
visualiserRace.setRaceStatusEnum(raceStatus.getRaceStatus());
|
||||
|
||||
//Wind.
|
||||
visualiserRace.setWind(
|
||||
raceStatus.getWindDirection(),
|
||||
raceStatus.getWindSpeed() );
|
||||
|
||||
//Current race time.
|
||||
visualiserRace.getRaceClock().setUTCTime(raceStatus.getCurrentTime());
|
||||
|
||||
|
||||
|
||||
for (BoatStatus boatStatus : raceStatus.getBoatStatuses()) {
|
||||
updateBoatStatus(boatStatus);
|
||||
}
|
||||
|
||||
|
||||
visualiserRace.updateBoatPositions(visualiserRace.getBoats());
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates a single boat's status using the boatStatus message.
|
||||
* @param boatStatus BoatStatus message to get data from.
|
||||
*/
|
||||
private void updateBoatStatus(BoatStatus boatStatus) {
|
||||
try {
|
||||
VisualiserBoat boat = visualiserRace.getBoat(boatStatus.getSourceID());
|
||||
|
||||
//Time at next mark.
|
||||
updateEstimatedTimeAtNextMark(boatStatus, boat);
|
||||
|
||||
|
||||
BoatStatusEnum newBoatStatusEnum = boatStatus.getBoatStatus();
|
||||
|
||||
//Time at last mark.
|
||||
initialiseTimeAtLastMark(boat, boat.getStatus(), newBoatStatusEnum);
|
||||
|
||||
//Status.
|
||||
boat.setStatus(newBoatStatusEnum);
|
||||
|
||||
|
||||
List<Leg> legs = visualiserRace.getLegs();
|
||||
|
||||
//Leg.
|
||||
updateLeg(boatStatus.getLegNumber(), boat, legs);
|
||||
|
||||
|
||||
//Set finish time if boat finished.
|
||||
attemptUpdateFinishTime(boatStatus, boat, legs);
|
||||
|
||||
|
||||
} catch (BoatNotFoundException e) {
|
||||
Logger.getGlobal().log(Level.WARNING, "RaceStatusCommand.updateBoatStatus: " + this + " could not execute. Boat with sourceID: " + boatStatus.getSourceID() + " not found.", e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attempts to update the finish time of the boat. Only works if the boat has actually finished the race.
|
||||
* @param boatStatus BoatStatus to read data from.
|
||||
* @param boat Boat to update.
|
||||
* @param legs Legs of the race.
|
||||
*/
|
||||
private void attemptUpdateFinishTime(BoatStatus boatStatus, VisualiserBoat boat, List<Leg> legs) {
|
||||
|
||||
if (boat.getStatus() == BoatStatusEnum.FINISHED || boatStatus.getLegNumber() == legs.size()) {
|
||||
boat.setTimeFinished(visualiserRace.getRaceClock().getCurrentTimeMilli());
|
||||
boat.setStatus(BoatStatusEnum.FINISHED);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Updates a boat's leg.
|
||||
* @param legNumber The new leg number.
|
||||
* @param boat The boat to update.
|
||||
* @param legs The legs in the race.
|
||||
*/
|
||||
private void updateLeg(int legNumber, VisualiserBoat boat, List<Leg> legs) {
|
||||
|
||||
if (legNumber >= 1 && legNumber < legs.size()) {
|
||||
if (boat.getCurrentLeg() != legs.get(legNumber)) {
|
||||
boatFinishedLeg(boat, legs.get(legNumber));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises the time at last mark for a boat. Only changes if the boat's status is changing from non-racing to racing.
|
||||
* @param boat The boat to update.
|
||||
* @param currentBoatStatus The current status of the boat.
|
||||
* @param newBoatStatusEnum The new status of the boat, from the BoatStatus message.
|
||||
*/
|
||||
private void initialiseTimeAtLastMark(VisualiserBoat boat, BoatStatusEnum currentBoatStatus, BoatStatusEnum newBoatStatusEnum) {
|
||||
//If we are changing from non-racing to racing, we need to initialise boat with their time at last mark.
|
||||
if ((currentBoatStatus != BoatStatusEnum.RACING) && (newBoatStatusEnum == BoatStatusEnum.RACING)) {
|
||||
boat.setTimeAtLastMark(visualiserRace.getRaceClock().getCurrentTime());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the estimated time at next mark for a given boat.
|
||||
* @param boatStatus BoatStatus to read data from.
|
||||
* @param boat Boat to update.
|
||||
*/
|
||||
private void updateEstimatedTimeAtNextMark(BoatStatus boatStatus, VisualiserBoat boat) {
|
||||
boat.setEstimatedTimeAtNextMark(visualiserRace.getRaceClock().getLocalTime(boatStatus.getEstTimeAtNextMark()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Updates a boat's leg to a specified leg. Also records the order in which the boat passed the leg.
|
||||
* @param boat The boat to update.
|
||||
* @param leg The leg to use.
|
||||
*/
|
||||
private void boatFinishedLeg(VisualiserBoat boat, Leg leg) {
|
||||
|
||||
//Record order in which boat finished leg.
|
||||
visualiserRace.getLegCompletionOrder().get(boat.getCurrentLeg()).add(boat);
|
||||
|
||||
//Update boat.
|
||||
boat.setCurrentLeg(leg);
|
||||
boat.setTimeAtLastMark(visualiserRace.getRaceClock().getCurrentTime());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package visualiser.Commands.VisualiserRaceCommands;
|
||||
|
||||
import mock.model.commandFactory.Command;
|
||||
import network.Messages.XMLMessage;
|
||||
import shared.dataInput.RaceDataSource;
|
||||
import visualiser.model.VisualiserRaceEvent;
|
||||
import visualiser.model.VisualiserRaceState;
|
||||
|
||||
|
||||
/**
|
||||
* Command created when a {@link network.Messages.Enums.XMLMessageType#BOAT} {@link XMLMessage} message is received.
|
||||
*/
|
||||
public class RaceXMLMessageCommand implements Command {
|
||||
|
||||
/**
|
||||
* The data source to operate on.
|
||||
*/
|
||||
private RaceDataSource raceDataSource;
|
||||
|
||||
/**
|
||||
* The context to operate on.
|
||||
*/
|
||||
private VisualiserRaceState visualiserRace;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new {@link RaceXMLMessageCommand}, which operates on a given {@link VisualiserRaceEvent}.
|
||||
* @param raceDataSource The data source to operate on.
|
||||
* @param visualiserRace The context to operate on.
|
||||
*/
|
||||
public RaceXMLMessageCommand(RaceDataSource raceDataSource, VisualiserRaceState visualiserRace) {
|
||||
this.raceDataSource = raceDataSource;
|
||||
this.visualiserRace = visualiserRace;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
|
||||
visualiserRace.setRaceDataSource(raceDataSource);
|
||||
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package visualiser.Commands.VisualiserRaceCommands;
|
||||
|
||||
import mock.model.commandFactory.Command;
|
||||
import network.Messages.XMLMessage;
|
||||
import shared.dataInput.RegattaDataSource;
|
||||
import visualiser.model.VisualiserRaceEvent;
|
||||
import visualiser.model.VisualiserRaceState;
|
||||
|
||||
|
||||
/**
|
||||
* Command created when a {@link network.Messages.Enums.XMLMessageType#BOAT} {@link XMLMessage} message is received.
|
||||
*/
|
||||
public class RegattaXMLMessageCommand implements Command {
|
||||
|
||||
/**
|
||||
* The data source to operate on.
|
||||
*/
|
||||
private RegattaDataSource regattaDataSource;
|
||||
|
||||
/**
|
||||
* The context to operate on.
|
||||
*/
|
||||
private VisualiserRaceState visualiserRace;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new {@link RegattaXMLMessageCommand}, which operates on a given {@link VisualiserRaceEvent}.
|
||||
* @param regattaDataSource The data source to operate on.
|
||||
* @param visualiserRace The context to operate on.
|
||||
*/
|
||||
public RegattaXMLMessageCommand(RegattaDataSource regattaDataSource, VisualiserRaceState visualiserRace) {
|
||||
this.regattaDataSource = regattaDataSource;
|
||||
this.visualiserRace = visualiserRace;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
|
||||
visualiserRace.setRegattaDataSource(regattaDataSource);
|
||||
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package visualiser.Commands.VisualiserRaceCommands;
|
||||
|
||||
|
||||
import mock.exceptions.CommandConstructionException;
|
||||
import mock.model.commandFactory.Command;
|
||||
import network.Messages.*;
|
||||
import visualiser.model.VisualiserRaceEvent;
|
||||
import visualiser.model.VisualiserRaceState;
|
||||
|
||||
/**
|
||||
* Factory to create VisualiserRace commands.
|
||||
*/
|
||||
public class VisualiserRaceCommandFactory {
|
||||
|
||||
/**
|
||||
* Generates a command on an VisualiserRace.
|
||||
* @param message The message to turn into a command.
|
||||
* @param visualiserRace The context for the command to operate on.
|
||||
* @return The command to execute the given action.
|
||||
* @throws CommandConstructionException Thrown if the command cannot be constructed.
|
||||
*/
|
||||
public static Command create(AC35Data message, VisualiserRaceState visualiserRace) throws CommandConstructionException {
|
||||
|
||||
switch (message.getType()) {
|
||||
|
||||
case BOATLOCATION: return new BoatLocationCommand((BoatLocation) message, visualiserRace);
|
||||
|
||||
case RACESTATUS: return new RaceStatusCommand((RaceStatus) message, visualiserRace);
|
||||
|
||||
case XMLMESSAGE: return XMLMessageCommandFactory.create((XMLMessage) message, visualiserRace);
|
||||
|
||||
case ASSIGN_PLAYER_BOAT: return new AssignPlayerBoatCommand((AssignPlayerBoat) message, visualiserRace);
|
||||
|
||||
default: throw new CommandConstructionException("Could not create VisualiserRaceCommand. Unrecognised or unsupported MessageType: " + message.getType());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package visualiser.Commands.VisualiserRaceCommands;
|
||||
|
||||
|
||||
import mock.exceptions.CommandConstructionException;
|
||||
import mock.model.commandFactory.Command;
|
||||
import network.Messages.AC35Data;
|
||||
import network.Messages.BoatLocation;
|
||||
import network.Messages.RaceStatus;
|
||||
import network.Messages.XMLMessage;
|
||||
import shared.dataInput.*;
|
||||
import shared.enums.XMLFileType;
|
||||
import shared.exceptions.InvalidBoatDataException;
|
||||
import shared.exceptions.InvalidRaceDataException;
|
||||
import shared.exceptions.InvalidRegattaDataException;
|
||||
import shared.exceptions.XMLReaderException;
|
||||
import visualiser.model.VisualiserRaceState;
|
||||
|
||||
/**
|
||||
* Factory to create VisualiserRace commands, from XMLMessages.
|
||||
*/
|
||||
public class XMLMessageCommandFactory {
|
||||
|
||||
/**
|
||||
* Generates a command on an VisualiserRace.
|
||||
* @param message The message to turn into a command.
|
||||
* @param visualiserRace The context for the command to operate on.
|
||||
* @return The command to execute the given action.
|
||||
* @throws CommandConstructionException Thrown if the command cannot be constructed.
|
||||
*/
|
||||
public static Command create(XMLMessage message, VisualiserRaceState visualiserRace) throws CommandConstructionException {
|
||||
|
||||
try {
|
||||
|
||||
switch (message.getXmlMsgSubType()) {
|
||||
|
||||
case BOAT:
|
||||
BoatDataSource boatDataSource = new BoatXMLReader(message.getXmlMessage(), XMLFileType.Contents);
|
||||
return new BoatsXMLMessageCommand(boatDataSource, visualiserRace);
|
||||
|
||||
|
||||
case RACE:
|
||||
RaceDataSource raceDataSource = new RaceXMLReader(message.getXmlMessage(), XMLFileType.Contents);
|
||||
return new RaceXMLMessageCommand(raceDataSource, visualiserRace);
|
||||
|
||||
|
||||
case REGATTA:
|
||||
RegattaDataSource regattaDataSource = new RegattaXMLReader(message.getXmlMessage(), XMLFileType.Contents);
|
||||
return new RegattaXMLMessageCommand(regattaDataSource, visualiserRace);
|
||||
|
||||
|
||||
default:
|
||||
throw new CommandConstructionException("Could not create VisualiserRaceCommand/XMLCommand. Unrecognised or unsupported MessageType: " + message.getType());
|
||||
|
||||
}
|
||||
|
||||
} catch (XMLReaderException | InvalidBoatDataException | InvalidRegattaDataException | InvalidRaceDataException e) {
|
||||
throw new CommandConstructionException("Could not create VisualiserRaceCommand/XMLCommand. Could not parse XML message payload.", e);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user