Skip to content

Commit f54aa44

Browse files
jushgithub-actions[bot]
authored andcommitted
Move simulate route line progress calculation to bg thread (#3442)
GitOrigin-RevId: 67087f5be23ff97589c9737e5af287fdddf8af0a
1 parent cfa6c44 commit f54aa44

File tree

2 files changed

+66
-49
lines changed

2 files changed

+66
-49
lines changed

app/src/main/java/com/mapbox/maps/testapp/utils/SimulateRouteLocationProvider.kt

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,38 @@
11
package com.mapbox.maps.testapp.utils
22

3-
import android.os.Handler
4-
import android.os.Looper
53
import com.mapbox.geojson.LineString
64
import com.mapbox.geojson.Point
75
import com.mapbox.maps.plugin.locationcomponent.LocationConsumer
86
import com.mapbox.maps.plugin.locationcomponent.LocationProvider
97
import com.mapbox.turf.TurfConstants
108
import com.mapbox.turf.TurfMeasurement
119
import com.mapbox.turf.TurfMisc
12-
import java.util.concurrent.*
10+
import kotlinx.coroutines.CoroutineScope
11+
import kotlinx.coroutines.Dispatchers
12+
import kotlinx.coroutines.Job
13+
import kotlinx.coroutines.SupervisorJob
14+
import kotlinx.coroutines.cancelAndJoin
15+
import kotlinx.coroutines.delay
16+
import kotlinx.coroutines.isActive
17+
import kotlinx.coroutines.launch
18+
import kotlinx.coroutines.withContext
19+
import java.util.concurrent.CopyOnWriteArraySet
1320

1421
/**
1522
* A location provider implementation that takes in a line string as route and animate the location
1623
* updates along the route.
1724
*/
1825
class SimulateRouteLocationProvider(
1926
val route: LineString,
20-
private val handler: Handler = Handler(Looper.getMainLooper())
2127
) : LocationProvider {
22-
private val totalRouteLength = TurfMeasurement.length(route, TurfConstants.UNIT_CENTIMETERS)
28+
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
29+
private var emitLocationsJob: Job? = null
30+
private val totalRouteLength by lazy { TurfMeasurement.length(route, TurfConstants.UNIT_CENTIMETERS) }
2331
private val routeStartPoint = route.coordinates().first()
2432
private val locationConsumers = CopyOnWriteArraySet<LocationConsumer>()
2533
private var isFakeLocationEmitting = false
34+
private val iterator = route.coordinates().toMutableList().iterator()
35+
2636
override fun registerLocationConsumer(locationConsumer: LocationConsumer) {
2737
locationConsumers.add(locationConsumer)
2838
if (!isFakeLocationEmitting) {
@@ -34,35 +44,34 @@ class SimulateRouteLocationProvider(
3444
override fun unRegisterLocationConsumer(locationConsumer: LocationConsumer) {
3545
locationConsumers.remove(locationConsumer)
3646
if (locationConsumers.isEmpty()) {
47+
emitLocationsJob?.cancel()
3748
isFakeLocationEmitting = false
3849
}
3950
}
4051

41-
private val pointList = route.coordinates().toMutableList()
42-
private val iterator = pointList.iterator()
43-
private var lastLocation: Point =
44-
if (iterator.hasNext()) iterator.next() else Point.fromLngLat(0.0, 0.0)
45-
private var lastBearing = 0.0
46-
4752
private fun emitFakeLocations() {
48-
handler.postDelayed(
49-
{
50-
if (iterator.hasNext()) {
51-
val point = iterator.next().insertProgressInfo()
52-
val bearing = TurfMeasurement.bearing(lastLocation, point)
53-
lastLocation = point
54-
lastBearing = bearing
55-
iterator.remove()
53+
val previousEmitLocationsJob = emitLocationsJob
54+
emitLocationsJob = scope.launch {
55+
// Make sure previous job is cancelled before starting a new one
56+
previousEmitLocationsJob?.cancelAndJoin()
57+
var lastLocation: Point = if (iterator.hasNext()) {
58+
iterator.next()
59+
} else {
60+
Point.fromLngLat(0.0, 0.0)
61+
}
62+
while (isActive && iterator.hasNext()) {
63+
val point = iterator.next().insertProgressInfo()
64+
val bearing = TurfMeasurement.bearing(lastLocation, point)
65+
lastLocation = point
66+
iterator.remove()
5667

68+
withContext(Dispatchers.Main) {
5769
locationConsumers.forEach { it.onLocationUpdated(point) }
5870
locationConsumers.forEach { it.onBearingUpdated(bearing) }
5971
}
60-
if (iterator.hasNext() && isFakeLocationEmitting) {
61-
emitFakeLocations()
62-
}
63-
},
64-
LOCATION_UPDATE_INTERVAL_MS
65-
)
72+
delay(LOCATION_UPDATE_INTERVAL_MS)
73+
}
74+
}
6675
}
6776

6877
// use altitude of Point to pass through progress data, and use internal animator to interpolate

compose-app/src/main/java/com/mapbox/maps/compose/testapp/examples/utils/SimulateRouteLocationProvider.kt

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
package com.mapbox.maps.compose.testapp.examples.utils
22

3-
import android.os.Handler
4-
import android.os.Looper
53
import com.mapbox.geojson.LineString
64
import com.mapbox.geojson.Point
75
import com.mapbox.maps.plugin.locationcomponent.LocationConsumer
86
import com.mapbox.maps.plugin.locationcomponent.LocationProvider
97
import com.mapbox.turf.TurfConstants
108
import com.mapbox.turf.TurfMeasurement
119
import com.mapbox.turf.TurfMisc
10+
import kotlinx.coroutines.CoroutineScope
11+
import kotlinx.coroutines.Dispatchers
12+
import kotlinx.coroutines.Job
13+
import kotlinx.coroutines.SupervisorJob
14+
import kotlinx.coroutines.cancelAndJoin
15+
import kotlinx.coroutines.delay
16+
import kotlinx.coroutines.isActive
17+
import kotlinx.coroutines.launch
18+
import kotlinx.coroutines.withContext
1219
import java.util.concurrent.CopyOnWriteArraySet
1320

1421
/**
@@ -17,12 +24,14 @@ import java.util.concurrent.CopyOnWriteArraySet
1724
*/
1825
public class SimulateRouteLocationProvider(
1926
private val route: LineString,
20-
private val handler: Handler = Handler(Looper.getMainLooper())
2127
) : LocationProvider {
22-
private val totalRouteLength = TurfMeasurement.length(route, TurfConstants.UNIT_CENTIMETERS)
28+
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
29+
private var emitLocationsJob: Job? = null
30+
private val totalRouteLength by lazy { TurfMeasurement.length(route, TurfConstants.UNIT_CENTIMETERS) }
2331
private val routeStartPoint = route.coordinates().first()
2432
private val locationConsumers = CopyOnWriteArraySet<LocationConsumer>()
2533
private var isFakeLocationEmitting = false
34+
private val iterator = route.coordinates().toMutableList().iterator()
2635

2736
override fun registerLocationConsumer(locationConsumer: LocationConsumer) {
2837
locationConsumers.add(locationConsumer)
@@ -35,35 +44,34 @@ public class SimulateRouteLocationProvider(
3544
override fun unRegisterLocationConsumer(locationConsumer: LocationConsumer) {
3645
locationConsumers.remove(locationConsumer)
3746
if (locationConsumers.isEmpty()) {
47+
emitLocationsJob?.cancel()
3848
isFakeLocationEmitting = false
3949
}
4050
}
4151

42-
private val pointList = route.coordinates().toMutableList()
43-
private val iterator = pointList.iterator()
44-
private var lastLocation: Point =
45-
if (iterator.hasNext()) iterator.next() else Point.fromLngLat(0.0, 0.0)
46-
private var lastBearing = 0.0
47-
4852
private fun emitFakeLocations() {
49-
handler.postDelayed(
50-
{
51-
if (iterator.hasNext()) {
52-
val point = iterator.next().insertProgressInfo()
53-
val bearing = TurfMeasurement.bearing(lastLocation, point)
54-
lastLocation = point
55-
lastBearing = bearing
56-
iterator.remove()
53+
val previousEmitLocationsJob = emitLocationsJob
54+
emitLocationsJob = scope.launch {
55+
// Make sure previous job is cancelled before starting a new one
56+
previousEmitLocationsJob?.cancelAndJoin()
57+
var lastLocation: Point = if (iterator.hasNext()) {
58+
iterator.next()
59+
} else {
60+
Point.fromLngLat(0.0, 0.0)
61+
}
62+
while (isActive && iterator.hasNext()) {
63+
val point = iterator.next().insertProgressInfo()
64+
val bearing = TurfMeasurement.bearing(lastLocation, point)
65+
lastLocation = point
66+
iterator.remove()
5767

68+
withContext(Dispatchers.Main) {
5869
locationConsumers.forEach { it.onLocationUpdated(point) }
5970
locationConsumers.forEach { it.onBearingUpdated(bearing) }
6071
}
61-
if (iterator.hasNext() && isFakeLocationEmitting) {
62-
emitFakeLocations()
63-
}
64-
},
65-
LOCATION_UPDATE_INTERVAL_MS
66-
)
72+
delay(LOCATION_UPDATE_INTERVAL_MS)
73+
}
74+
}
6775
}
6876

6977
// use altitude of Point to pass through progress data, and use internal animator to interpolate

0 commit comments

Comments
 (0)