@@ -24,8 +24,10 @@ import com.mapbox.navigation.utils.internal.InternalJobControlFactory
2424import com.mapbox.navigation.utils.internal.logE
2525import kotlinx.coroutines.cancel
2626import kotlinx.coroutines.launch
27+ import kotlinx.coroutines.suspendCancellableCoroutine
2728import java.net.MalformedURLException
2829import java.net.URL
30+ import kotlin.coroutines.resume
2931
3032internal class MapboxSpeechLoader (
3133 private val accessToken : String ,
@@ -35,7 +37,6 @@ internal class MapboxSpeechLoader(
3537 private val resourceLoader : ResourceLoader ,
3638) {
3739
38- private val currentRequests = mutableSetOf<Long >()
3940 private val downloadedInstructions = mutableSetOf<TypeAndAnnouncement >()
4041 private val downloadedInstructionsLock = Any ()
4142 private val defaultScope = InternalJobControlFactory .createDefaultScopeJobControl().scope
@@ -60,8 +61,8 @@ internal class MapboxSpeechLoader(
6061 }
6162
6263 fun triggerDownload (voiceInstructions : List <VoiceInstructions >) {
63- defaultScope.launch {
64- voiceInstructions.forEach { voiceInstruction ->
64+ voiceInstructions.forEach { voiceInstruction ->
65+ defaultScope.launch {
6566 val typeAndAnnouncement = VoiceInstructionsParser .parse(voiceInstruction).value
6667 if (typeAndAnnouncement != null && ! hasTypeAndAnnouncement(typeAndAnnouncement)) {
6768 predownload(typeAndAnnouncement)
@@ -72,7 +73,6 @@ internal class MapboxSpeechLoader(
7273
7374 fun cancel () {
7475 defaultScope.cancel()
75- currentRequests.forEach { resourceLoader.cancel(it) }
7676 }
7777
7878 private fun hasTypeAndAnnouncement (typeAndAnnouncement : TypeAndAnnouncement ): Boolean {
@@ -81,20 +81,21 @@ internal class MapboxSpeechLoader(
8181 }
8282 }
8383
84- private fun predownload (typeAndAnnouncement : TypeAndAnnouncement ) {
84+ private suspend fun predownload (typeAndAnnouncement : TypeAndAnnouncement ) {
8585 try {
86- val request = createRequest(typeAndAnnouncement)
87- var id : Long? = null
88- id = resourceLoader.load(request) { result ->
89- id?. let { currentRequests.remove(it) }
90- // tilestore thread
91- if (result.isValue ) {
92- synchronized(downloadedInstructionsLock) {
93- downloadedInstructions.add(typeAndAnnouncement)
86+ suspendCancellableCoroutine { cont ->
87+ val request = createRequest(typeAndAnnouncement)
88+ val id = resourceLoader.load(request) { result ->
89+ // tilestore thread
90+ if (result.isValue) {
91+ synchronized(downloadedInstructionsLock ) {
92+ downloadedInstructions.add(typeAndAnnouncement)
93+ }
9494 }
95+ cont.resume(Unit )
9596 }
97+ cont.invokeOnCancellation { resourceLoader.cancel(id) }
9698 }
97- currentRequests.add(id)
9899 } catch (ex: Throwable ) {
99100 logE(" Failed to download instruction '$typeAndAnnouncement ': ${ex.localizedMessage} " )
100101 }
0 commit comments