Add alert playback controller
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
package se.ajpanton.notificationsmaster.alerts
|
||||
|
||||
/** Plays one resolved effect and invokes [onFinished] when all of its effects finish. */
|
||||
fun interface AlertEffectPlayer {
|
||||
fun play(alert: QueuedAlert, onFinished: () -> Unit)
|
||||
|
||||
fun stop() {}
|
||||
}
|
||||
|
||||
/** Serializes effect playback around the pure queue policy. */
|
||||
class AlertPlaybackController(
|
||||
private val effectPlayer: AlertEffectPlayer,
|
||||
private val settings: () -> AlertQueueSettings,
|
||||
) {
|
||||
private var queue = AlertQueue()
|
||||
|
||||
@Synchronized
|
||||
fun enqueue(alert: QueuedAlert): AlertQueueTransition {
|
||||
val before = queue
|
||||
return AlertQueueController.enqueue(queue, alert, settings()).also { transition ->
|
||||
queue = transition.queue
|
||||
playCurrentIfChanged(before.current)
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun currentQueue() = queue
|
||||
|
||||
@Synchronized
|
||||
fun stop() {
|
||||
queue = AlertQueue()
|
||||
effectPlayer.stop()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun complete(alert: QueuedAlert) {
|
||||
if (queue.current != alert) return
|
||||
val before = queue
|
||||
queue = AlertQueueController.completeCurrent(queue).queue
|
||||
playCurrentIfChanged(before.current)
|
||||
}
|
||||
|
||||
private fun playCurrentIfChanged(previous: QueuedAlert?) {
|
||||
val current = queue.current
|
||||
if (previous == current) return
|
||||
effectPlayer.stop()
|
||||
current?.let { alert -> effectPlayer.play(alert) { complete(alert) } }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user