Reputation: 10629
I've implemented a Listenable/Listener trait that can be added to Actors. I'm wondering if it's possible to attach this style of trait to an actor without it having to explicitly call the listenerHandler method?
Also I was expecting to find this functionality in the Akka library. Am I missing something or is there some reason that Akka would not not include this?
trait Listenable { this: Actor =>
private var listeners: List[Actor] = Nil
protected def listenerHandler: PartialFunction[Any, Unit] = {
case AddListener(who) => listeners = who :: listeners
}
protected def notifyListeners(event: Any) = {
listeners.foreach(_.send(event))
}
}
class SomeActor extends Actor with Listenable
{
def receive = listenerHandler orElse {
case Start => notifyListeners(Started())
case Stop => notifyListeners(Stopped())
}
}
Upvotes: 8
Views: 1534
Reputation: 26597
Why haven't I seen this question before, erm, well, better late than never:
http://doc.akka.io/docs/akka/snapshot/scala/routing.html
Upvotes: 2
Reputation: 22660
There is built-in support for this in Akka: https://github.com/jboner/akka/blob/release-1.2/akka-actor/src/main/scala/akka/routing/Listeners.scala
Upvotes: 0
Reputation: 10629
Here is a solution (a modified version of the example from Beginning Scala):
import se.scalablesolutions.akka.actor.Actor
case class AddListener(who: Actor)
case class RemoveListener(who: Actor)
class ListenableActor extends Actor {
private var listeners: List[Actor] = Nil
def receive = {
case AddListener(who) => listeners ::= who
case RemoveListener(who) => listeners.filter(_ ne who)
}
protected def notifyListeners(event: Any) = {
listeners.foreach(_.send(event))
}
}
class ImplementingActor extends ListenableActor {
override def receive = {
super.receive orElse {
case Message(content) => println(content)
}
}
}
Upvotes: 0
Reputation: 297275
I suggest you extend Actor and use an abstract override
.
Upvotes: 2
Reputation: 167911
Why not extend Actor
directly, or if you want non-Actors to be Listenable also, create a ListenableActor that extends Actor with Listenable?
You then would override receive
in Actor as you've done above (except you'd want to call super.receive
also, wouldn't you?--you'd just want to modify the function that's passed in).
Upvotes: 5