All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.io.github.lyxnx.util.EventBus.kt Maven / Gradle / Ivy

There is a newer version: 1.6.1
Show newest version
package io.github.lyxnx.util

import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.filterIsInstance
import kotlin.coroutines.coroutineContext
import kotlin.jvm.JvmStatic
import kotlin.jvm.JvmSynthetic

/**
 * An event bus that can be used with the subscriber/listener pattern
 *
 * It is important to think if an event bus is really needed, where a [Flow] or LiveData could be used instead.
 *
 * As such, an event bus is easily abused and if so, keeping track of state becomes harder and this can introduce unintended behaviour.
 *
 * Usage of an event bus should be limited to a certain number of global events. For example, the user has logged out, or
 * the network status has changed.
 *
 * This should NOT be used to publish events to trigger a UI update - that is what a ViewModel is for.
 */
public object EventBus {

    private val _events: MutableSharedFlow = MutableSharedFlow(extraBufferCapacity = 1)

    @PublishedApi
    internal val events: SharedFlow = _events.asSharedFlow()

    /**
     * Publishes [event] to this event bus
     */
    @JvmSynthetic
    public fun publish(event: Any) {
        _events.tryEmit(event)
    }

    /**
     * Subscribes to a specific event as a read-only [Flow]
     *
     * @param T type of event to subscribe to
     */
    @JvmStatic
    public inline fun  subscribe(): Flow = events.filterIsInstance()

    /**
     * Subscribes to a specific event and calls [onEvent] on each event instance
     *
     * @param T type of event to subscribe to
     */
    @JvmSynthetic
    public suspend inline fun  subscribe(crossinline onEvent: (T) -> Unit) {
        subscribe()
            .collectLatest { event ->
                coroutineContext.ensureActive()
                onEvent(event)
            }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy