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 finecollect
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 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 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 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
}