mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-25 06:58:39 +00:00
bug 4175: using leaderboard to determine "quick ranks" if available;
in the process, I've adjusted the naming of what used to be the list of competitors ordered by windward distance traveled to simply "from best to worst." I had changed these semantics some time ago but never had adjusted the naming accordingly. Change-Id: I203840842eedf050f5c2ed8a3e052e4bc4d7772d
This commit is contained in:
+4
-2
@@ -30,6 +30,8 @@ import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
|
||||
import com.sap.sailing.gwt.ui.client.RaceTimesInfoProvider;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.DefaultQuickRanksDTOProvider;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceCompetitorSet;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMap;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapHelpLinesSettings;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapHelpLinesSettings.HelpLineTypes;
|
||||
@@ -173,8 +175,8 @@ public class StartAnalysisCard extends Composite implements HasWidgets, StartAna
|
||||
raceMap = new RaceMap(null, null, new RaceMapLifecycle(StringMessages.INSTANCE), raceMapSettings,
|
||||
sailingServiceAsync,
|
||||
asyncActionsExecutor, null, timer, competitorSelectionModel,
|
||||
StringMessages.INSTANCE, startAnalysisDTO.regattaAndRaceIdentifier,
|
||||
raceMapResources, /* showHeaderPanel */ true);
|
||||
new RaceCompetitorSet(competitorSelectionModel), StringMessages.INSTANCE,
|
||||
startAnalysisDTO.regattaAndRaceIdentifier, raceMapResources, /* showHeaderPanel */ true, new DefaultQuickRanksDTOProvider());
|
||||
raceTimesInfoProvider.addRaceTimesInfoProviderListener(raceMap);
|
||||
raceMap.setSize("100%", "100%");
|
||||
card_map_container.getElement().getStyle().setHeight(getHeightForRaceMapInPixels(), Unit.PX);
|
||||
|
||||
+14
@@ -175,6 +175,20 @@ public class LeaderboardEntryDTO implements Serializable {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public int getOneBasedCurrentLegNumber() {
|
||||
int result = 0;
|
||||
if (legDetails != null && !legDetails.isEmpty()) {
|
||||
for (LegEntryDTO legDetail : legDetails) {
|
||||
if (legDetail != null && legDetail.started) {
|
||||
result++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
-1
@@ -17,7 +17,6 @@ public interface LeaderboardUpdateListener {
|
||||
|
||||
/**
|
||||
* Called whenever the leaderboard has been updated.
|
||||
* @param leaderboard
|
||||
*/
|
||||
void updatedLeaderboard(LeaderboardDTO leaderboard);
|
||||
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.sap.sailing.gwt.ui.client.shared.racemap;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import com.sap.sailing.domain.common.dto.CompetitorDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.QuickRankDTO;
|
||||
|
||||
public class DefaultQuickRanksDTOProvider implements QuickRanksDTOProvider {
|
||||
private LinkedHashMap<CompetitorDTO, QuickRankDTO> quickRanksFromServer;
|
||||
|
||||
@Override
|
||||
public void quickRanksReceivedFromServer(LinkedHashMap<CompetitorDTO, QuickRankDTO> quickRanksFromServer) {
|
||||
this.quickRanksFromServer = quickRanksFromServer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LinkedHashMap<CompetitorDTO, QuickRankDTO> getQuickRanks() {
|
||||
return quickRanksFromServer;
|
||||
}
|
||||
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package com.sap.sailing.gwt.ui.client.shared.racemap;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import com.sap.sailing.domain.common.dto.CompetitorDTO;
|
||||
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
|
||||
import com.sap.sailing.gwt.ui.client.LeaderboardUpdateListener;
|
||||
import com.sap.sailing.gwt.ui.raceboard.RaceBoardPanel;
|
||||
import com.sap.sailing.gwt.ui.shared.QuickRankDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceMapDataDTO;
|
||||
|
||||
/**
|
||||
* The {@link QuickRankDTO} objects stored in the {@link RaceMap}'s {@code quickRanks} field may be obtained in
|
||||
* different ways. This interface abstracts the different strategies for how this may happen. If a {@link RaceMap} is
|
||||
* used in the context of a {@link RaceBoardPanel} which is a {@link LeaderboardUpdateListener}, {@link LeaderboardDTO}
|
||||
* objects can provide the up-to-date information for all aspects of the {@link QuickRankDTO} objects required.
|
||||
* Otherwise, the {@link QuickRankDTO} objects as received in the {@link RaceMapDataDTO} objects can be used. This may
|
||||
* not always be consistent and in sync with the leaderboard being shown for a particular time point because their
|
||||
* calculation in the back-end happens in a lower-priority thread, hence may be a bit delayed in a server under high
|
||||
* load. See also bug 4175.
|
||||
*
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public interface QuickRanksDTOProvider {
|
||||
/**
|
||||
* The strategy may or may not use this quick ranks information provided directly from the server. This information
|
||||
* may have been provided with some delay and may be slightly inconsistent with a {@link LeaderboardDTO leaderboard}
|
||||
* that was delivered through a different channel. Therefore, a strategy that has access to a current
|
||||
* {@link LeaderboardDTO leaderboard} should ignore this call if it already has quick ranks information available
|
||||
* from a leaderboard.
|
||||
*/
|
||||
void quickRanksReceivedFromServer(LinkedHashMap<CompetitorDTO, QuickRankDTO> quickRanksFromServer);
|
||||
|
||||
LinkedHashMap<CompetitorDTO, QuickRankDTO> getQuickRanks();
|
||||
}
|
||||
+20
-38
@@ -8,7 +8,6 @@ import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@@ -76,11 +75,11 @@ import com.sap.sailing.domain.common.Bounds;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.WindSource;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.domain.common.dto.CompetitorDTO;
|
||||
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||
@@ -349,18 +348,12 @@ public class RaceMap extends AbstractCompositeComponent<RaceMapSettings> impleme
|
||||
private int lastLegNumber;
|
||||
|
||||
/**
|
||||
* The last quick ranks received from a call to {@link SailingServiceAsync#getQuickRanks(RaceIdentifier, Date, AsyncCallback)} upon
|
||||
* the last {@link #timeChanged(Date, Date)} event. Therefore, the ranks listed here correspond to the {@link #timer}'s time.
|
||||
* The strategy for maintaining and delivering the "quick ranks" information. The provider will be informed about
|
||||
* quick ranks received from a {@link RaceMapDataDTO#quickRanks} field but may choose to ignore this information, e.g.,
|
||||
* if it can assume that more current information about ranks and leg numbers is available from a {@link LeaderboardDTO}.
|
||||
*/
|
||||
private LinkedHashMap<CompetitorDTO, QuickRankDTO> quickRanks;
|
||||
private final QuickRanksDTOProvider quickRanksDTOProvider;
|
||||
|
||||
/**
|
||||
* Taken from {@link RaceMapDataDTO#competitorsInOrderOfWindwardDistanceTraveledWithOneBasedLegNumber}; tells the
|
||||
* windward distances traveled and the leg numbers in which the respective competitor is.
|
||||
*/
|
||||
private LinkedHashMap<CompetitorDTO, Integer> competitorsInOrderOfWindwardDistanceTraveledWithOneBasedLegNumber;
|
||||
|
||||
|
||||
private final CombinedWindPanel combinedWindPanel;
|
||||
private final TrueNorthIndicatorPanel trueNorthIndicatorPanel;
|
||||
private final FlowPanel topLeftControlsWrapperPanel;
|
||||
@@ -418,10 +411,11 @@ public class RaceMap extends AbstractCompositeComponent<RaceMapSettings> impleme
|
||||
public RaceMap(Component<?> parent, ComponentContext<?> context, RaceMapLifecycle raceMapLifecycle,
|
||||
RaceMapSettings raceMapSettings,
|
||||
SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor,
|
||||
ErrorReporter errorReporter, Timer timer, CompetitorSelectionProvider competitorSelection, StringMessages stringMessages,
|
||||
RegattaAndRaceIdentifier raceIdentifier, RaceMapResources raceMapResources,
|
||||
boolean showHeaderPanel) {
|
||||
ErrorReporter errorReporter, Timer timer, CompetitorSelectionProvider competitorSelection, RaceCompetitorSet raceCompetitorSet,
|
||||
StringMessages stringMessages, RegattaAndRaceIdentifier raceIdentifier,
|
||||
RaceMapResources raceMapResources, boolean showHeaderPanel, QuickRanksDTOProvider quickRanksDTOProvider) {
|
||||
super(parent, context);
|
||||
this.quickRanksDTOProvider = quickRanksDTOProvider;
|
||||
this.raceMapLifecycle = raceMapLifecycle;
|
||||
this.stringMessages = stringMessages;
|
||||
this.sailingService = sailingService;
|
||||
@@ -442,7 +436,7 @@ public class RaceMap extends AbstractCompositeComponent<RaceMapSettings> impleme
|
||||
courseMarkOverlays = new HashMap<String, CourseMarkOverlay>();
|
||||
courseMarkClickHandlers = new HashMap<String, HandlerRegistration>();
|
||||
this.competitorSelection = competitorSelection;
|
||||
this.raceCompetitorSet = new RaceCompetitorSet(competitorSelection);
|
||||
this.raceCompetitorSet = raceCompetitorSet;
|
||||
competitorSelection.addCompetitorSelectionChangeListener(this);
|
||||
settings = raceMapSettings;
|
||||
coordinateSystem = new DelegateCoordinateSystem(new IdentityCoordinateSystem());
|
||||
@@ -972,9 +966,7 @@ public class RaceMap extends AbstractCompositeComponent<RaceMapSettings> impleme
|
||||
" in regatta "+raceIdentifier.getRegattaName(), e);
|
||||
}
|
||||
}
|
||||
quickRanks = raceMapDataDTO.quickRanks;
|
||||
competitorsInOrderOfWindwardDistanceTraveledWithOneBasedLegNumber =
|
||||
raceMapDataDTO.competitorsInOrderOfWindwardDistanceTraveledWithOneBasedLegNumber;
|
||||
quickRanksDTOProvider.quickRanksReceivedFromServer(raceMapDataDTO.quickRanks);
|
||||
if (isSimulationEnabled && settings.isShowSimulationOverlay()) {
|
||||
lastLegNumber = raceMapDataDTO.coursePositions.currentLegNumber;
|
||||
simulationOverlay.updateLeg(Math.max(lastLegNumber, 1), /* clearCanvas */ false, raceMapDataDTO.simulationResultVersion);
|
||||
@@ -1361,35 +1353,29 @@ public class RaceMap extends AbstractCompositeComponent<RaceMapSettings> impleme
|
||||
/**
|
||||
* Returns a pair whose first component is the leg number (one-based) of the competitor returned as the second component.
|
||||
*/
|
||||
private com.sap.sse.common.Util.Pair<Integer, CompetitorDTO> getFarthestAheadVisibleCompetitorWithOneBasedLegNumber(
|
||||
private com.sap.sse.common.Util.Pair<Integer, CompetitorDTO> getBestVisibleCompetitorWithOneBasedLegNumber(
|
||||
Iterable<CompetitorDTO> competitorsToShow) {
|
||||
CompetitorDTO leadingCompetitorDTO = null;
|
||||
int legOfLeaderCompetitor = -1;
|
||||
// this only works because the quickRanks are sorted
|
||||
for (Entry<CompetitorDTO, Integer> competitorsByWindwardDistanceTraveledAndOneBasedLegNumber :
|
||||
getCompetitorsInOrderOfWindwardDistanceTraveledWithOneBasedLegNumber()) {
|
||||
if (Util.contains(competitorsToShow, competitorsByWindwardDistanceTraveledAndOneBasedLegNumber.getKey()) &&
|
||||
competitorsByWindwardDistanceTraveledAndOneBasedLegNumber.getValue() != null) {
|
||||
leadingCompetitorDTO = competitorsByWindwardDistanceTraveledAndOneBasedLegNumber.getKey();
|
||||
legOfLeaderCompetitor = competitorsByWindwardDistanceTraveledAndOneBasedLegNumber.getValue();
|
||||
for (QuickRankDTO competitorFromBestToWorstAndOneBasedLegNumber : quickRanksDTOProvider.getQuickRanks().values()) {
|
||||
if (Util.contains(competitorsToShow, competitorFromBestToWorstAndOneBasedLegNumber.competitor) &&
|
||||
competitorFromBestToWorstAndOneBasedLegNumber.legNumberOneBased != 0) {
|
||||
leadingCompetitorDTO = competitorFromBestToWorstAndOneBasedLegNumber.competitor;
|
||||
legOfLeaderCompetitor = competitorFromBestToWorstAndOneBasedLegNumber.legNumberOneBased;
|
||||
return new com.sap.sse.common.Util.Pair<Integer, CompetitorDTO>(legOfLeaderCompetitor, leadingCompetitorDTO);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Set<Entry<CompetitorDTO, Integer>> getCompetitorsInOrderOfWindwardDistanceTraveledWithOneBasedLegNumber() {
|
||||
// TODO bug4175: obtain from raceBoardPanel.leaderboardPanel.leaderboard instead of QuickRanks
|
||||
return competitorsInOrderOfWindwardDistanceTraveledWithOneBasedLegNumber.entrySet();
|
||||
}
|
||||
|
||||
final static Distance advantageLineLength = new MeterDistance(1000); // TODO this should probably rather scale with the visible area of the map; bug 616
|
||||
private void showAdvantageLine(Iterable<CompetitorDTO> competitorsToShow, Date date, long timeForPositionTransitionMillis) {
|
||||
if (map != null && lastRaceTimesInfo != null && quickRanks != null && lastCombinedWindTrackInfoDTO != null) {
|
||||
if (map != null && lastRaceTimesInfo != null && quickRanksDTOProvider.getQuickRanks() != null && lastCombinedWindTrackInfoDTO != null) {
|
||||
boolean drawAdvantageLine = false;
|
||||
if (settings.getHelpLinesSettings().isVisible(HelpLineTypes.ADVANTAGELINE)) {
|
||||
// find competitor with highest rank
|
||||
com.sap.sse.common.Util.Pair<Integer, CompetitorDTO> visibleLeaderInfo = getFarthestAheadVisibleCompetitorWithOneBasedLegNumber(competitorsToShow);
|
||||
com.sap.sse.common.Util.Pair<Integer, CompetitorDTO> visibleLeaderInfo = getBestVisibleCompetitorWithOneBasedLegNumber(competitorsToShow);
|
||||
// the boat fix may be null; may mean that no positions were loaded yet for the leading visible boat;
|
||||
// don't show anything
|
||||
GPSFixDTOWithSpeedWindTackAndLegType lastBoatFix = null;
|
||||
@@ -2785,15 +2771,11 @@ public class RaceMap extends AbstractCompositeComponent<RaceMapSettings> impleme
|
||||
return result;
|
||||
}
|
||||
|
||||
private QuickRankDTO getQuickRank(CompetitorDTO competitorDTO) {
|
||||
return quickRanks.get(competitorDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getRank(CompetitorDTO competitor) {
|
||||
// TODO bug4175: obtain from raceBoardPanel.leaderboardPanel.leaderboard instead of QuickRanks
|
||||
final Integer result;
|
||||
QuickRankDTO quickRank = getQuickRank(competitor);
|
||||
QuickRankDTO quickRank = quickRanksDTOProvider.getQuickRanks().get(competitor);
|
||||
if (quickRank != null) {
|
||||
result = quickRank.rank;
|
||||
} else {
|
||||
|
||||
+3
-16
@@ -1648,22 +1648,9 @@ public class LeaderboardPanel extends AbstractCompositeComponent<LeaderboardSett
|
||||
public Double get(LeaderboardRowDTO row) {
|
||||
Double result = null;
|
||||
LeaderboardEntryDTO fieldsForRace = row.fieldsByRaceColumnName.get(getRaceColumnName());
|
||||
if (fieldsForRace != null && fieldsForRace.legDetails != null && !fieldsForRace.legDetails.isEmpty()) {
|
||||
for (LegEntryDTO legDetail : fieldsForRace.legDetails) {
|
||||
if (legDetail != null) {
|
||||
if (legDetail.started) {
|
||||
if (result == null) {
|
||||
result = 0.0;
|
||||
}
|
||||
result++;
|
||||
} else {
|
||||
if (result != null) {
|
||||
result++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fieldsForRace != null) {
|
||||
int currentLeg = fieldsForRace.getOneBasedCurrentLegNumber();
|
||||
result = currentLeg == 0 ? null : (double) currentLeg;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
+4
-2
@@ -37,6 +37,8 @@ import com.sap.sailing.gwt.ui.client.TimePanelSettings;
|
||||
import com.sap.sailing.gwt.ui.client.shared.charts.WindChart;
|
||||
import com.sap.sailing.gwt.ui.client.shared.charts.WindChartLifecycle;
|
||||
import com.sap.sailing.gwt.ui.client.shared.charts.WindChartSettings;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.DefaultQuickRanksDTOProvider;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceCompetitorSet;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMap;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapHelpLinesSettings;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapHelpLinesSettings.HelpLineTypes;
|
||||
@@ -200,8 +202,8 @@ public class EmbeddedMapAndWindChartEntryPoint extends AbstractSailingEntryPoint
|
||||
}
|
||||
final RaceMap raceMap = new RaceMap(null, null, new RaceMapLifecycle(getStringMessages()), raceMapSettings,
|
||||
sailingService, asyncActionsExecutor, /* errorReporter */ EmbeddedMapAndWindChartEntryPoint.this, timer,
|
||||
competitorSelection, getStringMessages(), selectedRaceIdentifier, raceMapResources,
|
||||
/* showHeaderPanel */ false) {
|
||||
competitorSelection, new RaceCompetitorSet(competitorSelection), getStringMessages(), selectedRaceIdentifier,
|
||||
raceMapResources, /* showHeaderPanel */ false, new DefaultQuickRanksDTOProvider()) {
|
||||
@Override
|
||||
protected void showAdditionalControls(MapWidget map) {
|
||||
backToLivePlayButton.removeFromParent();
|
||||
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
package com.sap.sailing.gwt.ui.raceboard;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.dto.CompetitorDTO;
|
||||
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
|
||||
import com.sap.sailing.domain.common.dto.LeaderboardEntryDTO;
|
||||
import com.sap.sailing.domain.common.dto.LeaderboardRowDTO;
|
||||
import com.sap.sailing.domain.common.dto.RaceColumnDTO;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.QuickRanksDTOProvider;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceCompetitorSet;
|
||||
import com.sap.sailing.gwt.ui.shared.QuickRankDTO;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
/**
|
||||
* Computes a map of {@link QuickRankDTO}s from a {@link LeaderboardDTO} and a {@link RaceCompetitorSet}, restricting
|
||||
* the calculation to those competitors actually taking part in a race. If the {@link LeaderboardDTO} does not contain
|
||||
* detail information about the race, only the order "from best to worst" is used, and ranks are determined based on it,
|
||||
* whereas the {@link QuickRankDTO#legNumberOneBased leg numbers} will continue to be accepted from the quick ranks
|
||||
* coming from the server.
|
||||
*
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public class QuickRanksDTOFromLeaderboardDTOProvider implements QuickRanksDTOProvider {
|
||||
private LinkedHashMap<CompetitorDTO, QuickRankDTO> quickRanks;
|
||||
private final RaceCompetitorSet raceCompetitorSet;
|
||||
private final RaceIdentifier selectedRace;
|
||||
private boolean lastLeaderboardProvidedLegNumbers;
|
||||
private String raceColumnName;
|
||||
|
||||
public QuickRanksDTOFromLeaderboardDTOProvider(RaceCompetitorSet raceCompetitorSet, RaceIdentifier selectedRace) {
|
||||
this.raceCompetitorSet = raceCompetitorSet;
|
||||
this.selectedRace = selectedRace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void quickRanksReceivedFromServer(LinkedHashMap<CompetitorDTO, QuickRankDTO> quickRanksFromServer) {
|
||||
if (quickRanks == null) {
|
||||
quickRanks = quickRanksFromServer;
|
||||
} else if (!lastLeaderboardProvidedLegNumbers) {
|
||||
// extract at least the leg numbers and update existing quick ranks accordingly in place
|
||||
for (final Entry<CompetitorDTO, QuickRankDTO> e : quickRanks.entrySet()) {
|
||||
final QuickRankDTO quickRankFromServer = quickRanksFromServer.get(e.getKey());
|
||||
if (quickRankFromServer != null) {
|
||||
e.getValue().legNumberOneBased = quickRankFromServer.legNumberOneBased;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateQuickRanks(final LeaderboardDTO leaderboard) {
|
||||
if (quickRanks == null) {
|
||||
quickRanks = new LinkedHashMap<>();
|
||||
}
|
||||
RaceColumnDTO raceColumn = leaderboard.getRaceColumnByName(raceColumnName);
|
||||
if (raceColumn == null || !raceColumn.containsRace(selectedRace)) {
|
||||
raceColumnName = getRaceColumnName(leaderboard, selectedRace);
|
||||
}
|
||||
if (raceColumnName != null) {
|
||||
final List<CompetitorDTO> competitorsFromBestToWorst = leaderboard.getCompetitorsFromBestToWorst(raceColumnName);
|
||||
int rank = 1;
|
||||
for (final CompetitorDTO c : competitorsFromBestToWorst) {
|
||||
if (Util.contains(raceCompetitorSet.getCompetitorsParticipatingInRace(), c)) {
|
||||
final LeaderboardRowDTO row = leaderboard.rows.get(c);
|
||||
final int oneBasedLegNumber;
|
||||
if (row != null) {
|
||||
final LeaderboardEntryDTO raceEntryForCompetitor = row.fieldsByRaceColumnName.get(raceColumnName);
|
||||
if (raceEntryForCompetitor != null && raceEntryForCompetitor.legDetails != null) {
|
||||
oneBasedLegNumber = raceEntryForCompetitor.getOneBasedCurrentLegNumber();
|
||||
lastLeaderboardProvidedLegNumbers = true;
|
||||
} else {
|
||||
oneBasedLegNumber = 0;
|
||||
lastLeaderboardProvidedLegNumbers = false;
|
||||
}
|
||||
} else {
|
||||
oneBasedLegNumber = 0;
|
||||
}
|
||||
QuickRankDTO quickRankToUpdate = quickRanks.get(c);
|
||||
if (quickRankToUpdate == null) {
|
||||
quickRanks.put(c, new QuickRankDTO(c, rank, oneBasedLegNumber));
|
||||
} else {
|
||||
quickRankToUpdate.rank = rank;
|
||||
if (lastLeaderboardProvidedLegNumbers) {
|
||||
quickRankToUpdate.legNumberOneBased = oneBasedLegNumber;
|
||||
}
|
||||
}
|
||||
rank++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getRaceColumnName(LeaderboardDTO leaderboard, RaceIdentifier selectedRace) {
|
||||
for (final RaceColumnDTO raceColumn : leaderboard.getRaceList()) {
|
||||
if (raceColumn.containsRace(selectedRace)) {
|
||||
return raceColumn.getName();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LinkedHashMap<CompetitorDTO, QuickRankDTO> getQuickRanks() {
|
||||
return quickRanks;
|
||||
}
|
||||
|
||||
}
|
||||
+7
-2
@@ -70,6 +70,7 @@ import com.sap.sailing.gwt.ui.client.shared.charts.WindChartLifecycle;
|
||||
import com.sap.sailing.gwt.ui.client.shared.charts.WindChartSettings;
|
||||
import com.sap.sailing.gwt.ui.client.shared.filter.FilterWithUI;
|
||||
import com.sap.sailing.gwt.ui.client.shared.filter.LeaderboardFetcher;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceCompetitorSet;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMap;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapLifecycle;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapResources;
|
||||
@@ -158,6 +159,7 @@ public class RaceBoardPanel
|
||||
|
||||
private final RaceBoardResources raceBoardResources = RaceBoardResources.INSTANCE;
|
||||
private final RaceBoardMainCss mainCss = raceBoardResources.mainCss();
|
||||
private final QuickRanksDTOFromLeaderboardDTOProvider quickRanksDTOProvider;
|
||||
|
||||
private static final RaceMapResources raceMapResources = GWT.create(RaceMapResources.class);
|
||||
|
||||
@@ -218,10 +220,12 @@ public class RaceBoardPanel
|
||||
RaceTimePanelLifecycle raceTimePanelLifecycle = lifecycle.getRaceTimePanelLifecycle();
|
||||
RaceTimePanelSettings raceTimePanelSettings = settings
|
||||
.findSettingsByComponentId(raceTimePanelLifecycle.getComponentId());
|
||||
final RaceCompetitorSet raceCompetitorSet = new RaceCompetitorSet(competitorSelectionProvider);
|
||||
quickRanksDTOProvider = new QuickRanksDTOFromLeaderboardDTOProvider(raceCompetitorSet, selectedRaceIdentifier);
|
||||
raceMap = new RaceMap(this, componentContext, raceMapLifecycle, defaultRaceMapSettings, sailingService, asyncActionsExecutor,
|
||||
errorReporter, timer,
|
||||
competitorSelectionProvider, stringMessages, selectedRaceIdentifier, raceMapResources,
|
||||
/* showHeaderPanel */ true) {
|
||||
competitorSelectionProvider, raceCompetitorSet, stringMessages, selectedRaceIdentifier,
|
||||
raceMapResources, /* showHeaderPanel */ true, quickRanksDTOProvider) {
|
||||
private static final String INDENT_SMALL_CONTROL_STYLE = "indentsmall";
|
||||
private static final String INDENT_BIG_CONTROL_STYLE = "indentbig";
|
||||
@Override
|
||||
@@ -568,6 +572,7 @@ public class RaceBoardPanel
|
||||
if (editMarkPositionPanel != null) {
|
||||
editMarkPositionPanel.setLeaderboard(leaderboard);
|
||||
}
|
||||
quickRanksDTOProvider.updateQuickRanks(leaderboard);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+5
-5
@@ -1076,6 +1076,10 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the {@link Competitor} objects passed as {@code iterable} to {@link CompetitorDTO} objects.
|
||||
* The iteration order in the result matches that of the {@code iterable} passed.
|
||||
*/
|
||||
private List<CompetitorDTO> convertToCompetitorDTOs(Iterable<? extends Competitor> iterable) {
|
||||
List<CompetitorDTO> result = new ArrayList<CompetitorDTO>();
|
||||
for (Competitor c : iterable) {
|
||||
@@ -2211,7 +2215,6 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
public QuickRanksDTO computeQuickRanks(RegattaAndRaceIdentifier raceIdentifier, TimePoint timePoint)
|
||||
throws NoWindException {
|
||||
final List<QuickRankDTO> result = new ArrayList<>();
|
||||
final List<CompetitorDTO> competitorDTOsInOrderOfWindwardDistanceTraveledFarthestFirst;
|
||||
TrackedRace trackedRace = getExistingTrackedRace(raceIdentifier);
|
||||
if (trackedRace != null) {
|
||||
final TimePoint actualTimePoint;
|
||||
@@ -2233,11 +2236,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
}
|
||||
rank++;
|
||||
}
|
||||
competitorDTOsInOrderOfWindwardDistanceTraveledFarthestFirst = convertToCompetitorDTOs(competitorsFromBestToWorst);
|
||||
} else {
|
||||
competitorDTOsInOrderOfWindwardDistanceTraveledFarthestFirst = Collections.emptyList();
|
||||
}
|
||||
return new QuickRanksDTO(result, competitorDTOsInOrderOfWindwardDistanceTraveledFarthestFirst);
|
||||
return new QuickRanksDTO(result);
|
||||
}
|
||||
|
||||
private QuickRanksDTO getQuickRanks(RegattaAndRaceIdentifier raceIdentifier, Date date) throws NoWindException {
|
||||
|
||||
-15
@@ -6,7 +6,6 @@ import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.google.gwt.user.client.rpc.IsSerializable;
|
||||
import com.sap.sailing.domain.base.RaceDefinition;
|
||||
@@ -30,7 +29,6 @@ public class CompactRaceMapDataDTO implements IsSerializable {
|
||||
private CoursePositionsDTO coursePositions;
|
||||
private List<SidelineDTO> courseSidelines;
|
||||
private List<CompactQuickRankDTO> quickRanks;
|
||||
private LinkedHashMap<String, Integer> competitorsInOrderOfWindwardDistanceTraveledFarthestFirstIdAsStringAndOneBasedLegNumber;
|
||||
private long simulationResultVersion;
|
||||
|
||||
/**
|
||||
@@ -46,7 +44,6 @@ public class CompactRaceMapDataDTO implements IsSerializable {
|
||||
this.boatPositionsByCompetitorIdAsString = new CompactBoatPositionsDTO(boatPositions);
|
||||
this.raceCompetitorIdsAsStrings = raceCompetitorIdsAsStrings;
|
||||
this.quickRanks = new ArrayList<CompactQuickRankDTO>(quickRanks == null ? 0 : Util.size(quickRanks.getQuickRanks()));
|
||||
this.competitorsInOrderOfWindwardDistanceTraveledFarthestFirstIdAsStringAndOneBasedLegNumber = new LinkedHashMap<>();
|
||||
Map<String, Integer> competitorIdAsStringToOneBasedLegNumber = new HashMap<>();
|
||||
if (quickRanks != null) {
|
||||
for (QuickRankDTO quickRank : quickRanks.getQuickRanks()) {
|
||||
@@ -54,11 +51,6 @@ public class CompactRaceMapDataDTO implements IsSerializable {
|
||||
quickRank.legNumberOneBased));
|
||||
competitorIdAsStringToOneBasedLegNumber.put(quickRank.competitor.getIdAsString(), quickRank.legNumberOneBased);
|
||||
}
|
||||
for (CompetitorDTO competitorInOrderOfWindwardDistanceTraveled : quickRanks.getCompetitorsInOrderOfWindwardDistanceTraveledFarthestFirst()) {
|
||||
this.competitorsInOrderOfWindwardDistanceTraveledFarthestFirstIdAsStringAndOneBasedLegNumber.put(
|
||||
competitorInOrderOfWindwardDistanceTraveled.getIdAsString(),
|
||||
competitorIdAsStringToOneBasedLegNumber.get(competitorInOrderOfWindwardDistanceTraveled.getIdAsString()));
|
||||
}
|
||||
}
|
||||
this.courseSidelines = courseSidelines;
|
||||
this.coursePositions = coursePositions;
|
||||
@@ -77,13 +69,6 @@ public class CompactRaceMapDataDTO implements IsSerializable {
|
||||
result.courseSidelines = courseSidelines;
|
||||
result.coursePositions = coursePositions;
|
||||
result.boatPositions = boatPositionsByCompetitorIdAsString.getBoatPositionsForCompetitors(competitorsByIdAsString);
|
||||
result.competitorsInOrderOfWindwardDistanceTraveledWithOneBasedLegNumber = new LinkedHashMap<>();
|
||||
for (Entry<String, Integer> i : competitorsInOrderOfWindwardDistanceTraveledFarthestFirstIdAsStringAndOneBasedLegNumber.entrySet()) {
|
||||
CompetitorDTO c = competitorsByIdAsString.get(i.getKey());
|
||||
if (c != null) {
|
||||
result.competitorsInOrderOfWindwardDistanceTraveledWithOneBasedLegNumber.put(c, i.getValue());
|
||||
}
|
||||
}
|
||||
result.simulationResultVersion = simulationResultVersion;
|
||||
result.raceCompetitorIdsAsStrings = this.raceCompetitorIdsAsStrings;
|
||||
return result;
|
||||
|
||||
+1
-14
@@ -1,7 +1,5 @@
|
||||
package com.sap.sailing.gwt.ui.shared;
|
||||
|
||||
import com.sap.sailing.domain.common.dto.CompetitorDTO;
|
||||
|
||||
/**
|
||||
* Combines a list of {@link QuickRankDTO} objects telling about the (calculated, according to any handicap ranking metric
|
||||
* in place)) ranks of the competitors with an information about the boat farthest ahead in the race. The latter is useful,
|
||||
@@ -17,23 +15,12 @@ public class QuickRanksDTO {
|
||||
*/
|
||||
private final Iterable<QuickRankDTO> quickRanksAfterCalculatedTime;
|
||||
|
||||
/**
|
||||
* Lists the competitors according to their windward distance traveled. The first boat (rank 1) is the
|
||||
* competitor farthest ahead.
|
||||
*/
|
||||
private final Iterable<CompetitorDTO> competitorsInOrderOfWindwardDistanceTraveledFarthestFirst;
|
||||
|
||||
public QuickRanksDTO(Iterable<QuickRankDTO> quickRanks, Iterable<CompetitorDTO> competitorsInOrderOfWindwardDistanceTraveledFarthestFirst) {
|
||||
public QuickRanksDTO(Iterable<QuickRankDTO> quickRanks) {
|
||||
super();
|
||||
this.quickRanksAfterCalculatedTime = quickRanks;
|
||||
this.competitorsInOrderOfWindwardDistanceTraveledFarthestFirst = competitorsInOrderOfWindwardDistanceTraveledFarthestFirst;
|
||||
}
|
||||
|
||||
public Iterable<QuickRankDTO> getQuickRanks() {
|
||||
return quickRanksAfterCalculatedTime;
|
||||
}
|
||||
|
||||
public Iterable<CompetitorDTO> getCompetitorsInOrderOfWindwardDistanceTraveledFarthestFirst() {
|
||||
return competitorsInOrderOfWindwardDistanceTraveledFarthestFirst;
|
||||
}
|
||||
}
|
||||
|
||||
-1
@@ -13,7 +13,6 @@ public class RaceMapDataDTO implements IsSerializable {
|
||||
public CoursePositionsDTO coursePositions;
|
||||
public List<SidelineDTO> courseSidelines;
|
||||
public LinkedHashMap<CompetitorDTO, QuickRankDTO> quickRanks;
|
||||
public LinkedHashMap<CompetitorDTO, Integer> competitorsInOrderOfWindwardDistanceTraveledWithOneBasedLegNumber;
|
||||
public long simulationResultVersion;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user