Merge branch 'master' into raceLength
# Conflicts: # racevisionGame/src/main/java/mock/app/Event.java
This commit is contained in:
@@ -55,6 +55,9 @@ public class Event {
|
||||
* This is used to allocate source IDs.
|
||||
*/
|
||||
private SourceIdAllocator sourceIdAllocator;
|
||||
|
||||
private RaceLogic raceLogic;
|
||||
|
||||
private Thread raceThread;
|
||||
private Thread connectionThread;
|
||||
private int mapIndex;
|
||||
@@ -101,11 +104,12 @@ public class Event {
|
||||
|
||||
//Read XML files.
|
||||
try {
|
||||
//this.raceXML = RaceXMLCreator.alterRaceToWind(raceXMLFile, 90);
|
||||
this.raceXML = Event.setRaceXMLAtCurrentTimeToNow(XMLReader.readXMLFileToString(raceXMLFile, StandardCharsets.UTF_8));
|
||||
|
||||
if(mapIndex==4){
|
||||
//this.raceXML = Event.setRaceXMLAtCurrentTimeToNow(XMLReader.readXMLFileToString(raceXMLFile, StandardCharsets.UTF_8), 1000, 5000);
|
||||
this.raceXML = RaceXMLCreator.alterRaceToWind(this.raceXML, XMLFileType.Contents, -1, true);
|
||||
//This is the tutorial map.
|
||||
this.raceXML = Event.setRaceXMLAtCurrentTimeToNow(XMLReader.readXMLFileToString(raceXMLFile, StandardCharsets.UTF_8), 1000, 5000);
|
||||
this.raceXML = RaceXMLCreator.alterRaceToWind(this.raceXML, XMLFileType.Contents, -1);
|
||||
|
||||
} else {
|
||||
this.raceXML = RaceXMLCreator.alterRaceToWind(this.raceXML, XMLFileType.Contents, windAngle, false);
|
||||
this.raceXML = RaceXMLCreator.scaleRaceSize(raceXML,
|
||||
@@ -159,20 +163,20 @@ public class Event {
|
||||
}
|
||||
|
||||
|
||||
RaceLogic newRace = new RaceLogic(
|
||||
this.raceLogic = new RaceLogic(
|
||||
mockRace,
|
||||
this.latestMessages,
|
||||
this.compositeCommand);
|
||||
|
||||
this.raceThread = new Thread(newRace, "Event.Start()->RaceLogic thread");
|
||||
this.raceThread = new Thread(raceLogic, "Event.Start()->RaceLogic thread");
|
||||
raceThread.start();
|
||||
|
||||
|
||||
//Create connection acceptor.
|
||||
this.sourceIdAllocator = new SourceIdAllocator(newRace.getRace());
|
||||
this.sourceIdAllocator = new SourceIdAllocator(raceLogic.getRace());
|
||||
|
||||
try {
|
||||
this.connectionAcceptor = new ConnectionAcceptor(latestMessages, compositeCommand, sourceIdAllocator, newRace);
|
||||
this.connectionAcceptor = new ConnectionAcceptor(latestMessages, compositeCommand, sourceIdAllocator, raceLogic);
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new EventConstructionException("Could not create ConnectionAcceptor.", e);
|
||||
@@ -205,16 +209,13 @@ public class Event {
|
||||
}
|
||||
|
||||
public static String setRaceXMLAtCurrentTimeToNow(String raceXML, long racePreStartTime, long racePreparatoryTime){
|
||||
//The start time is current time + 4 minutes. prestart is 3 minutes, and we add another minute.
|
||||
|
||||
long millisecondsToAdd = racePreStartTime + racePreparatoryTime;
|
||||
|
||||
long secondsToAdd = millisecondsToAdd / 1000;
|
||||
long minutesToAdd = 10;
|
||||
|
||||
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ");
|
||||
ZonedDateTime creationTime = ZonedDateTime.now();
|
||||
raceXML = raceXML.replace("RACE_CREATION_TIME", dateFormat.format(creationTime));
|
||||
raceXML = raceXML.replace("RACE_START_TIME", dateFormat.format(creationTime.plusSeconds(secondsToAdd)));
|
||||
raceXML = raceXML.replace("RACE_START_TIME", dateFormat.format(creationTime.plusMinutes(minutesToAdd)));
|
||||
|
||||
return raceXML;
|
||||
}
|
||||
@@ -229,4 +230,9 @@ public class Event {
|
||||
return new HostGame(ip, 3779,(byte) 1,(byte) 1, RaceStatusEnum.PRESTART, (byte) 1, (byte) 1);
|
||||
}
|
||||
|
||||
|
||||
public RaceLogic getRaceLogic() {
|
||||
return raceLogic;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -61,12 +61,17 @@ public class MockRace extends RaceState {
|
||||
*/
|
||||
private Polars polars;
|
||||
|
||||
private ActiveObserverCommand activeObserverCommand;
|
||||
private Map<Integer, ActiveObserverCommand> activeObserverCommands;
|
||||
|
||||
private long racePreStartTime = Constants.RacePreStartTime;
|
||||
|
||||
private long racePreparatoryTime = Constants.RacePreparatoryTime;
|
||||
|
||||
/**
|
||||
* True if the race has been manually started, false otherwise.
|
||||
*/
|
||||
private boolean hasBeenStarted = false;
|
||||
|
||||
/**
|
||||
* Constructs a race object with a given RaceDataSource, BoatDataSource, and RegattaDataSource and sends events to the given mockOutput.
|
||||
* @param boatDataSource Data source for boat related data (yachts and marker boats).
|
||||
@@ -82,7 +87,7 @@ public class MockRace extends RaceState {
|
||||
this.setRaceDataSource(raceDataSource);
|
||||
this.setRegattaDataSource(regattaDataSource);
|
||||
|
||||
this.activeObserverCommand = new ActiveObserverCommand();
|
||||
this.activeObserverCommands = new HashMap<>();
|
||||
this.polars = polars;
|
||||
this.scaleFactor = timeScale;
|
||||
|
||||
@@ -127,6 +132,7 @@ public class MockRace extends RaceState {
|
||||
getRaceDataSource().getParticipants().add(sourceID);
|
||||
|
||||
this.boats.add(mockBoat);
|
||||
this.activeObserverCommands.put(boat.getSourceID(), new ActiveObserverCommand());
|
||||
|
||||
getRaceDataSource().incrementSequenceNumber();
|
||||
|
||||
@@ -157,6 +163,23 @@ public class MockRace extends RaceState {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delays the start of the race, if needed, to ensure that the race doesn't start until host wants it to.
|
||||
* If the time until start is less that 5 minutes, it is extended to 10 minutes.
|
||||
*/
|
||||
public void delayRaceStart() {
|
||||
long timeToStart = getRaceDataSource().getStartDateTime().toInstant().toEpochMilli() - System.currentTimeMillis();
|
||||
|
||||
long fiveMinutesMilli = 5 * 60 * 1000;
|
||||
long tenMinutesMilli = 10 * 60 * 1000;
|
||||
|
||||
if ((timeToStart < fiveMinutesMilli) && (timeToStart > 0) && !hasBeenStarted) {
|
||||
startRace(tenMinutesMilli, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the race status enumeration based on the current time.
|
||||
*/
|
||||
@@ -165,7 +188,6 @@ public class MockRace extends RaceState {
|
||||
//The millisecond duration of the race. Negative means it hasn't started, so we flip sign.
|
||||
long timeToStart = - this.getRaceClock().getDurationMilli();
|
||||
|
||||
|
||||
if (timeToStart > racePreStartTime) {
|
||||
//Time > 3 minutes is the prestart period.
|
||||
this.setRaceStatusEnum(RaceStatusEnum.PRESTART);
|
||||
@@ -195,6 +217,26 @@ public class MockRace extends RaceState {
|
||||
this.racePreparatoryTime = racePreparatoryTime;
|
||||
}
|
||||
|
||||
public long getRacePreparatoryTime() {
|
||||
return racePreparatoryTime;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Starts the race in #timeToStartMilli milliseconds.
|
||||
* @param timeToStartMilli Millseconds before starting the race.
|
||||
* @param manualStart True if the race has been manually started, false otherwise.
|
||||
*/
|
||||
public void startRace(long timeToStartMilli, boolean manualStart) {
|
||||
this.hasBeenStarted = manualStart;
|
||||
ZonedDateTime startTime = ZonedDateTime.now().plus(timeToStartMilli, ChronoUnit.MILLIS);
|
||||
|
||||
getRaceDataSource().setStartDateTime(startTime);
|
||||
getRaceDataSource().incrementSequenceNumber();
|
||||
|
||||
this.getRaceClock().setStartingTime(getRaceDataSource().getStartDateTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the status of all boats in the race to RACING.
|
||||
*/
|
||||
@@ -711,11 +753,11 @@ public class MockRace extends RaceState {
|
||||
super.setChanged();
|
||||
}
|
||||
|
||||
public void addVelocityCommand(ObserverCommand c) {
|
||||
this.activeObserverCommand.changeVelocityCommand(this, c);
|
||||
public void addVelocityCommand(ObserverCommand c, int boatId) {
|
||||
this.activeObserverCommands.get(boatId).changeVelocityCommand(this, c);
|
||||
}
|
||||
|
||||
public void addAngularCommand(ObserverCommand c) {
|
||||
this.activeObserverCommand.changeAngularCommand(this, c);
|
||||
public void addAngularCommand(ObserverCommand c, int boatId) {
|
||||
this.activeObserverCommands.get(boatId).changeAngularCommand(this, c);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,6 +81,8 @@ public class RaceLogic implements RunnableWithFramePeriod, Observer {
|
||||
//Update race time.
|
||||
race.updateRaceTime(currentTime);
|
||||
|
||||
race.delayRaceStart();
|
||||
|
||||
//Update the race status based on the current time.
|
||||
race.updateRaceStatusEnum();
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ public class CollisionCommand extends ObserverCommand {
|
||||
@Override
|
||||
public void update(Observable o, Object arg) {
|
||||
if(GPSCoordinate.calculateDistanceMeters(boat.getPosition(), startingPosition) < distance) {
|
||||
boat.setVelocityDefault(false);
|
||||
boat.setPosition(GPSCoordinate.calculateNewPosition(boat.getPosition(), 3, azimuth));
|
||||
} else {
|
||||
race.deleteObserver(this);
|
||||
|
||||
@@ -13,7 +13,7 @@ public class SailsCommand extends ObserverCommand {
|
||||
|
||||
public SailsCommand(MockRace race, MockBoat boat, boolean sailsOut) {
|
||||
super(race, boat);
|
||||
race.addVelocityCommand(this);
|
||||
race.addVelocityCommand(this, boat.getSourceID());
|
||||
this.sailsOut = sailsOut;
|
||||
}
|
||||
|
||||
@@ -37,15 +37,18 @@ public class SailsCommand extends ObserverCommand {
|
||||
public void update(Observable o, Object arg) {
|
||||
double acceleration = 0.5;
|
||||
|
||||
if(sailsOut && boat.getCurrentSpeed() < goalVelocity) {
|
||||
boat.setCurrentSpeed(Math.min(goalVelocity, boat.getCurrentSpeed() + acceleration));
|
||||
} else if (!sailsOut && boat.getCurrentSpeed() > goalVelocity) {
|
||||
// Apply deceleration to strictly 0 speed
|
||||
boat.setCurrentSpeed(Math.max(0, boat.getCurrentSpeed() - acceleration));
|
||||
} else {
|
||||
// Release boat from SailsCommand control
|
||||
if(sailsOut) boat.setVelocityDefault(true);
|
||||
race.deleteObserver(this);
|
||||
if (!boat.isColliding()) {
|
||||
boat.setVelocityDefault(false);
|
||||
if (sailsOut && boat.getCurrentSpeed() < goalVelocity) {
|
||||
boat.setCurrentSpeed(Math.min(goalVelocity, boat.getCurrentSpeed() + acceleration));
|
||||
} else if (!sailsOut && boat.getCurrentSpeed() > goalVelocity) {
|
||||
// Apply deceleration to strictly 0 speed
|
||||
boat.setCurrentSpeed(Math.max(0, boat.getCurrentSpeed() - acceleration));
|
||||
} else {
|
||||
// Release boat from SailsCommand control
|
||||
if (sailsOut) boat.setVelocityDefault(true);
|
||||
race.deleteObserver(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ public class TackGybeCommand extends ObserverCommand {
|
||||
*/
|
||||
public TackGybeCommand(MockRace race, MockBoat boat) {
|
||||
super(race, boat);
|
||||
race.addAngularCommand(this);
|
||||
race.addAngularCommand(this, boat.getSourceID());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,7 +24,7 @@ public class VMGCommand extends ObserverCommand {
|
||||
*/
|
||||
public VMGCommand(MockRace race, MockBoat boat) {
|
||||
super(race, boat);
|
||||
race.addAngularCommand(this);
|
||||
race.addAngularCommand(this, boat.getSourceID());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,7 +20,7 @@ public class WindCommand extends ObserverCommand {
|
||||
*/
|
||||
public WindCommand(MockRace race, MockBoat boat, boolean upwind) {
|
||||
super(race, boat);
|
||||
race.addAngularCommand(this);
|
||||
race.addAngularCommand(this, boat.getSourceID());
|
||||
this.direction = upwind? -1 : 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,13 +58,12 @@ public class RaceXMLCreator {
|
||||
* Rotates the race in a specified direction.
|
||||
* @param s xml file name or contents.
|
||||
* @param fileType Whether s is a file name or contents.
|
||||
* @param degrees degrees to rotate
|
||||
* @param tutorial Whether we wish to run the tutorial - this changes the race start time.
|
||||
* @param degrees degrees to rotate. -1 means don't rotate.
|
||||
* @return the new xml file as a string
|
||||
* @throws XMLReaderException if the xml is not readable
|
||||
* @throws InvalidRaceDataException if the race is invalid
|
||||
*/
|
||||
public static String alterRaceToWind(String s, XMLFileType fileType, double degrees, boolean tutorial) throws XMLReaderException, InvalidRaceDataException {
|
||||
public static String alterRaceToWind(String s, XMLFileType fileType, double degrees) throws XMLReaderException, InvalidRaceDataException {
|
||||
|
||||
RaceXMLReader reader = new RaceXMLReader(s, fileType);
|
||||
|
||||
@@ -75,11 +74,6 @@ public class RaceXMLCreator {
|
||||
RaceXMLCreator.class.getClassLoader().getResource("mock/mockXML/schema/raceSchema.xsd"),
|
||||
XMLRace.class);
|
||||
|
||||
if(tutorial){
|
||||
setRaceXMLAtCurrentTimeToNow(race, 1000l, 5000l);
|
||||
} else {
|
||||
setRaceXMLAtCurrentTimeToNow(race);
|
||||
}
|
||||
|
||||
|
||||
CompoundMark leewardGate = getLeewardGate(reader);
|
||||
|
||||
Reference in New Issue
Block a user