ursus
04/18/2022, 10:01 PMfun ProgressThingy(duration: Long, running: Flow<Boolean>): Flow<Float> {
return callbackFlow {
val animator = ValueAnimator.ofFloat(0F, 1F)
animator.duration = duration
animator.addUpdateListener {
trySend(it.animatedFraction)
}
animator.addListener(onCancel = {
cancel()
})
animator.start()
running.collect {
if (it) animator.resume() else animator.pause()
}
awaitClose {
animator.cancel()
}
}
}
does anyone see a problem with collecting the running signal like that within the callback flow scope? it appears to work fineursus
04/18/2022, 10:04 PMcollect
obviosuly suspends so awaitClose is never registered since running
never completes
Any idea I could do this pattern? Rx used itJoffrey
04/18/2022, 10:05 PMawaitClose
ursus
04/18/2022, 10:07 PMursus
04/18/2022, 10:22 PMursus
04/18/2022, 10:28 PMJoffrey
04/18/2022, 10:37 PMclose()
on the channel it gives you, but I don't know the animator API so not sure how to know it is completeursus
04/18/2022, 10:38 PMJoffrey
04/18/2022, 10:38 PMursus
04/18/2022, 10:39 PMursus
04/18/2022, 10:39 PMclose
in there as wellJoffrey
04/18/2022, 10:40 PMtrySend
is provided by the producer scope I believe, and close should be also provided the same wayursus
04/18/2022, 10:40 PMJoffrey
04/18/2022, 10:42 PMursus
04/18/2022, 10:42 PMclose
is same as calling channel.close
?Joffrey
04/18/2022, 10:43 PMursus
04/18/2022, 10:44 PMursus
04/18/2022, 10:44 PMpublic override fun close(cause: Throwable?): Boolean {
val closed = Closed<E>(cause)
/*
* Try to commit close by adding a close token to the end of the queue.
* Successful -> we're now responsible for closing receivers
* Not successful -> help closing pending receivers to maintain invariant
* "if (!close()) next send will throw"
*/
val closeAdded = queue.addLastIfPrev(closed) { it !is Closed<*> }
val actuallyClosed = if (closeAdded) closed else queue.prevNode as Closed<*>
helpClose(actuallyClosed)
if (closeAdded) invokeOnCloseHandler(cause)
return closeAdded // true if we have closed
}