A simple EventBus implementation based on Kotlin SharedFlow and inspired by Greenrobot EventBus.
Use MavenCentral in settings.gradle.kts
:
repositories {
mavenCentral()
}
Include in application build.gradle.kts
:
dependencies {
implementation("org.holance:ktbus:{version}")
}
Make sure to replace {version}
with the version of the library.
flowchart TD
A["Publisher"] --> B(("SharedFlow"))
B --> C["Subscriber 1"] & D["Subscriber 2"]
data class Event1(val value: Int)
data class Event2(val value: Int)
data class Event3(val value: Int)
class SomeClass {
val bus = KtBus.getDefault()
fun setup() {
bus.subscribe(this)
}
fun tearDown() {
bus.unsubscribe(this)
}
@Subscribe
fun onEvent1(event: Event1) {
// Do something with the event
}
@Subscribe(scope = DispatcherTypes.IO)
fun onEvent2(event: Event2) {
// Do something with the event in a IO coroutine scope
}
@Subscribe
fun onEvent3(event: Event3) {
// Do something with the event
}
}
val bus = KtBus.getDefault()
bus.post(Event1(1))
bus.post(Event2(2))
bus.post(Event3(3))
flowchart TD
n1["Request"] --> n2(("SharedFlow"))
n2 --> n3["Subscriber"]
n3 -- Response --> n2
n2 -- Response --> n1
data class ComputeSquareRequest(val value: Int)
data class ComputeSquareResult(val value: Int)
class MathClass {
val bus = KtBus.getDefault()
fun setup() {
bus.subscribe(this)
}
fun tearDown() {
bus.unsubscribe(this)
}
@RequestHandler
fun computeSquare(event: ComputeSquareRequest) : ComputeSquareResult {
return ComputeSquareResult(event.value * event.value)
}
}
val bus = KtBus.getDefault()
try {
val result = bus.request<ComputeSquareRequest, ComputeSquareResult>(ComputeSquareRequest(5))
assert(result.value == 25)
}
catch (e: RequestException) {
// Handle request handler exception
}
catch (e: NoRequestHandlerException) {
// Handle no request handler exception
}
catch (e: RequestTimeoutException) {
// Handle request timeout exception
}
data class SomeEvent(val value: Int)
class SomeClass {
val bus = KtBus.getDefault()
fun setup() {
bus.subscribe(this)
}
fun tearDown() {
bus.unsubscribe(this)
}
@Subscribe(channel = "channel1")
fun handleEventFromChannel1(event: SomeEvent) {
// Do something with the event
}
@Subscribe(channel = "channel2")
fun handleEventFromChannel2(event: SomeEvent) {
// Do something with the event
}
@Subscribe(channel = "channel3")
fun handleEventFromChannel3(event: SomeEvent) {
// Do something with the event
}
}
val bus = KtBus.getDefault()
bus.post(SomeEvent(1), "channel1")
bus.post(SomeEvent(2), "channel2")
bus.post(SomeEvent(3), "channel3")
data class SomeEvent(val value: Int)
class SomeClass(val channel: String) {
class SomeChannelFactory : ChannelFactory {
override fun getChannel(obj: Any): String {
return (obj as? SomeClass)?.channel ?: DefaultChannelFactory.DEFAULT_CHANNEL
}
}
val bus = KtBus.getDefault()
fun setup() {
bus.subscribe(this)
}
fun tearDown() {
bus.unsubscribe(this)
}
@Subscribe(channelFactory = SomeChannelFactory::class)
fun handleEvent(event: SomeEvent) {
// Do something with the event
}
}
val objCh1 = SomeClass("channel1")
objCh1.setup()
val bus = KtBus.getDefault()
bus.post(SomeEvent(1), "channel1")