Joel Denke
08/21/2023, 11:57 AMblakelee
09/10/2023, 5:51 AMclass DeferredQueue<R>(private val coroutineScope: CoroutineScope) {
private val queue = Channel<Deferred<R>>(Channel.RENDEZVOUS)
private var onIdle: (suspend () -> Unit) = {}
init {
coroutineScope.launch {
while (true) {
select {
queue.onReceive { element ->
element.join()
}
// When there are no items in the queue, invoke the onIdle callback if set then wait for an item in the queue
// to continue
onTimeout(1) {
onIdle()
queue.receive().join()
}
}
}
}
}
fun onIdle(block: suspend () -> Unit): DeferredQueue<R> = also { onIdle = block }
suspend fun add(block: suspend CoroutineScope.() -> R): R {
val deferred = coroutineScope.async(start = CoroutineStart.LAZY) {
block()
}
queue.send(deferred)
return deferred.await()
}
}