You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

43 lines
1.1 KiB

2 years ago
2 years ago
2 years ago
2 years ago
  1. package net.aiterp.git.ykonsole2.domain.runtime
  2. import kotlinx.coroutines.flow.*
  3. import kotlinx.coroutines.runBlocking
  4. interface FlowBus<T : Any> {
  5. /**
  6. * Return this as shared flow
  7. */
  8. fun asSharedFlow(): SharedFlow<T>
  9. /**
  10. * Subscribe and read flow of [T].
  11. */
  12. suspend fun collect(forceAll: Boolean = false, action: suspend (value: T) -> Unit)
  13. /**
  14. * Emit an event to all subscribers.
  15. */
  16. suspend fun emit(data: T)
  17. /**
  18. * Emit [data] outside a coroutine.
  19. */
  20. fun emitBlocking(data: T) = runBlocking { emit(data) }
  21. }
  22. private class FlowBusImpl<T : Any> : FlowBus<T> {
  23. private val internal = MutableSharedFlow<T>()
  24. private val shared = internal.asSharedFlow()
  25. override fun asSharedFlow() = shared
  26. override suspend fun collect(forceAll: Boolean, action: suspend (value: T) -> Unit) = if (forceAll) {
  27. shared.buffer(capacity = 3).collect(action)
  28. } else shared.collectLatest(action)
  29. override suspend fun emit(data: T) = internal.emit(data)
  30. }
  31. fun CommandBus(): CommandBus = FlowBusImpl()
  32. typealias CommandBus = FlowBus<Command>
  33. fun EventBus(): EventBus = FlowBusImpl()
  34. typealias EventBus = FlowBus<Event>