mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-22 20:13:52 +00:00
Refactored the lifecycle of RaceLogSensorFixTracker to it's own class
and changed the implementation to be based on the denotation in RaceLog
This commit is contained in:
1 parent
10e4e2feec
commit
ead64e9310
10 files changed
+186
-145
No files matched your search
+5
-5
@@ -6,7 +6,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.racelog.tracking.SensorFixStore;
|
||||
import com.sap.sailing.domain.racelogsensortracking.SensorFixMapperFactory;
|
||||
import com.sap.sailing.domain.racelogtracking.impl.logtracker.RaceLogSensorFixTracker;
|
||||
import com.sap.sailing.domain.racelogtracking.impl.logtracker.RaceLogSensorFixTrackerLifecycle;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
|
||||
import com.sap.sailing.domain.tracking.RaceListener;
|
||||
@@ -14,7 +14,7 @@ import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
|
||||
public class RegattaLogSensorDataTracker {
|
||||
private final Map<RegattaAndRaceIdentifier, DynamicTrackedRace> knownTrackedRaces = new ConcurrentHashMap<>();
|
||||
private final Map<RegattaAndRaceIdentifier, RaceLogSensorFixTracker> dataTrackers = new ConcurrentHashMap<>();
|
||||
private final Map<RegattaAndRaceIdentifier, RaceLogSensorFixTrackerLifecycle> dataTrackers = new ConcurrentHashMap<>();
|
||||
private final DynamicTrackedRegatta trackedRegatta;
|
||||
private final RaceListener raceListener;
|
||||
private final SensorFixStore sensorFixStore;
|
||||
@@ -51,13 +51,13 @@ public class RegattaLogSensorDataTracker {
|
||||
if (existingRace != null) {
|
||||
removeRaceLogSensorDataTracker(raceIdentifier);
|
||||
}
|
||||
RaceLogSensorFixTracker dataTracker = new RaceLogSensorFixTracker((DynamicTrackedRace) trackedRace,
|
||||
RaceLogSensorFixTrackerLifecycle dataTracker = new RaceLogSensorFixTrackerLifecycle((DynamicTrackedRace) trackedRace,
|
||||
sensorFixStore, sensorFixMapperFactory, tracker -> trackerStopped(raceIdentifier, tracker));
|
||||
dataTrackers.put(raceIdentifier, dataTracker);
|
||||
}
|
||||
}
|
||||
|
||||
private void trackerStopped(RegattaAndRaceIdentifier raceIdentifier, RaceLogSensorFixTracker tracker) {
|
||||
private void trackerStopped(RegattaAndRaceIdentifier raceIdentifier, RaceLogSensorFixTrackerLifecycle tracker) {
|
||||
dataTrackers.remove(raceIdentifier, tracker);
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ public class RegattaLogSensorDataTracker {
|
||||
}
|
||||
|
||||
private void removeRaceLogSensorDataTracker(RegattaAndRaceIdentifier raceIdentifier) {
|
||||
RaceLogSensorFixTracker currentActiveDataTracker = dataTrackers.get(raceIdentifier);
|
||||
RaceLogSensorFixTrackerLifecycle currentActiveDataTracker = dataTrackers.get(raceIdentifier);
|
||||
if (currentActiveDataTracker != null) {
|
||||
currentActiveDataTracker.stop();
|
||||
trackerStopped(raceIdentifier, currentActiveDataTracker);
|
||||
|
||||
+9
-76
@@ -10,11 +10,6 @@ import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
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.race.tracking.RaceLogDenoteForTrackingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.tracking.analyzing.impl.RaceLogTrackingStateAnalyzer;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.EventMappingVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
||||
@@ -28,7 +23,6 @@ import com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl.Regatt
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.common.TrackedRaceStatusEnum;
|
||||
import com.sap.sailing.domain.common.racelog.tracking.RaceLogTrackingState;
|
||||
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
||||
import com.sap.sailing.domain.common.tracking.DoubleVectorFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||
@@ -46,7 +40,6 @@ import com.sap.sailing.domain.racelogtracking.DeviceMappingWithRegattaLogEvent;
|
||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.DynamicSensorFixTrack;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||
import com.sap.sailing.domain.tracking.RegattaLogAttachmentListener;
|
||||
import com.sap.sailing.domain.tracking.Track;
|
||||
import com.sap.sailing.domain.tracking.TrackingDataLoader;
|
||||
import com.sap.sailing.domain.tracking.impl.AbstractRaceChangeListener;
|
||||
@@ -63,10 +56,6 @@ import com.sap.sse.concurrent.NamedReentrantReadWriteLock;
|
||||
|
||||
public class RaceLogSensorFixTracker implements TrackingDataLoader {
|
||||
private static final Logger logger = Logger.getLogger(RaceLogSensorFixTracker.class.getName());
|
||||
|
||||
public interface Owner {
|
||||
void stopped(RaceLogSensorFixTracker tracker);
|
||||
}
|
||||
|
||||
protected final DynamicTrackedRace trackedRace;
|
||||
private final Set<RegattaLog> knownRegattaLogs = new HashSet<>();
|
||||
@@ -76,37 +65,7 @@ public class RaceLogSensorFixTracker implements TrackingDataLoader {
|
||||
private final RaceLogMappingWrapper<WithID> competitorMappings;
|
||||
private final AtomicInteger activeLoaders = new AtomicInteger();
|
||||
private final SensorFixMapperFactory sensorFixMapperFactory;
|
||||
private final Owner owner;
|
||||
private boolean tracking = false;
|
||||
|
||||
private final RaceLogEventVisitor raceLogEventVisitor = new BaseRaceLogEventVisitor() {
|
||||
@Override
|
||||
public void visit(RaceLogDenoteForTrackingEvent event) {
|
||||
updateDenotionState();
|
||||
}
|
||||
@Override
|
||||
public void visit(RaceLogRevokeEvent event) {
|
||||
updateDenotionState();
|
||||
}
|
||||
};
|
||||
|
||||
private final RegattaLogAttachmentListener regattaLogAttachmentListener = new RegattaLogAttachmentListener() {
|
||||
@Override
|
||||
public void regattaLogAboutToBeAttached(RegattaLog regattaLog) {
|
||||
synchronized (knownRegattaLogs) {
|
||||
addRegattaLogUnlocked(regattaLog);
|
||||
}
|
||||
updateMappingsAndAddListeners();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTracking(boolean preemptive) {
|
||||
if (preemptive) {
|
||||
waitForLoadingFromFixStoreToFinishRunning();
|
||||
}
|
||||
stop();
|
||||
}
|
||||
};
|
||||
|
||||
private final AbstractRaceChangeListener trackingTimesRaceChangeListener = new AbstractRaceChangeListener() {
|
||||
@Override
|
||||
public void startOfTrackingChanged(TimePoint oldStartOfTracking, TimePoint newStartOfTracking) {
|
||||
@@ -122,6 +81,13 @@ public class RaceLogSensorFixTracker implements TrackingDataLoader {
|
||||
loadFixesForExtendedTimeRange(oldEndOfTracking, newEndOfTracking);
|
||||
}
|
||||
}
|
||||
|
||||
public void regattaLogAttached(RegattaLog regattaLog) {
|
||||
synchronized (knownRegattaLogs) {
|
||||
addRegattaLogUnlocked(regattaLog);
|
||||
}
|
||||
updateMappingsAndAddListeners();
|
||||
}
|
||||
};
|
||||
private final RegattaLogEventVisitor regattaLogEventVisitor = new BaseRegattaLogEventVisitor() {
|
||||
@Override
|
||||
@@ -207,16 +173,10 @@ public class RaceLogSensorFixTracker implements TrackingDataLoader {
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
public RaceLogSensorFixTracker(DynamicTrackedRace trackedRace,
|
||||
SensorFixStore sensorFixStore, SensorFixMapperFactory sensorFixMapperFactory) {
|
||||
this(trackedRace, sensorFixStore, sensorFixMapperFactory, tracker -> {});
|
||||
}
|
||||
|
||||
public RaceLogSensorFixTracker(DynamicTrackedRace trackedRace,
|
||||
SensorFixStore sensorFixStore, SensorFixMapperFactory sensorFixMapperFactory, Owner owner) {
|
||||
SensorFixStore sensorFixStore, SensorFixMapperFactory sensorFixMapperFactory) {
|
||||
this.sensorFixStore = sensorFixStore;
|
||||
this.owner = owner;
|
||||
this.gpsFixStore = new GPSFixStoreImpl(sensorFixStore);
|
||||
this.sensorFixMapperFactory = sensorFixMapperFactory;
|
||||
this.trackedRace = trackedRace;
|
||||
@@ -250,30 +210,8 @@ public class RaceLogSensorFixTracker implements TrackingDataLoader {
|
||||
}
|
||||
};
|
||||
|
||||
// trackedRace.getRaceLog(trackedRace.getRaceIdentifier()).addListener(raceLogEventVisitor);
|
||||
// updateDenotionState();
|
||||
startTracking();
|
||||
}
|
||||
|
||||
private synchronized void updateDenotionState() {
|
||||
RaceLogTrackingState raceLogTrackingState = new RaceLogTrackingStateAnalyzer(trackedRace.getRaceLog(trackedRace.getRaceIdentifier())).analyze();
|
||||
boolean forTracking = raceLogTrackingState.isForTracking();
|
||||
if(!tracking && forTracking) {
|
||||
startTracking();
|
||||
}
|
||||
if(tracking && !forTracking) {
|
||||
trackedRace.removeListener(trackingTimesRaceChangeListener);
|
||||
trackedRace.removeRegattaLogAttachmentListener(regattaLogAttachmentListener);
|
||||
synchronized (knownRegattaLogs) {
|
||||
knownRegattaLogs.forEach((log) -> log.removeListener(regattaLogEventVisitor));
|
||||
knownRegattaLogs.clear();
|
||||
}
|
||||
setStatusAndProgress(TrackedRaceStatusEnum.FINISHED, 1.0);
|
||||
sensorFixStore.removeListener(listener);
|
||||
tracking = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void loadFixes(TimeRange timeRangeToLoad, DeviceMappingWithRegattaLogEvent<WithID> mapping) {
|
||||
mapping.getRegattaLogEvent().accept(new EventMappingVisitor() {
|
||||
@@ -348,19 +286,15 @@ public class RaceLogSensorFixTracker implements TrackingDataLoader {
|
||||
|
||||
public void stop() {
|
||||
trackedRace.removeListener(trackingTimesRaceChangeListener);
|
||||
trackedRace.removeRegattaLogAttachmentListener(regattaLogAttachmentListener);
|
||||
synchronized (knownRegattaLogs) {
|
||||
knownRegattaLogs.forEach((log) -> log.removeListener(regattaLogEventVisitor));
|
||||
knownRegattaLogs.clear();
|
||||
}
|
||||
setStatusAndProgress(TrackedRaceStatusEnum.FINISHED, 1.0);
|
||||
sensorFixStore.removeListener(listener);
|
||||
tracking = false;
|
||||
owner.stopped(this);
|
||||
}
|
||||
|
||||
protected void startTracking() {
|
||||
trackedRace.addRegattaLogAttachmentListener(regattaLogAttachmentListener);
|
||||
final boolean hasRegattaLogs;
|
||||
synchronized (knownRegattaLogs) {
|
||||
trackedRace.getAttachedRegattaLogs().forEach(this::addRegattaLogUnlocked);
|
||||
@@ -371,7 +305,6 @@ public class RaceLogSensorFixTracker implements TrackingDataLoader {
|
||||
updateMappingsAndAddListeners();
|
||||
waitForLoadingFromFixStoreToFinishRunning();
|
||||
}
|
||||
tracking = true;
|
||||
}
|
||||
protected void waitForLoadingFromFixStoreToFinishRunning() {
|
||||
try {
|
||||
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
package com.sap.sailing.domain.racelogtracking.impl.logtracker;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
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.race.tracking.RaceLogDenoteForTrackingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.tracking.analyzing.impl.RaceLogTrackingStateAnalyzer;
|
||||
import com.sap.sailing.domain.common.racelog.tracking.RaceLogTrackingState;
|
||||
import com.sap.sailing.domain.racelog.tracking.SensorFixStore;
|
||||
import com.sap.sailing.domain.racelogsensortracking.SensorFixMapperFactory;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||
import com.sap.sailing.domain.tracking.RaceChangeListener;
|
||||
import com.sap.sailing.domain.tracking.TrackingDataLoader;
|
||||
import com.sap.sailing.domain.tracking.impl.AbstractRaceChangeListener;
|
||||
|
||||
public class RaceLogSensorFixTrackerLifecycle implements TrackingDataLoader {
|
||||
private static final Logger logger = Logger.getLogger(RaceLogSensorFixTrackerLifecycle.class.getName());
|
||||
|
||||
private final DynamicTrackedRace trackedRace;
|
||||
|
||||
private final SensorFixStore sensorFixStore;
|
||||
|
||||
private final SensorFixMapperFactory sensorFixMapperFactory;
|
||||
|
||||
private final Owner owner;
|
||||
|
||||
private RaceLogSensorFixTracker tracker;
|
||||
|
||||
private final RaceChangeListener raceChangeListener = new AbstractRaceChangeListener() {
|
||||
public void raceLogAttached(RaceLog raceLog) {
|
||||
raceLog.addListener(raceLogEventVisitor);
|
||||
}
|
||||
|
||||
public void stopTracking(boolean preemptive) {
|
||||
stop();
|
||||
owner.stopped(RaceLogSensorFixTrackerLifecycle.this);
|
||||
}
|
||||
};
|
||||
|
||||
private final RaceLogEventVisitor raceLogEventVisitor = new BaseRaceLogEventVisitor() {
|
||||
@Override
|
||||
public void visit(RaceLogDenoteForTrackingEvent event) {
|
||||
updateDenotionState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RaceLogRevokeEvent event) {
|
||||
updateDenotionState();
|
||||
}
|
||||
};
|
||||
|
||||
public interface Owner {
|
||||
void stopped(RaceLogSensorFixTrackerLifecycle tracker);
|
||||
}
|
||||
|
||||
public RaceLogSensorFixTrackerLifecycle(DynamicTrackedRace trackedRace, SensorFixStore sensorFixStore,
|
||||
SensorFixMapperFactory sensorFixMapperFactory, Owner owner) {
|
||||
this.trackedRace = trackedRace;
|
||||
this.sensorFixStore = sensorFixStore;
|
||||
this.sensorFixMapperFactory = sensorFixMapperFactory;
|
||||
this.owner = owner;
|
||||
|
||||
trackedRace.addListener(raceChangeListener);
|
||||
|
||||
for (RaceLog raceLog : trackedRace.getAttachedRaceLogs()) {
|
||||
raceLog.addListener(raceLogEventVisitor);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void updateDenotionState() {
|
||||
boolean forTracking = getForTracking();
|
||||
if (tracker == null && forTracking) {
|
||||
tracker = new RaceLogSensorFixTracker(trackedRace, sensorFixStore, sensorFixMapperFactory);
|
||||
}
|
||||
if (tracker != null && !forTracking) {
|
||||
stopTracker();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
stopTracker();
|
||||
for (RaceLog raceLog : trackedRace.getAttachedRaceLogs()) {
|
||||
raceLog.removeListener(raceLogEventVisitor);
|
||||
}
|
||||
}
|
||||
|
||||
private void stopTracker() {
|
||||
tracker.stop();
|
||||
tracker = null;
|
||||
}
|
||||
|
||||
boolean getForTracking() {
|
||||
for (RaceLog raceLog : trackedRace.getAttachedRaceLogs()) {
|
||||
RaceLogTrackingState raceLogTrackingState = new RaceLogTrackingStateAnalyzer(raceLog).analyze();
|
||||
if (raceLogTrackingState.isForTracking()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+8
@@ -2,10 +2,12 @@ package com.sap.sailing.domain.tracking;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogPassChangeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogRevokeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.state.RaceState;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CourseListener;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
@@ -70,4 +72,10 @@ public interface RaceChangeListener extends CourseListener {
|
||||
void trackAdded(DynamicSensorFixTrack<Competitor, ?> track);
|
||||
|
||||
void fixAdded(Competitor competitor, String trackName, SensorFix fix);
|
||||
|
||||
void regattaLogAttached(RegattaLog regattaLog);
|
||||
|
||||
void raceLogAttached(RaceLog raceLog);
|
||||
|
||||
void stopTracking(boolean preemptive);
|
||||
}
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
package com.sap.sailing.domain.tracking;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
|
||||
public interface RegattaLogAttachmentListener {
|
||||
|
||||
void regattaLogAboutToBeAttached(RegattaLog regattaLog);
|
||||
|
||||
void onStopTracking(boolean preemptive);
|
||||
}
|
||||
@@ -913,12 +913,6 @@ public interface TrackedRace extends Serializable, IsManagedByCache<SharedDomain
|
||||
*/
|
||||
public void updateStartAndEndOfTracking(boolean waitForGPSFixesToLoad);
|
||||
|
||||
default void addRegattaLogAttachmentListener(RegattaLogAttachmentListener listener) {
|
||||
}
|
||||
|
||||
default void removeRegattaLogAttachmentListener(RegattaLogAttachmentListener listener) {
|
||||
}
|
||||
|
||||
default void lockForSerializationRead() {
|
||||
}
|
||||
|
||||
|
||||
+17
@@ -2,6 +2,8 @@ package com.sap.sailing.domain.tracking.impl;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
@@ -130,4 +132,19 @@ public abstract class AbstractRaceChangeListener implements RaceChangeListener {
|
||||
public void fixAdded(Competitor competitor, String trackName, SensorFix fix) {
|
||||
defaultAction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void regattaLogAttached(RegattaLog regattaLog) {
|
||||
defaultAction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void raceLogAttached(RaceLog raceLog) {
|
||||
defaultAction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopTracking(boolean preemptive) {
|
||||
defaultAction();
|
||||
}
|
||||
}
|
||||
+3
-18
@@ -13,7 +13,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NavigableSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -287,7 +286,7 @@ DynamicTrackedRace, GPSTrackListener<Competitor, GPSFixMoving> {
|
||||
|
||||
@Override
|
||||
public void onStopTracking(final boolean preemptive) {
|
||||
informListenersOnStopTracking(preemptive);
|
||||
notifyListenersOnStopTracking(preemptive);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -356,7 +355,8 @@ DynamicTrackedRace, GPSTrackListener<Competitor, GPSFixMoving> {
|
||||
* Callers iterating over the result need to synchronize on the resulting collection while iterating
|
||||
* to avoid {@link ConcurrentModificationException}s.
|
||||
*/
|
||||
private Set<RaceChangeListener> getListeners() {
|
||||
@Override
|
||||
protected Set<RaceChangeListener> getListeners() {
|
||||
if (listeners == null) {
|
||||
listeners = new HashSet<RaceChangeListener>();
|
||||
}
|
||||
@@ -460,21 +460,6 @@ DynamicTrackedRace, GPSTrackListener<Competitor, GPSFixMoving> {
|
||||
notifyListenersWindSourcesToExcludeChanged(windSourcesToExclude);
|
||||
}
|
||||
|
||||
private void notifyListeners(Consumer<RaceChangeListener> notifyAction) {
|
||||
RaceChangeListener[] listeners;
|
||||
synchronized (getListeners()) {
|
||||
listeners = getListeners().toArray(new RaceChangeListener[getListeners().size()]);
|
||||
}
|
||||
for (RaceChangeListener listener : listeners) {
|
||||
try {
|
||||
notifyAction.accept(listener);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "RaceChangeListener " + listener + " threw exception " + e.getMessage());
|
||||
logger.log(Level.SEVERE, "notifyListeners(Consumer<RaceChangeListener> notifyAction", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFinishedTime(final TimePoint newFinishedTime) {
|
||||
final TimePoint oldFinishedTime = getFinishedTime();
|
||||
|
||||
+24
-30
@@ -30,7 +30,7 @@ import java.util.concurrent.ConcurrentSkipListSet;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -126,9 +126,9 @@ import com.sap.sailing.domain.tracking.GPSTrackListener;
|
||||
import com.sap.sailing.domain.tracking.LineDetails;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.RaceChangeListener;
|
||||
import com.sap.sailing.domain.tracking.RaceExecutionOrderProvider;
|
||||
import com.sap.sailing.domain.tracking.RaceListener;
|
||||
import com.sap.sailing.domain.tracking.RegattaLogAttachmentListener;
|
||||
import com.sap.sailing.domain.tracking.SensorFixTrack;
|
||||
import com.sap.sailing.domain.tracking.Track;
|
||||
import com.sap.sailing.domain.tracking.TrackFactory;
|
||||
@@ -395,8 +395,6 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
private transient RaceLogResolver raceLogResolver;
|
||||
|
||||
private final NamedReentrantReadWriteLock sensorTracksLock;
|
||||
|
||||
private transient Set<RegattaLogAttachmentListener> regattaLogAttachmentListeners;
|
||||
|
||||
/**
|
||||
* Constructs the tracked race with one-design ranking.
|
||||
@@ -557,8 +555,6 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
} catch (InterruptedException e) {
|
||||
logger.log(Level.SEVERE, "Waiting for loading from stores to finish was interrupted", e);
|
||||
}
|
||||
|
||||
regattaLogAttachmentListeners = new HashSet<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -652,7 +648,6 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
adjustStructureToCourse();
|
||||
triggerManeuverCacheRecalculationForAllCompetitors();
|
||||
logger.info("Deserialized race " + getRace().getName());
|
||||
regattaLogAttachmentListeners = new HashSet<>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3329,6 +3324,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
updateStartOfRaceCacheFields();
|
||||
updateStartAndEndOfTracking(/* waitForGPSFixesToLoad */ false);
|
||||
}
|
||||
notifyListenersWhenAttachingRaceLog(raceLog);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3378,7 +3374,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
if (attachedRegattaLogs != null) {
|
||||
attachedRegattaLogs.put(regattaLog.getId(), regattaLog);
|
||||
}
|
||||
informListenersBeforeAttachingRegattaLog(regattaLog);
|
||||
notifyListenersWhenAttachingRegattaLog(regattaLog);
|
||||
// informListenersAboutAttachedRegattaLog(regattaLog);
|
||||
TrackedRaceImpl.this.notifyAll();
|
||||
}
|
||||
@@ -3990,35 +3986,33 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
return (TrackT) sensorTracks.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRegattaLogAttachmentListener(RegattaLogAttachmentListener listener) {
|
||||
synchronized (regattaLogAttachmentListeners) {
|
||||
regattaLogAttachmentListeners.add(listener);
|
||||
protected abstract Set<RaceChangeListener> getListeners();
|
||||
|
||||
protected void notifyListeners(Consumer<RaceChangeListener> notifyAction) {
|
||||
RaceChangeListener[] listeners;
|
||||
synchronized (getListeners()) {
|
||||
listeners = getListeners().toArray(new RaceChangeListener[getListeners().size()]);
|
||||
}
|
||||
for (RaceChangeListener listener : listeners) {
|
||||
try {
|
||||
notifyAction.accept(listener);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "RaceChangeListener " + listener + " threw exception " + e.getMessage());
|
||||
logger.log(Level.SEVERE, "notifyListeners(Consumer<RaceChangeListener> notifyAction", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRegattaLogAttachmentListener(RegattaLogAttachmentListener listener) {
|
||||
synchronized (regattaLogAttachmentListeners) {
|
||||
regattaLogAttachmentListeners.remove(listener);
|
||||
}
|
||||
private void notifyListenersWhenAttachingRegattaLog(RegattaLog regattaLog) {
|
||||
notifyListeners(listener -> listener.regattaLogAttached(regattaLog));
|
||||
}
|
||||
|
||||
private <T> void informRegattaLogAttachmentListeners(T regattaLog,
|
||||
BiConsumer<RegattaLogAttachmentListener, T> listenerCaller) {
|
||||
Iterable<RegattaLogAttachmentListener> listeners;
|
||||
synchronized (regattaLogAttachmentListeners) {
|
||||
listeners = new ArrayList<>(regattaLogAttachmentListeners);
|
||||
}
|
||||
listeners.forEach((listener) -> listenerCaller.accept(listener, regattaLog));
|
||||
}
|
||||
|
||||
private void informListenersBeforeAttachingRegattaLog(RegattaLog regattaLog) {
|
||||
informRegattaLogAttachmentListeners(regattaLog, RegattaLogAttachmentListener::regattaLogAboutToBeAttached);
|
||||
private void notifyListenersWhenAttachingRaceLog(RaceLog raceLog) {
|
||||
notifyListeners(listener -> listener.raceLogAttached(raceLog));
|
||||
}
|
||||
|
||||
protected void informListenersOnStopTracking(boolean preemptive) {
|
||||
informRegattaLogAttachmentListeners(preemptive, RegattaLogAttachmentListener::onStopTracking);
|
||||
protected void notifyListenersOnStopTracking(boolean preemptive) {
|
||||
notifyListeners(listener -> listener.stopTracking(preemptive));
|
||||
}
|
||||
|
||||
public void lockForSerializationRead() {
|
||||
|
||||
+15
@@ -58,6 +58,7 @@ import com.sap.sailing.domain.abstractlog.race.state.RaceState;
|
||||
import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState;
|
||||
import com.sap.sailing.domain.abstractlog.race.state.impl.RaceStateImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.state.impl.ReadonlyRaceStateImpl;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CompetitorStore;
|
||||
import com.sap.sailing.domain.base.CompetitorStore.CompetitorUpdateListener;
|
||||
@@ -1721,6 +1722,20 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
||||
return trackedRace.getRaceIdentifier();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void regattaLogAttached(RegattaLog regattaLog) {
|
||||
// no action required
|
||||
}
|
||||
|
||||
@Override
|
||||
public void raceLogAttached(RaceLog regattaLog) {
|
||||
// no action required
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopTracking(boolean preemptive) {
|
||||
// no action required
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user