Commit 4501410f authored by h2b's avatar h2b

Multi-screen subscription supported.

parent 850341ab
...@@ -72,11 +72,11 @@ Since version 1.2.0 an event package is available that constitutes a high-level ...@@ -72,11 +72,11 @@ Since version 1.2.0 an event package is available that constitutes a high-level
Such events, if triggered by the drivers, are published to the global event stream of that package and can be retrieved by subscribing to its `stream` object. Such events, if triggered by the drivers, are published to the global event stream of that package and can be retrieved by subscribing to its `stream` object.
Also, there is a `Subscriber` actor that can be used to handle events. Since version 1.3.0, it's companion object defines `on` methods for screens and worlds with a `PartialFunction[Event, Unit]` as a parameter. Also, there is a `Subscriber` actor that can be used to handle events. Since version 1.3.0, it's companion object defines `to` methods for screens and worlds with a `PartialFunction[Event, Unit]` as a parameter.
So, for example, you just can write So, for example, you just can write
Subscriber.on(world) { Subscriber.to(world) {
case e: Event ⇒ println(e) case e: Event ⇒ println(e)
} }
......
...@@ -32,7 +32,7 @@ import de.h2b.scala.lib.util.{ Level, Logger } ...@@ -32,7 +32,7 @@ import de.h2b.scala.lib.util.{ Level, Logger }
* *
* @param screen optional classifier * @param screen optional classifier
*/ */
class Publisher (screen: Option[Screen] = None) extends Actor { class Publisher (val screen: Option[Screen] = None) extends Actor {
private val log = Logger(getClass) at Level.Warn private val log = Logger(getClass) at Level.Warn
......
...@@ -23,15 +23,17 @@ import de.h2b.scala.lib.util.{ Level, Logger } ...@@ -23,15 +23,17 @@ import de.h2b.scala.lib.util.{ Level, Logger }
/** /**
* Provides an actor subscribing to `Event`s received from the package object's * Provides an actor subscribing to `Event`s received from the package object's
* global event stream. * global event stream for each of the specified screens.
* *
* @since 1.2.0 * @since 1.2.0
* @author h2b * @author h2b
*/ */
class Subscriber private (screen: Option[Screen]) class Subscriber private (val screens: Set[Screen])
(val handler: PartialFunction[Event, Unit]) extends Actor { (val handler: PartialFunction[Event, Unit]) extends Actor {
override def preStart = stream.subscribe(self, screen) override def preStart =
if (screens.isEmpty) stream.subscribe(self, None)
else for (screen screens) stream.subscribe(self, Some(screen))
private val log = Logger(getClass) at Level.Warn private val log = Logger(getClass) at Level.Warn
...@@ -50,34 +52,42 @@ object Subscriber { ...@@ -50,34 +52,42 @@ object Subscriber {
/** /**
* Subscribes to events not associated with a screen. * Subscribes to events not associated with a screen.
* *
* @note Currently, no such events are published by this package.
*
* @param handler partial function handling received events * @param handler partial function handling received events
* @return a reference to a new subscriber * @return a reference to a new subscriber
*/ */
def ref (handler: PartialFunction[Event, Unit]): ActorRef = def ref (handler: PartialFunction[Event, Unit]): ActorRef =
system.actorOf(Props(new Subscriber(None)(handler))) system.actorOf(Props(new Subscriber(Set.empty)(handler)))
/** /**
* Subscribes to events of a specified screen. * Subscribes to events of specified screens.
* *
* @param screen the screen to be listened for events * @param screen screen to be listened for events
* @param moreScreens additional screens to be listened for events (may be
* empty)
* @param handler partial function handling received events * @param handler partial function handling received events
* @return a reference to a new subscriber * @return a reference to a new subscriber
* *
* @since 1.3.0 * @since 1.3.0
*/ */
def on (screen: Screen) (handler: PartialFunction[Event, Unit]): ActorRef = def to (screen: Screen, moreScreens: Screen*)
system.actorOf(Props(new Subscriber(Some(screen))(handler))) (handler: PartialFunction[Event, Unit]): ActorRef =
system.actorOf(Props(new Subscriber(moreScreens.toSet + screen)(handler)))
/** /**
* Subscribes to events of a specified world. * Subscribes to events of specified worlds.
* *
* @param world the world to be listened for events * @param world world to be listened for events
* @param moreWorlds additional worlds to be listened for events (may be
* empty)
* @param handler partial function handling received events * @param handler partial function handling received events
* @return a reference to a new subscriber * @return a reference to a new subscriber
* *
* @since 1.3.0 * @since 1.3.0
*/ */
def on (world: World) (handler: PartialFunction[Event, Unit]): ActorRef = def to (world: World, moreWorlds: World*)
on(world.screen)(handler) (handler: PartialFunction[Event, Unit]): ActorRef =
to(world.screen, (moreWorlds map {_.screen}): _*)(handler)
} }
...@@ -29,13 +29,13 @@ import akka.event.EventBus ...@@ -29,13 +29,13 @@ import akka.event.EventBus
* `stream` object. * `stream` object.
* *
* Also, there is a `Subscriber` actor that can be used to handle events. * Also, there is a `Subscriber` actor that can be used to handle events.
* Since version 1.3.0, it's companion object defines `on` methods for screens * Since version 1.3.0, it's companion object defines `to` methods for screens
* and worlds with a `PartialFunction[Event, Unit]` as a parameter. * and worlds with a `PartialFunction[Event, Unit]` as a parameter.
* *
* So, for example, you just can write * So, for example, you just can write
* *
* {{{ * {{{
* Subscriber.on(world) { * Subscriber.to(world) {
* case e: Event ⇒ println(e) * case e: Event ⇒ println(e)
* } * }
* }}} * }}}
......
...@@ -50,23 +50,27 @@ object EventEchoDemo extends App { ...@@ -50,23 +50,27 @@ object EventEchoDemo extends App {
case _ Color.Red case _ Color.Red
})) }))
Subscriber.on(world1) { Subscriber.to(world1) {
case KeyEvent(k) if k=='q'
world1.screen.close()
system.terminate()
case e: Event case e: Event
println("w1: " + e) println("w1: " + e)
} }
Subscriber.on(world2) { Subscriber.to(world2) {
case e: Event
println("w2: " + e)
}
Subscriber.to(world1, world2) {
case KeyEvent(k) if k=='q' case KeyEvent(k) if k=='q'
world1.screen.close()
world2.screen.close() world2.screen.close()
system.terminate() system.terminate()
case e: Event case _: Event ()
println("w2: " + e)
} }
//Note: When one world is closed by 'q', the system is terminated and the Subscriber.ref {
//other one will not print events anymore. case e: Event
println("unexpected: " + e) //should not happen
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment