Skip to content

Commit

Permalink
Keanu (#7)
Browse files Browse the repository at this point in the history
* simple EventBus
  • Loading branch information
alterationx10 authored Nov 14, 2024
1 parent bf6a592 commit 7278021
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 3 deletions.
10 changes: 9 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,18 @@ lazy val blammo = {
.dependsOn(macaroni, lzy, friday, veil)
}

lazy val keanu =
project
.in(file("keanu"))
.settings(
name := "keanu"
)
.dependsOn(macaroni, lzy, blammo)

lazy val example =
project
.in(file("example"))
.dependsOn(macaroni, lzy, spider, piggy, friday, veil, blammo)
.dependsOn(macaroni, lzy, spider, piggy, friday, veil, blammo, keanu)
.settings(
name := "example",
libraryDependencies ++= Seq( // Examples and tests are allowed to have dependencies :-)
Expand Down
26 changes: 26 additions & 0 deletions example/src/main/scala/app/wishingtree/KeanuExample.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package app.wishingtree

import dev.wishingtree.branch.keanu.eventbus.{EventBus, EventMessage, Subscriber}

object IntEventBus extends EventBus[Int]

object KeanuExample extends Subscriber[Int] { self =>

override def onMessage(msg: Int): Unit =
println(s"Got Int = $msg")

def main(args: Array[String]): Unit = {

IntEventBus.subscribe(self, _.payload > 5)
IntEventBus.subscribe(self, _.payload % 2 == 0)

IntEventBus.subscribe((msg: Int) => println(s"Got message $msg"))

IntEventBus.publish(EventMessage[Int]("tinyInts", 4))
IntEventBus.publish(EventMessage[Int]("tinyInts", 6))
IntEventBus.publish(EventMessage[Int]("tinyInts", 10))
IntEventBus.publish(EventMessage[Int]("tinyInts", 9))

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package dev.wishingtree.branch.keanu.eventbus

import java.util
import java.util.UUID
import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer
import scala.util.Try

trait EventBus[T] {

private case class Subscription(
id: UUID,
subscriber: Subscriber[T],
filter: EventMessage[T] => Boolean
)

private val subscribers: mutable.ArrayBuffer[Subscription] =
ArrayBuffer.empty

def publish(msg: EventMessage[T]): Unit = synchronized {
subscribers.foreach { sub =>
if sub.filter(msg) then Try(sub.subscriber.onMessage(msg.payload))
}
}

def subscribe(subscriber: Subscriber[T]): UUID =
synchronized {
val sub = Subscription(UUID.randomUUID(), subscriber, _ => true)
subscribers.addOne(sub)
sub.id
}

def subscribe(
subscriber: Subscriber[T],
filter: EventMessage[T] => Boolean
): UUID = {
synchronized {
val sub = Subscription(UUID.randomUUID(), subscriber, filter)
subscribers.addOne(sub)
sub.id
}
}

def unsubscribe(subscriber: Subscriber[T]): Unit =
synchronized {
subscribers.filterInPlace(sub => sub.subscriber != subscriber)
}

def unsubscribe(ids: UUID*): Unit =
synchronized {
subscribers.filterInPlace(sub => !ids.contains(sub.id))
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package dev.wishingtree.branch.keanu.eventbus

case class EventMessage[T](topic: String, payload: T)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package dev.wishingtree.branch.keanu.eventbus

trait Subscriber[T] {
def onMessage(msg: T): Unit
}
3 changes: 2 additions & 1 deletion site/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@
- [Friday](./friday/index.md)
- [Macaroni](./macaroni/index.md)
- [Veil](./veil/index.md)
- [Blammo](./blammo/index.md)
- [Blammo](./blammo/index.md)
- [Keanu](./keanu/index.md)
2 changes: 1 addition & 1 deletion site/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ things done quickly! Think of it as the framework for your side-project, not you
- **Macaroni** - Some re-usable helpers and meta-programming utilities.
- **Veil** - `.env` / (Json based) Config utilities.
- **Blammo** - It's better than bad, it's (Json) logging!
- **Keanu** - A simple *typed* EventBus implementation, and where Actors will eventually live

... and *more to come*!

A list of other things important to this framework's goals are (but not limited to):

- Web Sockets
- Event Bus
- Actors, even if it kills me.
- (HTML) Templating
12 changes: 12 additions & 0 deletions site/src/keanu/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Keanu

This module currently contains a simple *typed* EventBus.

Have an object extend `EventBus[T]` for your type, e.g.

```scala 3
object IntEventBus extends EventBus[Int]
```

Then, you can have some implementation extend `Subsciber[T]` and subscribe, or pass in an anonymous implementation (e.g.
`IntEventBus.subscribe((msg: Int) => println(s"Got message $msg"))`)

0 comments on commit 7278021

Please sign in to comment.