2011-02-10 22 views
6

Merhaba Scala'da yeniyim ve daha sonra bir mesaj göndermek için bir aktör referansını ikinci bir oyuncuda nasıl saklayabileceğimi çözemedim. Kodumda bir oyuncuya test mesajı göndermeyi deniyorum. Bu mesajı aldığında, referansı (OutputChannel) ikinci aktöre kaydetmeli ve daha sonra ikinci aktöre bir mesaj gönderebilmelidir. Yanıtı çağırdığımda gönderilecek mesaja ihtiyacım olduğu için, cevabı() kullanmak istemedim. İşte kod. Herhangi bir yardım için teşekkürler!Bir scala oyuncusu referansını nasıl kaydedebilirim?

import scala.actors.Actor 
import scala.actors.Actor._ 
import scala.collection.mutable.ArrayBuffer 
import scala.actors.OutputChannel 

object testactors { 

    case object TestMessage 
    case object Respond 

    class TestActor(name: String) extends Actor { 
     private var source : ArrayBuffer[OutputChannel[Any]] = new ArrayBuffer 

     def act() { 
      loop { 
       react{ 
        case TestMessage => 
         println("i received a TestMessage " + name) 
         source += sender 
        case Respond => 
         println("i received a ResponseMessage " + name) 
       } 
      } 
     } 

     def sendMessage(dest: Actor) = dest ! TestMessage 

     def respond = { 
      println("responding... " + name) 
      source(0) ! Respond 
     } 
    } 


    def main(args: Array[String]) { 
     val actor1 = new TestActor("one") 
     actor1.start 

     val actor2 = new TestActor("two") 
     actor2.start 

     actor1.sendMessage(actor2) 

     Thread.sleep(5000) 

     actor2.respond 
    } 
} 

cevap

4

1. Bir merkezi aktör kayıt oluşturabilirsiniz olduğunu. Tekerleği yeniden icat etmekten kaçınmak için, iyi bir uygulama - Akka's Actor Registry (veya en azından ilham alın) kullanabilirsiniz.

case class AddActor(actor: Actor) 
case object NotifyAll 

class StatefulActor extends Actor { 

    override def act = loop(Nil) 

    def loop(actors: List[Actor]):Unit = { 
    react { 
     case AddActor(actor) => println("Added new actor") 
     loop(actor :: actors) 
     case NotifyAll => println("Notifying actors: " + actors) 
     actors.foreach(_ ! "Hi!") 
     loop(actors) 
     case unknown => println("Unknown message: " + unknown)  
     loop(actors) 
    } 
    } 

} 
+0

bu, sahip olduğum problemle mükemmel şekilde uyuyor. çok teşekkürler Vasil! – spydadome

+0

@spydadome, bir şey değil :) –

1

Bunu yapmanın bir yolu, her yerden alabileceğiniz oyuncuları depolayan bir Aktör Fabrikası oluşturmaktır.

import scala.actors.Actor 
import scala.actors.Actor._ 
import scala.collection.mutable._ 

Mesajlar Burada aktör türlerinin bir çift (herhangi bir "yük") ile ya da nesneler olabilir, ya da veri

abstract class Message 
case object MessageType1 extends Message 
case class MessageType2(str:String) extends Message 

içeren sınıfları olabilir. Actor2 örneği açıkça ana

class MyActor1 extends Actor { 
    def act() { 
     loop { 
      react { 
       case MessageType1 => 
        println("MessageType1 received") 
        ActorFactory.getActor2("B") ! MessageType2("Hello") 
       case _ => 
      } 
     } 
    } 
} 

class MyActor2 extends Actor { 
    def act() { 
     loop { 
      react { 
       case MessageType2(theString) => 
        println(theString+" from actor 2 instance") 
       case _ => 
      } 
     } 
    } 
} 

aşağıdaki ActorFactory yaratır ve saklar aktörler bildirilmiştir Actor1 örneği olduğu gibi, "on-the-fly" örneği ve daha sonra kullanılmak üzere ActorFactory saklanır. Burada, bir tür aktörün birden çok örneğini oluşturabilir ve ada göre depolayabilirsiniz.

object ActorFactory { 
    val actorMap = new HashMap[String,Actor] with SynchronizedMap[String,Actor] 

    def getActor1(symbol:String): Actor = { 
     val actor = actorMap.getOrElseUpdate(symbol,new MyActor1().start) 
     actor 
    } 

    def getActor2(symbol:String): Actor = { 
     val actor = actorMap.getOrElseUpdate(symbol,new MyActor2().start) 
     actor 
    } 
} 

object Test { 

    def main(args : Array[String]) {      

     val actor1 = ActorFactory.getActor1("A") 
     actor1 ! MessageType1 

    } 

} 

bu çıkışı

MessageType1 received 
Hello from actor 2 instance 
+0

sayesinde çok Bruce: Bunu geçen aktör referansların değişken listesini kullanarak önleyebilirsiniz

döngü tepki! şimdi benim için çalışıyor! – spydadome

İlgili konular