package mock.model; import network.Messages.*; import network.Messages.Enums.BoatLocationDeviceEnum; import shared.model.Bearing; import shared.model.CompoundMark; import shared.model.Mark; import java.util.ArrayList; import java.util.List; /** * Created by connortaylorbrown on 2/08/17. */ public class RaceServer { private MockRace race; private LatestMessages latestMessages; /** * The sequence number of the latest BoatLocation message sent or received. */ private int boatLocationSequenceNumber = 1; public RaceServer(MockRace race, LatestMessages latestMessages) { this.race = race; this.latestMessages = latestMessages; } /** * Parses the race to create a snapshot, and places it in latestMessages. */ public void parseSnapshot() { List snapshotMessages = new ArrayList<>(); //Parse the boat locations. snapshotMessages.addAll(parseBoatLocations()); //Parse the marks. snapshotMessages.addAll(parseMarks()); //Parse the race status. snapshotMessages.add(parseRaceStatus()); latestMessages.setSnapshot(snapshotMessages); } /** * Parses an individual marker boat, and returns it. * @param mark The marker boat to parse. * @return The BoatLocation message. */ private BoatLocation parseIndividualMark(Mark mark) { //Create message. BoatLocation boatLocation = new BoatLocation( mark.getSourceID(), mark.getPosition().getLatitude(), mark.getPosition().getLongitude(), this.boatLocationSequenceNumber, BoatLocationDeviceEnum.Mark, Bearing.fromDegrees(0), 0, race.getRaceClock().getCurrentTimeMilli()); //Iterates the sequence number. this.boatLocationSequenceNumber++; return boatLocation; } /** * Parse the compound marker boats, and returns a list of BoatLocation messages. * @return BoatLocation messages for each mark. */ private List parseMarks() { List markLocations = new ArrayList<>(race.getCompoundMarks().size()); for (CompoundMark compoundMark : race.getCompoundMarks()) { //Get the individual marks from the compound mark. Mark mark1 = compoundMark.getMark1(); Mark mark2 = compoundMark.getMark2(); //If they aren't null, parse them (some compound marks only have one mark). if (mark1 != null) { markLocations.add(this.parseIndividualMark(mark1)); } if (mark2 != null) { markLocations.add(this.parseIndividualMark(mark2)); } } return markLocations; } /** * Parse the boats in the race, and returns all of their BoatLocation messages. * @return List of BoatLocation messages, for each boat. */ private List parseBoatLocations() { List boatLocations = new ArrayList<>(race.getBoats().size()); //Parse each boat. for (MockBoat boat : race.getBoats()) { boatLocations.add(this.parseIndividualBoatLocation(boat)); } return boatLocations; } /** * Parses an individual boat, and returns it. * @param boat The boat to parse. * @return The BoatLocation message. */ private BoatLocation parseIndividualBoatLocation(MockBoat boat) { BoatLocation boatLocation = new BoatLocation( boat.getSourceID(), boat.getPosition().getLatitude(), boat.getPosition().getLongitude(), this.boatLocationSequenceNumber, BoatLocationDeviceEnum.RacingYacht, boat.getBearing(), boat.getCurrentSpeed(), race.getRaceClock().getCurrentTimeMilli()); //Iterates the sequence number. this.boatLocationSequenceNumber++; return boatLocation; } /** * Parses the race status, and returns it. * @return The race status message. */ private RaceStatus parseRaceStatus() { //A race status message contains a list of boat statuses. List boatStatuses = new ArrayList<>(); //Add each boat status to the status list. for (MockBoat boat : race.getBoats()) { BoatStatus boatStatus = new BoatStatus( boat.getSourceID(), boat.getStatus(), boat.getCurrentLeg().getLegNumber(), boat.getEstimatedTimeAtNextMark().toInstant().toEpochMilli() ); boatStatuses.add(boatStatus); } //Create race status object, and send it. RaceStatus raceStatus = new RaceStatus( RaceStatus.currentMessageVersionNumber, System.currentTimeMillis(), race.getRaceId(), race.getRaceStatusEnum(), race.getRaceClock().getStartingTimeMilli(), race.getWindDirection(), race.getWindSpeed(), race.getRaceType(), boatStatuses); return raceStatus; } }