Pergunta

Eu implementei um traço de ouvinte/ouvinte que pode ser adicionado aos atores. Estou me perguntando se é possível anexar esse estilo de característica a um ator sem ter que chamar explicitamente o ouvinte método?

Além disso, eu esperava encontrar essa funcionalidade na biblioteca Akka. Estou perdendo alguma coisa ou há alguma razão para que Akka não inclua isso?

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())
    }
}
Foi útil?

Solução

Por que não se estender Actor Diretamente, ou se você deseja que os não-atores também sejam ouvidos, crie um ouviceableActor que estende o ator com ouvido?

Você então substituiria receive no ator como você fez acima (exceto que você gostaria de ligar super.receive Além disso, não?-você só gostaria de modificar a função que foi passada).

Outras dicas

Eu sugiro que você estenda o ator e use um abstract override.

Por que eu nunca vi essa pergunta antes, erm, bem, melhor tarde do que nunca:

http://doc.akka.io/docs/akka/snapshot/scala/routing.html

Aqui está uma solução (uma versão modificada do exemplo do início do 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)
        }
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top