@@ -12,6 +12,7 @@ import com.mapbox.navigation.base.route.NavigationRoute
1212import com.mapbox.navigation.base.trip.model.RouteProgress
1313import com.mapbox.navigation.core.MapboxNavigation
1414import com.mapbox.navigation.core.directions.session.RoutesObserver
15+ import com.mapbox.navigation.core.history.MapboxHistoryReaderProvider
1516import com.mapbox.navigation.core.lifecycle.MapboxNavigationApp
1617import com.mapbox.navigation.core.lifecycle.MapboxNavigationObserver
1718import com.mapbox.navigation.core.replay.MapboxReplayer
@@ -20,6 +21,17 @@ import com.mapbox.navigation.core.replay.history.ReplayEventUpdateLocation
2021import com.mapbox.navigation.core.replay.history.ReplayEventsObserver
2122import com.mapbox.navigation.core.trip.session.RouteProgressObserver
2223import com.mapbox.navigation.utils.internal.logW
24+ import kotlinx.coroutines.CoroutineScope
25+ import kotlinx.coroutines.Dispatchers
26+ import kotlinx.coroutines.SupervisorJob
27+ import kotlinx.coroutines.flow.Flow
28+ import kotlinx.coroutines.flow.MutableStateFlow
29+ import kotlinx.coroutines.flow.StateFlow
30+ import kotlinx.coroutines.flow.asStateFlow
31+ import kotlinx.coroutines.flow.distinctUntilChanged
32+ import kotlinx.coroutines.flow.launchIn
33+ import kotlinx.coroutines.flow.map
34+ import kotlinx.coroutines.flow.onEach
2335import java.util.Collections
2436
2537/* *
@@ -54,13 +66,13 @@ import java.util.Collections
5466@ExperimentalPreviewMapboxNavigationAPI
5567class ReplayRouteSession : MapboxNavigationObserver {
5668
57- private var options = ReplayRouteSessionOptions .Builder ().build()
58-
5969 private lateinit var replayRouteMapper: ReplayRouteMapper
70+ private val optionsFlow = MutableStateFlow (ReplayRouteSessionOptions .Builder ().build())
6071 private var mapboxNavigation: MapboxNavigation ? = null
6172 private var lastLocationEvent: ReplayEventUpdateLocation ? = null
6273 private var polylineDecodeStream: ReplayPolylineDecodeStream ? = null
6374 private var currentRoute: NavigationRoute ? = null
75+ private var coroutineScope: CoroutineScope ? = null
6476
6577 private val routeProgressObserver = RouteProgressObserver { routeProgress ->
6678 if (currentRoute?.id != routeProgress.navigationRoute.id) {
@@ -89,34 +101,47 @@ class ReplayRouteSession : MapboxNavigationObserver {
89101 * setOptions(getOptions().toBuilder().locationResetEnabled(false).build())
90102 * ```
91103 */
92- fun getOptions (): ReplayRouteSessionOptions = options
104+ fun getOptions (): StateFlow < ReplayRouteSessionOptions > = optionsFlow.asStateFlow()
93105
94106 /* *
95107 * Set new options for the [ReplayRouteSession]. This will not effect previously simulated
96108 * events, the end behavior will depend on the values you have used. If you want to guarantee
97109 * the effect of the options, you need to set options before [MapboxNavigation] is attached.
98110 */
99111 fun setOptions (options : ReplayRouteSessionOptions ) = apply {
100- this .options = options
101- if (::replayRouteMapper.isInitialized) {
102- replayRouteMapper.options = this .options.replayRouteOptions
103- }
112+ this .optionsFlow.value = options
104113 }
105114
106115 override fun onAttached (mapboxNavigation : MapboxNavigation ) {
107- this .replayRouteMapper = ReplayRouteMapper (options.replayRouteOptions)
116+ val coroutineScope = CoroutineScope (SupervisorJob () + Dispatchers .Main .immediate)
117+ .also { this .coroutineScope = it }
108118 this .mapboxNavigation = mapboxNavigation
109119 mapboxNavigation.startReplayTripSession()
110120 mapboxNavigation.registerRouteProgressObserver(routeProgressObserver)
111121 mapboxNavigation.registerRoutesObserver(routesObserver)
112122 mapboxNavigation.mapboxReplayer.registerObserver(replayEventsObserver)
113123 mapboxNavigation.mapboxReplayer.play()
124+ observeStateFlow(mapboxNavigation).launchIn(coroutineScope)
125+ }
126+
127+ private fun observeStateFlow (mapboxNavigation : MapboxNavigation ): Flow <* > {
128+ return optionsFlow.mapDistinct { it.replayRouteOptions }.onEach { replayRouteOptions ->
129+ mapboxNavigation.mapboxReplayer.clearEvents()
130+ this .replayRouteMapper = ReplayRouteMapper (replayRouteOptions)
131+ val routes = mapboxNavigation.getNavigationRoutes()
132+ mapboxNavigation.setNavigationRoutes(emptyList())
133+ mapboxNavigation.setNavigationRoutes(routes)
134+ }
114135 }
115136
137+ private inline fun <T , R > Flow<T>.mapDistinct (
138+ crossinline transform : suspend (value: T ) -> R
139+ ): Flow <R > = map(transform).distinctUntilChanged()
140+
116141 private fun MapboxNavigation.resetReplayLocation () {
117142 mapboxReplayer.clearEvents()
118143 resetTripSession {
119- if (options .locationResetEnabled) {
144+ if (optionsFlow.value .locationResetEnabled) {
120145 val context = navigationOptions.applicationContext
121146 if (PermissionsManager .areLocationPermissionsGranted(context)) {
122147 pushRealLocation(context)
@@ -174,7 +199,7 @@ class ReplayRouteSession : MapboxNavigationObserver {
174199 }
175200
176201 private fun pushMorePoints () {
177- val nextPoints = polylineDecodeStream?.decode(options .decodeMinDistance) ? : return
202+ val nextPoints = polylineDecodeStream?.decode(optionsFlow.value .decodeMinDistance) ? : return
178203 val nextReplayLocations = replayRouteMapper.mapPointList(nextPoints)
179204 lastLocationEvent = nextReplayLocations.lastOrNull { it is ReplayEventUpdateLocation }
180205 as ? ReplayEventUpdateLocation
0 commit comments