package wow.doge.mygame.events import akka.actor.typed.ActorRef import akka.actor.typed.Behavior import akka.actor.typed.scaladsl.Behaviors import scala.reflect.ClassTag import akka.event.EventStream /** * A (typed) event bus * Copied (and repurposed) from Akka's EventStream */ object EventBus { sealed trait Command[A] final case class Publish[A, E <: A]( event: E, publisherName: String ) extends Command[A] final case class Subscribe[A, E <: A](subscriber: ActorRef[E])(implicit classTag: ClassTag[E] ) extends Command[A] { def topic: Class[_] = classTag.runtimeClass } final case class Unsubscribe[A, E <: A](subscriber: ActorRef[E]) extends Command[A] def apply[A](): Behavior[EventBus.Command[A]] = Behaviors.setup { ctx => val eventStream = new EventStream(ctx.system.classicSystem) new EventBus().eventStreamBehavior(eventStream) } } class EventBus[B] { import akka.actor.typed.scaladsl.adapter._ private def eventStreamBehavior( eventStream: akka.event.EventStream ): Behavior[EventBus.Command[B]] = Behaviors.receiveMessage { case EventBus.Publish(event, name) => eventStream.publish(event) Behaviors.same case s @ EventBus.Subscribe(subscriber) => eventStream.subscribe(subscriber.toClassic, s.topic) Behaviors.same case EventBus.Unsubscribe(subscriber) => eventStream.unsubscribe(subscriber.toClassic) Behaviors.same } }