Merge branch 'master' into foiling

Conflicts:
	java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceImpl.java
	java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java
This commit is contained in:
Steffen Schaefer committed 2016-06-27 16:15:41 +02:00
commit 0a1b56765c
45 files changed
+497 -168

No files matched your search

@@ -7,6 +7,14 @@ import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
/**
* The result of a {@link StartTimeFinder} that tells about the dependencies through which the start time
* may be resolved from other races, reasons for the failure to resolve a start time and the actual start
* time as obtained immediately or transitively through a chain of dependencies.
*
* @author Axel Uhl (D043530)
*
*/
public class StartTimeFinderResult {
public static enum ResolutionFailed { RACE_LOG_UNRESOLVED, CYCLIC_DEPENDENCY, NO_START_TIME_SET };
@@ -40,6 +48,9 @@ public class StartTimeFinderResult {
this(/* racesDependingOn */ Collections.<SimpleRaceLogIdentifier>emptyList(), startTime, startTimeDiff);
}
/**
* @return {@code null} if the start time was resolved; a reason for failure to resolve otherwise
*/
public ResolutionFailed getResolutionFailed() {
return resolutionFailed;
}
@@ -239,7 +239,6 @@ public class RaceStateImpl extends ReadonlyRaceStateImpl implements RaceState {
@Override
public void forceUpdate() {
super.update();
registerListenerOnDependentRaceIfDependentStartTime(Collections.<SimpleRaceLogIdentifier, ReadonlyRaceState>emptyMap());
}
}
@@ -9,6 +9,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.RaceLogChangedListener;
import com.sap.sailing.domain.abstractlog.race.RaceLogDependentStartTimeEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogPassChangeEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent;
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.ConfirmedFinishPositioningListFinder;
@@ -218,32 +219,24 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
} else {
dependentRaceStatesAndMe = dependentRaceStates;
}
registerListenerOnDependentRaceIfDependentStartTime(dependentRaceStatesAndMe);
}
protected void registerListenerOnDependentRaceIfDependentStartTime(Map<SimpleRaceLogIdentifier, ReadonlyRaceState> dependentRaceStates) {
// Check whether the latest known StartTimeEvent is a non-dependent or dependent start time in case of a
// dependent startTime setup listeners
this.raceLog.lockForRead();
try {
for (RaceLogEvent event : this.raceLog.getFixesDescending()) {
if (event instanceof RaceLogStartTimeEvent) {
break;
} else if (event instanceof RaceLogDependentStartTimeEvent) {
setupListenersOnDependentRace(event, dependentRaceStates);
break;
}
}
} finally {
this.raceLog.unlockAfterRead();
}
adjustObserverForRelativeStartTime();
}
protected ReadonlyRaceState getRaceStateToObserve() {
return raceStateToObserve;
}
protected RacingProcedureType determineInitialProcedureType() {
// Let's ensure there is a valid RacingProcedureType set, since a RaceState cannot live without a
// RacingProcedure we need to have a fallback
RegattaConfiguration configuration = getConfiguration();
RacingProcedureType inRaceLogType = racingProcedureAnalyzer.analyze();
return determineInitialProcedureType(inRaceLogType);
}
private RacingProcedureType determineInitialProcedureType(RacingProcedureType inRaceLogType) {
RegattaConfiguration configuration = getConfiguration();
if (inRaceLogType != RacingProcedureType.UNKNOWN) {
return inRaceLogType;
} else {
@@ -366,25 +359,40 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
@Override
public void eventAdded(RaceLogEvent event) {
if (event instanceof RaceLogDependentStartTimeEvent) {
setupListenersOnDependentRace(event, Collections.<SimpleRaceLogIdentifier, ReadonlyRaceState>emptyMap());
} else if (event instanceof RaceLogStartTimeEvent) {
if (raceStateToObserve != null) {
raceStateToObserve.removeChangedListener(raceStateToObserveListener);
raceStateToObserve = null;
}
// if a pass change or a start time-setting event, the observer relation to a race state of a
// race on which this race state's race's start time has depended or now depends needs to be
// re-assessed, and the observer relation needs to be established or canceled, respectively.
if (event instanceof RaceLogDependentStartTimeEvent ||
event instanceof RaceLogStartTimeEvent ||
event instanceof RaceLogPassChangeEvent) {
adjustObserverForRelativeStartTime();
}
update();
}
private void setupListenersOnDependentRace(RaceLogEvent event, Map<SimpleRaceLogIdentifier, ReadonlyRaceState> dependentRaceStates) {
private void adjustObserverForRelativeStartTime() {
final StartTimeFinderResult startTimeAnalysisResult = startTimeAnalyzer.analyze();
adjustObserverForRelativeStartTime(startTimeAnalysisResult);
}
private void adjustObserverForRelativeStartTime(final StartTimeFinderResult startTimeAnalysisResult) {
if (startTimeAnalysisResult.isDependentStartTime()) {
setupListenersOnDependentRace(startTimeAnalysisResult, Collections.<SimpleRaceLogIdentifier, ReadonlyRaceState>emptyMap());
} else if (raceStateToObserve != null) {
raceStateToObserve.removeChangedListener(raceStateToObserveListener);
raceStateToObserve = null;
}
}
private void setupListenersOnDependentRace(StartTimeFinderResult startTimeAnalysisResult, Map<SimpleRaceLogIdentifier, ReadonlyRaceState> dependentRaceStates) {
assert startTimeAnalysisResult.isDependentStartTime();
assert !Util.isEmpty(startTimeAnalysisResult.getDependingOnRaces());
if (raceStateToObserve != null) {
// Remove previous listeners
raceStateToObserve.removeChangedListener(raceStateToObserveListener);
raceStateToObserve = null;
}
RaceLogDependentStartTimeEvent dependentStartTimeEvent = (RaceLogDependentStartTimeEvent) event;
final SimpleRaceLogIdentifier dependentOnRaceIdentifier = dependentStartTimeEvent.getDependentOnRaceIdentifier();
final SimpleRaceLogIdentifier dependentOnRaceIdentifier = startTimeAnalysisResult.getDependingOnRaces().iterator().next();
if (dependentRaceStates.containsKey(dependentOnRaceIdentifier)) {
raceStateToObserve = dependentRaceStates.get(dependentOnRaceIdentifier);
raceStateToObserve.addChangedListener(raceStateToObserveListener);
@@ -412,6 +420,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
RacingProcedureType type = racingProcedureAnalyzer.analyze();
if (!Util.equalsWithNull(cachedRacingProcedureType, type) && type != RacingProcedureType.UNKNOWN) {
cachedRacingProcedureType = type;
cachedRacingProcedureTypeNoFallback = determineInitialProcedureType(type);
recreateRacingProcedure();
changedListeners.onRacingProcedureChanged(this);
}
@@ -428,6 +437,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
changedListeners.onAdvancePass(this);
// reset racing procedure to force recreate on next event!
cachedRacingProcedureType = null;
cachedRacingProcedureTypeNoFallback = null;
}
StartTimeFinderResult startTimeFinderResult = startTimeAnalyzer.analyze();
@@ -435,6 +445,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
cachedStartTimeFinderResult = startTimeFinderResult;
changedListeners.onStartTimeChanged(this);
}
adjustObserverForRelativeStartTime(startTimeFinderResult);
TimePoint finishingTime = finishingTimeAnalyzer.analyze();
if (!Util.equalsWithNull(cachedFinishingTime, finishingTime)) {
@@ -6,7 +6,7 @@ import com.sap.sailing.domain.abstractlog.BaseLogAnalyzer;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
import com.sap.sse.common.WithID;
@@ -29,8 +29,8 @@ public class OpenEndedDeviceMappingFinder extends BaseLogAnalyzer<RegattaLog, Re
@Override
protected Serializable performAnalysis() {
for (RegattaLogEvent regattaLogEvent : log.getUnrevokedEvents()) {
if (regattaLogEvent instanceof RegattaLogDeviceCompetitorMappingEvent) {
RegattaLogDeviceCompetitorMappingEvent deviceMappingEvent = (RegattaLogDeviceCompetitorMappingEvent) regattaLogEvent;
if (regattaLogEvent instanceof RegattaLogDeviceMappingEvent<?>) {
RegattaLogDeviceMappingEvent<?> deviceMappingEvent = (RegattaLogDeviceMappingEvent<?>) regattaLogEvent;
if (deviceMappingEvent.getMappedTo().equals(mappedTo) &&
deviceMappingEvent.getDevice().getStringRepresentation().equals(deviceUuid)) {
return deviceMappingEvent.getId();
@@ -6,11 +6,10 @@ import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
import com.sap.sse.common.Color;
import com.sap.sse.common.Duration;
import com.sap.sse.common.IsManagedByCache;
import com.sap.sse.common.Named;
import com.sap.sse.common.WithID;
import com.sap.sse.common.NamedWithID;
import com.sap.sse.datamining.annotations.Connector;
public interface Competitor extends Named, WithID, IsManagedByCache<SharedDomainFactory> {
public interface Competitor extends NamedWithID, IsManagedByCache<SharedDomainFactory> {
@Connector(messageKey="Team", ordinal=9)
Team getTeam();
@@ -1,8 +1,7 @@
package com.sap.sailing.domain.base;
import com.sap.sse.common.Named;
import com.sap.sse.common.WithID;
import com.sap.sse.common.NamedWithID;
public interface ControlPoint extends WithID, Named {
public interface ControlPoint extends NamedWithID {
Iterable<Mark> getMarks();
}
@@ -3,16 +3,15 @@ package com.sap.sailing.domain.base;
import java.util.UUID;
import com.sap.sse.common.IsManagedByCache;
import com.sap.sse.common.Named;
import com.sap.sse.common.WithID;
import com.sap.sse.common.NamedWithID;
/**
* A named area in a sailing {@link Venue} where races take place. Usually, the areas carry names according to the NATO
* alphabet, such as "Alpha", "Bravo" or "Charlie".
* alphabet, such as "Alpha", "Bravo" or "Charly".
*
* @author Axel Uhl (D043530)
*
*/
public interface CourseArea extends Named, WithID, IsManagedByCache<SharedDomainFactory> {
public interface CourseArea extends NamedWithID, IsManagedByCache<SharedDomainFactory> {
UUID getId();
}
@@ -5,9 +5,8 @@ import java.util.Locale;
import java.util.Map;
import com.sap.sailing.domain.common.Renamable;
import com.sap.sse.common.Named;
import com.sap.sse.common.NamedWithID;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.WithID;
import com.sap.sse.common.media.ImageSize;
import com.sap.sse.shared.media.WithMedia;
@@ -15,7 +14,7 @@ import com.sap.sse.shared.media.WithMedia;
* Base interface for an Event consisting of all static information, which might be shared
* by the server and an Android application.
*/
public interface EventBase extends Named, WithDescription, Renamable, WithID, WithMedia {
public interface EventBase extends NamedWithID, WithDescription, Renamable, WithMedia {
void setDescription(String description);
@@ -3,9 +3,9 @@ package com.sap.sailing.domain.base;
import java.util.UUID;
import com.sap.sailing.domain.common.Renamable;
import com.sap.sse.common.WithID;
import com.sap.sse.common.NamedWithID;
public interface LeaderboardGroupBase extends Renamable, WithID {
public interface LeaderboardGroupBase extends Renamable, NamedWithID {
UUID getId();
String getDescription();
void setDescriptiom(String description);
@@ -2,7 +2,6 @@ package com.sap.sailing.domain.base;
import com.sap.sailing.domain.common.MarkType;
import com.sap.sse.common.IsManagedByCache;
import com.sap.sse.common.WithID;
/**
@@ -12,7 +11,7 @@ import com.sap.sse.common.WithID;
* @author Axel Uhl (D043530)
*
*/
public interface Mark extends WithID, ControlPoint, IsManagedByCache<SharedDomainFactory> {
public interface Mark extends ControlPoint, IsManagedByCache<SharedDomainFactory> {
public String getColor();
public String getShape();
public String getPattern();
@@ -1,13 +1,13 @@
package com.sap.sailing.domain.base;
import com.sap.sse.common.Named;
import com.sap.sse.common.WithID;
import com.sap.sse.common.NamedWithID;
/**
* A side line in a race course
* @author Frank (C5163874)
*
* @author Frank Mittag (C5163874)
*
*/
public interface Sideline extends Named, WithID {
public interface Sideline extends NamedWithID {
Iterable<Mark> getMarks();
}
@@ -3,8 +3,7 @@ package com.sap.sailing.domain.base;
import com.sap.sailing.domain.common.Bearing;
import com.sap.sailing.domain.common.PassingInstruction;
import com.sap.sse.common.IsManagedByCache;
import com.sap.sse.common.Named;
import com.sap.sse.common.WithID;
import com.sap.sse.common.NamedWithID;
/**
* Waypoints constitute {@link Course}s and demarcate their {@link Leg}s. A waypoint's position is defined by a
@@ -14,7 +13,7 @@ import com.sap.sse.common.WithID;
* @author Axel Uhl (d043530)
*
*/
public interface Waypoint extends Named, WithID, IsManagedByCache<SharedDomainFactory> {
public interface Waypoint extends NamedWithID, IsManagedByCache<SharedDomainFactory> {
ControlPoint getControlPoint();
Iterable<Mark> getMarks();