Domanda

Ho implementato un tratto ascoltabile/ascoltatore che può essere aggiunto agli attori. Mi chiedo se è possibile attribuire questo stile di tratto a un attore senza che debba chiamare esplicitamente il ascoltatore metodo?

Inoltre mi aspettavo di trovare questa funzionalità nella biblioteca Akka. Mi manca qualcosa o c'è qualche motivo per cui Akka non lo includerebbe?

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())
    }
}
È stato utile?

Soluzione

Perché non estendersi Actor Direttamente, o se vuoi che i non attori siano anche ascoltabili, crea un ascoltableactor che estende l'attore con ascoltabile?

Quindi sovrascriveresti receive in attore come hai fatto sopra (tranne che vorresti chiamare super.receive Inoltre, vero?-vorresti solo modificare la funzione che è passata).

Altri suggerimenti

Ti suggerisco di estendere l'attore e usare un abstract override.

Perché non ho mai visto questa domanda prima, erm, beh, meglio tardi che mai:

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

Ecco una soluzione (una versione modificata dell'esempio dall'inizio 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)
        }
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top