Fergus Hewson
10/06/2024, 7:52 PMFergus Hewson
10/06/2024, 7:52 PMalertSettingsManager.setTTSVoice(settingsIntent.voiceId)
soundManager.textToSpeech("Testing testing")
I have tried many different mechanisms with async and different dispatchers, getting a working solution but with hacky looking code. Is there a prescribed way to guarantee the execution order here?Javier
10/06/2024, 8:01 PMsuspend fun foo() {
suspendBar()
suspendBaz() // execution starts after suspendBar finishes
}
suspend fun suspendBar() {
// do something
}
suspend fun suspendBaz() {
// do something
}
Francesc
10/06/2024, 8:02 PMscope.launch {
suspendFun1()
suspendFun2()
}
then suspendFun2
only runs after suspendFun1
is finished.
What I suspect happens here is that setTTSVoice
is returning before the change ha been committed, so that when you read it, you get the old value. You would have to find a way to determine when the value has been committed so that you can read the new valueFergus Hewson
10/06/2024, 8:05 PMFergus Hewson
10/06/2024, 8:09 PMwithContext(Dispatchers.Default) {
alertSettingsManager.setTTSVoice(settingsIntent.voiceId)
}
withContext(Dispatchers.Default) {
soundManager.textToSpeech("testing testing")
}
Oliver.O
10/06/2024, 8:31 PMlaunch
coroutines under the hood without waiting for them to complete (which would be a questionable API design), what you wrote is equivalent to this:
withContext(Dispatchers.Default) {
coroutineScope {
alertSettingsManager.setTTSVoice(settingsIntent.voiceId)
}
soundManager.textToSpeech("testing testing")
}
Otherwise, if the functions are regular suspending functions, you could just write:
withContext(Dispatchers.Default) {
alertSettingsManager.setTTSVoice(settingsIntent.voiceId)
soundManager.textToSpeech("testing testing")
}
Oliver.O
10/06/2024, 8:36 PMtextToSpeech
.Uday
10/08/2024, 10:52 AMUday
10/08/2024, 10:53 AMUday
10/08/2024, 11:05 AMFergus Hewson
10/08/2024, 6:16 PMFergus Hewson
10/08/2024, 6:16 PMOliver.O
10/08/2024, 6:38 PMOliver.O
10/08/2024, 6:40 PMFergus Hewson
10/08/2024, 7:14 PMOliver.O
10/08/2024, 7:23 PMsuspend fun writeToKstore(voiceId: Any) {
// ...
}
fun CoroutineScope.speak(voiceId: Any, text: String) {
launch(<http://Dispatchers.IO|Dispatchers.IO>) {
// speak text with voiceId
}
}
suspend fun doItAll(backgroundScope: CoroutineScope) {
writeToKstore(settingsIntent.voiceId)
backgroundScope.speak(settingsIntent.voiceId, "blabla")
}
Oliver.O
10/08/2024, 7:25 PMbackgroundScope
that would cancel your background coroutines when appropriate, you could use GlobalScope
with the usual caveats (see docs).Fergus Hewson
10/08/2024, 7:25 PMFergus Hewson
10/08/2024, 7:25 PMOliver.O
10/08/2024, 7:27 PMFergus Hewson
10/08/2024, 7:48 PMwithContext(Dispatchers.Main) {
launch {
settings.alertSettingsManager.setTTSVoice(settingsIntent.voiceId)
}.invokeOnCompletion {
launch {
soundManager.textToSpeech("Work. Rest. Finished.")
}
}
}
Oliver.O
10/08/2024, 7:53 PMFergus Hewson
10/08/2024, 7:56 PMOliver.O
10/08/2024, 8:02 PMFergus Hewson
10/08/2024, 8:03 PMOliver.O
10/08/2024, 8:10 PMFergus Hewson
10/08/2024, 8:13 PMFergus Hewson
10/08/2024, 8:22 PMxxfast
10/15/2024, 9:13 AMlaunch
any coroutines under the hood. It is using the coroutine that the call-site `launch`es. If you want parallel behaviour you can achieve this by `launch`ing your own coroutines in parallel.
KStore does maintain a Mutex
lock to guarantee the read/writes are done sequentially in the call-corder and this is why all the API signatures to the store are `suspend`ed.
I’ve replied to your issue if you want more details,xxfast
10/15/2024, 9:16 AMlaunch {
store.set(settingsIntent.voiceId)
withContext(<http://Dispatcher.IO|Dispatcher.IO>){
soundManager.textToSpeech("Work. Rest. Finished.")
}
}
xxfast
10/15/2024, 9:18 AMFergus Hewson
10/15/2024, 6:03 PMFergus Hewson
10/15/2024, 6:04 PMxxfast
10/15/2024, 9:19 PMFergus Hewson
10/15/2024, 9:20 PM