From 9be3c6e51127e7a77747205a5360efdfcaddd8c1 Mon Sep 17 00:00:00 2001 From: Simon Pamies Date: Thu, 16 Jul 2015 10:00:53 +0200 Subject: [PATCH 1/7] XML exporter now exporting empty race columns with RDG'ed competitors --- .../sailing/xmlexport/LeaderboardData.java | 83 ++++++++++++++----- 1 file changed, 61 insertions(+), 22 deletions(-) diff --git a/java/com.sap.sailing.xmlexport/src/com/sap/sailing/xmlexport/LeaderboardData.java b/java/com.sap.sailing.xmlexport/src/com/sap/sailing/xmlexport/LeaderboardData.java index 86e78215568..53a318f1747 100644 --- a/java/com.sap.sailing.xmlexport/src/com/sap/sailing/xmlexport/LeaderboardData.java +++ b/java/com.sap.sailing.xmlexport/src/com/sap/sailing/xmlexport/LeaderboardData.java @@ -202,6 +202,35 @@ public class LeaderboardData extends ExportAction { return windElements; } + private Element createRaceXMLWithoutRaceData(final Fleet fleet, final RaceColumn column, final Leaderboard leaderboard, int sameDayGroupIndex, int raceCounter, Util.Pair> raceConfidenceAndErrorMessages) throws NoWindException, IOException, ServletException { + Element raceElement = new Element("race"); + addNamedElementWithValue(raceElement, "name", column.getName()+'-'+fleet.getName()); + addNamedElementWithValue(raceElement, "race_index_in_leaderboard", raceCounter); + addNamedElementWithValue(raceElement, "fleet_name", fleet.getName()); + addNamedElementWithValue(raceElement, "same_day_index", sameDayGroupIndex); + addNamedElementWithValue(raceElement, "is_live", "false"); + TimePoint timepointToBeUsed = MillisecondsTimePoint.now(); + List competitors = leaderboard.getCompetitorsFromBestToWorst(column, timepointToBeUsed); + for (Competitor competitorInLeaderboard : competitors) { + MaxPointsReason mpr = leaderboard.getScoreCorrection().getMaxPointsReason(competitorInLeaderboard, column, timepointToBeUsed); + if (mpr != null && !mpr.equals(MaxPointsReason.NONE)) { + // add this competitor to the list to have him evaluated + Element competitorElement = createCompetitorXML(competitorInLeaderboard, leaderboard, /*shortVersion*/ true, null); + Element competitorRaceDataElement = new Element("competitor_race_data"); + MaxPointsReason maxPointsReason = leaderboard.getMaxPointsReason(competitorInLeaderboard, column, timepointToBeUsed); + addNamedElementWithValue(competitorRaceDataElement, "max_points_reason", maxPointsReason.toString()); + boolean isDiscardedForCompetitor = leaderboard.isDiscarded(competitorInLeaderboard, column, timepointToBeUsed); + addNamedElementWithValue(competitorRaceDataElement, "is_discarded", isDiscardedForCompetitor == true ? "true" : "false"); + Double finalRaceScore = leaderboard.getTotalPoints(competitorInLeaderboard, column, timepointToBeUsed); + addNamedElementWithValue(competitorRaceDataElement, "final_race_score", finalRaceScore); + competitorElement.addContent(competitorRaceDataElement); + raceElement.addContent(competitorElement); + raceConfidenceAndErrorMessages = updateConfidence("Competitor " + competitorInLeaderboard.getName() + " has no valid data for this race!", 0.2, raceConfidenceAndErrorMessages); + } + } + return raceElement; + } + /** * Creates elements containing information about a race */ @@ -784,24 +813,29 @@ public class LeaderboardData extends ExportAction { private Util.Pair> checkData(TrackedRace race) throws Exception { double simpleConfidence = 1.0; Vector messages = new Vector(); TimePoint dateAtYear2000 = new MillisecondsTimePoint(946681200000l); - if (race.getStartOfRace() == null || race.getStartOfRace().before(dateAtYear2000)) { - messages.add("Start time of race " + race.getRaceIdentifier().getRaceName() + " is either null or not valid!"); + if (race == null) { + messages.add("Tracked race is null - no race seems to be connected!"); simpleConfidence -= 1; - } - if (race.getEndOfRace() == null || race.getEndOfRace().before(dateAtYear2000)) { - messages.add("End time of race " + race.getRaceIdentifier().getRaceName() + " is either null or not valid!"); - simpleConfidence -= 1; - } - if (race.getStartOfTracking() == null || race.getStartOfTracking().before(dateAtYear2000)) { - messages.add("Start tracking time of race " + race.getRaceIdentifier().getRaceName() + " is either null or not valid!"); - simpleConfidence -= 0.2; - } - if (race.getEndOfTracking() == null || race.getEndOfTracking().before(dateAtYear2000)) { - messages.add("End tracking time of race " + race.getRaceIdentifier().getRaceName() + " is either null or not valid!"); - simpleConfidence -= 0.2; - } - if (race.isLive(MillisecondsTimePoint.now())) { - messages.add("This race is live - data for this race will not be available until the race has been finished!"); + } else { + if (race.getStartOfRace() == null || race.getStartOfRace().before(dateAtYear2000)) { + messages.add("Start time of race " + race.getRaceIdentifier().getRaceName() + " is either null or not valid!"); + simpleConfidence -= 1; + } + if (race.getEndOfRace() == null || race.getEndOfRace().before(dateAtYear2000)) { + messages.add("End time of race " + race.getRaceIdentifier().getRaceName() + " is either null or not valid!"); + simpleConfidence -= 1; + } + if (race.getStartOfTracking() == null || race.getStartOfTracking().before(dateAtYear2000)) { + messages.add("Start tracking time of race " + race.getRaceIdentifier().getRaceName() + " is either null or not valid!"); + simpleConfidence -= 0.2; + } + if (race.getEndOfTracking() == null || race.getEndOfTracking().before(dateAtYear2000)) { + messages.add("End tracking time of race " + race.getRaceIdentifier().getRaceName() + " is either null or not valid!"); + simpleConfidence -= 0.2; + } + if (race.isLive(MillisecondsTimePoint.now())) { + messages.add("This race is live - data for this race will not be available until the race has been finished!"); + } } return new Util.Pair>(simpleConfidence, messages); } @@ -899,11 +933,13 @@ public class LeaderboardData extends ExportAction { for (RaceColumn raceColumn : leaderboard.getRaceColumns()) { for (Fleet fleet : raceColumn.getFleets()) { TrackedRace trackedRace = raceColumn.getTrackedRace(fleet); - if (trackedRace != null && trackedRace.hasGPSData()) { + if (trackedRace != null) { sameDayGroupIndex += getSameDayGroupIndex(raceColumn.getTrackedRace(fleet), raceBefore); - TimePoint timeSpentForRace = MillisecondsTimePoint.now(); - Util.Pair> raceConfidenceAndErrorMessages = checkData(trackedRace); - final List legs = new ArrayList(); + } + TimePoint timeSpentForRace = MillisecondsTimePoint.now(); + Util.Pair> raceConfidenceAndErrorMessages = checkData(trackedRace); + final List legs = new ArrayList(); + if (trackedRace != null && trackedRace.hasGPSData()) { int legCounter = 0; for (TrackedLeg leg : trackedRace.getTrackedLegs()) { Util.Pair> legConfidenceAndErrorMessages = checkData(leg); @@ -914,8 +950,11 @@ public class LeaderboardData extends ExportAction { addNamedElementWithValue(raceElement, "generation_time_in_milliseconds", elapsedTimeForRace.asMillis()); racesElements.add(raceElement); log.info("Exported complete race " + trackedRace.getRace().getName() + " in " + elapsedTimeForRace.asMillis() + " milliseconds!"); - raceBefore = trackedRace; + } else { + racesElements.add(createRaceXMLWithoutRaceData(fleet, raceColumn, leaderboard, sameDayGroupIndex, ++raceCounter, raceConfidenceAndErrorMessages)); + log.info("Exported empty race in race column " + raceColumn.getName() + " with fleet " + fleet.getName()); } + raceBefore = trackedRace; } } log.info("Finished XML export of leaderboard " + leaderboard.getName() + " in " + MillisecondsTimePoint.now().minus(timeSpent.asMillis()).asMillis() + " milliseconds"); From a9be120ca6594731e373bc8edc1d408b5739081e Mon Sep 17 00:00:00 2001 From: Simon Pamies Date: Thu, 16 Jul 2015 10:05:36 +0200 Subject: [PATCH 2/7] XML exporter now getting the startline length at the time of the start of the race --- .../src/com/sap/sailing/xmlexport/LeaderboardData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/com.sap.sailing.xmlexport/src/com/sap/sailing/xmlexport/LeaderboardData.java b/java/com.sap.sailing.xmlexport/src/com/sap/sailing/xmlexport/LeaderboardData.java index 53a318f1747..418d41d1664 100644 --- a/java/com.sap.sailing.xmlexport/src/com/sap/sailing/xmlexport/LeaderboardData.java +++ b/java/com.sap.sailing.xmlexport/src/com/sap/sailing/xmlexport/LeaderboardData.java @@ -262,7 +262,7 @@ public class LeaderboardData extends ExportAction { addNamedElementWithValue(raceElement, "start_of_tracking_time_as_millis", handleValue(race.getStartOfTracking())); addNamedElementWithValue(raceElement, "end_of_tracking_time_as_millis", handleValue(race.getEndOfTracking())); - LineDetails start = race.getStartLine(race.getStartOfTracking()); + LineDetails start = race.getStartLine(race.getStartOfRace()); if (start != null) { if (start.getLength() != null) { addNamedElementWithValue(raceElement, "start_line_length_in_meters", start.getLength().getMeters()); From 4f9d08ac4360fab9f16dad27e96e9aa18b5d3942 Mon Sep 17 00:00:00 2001 From: Simon Pamies Date: Thu, 16 Jul 2015 10:17:47 +0200 Subject: [PATCH 3/7] XML exporter now makes sure to first take the time of the latest leaderboard change for rank calculation --- .../com/sap/sailing/xmlexport/LeaderboardData.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/java/com.sap.sailing.xmlexport/src/com/sap/sailing/xmlexport/LeaderboardData.java b/java/com.sap.sailing.xmlexport/src/com/sap/sailing/xmlexport/LeaderboardData.java index 418d41d1664..628b51d72e9 100644 --- a/java/com.sap.sailing.xmlexport/src/com/sap/sailing/xmlexport/LeaderboardData.java +++ b/java/com.sap.sailing.xmlexport/src/com/sap/sailing/xmlexport/LeaderboardData.java @@ -597,13 +597,16 @@ public class LeaderboardData extends ExportAction { // will kick in } } - if (endOfRaceForLastTrackedRaceInLeaderboard != null) { - timePointOfLatestModification = endOfRaceForLastTrackedRaceInLeaderboard; + // first look for latest modification of leaderboard + // if there is no latest modification then take the last races time + if (leaderboard.getTimePointOfLatestModification() != null) { + timePointOfLatestModification = leaderboard.getTimePointOfLatestModification(); } else { - if (leaderboard.getTimePointOfLatestModification() != null) { - timePointOfLatestModification = leaderboard.getTimePointOfLatestModification(); + if (endOfRaceForLastTrackedRaceInLeaderboard != null) { + timePointOfLatestModification = endOfRaceForLastTrackedRaceInLeaderboard; } else { - timePointOfLatestModification = MillisecondsTimePoint.now(); + // make sure that the timepoint is far in the future - could be that the export is called too early + timePointOfLatestModification = MillisecondsTimePoint.now().plus(Duration.ONE_YEAR); } } Duration totalTimeSailed = leaderboard.getTotalTimeSailed(competitor, timePointOfLatestModification); From 10d3ad53ee3ad617ece848870615fa700bb5955b Mon Sep 17 00:00:00 2001 From: Simon Pamies Date: Thu, 16 Jul 2015 11:01:30 +0200 Subject: [PATCH 4/7] XML exporter now extracting wind information --- .../sailing/xmlexport/LeaderboardData.java | 47 +++++++++++++++++-- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/java/com.sap.sailing.xmlexport/src/com/sap/sailing/xmlexport/LeaderboardData.java b/java/com.sap.sailing.xmlexport/src/com/sap/sailing/xmlexport/LeaderboardData.java index 628b51d72e9..60fe96a9e8b 100644 --- a/java/com.sap.sailing.xmlexport/src/com/sap/sailing/xmlexport/LeaderboardData.java +++ b/java/com.sap.sailing.xmlexport/src/com/sap/sailing/xmlexport/LeaderboardData.java @@ -34,8 +34,11 @@ import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.common.Position; import com.sap.sailing.domain.common.Speed; import com.sap.sailing.domain.common.Tack; +import com.sap.sailing.domain.common.WindSource; +import com.sap.sailing.domain.common.WindSourceType; import com.sap.sailing.domain.common.impl.KnotSpeedImpl; import com.sap.sailing.domain.common.impl.MeterDistance; +import com.sap.sailing.domain.common.impl.WindSourceImpl; import com.sap.sailing.domain.common.tracking.GPSFixMoving; import com.sap.sailing.domain.leaderboard.Leaderboard; import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo; @@ -46,6 +49,8 @@ import com.sap.sailing.domain.tracking.TrackedLeg; import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.domain.tracking.WindPositionMode; +import com.sap.sailing.domain.tracking.WindTrack; +import com.sap.sailing.domain.tracking.WindWithConfidence; import com.sap.sailing.server.RacingEventService; import com.sap.sse.common.Duration; import com.sap.sse.common.TimePoint; @@ -97,7 +102,7 @@ public class LeaderboardData extends ExportAction { * * */ - private Element createLeaderboardXML(Leaderboard leaderboard, List competitors, List races, Util.Pair> leaderboardConfidenceAndErrorMessages) { + private Element createLeaderboardXML(Leaderboard leaderboard, List windData, List competitors, List races, Util.Pair> leaderboardConfidenceAndErrorMessages) { Element leaderboardElement = new Element("leaderboard"); addNamedElementWithValue(leaderboardElement, "name", leaderboard.getName()); addNamedElementWithValue(leaderboardElement, "display_name", leaderboard.getDisplayName()); @@ -106,6 +111,9 @@ public class LeaderboardData extends ExportAction { addNamedElementWithValue(leaderboardElement, "boat_class", getBoatClassName(leaderboard)); leaderboardElement.addContent(createTimedXML("last_modification_", leaderboard.getTimePointOfLatestModification())); leaderboardElement.addContent(createDataConfidenceXML(leaderboardConfidenceAndErrorMessages)); + Element windContainer = new Element("wind"); + windContainer.addContent(windData); + leaderboardElement.addContent(windContainer); leaderboardElement.addContent(competitors); leaderboardElement.addContent(races); return leaderboardElement; @@ -740,6 +748,36 @@ public class LeaderboardData extends ExportAction { return legElement; } + private List createFullWindDataXML(TrackedRace race, Fleet fleet, int sameDayIndex) { + List windElements = new ArrayList<>(); + List windSourcesToDeliver = new ArrayList(); + WindSourceImpl windSource = new WindSourceImpl(WindSourceType.COMBINED); + windSourcesToDeliver.add(windSource); + TimePoint fromTimePoint = race.getStartOfRace(); + TimePoint toTimePoint = race.getEndOfRace(); + int numberOfFixes = (int) ((toTimePoint.asMillis() - fromTimePoint.asMillis()) / /*resolutionInMillis*/ 1000*60*5); + WindTrack windTrack = race.getOrCreateWindTrack(windSource); + TimePoint timePoint = fromTimePoint; + for (int i = 0; i < numberOfFixes && toTimePoint != null && timePoint.compareTo(toTimePoint) < 0; i++) { + WindWithConfidence> averagedWindWithConfidence = windTrack + .getAveragedWindWithConfidence(null, timePoint); + if (averagedWindWithConfidence != null) { + Element windElement = new Element("windFix"); + addNamedElementWithValue(windElement, "same_day_index", sameDayIndex); + addNamedElementWithValue(windElement, "race_name", race.getRace().getName()); + addNamedElementWithValue(windElement, "fleet_name", fleet.getName()); + windElement.addContent(createTimedXML("", averagedWindWithConfidence.getObject().getTimePoint())); + addNamedElementWithValue(windElement, "bearingInDegrees", averagedWindWithConfidence.getObject().getBearing().getDegrees()); + addNamedElementWithValue(windElement, "directionFromInDegrees", averagedWindWithConfidence.getObject().getBearing().reverse().getDegrees()); + windElement.addContent(createWindXML("", new SpeedWithConfidenceImpl(new KnotSpeedImpl(averagedWindWithConfidence.getObject().getKnots()), + averagedWindWithConfidence.getConfidence(), toTimePoint))); + windElements.add(windElement); + } + timePoint = new MillisecondsTimePoint(timePoint.asMillis() + 1000*60*5); + } + return windElements; + } + /** * Creates xml elements that indicate confidence. */ @@ -923,15 +961,13 @@ public class LeaderboardData extends ExportAction { TimePoint timeSpent = MillisecondsTimePoint.now(); log.info("Starting XML export of " + leaderboard.getName()); Util.Pair> leaderboardConfidenceAndErrorMessages = checkData(leaderboard); - final List racesElements = new ArrayList(); final List competitorElements = new ArrayList(); - for (Competitor competitor : leaderboard.getAllCompetitors()) { Util.Pair> competitorConfidenceAndErrorMessages = checkData(competitor); competitorElements.add(createCompetitorXML(competitor, leaderboard, /*shortVersion*/ false, competitorConfidenceAndErrorMessages)); } - + List windData = new ArrayList(); TrackedRace raceBefore = null; int sameDayGroupIndex = 0; int raceCounter = 0; for (RaceColumn raceColumn : leaderboard.getRaceColumns()) { for (Fleet fleet : raceColumn.getFleets()) { @@ -943,6 +979,7 @@ public class LeaderboardData extends ExportAction { Util.Pair> raceConfidenceAndErrorMessages = checkData(trackedRace); final List legs = new ArrayList(); if (trackedRace != null && trackedRace.hasGPSData()) { + windData.addAll(createFullWindDataXML(trackedRace, fleet, sameDayGroupIndex)); int legCounter = 0; for (TrackedLeg leg : trackedRace.getTrackedLegs()) { Util.Pair> legConfidenceAndErrorMessages = checkData(leg); @@ -961,7 +998,7 @@ public class LeaderboardData extends ExportAction { } } log.info("Finished XML export of leaderboard " + leaderboard.getName() + " in " + MillisecondsTimePoint.now().minus(timeSpent.asMillis()).asMillis() + " milliseconds"); - Element dataToExport = createLeaderboardXML(leaderboard, competitorElements, racesElements, leaderboardConfidenceAndErrorMessages); + Element dataToExport = createLeaderboardXML(leaderboard, windData, competitorElements, racesElements, leaderboardConfidenceAndErrorMessages); sendDocument(dataToExport, leaderboard.getName() + ".xml"); } } From fb9046ec94545658ae142764e751ee3a46b88fc4 Mon Sep 17 00:00:00 2001 From: Steffen Schaefer Date: Thu, 16 Jul 2015 11:11:14 +0200 Subject: [PATCH 5/7] Using ScoreCorrection instead of SettableScoreCorrection as we do not need to set anything --- .../sap/sailing/gwt/ui/shared/dispatch/event/RaceContext.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/dispatch/event/RaceContext.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/dispatch/event/RaceContext.java index d0204581431..1dc05840110 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/dispatch/event/RaceContext.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/dispatch/event/RaceContext.java @@ -30,7 +30,7 @@ import com.sap.sailing.domain.common.racelog.Flags; import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus; import com.sap.sailing.domain.leaderboard.Leaderboard; import com.sap.sailing.domain.leaderboard.RegattaLeaderboard; -import com.sap.sailing.domain.leaderboard.SettableScoreCorrection; +import com.sap.sailing.domain.leaderboard.ScoreCorrection; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.domain.tracking.WindTrack; import com.sap.sailing.domain.tracking.WindWithConfidence; @@ -353,7 +353,7 @@ public class RaceContext { } } } - SettableScoreCorrection scoreCorrection = leaderboard.getScoreCorrection(); + ScoreCorrection scoreCorrection = leaderboard.getScoreCorrection(); if(!hasTrackingForRaceColumn() && scoreCorrection != null && scoreCorrection.hasCorrectionFor(raceColumn)) { return RaceViewState.FINISHED; } From 2cc687d54728c99abc790fe6cc0bead7cc4c2310 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 16 Jul 2015 11:26:44 +0200 Subject: [PATCH 6/7] added ScoreCorrection method to detect score corrections in untracked fleets within a race column --- .../domain/base/impl/RaceDefinitionImpl.java | 9 +++++++-- .../domain/leaderboard/ScoreCorrection.java | 8 ++++++++ .../leaderboard/impl/ScoreCorrectionImpl.java | 15 +++++++++++++-- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RaceDefinitionImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RaceDefinitionImpl.java index b4ac93865e0..7b297db56cf 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RaceDefinitionImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RaceDefinitionImpl.java @@ -1,7 +1,10 @@ package com.sap.sailing.domain.base.impl; import java.io.Serializable; +import java.util.Collections; +import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.Set; import com.sap.sailing.domain.base.BoatClass; import com.sap.sailing.domain.base.Competitor; @@ -13,6 +16,7 @@ public class RaceDefinitionImpl extends NamedImpl implements RaceDefinition { private static final long serialVersionUID = -1900955198751393727L; private final Course course; private final LinkedHashMap competitorsById; + private final Set competitors; private final BoatClass boatClass; private final Serializable id; @@ -23,11 +27,12 @@ public class RaceDefinitionImpl extends NamedImpl implements RaceDefinition { public RaceDefinitionImpl(String name, Course course, BoatClass boatClass, Iterable competitors, Serializable id) { super(name); assert name != null; - this.course = course; + this.competitors = new HashSet<>(); this.competitorsById = new LinkedHashMap<>(); for (Competitor competitor : competitors) { Competitor competitorWithEqualID = competitorsById.put(competitor.getId(), competitor); + this.competitors.add(competitor); if (competitorWithEqualID != null && competitorWithEqualID != competitor) { throw new IllegalArgumentException("Two distinct competitors with equal ID "+competitor.getId()+" are not allowed within the single race "+name); } @@ -48,7 +53,7 @@ public class RaceDefinitionImpl extends NamedImpl implements RaceDefinition { @Override public Iterable getCompetitors() { - return competitorsById.values(); + return Collections.unmodifiableSet(competitors); } @Override diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoreCorrection.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoreCorrection.java index 1fd99932582..3182d990e1a 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoreCorrection.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoreCorrection.java @@ -99,6 +99,14 @@ public interface ScoreCorrection extends Serializable { */ boolean hasCorrectionFor(RaceColumn raceInLeaderboard); + /** + * Similar to {@link #hasCorrectionFor(RaceColumn)}, but returns true only if score corrections are found + * for any competitor who in raceInLeaderboard is not in a tracked race and hence the fleet assignment + * cannot be determined. This is helpful, e.g., for progress detection. If score corrections are present for such + * untracked competitors then all untracked fleets need to be assumed as finished. + */ + boolean hasCorrectionForNonTrackedFleet(RaceColumn raceInLeaderboard); + /** * @return all race columns for which this score corrections object has at least one correction; note that this * object may hold corrections also for competitors that are not currently returned by diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/ScoreCorrectionImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/ScoreCorrectionImpl.java index b58f433eb1d..a0891127129 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/ScoreCorrectionImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/ScoreCorrectionImpl.java @@ -472,19 +472,30 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection { @Override public boolean hasCorrectionFor(RaceColumn raceInLeaderboard) { + return internalHasScoreCorrectionFor(raceInLeaderboard, /* considerOnlyUntrackedRaces */ false); + } + + private boolean internalHasScoreCorrectionFor(RaceColumn raceInLeaderboard, boolean considerOnlyUntrackedRaces) { for (com.sap.sse.common.Util.Pair correctedScoresKey : correctedScores.keySet()) { - if (correctedScoresKey.getB() == raceInLeaderboard) { + if (correctedScoresKey.getB() == raceInLeaderboard && + (!considerOnlyUntrackedRaces || raceInLeaderboard.getTrackedRace(correctedScoresKey.getA()) == null)) { return true; } } for (com.sap.sse.common.Util.Pair maxPointsReasonsKey : maxPointsReasons.keySet()) { - if (maxPointsReasonsKey.getB() == raceInLeaderboard) { + if (maxPointsReasonsKey.getB() == raceInLeaderboard && + (!considerOnlyUntrackedRaces || raceInLeaderboard.getTrackedRace(maxPointsReasonsKey.getA()) == null)) { return true; } } return false; } + @Override + public boolean hasCorrectionForNonTrackedFleet(RaceColumn raceInLeaderboard) { + return internalHasScoreCorrectionFor(raceInLeaderboard, /* considerOnlyUntrackedRaces */ true); + } + @Override public TimePoint getTimePointOfLastCorrectionsValidity() { return timePointOfLastCorrectionsValidity; From d20f6eaebc56ffa4e6ae82bd2f5521957302ffdc Mon Sep 17 00:00:00 2001 From: Steffen Schaefer Date: Thu, 16 Jul 2015 11:33:52 +0200 Subject: [PATCH 7/7] Using ScoreCorrection.hasCorrectionForNonTrackedFleet to better calculate if a non tracked race is finished even if there is some tracking in a sibling fleet --- .../gwt/ui/shared/dispatch/event/RaceContext.java | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/dispatch/event/RaceContext.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/dispatch/event/RaceContext.java index 1dc05840110..00ce08219e3 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/dispatch/event/RaceContext.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/dispatch/event/RaceContext.java @@ -354,7 +354,7 @@ public class RaceContext { } } ScoreCorrection scoreCorrection = leaderboard.getScoreCorrection(); - if(!hasTrackingForRaceColumn() && scoreCorrection != null && scoreCorrection.hasCorrectionFor(raceColumn)) { + if(trackedRace == null && scoreCorrection != null && scoreCorrection.hasCorrectionForNonTrackedFleet(raceColumn)) { return RaceViewState.FINISHED; } if(startTime != null) { @@ -362,15 +362,6 @@ public class RaceContext { } return RaceViewState.PLANNED; } - - private boolean hasTrackingForRaceColumn() { - for(Fleet fleetOfRaceColumn : raceColumn.getFleets()) { - if(raceColumn.getTrackedRace(fleetOfRaceColumn) != null) { - return true; - } - } - return false; - } private Wind checkForWindFixesFromRaceLog() { WindFixesFinder windFixesFinder = new WindFixesFinder(raceLog);