mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-14 22:43:57 +00:00
Merge branch 'master' into ubilabs--rcapp--refactoring
This commit is contained in:
commit
4e1db79fa9
202 files changed
+3863
-2836
No files matched your search
@@ -1,4 +1,4 @@
|
||||
<<<<<<< HEAD:java/com.googlecode.mgwt/.settings/org.eclipse.jdt.core.prefs
|
||||
<<<<<<< HEAD:java/com.googlecode.mgwt/.settings/org.eclipse.jdt.core.prefs
|
||||
#Thu Jan 19 09:46:08 CET 2012
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
@@ -7,25 +7,25 @@ org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
||||
||||||| merged common ancestors
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
||||
=======
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
>>>>>>> origin/master:java/com.sap.sailing.datamining.test/.settings/org.eclipse.jdt.core.prefs
|
||||
||||||| merged common ancestors
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
||||
=======
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
>>>>>>> origin/master:java/com.sap.sailing.datamining.test/.settings/org.eclipse.jdt.core.prefs
|
||||
+3
-3
@@ -24,9 +24,9 @@ public enum DetailType implements Serializable {
|
||||
AVERAGE_ABSOLUTE_CROSS_TRACK_ERROR_IN_METERS(0, ASCENDING), AVERAGE_SIGNED_CROSS_TRACK_ERROR_IN_METERS(0, ASCENDING), RACE_DISTANCE_TRAVELED(0, ASCENDING),
|
||||
RACE_DISTANCE_TRAVELED_INCLUDING_GATE_START(0, ASCENDING),
|
||||
RACE_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS(2, DESCENDING), RACE_GAP_TO_LEADER_IN_SECONDS(0, ASCENDING),
|
||||
RACE_DISTANCE_TO_LEADER_IN_METERS(0, ASCENDING), RACE_AVERAGE_ABSOLUTE_CROSS_TRACK_ERROR_IN_METERS(0, ASCENDING),
|
||||
RACE_DISTANCE_TO_COMPETITOR_FARTHEST_AHEAD_IN_METERS(0, ASCENDING), RACE_AVERAGE_ABSOLUTE_CROSS_TRACK_ERROR_IN_METERS(0, ASCENDING),
|
||||
RACE_AVERAGE_SIGNED_CROSS_TRACK_ERROR_IN_METERS(0, ASCENDING),
|
||||
WINDWARD_DISTANCE_TO_OVERALL_LEADER(0, ASCENDING), START_TACK(0, ASCENDING), DISTANCE_TO_START_AT_RACE_START(1, ASCENDING),
|
||||
WINDWARD_DISTANCE_TO_COMPETITOR_FARTHEST_AHEAD(0, ASCENDING), START_TACK(0, ASCENDING), DISTANCE_TO_START_AT_RACE_START(1, ASCENDING),
|
||||
TIME_BETWEEN_RACE_START_AND_COMPETITOR_START(1, ASCENDING),
|
||||
SPEED_OVER_GROUND_AT_RACE_START(1, DESCENDING), SPEED_OVER_GROUND_WHEN_PASSING_START(1, DESCENDING),
|
||||
DISTANCE_TO_STARBOARD_END_OF_STARTLINE_WHEN_PASSING_START_IN_METERS(1, ASCENDING),
|
||||
@@ -43,7 +43,7 @@ public enum DetailType implements Serializable {
|
||||
RACE_TOTAL_POINTS(2, ASCENDING), REGATTA_TOTAL_POINTS(2, ASCENDING), REGATTA_TOTAL_POINTS_SUM(2, ASCENDING),
|
||||
RACE_RATIO_BETWEEN_TIME_SINCE_LAST_POSITION_FIX_AND_AVERAGE_SAMPLING_INTERVAL(1, ASCENDING), RACE_DISTANCE_TO_START_FIVE_SECONDS_BEFORE_RACE_START(1, ASCENDING),
|
||||
RACE_SPEED_OVER_GROUND_FIVE_SECONDS_BEFORE_START(2, DESCENDING),
|
||||
RACE_CORRECTED_TIME_TRAVELED(0, ASCENDING), RACE_CORRECTED_TIME_AT_ESTIMATED_ARRIVAL_AT_COMPETITOR_FARTHEST_AHEAD(0, ASCENDING),
|
||||
RACE_CALCULATED_TIME_TRAVELED(0, ASCENDING), RACE_CALCULATED_TIME_AT_ESTIMATED_ARRIVAL_AT_COMPETITOR_FARTHEST_AHEAD(0, ASCENDING),
|
||||
RACE_TIME_TRAVELED(0, ASCENDING), RACE_TIME_TRAVELED_UPWIND(0, ASCENDING), RACE_TIME_TRAVELED_DOWNWIND(0, ASCENDING), RACE_TIME_TRAVELED_REACHING(0, ASCENDING),
|
||||
DISTANCE_TO_START_LINE(0, ASCENDING), BEAT_ANGLE(0, ASCENDING), COURSE_OVER_GROUND_TRUE_DEGREES(0, ASCENDING);
|
||||
|
||||
|
||||
+15
-15
@@ -42,7 +42,7 @@ public class LeaderboardEntryDTO implements Serializable {
|
||||
|
||||
public boolean discarded;
|
||||
|
||||
public Double windwardDistanceToOverallLeaderInMeters;
|
||||
public Double windwardDistanceToCompetitorFarthestAheadInMeters;
|
||||
|
||||
public Double averageAbsoluteCrossTrackErrorInMeters;
|
||||
|
||||
@@ -104,14 +104,14 @@ public class LeaderboardEntryDTO implements Serializable {
|
||||
* The corrected time spent in the race; usually based on the current time and distance, calculated by the {@link RankingMetric}.
|
||||
* For one-design classes this equals the time spent in the race.
|
||||
*/
|
||||
public Duration correctedTime;
|
||||
public Duration calculatedTime;
|
||||
|
||||
/**
|
||||
* The corrections applied to the time and distance sailed when the competitor would have reached the
|
||||
* competitor farthest ahead, based on average VMG on the current leg and equal performance to the boat
|
||||
* farthest ahead for all subsequent legs.
|
||||
*/
|
||||
public Duration correctedTimeAtEstimatedArrivalAtCompetitorFarthestAhead;
|
||||
public Duration calculatedTimeAtEstimatedArrivalAtCompetitorFarthestAhead;
|
||||
|
||||
/**
|
||||
* If <code>null</code>, no leg details are known yet, the race is not being tracked or the details
|
||||
@@ -142,9 +142,9 @@ public class LeaderboardEntryDTO implements Serializable {
|
||||
result = prime * result
|
||||
+ ((gapToLeaderInOwnTime == null) ? 0 : gapToLeaderInOwnTime.hashCode());
|
||||
result = prime * result
|
||||
+ ((correctedTime == null) ? 0 : correctedTime.hashCode());
|
||||
+ ((calculatedTime == null) ? 0 : calculatedTime.hashCode());
|
||||
result = prime * result
|
||||
+ ((correctedTimeAtEstimatedArrivalAtCompetitorFarthestAhead == null) ? 0 : correctedTimeAtEstimatedArrivalAtCompetitorFarthestAhead.hashCode());
|
||||
+ ((calculatedTimeAtEstimatedArrivalAtCompetitorFarthestAhead == null) ? 0 : calculatedTimeAtEstimatedArrivalAtCompetitorFarthestAhead.hashCode());
|
||||
result = prime * result
|
||||
+ ((averageSignedCrossTrackErrorInMeters == null) ? 0 : averageSignedCrossTrackErrorInMeters.hashCode());
|
||||
result = prime * result + (discarded ? 1231 : 1237);
|
||||
@@ -179,7 +179,7 @@ public class LeaderboardEntryDTO implements Serializable {
|
||||
result = prime * result + ((totalPoints == null) ? 0 : totalPoints.hashCode());
|
||||
result = prime
|
||||
* result
|
||||
+ ((windwardDistanceToOverallLeaderInMeters == null) ? 0 : windwardDistanceToOverallLeaderInMeters
|
||||
+ ((windwardDistanceToCompetitorFarthestAheadInMeters == null) ? 0 : windwardDistanceToCompetitorFarthestAheadInMeters
|
||||
.hashCode());
|
||||
return result;
|
||||
}
|
||||
@@ -198,15 +198,15 @@ public class LeaderboardEntryDTO implements Serializable {
|
||||
return false;
|
||||
} else if (!gapToLeaderInOwnTime.equals(other.gapToLeaderInOwnTime))
|
||||
return false;
|
||||
if (correctedTime == null) {
|
||||
if (other.correctedTime != null)
|
||||
if (calculatedTime == null) {
|
||||
if (other.calculatedTime != null)
|
||||
return false;
|
||||
} else if (!correctedTime.equals(other.correctedTime))
|
||||
} else if (!calculatedTime.equals(other.calculatedTime))
|
||||
return false;
|
||||
if (correctedTimeAtEstimatedArrivalAtCompetitorFarthestAhead == null) {
|
||||
if (other.correctedTimeAtEstimatedArrivalAtCompetitorFarthestAhead != null)
|
||||
if (calculatedTimeAtEstimatedArrivalAtCompetitorFarthestAhead == null) {
|
||||
if (other.calculatedTimeAtEstimatedArrivalAtCompetitorFarthestAhead != null)
|
||||
return false;
|
||||
} else if (!correctedTimeAtEstimatedArrivalAtCompetitorFarthestAhead.equals(other.correctedTimeAtEstimatedArrivalAtCompetitorFarthestAhead))
|
||||
} else if (!calculatedTimeAtEstimatedArrivalAtCompetitorFarthestAhead.equals(other.calculatedTimeAtEstimatedArrivalAtCompetitorFarthestAhead))
|
||||
return false;
|
||||
if (averageAbsoluteCrossTrackErrorInMeters == null) {
|
||||
if (other.averageAbsoluteCrossTrackErrorInMeters != null)
|
||||
@@ -297,10 +297,10 @@ public class LeaderboardEntryDTO implements Serializable {
|
||||
return false;
|
||||
} else if (!totalPoints.equals(other.totalPoints))
|
||||
return false;
|
||||
if (windwardDistanceToOverallLeaderInMeters == null) {
|
||||
if (other.windwardDistanceToOverallLeaderInMeters != null)
|
||||
if (windwardDistanceToCompetitorFarthestAheadInMeters == null) {
|
||||
if (other.windwardDistanceToCompetitorFarthestAheadInMeters != null)
|
||||
return false;
|
||||
} else if (!windwardDistanceToOverallLeaderInMeters.equals(other.windwardDistanceToOverallLeaderInMeters))
|
||||
} else if (!windwardDistanceToCompetitorFarthestAheadInMeters.equals(other.windwardDistanceToCompetitorFarthestAheadInMeters))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package com.sap.sailing.domain.common.impl;
|
||||
|
||||
import com.sap.sailing.domain.common.ImageSize;
|
||||
import com.sap.sse.common.media.ImageSize;
|
||||
|
||||
public class ImageSizeImpl implements ImageSize {
|
||||
private static final long serialVersionUID = 1170701774852068780L;
|
||||
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
package com.sap.sailing.domain.common.media;
|
||||
|
||||
public enum MediaCategory {
|
||||
highlight, livestream;
|
||||
}
|
||||
+2
@@ -8,6 +8,8 @@ import java.util.Set;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.media.MediaSubType;
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
|
||||
/**
|
||||
* See http://my.opera.com/core/blog/2010/03/03/everything-you-need-to-know-about-html5-video-and-audio-2
|
||||
|
||||
+5
-5
@@ -6,9 +6,9 @@ import java.util.Set;
|
||||
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
import com.sap.sailing.domain.common.media.MimeType;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
|
||||
/**
|
||||
* Offers CRUD methods for mongo representation of media track objects.
|
||||
@@ -17,7 +17,7 @@ import com.sap.sse.common.TimePoint;
|
||||
*
|
||||
*/
|
||||
public interface MediaDB {
|
||||
|
||||
|
||||
/**
|
||||
* Stores a new track to the database, returning the db-generated id.
|
||||
*/
|
||||
@@ -40,7 +40,7 @@ public interface MediaDB {
|
||||
TimePoint startTime, Duration duration, MimeType mimeType,
|
||||
Set<RegattaAndRaceIdentifier> regattaAndRace);
|
||||
|
||||
List<MediaTrack> loadAllMediaTracks();
|
||||
List<MediaTrack> loadAllMediaTracks();
|
||||
|
||||
void deleteMediaTrack(String dbId);
|
||||
|
||||
@@ -53,7 +53,7 @@ public interface MediaDB {
|
||||
void updateDuration(String dbId, Duration duration);
|
||||
|
||||
void updateRace(String dbId, Set<RegattaAndRaceIdentifier> race);
|
||||
|
||||
|
||||
MediaDB TEST_STUB = new MediaDB() {
|
||||
|
||||
@Override
|
||||
@@ -61,7 +61,7 @@ public interface MediaDB {
|
||||
TimePoint startTime, Duration duration, MimeType mimeType,
|
||||
Set<RegattaAndRaceIdentifier> assignedRaces) {
|
||||
return "0";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertMediaTrackWithId(String dbId, String videoTitle,
|
||||
|
||||
+3
-3
@@ -19,12 +19,12 @@ import com.mongodb.WriteConcern;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RegattaNameAndRaceName;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
import com.sap.sailing.domain.common.media.MimeType;
|
||||
import com.sap.sailing.domain.persistence.media.MediaDB;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.impl.MillisecondsDurationImpl;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
|
||||
/**
|
||||
* MongoDB Java API examples: http://blog.rasc.ch/?p=1096
|
||||
@@ -121,8 +121,8 @@ public class MediaDBImpl implements MediaDB {
|
||||
String dbId = ((ObjectId) dbObject.get(DbNames.Fields._id.name())).toHexString();
|
||||
String title = (String) dbObject.get(DbNames.Fields.MEDIA_TITLE.name());
|
||||
String url = (String) dbObject.get(DbNames.Fields.MEDIA_URL.name());
|
||||
Date startTime = (Date) dbObject.get(DbNames.Fields.STARTTIME.name());
|
||||
Number duration = (Number) dbObject.get(DbNames.Fields.DURATION_IN_MILLIS.name());
|
||||
Date startTime = (Date) dbObject.get(DbNames.Fields.STARTTIME.name());
|
||||
Number duration = (Number) dbObject.get(DbNames.Fields.DURATION_IN_MILLIS.name());
|
||||
String mimeTypeText = (String) dbObject.get(DbNames.Fields.MIME_TYPE.name());
|
||||
MimeType mimeType = MimeType.byName(mimeTypeText);
|
||||
Set<RegattaAndRaceIdentifier> assignedRaces = new HashSet<RegattaAndRaceIdentifier>();
|
||||
|
||||
+1
-1
@@ -3,11 +3,11 @@ package com.sap.sailing.domain.base;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import com.sap.sailing.domain.common.ImageSize;
|
||||
import com.sap.sailing.domain.common.Renamable;
|
||||
import com.sap.sse.common.Named;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.WithID;
|
||||
import com.sap.sse.common.media.ImageSize;
|
||||
|
||||
/**
|
||||
* Base interface for an Event consisting of all static information, which might be shared
|
||||
|
||||
+1
-1
@@ -9,8 +9,8 @@ import java.util.concurrent.ExecutionException;
|
||||
import com.sap.sailing.domain.base.EventBase;
|
||||
import com.sap.sailing.domain.base.LeaderboardGroupBase;
|
||||
import com.sap.sailing.domain.base.Venue;
|
||||
import com.sap.sailing.domain.common.ImageSize;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.media.ImageSize;
|
||||
|
||||
/**
|
||||
* A simplified implementation of the {@link EventBase} interface which maintains an immutable collection of
|
||||
|
||||
+6
@@ -116,6 +116,12 @@ public class TestSimpleTimeOnTimeRankingWithOneUpwindLeg {
|
||||
c2,
|
||||
Arrays.<MarkPassing> asList(new MarkPassingImpl(startOfRace, trackedRace.getRace().getCourse()
|
||||
.getFirstWaypoint(), c2)));
|
||||
trackedRace.getTrack(c1).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.0, 0), startOfRace, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(45))));
|
||||
trackedRace.getTrack(c2).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.0, 0), startOfRace, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(315))));
|
||||
trackedRace.getTrack(c1).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.5, 0), middleOfFirstLeg, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(45))));
|
||||
|
||||
+1
-1
@@ -19,8 +19,8 @@ import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.impl.EventImpl;
|
||||
import com.sap.sailing.domain.common.ImageSize;
|
||||
import com.sap.sailing.domain.common.impl.ImageSizeImpl;
|
||||
import com.sap.sse.common.media.ImageSize;
|
||||
|
||||
public class CalculateImageSizeFromUrlTest {
|
||||
|
||||
|
||||
+4
-2
@@ -23,6 +23,7 @@ import com.sap.sailing.domain.common.impl.WindImpl;
|
||||
import com.sap.sailing.domain.common.impl.WindSourceImpl;
|
||||
import com.sap.sailing.domain.leaderboard.caching.LeaderboardDTOCalculationReuseCache;
|
||||
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||
import com.sap.sailing.domain.tracking.WindPositionMode;
|
||||
import com.sap.sailing.domain.tractracadapter.ReceiverType;
|
||||
@@ -65,7 +66,7 @@ public class DirectGapCalculationVersusOneDesignRankingMetricTest extends Abstra
|
||||
|
||||
/**
|
||||
* Asserts that Philipp Buhl is having equal gap value, regardless whether calculated using the traditional
|
||||
* {@link TrackedLegOfCompetitor#getGapToLeader(TimePoint, WindPositionMode)} method or the
|
||||
* {@link TrackedLegOfCompetitor#getGapToLeader(TimePoint, RankingInfo, WindPositionMode)} method or the
|
||||
* {@link OneDesignRankingMetric#getGapToLeaderInOwnTime(Competitor, TimePoint)} method.
|
||||
*/
|
||||
@Test
|
||||
@@ -74,7 +75,8 @@ public class DirectGapCalculationVersusOneDesignRankingMetricTest extends Abstra
|
||||
TimePoint timePoint = getTrackedRace().getStartOfRace();
|
||||
for (int i=1; i<10; i++) {
|
||||
timePoint = timePoint.plus(Duration.ONE_MINUTE);
|
||||
Duration classicGap = getTrackedRace().getTrackedLeg(buhli, timePoint).getGapToLeader(timePoint, WindPositionMode.LEG_MIDDLE);
|
||||
Duration classicGap = getTrackedRace().getTrackedLeg(buhli, timePoint).getGapToLeader(timePoint,
|
||||
getTrackedRace().getRankingMetric().getRankingInfo(timePoint), WindPositionMode.LEG_MIDDLE);
|
||||
Duration rankingMetricGap = getTrackedRace().getRankingMetric().getGapToLeaderInOwnTime(buhli, timePoint);
|
||||
assertEquals("At "+i+" minutes into the race ("+timePoint+"): ", classicGap.asSeconds(), rankingMetricGap.asSeconds(), 0.000001);
|
||||
}
|
||||
|
||||
+11
-11
@@ -194,8 +194,8 @@ public class ReachingLegTest extends TrackBasedTest {
|
||||
assertEquals(0.,
|
||||
getTrackedRace().getTrack(plattner).getEstimatedPosition(timePointInReaching, /* extrapolate */false)
|
||||
.getDistance(windwardMarkPos).getMeters(), 0.00001);
|
||||
Distance hungersDistanceToLeader = getTrackedRace().getWindwardDistanceToOverallLeader(hunger, timePointInReaching, WindPositionMode.LEG_MIDDLE);
|
||||
Distance plattnersDistanceToLeader = getTrackedRace().getWindwardDistanceToOverallLeader(plattner, timePointInReaching, WindPositionMode.LEG_MIDDLE);
|
||||
Distance hungersDistanceToLeader = getTrackedRace().getWindwardDistanceToCompetitorFarthestAhead(hunger, timePointInReaching, WindPositionMode.LEG_MIDDLE);
|
||||
Distance plattnersDistanceToLeader = getTrackedRace().getWindwardDistanceToCompetitorFarthestAhead(plattner, timePointInReaching, WindPositionMode.LEG_MIDDLE);
|
||||
assertEquals(0., hungersDistanceToLeader.getMeters(), 0.00001);
|
||||
assertEquals(distanceOfReachingLeg.getMeters(), plattnersDistanceToLeader.getMeters(), 0.001);
|
||||
}
|
||||
@@ -224,8 +224,8 @@ public class ReachingLegTest extends TrackBasedTest {
|
||||
assertEquals(0.,
|
||||
getTrackedRace().getTrack(plattner).getEstimatedPosition(timePointInReaching, /* extrapolate */false)
|
||||
.getDistance(windwardMarkPos).getMeters(), 0.00001);
|
||||
Distance hungersDistanceToLeader = getTrackedRace().getWindwardDistanceToOverallLeader(hunger, timePointInReaching, WindPositionMode.LEG_MIDDLE);
|
||||
Distance plattnersDistanceToLeader = getTrackedRace().getWindwardDistanceToOverallLeader(plattner, timePointInReaching, WindPositionMode.LEG_MIDDLE);
|
||||
Distance hungersDistanceToLeader = getTrackedRace().getWindwardDistanceToCompetitorFarthestAhead(hunger, timePointInReaching, WindPositionMode.LEG_MIDDLE);
|
||||
Distance plattnersDistanceToLeader = getTrackedRace().getWindwardDistanceToCompetitorFarthestAhead(plattner, timePointInReaching, WindPositionMode.LEG_MIDDLE);
|
||||
assertEquals(0., hungersDistanceToLeader.getMeters(), 0.00001);
|
||||
assertEquals(distanceOfReachingLeg.getMeters(), plattnersDistanceToLeader.getMeters(), 0.001);
|
||||
}
|
||||
@@ -254,8 +254,8 @@ public class ReachingLegTest extends TrackBasedTest {
|
||||
assertEquals(0.,
|
||||
getTrackedRace().getTrack(plattner).getEstimatedPosition(timePointInReaching, /* extrapolate */false)
|
||||
.getDistance(windwardMarkPos).getMeters(), 0.00001);
|
||||
Distance hungersDistanceToLeader = getTrackedRace().getWindwardDistanceToOverallLeader(hunger, timePointInReaching, WindPositionMode.LEG_MIDDLE);
|
||||
Distance plattnersDistanceToLeader = getTrackedRace().getWindwardDistanceToOverallLeader(plattner, timePointInReaching, WindPositionMode.LEG_MIDDLE);
|
||||
Distance hungersDistanceToLeader = getTrackedRace().getWindwardDistanceToCompetitorFarthestAhead(hunger, timePointInReaching, WindPositionMode.LEG_MIDDLE);
|
||||
Distance plattnersDistanceToLeader = getTrackedRace().getWindwardDistanceToCompetitorFarthestAhead(plattner, timePointInReaching, WindPositionMode.LEG_MIDDLE);
|
||||
assertEquals(0., hungersDistanceToLeader.getMeters(), 0.00001);
|
||||
assertEquals(distanceOfReachingLeg.getMeters(), plattnersDistanceToLeader.getMeters(), 0.001);
|
||||
}
|
||||
@@ -289,8 +289,8 @@ public class ReachingLegTest extends TrackBasedTest {
|
||||
assertEquals(0.,
|
||||
getTrackedRace().getTrack(plattner).getEstimatedPosition(timePointToConsider, /* extrapolate */false)
|
||||
.getDistance(leewardPos).getMeters(), 0.00001);
|
||||
Distance hungersDistanceToLeader = getTrackedRace().getWindwardDistanceToOverallLeader(hunger, timePointToConsider, WindPositionMode.LEG_MIDDLE);
|
||||
Distance plattnersDistanceToLeader = getTrackedRace().getWindwardDistanceToOverallLeader(plattner, timePointToConsider, WindPositionMode.LEG_MIDDLE);
|
||||
Distance hungersDistanceToLeader = getTrackedRace().getWindwardDistanceToCompetitorFarthestAhead(hunger, timePointToConsider, WindPositionMode.LEG_MIDDLE);
|
||||
Distance plattnersDistanceToLeader = getTrackedRace().getWindwardDistanceToCompetitorFarthestAhead(plattner, timePointToConsider, WindPositionMode.LEG_MIDDLE);
|
||||
assertEquals(0., hungersDistanceToLeader.getMeters(), 0.00001);
|
||||
assertEquals(distanceOfReachingLeg.getMeters()+windwardDistanceOfUpwindLeg.getMeters(), plattnersDistanceToLeader.getMeters(), 0.001);
|
||||
}
|
||||
@@ -333,8 +333,8 @@ public class ReachingLegTest extends TrackBasedTest {
|
||||
assertEquals(0.,
|
||||
getTrackedRace().getTrack(plattner).getEstimatedPosition(timePointToConsider, /* extrapolate */false)
|
||||
.getDistance(leewardPos).getMeters(), 0.00001);
|
||||
Distance schomaekersDistanceToLeader = getTrackedRace().getWindwardDistanceToOverallLeader(schomaeker, timePointToConsider, WindPositionMode.LEG_MIDDLE);
|
||||
Distance plattnersDistanceToLeader = getTrackedRace().getWindwardDistanceToOverallLeader(plattner, timePointToConsider, WindPositionMode.LEG_MIDDLE);
|
||||
Distance schomaekersDistanceToLeader = getTrackedRace().getWindwardDistanceToCompetitorFarthestAhead(schomaeker, timePointToConsider, WindPositionMode.LEG_MIDDLE);
|
||||
Distance plattnersDistanceToLeader = getTrackedRace().getWindwardDistanceToCompetitorFarthestAhead(plattner, timePointToConsider, WindPositionMode.LEG_MIDDLE);
|
||||
assertEquals(0., schomaekersDistanceToLeader.getMeters(), 0.00001);
|
||||
// distance to leading Schomaeker expected to be the entire upwind distance plus the offset distance plus half the downwind
|
||||
assertEquals(distanceOfReachingLeg.getMeters()+windwardDistanceOfUpwindLeg.getMeters()*1.5, plattnersDistanceToLeader.getMeters(), 0.001);
|
||||
@@ -374,7 +374,7 @@ public class ReachingLegTest extends TrackBasedTest {
|
||||
getTrackedRace().getTrack(plattner).getEstimatedPosition(timePointToConsider, /* extrapolate */
|
||||
false)).getMeters(), 0.00001);
|
||||
// however, projected onto the leg their distance should be 0
|
||||
Distance plattnersDistanceToLeader = getTrackedRace().getWindwardDistanceToOverallLeader(plattner, timePointToConsider, WindPositionMode.LEG_MIDDLE);
|
||||
Distance plattnersDistanceToLeader = getTrackedRace().getWindwardDistanceToCompetitorFarthestAhead(plattner, timePointToConsider, WindPositionMode.LEG_MIDDLE);
|
||||
assertEquals(0., plattnersDistanceToLeader.getMeters(), 0.00001);
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -239,9 +239,9 @@ public class WindEstimationOnConstructedTracksTest extends StoredTrackBasedTest
|
||||
assertNotNull(estimatedWindDirectionCached);
|
||||
assertEquals(185., estimatedWindDirectionCached.getBearing().getDegrees(), 0.00000001);
|
||||
// now add a GPS fix and make sure the cache is invalidated by adding it inside the averaging interval
|
||||
now = new MillisecondsTimePoint(checkTime.asMillis() + track.getMillisecondsOverWhichToAverageWind()/2);
|
||||
setBearingForCompetitor(competitors.get(0), now, 330);
|
||||
setBearingForCompetitor(competitors.get(0), now, 310);
|
||||
now = new MillisecondsTimePoint(checkTime.asMillis() + track.getMillisecondsOverWhichToAverageWind()/2);
|
||||
setBearingForCompetitor(competitors.get(0), now, 330);
|
||||
setBearingForCompetitor(competitors.get(0), now, 310);
|
||||
Wind estimatedWindDirectionNew = track.getAveragedWind(/* position */ null, checkTime);
|
||||
assertFalse(cachedFixes.isEmpty());
|
||||
assertNotNull(estimatedWindDirectionNew);
|
||||
|
||||
+20
-9
@@ -44,6 +44,7 @@ import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||
import com.sap.sailing.domain.polars.PolarDataService;
|
||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
||||
import com.sap.sailing.domain.ranking.RankingMetricConstructor;
|
||||
import com.sap.sailing.domain.regattalike.RegattaLikeIdentifier;
|
||||
import com.sap.sailing.domain.regattalike.RegattaLikeListener;
|
||||
@@ -506,6 +507,22 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
||||
DynamicRaceDefinitionSet raceDefinitionSetToUpdate, boolean useMarkPassingcalculator) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lockTrackedRacesForRead() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unlockTrackedRacesAfterRead() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lockTrackedRacesForWrite() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unlockTrackedRacesAfterWrite() {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -564,7 +581,7 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getWindwardDistanceToOverallLeader(Competitor competitor, TimePoint timePoint, WindPositionMode windPositionMode) {
|
||||
public Distance getWindwardDistanceToCompetitorFarthestAhead(Competitor competitor, TimePoint timePoint, WindPositionMode windPositionMode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -935,14 +952,8 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getCorrectedWindwardDistanceToOverallLeader(Competitor competitor, TimePoint timePoint,
|
||||
WindPositionMode windPositionMode) throws NoWindException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getWindwardDistanceToOverallLeader(Competitor competitor, TimePoint timePoint,
|
||||
WindPositionMode windPositionMode, WindLegTypeAndLegBearingCache cache) {
|
||||
public Distance getWindwardDistanceToCompetitorFarthestAhead(Competitor competitor, TimePoint timePoint,
|
||||
WindPositionMode windPositionMode, RankingInfo rankingInfo, WindLegTypeAndLegBearingCache cache) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+4
-9
@@ -35,6 +35,7 @@ import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||
import com.sap.sailing.domain.polars.PolarDataService;
|
||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
||||
import com.sap.sailing.domain.tracking.CourseDesignChangedListener;
|
||||
import com.sap.sailing.domain.tracking.GPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.LineDetails;
|
||||
@@ -345,7 +346,7 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getWindwardDistanceToOverallLeader(Competitor competitor, TimePoint timePoint, WindPositionMode windPositionMode) {
|
||||
public Distance getWindwardDistanceToCompetitorFarthestAhead(Competitor competitor, TimePoint timePoint, WindPositionMode windPositionMode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -611,14 +612,8 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getCorrectedWindwardDistanceToOverallLeader(Competitor competitor, TimePoint timePoint,
|
||||
WindPositionMode windPositionMode) throws NoWindException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getWindwardDistanceToOverallLeader(Competitor competitor, TimePoint timePoint,
|
||||
WindPositionMode windPositionMode, WindLegTypeAndLegBearingCache cache) {
|
||||
public Distance getWindwardDistanceToCompetitorFarthestAhead(Competitor competitor, TimePoint timePoint,
|
||||
WindPositionMode windPositionMode, RankingInfo rankingInfo, WindLegTypeAndLegBearingCache cache) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+11
-3
@@ -494,9 +494,17 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
TrackedRegatta trackedRegatta = trackedRegattaRegistry.getTrackedRegatta(regatta);
|
||||
if (trackedRegatta != null) {
|
||||
// see above; only remove tracked regatta if it *became* empty because of the tracked race removal here
|
||||
int oldSizeOfTrackedRaces = Util.size(trackedRegatta.getTrackedRaces());
|
||||
trackedRegatta.removeTrackedRace(raceDefinition);
|
||||
if (oldSizeOfTrackedRaces > 0 && Util.size(trackedRegatta.getTrackedRaces()) == 0) {
|
||||
final int oldSizeOfTrackedRaces;
|
||||
final int newSizeOfTrackedRaces;
|
||||
trackedRegatta.lockTrackedRacesForWrite();
|
||||
try {
|
||||
oldSizeOfTrackedRaces = Util.size(trackedRegatta.getTrackedRaces());
|
||||
trackedRegatta.removeTrackedRace(raceDefinition);
|
||||
newSizeOfTrackedRaces = Util.size(trackedRegatta.getTrackedRaces());
|
||||
} finally {
|
||||
trackedRegatta.unlockTrackedRacesAfterWrite();
|
||||
}
|
||||
if (oldSizeOfTrackedRaces > 0 && newSizeOfTrackedRaces == 0) {
|
||||
trackedRegattaRegistry.removeTrackedRegatta(regatta);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import java.net.URL;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import com.sap.sailing.domain.common.ImageSize;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
import com.sap.sse.common.media.ImageSize;
|
||||
|
||||
/**
|
||||
* An event is a group of {@link Regatta regattas} carried out at a common venue within a common time frame. For
|
||||
|
||||
@@ -26,11 +26,11 @@ import javax.imageio.stream.ImageInputStream;
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.base.Venue;
|
||||
import com.sap.sailing.domain.common.ImageSize;
|
||||
import com.sap.sailing.domain.common.impl.ImageSizeImpl;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.media.ImageSize;
|
||||
|
||||
public class EventImpl extends EventBaseImpl implements Event {
|
||||
private static final long serialVersionUID = 855135446595485715L;
|
||||
|
||||
+5
@@ -28,7 +28,12 @@ public interface LeaderboardGroup extends LeaderboardGroupBase {
|
||||
void addLeaderboardGroupListener(LeaderboardGroupListener listener);
|
||||
void removeLeaderboardGroupListener(LeaderboardGroupListener listener);
|
||||
boolean isDisplayGroupsInReverseOrder();
|
||||
|
||||
/**
|
||||
* @return a non-live copy of the leaderboard list as it looked when the method was called
|
||||
*/
|
||||
Iterable<Leaderboard> getLeaderboards();
|
||||
|
||||
int getIndexOf(Leaderboard leaderboard);
|
||||
void addLeaderboard(Leaderboard leaderboard);
|
||||
void addLeaderboardAt(Leaderboard leaderboard, int index);
|
||||
|
||||
+17
-17
@@ -1392,15 +1392,15 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
|
||||
RaceDetails raceDetails = getRaceDetails(trackedRace, competitor, timePoint, waitForLatestAnalyses,
|
||||
legRanksCache, rankingInfo, cache);
|
||||
entryDTO.legDetails = raceDetails.getLegDetails();
|
||||
entryDTO.windwardDistanceToOverallLeaderInMeters = raceDetails.getWindwardDistanceToOverallLeader() == null ? null
|
||||
: raceDetails.getWindwardDistanceToOverallLeader().getMeters();
|
||||
entryDTO.windwardDistanceToCompetitorFarthestAheadInMeters = raceDetails.getWindwardDistanceToCompetitorFarthestAhead() == null ? null
|
||||
: raceDetails.getWindwardDistanceToCompetitorFarthestAhead().getMeters();
|
||||
entryDTO.gapToLeaderInOwnTime = trackedRace.getRankingMetric().getGapToLeaderInOwnTime(rankingInfo, competitor, cache);
|
||||
entryDTO.averageAbsoluteCrossTrackErrorInMeters = raceDetails.getAverageAbsoluteCrossTrackError() == null ? null
|
||||
: raceDetails.getAverageAbsoluteCrossTrackError().getMeters();
|
||||
entryDTO.averageSignedCrossTrackErrorInMeters = raceDetails.getAverageSignedCrossTrackError() == null ? null
|
||||
: raceDetails.getAverageSignedCrossTrackError().getMeters();
|
||||
entryDTO.correctedTime = raceDetails.getCorrectedTime();
|
||||
entryDTO.correctedTimeAtEstimatedArrivalAtCompetitorFarthestAhead = raceDetails.getCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAhead();
|
||||
entryDTO.calculatedTime = raceDetails.getCorrectedTime();
|
||||
entryDTO.calculatedTimeAtEstimatedArrivalAtCompetitorFarthestAhead = raceDetails.getCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAhead();
|
||||
entryDTO.gapToLeaderInOwnTime = raceDetails.getGapToLeaderInOwnTime();
|
||||
final TimePoint startOfRace = trackedRace.getStartOfRace();
|
||||
if (startOfRace != null) {
|
||||
@@ -1481,20 +1481,20 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
|
||||
|
||||
private static class RaceDetails {
|
||||
private final List<LegEntryDTO> legDetails;
|
||||
private final Distance windwardDistanceToOverallLeader;
|
||||
private final Distance windwardDistanceToCompetitorFarthestAhead;
|
||||
private final Distance averageAbsoluteCrossTrackError;
|
||||
private final Distance averageSignedCrossTrackError;
|
||||
private final Duration gapToLeaderInOwnTime;
|
||||
private final Duration correctedTime;
|
||||
private final Duration correctedTimeAtEstimatedArrivalAtCompetitorFarthestAhead;
|
||||
|
||||
public RaceDetails(List<LegEntryDTO> legDetails, Distance windwardDistanceToOverallLeader,
|
||||
public RaceDetails(List<LegEntryDTO> legDetails, Distance windwardDistanceToCompetitorFarthestAhead,
|
||||
Distance averageAbsoluteCrossTrackError, Distance averageSignedCrossTrackError,
|
||||
Duration gapToLeaderInOwnTime, Duration correctedTime,
|
||||
Duration correctedTimeAtEstimatedArrivalAtCompetitorFarthestAhead) {
|
||||
super();
|
||||
this.legDetails = legDetails;
|
||||
this.windwardDistanceToOverallLeader = windwardDistanceToOverallLeader;
|
||||
this.windwardDistanceToCompetitorFarthestAhead = windwardDistanceToCompetitorFarthestAhead;
|
||||
this.averageAbsoluteCrossTrackError = averageAbsoluteCrossTrackError;
|
||||
this.averageSignedCrossTrackError = averageSignedCrossTrackError;
|
||||
this.gapToLeaderInOwnTime = gapToLeaderInOwnTime;
|
||||
@@ -1504,8 +1504,8 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
|
||||
public List<LegEntryDTO> getLegDetails() {
|
||||
return legDetails;
|
||||
}
|
||||
public Distance getWindwardDistanceToOverallLeader() {
|
||||
return windwardDistanceToOverallLeader;
|
||||
public Distance getWindwardDistanceToCompetitorFarthestAhead() {
|
||||
return windwardDistanceToCompetitorFarthestAhead;
|
||||
}
|
||||
public Distance getAverageAbsoluteCrossTrackError() {
|
||||
return averageAbsoluteCrossTrackError;
|
||||
@@ -1581,7 +1581,7 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
|
||||
|
||||
private RaceDetails calculateRaceDetails(TrackedRace trackedRace, Competitor competitor, TimePoint timePoint,
|
||||
boolean waitForLatestAnalyses, Map<Leg, LinkedHashMap<Competitor, Integer>> legRanksCache,
|
||||
WindLegTypeAndLegBearingCache cache, RankingInfo rankingInfo) throws NoWindException {
|
||||
WindLegTypeAndLegBearingCache cache, final RankingInfo rankingInfo) throws NoWindException {
|
||||
final List<LegEntryDTO> legDetails = new ArrayList<LegEntryDTO>();
|
||||
final Course course = trackedRace.getRace().getCourse();
|
||||
course.lockForRead(); // hold back any course re-configurations while looping over the legs
|
||||
@@ -1599,8 +1599,8 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
|
||||
}
|
||||
legDetails.add(legEntry);
|
||||
}
|
||||
final Distance windwardDistanceToOverallLeader = trackedRace == null ? null : trackedRace
|
||||
.getWindwardDistanceToOverallLeader(competitor, timePoint, WindPositionMode.LEG_MIDDLE, cache);
|
||||
final Distance windwardDistanceToCompetitorFarthestAhead = trackedRace == null ? null : trackedRace
|
||||
.getWindwardDistanceToCompetitorFarthestAhead(competitor, timePoint, WindPositionMode.LEG_MIDDLE, rankingInfo, cache);
|
||||
Distance averageAbsoluteCrossTrackError;
|
||||
try {
|
||||
averageAbsoluteCrossTrackError = trackedRace == null ? null : trackedRace.getAverageAbsoluteCrossTrackError(
|
||||
@@ -1617,7 +1617,7 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
|
||||
// without wind information, use null meaning "unknown"
|
||||
averageSignedCrossTrackError = null;
|
||||
}
|
||||
return new RaceDetails(legDetails, windwardDistanceToOverallLeader, averageAbsoluteCrossTrackError, averageSignedCrossTrackError,
|
||||
return new RaceDetails(legDetails, windwardDistanceToCompetitorFarthestAhead, averageAbsoluteCrossTrackError, averageSignedCrossTrackError,
|
||||
trackedRace.getRankingMetric().getGapToLeaderInOwnTime(rankingInfo, competitor, cache),
|
||||
trackedRace.getRankingMetric().getCorrectedTime(competitor, timePoint),
|
||||
rankingInfo.getCompetitorRankingInfo().apply(competitor).getCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAhead());
|
||||
@@ -1678,10 +1678,10 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
|
||||
trackedLeg.hasFinishedLeg(timePoint) ? trackedLeg.getFinishTime() : timePoint, cache) : null;
|
||||
// fetch the leg gap in own corrected time from the ranking metric
|
||||
final Duration gapToLeaderInOwnTime = trackedLeg.getTrackedLeg().getTrackedRace().getRankingMetric().
|
||||
getLegGapToLegLeaderInOwnTime(trackedLeg, timePoint, cache);
|
||||
getLegGapToLegLeaderInOwnTime(trackedLeg, timePoint, rankingInfo, cache);
|
||||
result.gapToLeaderInSeconds = gapToLeaderInOwnTime == null ? null : gapToLeaderInOwnTime.asSeconds();
|
||||
if (result.gapToLeaderInSeconds != null) {
|
||||
final Duration gapAtEndOfPreviousLeg = getGapAtEndOfPreviousLeg(trackedLeg, cache);
|
||||
final Duration gapAtEndOfPreviousLeg = getGapAtEndOfPreviousLeg(trackedLeg, rankingInfo, cache);
|
||||
if (gapAtEndOfPreviousLeg != null) {
|
||||
result.gapChangeSinceLegStartInSeconds = result.gapToLeaderInSeconds - gapAtEndOfPreviousLeg.asSeconds();
|
||||
}
|
||||
@@ -1766,7 +1766,7 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
|
||||
return result;
|
||||
}
|
||||
|
||||
private Duration getGapAtEndOfPreviousLeg(TrackedLegOfCompetitor trackedLeg, WindLegTypeAndLegBearingCache cache) {
|
||||
private Duration getGapAtEndOfPreviousLeg(TrackedLegOfCompetitor trackedLeg, final RankingInfo rankingInfo, WindLegTypeAndLegBearingCache cache) {
|
||||
final Duration result;
|
||||
final Course course = trackedLeg.getTrackedLeg().getTrackedRace().getRace().getCourse();
|
||||
// if trackedLeg is the first leg, compute the gap at the start of this leg; otherwise, compute gap
|
||||
@@ -1779,7 +1779,7 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
|
||||
tloc = trackedLeg.getTrackedLeg().getTrackedRace().getTrackedLegFinishingAt(trackedLeg.getLeg().getFrom())
|
||||
.getTrackedLeg(trackedLeg.getCompetitor());
|
||||
}
|
||||
result = trackedLeg.getTrackedLeg().getTrackedRace().getRankingMetric().getLegGapToLegLeaderInOwnTime(tloc, timePoint, cache);
|
||||
result = trackedLeg.getTrackedLeg().getTrackedRace().getRankingMetric().getLegGapToLegLeaderInOwnTime(tloc, timePoint, rankingInfo, cache);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+51
-11
@@ -13,12 +13,25 @@ import com.sap.sailing.domain.base.impl.LeaderboardGroupBaseImpl;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroupListener;
|
||||
import com.sap.sse.concurrent.LockUtil;
|
||||
import com.sap.sse.concurrent.NamedReentrantReadWriteLock;
|
||||
|
||||
public class LeaderboardGroupImpl extends LeaderboardGroupBaseImpl implements LeaderboardGroup {
|
||||
|
||||
private static final long serialVersionUID = 2035927369446736934L;
|
||||
private boolean displayGroupsInReverseOrder;
|
||||
|
||||
/**
|
||||
* The lock that guards access to the {@link #leaderboards} list.
|
||||
*/
|
||||
private final NamedReentrantReadWriteLock leaderboardsLock;
|
||||
|
||||
/**
|
||||
* The list of leaderboards grouped in this leaderboard group. Access to this list is guarded by
|
||||
* {@link #leaderboardsLock}. All access has to acquire the corresponding read or write lock.
|
||||
*/
|
||||
private final List<Leaderboard> leaderboards;
|
||||
|
||||
private final Set<LeaderboardGroupListener> listeners;
|
||||
|
||||
/**
|
||||
@@ -36,8 +49,13 @@ public class LeaderboardGroupImpl extends LeaderboardGroupBaseImpl implements Le
|
||||
this(UUID.randomUUID(), name, description, displayName, displayGroupsInReverseOrder, leaderboards);
|
||||
}
|
||||
|
||||
private synchronized void writeObject(ObjectOutputStream oos) throws IOException {
|
||||
oos.defaultWriteObject();
|
||||
private void writeObject(ObjectOutputStream oos) throws IOException {
|
||||
LockUtil.lockForRead(leaderboardsLock);
|
||||
try {
|
||||
oos.defaultWriteObject();
|
||||
} finally {
|
||||
LockUtil.unlockAfterRead(leaderboardsLock);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,9 +64,10 @@ public class LeaderboardGroupImpl extends LeaderboardGroupBaseImpl implements Le
|
||||
public LeaderboardGroupImpl(UUID id, String name, String description, String displayName,
|
||||
boolean displayGroupsInReverseOrder, List<? extends Leaderboard> leaderboards) {
|
||||
super(id, name, description, displayName);
|
||||
this.leaderboardsLock = new NamedReentrantReadWriteLock("leaderboards lock fo rleaderboard group "+name, /* fair */ false);
|
||||
this.displayGroupsInReverseOrder = displayGroupsInReverseOrder;
|
||||
this.leaderboards = new ArrayList<Leaderboard>(leaderboards);
|
||||
this.listeners = new HashSet<LeaderboardGroupListener>();
|
||||
this.leaderboards = new ArrayList<>(leaderboards);
|
||||
this.listeners = new HashSet<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -99,24 +118,42 @@ public class LeaderboardGroupImpl extends LeaderboardGroupBaseImpl implements Le
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Iterable<Leaderboard> getLeaderboards() {
|
||||
return new ArrayList<Leaderboard>(leaderboards);
|
||||
public Iterable<Leaderboard> getLeaderboards() {
|
||||
LockUtil.lockForRead(leaderboardsLock);
|
||||
try {
|
||||
return new ArrayList<Leaderboard>(leaderboards);
|
||||
} finally {
|
||||
LockUtil.unlockAfterRead(leaderboardsLock);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int getIndexOf(Leaderboard leaderboard) {
|
||||
return leaderboards.indexOf(leaderboard);
|
||||
public int getIndexOf(Leaderboard leaderboard) {
|
||||
LockUtil.lockForRead(leaderboardsLock);
|
||||
try {
|
||||
return leaderboards.indexOf(leaderboard);
|
||||
} finally {
|
||||
LockUtil.unlockAfterRead(leaderboardsLock);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLeaderboard(Leaderboard leaderboard) {
|
||||
addLeaderboardAt(leaderboard, leaderboards.size());
|
||||
LockUtil.lockForWrite(leaderboardsLock);
|
||||
try {
|
||||
addLeaderboardAt(leaderboard, leaderboards.size());
|
||||
} finally {
|
||||
LockUtil.unlockAfterWrite(leaderboardsLock);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLeaderboardAt(Leaderboard leaderboard, int index) {
|
||||
synchronized (this) {
|
||||
LockUtil.lockForWrite(leaderboardsLock);
|
||||
try {
|
||||
leaderboards.add(index, leaderboard);
|
||||
} finally {
|
||||
LockUtil.unlockAfterWrite(leaderboardsLock);
|
||||
}
|
||||
notifyLeaderboardGroupListenersAboutLeaderboardAdded(leaderboard);
|
||||
}
|
||||
@@ -130,8 +167,11 @@ public class LeaderboardGroupImpl extends LeaderboardGroupBaseImpl implements Le
|
||||
|
||||
@Override
|
||||
public void removeLeaderboard(Leaderboard leaderboard) {
|
||||
synchronized (this) {
|
||||
LockUtil.lockForWrite(leaderboardsLock);
|
||||
try {
|
||||
leaderboards.remove(leaderboard);
|
||||
} finally {
|
||||
LockUtil.unlockAfterWrite(leaderboardsLock);
|
||||
}
|
||||
notifyLeaderboardGroupListenersAboutLeaderboardRemoved(leaderboard);
|
||||
}
|
||||
|
||||
@@ -173,12 +173,11 @@ public interface PolarDataService {
|
||||
*
|
||||
* @param boatClass
|
||||
* @param legType
|
||||
* @param tack
|
||||
* @return The estimating function for the tack and legtype combination estimating boatspeed over windspeed for the
|
||||
* given boat class. All values in kn.
|
||||
* @throws NotEnoughDataHasBeenAddedException
|
||||
*/
|
||||
PolynomialFunction getSpeedRegressionFunction(BoatClass boatClass, LegType legType, Tack tack) throws NotEnoughDataHasBeenAddedException;
|
||||
PolynomialFunction getSpeedRegressionFunction(BoatClass boatClass, LegType legType) throws NotEnoughDataHasBeenAddedException;
|
||||
|
||||
/**
|
||||
* This method is not intended to be used directly apart from debugging purposes. If you intend to use the polar service please
|
||||
@@ -186,12 +185,11 @@ public interface PolarDataService {
|
||||
*
|
||||
* @param boatClass
|
||||
* @param legType
|
||||
* @param tack
|
||||
* @return The estimating function for the tack and legtype combination estimating true wind angle over windspeed for the
|
||||
* given boat class. TWA in degrees and windspeeds in knots.
|
||||
* @throws NotEnoughDataHasBeenAddedException
|
||||
*/
|
||||
PolynomialFunction getAngleRegressionFunction(BoatClass boatClass, LegType legType, Tack tack) throws NotEnoughDataHasBeenAddedException;
|
||||
PolynomialFunction getAngleRegressionFunction(BoatClass boatClass, LegType legType) throws NotEnoughDataHasBeenAddedException;
|
||||
|
||||
/**
|
||||
* This method is not intended to be used directly apart from debugging purposes. If you intend to use the polar service please
|
||||
|
||||
+176
-41
@@ -2,7 +2,9 @@ package com.sap.sailing.domain.ranking;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.StreamSupport;
|
||||
@@ -10,9 +12,11 @@ import java.util.stream.StreamSupport;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Leg;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.base.impl.CompetitorImpl;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||
import com.sap.sailing.domain.leaderboard.caching.LeaderboardDTOCalculationReuseCache;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||
@@ -121,14 +125,81 @@ public abstract class AbstractRankingMetric implements RankingMetric {
|
||||
}
|
||||
}
|
||||
|
||||
public class RankingInfoImpl implements RankingMetric.RankingInfo {
|
||||
private static final long serialVersionUID = -2390284312153324336L;
|
||||
|
||||
/**
|
||||
* Helper instance used to encode <code>null</code> values in {@link ConcurrentHashMap} instances which do not accept
|
||||
* <code>null</code> as key nor value.
|
||||
*/
|
||||
private final static Competitor NULL_COMPETITOR = new CompetitorImpl(null, null, null, null, null, null, null, null, null);
|
||||
|
||||
public abstract class AbstractRankingInfo implements RankingMetric.RankingInfo {
|
||||
private static final long serialVersionUID = 6845168655725234325L;
|
||||
|
||||
/**
|
||||
* The time point for which this ranking information is valid
|
||||
*/
|
||||
private final TimePoint timePoint;
|
||||
|
||||
/**
|
||||
* Caches, on demand, the results of calls to {@link #getCompetitorFarthestAheadInLeg(Leg, TimePoint, WindLegTypeAndLegBearingCache)}.
|
||||
* <code>null</code> values are encoded as the {@link #NULL_COMPETITOR} and must be translated back to <code>null</code> before returning
|
||||
* to a caller outside of this class.
|
||||
*/
|
||||
private final ConcurrentHashMap<Leg, Competitor> competitorFarthestAheadInLeg;
|
||||
|
||||
public AbstractRankingInfo(final TimePoint timePoint) {
|
||||
this.timePoint = timePoint;
|
||||
this.competitorFarthestAheadInLeg = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimePoint getTimePoint() {
|
||||
return timePoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getActualTimeFromRaceStartToReachFarthestAheadInLeg(Competitor competitor, Leg leg, WindLegTypeAndLegBearingCache cache) {
|
||||
final Duration result;
|
||||
final TrackedLegOfCompetitor tloc = getTrackedRace().getTrackedLeg(competitor, getTimePoint());
|
||||
final Duration raceDurationAtTimePoint = getTrackedRace().getStartOfRace().until(getTimePoint());
|
||||
if (tloc != null && tloc.hasStartedLeg(getTimePoint())) {
|
||||
final Competitor competitorFarthestAheadInLeg = getCompetitorFarthestAheadInLeg(leg, getTimePoint(), cache);
|
||||
final TrackedLegOfCompetitor tlocOfCompetitorFarthestAheadInLeg = tloc.getTrackedLeg().getTrackedLeg(competitorFarthestAheadInLeg);
|
||||
final Duration predictedDurationFromTimePointToReachFarthestAheadInLeg = getPredictedDurationToReachWindwardPositionOf(
|
||||
tloc, tlocOfCompetitorFarthestAheadInLeg, getTimePoint(), cache);
|
||||
if (predictedDurationFromTimePointToReachFarthestAheadInLeg == null) {
|
||||
result = null;
|
||||
} else {
|
||||
final Duration cDurationFromRaceStartToReachFarthestInLeg = raceDurationAtTimePoint.plus(predictedDurationFromTimePointToReachFarthestAheadInLeg);
|
||||
result = cDurationFromRaceStartToReachFarthestInLeg;
|
||||
}
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Competitor getCompetitorFarthestAheadInLeg(Leg leg, TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
|
||||
Competitor result = competitorFarthestAheadInLeg.get(leg);
|
||||
if (result == NULL_COMPETITOR) {
|
||||
result = null;
|
||||
} else if (result == null) {
|
||||
result = AbstractRankingMetric.this.getCompetitorFarthestAheadInLeg(getTrackedRace().getTrackedLeg(leg), timePoint, cache);
|
||||
competitorFarthestAheadInLeg.put(leg, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Competitor getLeaderInLegByCalculatedTime(Leg leg, WindLegTypeAndLegBearingCache cache) {
|
||||
final TrackedLeg trackedLeg = getTrackedRace().getTrackedLeg(leg);
|
||||
return trackedLeg.getLeader(getTimePoint(), cache);
|
||||
}
|
||||
}
|
||||
|
||||
public class RankingInfoImpl extends AbstractRankingInfo {
|
||||
private static final long serialVersionUID = -2390284312153324336L;
|
||||
|
||||
/**
|
||||
* The basic information for each competitor, telling about actual and corrected times as well as information
|
||||
* about actual and corrected times needed to reach the position of the competitor farthest ahead at
|
||||
@@ -145,20 +216,15 @@ public abstract class AbstractRankingMetric implements RankingMetric {
|
||||
private final Competitor leaderByCorrectedEstimatedTimeToCompetitorFarthestAhead;
|
||||
|
||||
public RankingInfoImpl(TimePoint timePoint, Map<Competitor, RankingMetric.CompetitorRankingInfo> competitorRankingInfo, Competitor competitorFarthestAhead) {
|
||||
super(timePoint);
|
||||
final Comparator<Duration> durationComparatorNullsLast = Comparator.nullsLast(Comparator.naturalOrder());
|
||||
this.timePoint = timePoint;
|
||||
this.competitorRankingInfo = c->competitorRankingInfo.get(c);
|
||||
this.competitorFarthestAhead = competitorFarthestAhead;
|
||||
leaderByCorrectedEstimatedTimeToCompetitorFarthestAhead = competitorRankingInfo.keySet().stream().sorted(
|
||||
(c1, c2) -> durationComparatorNullsLast.compare(
|
||||
competitorRankingInfo.get(c1).getCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAhead(),
|
||||
competitorRankingInfo.get(c2).getCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAhead())).
|
||||
findFirst().get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimePoint getTimePoint() {
|
||||
return timePoint;
|
||||
findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -219,7 +285,7 @@ public abstract class AbstractRankingMetric implements RankingMetric {
|
||||
*/
|
||||
private Comparator<Competitor> getWindwardDistanceTraveledComparator(final TimePoint timePoint, final WindLegTypeAndLegBearingCache cache) {
|
||||
final Map<Competitor, Distance> windwardDistanceTraveledPerCompetitor = new HashMap<>();
|
||||
for (final Competitor competitor : getTrackedRace().getRace().getCompetitors()) {
|
||||
for (final Competitor competitor : getCompetitors()) {
|
||||
windwardDistanceTraveledPerCompetitor.put(competitor, getWindwardDistanceTraveled(competitor, timePoint, cache));
|
||||
}
|
||||
final Comparator<Distance> nullsFirstDistanceComparator = Comparator.nullsFirst(Comparator.naturalOrder());
|
||||
@@ -227,12 +293,19 @@ public abstract class AbstractRankingMetric implements RankingMetric {
|
||||
windwardDistanceTraveledPerCompetitor.get(c2),
|
||||
windwardDistanceTraveledPerCompetitor.get(c1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the competitors to consider for this ranking
|
||||
*/
|
||||
protected Iterable<Competitor> getCompetitors() {
|
||||
return getTrackedRace().getRace().getCompetitors();
|
||||
}
|
||||
|
||||
public RankingMetric.RankingInfo getRankingInfo(TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
|
||||
Map<Competitor, RankingMetric.CompetitorRankingInfo> result = new HashMap<>();
|
||||
Comparator<Competitor> oneDesignComparator = getWindwardDistanceTraveledComparator(timePoint, cache);
|
||||
Competitor competitorFarthestAhead = StreamSupport
|
||||
.stream(getTrackedRace().getRace().getCompetitors().spliterator(), /* parallel */true).
|
||||
.stream(getCompetitors().spliterator(), /* parallel */true).
|
||||
sorted(oneDesignComparator).findFirst().get();
|
||||
final Distance totalWindwardDistanceTraveled = getWindwardDistanceTraveled(competitorFarthestAhead, timePoint, cache);
|
||||
final TimePoint startOfRace = getTrackedRace().getStartOfRace();
|
||||
@@ -241,27 +314,27 @@ public abstract class AbstractRankingMetric implements RankingMetric {
|
||||
actualRaceDuration = null;
|
||||
} else {
|
||||
actualRaceDuration = startOfRace.until(timePoint);
|
||||
for (Competitor competitor : getTrackedRace().getRace().getCompetitors()) {
|
||||
for (Competitor competitor : getCompetitors()) {
|
||||
final Duration predictedDurationToReachWindwardPositionOfCompetitorFarthestAhead = getPredictedDurationToReachWindwardPositionOf(
|
||||
competitor, competitorFarthestAhead, timePoint, cache);
|
||||
final Duration totalEstimatedDurationSinceRaceStartToCompetitorFarthestAhead = predictedDurationToReachWindwardPositionOfCompetitorFarthestAhead == null ? null
|
||||
: actualRaceDuration.plus(predictedDurationToReachWindwardPositionOfCompetitorFarthestAhead);
|
||||
final Duration correctedEstimatedTimeWhenReachingCompetitorFarthestAhead = totalEstimatedDurationSinceRaceStartToCompetitorFarthestAhead == null ? null
|
||||
: getCorrectedTime(
|
||||
final Duration calculatedEstimatedTimeWhenReachingCompetitorFarthestAhead = totalEstimatedDurationSinceRaceStartToCompetitorFarthestAhead == null ? null
|
||||
: getCalculatedTime(
|
||||
competitor,
|
||||
() -> getTrackedRace().getTrackedLeg(competitorFarthestAhead, timePoint).getLeg(),
|
||||
() -> getTrackedRace().getTrack(competitorFarthestAhead).getEstimatedPosition(
|
||||
timePoint, /* extrapolate */true),
|
||||
totalEstimatedDurationSinceRaceStartToCompetitorFarthestAhead,
|
||||
totalWindwardDistanceTraveled);
|
||||
final Duration correctedTime = getCorrectedTime(competitor,
|
||||
final Duration calculatedTime = getCalculatedTime(competitor,
|
||||
() -> getTrackedRace().getCurrentLeg(competitor, timePoint).getLeg(), () -> getTrackedRace()
|
||||
.getTrack(competitor).getEstimatedPosition(timePoint, /* extrapolated */true),
|
||||
actualRaceDuration, totalWindwardDistanceTraveled);
|
||||
RankingMetric.CompetitorRankingInfo rankingInfo = new CompetitorRankingInfoImpl(timePoint, competitor,
|
||||
getWindwardDistanceTraveled(competitor, timePoint, cache), actualRaceDuration, correctedTime,
|
||||
getWindwardDistanceTraveled(competitor, timePoint, cache), actualRaceDuration, calculatedTime,
|
||||
predictedDurationToReachWindwardPositionOfCompetitorFarthestAhead,
|
||||
correctedEstimatedTimeWhenReachingCompetitorFarthestAhead);
|
||||
calculatedEstimatedTimeWhenReachingCompetitorFarthestAhead);
|
||||
result.put(competitor, rankingInfo);
|
||||
}
|
||||
}
|
||||
@@ -290,7 +363,7 @@ public abstract class AbstractRankingMetric implements RankingMetric {
|
||||
* competitor has sailed. As others may not need it at all, the parameter is declared as a
|
||||
* {@link Supplier} which delays evaluation until it is needed or avoids it altogether.
|
||||
*/
|
||||
protected abstract Duration getCorrectedTime(Competitor who, Supplier<Leg> leg,
|
||||
protected abstract Duration getCalculatedTime(Competitor who, Supplier<Leg> leg,
|
||||
Supplier<Position> estimatedPosition, Duration totalDurationSinceRaceStart,
|
||||
Distance totalWindwardDistanceTraveled);
|
||||
|
||||
@@ -371,14 +444,18 @@ public abstract class AbstractRankingMetric implements RankingMetric {
|
||||
assert getTrackedRace().getRace().getCourse().getIndexOfWaypoint(legWho.getLeg().getFrom()) <= getTrackedRace()
|
||||
.getRace().getCourse().getIndexOfWaypoint(legTo.getLeg().getFrom());
|
||||
final Duration toEndOfLegOrTo = getPredictedDurationToEndOfLegOrTo(timePoint, legWho, legWho.getTrackedLeg().getTrackedLeg(to), cache);
|
||||
final Duration durationForSubsequentLegsToReachAtEqualPerformance;
|
||||
if (legWho.getLeg() == legTo.getLeg()) {
|
||||
durationForSubsequentLegsToReachAtEqualPerformance = Duration.NULL;
|
||||
if (toEndOfLegOrTo == null) {
|
||||
result = null;
|
||||
} else {
|
||||
durationForSubsequentLegsToReachAtEqualPerformance = getDurationToReachAtEqualPerformance(who, to,
|
||||
legWho.getLeg().getTo(), timePoint, cache);
|
||||
final Duration durationForSubsequentLegsToReachAtEqualPerformance;
|
||||
if (legWho.getLeg() == legTo.getLeg()) {
|
||||
durationForSubsequentLegsToReachAtEqualPerformance = Duration.NULL;
|
||||
} else {
|
||||
durationForSubsequentLegsToReachAtEqualPerformance = getDurationToReachAtEqualPerformance(who, to,
|
||||
legWho.getLeg().getTo(), timePoint, cache);
|
||||
}
|
||||
result = toEndOfLegOrTo.plus(durationForSubsequentLegsToReachAtEqualPerformance);
|
||||
}
|
||||
result = toEndOfLegOrTo.plus(durationForSubsequentLegsToReachAtEqualPerformance);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -427,9 +504,6 @@ public abstract class AbstractRankingMetric implements RankingMetric {
|
||||
WindLegTypeAndLegBearingCache cache) {
|
||||
assert legWho.hasStartedLeg(timePoint);
|
||||
assert legTo.hasStartedLeg(timePoint);
|
||||
// FIXME see bug 2907!!!
|
||||
//assert getWindwardDistanceTraveled(legTo.getCompetitor(), legTo.hasFinishedLeg(timePoint)?legTo.getFinishTime():timePoint, cache).compareTo(
|
||||
// getWindwardDistanceTraveled(legWho.getCompetitor(), legWho.hasFinishedLeg(timePoint)?legWho.getFinishTime():timePoint, cache)) >= 0;
|
||||
final Duration toEndOfLegOrTo;
|
||||
if (legTo.hasFinishedLeg(timePoint)) {
|
||||
// calculate actual time it takes who to reach the end of the leg starting at timePoint:
|
||||
@@ -438,6 +512,8 @@ public abstract class AbstractRankingMetric implements RankingMetric {
|
||||
// who's leg finishing time is known; we don't need to extrapolate
|
||||
toEndOfLegOrTo = timePoint.until(whosLegFinishTime);
|
||||
} else {
|
||||
assert getWindwardDistanceTraveled(legTo.getCompetitor(), legTo.hasFinishedLeg(timePoint)?legTo.getFinishTime():timePoint, cache).compareTo(
|
||||
getWindwardDistanceTraveled(legWho.getCompetitor(), legWho.hasFinishedLeg(timePoint)?legWho.getFinishTime():timePoint, cache)) >= 0;
|
||||
// estimate who's leg finishing time by extrapolating with the average VMG (if available) or the current VMG
|
||||
// (if no average VMG can currently be computed, e.g., because the time point is exactly at the leg start)
|
||||
final Position windwardPositionToReachInWhosCurrentLeg =
|
||||
@@ -455,10 +531,10 @@ public abstract class AbstractRankingMetric implements RankingMetric {
|
||||
private Duration getDurationToReach(final Position windwardPositionToReachInWhosCurrentLeg, TimePoint timePoint,
|
||||
final TrackedLegOfCompetitor whosLeg, WindLegTypeAndLegBearingCache cache) {
|
||||
final Duration toEndOfLegOrTo;
|
||||
final Speed currentVMG = whosLeg.getVelocityMadeGood(timePoint, WindPositionMode.EXACT, cache);
|
||||
final Speed averageVMG = whosLeg.getAverageVelocityMadeGood(timePoint, cache);
|
||||
final Speed vmg = Double.isNaN(averageVMG.getKnots()) ? currentVMG : averageVMG;
|
||||
toEndOfLegOrTo = vmg.getDuration(
|
||||
final Speed vmg = averageVMG == null || Double.isNaN(averageVMG.getKnots()) ?
|
||||
/* default to current VMG */ whosLeg.getVelocityMadeGood(timePoint, WindPositionMode.EXACT, cache) : averageVMG;
|
||||
toEndOfLegOrTo = vmg == null || vmg.getKnots() == 0.0 ? null : vmg.getDuration(
|
||||
whosLeg.getTrackedLeg().getWindwardDistance(
|
||||
getTrackedRace().getTrack(whosLeg.getCompetitor()).getEstimatedPosition(timePoint, /* extrapolate */true),
|
||||
windwardPositionToReachInWhosCurrentLeg, timePoint, WindPositionMode.LEG_MIDDLE));
|
||||
@@ -532,16 +608,18 @@ public abstract class AbstractRankingMetric implements RankingMetric {
|
||||
if (trackedLegOfCompetitor.hasStartedLeg(timePoint)) {
|
||||
if (!trackedLegOfCompetitor.hasFinishedLeg(timePoint)) {
|
||||
// partial distance sailed:
|
||||
final Distance windwardDistanceFromLegStart = trackedLeg.getWindwardDistanceFromLegStart(
|
||||
getTrackedRace().getTrack(competitor).getEstimatedPosition(timePoint, /* extrapolate */ true), cache);
|
||||
final Distance legWindwardDistance = trackedLeg.getWindwardDistance(cache);
|
||||
if (legWindwardDistance.compareTo(windwardDistanceFromLegStart) < 0) {
|
||||
d = d.add(legWindwardDistance);
|
||||
} else {
|
||||
// if the competitor is currently at the mark rounding, the windward distance within the leg may
|
||||
// be negative; don't reduce the distance in this case
|
||||
if (windwardDistanceFromLegStart.getMeters() > 0) {
|
||||
d = d.add(windwardDistanceFromLegStart);
|
||||
final Position estimatedPosition = getTrackedRace().getTrack(competitor).getEstimatedPosition(timePoint, /* extrapolate */ true);
|
||||
if (estimatedPosition != null) {
|
||||
final Distance windwardDistanceFromLegStart = trackedLeg.getWindwardDistanceFromLegStart(estimatedPosition, cache);
|
||||
final Distance legWindwardDistance = trackedLeg.getWindwardDistance(cache);
|
||||
if (legWindwardDistance.compareTo(windwardDistanceFromLegStart) < 0) {
|
||||
d = d.add(legWindwardDistance);
|
||||
} else {
|
||||
// if the competitor is currently at the mark rounding, the windward distance within the leg may
|
||||
// be negative; don't reduce the distance in this case
|
||||
if (windwardDistanceFromLegStart.getMeters() > 0) {
|
||||
d = d.add(windwardDistanceFromLegStart);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -555,4 +633,61 @@ public abstract class AbstractRankingMetric implements RankingMetric {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>null</code> if no competitor has started the leg yet; the first competitor to finish the leg if any
|
||||
* has already finished the leg at <code>timePoint</code>; or the competitor with the greatest windward
|
||||
* distance traveled in the leg at <code>timePoint</code> otherwise
|
||||
*/
|
||||
protected Competitor getCompetitorFarthestAheadInLeg(TrackedLeg trackedLeg, TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
|
||||
Competitor firstAroundMark = getFirstLegFinisherBefore(trackedLeg, timePoint);
|
||||
final Competitor result;
|
||||
if (firstAroundMark != null) {
|
||||
result = firstAroundMark;
|
||||
} else {
|
||||
Iterable<MarkPassing> markPassingsForLegStart = getTrackedRace().getMarkPassingsInOrder(trackedLeg.getLeg().getFrom());
|
||||
Distance maxWindwardDistanceTraveled = new MeterDistance(Double.MIN_VALUE);
|
||||
Competitor competitorFarthestAlong = null;
|
||||
getTrackedRace().lockForRead(markPassingsForLegStart);
|
||||
try {
|
||||
for (MarkPassing mp : markPassingsForLegStart) {
|
||||
if (mp.getTimePoint().after(timePoint)) {
|
||||
break;
|
||||
}
|
||||
final Distance windwardDistanceTraveled = getWindwardDistanceTraveled(mp.getCompetitor(), mp.getWaypoint(),
|
||||
timePoint, cache);
|
||||
if (windwardDistanceTraveled.compareTo(maxWindwardDistanceTraveled) > 0) {
|
||||
maxWindwardDistanceTraveled = windwardDistanceTraveled;
|
||||
competitorFarthestAlong = mp.getCompetitor();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
getTrackedRace().unlockAfterRead(markPassingsForLegStart);
|
||||
}
|
||||
result = competitorFarthestAlong;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the first competitor finishing the leg identified by <code>trackedLeg</code> at or before <code>timePoint</code>. If
|
||||
* no such competitor exists, <code>null</code> is returned.
|
||||
*/
|
||||
private Competitor getFirstLegFinisherBefore(TrackedLeg trackedLeg, TimePoint timePoint) {
|
||||
Iterable<MarkPassing> markPassingsForLegEnd = getTrackedRace().getMarkPassingsInOrder(trackedLeg.getLeg().getTo());
|
||||
Competitor firstAroundMark = null;
|
||||
getTrackedRace().lockForRead(markPassingsForLegEnd);
|
||||
try {
|
||||
final Iterator<MarkPassing> i = markPassingsForLegEnd.iterator();
|
||||
if (i.hasNext()) {
|
||||
MarkPassing markPassing = i.next();
|
||||
if (!markPassing.getTimePoint().after(timePoint)) {
|
||||
firstAroundMark = markPassing.getCompetitor();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
getTrackedRace().unlockAfterRead(markPassingsForLegEnd);
|
||||
}
|
||||
return firstAroundMark;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -51,7 +51,7 @@ public class ORCPerformanceCurveRankingMetric extends AbstractRankingMetric {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Duration getCorrectedTime(Competitor who, Supplier<Leg> leg, Supplier<Position> estimatedPosition,
|
||||
protected Duration getCalculatedTime(Competitor who, Supplier<Leg> leg, Supplier<Position> estimatedPosition,
|
||||
Duration totalDurationSinceRaceStart, Distance totalWindwardDistanceTraveled) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
@@ -66,7 +66,7 @@ public class ORCPerformanceCurveRankingMetric extends AbstractRankingMetric {
|
||||
|
||||
@Override
|
||||
public Duration getLegGapToLegLeaderInOwnTime(TrackedLegOfCompetitor trackedLegOfCompetitor, TimePoint timePoint,
|
||||
WindLegTypeAndLegBearingCache cache) {
|
||||
RankingInfo rankingInfo, WindLegTypeAndLegBearingCache cache) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
+4
-9
@@ -62,27 +62,22 @@ public class OneDesignRankingMetric extends AbstractRankingMetric {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Duration getCorrectedTime(Competitor who, Supplier<Leg> leg, Supplier<Position> estimatedPosition,
|
||||
protected Duration getCalculatedTime(Competitor who, Supplier<Leg> leg, Supplier<Position> estimatedPosition,
|
||||
Duration totalDurationSinceRaceStart, Distance totalWindwardDistanceTraveled) {
|
||||
return totalDurationSinceRaceStart;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getLegGapToLegLeaderInOwnTime(TrackedLegOfCompetitor trackedLegOfCompetitor, TimePoint timePoint,
|
||||
WindLegTypeAndLegBearingCache cache) {
|
||||
return trackedLegOfCompetitor.getGapToLeader(timePoint, WindPositionMode.LEG_MIDDLE, cache);
|
||||
final RankingInfo rankingInfo, WindLegTypeAndLegBearingCache cache) {
|
||||
return trackedLegOfCompetitor.getGapToLeader(timePoint, WindPositionMode.LEG_MIDDLE, rankingInfo, cache);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RankingInfo getRankingInfo(final TimePoint timePoint, final WindLegTypeAndLegBearingCache cache) {
|
||||
return new RankingInfo() {
|
||||
return new AbstractRankingInfo(timePoint) {
|
||||
private static final long serialVersionUID = 25689357311324825L;
|
||||
|
||||
@Override
|
||||
public TimePoint getTimePoint() {
|
||||
return timePoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Function<Competitor, CompetitorRankingInfo> getCompetitorRankingInfo() {
|
||||
return competitor -> getCompetitorRankingInfo(competitor);
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.Comparator;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Leg;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.leaderboard.caching.LeaderboardDTOCalculationReuseCache;
|
||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||
@@ -112,6 +113,20 @@ public interface RankingMetric extends Serializable {
|
||||
* position at {@link #timePoint}.
|
||||
*/
|
||||
Competitor getLeaderByCorrectedEstimatedTimeToCompetitorFarthestAhead();
|
||||
|
||||
/**
|
||||
* Similar to {@link #getLeaderByCorrectedEstimatedTimeToCompetitorFarthestAhead()}, but relative to a
|
||||
* {@link Leg}. This will not consider any progress or position beyond the finishing of that <code>leg</code>.
|
||||
* Instead, for those competitors who have already finished the leg, their
|
||||
* {@link TrackedLegOfCompetitor#getFinishTime() finishing time} for the leg is used, and the distance traveled
|
||||
* is normalized to the {@link TrackedLeg#getWindwardDistance() windward distance of the leg} at the
|
||||
* {@link TrackedLeg#getReferenceTimePoint() reference time point}.
|
||||
*/
|
||||
Competitor getLeaderInLegByCalculatedTime(Leg leg, WindLegTypeAndLegBearingCache cache);
|
||||
|
||||
Competitor getCompetitorFarthestAheadInLeg(Leg leg, TimePoint timePoint, WindLegTypeAndLegBearingCache cache);
|
||||
|
||||
Duration getActualTimeFromRaceStartToReachFarthestAheadInLeg(Competitor competitor, Leg leg, WindLegTypeAndLegBearingCache cache);
|
||||
}
|
||||
|
||||
public interface LegRankingInfo extends Timed, Serializable {
|
||||
@@ -178,7 +193,7 @@ public interface RankingMetric extends Serializable {
|
||||
* @param competitor
|
||||
* the competitor for which to tell the gap to the leader in <code>competitor</code>'s own time
|
||||
*
|
||||
* @see #getLegGapToLegLeaderInOwnTime(TrackedLegOfCompetitor, TimePoint, WindLegTypeAndLegBearingCache)
|
||||
* @see #getLegGapToLegLeaderInOwnTime(TrackedLegOfCompetitor, TimePoint, com.sap.sailing.domain.ranking.RankingMetric.CompetitorRankingInfo.RankingInfo, WindLegTypeAndLegBearingCache)
|
||||
*/
|
||||
default Duration getGapToLeaderInOwnTime(RankingInfo rankingInfo, Competitor competitor) {
|
||||
return getGapToLeaderInOwnTime(rankingInfo, competitor, new LeaderboardDTOCalculationReuseCache(rankingInfo.getTimePoint()));
|
||||
@@ -205,6 +220,10 @@ public interface RankingMetric extends Serializable {
|
||||
* handicap ranking is in effect) of the leg that the <code>competitor</code> is in at <code>timePoint</code> (or
|
||||
* the last leg if <code>timePoint</code> is after <code>competitor</code> has finished the race). Returns
|
||||
* <code>null</code> if <code>timePoint</code> is before <code>competitor</code> has started.
|
||||
*
|
||||
* @param rankingInfo
|
||||
* tells about leader (by calculated time) and boat farthest ahead
|
||||
*/
|
||||
Duration getLegGapToLegLeaderInOwnTime(TrackedLegOfCompetitor trackedLegOfCompetitor, TimePoint timePoint, WindLegTypeAndLegBearingCache cache);
|
||||
Duration getLegGapToLegLeaderInOwnTime(TrackedLegOfCompetitor trackedLegOfCompetitor, TimePoint timePoint,
|
||||
RankingInfo rankingInfo, WindLegTypeAndLegBearingCache cache);
|
||||
}
|
||||
+45
-106
@@ -2,7 +2,6 @@ package com.sap.sailing.domain.ranking;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
@@ -14,7 +13,6 @@ import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.Mile;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||
@@ -106,8 +104,10 @@ public class TimeOnTimeAndDistanceRankingMetric extends AbstractRankingMetric {
|
||||
// competitors that have not yet started the leg will get a duration based on Long.MAX_VALUE
|
||||
final Map<Competitor, Duration> correctedTimesToReachFastestBoatsPositionAtTimePointOrEndOfLegMeasuredFromStartOfRace = new HashMap<>();
|
||||
final Competitor fastestCompetitorInLeg = getCompetitorFarthestAheadInLeg(trackedLeg, timePoint, cache);
|
||||
final boolean fastestCompetitorHasStartedLeg;
|
||||
if (fastestCompetitorInLeg != null) {
|
||||
final TrackedLegOfCompetitor trackedLegOfFastestCompetitorInLeg = trackedLeg.getTrackedLeg(fastestCompetitorInLeg);
|
||||
fastestCompetitorHasStartedLeg = trackedLegOfFastestCompetitorInLeg.hasStartedLeg(timePoint);
|
||||
final Distance totalWindwardDistanceLegLeaderTraveledUpToTimePointOrLegEnd;
|
||||
final TimePoint startOfRace = getTrackedRace().getStartOfRace();
|
||||
final Position positionOfFastestBoatInLegAtTimePointOrLegEnd;
|
||||
@@ -137,14 +137,15 @@ public class TimeOnTimeAndDistanceRankingMetric extends AbstractRankingMetric {
|
||||
totalWindwardDistanceLegLeaderTraveledUpToTimePointOrLegEnd = getWindwardDistanceTraveled(
|
||||
fastestCompetitorInLeg, timePoint, cache);
|
||||
}
|
||||
for (Competitor competitor : getTrackedRace().getRace().getCompetitors()) {
|
||||
for (Competitor competitor : getCompetitors()) {
|
||||
final TrackedLegOfCompetitor competitorLeg = trackedLeg.getTrackedLeg(competitor);
|
||||
final Duration correctedTime;
|
||||
if (competitorLeg != null && competitorLeg.hasStartedLeg(timePoint)) {
|
||||
final Duration timeToReachFastest = getPredictedDurationToEndOfLegOrTo(timePoint,
|
||||
competitorLeg, trackedLegOfFastestCompetitorInLeg, cache);
|
||||
final Duration totalDurationSinceRaceStart = startOfRace.until(timePoint).plus(timeToReachFastest);
|
||||
correctedTime = getCorrectedTime(competitor, () -> trackedLeg.getLeg(),
|
||||
final Duration totalDurationSinceRaceStart = timeToReachFastest == null ? null :
|
||||
startOfRace.until(timePoint).plus(timeToReachFastest);
|
||||
correctedTime = getCalculatedTime(competitor, () -> trackedLeg.getLeg(),
|
||||
() -> positionOfFastestBoatInLegAtTimePointOrLegEnd, totalDurationSinceRaceStart,
|
||||
totalWindwardDistanceLegLeaderTraveledUpToTimePointOrLegEnd);
|
||||
} else { // competitor hasn't started the leg yet; they all get MAX_VALUE as the corrected duration,
|
||||
@@ -154,74 +155,22 @@ public class TimeOnTimeAndDistanceRankingMetric extends AbstractRankingMetric {
|
||||
}
|
||||
correctedTimesToReachFastestBoatsPositionAtTimePointOrEndOfLegMeasuredFromStartOfRace.put(competitor, correctedTime);
|
||||
}
|
||||
}
|
||||
return (tloc1, tloc2) -> fastestCompetitorInLeg==null ? 0 :
|
||||
correctedTimesToReachFastestBoatsPositionAtTimePointOrEndOfLegMeasuredFromStartOfRace.get(tloc1.getCompetitor()).
|
||||
compareTo(correctedTimesToReachFastestBoatsPositionAtTimePointOrEndOfLegMeasuredFromStartOfRace.get(tloc2.getCompetitor()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>null</code> if no competitor has started the leg yet; the first competitor to finish the leg if any
|
||||
* has already finished the leg at <code>timePoint</code>; or the competitor with the greatest windward
|
||||
* distance traveled in the leg at <code>timePoint</code> otherwise
|
||||
*/
|
||||
private Competitor getCompetitorFarthestAheadInLeg(TrackedLeg trackedLeg, TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
|
||||
Competitor firstAroundMark = getFirstLegFinisherBefore(trackedLeg, timePoint);
|
||||
final Competitor result;
|
||||
if (firstAroundMark != null) {
|
||||
result = firstAroundMark;
|
||||
} else {
|
||||
Iterable<MarkPassing> markPassingsForLegStart = getTrackedRace().getMarkPassingsInOrder(trackedLeg.getLeg().getFrom());
|
||||
Distance maxWindwardDistanceTraveled = new MeterDistance(Double.MIN_VALUE);
|
||||
Competitor competitorFarthestAlong = null;
|
||||
getTrackedRace().lockForRead(markPassingsForLegStart);
|
||||
try {
|
||||
for (MarkPassing mp : markPassingsForLegStart) {
|
||||
if (mp.getTimePoint().after(timePoint)) {
|
||||
break;
|
||||
}
|
||||
final Distance windwardDistanceTraveled = getWindwardDistanceTraveled(mp.getCompetitor(), mp.getWaypoint(),
|
||||
timePoint, cache);
|
||||
if (windwardDistanceTraveled.compareTo(maxWindwardDistanceTraveled) > 0) {
|
||||
maxWindwardDistanceTraveled = windwardDistanceTraveled;
|
||||
competitorFarthestAlong = mp.getCompetitor();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
getTrackedRace().unlockAfterRead(markPassingsForLegStart);
|
||||
}
|
||||
result = competitorFarthestAlong;
|
||||
fastestCompetitorHasStartedLeg = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the first competitor finishing the leg identified by <code>trackedLeg</code> at or before <code>timePoint</code>. If
|
||||
* no such competitor exists, <code>null</code> is returned.
|
||||
*/
|
||||
private Competitor getFirstLegFinisherBefore(TrackedLeg trackedLeg, TimePoint timePoint) {
|
||||
Iterable<MarkPassing> markPassingsForLegEnd = getTrackedRace().getMarkPassingsInOrder(trackedLeg.getLeg().getTo());
|
||||
Competitor firstAroundMark = null;
|
||||
getTrackedRace().lockForRead(markPassingsForLegEnd);
|
||||
try {
|
||||
final Iterator<MarkPassing> i = markPassingsForLegEnd.iterator();
|
||||
if (i.hasNext()) {
|
||||
MarkPassing markPassing = i.next();
|
||||
if (!markPassing.getTimePoint().after(timePoint)) {
|
||||
firstAroundMark = markPassing.getCompetitor();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
getTrackedRace().unlockAfterRead(markPassingsForLegEnd);
|
||||
}
|
||||
return firstAroundMark;
|
||||
final Comparator<Duration> durationComparatorNullsLast = Comparator.nullsLast(Comparator.naturalOrder());
|
||||
return (tloc1, tloc2) -> fastestCompetitorHasStartedLeg ?
|
||||
durationComparatorNullsLast.compare(
|
||||
correctedTimesToReachFastestBoatsPositionAtTimePointOrEndOfLegMeasuredFromStartOfRace.get(tloc1.getCompetitor()),
|
||||
correctedTimesToReachFastestBoatsPositionAtTimePointOrEndOfLegMeasuredFromStartOfRace.get(tloc2.getCompetitor()))
|
||||
: 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getCorrectedTime(Competitor competitor, TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
|
||||
final Duration timeActuallySpent = getActualTimeSinceStartOfRace(competitor, timePoint);
|
||||
final Distance windwardDistanceSailed = getWindwardDistanceTraveled(competitor, timePoint, cache);
|
||||
return getCorrectedTime(competitor, ()->getTrackedRace().getCurrentLeg(competitor, timePoint).getLeg(),
|
||||
return getCalculatedTime(competitor, ()->getTrackedRace().getCurrentLeg(competitor, timePoint).getLeg(),
|
||||
()->getTrackedRace().getTrack(competitor).getEstimatedPosition(timePoint, /* extrapolate */true),
|
||||
timeActuallySpent, windwardDistanceSailed);
|
||||
}
|
||||
@@ -235,7 +184,7 @@ public class TimeOnTimeAndDistanceRankingMetric extends AbstractRankingMetric {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Duration getCorrectedTime(Competitor who, Supplier<Leg> leg, Supplier<Position> estimatedPosition,
|
||||
protected Duration getCalculatedTime(Competitor who, Supplier<Leg> leg, Supplier<Position> estimatedPosition,
|
||||
Duration totalDurationSinceRaceStart, Distance totalWindwardDistanceTraveled) {
|
||||
final Duration timeOnDistanceFactorInSecondsPerNauticalMile = getTimeOnDistanceFactorInSecondsPerNauticalMile(who);
|
||||
return totalDurationSinceRaceStart == null ? null :
|
||||
@@ -311,13 +260,19 @@ public class TimeOnTimeAndDistanceRankingMetric extends AbstractRankingMetric {
|
||||
*/
|
||||
@Override
|
||||
public Duration getGapToLeaderInOwnTime(RankingMetric.RankingInfo rankingInfo, Competitor competitor, WindLegTypeAndLegBearingCache cache) {
|
||||
final Duration result;
|
||||
// actual times and common distance:
|
||||
final Competitor leaderByCorrectedEstimatedTimeToCompetitorFarthestAhead = rankingInfo.getLeaderByCorrectedEstimatedTimeToCompetitorFarthestAhead();
|
||||
final Duration t_k = rankingInfo.getCompetitorRankingInfo().apply(leaderByCorrectedEstimatedTimeToCompetitorFarthestAhead).
|
||||
getEstimatedActualDurationFromRaceStartToCompetitorFarthestAhead();
|
||||
final Duration t_i = rankingInfo.getCompetitorRankingInfo().apply(competitor).getEstimatedActualDurationFromRaceStartToCompetitorFarthestAhead();
|
||||
final Distance d = rankingInfo.getCompetitorRankingInfo().apply(rankingInfo.getCompetitorFarthestAhead()).getWindwardDistanceSailed();
|
||||
return getGapToCompetitorInOwnTime(competitor, leaderByCorrectedEstimatedTimeToCompetitorFarthestAhead, t_i, t_k, d);
|
||||
if (leaderByCorrectedEstimatedTimeToCompetitorFarthestAhead == null) {
|
||||
result = null;
|
||||
} else {
|
||||
final Duration t_k = rankingInfo.getCompetitorRankingInfo().apply(leaderByCorrectedEstimatedTimeToCompetitorFarthestAhead).
|
||||
getEstimatedActualDurationFromRaceStartToCompetitorFarthestAhead();
|
||||
final Duration t_i = rankingInfo.getCompetitorRankingInfo().apply(competitor).getEstimatedActualDurationFromRaceStartToCompetitorFarthestAhead();
|
||||
final Distance d = rankingInfo.getCompetitorRankingInfo().apply(rankingInfo.getCompetitorFarthestAhead()).getWindwardDistanceSailed();
|
||||
result = getGapToCompetitorInOwnTime(competitor, leaderByCorrectedEstimatedTimeToCompetitorFarthestAhead, t_i, t_k, d);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -376,47 +331,31 @@ public class TimeOnTimeAndDistanceRankingMetric extends AbstractRankingMetric {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getLegGapToLegLeaderInOwnTime(TrackedLegOfCompetitor trackedLegOfCompetitor, TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
|
||||
public Duration getLegGapToLegLeaderInOwnTime(TrackedLegOfCompetitor trackedLegOfCompetitor, TimePoint timePoint,
|
||||
RankingInfo rankingInfo, WindLegTypeAndLegBearingCache cache) {
|
||||
final Duration result;
|
||||
final Leg leg = trackedLegOfCompetitor.getLeg();
|
||||
if (getTrackedRace().getStartOfRace() == null || !trackedLegOfCompetitor.hasStartedLeg(timePoint)) {
|
||||
result = null;
|
||||
} else {
|
||||
// FIXME need to calculate the ranking stuff only once for requests for all competitors to this method, or else we'll end up with n^2 effort
|
||||
final Duration raceDurationAtTimePoint = getTrackedRace().getStartOfRace().until(timePoint);
|
||||
final Competitor farthestAheadOrEarliestLegFinisher = getCompetitorFarthestAheadInLeg(trackedLegOfCompetitor.getTrackedLeg(), timePoint, cache);
|
||||
final TrackedLegOfCompetitor tlocOfFarthestAhead = trackedLegOfCompetitor.getTrackedLeg().getTrackedLeg(farthestAheadOrEarliestLegFinisher);
|
||||
final boolean farthestAheadAlreadyFinishedLeg = tlocOfFarthestAhead.hasFinishedLeg(timePoint);
|
||||
final Distance windwardDistanceFarthestTraveledUntilFinishingLeg = getWindwardDistanceTraveled(farthestAheadOrEarliestLegFinisher,
|
||||
farthestAheadAlreadyFinishedLeg ? tlocOfFarthestAhead.getFinishTime() : timePoint, cache);
|
||||
final Map<Competitor, Duration> correctedTimeToReachFarthestAheadInLeg = new HashMap<>();
|
||||
final Map<Competitor, Duration> actualTimeFromRaceStartToReachFarthestAheadInLeg = new HashMap<>();
|
||||
// Consider all competitors, regardless of whether they have started the leg or not; a competitor in a previous
|
||||
// leg may well be the race leader. However, if a competitor has finished the leg already, use the finishing time
|
||||
// point for that competitor.
|
||||
for (Competitor c : getTrackedRace().getRace().getCompetitors()) {
|
||||
final TrackedLegOfCompetitor tloc = trackedLegOfCompetitor.getTrackedLeg().getTrackedLeg(c);
|
||||
if (tloc.hasStartedLeg(timePoint)) {
|
||||
final Duration predictedDurationFromTimePointToReachFarthestAheadInLeg = getPredictedDurationToReachWindwardPositionOf(tloc, tlocOfFarthestAhead, timePoint, cache);
|
||||
final Duration cDurationFromRaceStartToReachFarthestInLeg = raceDurationAtTimePoint.plus(predictedDurationFromTimePointToReachFarthestAheadInLeg);
|
||||
actualTimeFromRaceStartToReachFarthestAheadInLeg.put(c, cDurationFromRaceStartToReachFarthestInLeg);
|
||||
final Duration correctedTimeWhenReachingFarthestAheadInLeg = getCorrectedTime(c, ()->tloc.getTrackedLeg().getLeg(),
|
||||
()->farthestAheadAlreadyFinishedLeg?getTrackedRace().getApproximatePosition(tlocOfFarthestAhead.getTrackedLeg().getLeg().getTo(), tlocOfFarthestAhead.getFinishTime()):
|
||||
getTrackedRace().getTrack(farthestAheadOrEarliestLegFinisher).getEstimatedPosition(timePoint, /* extrapolate */ true),
|
||||
cDurationFromRaceStartToReachFarthestInLeg, windwardDistanceFarthestTraveledUntilFinishingLeg);
|
||||
correctedTimeToReachFarthestAheadInLeg.put(c, correctedTimeWhenReachingFarthestAheadInLeg);
|
||||
} else {
|
||||
actualTimeFromRaceStartToReachFarthestAheadInLeg.put(c, null);
|
||||
correctedTimeToReachFarthestAheadInLeg.put(c, null);
|
||||
}
|
||||
if (farthestAheadOrEarliestLegFinisher == null) {
|
||||
result = null;
|
||||
} else {
|
||||
final TrackedLegOfCompetitor tlocOfFarthestAhead = trackedLegOfCompetitor.getTrackedLeg().getTrackedLeg(farthestAheadOrEarliestLegFinisher);
|
||||
final boolean farthestAheadAlreadyFinishedLeg = tlocOfFarthestAhead.hasFinishedLeg(timePoint);
|
||||
final Distance windwardDistanceFarthestTraveledUntilFinishingLeg = getWindwardDistanceTraveled(farthestAheadOrEarliestLegFinisher,
|
||||
farthestAheadAlreadyFinishedLeg ? tlocOfFarthestAhead.getFinishTime() : timePoint, cache);
|
||||
// Consider all competitors, regardless of whether they have started the leg or not; a competitor in a previous
|
||||
// leg may well be the race leader. However, if a competitor has finished the leg already, use the finishing time
|
||||
// point for that competitor.
|
||||
// leader in the leg is now the competitor with the least corrected time to reach the competitor farthest ahead in the leg
|
||||
final Competitor legLeader = rankingInfo.getLeaderInLegByCalculatedTime(trackedLegOfCompetitor.getTrackedLeg().getLeg(), cache);
|
||||
result = getGapToCompetitorInOwnTime(trackedLegOfCompetitor.getCompetitor(), legLeader,
|
||||
rankingInfo.getActualTimeFromRaceStartToReachFarthestAheadInLeg(trackedLegOfCompetitor.getCompetitor(), leg, cache),
|
||||
rankingInfo.getActualTimeFromRaceStartToReachFarthestAheadInLeg(legLeader, leg, cache),
|
||||
windwardDistanceFarthestTraveledUntilFinishingLeg);
|
||||
}
|
||||
// leader in the leg is now the competitor with the least corrected time to reach the competitor farthest ahead in the leg
|
||||
Comparator<Duration> durationComparatorNUllsLast = Comparator.nullsLast(Comparator.naturalOrder());
|
||||
final Competitor leader = correctedTimeToReachFarthestAheadInLeg.entrySet().stream()
|
||||
.sorted((e1, e2) -> durationComparatorNUllsLast.compare(e1.getValue(), e2.getValue())).findFirst().get().getKey();
|
||||
result = getGapToCompetitorInOwnTime(trackedLegOfCompetitor.getCompetitor(), leader,
|
||||
actualTimeFromRaceStartToReachFarthestAheadInLeg.get(trackedLegOfCompetitor.getCompetitor()),
|
||||
actualTimeFromRaceStartToReachFarthestAheadInLeg.get(leader),
|
||||
windwardDistanceFarthestTraveledUntilFinishingLeg);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
+12
-2
@@ -64,7 +64,12 @@ public class BaseRegattaLikeImpl implements IsRegattaLike {
|
||||
final Double timeOnTimeFactorFromRegattaLog = getTimeOnTimeFactorFromRegattaLog(competitor);
|
||||
final Double result;
|
||||
if (timeOnTimeFactorFromRegattaLog == null) {
|
||||
result = competitor.getTimeOnTimeFactor();
|
||||
final Double competitorTimeOnTimeFactorDefault = competitor.getTimeOnTimeFactor();
|
||||
if (competitorTimeOnTimeFactorDefault == null) {
|
||||
result = 1.0;
|
||||
} else {
|
||||
result = competitorTimeOnTimeFactorDefault;
|
||||
}
|
||||
} else {
|
||||
result = timeOnTimeFactorFromRegattaLog;
|
||||
}
|
||||
@@ -76,7 +81,12 @@ public class BaseRegattaLikeImpl implements IsRegattaLike {
|
||||
final Duration timeOnDistanceAllowancePerNauticalMileFromRegattaLog = getTimeOnDistanceAllowancePerNauticalMileFromRegattaLog(competitor);
|
||||
final Duration result;
|
||||
if (timeOnDistanceAllowancePerNauticalMileFromRegattaLog == null) {
|
||||
result = competitor.getTimeOnDistanceAllowancePerNauticalMile();
|
||||
final Duration competitorAllowanceDefault = competitor.getTimeOnDistanceAllowancePerNauticalMile();
|
||||
if (competitorAllowanceDefault == null) {
|
||||
result = Duration.NULL;
|
||||
} else {
|
||||
result = competitorAllowanceDefault;
|
||||
}
|
||||
} else {
|
||||
result = timeOnDistanceAllowancePerNauticalMileFromRegattaLog;
|
||||
}
|
||||
|
||||
+18
-10
@@ -13,6 +13,7 @@ import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.Wind;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
@@ -151,27 +152,31 @@ public interface TrackedLegOfCompetitor extends Serializable {
|
||||
/**
|
||||
* Computes the gap in seconds to the leader / winner of this leg. Returns <code>null</code> in case this leg's
|
||||
* competitor hasn't started the leg yet.
|
||||
* @param rankingInfo TODO
|
||||
*/
|
||||
Duration getGapToLeader(TimePoint timePoint, WindPositionMode windPositionMode);
|
||||
Duration getGapToLeader(TimePoint timePoint, RankingInfo rankingInfo, WindPositionMode windPositionMode);
|
||||
|
||||
/**
|
||||
* Same as {@link #getGapToLeader(TimePoint, WindPositionMode)}, only that a cache for wind and leg type data is used.
|
||||
* Same as {@link #getGapToLeader(TimePoint, RankingInfo, WindPositionMode)}, only that a cache for wind and leg type data is used.
|
||||
* @param rankingInfo TODO
|
||||
*/
|
||||
Duration getGapToLeader(TimePoint timePoint, WindPositionMode windPositionMode, WindLegTypeAndLegBearingCache cache);
|
||||
Duration getGapToLeader(TimePoint timePoint, WindPositionMode windPositionMode, RankingInfo rankingInfo, WindLegTypeAndLegBearingCache cache);
|
||||
|
||||
/**
|
||||
* If a caller already went through the effort of computing the leg's leader at <code>timePoint</code>, it
|
||||
* can share this knowledge to speed up computation as compared to {@link #getGapToLeader(TimePoint, WindPositionMode)}.
|
||||
* can share this knowledge to speed up computation as compared to {@link #getGapToLeader(TimePoint, RankingInfo, WindPositionMode)}.
|
||||
* @param rankingInfo TODO
|
||||
*/
|
||||
Duration getGapToLeader(TimePoint timePoint, Competitor leaderInLegAtTimePoint, WindPositionMode windPositionMode) throws NoWindException;
|
||||
Duration getGapToLeader(TimePoint timePoint, Competitor leaderInLegAtTimePoint, RankingInfo rankingInfo, WindPositionMode windPositionMode) throws NoWindException;
|
||||
|
||||
/**
|
||||
* Same as {@link #getGapToLeader(TimePoint, Competitor, WindPositionMode)}, only that an additional cache is used
|
||||
* Same as {@link #getGapToLeader(TimePoint, Competitor, RankingInfo, WindPositionMode)}, only that an additional cache is used
|
||||
* to avoid redundant evaluations of leg types and wind field information across various calculations that
|
||||
* all can use the same basic information.
|
||||
* @param rankingInfo TODO
|
||||
*/
|
||||
Duration getGapToLeader(TimePoint timePoint, Competitor leaderInLegAtTimePoint,
|
||||
WindPositionMode windPositionMode, WindLegTypeAndLegBearingCache cache);
|
||||
WindPositionMode windPositionMode, RankingInfo rankingInfo, WindLegTypeAndLegBearingCache cache);
|
||||
|
||||
boolean hasStartedLeg(TimePoint timePoint);
|
||||
|
||||
@@ -228,14 +233,17 @@ public interface TrackedLegOfCompetitor extends Serializable {
|
||||
* distance between this leg's competitor and the leader is returned. Note that this can lead to a situation where
|
||||
* the distance to leader is unrelated to the {@link #getWindwardDistanceToGo(TimePoint, WindPositionMode) distance to go} which is
|
||||
* used for ranking.
|
||||
*
|
||||
* @param rankingInfo materialized ranking information that is pre-calculated to avoid expensive redundant work
|
||||
*/
|
||||
Distance getWindwardDistanceToOverallLeader(TimePoint timePoint, WindPositionMode windPositionMode);
|
||||
Distance getWindwardDistanceToCompetitorFarthestAhead(TimePoint timePoint, WindPositionMode windPositionMode, RankingInfo rankingInfo);
|
||||
|
||||
/**
|
||||
* Same as {@link #getWindwardDistanceToOverallLeader(TimePoint, WindPositionMode)}, only that a cache for leg type
|
||||
* Same as {@link #getWindwardDistanceToCompetitorFarthestAhead(TimePoint, WindPositionMode, RankingInfo)}, only that a cache for leg type
|
||||
* calculation is passed.
|
||||
* @param rankingInfo TODO
|
||||
*/
|
||||
Distance getWindwardDistanceToOverallLeader(TimePoint timePoint, WindPositionMode windPositionMode, WindLegTypeAndLegBearingCache cache);
|
||||
Distance getWindwardDistanceToCompetitorFarthestAhead(TimePoint timePoint, WindPositionMode windPositionMode, RankingInfo rankingInfo, WindLegTypeAndLegBearingCache cache);
|
||||
|
||||
/**
|
||||
* Computes the average absolute cross track error for this leg. The cross track error for each fix is taken to be a
|
||||
|
||||
@@ -41,6 +41,7 @@ import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||
import com.sap.sailing.domain.polars.PolarDataService;
|
||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
@@ -515,17 +516,21 @@ public interface TrackedRace extends Serializable {
|
||||
Distance getDistanceTraveledIncludingGateStart(Competitor competitor, TimePoint timePoint);
|
||||
|
||||
/**
|
||||
* See {@link TrackedLegOfCompetitor#getWindwardDistanceToOverallLeader(TimePoint, WindPositionMode)}
|
||||
* See {@link TrackedLegOfCompetitor#getWindwardDistanceToCompetitorFarthestAhead(TimePoint, WindPositionMode, RankingInfo)}
|
||||
*/
|
||||
Distance getWindwardDistanceToOverallLeader(Competitor competitor, TimePoint timePoint, WindPositionMode windPositionMode);
|
||||
Distance getWindwardDistanceToCompetitorFarthestAhead(Competitor competitor, TimePoint timePoint, WindPositionMode windPositionMode);
|
||||
|
||||
/**
|
||||
* Same as {@link #getWindwardDistanceToOverallLeader(Competitor, TimePoint, WindPositionMode)}, only with an additional
|
||||
* cache to speed up wind and leg type and leg bearing calculations in case of multiple similar look-ups for the same
|
||||
* time point.
|
||||
* Same as {@link #getWindwardDistanceToCompetitorFarthestAhead(Competitor, TimePoint, WindPositionMode)}, only with an
|
||||
* additional cache to speed up wind and leg type and leg bearing calculations in case of multiple similar look-ups
|
||||
* for the same time point.
|
||||
*
|
||||
* @param rankingInfo
|
||||
* materialized ranking information that is expensive to calculate, avoiding redundant calculations
|
||||
*/
|
||||
Distance getWindwardDistanceToOverallLeader(Competitor competitor, TimePoint timePoint, WindPositionMode windPositionMode, WindLegTypeAndLegBearingCache cache);
|
||||
|
||||
Distance getWindwardDistanceToCompetitorFarthestAhead(Competitor competitor, TimePoint timePoint,
|
||||
WindPositionMode windPositionMode, RankingInfo rankingInfo, WindLegTypeAndLegBearingCache cache);
|
||||
|
||||
/**
|
||||
* Calls {@link #getWindWithConfidence(Position, TimePoint, Iterable)} and excludes those wind sources listed in
|
||||
* {@link #getWindSourcesToExclude}.
|
||||
@@ -818,13 +823,4 @@ public interface TrackedRace extends Serializable {
|
||||
Duration getEstimatedTimeToComplete(TimePoint timepoint) throws NotEnoughDataHasBeenAddedException, NoWindException;
|
||||
|
||||
void setPolarDataService(PolarDataService polarDataService);
|
||||
|
||||
/**
|
||||
* With a handicap system in place, computes the windward distance to the race's overall leader based on the correction factors
|
||||
* introduced by the handicap's ranking and scoring system. For one-design classes, this method returns the same result as
|
||||
* {@link #getWindwardDistanceToOverallLeader(Competitor, TimePoint, WindPositionMode)}.
|
||||
*/
|
||||
Distance getCorrectedWindwardDistanceToOverallLeader(Competitor competitor, TimePoint timePoint,
|
||||
WindPositionMode windPositionMode) throws NoWindException;
|
||||
|
||||
}
|
||||
+24
-1
@@ -29,8 +29,31 @@ import com.sap.sse.common.TimePoint;
|
||||
public interface TrackedRegatta extends Serializable {
|
||||
Regatta getRegatta();
|
||||
|
||||
/**
|
||||
* Callers must {@link #lockTrackedRacesForRead() acquire the read lock} before calling this method and hold on to the lock
|
||||
* while iterating over the data structure returned. Example:
|
||||
* <pre>
|
||||
* trackedRegatta.lockTrackedRacesForRead();
|
||||
* try {
|
||||
* for (TrackedRace trackedRace : trackedRegatta.getTrackedRaces()) {
|
||||
* // do something
|
||||
* }
|
||||
* } finally {
|
||||
* trackedRegatta.unlockTrackedRacesAfterRead();
|
||||
* }
|
||||
* </pre>
|
||||
* The method will throw an {@link IllegalArgumentException} if the caller fails to do so.
|
||||
*/
|
||||
Iterable<? extends TrackedRace> getTrackedRaces();
|
||||
|
||||
void lockTrackedRacesForRead();
|
||||
|
||||
void unlockTrackedRacesAfterRead();
|
||||
|
||||
void lockTrackedRacesForWrite();
|
||||
|
||||
void unlockTrackedRacesAfterWrite();
|
||||
|
||||
Iterable<TrackedRace> getTrackedRaces(BoatClass boatClass);
|
||||
|
||||
/**
|
||||
@@ -72,5 +95,5 @@ public interface TrackedRegatta extends Serializable {
|
||||
int getNetPoints(Competitor competitor, TimePoint timePoint) throws NoWindException;
|
||||
|
||||
void removeTrackedRace(RaceDefinition raceDefinition);
|
||||
|
||||
|
||||
}
|
||||
+9
-14
@@ -12,6 +12,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
@@ -57,7 +58,7 @@ public class TrackedLegImpl implements TrackedLeg {
|
||||
private final Leg leg;
|
||||
private final Map<Competitor, TrackedLegOfCompetitor> trackedLegsOfCompetitors;
|
||||
private TrackedRaceImpl trackedRace;
|
||||
private transient Map<TimePoint, List<TrackedLegOfCompetitor>> competitorTracksOrderedByRank;
|
||||
private transient ConcurrentHashMap<TimePoint, List<TrackedLegOfCompetitor>> competitorTracksOrderedByRank;
|
||||
|
||||
public TrackedLegImpl(DynamicTrackedRaceImpl trackedRace, Leg leg, Iterable<Competitor> competitors) {
|
||||
super();
|
||||
@@ -68,12 +69,12 @@ public class TrackedLegImpl implements TrackedLeg {
|
||||
trackedLegsOfCompetitors.put(competitor, new TrackedLegOfCompetitorImpl(this, competitor));
|
||||
}
|
||||
trackedRace.addListener(new CacheClearingRaceChangeListener());
|
||||
competitorTracksOrderedByRank = new HashMap<>();
|
||||
competitorTracksOrderedByRank = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
|
||||
ois.defaultReadObject();
|
||||
competitorTracksOrderedByRank = new HashMap<>();
|
||||
competitorTracksOrderedByRank = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -124,11 +125,9 @@ public class TrackedLegImpl implements TrackedLeg {
|
||||
|
||||
List<TrackedLegOfCompetitor> getCompetitorTracksOrderedByRank(TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
|
||||
List<TrackedLegOfCompetitor> rankedCompetitorList;
|
||||
synchronized (competitorTracksOrderedByRank) {
|
||||
rankedCompetitorList = competitorTracksOrderedByRank.get(timePoint);
|
||||
if (rankedCompetitorList != null) {
|
||||
rankedCompetitorList = new ArrayList<TrackedLegOfCompetitor>(rankedCompetitorList);
|
||||
}
|
||||
rankedCompetitorList = competitorTracksOrderedByRank.get(timePoint);
|
||||
if (rankedCompetitorList != null) {
|
||||
rankedCompetitorList = new ArrayList<TrackedLegOfCompetitor>(rankedCompetitorList);
|
||||
}
|
||||
if (rankedCompetitorList == null) {
|
||||
rankedCompetitorList = new ArrayList<TrackedLegOfCompetitor>();
|
||||
@@ -140,9 +139,7 @@ public class TrackedLegImpl implements TrackedLeg {
|
||||
// an the asynchronous nature of how the data is being received
|
||||
Collections.sort(rankedCompetitorList, getTrackedRace().getRankingMetric().getLegRankingComparator(this, timePoint, cache));
|
||||
rankedCompetitorList = Collections.unmodifiableList(rankedCompetitorList);
|
||||
synchronized (competitorTracksOrderedByRank) {
|
||||
competitorTracksOrderedByRank.put(timePoint, rankedCompetitorList);
|
||||
}
|
||||
competitorTracksOrderedByRank.put(timePoint, rankedCompetitorList);
|
||||
if (Util.size(getTrackedLegsOfCompetitors()) != rankedCompetitorList.size()) {
|
||||
logger.warning("Number of competitors in leg (" + Util.size(getTrackedLegsOfCompetitors())
|
||||
+ ") differs from number of competitors in race ("
|
||||
@@ -302,9 +299,7 @@ public class TrackedLegImpl implements TrackedLeg {
|
||||
}
|
||||
|
||||
private void clearCaches() {
|
||||
synchronized (competitorTracksOrderedByRank) {
|
||||
competitorTracksOrderedByRank.clear();
|
||||
}
|
||||
competitorTracksOrderedByRank.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+17
-16
@@ -25,6 +25,7 @@ import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.leaderboard.caching.LeaderboardDTOCalculationReuseCache;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
||||
import com.sap.sailing.domain.tracking.GPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
@@ -406,17 +407,17 @@ public class TrackedLegOfCompetitorImpl implements TrackedLegOfCompetitor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getWindwardDistanceToOverallLeader(TimePoint timePoint, WindPositionMode windPositionMode) {
|
||||
return getWindwardDistanceToOverallLeader(timePoint, windPositionMode, new LeaderboardDTOCalculationReuseCache(timePoint));
|
||||
public Distance getWindwardDistanceToCompetitorFarthestAhead(TimePoint timePoint, WindPositionMode windPositionMode, final RankingInfo rankingInfo) {
|
||||
return getWindwardDistanceToCompetitorFarthestAhead(timePoint, windPositionMode, rankingInfo, new LeaderboardDTOCalculationReuseCache(timePoint));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getWindwardDistanceToOverallLeader(TimePoint timePoint, WindPositionMode windPositionMode, WindLegTypeAndLegBearingCache cache) {
|
||||
public Distance getWindwardDistanceToCompetitorFarthestAhead(TimePoint timePoint, WindPositionMode windPositionMode, final RankingInfo rankingInfo, WindLegTypeAndLegBearingCache cache) {
|
||||
// FIXME bug 607 it seems the following fetches the leader of this leg, not the overall leader; validate!!! Use getTrackedRace().getRanks() instead
|
||||
Competitor leader = getTrackedRace().getOverallLeader(timePoint, cache);
|
||||
TrackedLegOfCompetitor leaderLeg = getTrackedRace().getCurrentLeg(leader, timePoint);
|
||||
Competitor competitorFarthestAhead = rankingInfo.getCompetitorFarthestAhead();
|
||||
TrackedLegOfCompetitor leaderLeg = getTrackedRace().getCurrentLeg(competitorFarthestAhead, timePoint);
|
||||
Distance result = null;
|
||||
Position leaderPosition = getTrackedRace().getTrack(leader).getEstimatedPosition(timePoint, /* extrapolate */ false);
|
||||
Position leaderPosition = getTrackedRace().getTrack(competitorFarthestAhead).getEstimatedPosition(timePoint, /* extrapolate */ false);
|
||||
Position currentPosition = getTrackedRace().getTrack(getCompetitor()).getEstimatedPosition(timePoint, /* extrapolate */ false);
|
||||
if (leaderPosition != null && currentPosition != null) {
|
||||
result = Distance.NULL;
|
||||
@@ -486,15 +487,15 @@ public class TrackedLegOfCompetitorImpl implements TrackedLegOfCompetitor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getGapToLeader(TimePoint timePoint, final Competitor leaderInLegAtTimePoint, WindPositionMode windPositionMode)
|
||||
throws NoWindException {
|
||||
return getGapToLeader(timePoint, leaderInLegAtTimePoint, windPositionMode, new LeaderboardDTOCalculationReuseCache(timePoint));
|
||||
public Duration getGapToLeader(TimePoint timePoint, final Competitor leaderInLegAtTimePoint,
|
||||
final RankingInfo rankingInfo, WindPositionMode windPositionMode) throws NoWindException {
|
||||
return getGapToLeader(timePoint, leaderInLegAtTimePoint, windPositionMode, rankingInfo, new LeaderboardDTOCalculationReuseCache(timePoint));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getGapToLeader(TimePoint timePoint, final Competitor leaderInLegAtTimePoint,
|
||||
WindPositionMode windPositionMode, WindLegTypeAndLegBearingCache cache) {
|
||||
return getGapToLeader(timePoint, ()->leaderInLegAtTimePoint, windPositionMode, cache);
|
||||
WindPositionMode windPositionMode, final RankingInfo rankingInfo, WindLegTypeAndLegBearingCache cache) {
|
||||
return getGapToLeader(timePoint, ()->leaderInLegAtTimePoint, windPositionMode, rankingInfo, cache);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
@@ -503,17 +504,17 @@ public class TrackedLegOfCompetitorImpl implements TrackedLegOfCompetitor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getGapToLeader(final TimePoint timePoint, WindPositionMode windPositionMode) {
|
||||
return getGapToLeader(timePoint, windPositionMode, new LeaderboardDTOCalculationReuseCache(timePoint));
|
||||
public Duration getGapToLeader(final TimePoint timePoint, final RankingInfo rankingInfo, WindPositionMode windPositionMode) {
|
||||
return getGapToLeader(timePoint, windPositionMode, rankingInfo, new LeaderboardDTOCalculationReuseCache(timePoint));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getGapToLeader(final TimePoint timePoint, WindPositionMode windPositionMode, WindLegTypeAndLegBearingCache cache) {
|
||||
public Duration getGapToLeader(final TimePoint timePoint, WindPositionMode windPositionMode, final RankingInfo rankingInfo, WindLegTypeAndLegBearingCache cache) {
|
||||
return getGapToLeader(timePoint, ()->getTrackedLeg().getLeader(hasFinishedLeg(timePoint) ? getFinishTime() : timePoint),
|
||||
windPositionMode, new LeaderboardDTOCalculationReuseCache(timePoint));
|
||||
windPositionMode, rankingInfo, new LeaderboardDTOCalculationReuseCache(timePoint));
|
||||
}
|
||||
|
||||
private Duration getGapToLeader(TimePoint timePoint, LeaderGetter leaderGetter, WindPositionMode windPositionMode, WindLegTypeAndLegBearingCache cache) {
|
||||
private Duration getGapToLeader(TimePoint timePoint, LeaderGetter leaderGetter, WindPositionMode windPositionMode, RankingInfo rankingInfo, WindLegTypeAndLegBearingCache cache) {
|
||||
// If a competitor already completed this leg, compute the estimated arrival time at the
|
||||
// end of this leg and compare to the first mark passing for the end of this leg; if this leg's competitor also already
|
||||
// finished the leg, return the difference between this competitor's leg completion time point and the leader's completion
|
||||
|
||||
+9
-13
@@ -107,6 +107,7 @@ import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
||||
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
|
||||
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
||||
import com.sap.sailing.domain.ranking.RankingMetricConstructor;
|
||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.GPSFixTrack;
|
||||
@@ -1376,12 +1377,12 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
|
||||
@Override
|
||||
public MarkPassing getMarkPassing(Competitor competitor, Waypoint waypoint) {
|
||||
final NavigableSet<MarkPassing> markPassings = getMarkPassings(competitor);
|
||||
final Iterable<MarkPassing> markPassings = getMarkPassingsInOrder(waypoint);
|
||||
if (markPassings != null) {
|
||||
lockForRead(markPassings);
|
||||
try {
|
||||
for (MarkPassing markPassing : markPassings) {
|
||||
if (markPassing.getWaypoint() == waypoint) {
|
||||
if (markPassing.getCompetitor() == competitor) {
|
||||
return markPassing;
|
||||
}
|
||||
}
|
||||
@@ -2869,15 +2870,17 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getWindwardDistanceToOverallLeader(Competitor competitor, TimePoint timePoint, WindPositionMode windPositionMode) {
|
||||
public Distance getWindwardDistanceToCompetitorFarthestAhead(Competitor competitor, TimePoint timePoint, WindPositionMode windPositionMode) {
|
||||
final TrackedLegOfCompetitor trackedLeg = getTrackedLeg(competitor, timePoint);
|
||||
return trackedLeg == null ? null : trackedLeg.getWindwardDistanceToOverallLeader(timePoint, windPositionMode);
|
||||
return trackedLeg == null ? null : trackedLeg.getWindwardDistanceToCompetitorFarthestAhead(timePoint, windPositionMode,
|
||||
getRankingMetric().getRankingInfo(timePoint));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getWindwardDistanceToOverallLeader(Competitor competitor, TimePoint timePoint, WindPositionMode windPositionMode, WindLegTypeAndLegBearingCache cache) {
|
||||
public Distance getWindwardDistanceToCompetitorFarthestAhead(Competitor competitor, TimePoint timePoint,
|
||||
WindPositionMode windPositionMode, RankingInfo rankingInfo, WindLegTypeAndLegBearingCache cache) {
|
||||
final TrackedLegOfCompetitor trackedLeg = getTrackedLeg(competitor, timePoint);
|
||||
return trackedLeg == null ? null : trackedLeg.getWindwardDistanceToOverallLeader(timePoint, windPositionMode, cache);
|
||||
return trackedLeg == null ? null : trackedLeg.getWindwardDistanceToCompetitorFarthestAhead(timePoint, windPositionMode, rankingInfo, cache);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3584,11 +3587,4 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
public void setPolarDataService(PolarDataService polarDataService) {
|
||||
this.polarDataService = polarDataService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getCorrectedWindwardDistanceToOverallLeader(Competitor competitor, TimePoint timePoint,
|
||||
WindPositionMode windPositionMode) throws NoWindException {
|
||||
// TODO bug 1018, see comment #17: implement the calculation for corrected windward distance
|
||||
return getWindwardDistanceToOverallLeader(competitor, timePoint, windPositionMode);
|
||||
}
|
||||
}
|
||||
+90
-20
@@ -7,6 +7,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
@@ -26,6 +27,9 @@ import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.TrackedRegatta;
|
||||
import com.sap.sailing.domain.tracking.WindStore;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.concurrent.LockUtil;
|
||||
import com.sap.sse.concurrent.NamedReentrantReadWriteLock;
|
||||
|
||||
public class TrackedRegattaImpl implements TrackedRegatta {
|
||||
private static final long serialVersionUID = 6480508193567014285L;
|
||||
@@ -33,12 +37,24 @@ public class TrackedRegattaImpl implements TrackedRegatta {
|
||||
private static final Logger logger = Logger.getLogger(TrackedRegattaImpl.class.getName());
|
||||
|
||||
private final Regatta regatta;
|
||||
|
||||
/**
|
||||
* Guards access to {@link #trackedRaces}. Callers of {@link #getTrackedRaces()} need to acquire the
|
||||
* read lock before iterating.
|
||||
*/
|
||||
private final NamedReentrantReadWriteLock trackedRacesLock;
|
||||
|
||||
/**
|
||||
* Guarded by {@link #trackedRacesLock}
|
||||
*/
|
||||
private final Map<RaceDefinition, TrackedRace> trackedRaces;
|
||||
|
||||
private final Map<BoatClass, Collection<TrackedRace>> trackedRacesByBoatClass;
|
||||
private transient Set<RaceListener> raceListeners;
|
||||
|
||||
public TrackedRegattaImpl(Regatta regatta) {
|
||||
super();
|
||||
trackedRacesLock = new NamedReentrantReadWriteLock("trackeRaces lock for tracked regatta "+regatta.getName(), /* fair */ false);
|
||||
this.regatta = regatta;
|
||||
this.trackedRaces = new HashMap<RaceDefinition, TrackedRace>();
|
||||
this.trackedRacesByBoatClass = new HashMap<BoatClass, Collection<TrackedRace>>();
|
||||
@@ -49,10 +65,33 @@ public class TrackedRegattaImpl implements TrackedRegatta {
|
||||
ois.defaultReadObject();
|
||||
this.raceListeners = new HashSet<RaceListener>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lockTrackedRacesForRead() {
|
||||
LockUtil.lockForRead(trackedRacesLock);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unlockTrackedRacesAfterRead() {
|
||||
LockUtil.unlockAfterRead(trackedRacesLock);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lockTrackedRacesForWrite() {
|
||||
LockUtil.lockForWrite(trackedRacesLock);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unlockTrackedRacesAfterWrite() {
|
||||
LockUtil.unlockAfterWrite(trackedRacesLock);
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream oos) throws IOException {
|
||||
synchronized (trackedRaces) {
|
||||
lockTrackedRacesForRead();
|
||||
try {
|
||||
oos.defaultWriteObject();
|
||||
} finally {
|
||||
unlockTrackedRacesAfterRead();
|
||||
}
|
||||
}
|
||||
/**
|
||||
@@ -68,10 +107,12 @@ public class TrackedRegattaImpl implements TrackedRegatta {
|
||||
|
||||
@Override
|
||||
public void addTrackedRace(TrackedRace trackedRace) {
|
||||
synchronized (trackedRaces) {
|
||||
final TrackedRace oldTrackedRace;
|
||||
LockUtil.lockForWrite(trackedRacesLock);
|
||||
try {
|
||||
logger.info("adding tracked race for "+trackedRace.getRace()+" to tracked regatta "+getRegatta().getName()+
|
||||
" with regatta hash code "+getRegatta().hashCode());
|
||||
TrackedRace oldTrackedRace = trackedRaces.put(trackedRace.getRace(), trackedRace);
|
||||
oldTrackedRace = trackedRaces.put(trackedRace.getRace(), trackedRace);
|
||||
if (oldTrackedRace != trackedRace) {
|
||||
Collection<TrackedRace> coll = trackedRacesByBoatClass.get(trackedRace.getRace().getBoatClass());
|
||||
if (coll == null) {
|
||||
@@ -79,24 +120,31 @@ public class TrackedRegattaImpl implements TrackedRegatta {
|
||||
trackedRacesByBoatClass.put(trackedRace.getRace().getBoatClass(), coll);
|
||||
}
|
||||
coll.add(trackedRace);
|
||||
for (RaceListener listener : raceListeners) {
|
||||
listener.raceAdded(trackedRace);
|
||||
}
|
||||
trackedRaces.notifyAll();
|
||||
}
|
||||
} finally {
|
||||
LockUtil.unlockAfterWrite(trackedRacesLock);
|
||||
}
|
||||
if (oldTrackedRace != trackedRace) {
|
||||
for (RaceListener listener : raceListeners) {
|
||||
listener.raceAdded(trackedRace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTrackedRace(RaceDefinition raceDefinition) {
|
||||
synchronized (trackedRaces) {
|
||||
LockUtil.lockForWrite(trackedRacesLock);
|
||||
try {
|
||||
trackedRaces.remove(raceDefinition);
|
||||
} finally {
|
||||
LockUtil.unlockAfterWrite(trackedRacesLock);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTrackedRace(TrackedRace trackedRace) {
|
||||
synchronized (trackedRaces) {
|
||||
LockUtil.lockForWrite(trackedRacesLock);
|
||||
try {
|
||||
trackedRaces.remove(trackedRace.getRace());
|
||||
Collection<TrackedRace> trbbc = trackedRacesByBoatClass.get(trackedRace.getRace().getBoatClass());
|
||||
if (trbbc != null) {
|
||||
@@ -108,7 +156,8 @@ public class TrackedRegattaImpl implements TrackedRegatta {
|
||||
for (RaceListener listener : raceListeners) {
|
||||
listener.raceRemoved(trackedRace);
|
||||
}
|
||||
trackedRaces.notifyAll();
|
||||
} finally {
|
||||
LockUtil.unlockAfterWrite(trackedRacesLock);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,6 +168,9 @@ public class TrackedRegattaImpl implements TrackedRegatta {
|
||||
|
||||
@Override
|
||||
public Iterable<? extends TrackedRace> getTrackedRaces() {
|
||||
if (trackedRacesLock.getReadHoldCount() <= 0 && trackedRacesLock.getWriteHoldCount() <= 0) {
|
||||
throw new IllegalStateException("Callers of TrackedRegatta.getTrackedRaces() must hold the read lock; see TrackedRegatta.lockTrackedRacesForRead()");
|
||||
}
|
||||
return trackedRaces.values();
|
||||
}
|
||||
|
||||
@@ -130,7 +182,8 @@ public class TrackedRegattaImpl implements TrackedRegatta {
|
||||
@Override
|
||||
public TrackedRace getTrackedRace(RaceDefinition race) {
|
||||
boolean interrupted = false;
|
||||
synchronized (trackedRaces) {
|
||||
lockTrackedRacesForRead();
|
||||
try {
|
||||
TrackedRace result = trackedRaces.get(race);
|
||||
while (!interrupted && result == null) {
|
||||
try {
|
||||
@@ -141,31 +194,48 @@ public class TrackedRegattaImpl implements TrackedRegatta {
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} finally {
|
||||
unlockTrackedRacesAfterRead();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrackedRace getExistingTrackedRace(RaceDefinition race) {
|
||||
return trackedRaces.get(race);
|
||||
lockTrackedRacesForRead();
|
||||
try {
|
||||
return trackedRaces.get(race);
|
||||
} finally {
|
||||
unlockTrackedRacesAfterRead();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRaceListener(RaceListener listener) {
|
||||
raceListeners.add(listener);
|
||||
synchronized (trackedRaces) {
|
||||
for (TrackedRace trackedRace : getTrackedRaces()) {
|
||||
listener.raceAdded(trackedRace);
|
||||
}
|
||||
final List<TrackedRace> trackedRacesCopy = new ArrayList<>();
|
||||
lockTrackedRacesForRead();
|
||||
try {
|
||||
raceListeners.add(listener);
|
||||
Util.addAll(getTrackedRaces(), trackedRacesCopy);
|
||||
} finally {
|
||||
unlockTrackedRacesAfterRead();
|
||||
}
|
||||
for (TrackedRace trackedRace : trackedRacesCopy) {
|
||||
listener.raceAdded(trackedRace);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNetPoints(Competitor competitor, TimePoint timePoint) throws NoWindException {
|
||||
int result = 0;
|
||||
for (TrackedRace trackedRace : getTrackedRaces()) {
|
||||
result += trackedRace.getRank(competitor, timePoint);
|
||||
lockTrackedRacesForRead();
|
||||
try {
|
||||
for (TrackedRace trackedRace : getTrackedRaces()) {
|
||||
result += trackedRace.getRank(competitor, timePoint);
|
||||
}
|
||||
return result;
|
||||
} finally {
|
||||
unlockTrackedRacesAfterRead();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
provider-name="SAP">
|
||||
|
||||
<description url="http://www.sap.com">
|
||||
The SAP Sailing Server.
|
||||
|
||||
Provides connectivity to a TracTrac live GPS feed as well as a live feed from an Expedition system.
|
||||
The SAP Sailing Server.
|
||||
|
||||
Provides connectivity to a TracTrac live GPS feed as well as a live feed from an Expedition system.
|
||||
Computes leaderboard information for sailing races and offers RESTful APIs to all of this.
|
||||
</description>
|
||||
|
||||
|
||||
+20
-9
@@ -37,6 +37,7 @@ import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||
import com.sap.sailing.domain.polars.PolarDataService;
|
||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
||||
import com.sap.sailing.domain.tracking.CourseDesignChangedListener;
|
||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.DynamicRaceDefinitionSet;
|
||||
@@ -314,6 +315,22 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
||||
boolean useMarkPassingCalculator) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lockTrackedRacesForRead() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unlockTrackedRacesAfterRead() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lockTrackedRacesForWrite() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unlockTrackedRacesAfterWrite() {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -372,7 +389,7 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getWindwardDistanceToOverallLeader(Competitor competitor, TimePoint timePoint, WindPositionMode windPositionMode) {
|
||||
public Distance getWindwardDistanceToCompetitorFarthestAhead(Competitor competitor, TimePoint timePoint, WindPositionMode windPositionMode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -736,12 +753,6 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
||||
public void setPolarDataService(PolarDataService polarDataService) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getCorrectedWindwardDistanceToOverallLeader(Competitor competitor, TimePoint timePoint,
|
||||
WindPositionMode windPositionMode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getEstimatedTimeToComplete(TimePoint timepoint) throws NotEnoughDataHasBeenAddedException,
|
||||
NoWindException {
|
||||
@@ -749,8 +760,8 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getWindwardDistanceToOverallLeader(Competitor competitor, TimePoint timePoint,
|
||||
WindPositionMode windPositionMode, WindLegTypeAndLegBearingCache cache) {
|
||||
public Distance getWindwardDistanceToCompetitorFarthestAhead(Competitor competitor, TimePoint timePoint,
|
||||
WindPositionMode windPositionMode, RankingInfo rankingInfo, WindLegTypeAndLegBearingCache cache) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Executable → Regular
+924
-917
File diff suppressed because it is too large.
Load diff
@@ -26,7 +26,7 @@
|
||||
|
||||
body {
|
||||
background: url(images/spectatorview-bg.png) no-repeat left top #ebebeb;
|
||||
font-family: 'OpenSansRegular', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
line-height: 1;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
@@ -42,7 +42,7 @@ a {
|
||||
|
||||
table td,select,button {
|
||||
line-height: 1;
|
||||
font-family: 'OpenSansRegular', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
@@ -161,7 +161,8 @@ input.magnifier {
|
||||
}
|
||||
|
||||
.chart-importantMessage {
|
||||
font-family: 'OpenSansSemiBold',Arial,Verdana,sans-serif;
|
||||
font-family: 'Open Sans',Arial,Verdana,sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 20px;
|
||||
height: 70px;
|
||||
margin: 0 auto;
|
||||
@@ -172,7 +173,8 @@ input.magnifier {
|
||||
}
|
||||
|
||||
.chart-busyMessage {
|
||||
font-family: 'OpenSansSemiBold',Arial,Verdana,sans-serif;
|
||||
font-family: 'Open Sans',Arial,Verdana,sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 20px;
|
||||
height: 70px;
|
||||
margin: 0 auto;
|
||||
@@ -193,7 +195,8 @@ input.magnifier {
|
||||
border-top-left-radius: 3px;
|
||||
color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
font-family: OpenSansSemiBold,Verdana,Arial,sans-serif;
|
||||
font-family: 'Open Sans',Verdana,Arial,sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
margin: 0 0 0 0;
|
||||
padding: 2px 7px 2px 3px;
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
body {
|
||||
background: #fff;
|
||||
font-family: 'OpenSansRegular', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
line-height: 1;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
@@ -81,7 +81,7 @@ input.magnifier{
|
||||
}
|
||||
|
||||
body, table td, select, button {
|
||||
font-family: 'OpenSansLight', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
@@ -90,7 +90,8 @@ body, table td, select, button {
|
||||
}
|
||||
|
||||
.abstractChartPanel-importantMessageOfChart {
|
||||
font-family: 'OpenSansBold',Arial,Verdana,sans-serif;
|
||||
font-family: 'Open Sans',Arial,Verdana,sans-serif;
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
height: 70px;
|
||||
margin: 0 auto;
|
||||
@@ -105,7 +106,7 @@ body, table td, select, button {
|
||||
margin: 0 auto;
|
||||
width: 400px;
|
||||
text-align: center;
|
||||
font-family: 'OpenSansRegular', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-size: 18px;
|
||||
color: #fff;
|
||||
margin-top: 22px;
|
||||
@@ -113,7 +114,7 @@ body, table td, select, button {
|
||||
|
||||
.leaderboardHeading {
|
||||
font-size: 16px;
|
||||
font-family: 'OpenSansRegular', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@@ -122,7 +123,8 @@ body, table td, select, button {
|
||||
}
|
||||
|
||||
.bold {
|
||||
font-family: "OpenSansCondensedBold", sans-serif;
|
||||
font-family: 'Open Sans Condensed', sans-serif;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.trackingQuality-circle {
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/clean/sailing-clean-1.0.cache.css">
|
||||
<link rel="stylesheet" type="text/css" href="/sailing-fontface-1.0.cache.css">
|
||||
<link rel="stylesheet" type="text/css" href="CommonControls.css">
|
||||
<link rel="stylesheet" type="text/css" href="SettingsDialog.css">
|
||||
<link rel="stylesheet" type="text/css" href="ViewerToolbar.css">
|
||||
<link rel="stylesheet" type="text/css" href="Leaderboard.css">
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ input.magnifier{
|
||||
}
|
||||
|
||||
body, table td, select, button {
|
||||
font-family: 'OpenSansLight', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,8 @@ body, table td, select, button {
|
||||
}
|
||||
|
||||
.abstractChartPanel-importantMessageOfChart {
|
||||
font-family: 'OpenSansBold',Arial,Verdana,sans-serif;
|
||||
font-family: 'Open Sans',Arial,Verdana,sans-serif;
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
height: 70px;
|
||||
margin: 0 auto;
|
||||
@@ -60,7 +61,7 @@ body, table td, select, button {
|
||||
margin: 0 auto;
|
||||
width: 400px;
|
||||
text-align: center;
|
||||
font-family: 'OpenSansRegular', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-size: 18px;
|
||||
color: #fff;
|
||||
margin-top: 22px;
|
||||
@@ -68,7 +69,7 @@ body, table td, select, button {
|
||||
|
||||
.leaderboardHeading {
|
||||
font-size: 16px;
|
||||
font-family: 'OpenSansRegular', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@@ -77,7 +78,8 @@ body, table td, select, button {
|
||||
}
|
||||
|
||||
.bold {
|
||||
font-family: "OpenSansCondensedBold", sans-serif;
|
||||
font-family: 'Open Sans Condensed', sans-serif;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.trackingQuality-circle {
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
body {
|
||||
background: #fff;
|
||||
font-family: 'OpenSansRegular', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
line-height: 1;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
@@ -85,7 +85,8 @@ input.magnifier{
|
||||
}
|
||||
|
||||
body, table td, select, button {
|
||||
font-family: 'OpenSansLight', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-weight: 300;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
@@ -94,7 +95,8 @@ body, table td, select, button {
|
||||
}
|
||||
|
||||
.abstractChartPanel-importantMessageOfChart {
|
||||
font-family: 'OpenSansSemiBold',Arial,Verdana,sans-serif;
|
||||
font-family: 'Open Sans',Arial,Verdana,sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 20px;
|
||||
height: 70px;
|
||||
margin: 0 auto;
|
||||
@@ -109,7 +111,7 @@ body, table td, select, button {
|
||||
margin: 0 auto;
|
||||
width: 400px;
|
||||
text-align: center;
|
||||
font-family: 'OpenSansRegular', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-size: 18px;
|
||||
color: #fff;
|
||||
margin-top: 22px;
|
||||
@@ -117,7 +119,7 @@ body, table td, select, button {
|
||||
|
||||
.leaderboardHeading {
|
||||
font-size: 16px;
|
||||
font-family: 'OpenSansRegular', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
@@ -83,11 +83,21 @@ table {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.MapSimulationLegendParentDiv {
|
||||
.TrueNorthIndicatorPanelParentDiv {
|
||||
padding-top: 10px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.MapSimulationLegendParentDiv {
|
||||
padding-bottom: 10px;
|
||||
padding-right: 10px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.MapSimulationLegend {
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
.RaceMap-HeaderPanel {
|
||||
height: 60px;
|
||||
width: 100%;
|
||||
@@ -142,13 +152,15 @@ img.openColumn {
|
||||
.raceBoardNavigation {
|
||||
float: left;
|
||||
margin: 9px 0 0 12px;
|
||||
font-family: 'OpenSansLight', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.raceBoardControls {
|
||||
float: right;
|
||||
margin: 9px 0 0 12px;
|
||||
font-family: 'OpenSansLight', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.raceBoardNavigation-navigationitem {
|
||||
@@ -180,7 +192,8 @@ img.openColumn {
|
||||
}
|
||||
|
||||
.abstractChartPanel-importantMessageOfChart {
|
||||
font-family: 'OpenSansSemiBold', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 20px;
|
||||
height: 70px;
|
||||
margin: 0 auto;
|
||||
@@ -239,7 +252,8 @@ img.openColumn {
|
||||
0 transparent;
|
||||
color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
font-family: OpenSansSemiBold, Verdana, Arial, sans-serif;
|
||||
font-family: 'Open Sans', Verdana, Arial, sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
margin: 0 0 0 0;
|
||||
padding: 2px 7px 2px 3px;
|
||||
@@ -272,7 +286,8 @@ img.openColumn {
|
||||
0 transparent;
|
||||
color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
font-family: OpenSansSemiBold, Verdana, Arial, sans-serif;
|
||||
font-family: 'Open Sans', Verdana, Arial, sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
margin: 0 0 0 0;
|
||||
padding: 2px 7px 2px 3px;
|
||||
@@ -584,6 +599,7 @@ img.openColumn {
|
||||
}
|
||||
|
||||
.RegattaRaceInformation-Header {
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
position: relative;
|
||||
left: 140px;
|
||||
top: 11px;
|
||||
|
||||
@@ -1,62 +1,78 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="com.google.gdt.eclipse.suite.webapp">
|
||||
<booleanAttribute key="com.google.gdt.eclipse.core.RUN_SERVER" value="false"/>
|
||||
<stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/>
|
||||
<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/>
|
||||
<booleanAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT_AUTO" value="true"/>
|
||||
<booleanAttribute key="com.google.gwt.eclipse.core.SUPERDEVMODE_ENABLED" value="true"/>
|
||||
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/gwt/Home.html"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/com.sap.sailing.gwt.ui"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
|
||||
</listAttribute>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="false"/>
|
||||
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6" javaProject="com.sap.sailing.gwt.ui" path="1" type="4"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src/main/resources" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src/main/java" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt.theme/src/main/java" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.googlecode.java-diff-utils/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.common/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.json.simple/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.server/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.tractracadapter/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.expeditionconnector/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.declination/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.declination/resources" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.udpconnector/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.mongodb/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.swisstimingadapter/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.persistence/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.swisstimingadapter.persistence/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.operationaltransformation/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.replication/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.tractracadapter.persistence/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.moxieapps.gwt.highcharts/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.geocoding/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.datamining.shared/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.common/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.datamining.shared/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.google.gwt.osgi/lib/gwt-user.jar" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="com.sap.sailing.gwt.ui"/> </runtimeClasspathEntry> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.security/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.security.ui/src/main/java" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt.adminconsole/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.security.common/src" path="3" type="2"/> "/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-superDevMode -incremental -war "${project_loc:com.sap.sailing.gwt.ui}" -noserver -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -logLevel INFO -codeServerPort auto -startupUrl /gwt/Home.html com.sap.sailing.gwt.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/PolarSheets.html com.sap.sailing.gwt.ui.PolarSheets -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.ui.PolarSheets com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.Home com.sap.sailing.gwt.ui.RaceBoard com.sap.sailing.gwt.ui.RegattaOverview"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms1024m -Xmx3072m"/>
|
||||
</launchConfiguration>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="com.google.gdt.eclipse.suite.webapp">
|
||||
<booleanAttribute key="com.google.gdt.eclipse.core.RUN_SERVER" value="false"/>
|
||||
<stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/>
|
||||
<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/>
|
||||
<booleanAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT_AUTO" value="true"/>
|
||||
<listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES">
|
||||
<listEntry value="com.sap.sailing.gwt.regattaoverview.RegattaOverview"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.RaceBoard"/>
|
||||
<listEntry value="com.sap.sailing.gwt.Home"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.DataMining"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.LeaderboardEditing"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.AdminConsole"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.Spectator"/>
|
||||
<listEntry value="com.sap.sailing.gwt.regattaoverview.RegattaOverview"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.PolarSheets"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.Leaderboard"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.Simulator"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.YoutubePopup"/>
|
||||
<listEntry value="com.sap.sailing.gwt.AutoPlay"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.VideoPopup"/>
|
||||
</listAttribute>
|
||||
<booleanAttribute key="com.google.gwt.eclipse.core.SUPERDEVMODE_ENABLED" value="true"/>
|
||||
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/gwt/Home.html"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/com.sap.sailing.gwt.ui"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
|
||||
</listAttribute>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="false"/>
|
||||
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6" javaProject="com.sap.sailing.gwt.ui" path="1" type="4"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src/main/resources" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src/main/java" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt.theme/src/main/java" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.googlecode.java-diff-utils/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.common/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.json.simple/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.server/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.tractracadapter/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.expeditionconnector/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.declination/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.declination/resources" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.udpconnector/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.mongodb/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.swisstimingadapter/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.persistence/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.swisstimingadapter.persistence/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.operationaltransformation/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.replication/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.tractracadapter.persistence/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.moxieapps.gwt.highcharts/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.geocoding/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.datamining.shared/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.common/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.datamining.shared/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.google.gwt.osgi/lib/gwt-user.jar" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="com.sap.sailing.gwt.ui"/> </runtimeClasspathEntry> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.security/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.security.ui/src/main/java" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt.adminconsole/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.security.common/src" path="3" type="2"/> "/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-superDevMode -incremental -war "${project_loc:com.sap.sailing.gwt.ui}" -noserver -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -logLevel INFO -codeServerPort auto -startupUrl /gwt/Home.html com.sap.sailing.gwt.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/PolarSheets.html com.sap.sailing.gwt.ui.PolarSheets -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.ui.PolarSheets com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.Home com.sap.sailing.gwt.ui.RaceBoard com.sap.sailing.gwt.regattaoverview.RegattaOverview"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms1024m -Xmx3072m"/>
|
||||
</launchConfiguration>
|
||||
@@ -1,75 +1,75 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="com.google.gdt.eclipse.suite.webapp">
|
||||
<booleanAttribute key="com.google.gdt.eclipse.core.RUN_SERVER" value="false"/>
|
||||
<stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/>
|
||||
<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/>
|
||||
<booleanAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT_AUTO" value="true"/>
|
||||
<listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES">
|
||||
<listEntry value="com.sap.sailing.gwt.ui.RaceBoard"/>
|
||||
<listEntry value="com.sap.sailing.gwt.Home"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.DataMining"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.YoutubePopup"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.LeaderboardEditing"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.AdminConsole"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.Spectator"/>
|
||||
<listEntry value="com.sap.sailing.gwt.regattaoverview.RegattaOverview"/>
|
||||
<listEntry value="com.sap.sailing.gwt.AutoPlay"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.VideoPopup"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.PolarSheets"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.Leaderboard"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.Simulator"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/gwt/Home.html"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/com.sap.sailing.gwt.ui"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6" javaProject="com.sap.sailing.gwt.ui" path="1" type="4"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src/main/resources" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src/main/java" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt.theme/src/main/java" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.googlecode.java-diff-utils/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.common/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.json.simple/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.server/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.tractracadapter/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.expeditionconnector/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.declination/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.declination/resources" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.udpconnector/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.mongodb/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.swisstimingadapter/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.persistence/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.swisstimingadapter.persistence/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.operationaltransformation/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.replication/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.tractracadapter.persistence/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.moxieapps.gwt.highcharts/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.geocoding/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.datamining.shared/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.common/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.datamining.shared/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.google.gwt.osgi/lib/gwt-user.jar" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="com.sap.sailing.gwt.ui"/> </runtimeClasspathEntry> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.security/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.security.ui/src/main/java" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt.adminconsole/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.security.common/src" path="3" type="2"/> "/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -war "${project_loc:com.sap.sailing.gwt.ui}" -noserver -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -logLevel INFO -codeServerPort auto -startupUrl /gwt/Home.html com.sap.sailing.gwt.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/PolarSheets.html com.sap.sailing.gwt.ui.PolarSheets -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.ui.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup -startupUrl /security/ui/Login.html com.sap.sse.security.ui.Login -startupUrl /security/ui/EditProfile.html com.sap.sse.security.ui.EditProfile -startupUrl /security/ui/EmailValidation.html com.sap.sse.security.ui.EmailValidation com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.ui.PolarSheets com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.Home com.sap.sailing.gwt.ui.RaceBoard com.sap.sailing.gwt.regattaoverview.RegattaOverview"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m -Dgwt-usearchives=false -Dgwt.persistentunitcache=false"/>
|
||||
</launchConfiguration>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="com.google.gdt.eclipse.suite.webapp">
|
||||
<booleanAttribute key="com.google.gdt.eclipse.core.RUN_SERVER" value="false"/>
|
||||
<stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/>
|
||||
<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/>
|
||||
<booleanAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT_AUTO" value="true"/>
|
||||
<listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES">
|
||||
<listEntry value="com.sap.sailing.gwt.ui.RaceBoard"/>
|
||||
<listEntry value="com.sap.sailing.gwt.Home"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.DataMining"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.YoutubePopup"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.LeaderboardEditing"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.AdminConsole"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.Spectator"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.RegattaOverview"/>
|
||||
<listEntry value="com.sap.sailing.gwt.AutoPlay"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.VideoPopup"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.PolarSheets"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.Leaderboard"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.Simulator"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/gwt/Home.html"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/com.sap.sailing.gwt.ui"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6" javaProject="com.sap.sailing.gwt.ui" path="1" type="4"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src/main/resources" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src/main/java" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt.theme/src/main/java" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.googlecode.java-diff-utils/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.common/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.json.simple/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.server/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.tractracadapter/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.expeditionconnector/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.declination/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.declination/resources" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.udpconnector/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.mongodb/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.swisstimingadapter/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.persistence/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.swisstimingadapter.persistence/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.operationaltransformation/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.replication/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.tractracadapter.persistence/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.moxieapps.gwt.highcharts/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.geocoding/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.datamining.shared/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.common/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.datamining.shared/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.google.gwt.osgi/lib/gwt-user.jar" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="com.sap.sailing.gwt.ui"/> </runtimeClasspathEntry> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.security/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.security.ui/src/main/java" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt.adminconsole/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.security.common/src" path="3" type="2"/> "/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -war "${project_loc:com.sap.sailing.gwt.ui}" -noserver -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -logLevel INFO -codeServerPort auto -startupUrl /gwt/Home.html com.sap.sailing.gwt.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/PolarSheets.html com.sap.sailing.gwt.ui.PolarSheets -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup -startupUrl /security/ui/Login.html com.sap.sse.security.ui.Login -startupUrl /security/ui/EditProfile.html com.sap.sse.security.ui.EditProfile -startupUrl /security/ui/EmailValidation.html com.sap.sse.security.ui.EmailValidation com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.ui.PolarSheets com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.Home com.sap.sailing.gwt.ui.RaceBoard"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m -Dgwt-usearchives=false -Dgwt.persistentunitcache=false"/>
|
||||
</launchConfiguration>
|
||||
@@ -5,14 +5,16 @@
|
||||
|
||||
.dialogInnerHeadline {
|
||||
border-bottom: 1px solid #CCCCCC;
|
||||
font-family: OpenSansSemiBold,Arial,Verdana,sans-serif;
|
||||
font-family: 'Open Sans',Arial,Verdana,sans-serif;
|
||||
font-weight: 600;
|
||||
height: 21px;
|
||||
padding: 2px 0 0 2px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.dialogInnerHeadlineOther {
|
||||
font-family: OpenSansSemiBold, Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-weight: 600;
|
||||
color: #e84a1a;
|
||||
padding-left: 9px;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,8 @@
|
||||
|
||||
.titleLabel {
|
||||
text-align: center;
|
||||
font-family: 'OpenSansSemiBold', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-weight: 600
|
||||
font-size: 18px;
|
||||
color: #fff;
|
||||
margin: 23px 0 0 0;
|
||||
@@ -40,7 +41,7 @@
|
||||
|
||||
body {
|
||||
background: #ebebeb;
|
||||
font-family: 'OpenSansRegular', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
line-height: 1;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
@@ -50,7 +51,8 @@ body {
|
||||
}
|
||||
|
||||
table td,select,button {
|
||||
font-family: 'OpenSansLight', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-weight: 300;
|
||||
line-height: 1;
|
||||
font-size: 14px;
|
||||
}
|
||||
@@ -64,7 +66,8 @@ table td,select,button {
|
||||
/** Example rules used by the template application (remove for your app) */
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
font-family: 'OpenSansSemiBold', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-weight: 600
|
||||
color: #777777;
|
||||
margin: 40px 0px 70px;
|
||||
text-align: center;
|
||||
@@ -106,7 +109,8 @@ table {
|
||||
/*.leaderboardLabel {
|
||||
border-bottom: 2px solid #007dc0;
|
||||
padding: 0 0 6px 0;
|
||||
font-family: 'OpenSansSemiBold', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-weight: 600
|
||||
}*/
|
||||
.refreshAndSettings {
|
||||
background: #f2f2f2;
|
||||
@@ -144,7 +148,8 @@ input.magnifier {
|
||||
/*.raceBoardNavigation {
|
||||
float: right;
|
||||
margin: 26px 0 0 0;
|
||||
font-family: 'OpenSansLight', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.raceBoardNavigation-navigationitem {
|
||||
@@ -167,7 +172,8 @@ input.magnifier {
|
||||
text-decoration: none;
|
||||
}*/
|
||||
.abstractChartPanel-importantMessageOfChart {
|
||||
font-family: 'OpenSansSemiBold', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-weight: 600
|
||||
font-size: 20px;
|
||||
height: 70px;
|
||||
margin: 0 auto;
|
||||
@@ -186,14 +192,15 @@ input.magnifier {
|
||||
}
|
||||
|
||||
.innerHeadline {
|
||||
font-family: OpenSansSemiBold, Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-size: 16px;
|
||||
color: #7c7c7c;
|
||||
margin: 15px 0
|
||||
}
|
||||
|
||||
.sectorHeadline {
|
||||
font-family: OpenSansLight, Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-weight: 300;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
@@ -329,7 +336,8 @@ input.magnifier {
|
||||
#masterPanelLeft .gwt-SliderBar-shell .gwt-SliderBar-ticklabel {
|
||||
font-size: 12px;
|
||||
cursor: default;
|
||||
font-family: 'OpenSansSemiBold',Arial,Verdana,sans-serif;
|
||||
font-family: 'Open Sans',Arial,Verdana,sans-serif;
|
||||
font-weight: 600;
|
||||
top: 5px;
|
||||
}
|
||||
|
||||
@@ -338,7 +346,8 @@ input.magnifier {
|
||||
font-size: 12px;
|
||||
color: #bc9434;
|
||||
cursor: default;
|
||||
font-family: 'OpenSansSemiBold',Arial,Verdana,sans-serif;
|
||||
font-family: 'Open Sans',Arial,Verdana,sans-serif;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
#masterPanelLeft .gwt-SliderBar-shell-focused {
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
body {
|
||||
background: url(images/spectatorview-bg.png) no-repeat left top #ebebeb;
|
||||
font-family: 'OpenSansRegular', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
line-height: 1;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
@@ -42,7 +42,7 @@ a {
|
||||
|
||||
table td,select,button {
|
||||
line-height: 1;
|
||||
font-family: 'OpenSansRegular', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
@@ -186,7 +186,8 @@ input.magnifier {
|
||||
float: left;
|
||||
margin: 5px 5px 5px 0;
|
||||
text-decoration: none;
|
||||
font-family: 'OpenSansSemiBold', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-weight: 600
|
||||
}
|
||||
|
||||
.leaderboardGroupPanel-BoatClass {
|
||||
@@ -196,7 +197,8 @@ input.magnifier {
|
||||
margin: 5px 5px 5px 0;
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
font-family: 'OpenSansSemiBold', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-weight: 600
|
||||
}
|
||||
|
||||
.leaderboardGroupPanel-ColorBox {
|
||||
@@ -227,7 +229,8 @@ input.magnifier {
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
/*border: 1px solid #a6a6a6;*/
|
||||
font-family: 'OpenSansSemiBold', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-weight: 600
|
||||
}
|
||||
|
||||
.leaderboardGroupPanel-LiveRace, .leaderboardGroupPanel-LegendLive {
|
||||
@@ -244,7 +247,8 @@ input.magnifier {
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
/*border: 1px solid #a6a6a6;*/
|
||||
font-family: 'OpenSansSemiBold', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-weight: 600
|
||||
}
|
||||
|
||||
.leaderboardGroupPanel-ActiveLeaderboard {
|
||||
@@ -260,7 +264,8 @@ input.magnifier {
|
||||
background: url("images/btn-cta-orangeleft.png") repeat-x -10px 0 #e7e7e7;
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
font-family: 'OpenSansSemiBold', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-weight: 600
|
||||
}
|
||||
|
||||
.leaderboardGroupPanel-ActiveButton {
|
||||
@@ -274,7 +279,8 @@ input.magnifier {
|
||||
background: url("images/btn-cta-blueleft.png") repeat-x 0px 0 #e7e7e7;
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
font-family: 'OpenSansSemiBold', Arial, Verdana, sans-serif;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-weight: 600
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
@@ -352,7 +358,7 @@ input.magnifier {
|
||||
|
||||
.leaderboardGroupPanel-InactiveRace {
|
||||
background: #c0bebe;
|
||||
font-family: 'OpenSansRegular', Arial, Verdana, sans-serif
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif
|
||||
}
|
||||
|
||||
.errorLabel {
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 30 30" enable-background="new 0 0 30 30" xml:space="preserve">
|
||||
<g>
|
||||
<path fill="#FFFFFF" d="M27.2,12.3L26.4,12c-1.1-0.3-2.8-0.8-3.9-1.1l-0.8-0.2c-1.1-0.3-1.3-1.2-0.5-1.9l0.5-0.5
|
||||
c0.1-0.1,0.3-0.3,0.5-0.5c-0.1,0-0.2-0.1-0.2-0.1c-4-4-10.6-4-14.7,0c-4,4-4,10.6,0,14.7c4,4,10.6,4,14.7,0c0.6-0.6,1.5-0.6,2.1,0
|
||||
s0.6,1.5,0,2.1c-2.6,2.6-6,3.9-9.5,3.9c-3.4,0-6.8-1.3-9.5-3.9c-5.2-5.2-5.2-13.7,0-18.9c5.2-5.2,13.7-5.2,18.9,0
|
||||
c0.1,0.1,0.1,0.1,0.1,0.2c0.1-0.1,0.2-0.2,0.3-0.3l0.5-0.5c0.8-0.8,1.7-0.5,1.9,0.5l0.2,0.8c0.3,1.1,0.8,2.8,1.1,3.9l0.2,0.8
|
||||
C28.9,11.9,28.2,12.5,27.2,12.3z M12,15.1v5l4.2-2.5l4.3-2.5l-4.3-2.5L12,10.1V15.1z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1014 B |
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 30 30" enable-background="new 0 0 30 30" xml:space="preserve">
|
||||
<path fill="#FFFFFF" d="M17.2,15L27,5.2c0.6-0.6,0.6-1.6,0-2.2c-0.6-0.6-1.6-0.6-2.2,0L15,12.8L5.2,3C4.6,2.3,3.6,2.3,3,3
|
||||
C2.3,3.6,2.3,4.6,3,5.2l9.8,9.8L3,24.8c-0.6,0.6-0.6,1.6,0,2.2c0.3,0.3,0.7,0.5,1.1,0.5c0.4,0,0.8-0.2,1.1-0.5l9.8-9.8l9.8,9.8
|
||||
c0.3,0.3,0.7,0.5,1.1,0.5c0.4,0,0.8-0.2,1.1-0.5c0.6-0.6,0.6-1.6,0-2.2L17.2,15z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 769 B |
+18
@@ -20,6 +20,7 @@ public interface SharedResources extends ClientBundle {
|
||||
String navbar_buttonhidden();
|
||||
String navbar_buttonactive();
|
||||
String button();
|
||||
String buttontextonly();
|
||||
String buttonsmall();
|
||||
String buttonstrong();
|
||||
String buttoninactive();
|
||||
@@ -41,6 +42,23 @@ public interface SharedResources extends ClientBundle {
|
||||
String lightbox_overlay();
|
||||
String lightbox_content();
|
||||
String lightbox_close();
|
||||
String spacer();
|
||||
String spacersmall();
|
||||
String spacermediumsmall();
|
||||
String spacermedium();
|
||||
String spacermediumbig();
|
||||
String spacerbig();
|
||||
String spacermargin();
|
||||
String spacermargintopsmall();
|
||||
String spacermargintopmediumsmall();
|
||||
String spacermargintopmedium();
|
||||
String spacermargintopmediumbig();
|
||||
String spacermargintopbig();
|
||||
String spacermarginbottomsmall();
|
||||
String spacermarginbottommediumsmall();
|
||||
String spacermarginbottommedium();
|
||||
String spacermarginbottommediumbig();
|
||||
String spacermarginbottombig();
|
||||
String stickyheader();
|
||||
String slideto();
|
||||
String slidetonav();
|
||||
|
||||
+1
@@ -4,6 +4,7 @@
|
||||
<ui:with field="i18n_ubi" type="com.sap.sailing.gwt.common.client.i18n.TextMessages"/>
|
||||
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
|
||||
<g:HTMLPanel>
|
||||
<div class="{res.mainCss.spacer} {res.mainCss.spacersmall}"></div>
|
||||
<m:Message ui:field="message" />
|
||||
<div class="{res.mediaCss.grid}">
|
||||
<g:SimplePanel ui:field="stage" addStyleNames="{res.mediaCss.small12} {res.mediaCss.columns}" />
|
||||
|
||||
+16
@@ -4,6 +4,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.AnchorElement;
|
||||
import com.google.gwt.dom.client.DivElement;
|
||||
import com.google.gwt.dom.client.HeadingElement;
|
||||
import com.google.gwt.dom.client.SpanElement;
|
||||
@@ -13,6 +14,7 @@ import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
import com.google.gwt.uibinder.client.UiHandler;
|
||||
import com.google.gwt.user.client.Event;
|
||||
import com.google.gwt.user.client.EventListener;
|
||||
import com.google.gwt.user.client.ui.Anchor;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.Image;
|
||||
@@ -68,6 +70,8 @@ public class Regatta extends Composite {
|
||||
@UiField Anchor regattaDetailsLink;
|
||||
|
||||
@UiField Image boatClassImage;
|
||||
@UiField
|
||||
AnchorElement boatClassLinkUi;
|
||||
|
||||
private Presenter presenter;
|
||||
|
||||
@@ -83,6 +87,7 @@ public class Regatta extends Composite {
|
||||
RegattaResources.INSTANCE.css().ensureInjected();
|
||||
|
||||
initWidget(uiBinder.createAndBindUi(this));
|
||||
|
||||
}
|
||||
|
||||
public void setData(LeaderboardGroupDTO leaderboardGroup, boolean hasMultipleLeaderboardGroups, StrippedLeaderboardDTO leaderboard,
|
||||
@@ -95,6 +100,17 @@ public class Regatta extends Composite {
|
||||
} else {
|
||||
regattaNavigation = presenter.getRegattaNavigation(leaderboard.regattaName != null ? leaderboard.regattaName : leaderboard.name);
|
||||
regattaDetailsLink.setHref(regattaNavigation.getTargetUrl());
|
||||
boatClassLinkUi.setHref(regattaNavigation.getTargetUrl());
|
||||
Event.sinkEvents(boatClassLinkUi, Event.ONCLICK);
|
||||
Event.setEventListener(boatClassLinkUi, new EventListener() {
|
||||
@Override
|
||||
public void onBrowserEvent(Event event) {
|
||||
if (LinkUtil.handleLinkClick(event)) {
|
||||
event.preventDefault();
|
||||
regattaNavigation.goToPlace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
boolean hasLiveRace = leaderboard.hasLiveRace(presenter.getTimerForClientServerOffset().getLiveTimePointInMillis());
|
||||
|
||||
+2
-2
@@ -11,9 +11,9 @@
|
||||
<div class="{res.mediaCss.grid}">
|
||||
<div class="{res.mediaCss.small12} {res.mediaCss.columns}">
|
||||
<div class="{local_res.css.regatta_intro}">
|
||||
<div>
|
||||
<a ui:field="boatClassLinkUi" style="display:block;">
|
||||
<g:Image ui:field="boatClassImage" height="140" width="140" styleName="{local_res.css.regatta_intro_image}"></g:Image>
|
||||
</div>
|
||||
</a>
|
||||
<div class="{local_res.css.regatta_intro_header}">
|
||||
<div class="{res.mediaCss.grid}">
|
||||
<div class="{res.mediaCss.small4} {res.mediaCss.columns}">
|
||||
|
||||
+1
-1
@@ -1,11 +1,11 @@
|
||||
.message {
|
||||
font-size: 1rem;
|
||||
margin-top: 2em;
|
||||
line-height: 1.733333333333333em;
|
||||
background: #f2f2f2;
|
||||
border: 1px solid #dedede;
|
||||
border-radius: 0.333333333333333em;
|
||||
padding: 1.066666666666667em 2.533333333333333em 1.066666666666667em 2.733333333333333em;
|
||||
margin-bottom: 1.333333333333333em;
|
||||
}
|
||||
.message img {
|
||||
display: inline-block;
|
||||
|
||||
+1
@@ -322,6 +322,7 @@ public abstract class AbstractRaceList<T extends RaceMetadataDTO> extends Compos
|
||||
public void render(Context context, SimpleWindDTO value, SafeHtmlBuilder sb) {
|
||||
if (value != null) {
|
||||
SafeStylesBuilder safeStyles = new SafeStylesBuilder();
|
||||
safeStyles.trustedNameAndValue("-webkit-transform", "rotate(" + value.getTrueWindFromDeg() + "deg)");
|
||||
safeStyles.trustedNameAndValue("transform", "rotate(" + value.getTrueWindFromDeg() + "deg)");
|
||||
safeStyles.width(2.75, Unit.EM).height(2.75, Unit.EM);
|
||||
sb.append(TEMPLATE.windDirection(safeStyles.toSafeStyles()));
|
||||
|
||||
-1
@@ -36,7 +36,6 @@
|
||||
font-size: 1rem;
|
||||
height: 28.333333333333332em;
|
||||
position: relative;
|
||||
margin-top: 1.333333333333333em;
|
||||
}
|
||||
@media (max-width: 976px) {
|
||||
.video {
|
||||
|
||||
+6
-3
@@ -15,7 +15,6 @@ import com.sap.sailing.gwt.home.client.place.event.regatta.RegattaTabView;
|
||||
import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.reload.RefreshManager;
|
||||
import com.sap.sailing.gwt.ui.shared.dispatch.event.GetEventOverviewStageAction;
|
||||
import com.sap.sailing.gwt.ui.shared.dispatch.event.GetLiveRacesForRegattaAction;
|
||||
import com.sap.sailing.gwt.ui.shared.eventview.EventViewDTO.EventType;
|
||||
|
||||
/**
|
||||
* Created by pgtaboada on 25.11.14.
|
||||
@@ -32,8 +31,12 @@ public class RegattaOverviewTabView extends Composite implements RegattaTabView<
|
||||
|
||||
@Override
|
||||
public TabView.State getState() {
|
||||
return currentPresenter.getCtx().getEventDTO().getType() == EventType.MULTI_REGATTA ? TabView.State.NOT_AVAILABLE_SHOW_NEXT_AVAILABLE
|
||||
: TabView.State.VISIBLE;
|
||||
// Made not available until we have something to show
|
||||
// TODO: implement backend and required UI
|
||||
// return currentPresenter.getCtx().getEventDTO().getType() == EventType.MULTI_REGATTA ?
|
||||
// TabView.State.NOT_AVAILABLE_SHOW_NEXT_AVAILABLE
|
||||
// : TabView.State.VISIBLE;
|
||||
return TabView.State.NOT_AVAILABLE_SHOW_NEXT_AVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-1
@@ -3,6 +3,7 @@ package com.sap.sailing.gwt.home.client.shared.dispatch;
|
||||
import java.util.Date;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.i18n.client.LocaleInfo;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.rpc.ServiceDefTarget;
|
||||
import com.sap.sailing.gwt.ui.client.RemoteServiceMappingConstants;
|
||||
@@ -32,7 +33,7 @@ public class SimpleDispatch implements DispatchAsync {
|
||||
|
||||
@Override
|
||||
public <R extends Result, A extends Action<R>> void execute(A action, final AsyncCallback<R> callback) {
|
||||
dispatchRPC.execute(new RequestWrapper<R, A>(action), new AsyncCallback<ResultWrapper<R>>() {
|
||||
dispatchRPC.execute(new RequestWrapper<R, A>(action, LocaleInfo.getCurrentLocale().getLocaleName()), new AsyncCallback<ResultWrapper<R>>() {
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
|
||||
+72
-23
@@ -1,14 +1,17 @@
|
||||
package com.sap.sailing.gwt.home.client.shared.footer;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.DivElement;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.logical.shared.ValueChangeEvent;
|
||||
import com.google.gwt.http.client.UrlBuilder;
|
||||
import com.google.gwt.i18n.client.LocaleInfo;
|
||||
import com.google.gwt.text.shared.Renderer;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
import com.google.gwt.uibinder.client.UiHandler;
|
||||
@@ -16,11 +19,13 @@ import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.Window.Location;
|
||||
import com.google.gwt.user.client.ui.Anchor;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.ValueListBox;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator;
|
||||
import com.sap.sailing.gwt.home.client.app.PlaceNavigation;
|
||||
import com.sap.sailing.gwt.home.client.place.whatsnew.WhatsNewPlace;
|
||||
import com.sap.sailing.gwt.home.client.place.whatsnew.WhatsNewPlace.WhatsNewNavigationTabs;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
|
||||
public class Footer extends Composite {
|
||||
private static FooterPanelUiBinder uiBinder = GWT.create(FooterPanelUiBinder.class);
|
||||
@@ -30,17 +35,32 @@ public class Footer extends Composite {
|
||||
|
||||
@UiField Anchor changeLanguageLink;
|
||||
@UiField DivElement languageSelectionDiv;
|
||||
@UiField(provided = true) ValueListBox<Pair<String, String>> changeLanguageList = new ValueListBox<Pair<String,String>>(new Renderer<Pair<String, String>>() {
|
||||
@Override
|
||||
public String render(Pair<String, String> object) {
|
||||
if(object == null) {
|
||||
return "";
|
||||
}
|
||||
if(object.getB() != null) {
|
||||
return object.getB();
|
||||
}
|
||||
return object.getA();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Pair<String, String> object, Appendable appendable) throws IOException {
|
||||
appendable.append(render(object));
|
||||
}
|
||||
});
|
||||
|
||||
private String otherLanguage;
|
||||
private final LocaleInfo currentLocale = LocaleInfo.getCurrentLocale();
|
||||
|
||||
private final Map<String, String> localeAndLanguages;
|
||||
|
||||
@UiField(provided = true)
|
||||
final PlaceNavigation<WhatsNewPlace> releaseNotesNavigation;
|
||||
|
||||
public Footer(final HomePlacesNavigator navigator) {
|
||||
localeAndLanguages = new HashMap<String, String>();
|
||||
localeAndLanguages.put("en", "English");
|
||||
localeAndLanguages.put("de", "Deutsch");
|
||||
|
||||
FooterResources.INSTANCE.css().ensureInjected();
|
||||
releaseNotesNavigation = navigator.getWhatsNewNavigation(WhatsNewNavigationTabs.SailingAnalytics);
|
||||
|
||||
@@ -51,26 +71,55 @@ public class Footer extends Composite {
|
||||
|
||||
@UiHandler("changeLanguageLink")
|
||||
public void changeLanguage(ClickEvent e) {
|
||||
String selectedLanguage = changeLanguageLink.getText();
|
||||
String selectedLocale = null;
|
||||
for (Entry<String, String> entry: localeAndLanguages.entrySet()) {
|
||||
if (entry.getValue().equals(selectedLanguage)) {
|
||||
selectedLocale = entry.getKey();
|
||||
}
|
||||
if(otherLanguage != null) {
|
||||
UrlBuilder builder = Location.createUrlBuilder().setParameter("locale", otherLanguage);
|
||||
Window.Location.replace(builder.buildString());
|
||||
}
|
||||
if(selectedLocale != null) {
|
||||
UrlBuilder builder = Location.createUrlBuilder().setParameter("locale", selectedLocale);
|
||||
Window.Location.replace(builder.buildString());
|
||||
}
|
||||
|
||||
@UiHandler("changeLanguageList")
|
||||
void onListSelection(ValueChangeEvent<Pair<String, String>> event) {
|
||||
String selectedLocaleName = event.getValue().getA();
|
||||
if(!currentLocale.getLocaleName().equals(selectedLocaleName)) {
|
||||
UrlBuilder builder = Location.createUrlBuilder().setParameter("locale", selectedLocaleName);
|
||||
Window.Location.replace(builder.buildString());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateUI() {
|
||||
LocaleInfo currentLocale = LocaleInfo.getCurrentLocale();
|
||||
HashMap<String, String> languagesToSelectFrom = new HashMap<String, String>(localeAndLanguages);
|
||||
languagesToSelectFrom.remove(currentLocale.getLocaleName());
|
||||
|
||||
if(languagesToSelectFrom.size() == 1) {
|
||||
changeLanguageLink.setText(languagesToSelectFrom.values().iterator().next());
|
||||
Set<String> availableLocales = new HashSet<String>(Arrays.asList(LocaleInfo.getAvailableLocaleNames()));
|
||||
availableLocales.remove("default");
|
||||
|
||||
if(availableLocales.size() <= 1) {
|
||||
// only current language (or removed default) available
|
||||
changeLanguageLink.removeFromParent();
|
||||
changeLanguageList.removeFromParent();
|
||||
languageSelectionDiv.removeFromParent();
|
||||
return;
|
||||
}
|
||||
if(availableLocales.size() == 2) {
|
||||
changeLanguageList.removeFromParent();
|
||||
// current language + one we can switch to
|
||||
for(String localeName : availableLocales) {
|
||||
if(!currentLocale.getLocaleName().equals(localeName)) {
|
||||
otherLanguage = localeName;
|
||||
changeLanguageLink.setText(LocaleInfo.getLocaleNativeDisplayName(otherLanguage));
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
changeLanguageLink.removeFromParent();
|
||||
Set<Pair<String, String>> values = new HashSet<>();
|
||||
Pair<String, String> selectedValue = null;
|
||||
for(String localeName : availableLocales) {
|
||||
Pair<String, String> value = new Pair<String, String>(localeName, LocaleInfo.getLocaleNativeDisplayName(localeName));
|
||||
values.add(value);
|
||||
if(currentLocale.getLocaleName().equals(localeName)) {
|
||||
selectedValue = value;
|
||||
}
|
||||
}
|
||||
changeLanguageList.setValue(selectedValue);
|
||||
changeLanguageList.setAcceptableValues(values);
|
||||
}
|
||||
}
|
||||
+28
@@ -5,6 +5,33 @@
|
||||
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
|
||||
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.shared.footer.FooterResources" />
|
||||
<ui:with field="releaseNotesNavigation" type="com.sap.sailing.gwt.home.client.app.PlaceNavigation" />
|
||||
<ui:style gss="true">
|
||||
.languageSelect::-ms-expand {
|
||||
display: none;
|
||||
}
|
||||
.languageSelect {
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
-ms-appearance: none;
|
||||
appearance: none;
|
||||
|
||||
margin-top: 25px;
|
||||
color: #efaa00;
|
||||
line-height: 1.5em;
|
||||
height: 1.5em;
|
||||
display: inline-block;
|
||||
border: transparent;
|
||||
cursor: pointer;
|
||||
padding-right: 1.2em;
|
||||
background: #333;
|
||||
cursor: pointer;
|
||||
|
||||
background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZlcnNpb249JzEuMScgaGVpZ2h0PScxOHB4JyB3aWR0aD0nMTZweCc+PHRleHQgeD0nMCcgeT0nMTUnIGZpbGw9JyNlZmFhMDAnIGZvbnQtc2l6ZT0nMTYnPiYjOTY2MDs8L3RleHQ+PC9zdmc+");
|
||||
background-position: right center;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
}
|
||||
</ui:style>
|
||||
<g:HTMLPanel tag="footer" addStyleNames="{local_res.css.sitefooter}">
|
||||
<!-- Website footer-->
|
||||
<div class="{res.mediaCss.grid}">
|
||||
@@ -33,6 +60,7 @@
|
||||
<div ui:field="languageSelectionDiv" class="{res.mediaCss.small12} {res.mediaCss.medium3} {res.mediaCss.columns} {local_res.css.sitefooter_language}">
|
||||
<span><ui:text from='{i18n.footerLanguage}' />:</span>
|
||||
<g:Anchor ui:field="changeLanguageLink" styleName="{local_res.css.sitefooter_language_link}" />
|
||||
<g:ValueListBox addStyleNames="{style.languageSelect}" ui:field="changeLanguageList" />
|
||||
</div>
|
||||
</div>
|
||||
</g:HTMLPanel>
|
||||
|
||||
+10
-8
@@ -12,8 +12,9 @@ import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.HTMLPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.gwt.home.client.app.PlaceNavigator;
|
||||
import com.sap.sailing.gwt.ui.shared.media.ImageMetadataDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.media.VideoMetadataDTO;
|
||||
import com.sap.sailing.gwt.home.client.shared.media.SailingFullscreenViewer;
|
||||
import com.sap.sailing.gwt.ui.shared.media.SailingImageDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.media.SailingVideoDTO;
|
||||
import com.sap.sse.gwt.client.controls.carousel.ImageCarousel;
|
||||
|
||||
public class MainMedia extends Composite {
|
||||
@@ -27,7 +28,7 @@ public class MainMedia extends Composite {
|
||||
DivElement videoLightBoxData;
|
||||
|
||||
@UiField
|
||||
ImageCarousel imageCarousel;
|
||||
ImageCarousel<SailingImageDTO> imageCarousel;
|
||||
|
||||
interface MainMediaUiBinder extends UiBinder<Widget, MainMedia> {
|
||||
}
|
||||
@@ -37,20 +38,21 @@ public class MainMedia extends Composite {
|
||||
public MainMedia(PlaceNavigator navigator) {
|
||||
MainMediaResources.INSTANCE.css().ensureInjected();
|
||||
initWidget(uiBinder.createAndBindUi(this));
|
||||
imageCarousel.registerFullscreenViewer(new SailingFullscreenViewer());
|
||||
}
|
||||
|
||||
public void setData(Collection<VideoMetadataDTO> videos, ArrayList<ImageMetadataDTO> photos) {
|
||||
Iterator<VideoMetadataDTO> videoIterator = videos.iterator();
|
||||
public void setData(Collection<SailingVideoDTO> videos, ArrayList<SailingImageDTO> photos) {
|
||||
Iterator<SailingVideoDTO> videoIterator = videos.iterator();
|
||||
int videoCount = 0;
|
||||
while(videoCount < MAX_VIDEO_COUNT && videoIterator.hasNext()) {
|
||||
VideoMetadataDTO videoDTO = videoIterator.next();
|
||||
SailingVideoDTO videoDTO = videoIterator.next();
|
||||
MainMediaVideo video = new MainMediaVideo(videoDTO.getTitle(), videoDTO.getSourceRef(),
|
||||
videoDTO.getMimeType());
|
||||
videosPanel.add(video);
|
||||
videoCount++;
|
||||
}
|
||||
for (ImageMetadataDTO image : photos) {
|
||||
imageCarousel.addImage(image.getSourceRef(), image.getHeightInPx(), image.getWidthInPx());
|
||||
for (SailingImageDTO image : photos) {
|
||||
imageCarousel.addImage(image);
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -9,10 +9,10 @@ import com.google.gwt.uibinder.client.UiField;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.HTMLPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.media.MimeType;
|
||||
import com.sap.sailing.gwt.home.client.shared.LongNamesUtil;
|
||||
import com.sap.sailing.gwt.ui.client.media.VideoJSPlayer;
|
||||
import com.sap.sailing.gwt.ui.shared.media.VideoMetadataDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.media.SailingVideoDTO;
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
|
||||
public class MainMediaVideo extends Composite {
|
||||
|
||||
@@ -64,7 +64,7 @@ public class MainMediaVideo extends Composite {
|
||||
|
||||
}
|
||||
|
||||
public void show(VideoMetadataDTO videoCandidateInfo) {
|
||||
public void show(SailingVideoDTO videoCandidateInfo) {
|
||||
vJs.setSource(videoCandidateInfo.getSourceRef(), videoCandidateInfo.getMimeType());
|
||||
|
||||
}
|
||||
|
||||
+6
-6
@@ -17,9 +17,9 @@ import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.client.media.GalleryImageHolder;
|
||||
import com.sap.sailing.gwt.ui.client.media.VideoJSPlayer;
|
||||
import com.sap.sailing.gwt.ui.client.media.VideoThumbnail;
|
||||
import com.sap.sailing.gwt.ui.shared.media.ImageMetadataDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.media.MediaDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.media.VideoMetadataDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.media.SailingImageDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.media.SailingVideoDTO;
|
||||
|
||||
public class MediaPage extends Composite {
|
||||
private static MediaPageUiBinder uiBinder = GWT.create(MediaPageUiBinder.class);
|
||||
@@ -85,7 +85,7 @@ public class MediaPage extends Composite {
|
||||
break;
|
||||
}
|
||||
|
||||
for (final ImageMetadataDTO holder : media.getPhotos()) {
|
||||
for (final SailingImageDTO holder : media.getPhotos()) {
|
||||
if (holder.getSourceRef() != null) {
|
||||
|
||||
GalleryImageHolder gih = new GalleryImageHolder(holder);
|
||||
@@ -96,7 +96,7 @@ public class MediaPage extends Composite {
|
||||
gih.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
new FullscreenViewer(holder, media.getPhotos());
|
||||
new SailingFullscreenViewer().show(holder, media.getPhotos());
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -113,7 +113,7 @@ public class MediaPage extends Composite {
|
||||
videoListOuterBoxUi.addClassName(res.mediaCss().large3());
|
||||
}
|
||||
boolean first = true;
|
||||
for (final VideoMetadataDTO videoCandidateInfo : media.getVideos()) {
|
||||
for (final SailingVideoDTO videoCandidateInfo : media.getVideos()) {
|
||||
if (first) {
|
||||
putVideoOnDisplay(videoCandidateInfo, false);
|
||||
first = false;
|
||||
@@ -137,7 +137,7 @@ public class MediaPage extends Composite {
|
||||
}
|
||||
}
|
||||
|
||||
private void putVideoOnDisplay(final VideoMetadataDTO videoCandidateInfo, boolean autoplay) {
|
||||
private void putVideoOnDisplay(final SailingVideoDTO videoCandidateInfo, boolean autoplay) {
|
||||
videoDisplayUi = new VideoJSPlayer(true, autoplay);
|
||||
videoDisplayUi.setSource(videoCandidateInfo.getSourceRef(), videoCandidateInfo.getMimeType());
|
||||
videoDisplayHolderUi.setWidget(videoDisplayUi);
|
||||
|
||||
+6
-4
@@ -15,9 +15,10 @@ import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.ui.PopupPanel;
|
||||
import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
|
||||
import com.google.gwt.user.client.ui.RootPanel;
|
||||
import com.sap.sailing.gwt.ui.shared.media.ImageMetadataDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.media.SailingImageDTO;
|
||||
import com.sap.sse.gwt.client.controls.carousel.ImageCarousel.FullscreenViewer;
|
||||
|
||||
public class FullscreenViewer {
|
||||
public class SailingFullscreenViewer implements FullscreenViewer<SailingImageDTO> {
|
||||
private PopupPanel popup = new PopupPanel(true) {
|
||||
protected void onPreviewNativeEvent(NativePreviewEvent event) {
|
||||
if (event.getTypeInt() == Event.ONKEYDOWN && event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ESCAPE) {
|
||||
@@ -26,8 +27,8 @@ public class FullscreenViewer {
|
||||
};
|
||||
};
|
||||
|
||||
public FullscreenViewer(ImageMetadataDTO selected, List<ImageMetadataDTO> images) {
|
||||
final GalleryPlayer viewer = new GalleryPlayer(selected, images);
|
||||
public void show(SailingImageDTO selected, List<SailingImageDTO> images) {
|
||||
final SailingGalleryPlayer viewer = new SailingGalleryPlayer(selected, images);
|
||||
|
||||
Window.addResizeHandler(new ResizeHandler() {
|
||||
@Override
|
||||
@@ -63,4 +64,5 @@ public class FullscreenViewer {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
+9
-9
@@ -15,14 +15,14 @@ import com.google.gwt.uibinder.client.UiHandler;
|
||||
import com.google.gwt.user.client.Command;
|
||||
import com.google.gwt.user.client.ui.ResizeComposite;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.gwt.ui.shared.media.ImageMetadataDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.media.SailingImageDTO;
|
||||
import com.sap.sse.gwt.client.controls.carousel.ImageCarousel;
|
||||
|
||||
public class GalleryPlayer extends ResizeComposite {
|
||||
private static GalleryPlayerUiBinder uiBinder = GWT.create(GalleryPlayerUiBinder.class);
|
||||
public class SailingGalleryPlayer extends ResizeComposite {
|
||||
private static MyBinder uiBinder = GWT.create(MyBinder.class);
|
||||
private Command closeCommand;
|
||||
|
||||
interface GalleryPlayerUiBinder extends UiBinder<Widget, GalleryPlayer> {
|
||||
interface MyBinder extends UiBinder<Widget, SailingGalleryPlayer> {
|
||||
}
|
||||
|
||||
@UiField
|
||||
@@ -30,19 +30,19 @@ public class GalleryPlayer extends ResizeComposite {
|
||||
@UiField
|
||||
DivElement subSliderUi;
|
||||
|
||||
ImageCarousel carousel = new ImageCarousel();
|
||||
ImageCarousel<SailingImageDTO> carousel = new ImageCarousel<>();
|
||||
private int selectedIdx;
|
||||
|
||||
public GalleryPlayer(ImageMetadataDTO selected, List<ImageMetadataDTO> images) {
|
||||
public SailingGalleryPlayer(SailingImageDTO selected, List<SailingImageDTO> images) {
|
||||
initWidget(uiBinder.createAndBindUi(this));
|
||||
selectedIdx = Math.max(selectedIdx, images.indexOf(selected));
|
||||
for (ImageMetadataDTO i : images) {
|
||||
for (SailingImageDTO i : images) {
|
||||
mainSliderUi.appendChild(createMainImgElement(i));
|
||||
subSliderUi.appendChild(createThumbImgElement(i));
|
||||
}
|
||||
}
|
||||
|
||||
private ImageElement createThumbImgElement(ImageMetadataDTO i ) {
|
||||
private ImageElement createThumbImgElement(SailingImageDTO i ) {
|
||||
ImageElement img = Document.get().createImageElement();
|
||||
img.setAttribute("src", i.getSourceRef());
|
||||
img.setHeight(100);
|
||||
@@ -50,7 +50,7 @@ public class GalleryPlayer extends ResizeComposite {
|
||||
return img;
|
||||
}
|
||||
|
||||
private DivElement createMainImgElement(ImageMetadataDTO i) {
|
||||
private DivElement createMainImgElement(SailingImageDTO i) {
|
||||
DivElement img = Document.get().createDivElement();
|
||||
img.getStyle().setBackgroundImage("url(\"" + i.getSourceRef() + "\")");
|
||||
img.getStyle().setProperty("backgroundSize", "contain");
|
||||
+7
-7
@@ -31,26 +31,26 @@
|
||||
}
|
||||
.toolbar {
|
||||
text-align: right;
|
||||
padding: 10px;
|
||||
padding: 10px 20px 10px 10px;
|
||||
|
||||
}
|
||||
.content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
}
|
||||
.close {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
|
||||
}
|
||||
.subcontent {
|
||||
border-top: 1px solid #ebebeb;
|
||||
|
||||
|
||||
|
||||
}
|
||||
</ui:style>
|
||||
<g:LayoutPanel styleName="{style.fs-background}">
|
||||
<g:layer top="0" height="50">
|
||||
<g:FlowPanel styleName="{style.toolbar}">
|
||||
<g:Button ui:field="closeUi">CLOSE</g:Button>
|
||||
<g:Image url="images/home/close.svg" styleName="{style.close}" ui:field="closeUi"></g:Image>
|
||||
</g:FlowPanel>
|
||||
</g:layer>
|
||||
<g:layer top="50" bottom="150">
|
||||
@@ -63,7 +63,7 @@
|
||||
<g:layer height="120" bottom="0">
|
||||
<g:HTMLPanel styleName="{style.subcontent}">
|
||||
<div class="subSlider {style.subSlider}" ui:field="subSliderUi">
|
||||
|
||||
|
||||
</div>
|
||||
</g:HTMLPanel>
|
||||
</g:layer>
|
||||
+1
-1
@@ -92,7 +92,7 @@ public abstract class StageTeaser extends Composite implements LazyLoadable {
|
||||
return;
|
||||
}
|
||||
Element element = eventTarget.cast();
|
||||
if (stageTeaserBandsPanel.getElement().isOrHasChild(element)) {
|
||||
if (bandCount.isOrHasChild(element)) {
|
||||
return;
|
||||
}
|
||||
handleUserAction();
|
||||
|
||||
+2
@@ -389,6 +389,7 @@ public class RegattaRaceStatesComponent extends SimplePanel implements Component
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private void createColumns() {
|
||||
regattaOverviewListHandler = new ListHandler<RegattaOverviewEntryDTO>(regattaOverviewDataProvider.getList());
|
||||
courseAreaColumn = new TextColumn<RegattaOverviewEntryDTO>() {
|
||||
@@ -568,6 +569,7 @@ public class RegattaRaceStatesComponent extends SimplePanel implements Component
|
||||
tooltip);
|
||||
}
|
||||
};
|
||||
flagColumn.setCellStyleNames(tableRes.cellTableStyle().flagColumn());
|
||||
boatClass = new TextColumn<RegattaOverviewEntryDTO>() {
|
||||
@Override
|
||||
public String getValue(RegattaOverviewEntryDTO entryDTO) {
|
||||
|
||||
+98
-89
@@ -1,90 +1,99 @@
|
||||
.cellTableWidget {
|
||||
border-spacing: 0px;
|
||||
font-size:16px;
|
||||
}
|
||||
.cellTableWidget a {
|
||||
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
/** v-align images in the table header
|
||||
* grey background for table header
|
||||
*/
|
||||
.cellTableHeader {
|
||||
position: relative;
|
||||
vertical-align: bottom;
|
||||
background-color: #f2f2f2;
|
||||
background-color: #fff;
|
||||
padding: 20px 5px;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid black;
|
||||
text-shadow: none;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.cellTableHeader:FOCUS {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.cellTableFirstColumnHeader {
|
||||
|
||||
}
|
||||
|
||||
.cellTableLastColumnHeader {
|
||||
|
||||
}
|
||||
|
||||
.cellTableHeader>span>img:first-child {
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.cellTableEvenRow {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.cellTableEvenRowCell {
|
||||
border: none;
|
||||
border-bottom: 1px solid #dedede;
|
||||
padding: 20px 5px 20px 10px;
|
||||
vertical-align: top;
|
||||
|
||||
}
|
||||
|
||||
.cellTableOddRow {
|
||||
background-color: #fdfdfd;
|
||||
}
|
||||
|
||||
.cellTableOddRowCell {
|
||||
border: none;
|
||||
border-bottom: 1px solid #dedede;
|
||||
padding: 20px 5px 20px 10px;
|
||||
vertical-align: top;
|
||||
|
||||
}
|
||||
|
||||
.cellTableHoveredRow {
|
||||
background-color: rgba(229, 242, 249, 0.5);
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.cellTableSelectedRow {
|
||||
color: #000000;
|
||||
background-color: rgba(229, 242, 249, 0.5);
|
||||
}
|
||||
|
||||
.cellTableSelectedRowCell {
|
||||
border-top: 2px solid #21a0e4 !important;
|
||||
border-bottom: 2px solid #21a0e4 !important;
|
||||
}
|
||||
|
||||
.cellTableRaceNameColumnHeader {
|
||||
background-color: #e0e0e0;
|
||||
padding: 5px 20px;
|
||||
}
|
||||
|
||||
.cellTableRaceNameColumn {
|
||||
background-color: #e0e0e0 !important;
|
||||
.cellTableWidget {
|
||||
border-spacing: 0px;
|
||||
font-size:16px;
|
||||
}
|
||||
.cellTableWidget a {
|
||||
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
/** v-align images in the table header
|
||||
* grey background for table header
|
||||
*/
|
||||
.cellTableHeader {
|
||||
position: relative;
|
||||
vertical-align: bottom;
|
||||
background-color: #f2f2f2;
|
||||
background-color: #fff;
|
||||
padding: 15px 5px;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid black;
|
||||
text-shadow: none;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.cellTableHeader:FOCUS {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.cellTableFirstColumnHeader {
|
||||
|
||||
}
|
||||
|
||||
.cellTableLastColumnHeader {
|
||||
|
||||
}
|
||||
|
||||
.cellTableHeader>span>img:first-child {
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.cellTableEvenRow {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.cellTableEvenRowCell {
|
||||
border: none;
|
||||
border-bottom: 1px solid #dedede;
|
||||
padding: 15px 5px 15px 10px;
|
||||
vertical-align: top;
|
||||
|
||||
}
|
||||
|
||||
.cellTableOddRow {
|
||||
background-color: #fdfdfd;
|
||||
}
|
||||
|
||||
.cellTableOddRowCell {
|
||||
border: none;
|
||||
border-bottom: 1px solid #dedede;
|
||||
padding: 15px 5px 15px 10px;
|
||||
vertical-align: top;
|
||||
|
||||
}
|
||||
|
||||
.cellTableHoveredRow {
|
||||
background-color: rgba(229, 242, 249, 0.5);
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.cellTableSelectedRow {
|
||||
color: #000000;
|
||||
background-color: rgba(229, 242, 249, 0.5);
|
||||
}
|
||||
|
||||
.cellTableSelectedRowCell {
|
||||
border-top: 2px solid #21a0e4 !important;
|
||||
border-bottom: 2px solid #21a0e4 !important;
|
||||
}
|
||||
|
||||
.cellTableRaceNameColumnHeader {
|
||||
background-color: #e0e0e0;
|
||||
padding: 5px 20px;
|
||||
}
|
||||
|
||||
.cellTableRaceNameColumn {
|
||||
background-color: #e0e0e0 !important;
|
||||
}
|
||||
|
||||
.flagColumn {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.flagColumn>div {
|
||||
display: inline-block;
|
||||
}
|
||||
+24
-22
@@ -1,22 +1,24 @@
|
||||
package com.sap.sailing.gwt.regattaoverview.client;
|
||||
|
||||
import com.google.gwt.user.cellview.client.CellTable;
|
||||
|
||||
public interface RegattaRaceStatesTableResources extends CellTable.Resources {
|
||||
interface AdminConsoleTableStyle extends CellTable.Style {
|
||||
/**
|
||||
* Applied to header cells of race columns
|
||||
*/
|
||||
String cellTableRaceNameColumnHeader();
|
||||
|
||||
/**
|
||||
* Applied to the totals columns
|
||||
*/
|
||||
String cellTableRaceNameColumn();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@Source({ CellTable.Style.DEFAULT_CSS, "RegattaRaceStatesTable.css" })
|
||||
AdminConsoleTableStyle cellTableStyle();
|
||||
}
|
||||
package com.sap.sailing.gwt.regattaoverview.client;
|
||||
|
||||
import com.google.gwt.user.cellview.client.CellTable;
|
||||
|
||||
public interface RegattaRaceStatesTableResources extends CellTable.Resources {
|
||||
interface AdminConsoleTableStyle extends CellTable.Style {
|
||||
/**
|
||||
* Applied to header cells of race columns
|
||||
*/
|
||||
String cellTableRaceNameColumnHeader();
|
||||
|
||||
/**
|
||||
* Applied to the totals columns
|
||||
*/
|
||||
String cellTableRaceNameColumn();
|
||||
|
||||
String flagColumn();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@Source({ CellTable.Style.DEFAULT_CSS, "RegattaRaceStatesTable.css" })
|
||||
AdminConsoleTableStyle cellTableStyle();
|
||||
}
|
||||
Executable → Regular
-7
@@ -20,13 +20,6 @@ public class SailingFlagsBuilder {
|
||||
private final static FlagImageResolver flagImageResolver = new FlagImageResolver();
|
||||
|
||||
interface SailingFlagsTemplates extends SafeHtmlTemplates {
|
||||
/**
|
||||
* @param title
|
||||
* the tool-tip to display for the image on mouse-over
|
||||
* @param upperFlag
|
||||
* how to render the image; this needs to be an <img> tag, not enclosed by any other element,
|
||||
* as returned by {@link ImagesBarCell#makeImagePrototype(ImageResource)}
|
||||
*/
|
||||
@SafeHtmlTemplates.Template("<div title=\"{0}\">{1}</div>")
|
||||
SafeHtml cell(String title, SafeHtml content);
|
||||
|
||||
|
||||
+25
-17
@@ -25,9 +25,6 @@ import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.EventBase;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.base.RemoteSailingServerReference;
|
||||
import com.sap.sailing.domain.common.ImageSize;
|
||||
import com.sap.sailing.domain.common.media.MediaType;
|
||||
import com.sap.sailing.domain.common.media.MimeType;
|
||||
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
@@ -45,10 +42,10 @@ import com.sap.sailing.gwt.ui.shared.fakeseries.EventSeriesViewDTO.EventSeriesSt
|
||||
import com.sap.sailing.gwt.ui.shared.general.EventMetadataDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.general.EventReferenceDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.general.EventState;
|
||||
import com.sap.sailing.gwt.ui.shared.media.ImageMetadataDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.media.MediaDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.media.MediaUtils;
|
||||
import com.sap.sailing.gwt.ui.shared.media.VideoMetadataDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.media.SailingImageDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.media.SailingVideoDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.start.EventStageDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.start.StageEventType;
|
||||
import com.sap.sailing.gwt.ui.shared.start.StartViewDTO;
|
||||
@@ -60,6 +57,9 @@ import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.impl.TimeRangeImpl;
|
||||
import com.sap.sse.common.media.ImageSize;
|
||||
import com.sap.sse.common.media.MediaType;
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
import com.sap.sse.util.ServiceTrackerFactory;
|
||||
|
||||
/**
|
||||
@@ -189,8 +189,10 @@ public class HomeServiceImpl extends ProxiedRemoteServiceServlet implements Home
|
||||
|
||||
MimeType type = MediaUtils.detectMimeTypeFromUrl(youTubeRandomUrl.toString());
|
||||
if (type.mediaType == MediaType.video) {
|
||||
VideoMetadataDTO candidate = new VideoMetadataDTO(eventRef, youTubeRandomUrl, type,
|
||||
holder.event.getName());
|
||||
SailingVideoDTO candidate = new SailingVideoDTO(eventRef, youTubeRandomUrl.toString(), type, //
|
||||
holder.event.getEndDate().asDate() // FIXME: using event enddate for now
|
||||
);
|
||||
candidate.setTitle(holder.event.getName());
|
||||
result.addVideo(candidate);
|
||||
}
|
||||
}
|
||||
@@ -203,9 +205,9 @@ public class HomeServiceImpl extends ProxiedRemoteServiceServlet implements Home
|
||||
}
|
||||
});
|
||||
|
||||
final Set<ImageMetadataDTO> photoGalleryUrls = new HashSet<>(); // using a HashSet here leads to a reasonable
|
||||
final Set<SailingImageDTO> photoGalleryUrls = new HashSet<>(); // using a HashSet here leads to a reasonable
|
||||
// amount of shuffling
|
||||
final List<VideoMetadataDTO> videoCandidates = new ArrayList<>();
|
||||
final List<SailingVideoDTO> videoCandidates = new ArrayList<>();
|
||||
|
||||
for(EventHolder holder : recentEventsOfLast12Month) {
|
||||
if(result.getRecentEvents().size() < MAX_RECENT_EVENTS) {
|
||||
@@ -220,7 +222,7 @@ public class HomeServiceImpl extends ProxiedRemoteServiceServlet implements Home
|
||||
ImageSize imageSize = event.getImageSize(url);
|
||||
if(imageSize != null) {
|
||||
// TODO: do we habe a title?
|
||||
photoGalleryUrls.add(new ImageMetadataDTO(eventRef, url, imageSize, null));
|
||||
photoGalleryUrls.add(new SailingImageDTO(eventRef, url.toString(), imageSize, null));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
@@ -229,7 +231,10 @@ public class HomeServiceImpl extends ProxiedRemoteServiceServlet implements Home
|
||||
|
||||
MimeType type = MediaUtils.detectMimeTypeFromUrl(videoUrl.toString());
|
||||
if (type.mediaType == MediaType.video) {
|
||||
VideoMetadataDTO candidate = new VideoMetadataDTO(eventRef, videoUrl, type, holder.event.getName());
|
||||
SailingVideoDTO candidate = new SailingVideoDTO(eventRef, videoUrl.toString(), type, //
|
||||
holder.event.getEndDate().asDate() // FIXME: using event enddate for now
|
||||
);
|
||||
candidate.setTitle(holder.event.getName());
|
||||
videoCandidates.add(candidate);
|
||||
}
|
||||
}
|
||||
@@ -238,7 +243,7 @@ public class HomeServiceImpl extends ProxiedRemoteServiceServlet implements Home
|
||||
final int numberOfCandidatesAvailable = videoCandidates.size();
|
||||
if (numberOfCandidatesAvailable <= (MAX_VIDEO_COUNT - result.getVideos().size())) {
|
||||
// add all we have, no randomize
|
||||
for (VideoMetadataDTO video : videoCandidates) {
|
||||
for (SailingVideoDTO video : videoCandidates) {
|
||||
result.addVideo(video);
|
||||
}
|
||||
} else {
|
||||
@@ -246,7 +251,7 @@ public class HomeServiceImpl extends ProxiedRemoteServiceServlet implements Home
|
||||
final Random videosRandomizer = new Random(numberOfCandidatesAvailable);
|
||||
randomlyPick: for (int i = 0; i < numberOfCandidatesAvailable; i++) {
|
||||
int nextVideoindex = videosRandomizer.nextInt(numberOfCandidatesAvailable);
|
||||
final VideoMetadataDTO video = videoCandidates.get(nextVideoindex);
|
||||
final SailingVideoDTO video = videoCandidates.get(nextVideoindex);
|
||||
result.addVideo(video);
|
||||
if (result.getVideos().size() == MAX_VIDEO_COUNT) {
|
||||
break randomlyPick;
|
||||
@@ -254,12 +259,12 @@ public class HomeServiceImpl extends ProxiedRemoteServiceServlet implements Home
|
||||
}
|
||||
}
|
||||
Random random = new Random();
|
||||
List<ImageMetadataDTO> shuffledPhotoGallery = new ArrayList<>(photoGalleryUrls);
|
||||
List<SailingImageDTO> shuffledPhotoGallery = new ArrayList<>(photoGalleryUrls);
|
||||
final int gallerySize = photoGalleryUrls.size();
|
||||
for (int i = 0; i < gallerySize; i++) {
|
||||
Collections.swap(shuffledPhotoGallery, i, random.nextInt(gallerySize));
|
||||
}
|
||||
for (ImageMetadataDTO holder : shuffledPhotoGallery) {
|
||||
for (SailingImageDTO holder : shuffledPhotoGallery) {
|
||||
result.addPhoto(holder);
|
||||
}
|
||||
// TODO media
|
||||
@@ -429,13 +434,16 @@ public class HomeServiceImpl extends ProxiedRemoteServiceServlet implements Home
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
logger.log(Level.FINE, "Was unable to obtain image size for "+url+" earlier.", e);
|
||||
}
|
||||
ImageMetadataDTO entry = new ImageMetadataDTO(eventRef, url, imageSize, eventName);
|
||||
SailingImageDTO entry = new SailingImageDTO(eventRef, url.toString(), imageSize, //
|
||||
event.getEndDate().asDate() // FIXME: using the event end date for now, we need a better solution for migration
|
||||
);
|
||||
entry.setTitle(eventName);
|
||||
media.addPhoto(entry);
|
||||
}
|
||||
for(URL url : event.getVideoURLs()) {
|
||||
MimeType type = MediaUtils.detectMimeTypeFromUrl(url.toString());
|
||||
if (type.mediaType == MediaType.video) {
|
||||
VideoMetadataDTO candidate = new VideoMetadataDTO(eventRef, url, type, null);
|
||||
SailingVideoDTO candidate = new SailingVideoDTO(eventRef, url.toString(), type, null);
|
||||
media.addVideo(candidate);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -19,7 +19,6 @@ import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.LeaderboardGroupBase;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.common.ImageSize;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
@@ -27,6 +26,7 @@ import com.sap.sailing.gwt.ui.shared.eventview.HasRegattaMetadata.RegattaState;
|
||||
import com.sap.sailing.gwt.ui.shared.eventview.RegattaMetadataDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.general.EventState;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.media.ImageSize;
|
||||
|
||||
public final class HomeServiceUtil {
|
||||
private HomeServiceUtil() {
|
||||
@@ -315,6 +315,9 @@ public final class HomeServiceUtil {
|
||||
boolean first = true;
|
||||
for (Iterator<URL> iter = imageURLs.iterator(); iter.hasNext(); ) {
|
||||
URL imageUrl = iter.next();
|
||||
if(imageUrl.toString().toLowerCase().contains(THUMBNAIL_IMAGE_URL_SUBSTRING_INDICATOR_CASE_INSENSITIVE)) {
|
||||
continue;
|
||||
}
|
||||
if ((first && !iter.hasNext()) || !Util.equalsWithNull(imageUrl, stageImageURL)) {
|
||||
result.add(imageUrl);
|
||||
}
|
||||
|
||||
+22
-22
@@ -45,7 +45,7 @@ public class DetailTypeFormatter {
|
||||
case GAP_TO_LEADER_IN_SECONDS:
|
||||
return stringMessages.gapToLeaderInSeconds();
|
||||
case CORRECTED_TIME_TRAVELED:
|
||||
return stringMessages.correctedTimeTraveled();
|
||||
return stringMessages.calculatedTimeTraveled();
|
||||
case GAP_CHANGE_SINCE_LEG_START_IN_SECONDS:
|
||||
return stringMessages.gapChangeSinceLegStartInSeconds();
|
||||
case SIDE_TO_WHICH_MARK_AT_LEG_START_WAS_ROUNDED:
|
||||
@@ -60,16 +60,16 @@ public class DetailTypeFormatter {
|
||||
return stringMessages.averageSpeedInKnots();
|
||||
case RACE_GAP_TO_LEADER_IN_SECONDS:
|
||||
return stringMessages.gapToLeaderInSeconds();
|
||||
case RACE_DISTANCE_TO_LEADER_IN_METERS:
|
||||
return stringMessages.windwardDistanceToLeaderInMeters();
|
||||
case RACE_DISTANCE_TO_COMPETITOR_FARTHEST_AHEAD_IN_METERS:
|
||||
return stringMessages.windwardDistanceToCompetitorFarthestAheadInMeters();
|
||||
case RACE_AVERAGE_ABSOLUTE_CROSS_TRACK_ERROR_IN_METERS:
|
||||
return stringMessages.averageAbsoluteCrossTrackErrorInMeters();
|
||||
case RACE_AVERAGE_SIGNED_CROSS_TRACK_ERROR_IN_METERS:
|
||||
return stringMessages.averageSignedCrossTrackErrorInMeters();
|
||||
case START_TACK:
|
||||
return stringMessages.startTack();
|
||||
case WINDWARD_DISTANCE_TO_OVERALL_LEADER:
|
||||
return stringMessages.windwardDistanceToLeaderInMeters();
|
||||
case WINDWARD_DISTANCE_TO_COMPETITOR_FARTHEST_AHEAD:
|
||||
return stringMessages.windwardDistanceToCompetitorFarthestAheadInMeters();
|
||||
case DISTANCE_TO_START_AT_RACE_START:
|
||||
return stringMessages.distanceToLineAtRaceStart();
|
||||
case TIME_BETWEEN_RACE_START_AND_COMPETITOR_START:
|
||||
@@ -128,10 +128,10 @@ public class DetailTypeFormatter {
|
||||
return stringMessages.speedOverGroundFiveSecondsBeforeStart();
|
||||
case RACE_TIME_TRAVELED:
|
||||
return stringMessages.time();
|
||||
case RACE_CORRECTED_TIME_TRAVELED:
|
||||
return stringMessages.correctedTimeTraveled();
|
||||
case RACE_CORRECTED_TIME_AT_ESTIMATED_ARRIVAL_AT_COMPETITOR_FARTHEST_AHEAD:
|
||||
return stringMessages.raceCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSeconds();
|
||||
case RACE_CALCULATED_TIME_TRAVELED:
|
||||
return stringMessages.calculatedTimeTraveled();
|
||||
case RACE_CALCULATED_TIME_AT_ESTIMATED_ARRIVAL_AT_COMPETITOR_FARTHEST_AHEAD:
|
||||
return stringMessages.raceCalculatedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSeconds();
|
||||
case RACE_TIME_TRAVELED_DOWNWIND:
|
||||
return stringMessages.timeDownwind();
|
||||
case RACE_TIME_TRAVELED_REACHING:
|
||||
@@ -170,11 +170,11 @@ public class DetailTypeFormatter {
|
||||
case RACE_SPEED_OVER_GROUND_FIVE_SECONDS_BEFORE_START:
|
||||
return stringMessages.knotsUnit();
|
||||
|
||||
case WINDWARD_DISTANCE_TO_OVERALL_LEADER:
|
||||
case WINDWARD_DISTANCE_TO_COMPETITOR_FARTHEST_AHEAD:
|
||||
case WINDWARD_DISTANCE_TO_GO_IN_METERS:
|
||||
case DISTANCE_TRAVELED:
|
||||
case DISTANCE_TRAVELED_INCLUDING_GATE_START:
|
||||
case RACE_DISTANCE_TO_LEADER_IN_METERS:
|
||||
case RACE_DISTANCE_TO_COMPETITOR_FARTHEST_AHEAD_IN_METERS:
|
||||
case RACE_DISTANCE_TRAVELED:
|
||||
case RACE_DISTANCE_TRAVELED_INCLUDING_GATE_START:
|
||||
case AVERAGE_TACK_LOSS_IN_METERS:
|
||||
@@ -200,13 +200,13 @@ public class DetailTypeFormatter {
|
||||
case ESTIMATED_TIME_TO_NEXT_WAYPOINT_IN_SECONDS:
|
||||
case TIME_TRAVELED:
|
||||
case CORRECTED_TIME_TRAVELED:
|
||||
case RACE_CORRECTED_TIME_TRAVELED:
|
||||
case RACE_CALCULATED_TIME_TRAVELED:
|
||||
case RACE_TIME_TRAVELED:
|
||||
case RACE_TIME_TRAVELED_DOWNWIND:
|
||||
case RACE_TIME_TRAVELED_REACHING:
|
||||
case RACE_TIME_TRAVELED_UPWIND:
|
||||
case TIME_BETWEEN_RACE_START_AND_COMPETITOR_START:
|
||||
case RACE_CORRECTED_TIME_AT_ESTIMATED_ARRIVAL_AT_COMPETITOR_FARTHEST_AHEAD:
|
||||
case RACE_CALCULATED_TIME_AT_ESTIMATED_ARRIVAL_AT_COMPETITOR_FARTHEST_AHEAD:
|
||||
return stringMessages.secondsUnit();
|
||||
|
||||
case TIME_ON_DISTANCE_ALLOWANCE_IN_SECONDS_PER_NAUTICAL_MILE:
|
||||
@@ -289,7 +289,7 @@ public class DetailTypeFormatter {
|
||||
case GAP_TO_LEADER_IN_SECONDS:
|
||||
return stringMessages.gapToLeaderInSecondsTooltip();
|
||||
case CORRECTED_TIME_TRAVELED:
|
||||
return stringMessages.correctedTimeTraveledTooltip();
|
||||
return stringMessages.calculatedTimeTraveledTooltip();
|
||||
case JIBE:
|
||||
return stringMessages.jibeTooltip();
|
||||
case MAXIMUM_SPEED_OVER_GROUND_IN_KNOTS:
|
||||
@@ -304,10 +304,10 @@ public class DetailTypeFormatter {
|
||||
return stringMessages.currentOrAverageSpeedOverGroundInKnotsTooltip();
|
||||
case RACE_CURRENT_SPEED_OVER_GROUND_IN_KNOTS:
|
||||
return stringMessages.currentSpeedOverGroundInKnotsTooltip();
|
||||
case RACE_DISTANCE_TO_LEADER_IN_METERS:
|
||||
return stringMessages.windwardDistanceToLeaderInMetersTooltip();
|
||||
case WINDWARD_DISTANCE_TO_OVERALL_LEADER:
|
||||
return stringMessages.windwardDistanceToLeaderInMetersTooltip();
|
||||
case RACE_DISTANCE_TO_COMPETITOR_FARTHEST_AHEAD_IN_METERS:
|
||||
return stringMessages.windwardDistanceToCompetitorFarthestAheadInMetersTooltip();
|
||||
case WINDWARD_DISTANCE_TO_COMPETITOR_FARTHEST_AHEAD:
|
||||
return stringMessages.windwardDistanceToCompetitorFarthestAheadInMetersTooltip();
|
||||
case DISTANCE_TO_START_AT_RACE_START:
|
||||
return stringMessages.distanceToLineAtRaceStartTooltip();
|
||||
case TIME_BETWEEN_RACE_START_AND_COMPETITOR_START:
|
||||
@@ -326,10 +326,10 @@ public class DetailTypeFormatter {
|
||||
return stringMessages.raceDistanceTraveledIncludingGateStartTooltip();
|
||||
case RACE_GAP_TO_LEADER_IN_SECONDS:
|
||||
return stringMessages.gapToLeaderInSecondsTooltip();
|
||||
case RACE_CORRECTED_TIME_TRAVELED:
|
||||
return stringMessages.correctedTimeTraveledTooltip();
|
||||
case RACE_CORRECTED_TIME_AT_ESTIMATED_ARRIVAL_AT_COMPETITOR_FARTHEST_AHEAD:
|
||||
return stringMessages.raceCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSecondsTooltip();
|
||||
case RACE_CALCULATED_TIME_TRAVELED:
|
||||
return stringMessages.calculatedTimeTraveledTooltip();
|
||||
case RACE_CALCULATED_TIME_AT_ESTIMATED_ARRIVAL_AT_COMPETITOR_FARTHEST_AHEAD:
|
||||
return stringMessages.raceCalculatedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSecondsTooltip();
|
||||
case RACE_RANK:
|
||||
return stringMessages.rankTooltip();
|
||||
case REGATTA_RANK:
|
||||
|
||||
+8
-7
@@ -3,6 +3,7 @@ package com.sap.sailing.gwt.ui.client;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.i18n.client.LocalizableResource.DefaultLocale;
|
||||
import com.google.gwt.json.client.JSONValue;
|
||||
import com.sap.sse.gwt.client.DefaultRule_0_1_2_n;
|
||||
import com.sap.sse.gwt.client.DefaultRule_0_1_n;
|
||||
import com.sap.sse.gwt.client.DefaultRule_1_0n;
|
||||
|
||||
@@ -93,7 +94,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
|
||||
String gapToLeaderInSeconds();
|
||||
String velocityMadeGoodInKnots();
|
||||
String windwardDistanceToGoInMeters();
|
||||
String windwardDistanceToLeaderInMeters();
|
||||
String windwardDistanceToCompetitorFarthestAheadInMeters();
|
||||
String name();
|
||||
String leaveEmptyForDefault();
|
||||
String trackNewEvent();
|
||||
@@ -511,7 +512,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
|
||||
String penaltyCircleTooltip();
|
||||
String raceAverageSpeedInKnotsTooltip();
|
||||
String currentSpeedOverGroundInKnotsTooltip();
|
||||
String windwardDistanceToLeaderInMetersTooltip();
|
||||
String windwardDistanceToCompetitorFarthestAheadInMetersTooltip();
|
||||
String raceDistanceTraveledTooltip();
|
||||
String rankTooltip();
|
||||
String rankGainTooltip();
|
||||
@@ -1067,7 +1068,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
|
||||
String addRaces();
|
||||
String withNamePrefix();
|
||||
String pleaseSelectASeriesFirst();
|
||||
String upcommingEventStartsInDays(@PluralCount(DefaultRule_0_1_n.class) int days);
|
||||
String upcommingEventStartsInDays(@PluralCount(DefaultRule_0_1_2_n.class) int days);
|
||||
String sharingMailTooltip();
|
||||
String sharingTwitterTooltip();
|
||||
String sharingFacebookTooltip();
|
||||
@@ -1300,10 +1301,10 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
|
||||
String timeOnTimeAndDistanceRankingMetricDescription();
|
||||
String timeOnTimeFactor();
|
||||
String timeOnDistanceAllowanceInSecondsPerNauticalMile();
|
||||
String correctedTimeTraveled();
|
||||
String correctedTimeTraveledTooltip();
|
||||
String calculatedTimeTraveled();
|
||||
String calculatedTimeTraveledTooltip();
|
||||
String timeOnTimeFactorTooltip();
|
||||
String timeOnDistanceAllowanceInSecondsPerNauticalMileTooltip();
|
||||
String raceCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSeconds();
|
||||
String raceCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSecondsTooltip();
|
||||
String raceCalculatedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSeconds();
|
||||
String raceCalculatedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSecondsTooltip();
|
||||
}
|
||||
+9
-9
@@ -86,13 +86,13 @@ currentSpeedOverGroundInKnotsTooltip=The current speed over ground.
|
||||
estimatedTimeToNextWaypointInSeconds=ETA
|
||||
estimatedTimeToNextWaypointInSecondsTooltip=The estimated time that the competitor needs to reach the next waypoint, based on the competitor''s current velocity made good, considering the true wind direction.
|
||||
gapToLeaderInSeconds=Gap to leader
|
||||
gapToLeaderInSecondsTooltip=Estimates the (corrected) arrival time at the current position of the boat that is farthest ahead,\nbased on average VMG for the current leg and with performance equal to that of the race leader for subsequent legs.\nThe gap tells how much earlier the competitor would have had to be where she currently is\nin order to rank equal to the race leader at the projected arrival at the current position of the boat farthest ahead.
|
||||
gapToLeaderInSecondsTooltip=Estimates the (calculated) arrival time at the current position of the boat that is farthest ahead,\nbased on average VMG for the current leg and with performance equal to that of the race leader for subsequent legs.\nThe gap tells how much earlier the competitor would have had to be where she currently is\nin order to rank equal to the race leader at the projected arrival at the current position of the boat farthest ahead.
|
||||
velocityMadeGoodInKnots=VMG
|
||||
velocityMadeGoodInKnotsTooltip=The velocity made good, which is the windward/leeward speed for upwind/downwind legs, respectively, or the along-track speed for reaching legs.
|
||||
windwardDistanceToGoInMeters=Windward distance to go
|
||||
windwardDistanceToGoInMetersTooltip=Windward/leeward distance from the competitor''s current position to the end of the leg for upwind/downwind legs, respectively, or the along-track distance for reaching legs.
|
||||
windwardDistanceToLeaderInMeters=Windward Distance To Leader
|
||||
windwardDistanceToLeaderInMetersTooltip=Windward/leeward distance of the competitor to the leader for upwind/downwind legs, respectively, or the along-track distance for reaching legs.
|
||||
windwardDistanceToCompetitorFarthestAheadInMeters=Windward Distance To Competitor Farthest Ahead
|
||||
windwardDistanceToCompetitorFarthestAheadInMetersTooltip=Windward/leeward distance of the competitor to the competitor farthest ahead in the race for upwind/downwind legs, respectively, or the along-track distance for reaching legs.\nNote that the competitor that is farthest ahead is not necessarily leading the race if handicap ranking is in place.
|
||||
name=Name
|
||||
leaveEmptyForDefault=Leave empty for default
|
||||
trackNewEvent=Track New event
|
||||
@@ -1266,12 +1266,12 @@ orcPerformanceCurveRankingMetric=ORC Performance Curve
|
||||
timeOnTimeAndDistanceRankingMetric=Time-on-Time/Time-on-Distance
|
||||
oneDesignRankingMetricDescription=One-Design: First across the line wins;\nin-race ranks based on windward positions (upwind/downwind) or along-course position (reaching)
|
||||
orcPerformanceCurveRankingMetricDescription=ORC Performance Curve: Sophisticated handicapping scheme that awards time allowances based on a VPP/polar assuming pre-defined legs'' angles to the wind;\nbased on these allowances, an "implied wind" is calculated which is the basis for ranking.\nImplied wind can be calculated at any time in the race and is therefore the basis for in-race ranking.
|
||||
timeOnTimeAndDistanceRankingMetricDescription=Time-on-Time / Time-on-Distance: Final ranking by corrected time;\ntime is corrected by optionally applying a factor to the actual time (defaulting to 1.0)\nand subtracting an allowance in seconds per nautical mile,\napplied to the course length.\nIn-race ranks based on expected arrival at fastest boat's current position\nassuming current leg's average VMG/VMC.
|
||||
timeOnTimeAndDistanceRankingMetricDescription=Time-on-Time / Time-on-Distance: Final ranking by calculated time;\ntime is calculated by optionally applying a factor to the actual time (defaulting to 1.0)\nand subtracting an allowance in seconds per nautical mile,\napplied to the course length.\nIn-race ranks based on expected arrival at fastest boat's current position\nassuming current leg's average VMG/VMC.
|
||||
timeOnTimeFactor=ToT Factor
|
||||
timeOnDistanceAllowanceInSecondsPerNauticalMile=ToD Allowance
|
||||
timeOnTimeFactorTooltip=Time-on-Time factor; actual time is multiplied with this factor in calculated time formula
|
||||
timeOnDistanceAllowanceInSecondsPerNauticalMileTooltip=Time-on-Distance allowance in seconds per nautical mile;\ndistance sailed is multiplied with this allowance, and the resulting seconds are subtracted from the actual time sailed\n(optionally corrected by the time-on-time factor) in the calculated time formula
|
||||
correctedTimeTraveled=Corrected Time
|
||||
correctedTimeTraveledTooltip=Corrected time according to competitor''s handicap\nbased on time since start of race and (windward) distance traveled
|
||||
raceCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSeconds=Corr.Time@Fastest
|
||||
raceCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSecondsTooltip=Corrected time at estimated arrival at the competitor that is currently farthest ahead in the race;\nestimation based on average VMG in current leg and equal (corrected) performance to fastest boat in all subsequent legs
|
||||
timeOnDistanceAllowanceInSecondsPerNauticalMileTooltip=Time-on-Distance allowance in seconds per nautical mile;\ndistance sailed is multiplied with this allowance, and the resulting seconds are subtracted from the actual time sailed\n(optionally calculated by applying the time-on-time factor) in the calculated time formula
|
||||
calculatedTimeTraveled=Calculated Time
|
||||
calculatedTimeTraveledTooltip=Calculated time according to competitor''s handicap\nbased on time since start of race and (windward) distance traveled
|
||||
raceCalculatedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSeconds=Calc.Time @ Fastest
|
||||
raceCalculatedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSecondsTooltip=Calculated time at estimated arrival at the competitor that is currently farthest ahead in the race;\nestimation based on average VMG in current leg and equal (calculated) performance to fastest boat in all subsequent legs
|
||||
+9
-9
@@ -814,7 +814,7 @@ papaRemoved=Start mode flag - one minute till start
|
||||
showDiagram=显示图表
|
||||
dontoverwrite=Don''t overwrite
|
||||
storedData=Stored data
|
||||
windwardDistanceToLeaderInMeters=迎风航段时离开上风第一名的平行距离
|
||||
windwardDistanceToCompetitorFarthestAheadInMeters=迎风航段时离开上风第一名的平行距离
|
||||
hostname=Hostname
|
||||
distanceIncludingGateStartInMeters=距离(起航门标)
|
||||
valueForCompetitorAt={0} at {1}: {2}
|
||||
@@ -829,7 +829,7 @@ windChart=Wind Chart
|
||||
events=活动
|
||||
racesAreLive=Races {0} are live
|
||||
operatorNotContains=Not Contains
|
||||
windwardDistanceToLeaderInMetersTooltip=迎/顺风航段时离开上风/下风第一名的平行距离或横风时的实际距离name 名字
|
||||
windwardDistanceToCompetitorFarthestAheadInMetersTooltip=迎/顺风航段时离开上风/下风第一名的平行距离或横风时的实际距离name 名字
|
||||
errorAddingResultImportUrl=Error adding result import URL: {0}
|
||||
noGrouperSelectedError=No grouper type is selected
|
||||
leaderboardsExceptFromSelectedGroup=Leaderboards (except those of selected group)
|
||||
@@ -1082,7 +1082,7 @@ clickAndDragToZoomIn=Click and drag in the plot area to zoom in
|
||||
runAutomaticallyTooltip=Run the query automatically, after you changed e.g. the statistic or the grouping.
|
||||
essThreeDisplayed=Three minutes till start
|
||||
actionEdit=Edit
|
||||
gapToLeaderInSecondsTooltip=Estimates the (corrected) arrival time at the current position of the boat that is farthest ahead,\nbased on average VMG for the current leg and with performance equal to that of the race leader for subsequent legs.\nThe gap tells how much earlier the competitor would have had to be where she currently is\nin order to rank equal to the race leader at the projected arrival at the current position of the boat farthest ahead.
|
||||
gapToLeaderInSecondsTooltip=Estimates the (calculated) arrival time at the current position of the boat that is farthest ahead,\nbased on average VMG for the current leg and with performance equal to that of the race leader for subsequent legs.\nThe gap tells how much earlier the competitor would have had to be where she currently is\nin order to rank equal to the race leader at the projected arrival at the current position of the boat farthest ahead.
|
||||
showAllCompetitors=显示所有参赛队
|
||||
leaderboardNotContainedInLeaderboardGroup=The leaderboard {0} is not contained in leaderboard group {1}.
|
||||
playSpeed=游戏速度
|
||||
@@ -1257,12 +1257,12 @@ orcPerformanceCurveRankingMetric=ORC Performance Curve
|
||||
timeOnTimeAndDistanceRankingMetric=Time-on-Time/Time-on-Distance
|
||||
oneDesignRankingMetricDescription=One-Design: First across the line wins;\nin-race ranks based on windward positions (upwind/downwind) or along-course position (reaching)
|
||||
orcPerformanceCurveRankingMetricDescription=ORC Performance Curve: Sophisticated handicapping scheme that awards time allowances based on a VPP/polar assuming pre-defined legs'' angles to the wind;\nbased on these allowances, an "implied wind" is calculated which is the basis for ranking.\nImplied wind can be calculated at any time in the race and is therefore the basis for in-race ranking.
|
||||
timeOnTimeAndDistanceRankingMetricDescription=Time-on-Time / Time-on-Distance: Final ranking by corrected time;\ntime is corrected by optionally applying a factor to the actual time (defaulting to 1.0)\nand subtracting an allowance in seconds per nautical mile,\napplied to the course length.\nIn-race ranks based on expected arrival at fastest boat's current position\nassuming current leg's average VMG/VMC.
|
||||
timeOnTimeAndDistanceRankingMetricDescription=Time-on-Time / Time-on-Distance: Final ranking by calculated time;\ntime is calculated by optionally applying a factor to the actual time (defaulting to 1.0)\nand subtracting an allowance in seconds per nautical mile,\napplied to the course length.\nIn-race ranks based on expected arrival at fastest boat's current position\nassuming current leg's average VMG/VMC.
|
||||
timeOnTimeFactor=Time-on-time handicap factor
|
||||
timeOnDistanceAllowanceInSecondsPerNauticalMile=Time-on-distance handicap allowance in seconds per nautical mile
|
||||
timeOnTimeFactorTooltip=Time-on-Time factor; actual time is multiplied with this factor in calculated time formula
|
||||
timeOnDistanceAllowanceInSecondsPerNauticalMileTooltip=Time-on-Distance allowance in seconds per nautical mile;\ndistance sailed is multiplied with this allowance, and the resulting seconds are subtracted from the actual time sailed\n(optionally corrected by the time-on-time factor) in the calculated time formula
|
||||
correctedTimeTraveled=Corrected Time
|
||||
correctedTimeTraveledTooltip=Corrected time according to competitor''s handicap\nbased on time since start of race and (windward) distance traveled
|
||||
raceCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSeconds=Corr.Time@Fastest
|
||||
raceCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSecondsTooltip=Corrected time at estimated arrival at the competitor that is currently farthest ahead in the race;\nestimation based on average VMG in current leg and equal (corrected) performance to fastest boat in all subsequent legs
|
||||
timeOnDistanceAllowanceInSecondsPerNauticalMileTooltip=Time-on-Distance allowance in seconds per nautical mile;\ndistance sailed is multiplied with this allowance, and the resulting seconds are subtracted from the actual time sailed\n(optionally calculated by applying the time-on-time factor) in the calculated time formula
|
||||
calculatedTimeTraveled=Calculated Time
|
||||
calculatedTimeTraveledTooltip=Calculated time according to competitor''s handicap\nbased on time since start of race and (windward) distance traveled
|
||||
raceCalculatedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSeconds=Calc.Time @ Fastest
|
||||
raceCalculatedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSecondsTooltip=Calculated time at estimated arrival at the competitor that is currently farthest ahead in the race;\nestimation based on average VMG in current leg and equal (calculated) performance to fastest boat in all subsequent legs
|
||||
+8
-8
@@ -86,13 +86,13 @@ currentSpeedOverGroundInKnotsTooltip=Die aktuelle Fahrt über Grund
|
||||
estimatedTimeToNextWaypointInSeconds=ETA
|
||||
estimatedTimeToNextWaypointInSecondsTooltip=Die vorraussichtliche Zeit, die der Teilnehmer benötigen wird,\num den nächsten Wegpunkt zu erreichen
|
||||
gapToLeaderInSeconds=Abstand zum Führenden
|
||||
gapToLeaderInSecondsTooltip=Schätzt die (korrigierte) Ankunftszeit an der jetzigen Position des bisher nach gesegelter Distanz in Führung liegenden Teilnehmers\nbasierend auf dem VMG des aktuellen Bahnschenkels, danach gleichauf mit dem Führenden.\nDer Zeitabstand besagt dann, wieviel früher der Teilnehmer an seiner jetzigen Position hätte sein müssen, um gemäß dieser Vorhersage gleichauf mit dem Führenden nach korrigierter Zeit zu liegen.
|
||||
gapToLeaderInSecondsTooltip=Schätzt die (berechnete) Ankunftszeit an der jetzigen Position des bisher nach gesegelter Distanz in Führung liegenden Teilnehmers\nbasierend auf dem VMG des aktuellen Bahnschenkels, danach gleichauf mit dem Führenden.\nDer Zeitabstand besagt dann, wieviel früher der Teilnehmer an seiner jetzigen Position hätte sein müssen, um gemäß dieser Vorhersage gleichauf mit dem Führenden nach korrigierter Zeit zu liegen.
|
||||
velocityMadeGoodInKnots=VMG
|
||||
velocityMadeGoodInKnotsTooltip=Die effektive Geschwindigkeit zum Ziel; auf der Kreuz die windwärtige Geschwindigkeit; auf der Vorwindstrecke die leewärtige Geschwindigkeit
|
||||
windwardDistanceToGoInMeters=Abstand in Windrichtung zur nächsten Bahnmarke
|
||||
windwardDistanceToGoInMetersTooltip=Windwärtige / leewärtige Distanz des Teilnehmerns bis zum Ende des Schenkels auf Kreuz bzw. Vorwindstrecke; Strecke entlang des Schenkels bei Holeschlägen
|
||||
windwardDistanceToLeaderInMeters=Abstand zum führenden Boot
|
||||
windwardDistanceToLeaderInMetersTooltip=Windwärtige Distanz des Teilnehmers zum Führenden
|
||||
windwardDistanceToCompetitorFarthestAheadInMeters=Windärtiger Abstand zum schnellsten Boot
|
||||
windwardDistanceToCompetitorFarthestAheadInMetersTooltip=Windwärtiger Abstand zum Boot, das bisher am weitesten windwärts gesegelt ist.\nFür Handicap-Wertungen ist das nicht notwendigerweise der nach Verrechnung in Führung liegende Teilnehmer.
|
||||
name=Name
|
||||
leaveEmptyForDefault=Leer für Standardeinstellung
|
||||
trackNewEvent=Track New event
|
||||
@@ -513,7 +513,7 @@ upcoming=demnächst
|
||||
next=gleich
|
||||
inProgress=aktiv
|
||||
passedTo=an {0} gerundet
|
||||
gapChangeSinceLegStartInSeconds=Gap Änderung
|
||||
gapChangeSinceLegStartInSeconds=Änderung Abstand zum Führenden
|
||||
gapChangeSinceLegStartInSecondsTooltip=Die Änderung des Abstands zum Führenden seit dem letzten Schenkelstart.\nEine negative Zahl bedeutet,\ndass sich der Abstand verringert hat; eine positive Zahl bedeutet, dass er sich vergrößert hat.
|
||||
sideToWhichMarkAtLegStartWasRounded=Tonne gerundet an
|
||||
sideToWhichMarkAtLegStartWasRoundedTooltip=Seite, an der die Bahnmarke am Schenkelstart gerundet wurde
|
||||
@@ -1261,7 +1261,7 @@ timeOnTimeFactor=ToT Faktor
|
||||
timeOnDistanceAllowanceInSecondsPerNauticalMile=ToD Zuteilung
|
||||
timeOnTimeFactorTooltip=Zeit-auf-Zeit Faktor; tatsächlich gesegelte Zeit wird für die berechnete Zeit mit diesem Faktor multipliziert
|
||||
timeOnDistanceAllowanceInSecondsPerNauticalMileTooltip=Zeit-auf-Distanz Zuteilung in Sekunden pro Seemeile;\ndie gesegelte Distanz wird mit diesem Wert multipliziert, und die sich ergebende Zeit wird von der (ggf. per ToT-Faktor angepassten) Zeit subtrahiert
|
||||
correctedTimeTraveled=Berechnete Zeit
|
||||
correctedTimeTraveledTooltip=Berechnete Zeit anhand Teilnehmer-Handicap\nauf der Grundlage von Zeit seit Rennstart und zurückgelegter Distanz
|
||||
raceCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSeconds=Ber.Zeit@Führender
|
||||
raceCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSecondsTooltip=Berechnete Zeit bei erwarteter Ankunft am derzeit absolut in Führung liegenden Teilnehmers;\nSchätzung basierend auf durchschnittlichem VMG im aktuellen Bahnschenkel und gleicher verrechneter Geschwindigket wie der absolut in Führung liegende Teilnehmer\nfür alle nachfolgenden Bahnschenkel
|
||||
calculatedTimeTraveled=Berechnete Zeit
|
||||
calculatedTimeTraveledTooltip=Berechnete Zeit anhand Teilnehmer-Handicap\nauf der Grundlage von Zeit seit Rennstart und zurückgelegter Distanz
|
||||
raceCalcluatedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSeconds=Ber.Zeit@Führender
|
||||
raceCalculatedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSecondsTooltip=Berechnete Zeit bei erwarteter Ankunft am derzeit absolut in Führung liegenden Teilnehmers;\nSchätzung basierend auf durchschnittlichem VMG im aktuellen Bahnschenkel und gleicher verrechneter Geschwindigket wie der absolut in Führung liegende Teilnehmer\nfür alle nachfolgenden Bahnschenkel
|
||||
+9
-9
@@ -86,13 +86,13 @@ currentSpeedOverGroundInKnotsTooltip=Текущая скорость относ
|
||||
estimatedTimeToNextWaypointInSeconds=Расчетное время прибытия (ETA).
|
||||
estimatedTimeToNextWaypointInSecondsTooltip= Расчетное время, необходимое участнику для прибытия в следующую промежуточную точку маршрута, исходя из скорости лавирования участника и с учетом истинного направление ветра.
|
||||
gapToLeaderInSeconds=Отставание от лидера
|
||||
gapToLeaderInSecondsTooltip=Estimates the (corrected) arrival time at the current position of the boat that is farthest ahead,\nbased on average VMG for the current leg and with performance equal to that of the race leader for subsequent legs.\nThe gap tells how much earlier the competitor would have had to be where she currently is\nin order to rank equal to the race leader at the projected arrival at the current position of the boat farthest ahead.
|
||||
gapToLeaderInSecondsTooltip=Estimates the (calculated) arrival time at the current position of the boat that is farthest ahead,\nbased on average VMG for the current leg and with performance equal to that of the race leader for subsequent legs.\nThe gap tells how much earlier the competitor would have had to be where she currently is\nin order to rank equal to the race leader at the projected arrival at the current position of the boat farthest ahead.
|
||||
velocityMadeGoodInKnots=Скорость лавирования (VMG)
|
||||
velocityMadeGoodInKnotsTooltip=Скорость лавирования, представляет собой скорость продвижения на ветер/ по ветру для этапов движения против ветра/ по ветру соответственно, или скорость в направлении движения при лавировании по ветру
|
||||
windwardDistanceToGoInMeters=Расстояние, которое необходимо пройти на ветер
|
||||
windwardDistanceToGoInMetersTooltip=Расстояние движения на ветер/ по ветру от текущего положения участника до конца этапа для этапов движения против ветра/ по ветру соответственно, или скорость в направлении движения при лавировании по ветру.
|
||||
windwardDistanceToLeaderInMeters=Расстояние на ветер до лидера
|
||||
windwardDistanceToLeaderInMetersTooltip=Расстояние на ветер/ под ветер от участника до лидера для этапов движения против ветра/ по ветру соответственно или скорость в направлении движения при лавировании по ветру.
|
||||
windwardDistanceToCompetitorFarthestAheadInMeters=Расстояние на ветер до лидера
|
||||
windwardDistanceToCompetitorFarthestAheadInMetersTooltip=Расстояние на ветер/ под ветер от участника до лидера для этапов движения против ветра/ по ветру соответственно или скорость в направлении движения при лавировании по ветру.
|
||||
name=Имя
|
||||
leaveEmptyForDefault=Оставьте пустым по умолчанию.
|
||||
trackNewEvent=Отследить новое событие
|
||||
@@ -1204,12 +1204,12 @@ orcPerformanceCurveRankingMetric=ORC Performance Curve
|
||||
timeOnTimeAndDistanceRankingMetric=Time-on-Time/Time-on-Distance
|
||||
oneDesignRankingMetricDescription=One-Design: First across the line wins;\nin-race ranks based on windward positions (upwind/downwind) or along-course position (reaching)
|
||||
orcPerformanceCurveRankingMetricDescription=ORC Performance Curve: Sophisticated handicapping scheme that awards time allowances based on a VPP/polar assuming pre-defined legs'' angles to the wind;\nbased on these allowances, an "implied wind" is calculated which is the basis for ranking.\nImplied wind can be calculated at any time in the race and is therefore the basis for in-race ranking.
|
||||
timeOnTimeAndDistanceRankingMetricDescription=Time-on-Time / Time-on-Distance: Final ranking by corrected time;\ntime is corrected by optionally applying a factor to the actual time (defaulting to 1.0)\nand subtracting an allowance in seconds per nautical mile,\napplied to the course length.\nIn-race ranks based on expected arrival at fastest boat's current position\nassuming current leg's average VMG/VMC.
|
||||
timeOnTimeAndDistanceRankingMetricDescription=Time-on-Time / Time-on-Distance: Final ranking by calculated time;\ntime is calculated by optionally applying a factor to the actual time (defaulting to 1.0)\nand subtracting an allowance in seconds per nautical mile,\napplied to the course length.\nIn-race ranks based on expected arrival at fastest boat's current position\nassuming current leg's average VMG/VMC.
|
||||
timeOnTimeFactor=Time-on-time handicap factor
|
||||
timeOnDistanceAllowanceInSecondsPerNauticalMile=Time-on-distance handicap allowance in seconds per nautical mile
|
||||
timeOnTimeFactorTooltip=Time-on-Time factor; actual time is multiplied with this factor in calculated time formula
|
||||
timeOnDistanceAllowanceInSecondsPerNauticalMileTooltip=Time-on-Distance allowance in seconds per nautical mile;\ndistance sailed is multiplied with this allowance, and the resulting seconds are subtracted from the actual time sailed\n(optionally corrected by the time-on-time factor) in the calculated time formula
|
||||
correctedTimeTraveled=Corrected Time
|
||||
correctedTimeTraveledTooltip=Corrected time according to competitor''s handicap\nbased on time since start of race and (windward) distance traveled
|
||||
raceCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSeconds=Corr.Time@Fastest
|
||||
raceCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSecondsTooltip=Corrected time at estimated arrival at the competitor that is currently farthest ahead in the race;\nestimation based on average VMG in current leg and equal (corrected) performance to fastest boat in all subsequent legs
|
||||
timeOnDistanceAllowanceInSecondsPerNauticalMileTooltip=Time-on-Distance allowance in seconds per nautical mile;\ndistance sailed is multiplied with this allowance, and the resulting seconds are subtracted from the actual time sailed\n(optionally calculated by applying the time-on-time factor) in the calculated time formula
|
||||
calculatedTimeTraveled=Calculated Time
|
||||
calculatedTimeTraveledTooltip=Calculated time according to competitor''s handicap\nbased on time since start of race and (windward) distance traveled
|
||||
raceCalculatedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSeconds=Calc.Time @ Fastest
|
||||
raceCalculatedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSecondsTooltip=Calculated time at estimated arrival at the competitor that is currently farthest ahead in the race;\nestimation based on average VMG in current leg and equal (calculated) performance to fastest boat in all subsequent legs
|
||||
+2
-2
@@ -10,7 +10,7 @@ import com.google.gwt.event.shared.HandlerRegistration;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.gwt.ui.shared.media.ImageMetadataDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.media.SailingImageDTO;
|
||||
|
||||
public class GalleryImageHolder extends Widget implements HasClickHandlers {
|
||||
|
||||
@@ -22,7 +22,7 @@ public class GalleryImageHolder extends Widget implements HasClickHandlers {
|
||||
@UiField
|
||||
DivElement imageHolderUi;
|
||||
|
||||
public GalleryImageHolder(ImageMetadataDTO video) {
|
||||
public GalleryImageHolder(SailingImageDTO video) {
|
||||
setElement(uiBinder.createAndBindUi(this));
|
||||
imageHolderUi.getStyle().setBackgroundImage("url(\"" + video.getSourceRef() + "\")");
|
||||
|
||||
|
||||
+1
-1
@@ -24,7 +24,6 @@ import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack.Status;
|
||||
import com.sap.sailing.domain.common.media.MediaType;
|
||||
import com.sap.sailing.domain.common.security.Roles;
|
||||
import com.sap.sailing.gwt.ui.client.MediaServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.RaceTimesInfoProvider;
|
||||
@@ -38,6 +37,7 @@ import com.sap.sailing.gwt.ui.client.media.shared.VideoPlayer;
|
||||
import com.sap.sailing.gwt.ui.client.media.shared.VideoSynchPlayer;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.media.MediaType;
|
||||
import com.sap.sse.common.settings.AbstractSettings;
|
||||
import com.sap.sse.gwt.client.ErrorReporter;
|
||||
import com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback;
|
||||
|
||||
+1
-1
@@ -14,8 +14,8 @@ import com.google.gwt.user.client.ui.PopupPanel;
|
||||
import com.google.gwt.user.client.ui.UIObject;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
import com.sap.sailing.domain.common.media.MediaType;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sse.common.media.MediaType;
|
||||
|
||||
public class MediaSingleSelectionControl extends AbstractMediaSelectionControl implements CloseHandler<PopupPanel> {
|
||||
|
||||
|
||||
+1
-1
@@ -17,12 +17,12 @@ import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
import com.sap.sailing.domain.common.media.MimeType;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.common.client.YoutubeApi;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.impl.MillisecondsDurationImpl;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
|
||||
|
||||
public class NewMediaDialog extends DataEntryDialog<MediaTrack> {
|
||||
|
||||
+3
-3
@@ -9,9 +9,9 @@ import com.google.gwt.dom.client.VideoElement;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.media.MediaSubType;
|
||||
import com.sap.sailing.domain.common.media.MediaType;
|
||||
import com.sap.sailing.domain.common.media.MimeType;
|
||||
import com.sap.sse.common.media.MediaSubType;
|
||||
import com.sap.sse.common.media.MediaType;
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
|
||||
public class VideoJSPlayer extends Widget {
|
||||
|
||||
|
||||
+3
-3
@@ -11,9 +11,9 @@ import com.google.gwt.event.shared.HandlerRegistration;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.media.MediaSubType;
|
||||
import com.sap.sailing.gwt.ui.common.client.YoutubeApi;
|
||||
import com.sap.sailing.gwt.ui.shared.media.VideoMetadataDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.media.SailingVideoDTO;
|
||||
import com.sap.sse.common.media.MediaSubType;
|
||||
|
||||
public class VideoThumbnail extends Widget implements HasClickHandlers {
|
||||
|
||||
@@ -28,7 +28,7 @@ public class VideoThumbnail extends Widget implements HasClickHandlers {
|
||||
@UiField
|
||||
ImageElement thumbnailUi;
|
||||
|
||||
public VideoThumbnail(VideoMetadataDTO video) {
|
||||
public VideoThumbnail(SailingVideoDTO video) {
|
||||
setElement(uiBinder.createAndBindUi(this));
|
||||
getElement().addClassName("videoThumbnail");
|
||||
captionUi.setInnerText(video.getTitle());
|
||||
|
||||
+1
-1
@@ -539,7 +539,7 @@ public abstract class AbstractCompetitorRaceChart<SettingsType extends ChartSett
|
||||
}
|
||||
|
||||
private boolean hasReversedYAxis(DetailType detailType) {
|
||||
return selectedDetailType == DetailType.WINDWARD_DISTANCE_TO_OVERALL_LEADER ||
|
||||
return selectedDetailType == DetailType.WINDWARD_DISTANCE_TO_COMPETITOR_FARTHEST_AHEAD ||
|
||||
selectedDetailType == DetailType.GAP_TO_LEADER_IN_SECONDS ||
|
||||
selectedDetailType == DetailType.RACE_RANK ||
|
||||
selectedDetailType == DetailType.REGATTA_RANK ||
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ public class MultiCompetitorRaceChart extends AbstractCompetitorRaceChart<MultiC
|
||||
final ErrorReporter errorReporter, boolean compactChart, boolean allowTimeAdjust,
|
||||
final String leaderboardGroupName, String leaderboardName) {
|
||||
super(sailingService, asyncActionsExecutor, competitorSelectionProvider, raceSelectionProvider, timer, timeRangeWithZoomProvider, stringMessages, errorReporter,
|
||||
/*show initially*/ DetailType.WINDWARD_DISTANCE_TO_OVERALL_LEADER, compactChart, allowTimeAdjust, leaderboardGroupName, leaderboardName);
|
||||
/*show initially*/ DetailType.WINDWARD_DISTANCE_TO_COMPETITOR_FARTHEST_AHEAD, compactChart, allowTimeAdjust, leaderboardGroupName, leaderboardName);
|
||||
if (leaderboardGroupName != null) {
|
||||
sailingService.getLeaderboardGroupByName(leaderboardGroupName, false,
|
||||
new AsyncCallback<LeaderboardGroupDTO>() {
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ public class MultiCompetitorRaceChartSettingsComponent extends AbstractChartSett
|
||||
this.initialDetailType = settings.getDetailType();
|
||||
|
||||
availableDetailsTypes = new ArrayList<DetailType>();
|
||||
availableDetailsTypes.add(DetailType.WINDWARD_DISTANCE_TO_OVERALL_LEADER);
|
||||
availableDetailsTypes.add(DetailType.WINDWARD_DISTANCE_TO_COMPETITOR_FARTHEST_AHEAD);
|
||||
availableDetailsTypes.add(DetailType.DISTANCE_TRAVELED);
|
||||
availableDetailsTypes.add(DetailType.DISTANCE_TRAVELED_INCLUDING_GATE_START);
|
||||
availableDetailsTypes.add(DetailType.VELOCITY_MADE_GOOD_IN_KNOTS);
|
||||
|
||||
+18
-8
@@ -315,6 +315,13 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
* the last {@link #timeChanged(Date, Date)} event. Therefore, the ranks listed here correspond to the {@link #timer}'s time.
|
||||
*/
|
||||
private LinkedHashMap<CompetitorDTO, QuickRankDTO> quickRanks;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
@@ -504,7 +511,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
map.setControls(ControlPosition.LEFT_TOP, combinedWindPanel);
|
||||
combinedWindPanel.getParent().addStyleName("CombinedWindPanelParentDiv");
|
||||
map.setControls(ControlPosition.LEFT_TOP, trueNorthIndicatorPanel);
|
||||
trueNorthIndicatorPanel.getParent().addStyleName("CombinedWindPanelParentDiv");
|
||||
trueNorthIndicatorPanel.getParent().addStyleName("TrueNorthIndicatorPanelParentDiv");
|
||||
|
||||
RaceMap.this.raceMapImageManager.loadMapIcons(map);
|
||||
map.setSize("100%", "100%");
|
||||
@@ -844,6 +851,8 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
public void onSuccess(RaceMapDataDTO raceMapDataDTO) {
|
||||
if (map != null && raceMapDataDTO != null) {
|
||||
quickRanks = raceMapDataDTO.quickRanks;
|
||||
competitorsInOrderOfWindwardDistanceTraveledWithOneBasedLegNumber =
|
||||
raceMapDataDTO.competitorsInOrderOfWindwardDistanceTraveledWithOneBasedLegNumber;
|
||||
if (showViewSimulation && settings.isShowSimulationOverlay()) {
|
||||
lastLegNumber = raceMapDataDTO.coursePositions.currentLegNumber;
|
||||
simulationOverlay.updateLeg(Math.max(lastLegNumber,1), /* clearCanvas */ false, raceMapDataDTO.simulationResultVersion);
|
||||
@@ -1153,15 +1162,16 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
/**
|
||||
* 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> getLeadingVisibleCompetitorWithOneBasedLegNumber(
|
||||
private com.sap.sse.common.Util.Pair<Integer, CompetitorDTO> getFarthestAheadVisibleCompetitorWithOneBasedLegNumber(
|
||||
Iterable<CompetitorDTO> competitorsToShow) {
|
||||
CompetitorDTO leadingCompetitorDTO = null;
|
||||
int legOfLeaderCompetitor = -1;
|
||||
// this only works because the quickRanks are sorted
|
||||
for (QuickRankDTO quickRank : quickRanks.values()) {
|
||||
if (Util.contains(competitorsToShow, quickRank.competitor)) {
|
||||
leadingCompetitorDTO = quickRank.competitor;
|
||||
legOfLeaderCompetitor = quickRank.legNumberOneBased;
|
||||
for (Entry<CompetitorDTO, Integer> competitorsByWindwardDistanceTraveledAndOneBasedLegNumber :
|
||||
competitorsInOrderOfWindwardDistanceTraveledWithOneBasedLegNumber.entrySet()) {
|
||||
if (Util.contains(competitorsToShow, competitorsByWindwardDistanceTraveledAndOneBasedLegNumber.getKey())) {
|
||||
leadingCompetitorDTO = competitorsByWindwardDistanceTraveledAndOneBasedLegNumber.getKey();
|
||||
legOfLeaderCompetitor = competitorsByWindwardDistanceTraveledAndOneBasedLegNumber.getValue();
|
||||
return new com.sap.sse.common.Util.Pair<Integer, CompetitorDTO>(legOfLeaderCompetitor, leadingCompetitorDTO);
|
||||
}
|
||||
}
|
||||
@@ -1173,7 +1183,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
boolean drawAdvantageLine = false;
|
||||
if (settings.getHelpLinesSettings().isVisible(HelpLineTypes.ADVANTAGELINE)) {
|
||||
// find competitor with highest rank
|
||||
com.sap.sse.common.Util.Pair<Integer, CompetitorDTO> visibleLeaderInfo = getLeadingVisibleCompetitorWithOneBasedLegNumber(competitorsToShow);
|
||||
com.sap.sse.common.Util.Pair<Integer, CompetitorDTO> visibleLeaderInfo = getFarthestAheadVisibleCompetitorWithOneBasedLegNumber(competitorsToShow);
|
||||
// the boat fix may be null; may mean that no positions were loaded yet for the leading visible boat;
|
||||
// don't show anything
|
||||
GPSFixDTO lastBoatFix = null;
|
||||
@@ -1374,7 +1384,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
|
||||
private void showStartAndFinishLines(final CoursePositionsDTO courseDTO) {
|
||||
if (map != null && courseDTO != null && lastRaceTimesInfo != null) {
|
||||
com.sap.sse.common.Util.Pair<Integer, CompetitorDTO> leadingVisibleCompetitorInfo = getLeadingVisibleCompetitorWithOneBasedLegNumber(getCompetitorsToShow());
|
||||
com.sap.sse.common.Util.Pair<Integer, CompetitorDTO> leadingVisibleCompetitorInfo = getFarthestAheadVisibleCompetitorWithOneBasedLegNumber(getCompetitorsToShow());
|
||||
int legOfLeadingCompetitor = leadingVisibleCompetitorInfo == null ? -1 : leadingVisibleCompetitorInfo.getA();
|
||||
int numberOfLegs = lastRaceTimesInfo.legInfos.size();
|
||||
// draw the start line
|
||||
|
||||
+21
-21
@@ -861,9 +861,9 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
|
||||
return new DetailType[] { DetailType.RACE_GAP_TO_LEADER_IN_SECONDS,
|
||||
DetailType.RACE_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS,
|
||||
DetailType.RACE_DISTANCE_TRAVELED, DetailType.RACE_DISTANCE_TRAVELED_INCLUDING_GATE_START,
|
||||
DetailType.RACE_TIME_TRAVELED, DetailType.RACE_CORRECTED_TIME_TRAVELED,
|
||||
DetailType.RACE_CORRECTED_TIME_AT_ESTIMATED_ARRIVAL_AT_COMPETITOR_FARTHEST_AHEAD,
|
||||
DetailType.RACE_CURRENT_SPEED_OVER_GROUND_IN_KNOTS, DetailType.RACE_DISTANCE_TO_LEADER_IN_METERS,
|
||||
DetailType.RACE_TIME_TRAVELED, DetailType.RACE_CALCULATED_TIME_TRAVELED,
|
||||
DetailType.RACE_CALCULATED_TIME_AT_ESTIMATED_ARRIVAL_AT_COMPETITOR_FARTHEST_AHEAD,
|
||||
DetailType.RACE_CURRENT_SPEED_OVER_GROUND_IN_KNOTS, DetailType.RACE_DISTANCE_TO_COMPETITOR_FARTHEST_AHEAD_IN_METERS,
|
||||
DetailType.NUMBER_OF_MANEUVERS, DetailType.DISPLAY_LEGS, DetailType.CURRENT_LEG,
|
||||
DetailType.RACE_AVERAGE_ABSOLUTE_CROSS_TRACK_ERROR_IN_METERS,
|
||||
DetailType.RACE_AVERAGE_SIGNED_CROSS_TRACK_ERROR_IN_METERS,
|
||||
@@ -873,8 +873,7 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
|
||||
DetailType.SPEED_OVER_GROUND_WHEN_PASSING_START,
|
||||
DetailType.DISTANCE_TO_STARBOARD_END_OF_STARTLINE_WHEN_PASSING_START_IN_METERS,
|
||||
DetailType.START_TACK,
|
||||
DetailType.RACE_RATIO_BETWEEN_TIME_SINCE_LAST_POSITION_FIX_AND_AVERAGE_SAMPLING_INTERVAL,
|
||||
DetailType.RACE_CORRECTED_TIME_AT_ESTIMATED_ARRIVAL_AT_COMPETITOR_FARTHEST_AHEAD};
|
||||
DetailType.RACE_RATIO_BETWEEN_TIME_SINCE_LAST_POSITION_FIX_AND_AVERAGE_SAMPLING_INTERVAL};
|
||||
}
|
||||
|
||||
public static DetailType[] getAvailableOverallDetailColumnTypes() {
|
||||
@@ -939,8 +938,8 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
|
||||
result.put(DetailType.RACE_CURRENT_SPEED_OVER_GROUND_IN_KNOTS,
|
||||
new FormattedDoubleDetailTypeColumn(DetailType.RACE_CURRENT_SPEED_OVER_GROUND_IN_KNOTS, new CurrentSpeedOverGroundInKnots(),
|
||||
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, LeaderboardPanel.this));
|
||||
result.put(DetailType.RACE_DISTANCE_TO_LEADER_IN_METERS,
|
||||
new FormattedDoubleDetailTypeColumn(DetailType.RACE_DISTANCE_TO_LEADER_IN_METERS, new RaceDistanceToLeaderInMeters(),
|
||||
result.put(DetailType.RACE_DISTANCE_TO_COMPETITOR_FARTHEST_AHEAD_IN_METERS,
|
||||
new FormattedDoubleDetailTypeColumn(DetailType.RACE_DISTANCE_TO_COMPETITOR_FARTHEST_AHEAD_IN_METERS, new RaceDistanceToCompetitorFarthestAheadInMeters(),
|
||||
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, LeaderboardPanel.this));
|
||||
result.put(DetailType.RACE_AVERAGE_ABSOLUTE_CROSS_TRACK_ERROR_IN_METERS,
|
||||
new FormattedDoubleDetailTypeColumn(DetailType.RACE_AVERAGE_ABSOLUTE_CROSS_TRACK_ERROR_IN_METERS, new RaceAverageAbsoluteCrossTrackErrorInMeters(),
|
||||
@@ -978,12 +977,12 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
|
||||
result.put(DetailType.RACE_TIME_TRAVELED, new TimeTraveledRaceColumn(getLeaderboardPanel(), this,
|
||||
stringMessages, LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, LEG_DETAIL_COLUMN_HEADER_STYLE,
|
||||
LEG_DETAIL_COLUMN_STYLE));
|
||||
result.put(DetailType.RACE_CORRECTED_TIME_TRAVELED,
|
||||
new FormattedDoubleDetailTypeColumn(DetailType.RACE_CORRECTED_TIME_TRAVELED, new RaceCorrectedTimeTraveledInSeconds(),
|
||||
result.put(DetailType.RACE_CALCULATED_TIME_TRAVELED,
|
||||
new FormattedDoubleDetailTypeColumn(DetailType.RACE_CALCULATED_TIME_TRAVELED, new RaceCalculatedTimeTraveledInSeconds(),
|
||||
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, LeaderboardPanel.this));
|
||||
result.put(DetailType.RACE_CORRECTED_TIME_TRAVELED, new FormattedDoubleDetailTypeColumn(
|
||||
DetailType.RACE_CORRECTED_TIME_AT_ESTIMATED_ARRIVAL_AT_COMPETITOR_FARTHEST_AHEAD,
|
||||
new RaceCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSeconds(),
|
||||
result.put(DetailType.RACE_CALCULATED_TIME_AT_ESTIMATED_ARRIVAL_AT_COMPETITOR_FARTHEST_AHEAD, new FormattedDoubleDetailTypeColumn(
|
||||
DetailType.RACE_CALCULATED_TIME_AT_ESTIMATED_ARRIVAL_AT_COMPETITOR_FARTHEST_AHEAD,
|
||||
new RaceCalculatedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSeconds(),
|
||||
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, LeaderboardPanel.this));
|
||||
return result;
|
||||
}
|
||||
@@ -1280,26 +1279,26 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
|
||||
}
|
||||
}
|
||||
|
||||
private class RaceCorrectedTimeTraveledInSeconds implements LegDetailField<Double> {
|
||||
private class RaceCalculatedTimeTraveledInSeconds implements LegDetailField<Double> {
|
||||
@Override
|
||||
public Double get(LeaderboardRowDTO row) {
|
||||
Double result = null;
|
||||
LeaderboardEntryDTO fieldsForRace = row.fieldsByRaceColumnName.get(getRaceColumnName());
|
||||
if (fieldsForRace != null) {
|
||||
result = fieldsForRace.correctedTime == null ? null : fieldsForRace.correctedTime.asSeconds();
|
||||
result = fieldsForRace.calculatedTime == null ? null : fieldsForRace.calculatedTime.asSeconds();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private class RaceCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSeconds implements LegDetailField<Double> {
|
||||
private class RaceCalculatedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSeconds implements LegDetailField<Double> {
|
||||
@Override
|
||||
public Double get(LeaderboardRowDTO row) {
|
||||
Double result = null;
|
||||
LeaderboardEntryDTO fieldsForRace = row.fieldsByRaceColumnName.get(getRaceColumnName());
|
||||
if (fieldsForRace != null) {
|
||||
result = fieldsForRace.correctedTimeAtEstimatedArrivalAtCompetitorFarthestAhead == null ? null
|
||||
: fieldsForRace.correctedTimeAtEstimatedArrivalAtCompetitorFarthestAhead.asSeconds();
|
||||
result = fieldsForRace.calculatedTimeAtEstimatedArrivalAtCompetitorFarthestAhead == null ? null
|
||||
: fieldsForRace.calculatedTimeAtEstimatedArrivalAtCompetitorFarthestAhead.asSeconds();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -1378,17 +1377,18 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the windward distance to the overall leader in meters
|
||||
* Computes the windward distance to the competitor farthest ahead in the race (not necessarily the leader with
|
||||
* handicap scoring) in meters
|
||||
*
|
||||
* @author Axel Uhl (D043530)
|
||||
*/
|
||||
private class RaceDistanceToLeaderInMeters implements LegDetailField<Double> {
|
||||
private class RaceDistanceToCompetitorFarthestAheadInMeters implements LegDetailField<Double> {
|
||||
@Override
|
||||
public Double get(LeaderboardRowDTO row) {
|
||||
Double result = null;
|
||||
LeaderboardEntryDTO fieldsForRace = row.fieldsByRaceColumnName.get(getRaceColumnName());
|
||||
if (fieldsForRace != null && fieldsForRace.windwardDistanceToOverallLeaderInMeters != null) {
|
||||
result = fieldsForRace.windwardDistanceToOverallLeaderInMeters;
|
||||
if (fieldsForRace != null && fieldsForRace.windwardDistanceToCompetitorFarthestAheadInMeters != null) {
|
||||
result = fieldsForRace.windwardDistanceToCompetitorFarthestAheadInMeters;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
+2
-2
@@ -67,7 +67,7 @@ public class LeaderboardSettingsFactory {
|
||||
List<DetailType> raceDetails = new ArrayList<DetailType>();
|
||||
raceDetails.add(DetailType.RACE_DISTANCE_TRAVELED);
|
||||
raceDetails.add(DetailType.RACE_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS);
|
||||
raceDetails.add(DetailType.RACE_DISTANCE_TO_LEADER_IN_METERS);
|
||||
raceDetails.add(DetailType.RACE_DISTANCE_TO_COMPETITOR_FARTHEST_AHEAD_IN_METERS);
|
||||
raceDetails.add(DetailType.NUMBER_OF_MANEUVERS);
|
||||
raceDetails.add(DetailType.DISPLAY_LEGS);
|
||||
final List<DetailType> overallDetails = createOverallDetailsForShowRegattaRank(showRegattaRank);
|
||||
@@ -78,7 +78,7 @@ public class LeaderboardSettingsFactory {
|
||||
/* refresh interval */ null, /* name of race to sort */ nameOfRaceToSort,
|
||||
/* ascending */ true, /* updateUponPlayStateChange */ true, raceColumnSelection.getType(),
|
||||
/*showAddedScores*/ false, /*showOverallRacesCompleted*/ false,
|
||||
/*showCompetitorSailIdColumns*/showCompetitorSailIdColumn, /*showCompetitorFullNameColumn*/showCompetitorNameColumn);
|
||||
/*showCompetitorSailIdColumns*/showCompetitorSailIdColumn, /*showCompetitorFullNameColumn*/showCompetitorNameColumn);
|
||||
break;
|
||||
case Replay:
|
||||
settings = createNewDefaultSettings(namesOfRaceColumnsToShow, namesOfRacesToShow, nameOfRaceToSort, /* autoExpandFirstRace */
|
||||
|
||||
+58
-43
@@ -1,43 +1,58 @@
|
||||
package com.sap.sailing.gwt.ui.leaderboardedit;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.RootPanel;
|
||||
import com.sap.sailing.gwt.ui.client.AbstractSailingEntryPoint;
|
||||
import com.sap.sailing.gwt.ui.client.LogoAndTitlePanel;
|
||||
import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
|
||||
import com.sap.sse.gwt.client.async.MarkedAsyncCallback;
|
||||
|
||||
public class LeaderboardEditPage extends AbstractSailingEntryPoint {
|
||||
@Override
|
||||
protected void doOnModuleLoad() {
|
||||
super.doOnModuleLoad();
|
||||
|
||||
sailingService.getLeaderboardNames(new MarkedAsyncCallback<List<String>>(
|
||||
new AsyncCallback<List<String>>() {
|
||||
@Override
|
||||
public void onSuccess(List<String> leaderboardNames) {
|
||||
String leaderboardName = Window.Location.getParameter("name");
|
||||
if (leaderboardNames.contains(leaderboardName)) {
|
||||
LogoAndTitlePanel logoAndTitlePanel = new LogoAndTitlePanel(getStringMessages().editScores(), getStringMessages(), LeaderboardEditPage.this, getUserService());
|
||||
logoAndTitlePanel.addStyleName("LogoAndTitlePanel");
|
||||
EditableLeaderboardPanel leaderboardPanel = new EditableLeaderboardPanel(sailingService, new AsyncActionsExecutor(), leaderboardName, null,
|
||||
LeaderboardEditPage.this, getStringMessages(), userAgent);
|
||||
leaderboardPanel.ensureDebugId("EditableLeaderboardPanel");
|
||||
RootPanel.get().add(logoAndTitlePanel);
|
||||
RootPanel.get().add(leaderboardPanel);
|
||||
} else {
|
||||
RootPanel.get().add(new Label(getStringMessages().noSuchLeaderboard()));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
reportError("Error trying to obtain list of leaderboard names: "+t.getMessage());
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
package com.sap.sailing.gwt.ui.leaderboardedit;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.dom.client.Style.FontWeight;
|
||||
import com.google.gwt.dom.client.Style.Position;
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.RootPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.gwt.ui.client.AbstractSailingEntryPoint;
|
||||
import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
|
||||
import com.sap.sse.gwt.client.async.MarkedAsyncCallback;
|
||||
import com.sap.sse.gwt.theme.client.component.sapheader2.SAPHeader2;
|
||||
|
||||
public class LeaderboardEditPage extends AbstractSailingEntryPoint {
|
||||
@Override
|
||||
protected void doOnModuleLoad() {
|
||||
super.doOnModuleLoad();
|
||||
|
||||
sailingService.getLeaderboardNames(new MarkedAsyncCallback<List<String>>(
|
||||
new AsyncCallback<List<String>>() {
|
||||
@Override
|
||||
public void onSuccess(List<String> leaderboardNames) {
|
||||
String leaderboardName = Window.Location.getParameter("name");
|
||||
if (leaderboardNames.contains(leaderboardName)) {
|
||||
EditableLeaderboardPanel leaderboardPanel = new EditableLeaderboardPanel(sailingService, new AsyncActionsExecutor(), leaderboardName, null,
|
||||
LeaderboardEditPage.this, getStringMessages(), userAgent);
|
||||
leaderboardPanel.ensureDebugId("EditableLeaderboardPanel");
|
||||
RootPanel.get().add(initHeader());
|
||||
RootPanel.get().add(leaderboardPanel);
|
||||
} else {
|
||||
RootPanel.get().add(new Label(getStringMessages().noSuchLeaderboard()));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
reportError("Error trying to obtain list of leaderboard names: "+t.getMessage());
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private Widget initHeader() {
|
||||
Label title = new Label(getStringMessages().editScores());
|
||||
title.getElement().getStyle().setColor("white");
|
||||
title.getElement().getStyle().setFontSize(20, Unit.PX);
|
||||
title.getElement().getStyle().setFontWeight(FontWeight.BOLD);
|
||||
title.getElement().getStyle().setMarginTop(16, Unit.PX);
|
||||
SAPHeader2 header = new SAPHeader2(getStringMessages().sapSailingAnalytics(), title, false);
|
||||
header.getElement().getStyle().setPosition(Position.FIXED);
|
||||
header.getElement().getStyle().setTop(0, Unit.PX);
|
||||
header.getElement().getStyle().setWidth(100, Unit.PCT);
|
||||
header.getElement().getStyle().setZIndex(1337);
|
||||
return header;
|
||||
}
|
||||
}
|
||||
+11
-11
@@ -4,7 +4,6 @@ import java.lang.ref.Reference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@@ -13,6 +12,7 @@ import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.impl.AbstractRaceChangeListener;
|
||||
import com.sap.sailing.gwt.ui.shared.QuickRankDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.QuickRanksDTO;
|
||||
import com.sap.sailing.server.masterdata.DummyTrackedRace;
|
||||
import com.sap.sse.util.SmartFutureCache;
|
||||
import com.sap.sse.util.SmartFutureCache.AbstractCacheUpdater;
|
||||
@@ -50,7 +50,7 @@ public class QuickRanksLiveCache {
|
||||
|
||||
private final WeakReference<? extends TrackedRace> stopRef = new WeakReference<TrackedRace>(dummyTrackedRace);
|
||||
|
||||
private final SmartFutureCache<RegattaAndRaceIdentifier, List<QuickRankDTO>, CalculateOrPurge> cache;
|
||||
private final SmartFutureCache<RegattaAndRaceIdentifier, QuickRanksDTO, CalculateOrPurge> cache;
|
||||
|
||||
private final SailingServiceImpl service;
|
||||
|
||||
@@ -72,19 +72,19 @@ public class QuickRanksLiveCache {
|
||||
|
||||
public QuickRanksLiveCache(final SailingServiceImpl service) {
|
||||
this.service = service;
|
||||
cache = new SmartFutureCache<RegattaAndRaceIdentifier, List<QuickRankDTO>, CalculateOrPurge>(
|
||||
new AbstractCacheUpdater<RegattaAndRaceIdentifier, List<QuickRankDTO>, CalculateOrPurge>() {
|
||||
cache = new SmartFutureCache<RegattaAndRaceIdentifier, QuickRanksDTO, CalculateOrPurge>(
|
||||
new AbstractCacheUpdater<RegattaAndRaceIdentifier, QuickRanksDTO, CalculateOrPurge>() {
|
||||
@Override
|
||||
public List<QuickRankDTO> computeCacheUpdate(RegattaAndRaceIdentifier key,
|
||||
public QuickRanksDTO computeCacheUpdate(RegattaAndRaceIdentifier key,
|
||||
CalculateOrPurge updateInterval) throws Exception {
|
||||
logger.fine("Computing cache update for live QuickRanks of race "+key);
|
||||
final List<QuickRankDTO> result;
|
||||
final QuickRanksDTO quickRanks;
|
||||
if (updateInterval == CalculateOrPurge.PURGE) {
|
||||
result = null;
|
||||
quickRanks = null;
|
||||
} else {
|
||||
result = service.computeQuickRanks(key, /* time point; null means live */ null);
|
||||
quickRanks = service.computeQuickRanks(key, /* time point; null means live */ null);
|
||||
}
|
||||
return result;
|
||||
return quickRanks;
|
||||
}
|
||||
}, getClass().getName());
|
||||
fromRefToRaceIdentifier = new HashMap<>();
|
||||
@@ -118,8 +118,8 @@ public class QuickRanksLiveCache {
|
||||
dummyTrackedRace = null; // release the dummy tracked race, causing the stopRef to be enqueued
|
||||
}
|
||||
|
||||
public List<QuickRankDTO> get(RegattaAndRaceIdentifier raceIdentifier) {
|
||||
List<QuickRankDTO> result = cache.get(raceIdentifier, false);
|
||||
public QuickRanksDTO get(RegattaAndRaceIdentifier raceIdentifier) {
|
||||
QuickRanksDTO result = cache.get(raceIdentifier, false);
|
||||
if (result == null) {
|
||||
TrackedRace trackedRace = service.getExistingTrackedRace(raceIdentifier);
|
||||
if (trackedRace != null) {
|
||||
|
||||
+28
-13
@@ -238,6 +238,7 @@ import com.sap.sailing.domain.racelogtracking.DeviceMapping;
|
||||
import com.sap.sailing.domain.racelogtracking.RaceLogTrackingAdapter;
|
||||
import com.sap.sailing.domain.racelogtracking.RaceLogTrackingAdapterFactory;
|
||||
import com.sap.sailing.domain.racelogtracking.impl.DeviceMappingImpl;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
||||
import com.sap.sailing.domain.ranking.RankingMetricsFactory;
|
||||
import com.sap.sailing.domain.regattalike.HasRegattaLike;
|
||||
import com.sap.sailing.domain.regattalike.LeaderboardThatHasRegattaLike;
|
||||
@@ -303,6 +304,7 @@ import com.sap.sailing.gwt.ui.shared.MarkPassingTimesDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.MarkpassingManeuverDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.PathDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.QuickRankDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.QuickRanksDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceCourseDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceGroupDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceGroupSeriesDTO;
|
||||
@@ -1570,7 +1572,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
fromPerCompetitorIdAsString, toPerCompetitorIdAsString, extrapolate);
|
||||
final CoursePositionsDTO coursePositions = getCoursePositions(raceIdentifier, date);
|
||||
final List<SidelineDTO> courseSidelines = getCourseSidelines(raceIdentifier, date);
|
||||
final List<QuickRankDTO> quickRanks = getQuickRanks(raceIdentifier, date);
|
||||
final QuickRanksDTO quickRanks = getQuickRanks(raceIdentifier, date);
|
||||
int simulationResultVersion = 0;
|
||||
if (simulationLegIdentifier != null) {
|
||||
SimulationService simulationService = getService().getSimulationService();
|
||||
@@ -2029,9 +2031,10 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
* <code>null</code> means "live" and is then replaced by "now" minus the tracked race's
|
||||
* {@link TrackedRace#getDelayToLiveInMillis() delay}.
|
||||
*/
|
||||
public List<QuickRankDTO> computeQuickRanks(RegattaAndRaceIdentifier raceIdentifier, TimePoint timePoint)
|
||||
public QuickRanksDTO computeQuickRanks(RegattaAndRaceIdentifier raceIdentifier, TimePoint timePoint)
|
||||
throws NoWindException {
|
||||
List<QuickRankDTO> result = new ArrayList<QuickRankDTO>();
|
||||
final List<QuickRankDTO> result = new ArrayList<>();
|
||||
final List<CompetitorDTO> competitorDTOsInOrderOfWindwardDistanceTraveledFarthestFirst;
|
||||
TrackedRace trackedRace = getExistingTrackedRace(raceIdentifier);
|
||||
if (trackedRace != null) {
|
||||
final TimePoint actualTimePoint;
|
||||
@@ -2052,12 +2055,17 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
}
|
||||
rank++;
|
||||
}
|
||||
final Iterable<Competitor> competitorsInOrderOfWindwardDistanceTraveledFarthestFirst = getService()
|
||||
.getCompetitorInOrderOfWindwardDistanceTraveledFarthestFirst(trackedRace, actualTimePoint);
|
||||
competitorDTOsInOrderOfWindwardDistanceTraveledFarthestFirst = convertToCompetitorDTOs(competitorsInOrderOfWindwardDistanceTraveledFarthestFirst);
|
||||
} else {
|
||||
competitorDTOsInOrderOfWindwardDistanceTraveledFarthestFirst = Collections.emptyList();
|
||||
}
|
||||
return result;
|
||||
return new QuickRanksDTO(result, competitorDTOsInOrderOfWindwardDistanceTraveledFarthestFirst);
|
||||
}
|
||||
|
||||
private List<QuickRankDTO> getQuickRanks(RegattaAndRaceIdentifier raceIdentifier, Date date) throws NoWindException {
|
||||
final List<QuickRankDTO> result;
|
||||
private QuickRanksDTO getQuickRanks(RegattaAndRaceIdentifier raceIdentifier, Date date) throws NoWindException {
|
||||
final QuickRanksDTO result;
|
||||
if (date == null) {
|
||||
result = quickRanksLiveCache.get(raceIdentifier);
|
||||
} else {
|
||||
@@ -2091,7 +2099,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
Map<WindSource, WindTrackInfoDTO> windTrackInfoDTOs = new HashMap<WindSource, WindTrackInfoDTO>();
|
||||
result.windTrackInfoByWindSource = windTrackInfoDTOs;
|
||||
|
||||
for(WindSource windSource: trackedRace.getWindSources()) {
|
||||
for (WindSource windSource: trackedRace.getWindSources()) {
|
||||
windTrackInfoDTOs.put(windSource, new WindTrackInfoDTO());
|
||||
}
|
||||
windTrackInfoDTOs.put(new WindSourceImpl(WindSourceType.COMBINED), new WindTrackInfoDTO());
|
||||
@@ -2720,13 +2728,15 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
break;
|
||||
case GAP_TO_LEADER_IN_SECONDS:
|
||||
if (trackedLeg != null) {
|
||||
final Duration gapToLeaderInOwnTime = trackedLeg.getTrackedLeg().getTrackedRace().getRankingMetric().getGapToLeaderInOwnTime(competitor, timePoint, cache);
|
||||
final RankingInfo rankingInfo = trackedRace.getRankingMetric().getRankingInfo(timePoint);
|
||||
final Duration gapToLeaderInOwnTime = trackedLeg.getTrackedLeg().getTrackedRace().getRankingMetric().getGapToLeaderInOwnTime(rankingInfo, competitor, cache);
|
||||
result = gapToLeaderInOwnTime == null ? null : gapToLeaderInOwnTime.asSeconds();
|
||||
}
|
||||
break;
|
||||
case WINDWARD_DISTANCE_TO_OVERALL_LEADER:
|
||||
case WINDWARD_DISTANCE_TO_COMPETITOR_FARTHEST_AHEAD:
|
||||
if (trackedLeg != null) {
|
||||
Distance distanceToLeader = trackedLeg.getWindwardDistanceToOverallLeader(timePoint, WindPositionMode.LEG_MIDDLE);
|
||||
final RankingInfo rankingInfo = trackedRace.getRankingMetric().getRankingInfo(timePoint);
|
||||
Distance distanceToLeader = trackedLeg.getWindwardDistanceToCompetitorFarthestAhead(timePoint, WindPositionMode.LEG_MIDDLE, rankingInfo);
|
||||
result = (distanceToLeader == null) ? null : distanceToLeader.getMeters();
|
||||
}
|
||||
break;
|
||||
@@ -4772,9 +4782,14 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
for (Regatta regatta : allRegattas) {
|
||||
DynamicTrackedRegatta trackedRegatta = getService().getTrackedRegatta(regatta);
|
||||
if (trackedRegatta != null) {
|
||||
Iterable<DynamicTrackedRace> trackedRaces = trackedRegatta.getTrackedRaces();
|
||||
for (TrackedRace trackedRace : trackedRaces) {
|
||||
result.add((DynamicTrackedRace) trackedRace);
|
||||
trackedRegatta.lockTrackedRacesForRead();
|
||||
try {
|
||||
Iterable<DynamicTrackedRace> trackedRaces = trackedRegatta.getTrackedRaces();
|
||||
for (TrackedRace trackedRace : trackedRaces) {
|
||||
result.add((DynamicTrackedRace) trackedRace);
|
||||
}
|
||||
} finally {
|
||||
trackedRegatta.unlockTrackedRacesAfterRead();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ public class DispatchRPCImpl extends ProxiedRemoteServiceServlet implements Disp
|
||||
|
||||
@Override
|
||||
public <R extends Result, A extends Action<R>> ResultWrapper<R> execute(RequestWrapper<R, A> request) throws DispatchException {
|
||||
R executionResult = request.getAction().execute(new DispatchContextImpl(request.getCurrentClientTime(), racingEventServiceTracker.getService()));
|
||||
R executionResult = request.getAction().execute(new DispatchContextImpl(request.getCurrentClientTime(), racingEventServiceTracker.getService(), request.getClientLocaleName()));
|
||||
return new ResultWrapper<R>(executionResult);
|
||||
}
|
||||
|
||||
|
||||
+21
-3
@@ -5,10 +5,12 @@ import java.util.HashMap;
|
||||
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.common.dto.CompetitorDTO;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
/**
|
||||
* A compact representation of a {@link RaceMapDataDTO} that represents competitors by their ID only instead of a
|
||||
@@ -25,21 +27,30 @@ public class CompactRaceMapDataDTO implements IsSerializable {
|
||||
private CoursePositionsDTO coursePositions;
|
||||
private List<SidelineDTO> courseSidelines;
|
||||
private List<CompactQuickRankDTO> quickRanks;
|
||||
private LinkedHashMap<String, Integer> competitorsInOrderOfWindwardDistanceTraveledFarthestFirstIdAsStringAndOneBasedLegNumber;
|
||||
private int simulationResultVersion;
|
||||
|
||||
CompactRaceMapDataDTO() {}
|
||||
|
||||
public CompactRaceMapDataDTO(Map<CompetitorDTO, List<GPSFixDTO>> boatPositions, CoursePositionsDTO coursePositions,
|
||||
List<SidelineDTO> courseSidelines, List<QuickRankDTO> quickRanks, int simulationResultVersion) {
|
||||
List<SidelineDTO> courseSidelines, QuickRanksDTO quickRanks, int simulationResultVersion) {
|
||||
this.boatPositionsByCompetitorIdAsString = new HashMap<String, List<GPSFixDTO>>();
|
||||
for (Map.Entry<CompetitorDTO, List<GPSFixDTO>> e : boatPositions.entrySet()) {
|
||||
this.boatPositionsByCompetitorIdAsString.put(e.getKey().getIdAsString(), e.getValue());
|
||||
}
|
||||
this.quickRanks = new ArrayList<CompactQuickRankDTO>(quickRanks == null ? 0 : quickRanks.size());
|
||||
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) {
|
||||
for (QuickRankDTO quickRank : quickRanks.getQuickRanks()) {
|
||||
this.quickRanks.add(new CompactQuickRankDTO(quickRank.competitor.getIdAsString(), quickRank.rank,
|
||||
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;
|
||||
@@ -70,6 +81,13 @@ public class CompactRaceMapDataDTO implements IsSerializable {
|
||||
result.boatPositions.put(competitor, e.getValue());
|
||||
}
|
||||
}
|
||||
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;
|
||||
return result;
|
||||
}
|
||||
|
||||
Loaded 100 of 202 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user