mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-02 10:23:51 +00:00
added tests for RaceLog-based ORC PCS leg definitions
Change-Id: Iddb5c41079fea3de8428f45597a6d79f8d02bee4
This commit is contained in:
1 parent
a34966fc75
commit
f00585d4cd
14 files changed
+279
-47
No files matched your search
+2
-1
@@ -22,7 +22,8 @@ public interface ORCPerformanceCurveCourse {
|
||||
|
||||
/**
|
||||
* @return summed up {@link Distance} of all {@link ORCPerformanceCurveLeg}s of an implementing instance of this
|
||||
* class
|
||||
* class; {@code null} in case the length currently cannot be determined, e.g., because no explicit lengths
|
||||
* have been set and the positions of one or more waypoints are unknown.
|
||||
*/
|
||||
default Distance getTotalLength() {
|
||||
Distance result = Distance.NULL;
|
||||
|
||||
+16
-26
@@ -1,50 +1,40 @@
|
||||
package com.sap.sailing.domain.common.orc.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.sap.sailing.domain.common.orc.ORCPerformanceCurveCourse;
|
||||
import com.sap.sailing.domain.common.orc.ORCPerformanceCurveLeg;
|
||||
import com.sap.sse.common.Distance;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
public class ORCPerformanceCurveCourseImpl implements ORCPerformanceCurveCourse {
|
||||
private final List<ORCPerformanceCurveLeg> legs;
|
||||
private final Distance totalLength;
|
||||
private final Iterable<ORCPerformanceCurveLeg> legs;
|
||||
|
||||
public ORCPerformanceCurveCourseImpl(List<ORCPerformanceCurveLeg> legs) {
|
||||
this.legs = Collections.unmodifiableList(legs);
|
||||
Distance myTotalLength = Distance.NULL;
|
||||
for (ORCPerformanceCurveLeg leg : legs) {
|
||||
myTotalLength = myTotalLength.add(leg.getLength());
|
||||
}
|
||||
totalLength = myTotalLength;
|
||||
}
|
||||
|
||||
public ORCPerformanceCurveLeg getLeg(int i) {
|
||||
return legs.get(i);
|
||||
public ORCPerformanceCurveCourseImpl(Iterable<ORCPerformanceCurveLeg> legs) {
|
||||
this.legs = legs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getTotalLength() {
|
||||
return totalLength;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ORCPerformanceCurveLeg> getLegs() {
|
||||
public Iterable<ORCPerformanceCurveLeg> getLegs() {
|
||||
return legs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ORCPerformanceCurveCourse subcourse(int lastFinishedLegOneBased, double shareOfCurrentLeg) {
|
||||
// does function for empty courses, returns again empty course
|
||||
if (lastFinishedLegOneBased >= legs.size()) {
|
||||
if (lastFinishedLegOneBased >= Util.size(legs)) {
|
||||
return this;
|
||||
} else {
|
||||
List<ORCPerformanceCurveLeg> resultLegs = new ArrayList<>();
|
||||
resultLegs.addAll(legs.subList(0, lastFinishedLegOneBased));
|
||||
ORCPerformanceCurveLeg lastFinishedLeg = legs.get(lastFinishedLegOneBased);
|
||||
int count = 0;
|
||||
ORCPerformanceCurveLeg lastFinishedLeg = null;
|
||||
for (final ORCPerformanceCurveLeg leg : getLegs()) {
|
||||
if (count++ >= lastFinishedLegOneBased) {
|
||||
lastFinishedLeg = leg;
|
||||
break;
|
||||
}
|
||||
resultLegs.add(leg);
|
||||
}
|
||||
resultLegs.add(lastFinishedLeg.scale(shareOfCurrentLeg));
|
||||
return new ORCPerformanceCurveCourseImpl(resultLegs);
|
||||
}
|
||||
@@ -52,6 +42,6 @@ public class ORCPerformanceCurveCourseImpl implements ORCPerformanceCurveCourse
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[legs=" + legs + ", totalLength=" + totalLength + "]";
|
||||
return "[legs=" + legs + ", totalLength=" + getTotalLength().getNauticalMiles() + "NM]";
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -41,7 +41,7 @@ public class ORCPerformanceCurveLegImpl implements ORCPerformanceCurveLeg {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[length=" + length.getNauticalMiles() + "NM, "+(twa==null?type.name():"TWA=" + twa.getDegrees() + "°")+"]";
|
||||
return "[length=" + length.getNauticalMiles() + "NM, "+(twa==null?type.name():"TWA=" + twa)+"]";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -1019,7 +1019,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
Document result = new Document();
|
||||
storeRaceLogEventProperties(event, result);
|
||||
result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), RaceLogORCLegDataEvent.class.getSimpleName());
|
||||
result.put(FieldNames.ORC_LEG_NR.name(), event.getLegNr());
|
||||
result.put(FieldNames.ORC_LEG_NR.name(), event.getOneBasedLegNumber());
|
||||
result.put(FieldNames.ORC_LEG_LENGTH_IN_NAUTICAL_MILES.name(), event.getLength().getNauticalMiles());
|
||||
result.put(FieldNames.ORC_LEG_TWA_IN_DEG.name(), event.getTwa().getDegrees());
|
||||
result.put(FieldNames.ORC_LEG_TYPE.name(), event.getType().name());
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ public interface RevokeEvent<VisitorT> extends AbstractLogEvent<VisitorT> {
|
||||
String getReason();
|
||||
|
||||
/**
|
||||
* {@link Class#getSimpleName() Simple class name} of the revoked event.
|
||||
* {@link Class#getName() Fully-qualified class name} of the revoked event.
|
||||
*/
|
||||
String getRevokedEventType();
|
||||
}
|
||||
+5
-5
@@ -12,10 +12,10 @@ import com.sap.sailing.domain.common.orc.impl.ORCPerformanceCurveLegImpl;
|
||||
import com.sap.sse.common.Distance;
|
||||
|
||||
/**
|
||||
* Returns a map with unique entries per {@link RaceLogORCLegDataEvent#getLegNr() leg number} where the
|
||||
* relevant valid leg data is converted to the {@link ORCPerformanceCurveLeg} data. Note that for legs
|
||||
* for which no entry is found no adapter to any tracked race or tracked leg is created implicitly. Only
|
||||
* entries with explicit race log events are returned.
|
||||
* Returns a map with unique entries per {@link RaceLogORCLegDataEvent#getOneBasedLegNumber() one-based leg number}
|
||||
* where the relevant valid leg data is converted to the {@link ORCPerformanceCurveLeg} data. Note that for legs for
|
||||
* which no entry is found no adapter to any tracked race or tracked leg is created implicitly. Only entries with
|
||||
* explicit race log events are returned.
|
||||
*
|
||||
* @author Axel Uhl (D043530)
|
||||
*
|
||||
@@ -40,7 +40,7 @@ public class RaceLogORCLegDataAnalyzer extends RaceLogAnalyzer<Map<Integer, ORCP
|
||||
} else {
|
||||
leg = new ORCPerformanceCurveLegImpl(length, legDataEvent.getType());
|
||||
}
|
||||
result.put(legDataEvent.getLegNr(), leg);
|
||||
result.put(legDataEvent.getOneBasedLegNumber(), leg);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
+1
-1
@@ -23,6 +23,6 @@ public interface RaceLogORCLegDataEvent extends RaceLogEvent, Revokable {
|
||||
|
||||
public Bearing getTwa();
|
||||
|
||||
public int getLegNr();
|
||||
public int getOneBasedLegNumber();
|
||||
|
||||
}
|
||||
+6
-6
@@ -15,15 +15,15 @@ public class RaceLogORCLegDataEventImpl extends RaceLogEventImpl implements Race
|
||||
|
||||
private static final long serialVersionUID = -5063350268001993185L;
|
||||
|
||||
private final int legNr;
|
||||
private final int oneBasedLegNumber;
|
||||
private final Bearing twa;
|
||||
private final Distance length;
|
||||
private final ORCPerformanceCurveLegTypes type;
|
||||
|
||||
public RaceLogORCLegDataEventImpl(TimePoint createdAt, TimePoint logicalTimePoint, AbstractLogEventAuthor author,
|
||||
Serializable pId, int pPassId, int legNr, Bearing twa, Distance length, ORCPerformanceCurveLegTypes type) {
|
||||
Serializable pId, int pPassId, int oneBasedLegNumber, Bearing twa, Distance length, ORCPerformanceCurveLegTypes type) {
|
||||
super(createdAt, logicalTimePoint, author, pId, pPassId);
|
||||
this.legNr = legNr;
|
||||
this.oneBasedLegNumber = oneBasedLegNumber;
|
||||
this.twa = twa;
|
||||
this.length = length;
|
||||
this.type = type;
|
||||
@@ -36,12 +36,12 @@ public class RaceLogORCLegDataEventImpl extends RaceLogEventImpl implements Race
|
||||
|
||||
@Override
|
||||
public String getShortInfo() {
|
||||
return "ORCLegData, legNr= " + legNr + ", twa: " + twa.getDegrees() + ", length: " + length.getNauticalMiles();
|
||||
return "ORCLegData, oneBasedLegNumber= " + oneBasedLegNumber + ", twa: " + twa.getDegrees() + ", length: " + length.getNauticalMiles();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLegNr() {
|
||||
return legNr;
|
||||
public int getOneBasedLegNumber() {
|
||||
return oneBasedLegNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+211
@@ -0,0 +1,211 @@
|
||||
package com.sap.sailing.domain.orc;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||
import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl;
|
||||
import com.sap.sailing.domain.abstractlog.orc.RaceLogORCCertificateAssignmentEvent;
|
||||
import com.sap.sailing.domain.abstractlog.orc.RaceLogORCLegDataEvent;
|
||||
import com.sap.sailing.domain.abstractlog.orc.RegattaLogORCCertificateAssignmentEvent;
|
||||
import com.sap.sailing.domain.abstractlog.orc.impl.RaceLogORCCertificateAssignmentEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.orc.impl.RaceLogORCLegDataEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.orc.impl.RegattaLogORCCertificateAssignmentEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogImpl;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CompetitorWithBoat;
|
||||
import com.sap.sailing.domain.common.abstractlog.NotRevokableException;
|
||||
import com.sap.sailing.domain.common.impl.NauticalMileDistance;
|
||||
import com.sap.sailing.domain.common.orc.ORCCertificate;
|
||||
import com.sap.sailing.domain.common.orc.ORCPerformanceCurveCourse;
|
||||
import com.sap.sailing.domain.common.orc.ORCPerformanceCurveLeg;
|
||||
import com.sap.sailing.domain.common.orc.ORCPerformanceCurveLegTypes;
|
||||
import com.sap.sailing.domain.orc.impl.ORCPerformanceCurveLegAdapter;
|
||||
import com.sap.sailing.domain.orc.impl.ORCPerformanceCurveRankingMetric;
|
||||
import com.sap.sailing.domain.test.TrackBasedTest;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
|
||||
/**
|
||||
* An {@link ORCPerformanceCurveRankingMetric} observes its {@link TrackedRace} for the regatta log
|
||||
* and the race logs, regarding the attachment and detachment of such logs, as well as regarding
|
||||
* the appearance of new certificate assignment events in those logs. This test verifies that
|
||||
* the dynamics work as expected.
|
||||
*
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public class TestORCRankingMetricCollaborationWithRaceLogAndRegattaLog {
|
||||
private Boat boat1, boat2;
|
||||
private CompetitorWithBoat competitor1, competitor2;
|
||||
private DynamicTrackedRaceImpl trackedRace;
|
||||
private RaceLog raceLog;
|
||||
private RegattaLog regattaLog;
|
||||
private ORCPerformanceCurveRankingMetric rankingMetric;
|
||||
private AbstractLogEventAuthor authorP1 = new LogEventAuthorImpl("Test Author P1", 1);
|
||||
private AbstractLogEventAuthor authorP2 = new LogEventAuthorImpl("Test Author P2", 2);
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
final RaceLogResolver raceLogResolver = createRaceLogResolver();
|
||||
competitor1 = TrackBasedTest.createCompetitorWithBoat("C1");
|
||||
competitor2 = TrackBasedTest.createCompetitorWithBoat("C2");
|
||||
final Map<Competitor, Boat> competitorsAndBoats = TrackBasedTest.createCompetitorAndBoatsMap(competitor1, competitor2);
|
||||
boat1 = competitorsAndBoats.get(competitor1);
|
||||
boat2 = competitorsAndBoats.get(competitor2);
|
||||
trackedRace = TrackBasedTest.createTestTrackedRace("TestRegatta", "TestRace", "F18", competitorsAndBoats,
|
||||
MillisecondsTimePoint.now(), /* useMarkPassingCalculator */ false, raceLogResolver, ORCPerformanceCurveRankingMetric::new);
|
||||
regattaLog = trackedRace.getTrackedRegatta().getRegatta().getRegattaLog();
|
||||
trackedRace.attachRegattaLog(regattaLog);
|
||||
assertSame(regattaLog, trackedRace.getAttachedRegattaLogs().iterator().next());
|
||||
raceLog = new RaceLogImpl(UUID.randomUUID());
|
||||
rankingMetric = (ORCPerformanceCurveRankingMetric) trackedRace.getRankingMetric();
|
||||
}
|
||||
|
||||
private void attachRaceLog() {
|
||||
trackedRace.attachRaceLog(raceLog);
|
||||
}
|
||||
|
||||
private RaceLogResolver createRaceLogResolver() {
|
||||
return new RaceLogResolver() {
|
||||
@Override
|
||||
public RaceLog resolve(SimpleRaceLogIdentifier identifier) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCertificateAssignments() {
|
||||
// no logs attached; therefore no certs
|
||||
assertNoCertificate(boat1);
|
||||
assertNoCertificate(boat2);
|
||||
attachRaceLog();
|
||||
// empty race log attached, still no certs:
|
||||
assertNoCertificate(boat1);
|
||||
assertNoCertificate(boat2);
|
||||
ORCCertificate boat1RegattaCert1 = mock(ORCCertificate.class);
|
||||
regattaLog.add(createRegattaLogCertificateAssignmentEvent(boat1RegattaCert1, boat1, authorP1));
|
||||
assertCertificate(boat1, boat1RegattaCert1);
|
||||
ORCCertificate boat1RegattaCert2 = mock(ORCCertificate.class);
|
||||
regattaLog.add(createRegattaLogCertificateAssignmentEvent(boat1RegattaCert2, boat1, authorP2));
|
||||
// the priority for Cert2 was 2 and therefore the P1 assignment still takes precedence
|
||||
assertCertificate(boat1, boat1RegattaCert1);
|
||||
regattaLog.add(createRegattaLogCertificateAssignmentEvent(boat1RegattaCert2, boat1, authorP1));
|
||||
assertCertificate(boat1, boat1RegattaCert2);
|
||||
ORCCertificate boat2RegattaCert1 = mock(ORCCertificate.class);
|
||||
regattaLog.add(createRegattaLogCertificateAssignmentEvent(boat2RegattaCert1, boat2, authorP2));
|
||||
assertCertificate(boat2, boat2RegattaCert1);
|
||||
// now override on race log level:
|
||||
ORCCertificate boat1RaceCert1 = mock(ORCCertificate.class);
|
||||
raceLog.add(createRaceLogCertificateAssignmentEvent(boat1RaceCert1, boat1, authorP2));
|
||||
assertCertificate(boat1, boat1RaceCert1);
|
||||
trackedRace.detachRaceLog(raceLog.getId());
|
||||
// after detaching race log, boat1 must have defaulted again to the regatta log's definition
|
||||
assertCertificate(boat1, boat1RegattaCert2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoCourseDefinitionsInRaceLog() {
|
||||
final ORCPerformanceCurveCourse orcCourse = rankingMetric.getTotalCourse();
|
||||
assertEquals(trackedRace.getRace().getCourse().getLegs().size(), Util.size(orcCourse.getLegs()));
|
||||
for (final ORCPerformanceCurveLeg leg : orcCourse.getLegs()) {
|
||||
assertTrue(leg instanceof ORCPerformanceCurveLegAdapter); // only adapters, no explicit leg specification yet
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneLegDefinitionInRaceLog() throws NotRevokableException {
|
||||
attachRaceLog();
|
||||
final double lengthInNauticalMiles = 1.7;
|
||||
final double twaInDegrees = 2.0;
|
||||
final RaceLogORCLegDataEvent firstLegSpecificationEvent = createLegSpecificationEvent(
|
||||
/* one-based leg number */ 1, ORCPerformanceCurveLegTypes.TWA, /* distance in nautical miles */ lengthInNauticalMiles,
|
||||
/* TWA */ twaInDegrees, authorP2);
|
||||
raceLog.add(firstLegSpecificationEvent);
|
||||
final ORCPerformanceCurveCourse orcCourse = rankingMetric.getTotalCourse();
|
||||
assertEquals(trackedRace.getRace().getCourse().getLegs().size(), Util.size(orcCourse.getLegs()));
|
||||
final ORCPerformanceCurveLeg firstLeg = orcCourse.getLegs().iterator().next();
|
||||
assertFalse(firstLeg instanceof ORCPerformanceCurveLegAdapter);
|
||||
assertEquals(lengthInNauticalMiles, firstLeg.getLength().getNauticalMiles(), 0.000001);
|
||||
assertEquals(twaInDegrees, firstLeg.getTwa().getDegrees(), 0.0000001);
|
||||
// now revoke event and ensure that the course defaults back to all adapters:
|
||||
raceLog.revokeEvent(authorP2, firstLegSpecificationEvent);
|
||||
assertEquals(trackedRace.getRace().getCourse().getLegs().size(), Util.size(rankingMetric.getTotalCourse().getLegs()));
|
||||
for (final ORCPerformanceCurveLeg leg : rankingMetric.getTotalCourse().getLegs()) {
|
||||
assertTrue(leg instanceof ORCPerformanceCurveLegAdapter); // only adapters, no explicit leg specification anymore
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHigherPriorityLegDefinitionInRaceLogWins() throws NotRevokableException {
|
||||
attachRaceLog();
|
||||
final double lengthInNauticalMiles = 1.7;
|
||||
final double twaP1InDegrees = 1.0;
|
||||
final double twaP2InDegrees = 2.0;
|
||||
final RaceLogORCLegDataEvent firstLegP2SpecificationEvent = createLegSpecificationEvent(
|
||||
/* one-based leg number */ 1, ORCPerformanceCurveLegTypes.TWA, /* distance in nautical miles */ lengthInNauticalMiles,
|
||||
/* TWA */ twaP2InDegrees, authorP2);
|
||||
raceLog.add(firstLegP2SpecificationEvent);
|
||||
final RaceLogORCLegDataEvent firstLegP1SpecificationEvent = createLegSpecificationEvent(
|
||||
/* one-based leg number */ 1, ORCPerformanceCurveLegTypes.TWA, /* distance in nautical miles */ lengthInNauticalMiles,
|
||||
/* TWA */ twaP1InDegrees, authorP1);
|
||||
raceLog.add(firstLegP1SpecificationEvent);
|
||||
final ORCPerformanceCurveCourse orcCourse = rankingMetric.getTotalCourse();
|
||||
assertEquals(trackedRace.getRace().getCourse().getLegs().size(), Util.size(orcCourse.getLegs()));
|
||||
final ORCPerformanceCurveLeg firstLeg = orcCourse.getLegs().iterator().next();
|
||||
assertFalse(firstLeg instanceof ORCPerformanceCurveLegAdapter);
|
||||
assertEquals(lengthInNauticalMiles, firstLeg.getLength().getNauticalMiles(), 0.000001);
|
||||
assertEquals(twaP1InDegrees, firstLeg.getTwa().getDegrees(), 0.0000001);
|
||||
// now revoke P1 event and ensure that the course defaults to the P2 definition:
|
||||
raceLog.revokeEvent(authorP1, firstLegP1SpecificationEvent);
|
||||
assertEquals(trackedRace.getRace().getCourse().getLegs().size(), Util.size(rankingMetric.getTotalCourse().getLegs()));
|
||||
assertEquals(twaP2InDegrees, rankingMetric.getTotalCourse().getLegs().iterator().next().getTwa().getDegrees(), 0.0000001);
|
||||
}
|
||||
|
||||
private RaceLogORCLegDataEvent createLegSpecificationEvent(int oneBasedLegNumber,
|
||||
ORCPerformanceCurveLegTypes legType, double lengthInNauticalMiles, double twaInDegrees,
|
||||
AbstractLogEventAuthor author) {
|
||||
return new RaceLogORCLegDataEventImpl(MillisecondsTimePoint.now(), MillisecondsTimePoint.now(), author,
|
||||
UUID.randomUUID(), /* pass */ 0, oneBasedLegNumber, new DegreeBearingImpl(twaInDegrees),
|
||||
new NauticalMileDistance(lengthInNauticalMiles), legType);
|
||||
}
|
||||
|
||||
private RaceLogORCCertificateAssignmentEvent createRaceLogCertificateAssignmentEvent(
|
||||
ORCCertificate certificate, Boat boat, AbstractLogEventAuthor author) {
|
||||
return new RaceLogORCCertificateAssignmentEventImpl(MillisecondsTimePoint.now(), MillisecondsTimePoint.now(), author, UUID.randomUUID(), /* pass */ 0, certificate, boat);
|
||||
}
|
||||
|
||||
private RegattaLogORCCertificateAssignmentEvent createRegattaLogCertificateAssignmentEvent(
|
||||
ORCCertificate certificate, Boat boat, AbstractLogEventAuthor author) {
|
||||
return new RegattaLogORCCertificateAssignmentEventImpl(MillisecondsTimePoint.now(), MillisecondsTimePoint.now(), author, UUID.randomUUID(), certificate, boat);
|
||||
}
|
||||
|
||||
private void assertNoCertificate(Boat boat) {
|
||||
final ORCCertificate certificate = rankingMetric.getCertificate(boat);
|
||||
assertNull(certificate);
|
||||
}
|
||||
|
||||
private void assertCertificate(Boat boat, ORCCertificate expectedCertificate) {
|
||||
final ORCCertificate certificate = rankingMetric.getCertificate(boat);
|
||||
assertSame(expectedCertificate, certificate);
|
||||
}
|
||||
}
|
||||
+5
@@ -50,4 +50,9 @@ public class ORCPerformanceCurveLegAdapter implements ORCPerformanceCurveLeg {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ORCPerformanceCurveLegAdapter for "+trackedLeg.getLeg()+": length="+getLength().getNauticalMiles()+"NM, TWA="+getTwa();
|
||||
}
|
||||
}
|
||||
+27
-2
@@ -1,8 +1,10 @@
|
||||
package com.sap.sailing.domain.orc.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@@ -13,8 +15,10 @@ import com.sap.sailing.domain.abstractlog.orc.RaceLogORCLegDataAnalyzer;
|
||||
import com.sap.sailing.domain.abstractlog.orc.RaceLogORCLegDataEvent;
|
||||
import com.sap.sailing.domain.abstractlog.orc.RegattaLogORCCertificateAssignmentEvent;
|
||||
import com.sap.sailing.domain.abstractlog.orc.RegattaLogORCCertificateAssignmentFinder;
|
||||
import com.sap.sailing.domain.abstractlog.orc.impl.RaceLogORCLegDataEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogRevokeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.BaseRaceLogEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
||||
@@ -27,6 +31,7 @@ import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.orc.ORCCertificate;
|
||||
import com.sap.sailing.domain.common.orc.ORCPerformanceCurveCourse;
|
||||
import com.sap.sailing.domain.common.orc.ORCPerformanceCurveLeg;
|
||||
import com.sap.sailing.domain.common.orc.impl.ORCPerformanceCurveCourseImpl;
|
||||
import com.sap.sailing.domain.ranking.AbstractRankingMetric;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric;
|
||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||
@@ -37,6 +42,7 @@ import com.sap.sailing.domain.tracking.impl.AbstractRaceChangeListener;
|
||||
import com.sap.sse.common.Distance;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
public class ORCPerformanceCurveRankingMetric extends AbstractRankingMetric {
|
||||
private static final long serialVersionUID = -7814822523533929816L;
|
||||
@@ -62,6 +68,7 @@ public class ORCPerformanceCurveRankingMetric extends AbstractRankingMetric {
|
||||
super(trackedRace);
|
||||
boatsById = initBoatsById();
|
||||
updateCertificatesFromLogs();
|
||||
updateCourseFromRaceLogs();
|
||||
certificatesFromRaceLogUpdater = createCertificatesFromRaceLogUpdater();
|
||||
certificatesFromRegattaLogUpdater = createCertificatesFromRegattaLogUpdater();
|
||||
if (trackedRace != null) {
|
||||
@@ -101,13 +108,20 @@ public class ORCPerformanceCurveRankingMetric extends AbstractRankingMetric {
|
||||
return new BaseRaceLogEventVisitor() {
|
||||
@Override
|
||||
public void visit(RaceLogORCLegDataEvent orcLegDataEventImpl) {
|
||||
updateCertificatesFromLogs();
|
||||
updateCourseFromRaceLogs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RaceLogORCCertificateAssignmentEvent event) {
|
||||
updateCertificatesFromLogs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RaceLogRevokeEvent event) {
|
||||
if (event.getRevokedEventType().equals(RaceLogORCLegDataEventImpl.class.getName())) {
|
||||
updateCourseFromRaceLogs();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -143,7 +157,18 @@ public class ORCPerformanceCurveRankingMetric extends AbstractRankingMetric {
|
||||
for (final RaceLog raceLog : getTrackedRace().getAttachedRaceLogs()) {
|
||||
legsWithDefinitions.putAll(new RaceLogORCLegDataAnalyzer(raceLog).analyze());
|
||||
}
|
||||
// TODO continue here, taking only those definitions up to the true number of legs in the race's course and fill the blanks with tracked leg adapters
|
||||
final Iterable<Leg> legs = getTrackedRace().getRace().getCourse().getLegs();
|
||||
int oneBasedLegNumber = 1;
|
||||
final List<ORCPerformanceCurveLeg> performanceCurveLegs = new ArrayList<>(Util.size(legs));
|
||||
for (final Leg leg : legs) {
|
||||
performanceCurveLegs.add(legsWithDefinitions.computeIfAbsent(oneBasedLegNumber, i->new ORCPerformanceCurveLegAdapter(getTrackedRace().getTrackedLeg(leg))));
|
||||
oneBasedLegNumber++;
|
||||
}
|
||||
totalCourse = new ORCPerformanceCurveCourseImpl(performanceCurveLegs);
|
||||
}
|
||||
|
||||
public ORCPerformanceCurveCourse getTotalCourse() {
|
||||
return totalCourse;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -445,7 +445,6 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
RaceLogResolver raceLogResolver) {
|
||||
super(race, trackedRegatta, windStore, millisecondsOverWhichToAverageWind);
|
||||
this.raceLogResolver = raceLogResolver;
|
||||
rankingMetric = rankingMetricConstructor.apply(this);
|
||||
raceStates = new WeakHashMap<>();
|
||||
shortTimeWindCache = new ShortTimeWindCache(this, millisecondsOverWhichToAverageWind / 2);
|
||||
locksForMarkPassings = new ConcurrentHashMap<IdentityWrapper<Iterable<MarkPassing>>, NamedReentrantReadWriteLock>();
|
||||
@@ -579,6 +578,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
} catch (InterruptedException e) {
|
||||
logger.log(Level.SEVERE, "Waiting for loading from stores to finish was interrupted", e);
|
||||
}
|
||||
rankingMetric = rankingMetricConstructor.apply(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ public class RaceLogORCLegDataEventSerializer extends BaseRaceLogEventSerializer
|
||||
public JSONObject serialize(RaceLogEvent object) {
|
||||
RaceLogORCLegDataEvent legData = (RaceLogORCLegDataEvent) object;
|
||||
JSONObject result = super.serialize(legData);
|
||||
result.put(ORC_LEG_NR, legData.getLegNr());
|
||||
result.put(ORC_LEG_NR, legData.getOneBasedLegNumber());
|
||||
result.put(ORC_LEG_LENGTH, legData.getLength().getNauticalMiles());
|
||||
result.put(ORC_LEG_TWA, legData.getTwa().getDegrees());
|
||||
result.put(ORC_LEG_TYPE, legData.getType().name());
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@ public class RaceLogEventDeserializerTest {
|
||||
assertEquals(originalEvent.getClass(), newEvent.getClass());
|
||||
assertEquals(originalEvent.getId(), newEvent.getId());
|
||||
assertEquals(originalEvent.getShortInfo(), newEvent.getShortInfo());
|
||||
assertEquals(originalEvent.getLegNr(), newEvent.getLegNr());
|
||||
assertEquals(originalEvent.getOneBasedLegNumber(), newEvent.getOneBasedLegNumber());
|
||||
assertEquals(originalEvent.getTwa(), newEvent.getTwa());
|
||||
assertEquals(originalEvent.getType(), newEvent.getType());
|
||||
assertEquals(originalEvent.getLength(), newEvent.getLength());
|
||||
|
||||
Reference in new issue
Block a user