Concurrency Actors and Traits in Scala
Folks, I'm new to Scala and am trying to figure something out. I've been messing around a bit with traits and I really like their ability to "mix in" functionality and interface. I've also been messing around with concurrency and Actors and I really like the ability I get to model highly complicated concurrent systems easily.
The problem I'm having is I can't quite find a pattern for combining both worlds. What I'm really looking for is using traits to determine which types of messages an Actor responds to, allowing for different responses across inheritance hierarchies.
So, to use a battlefield simulator example: I have Simulants, which are traits. All objects on the battlefield are Simulants, and Simulants should respond to "Ping" by sending "Pong" - this is it. I want an IFF
trait, which will allow a simulant to identify itself as a friend or foe of the message sender. Another trait should be Mobile
, which means the simulant can move and should respond to messages telling the simulant its new destination.
As you can see, I might have : class Tank extends Actor with Simulant with IFF wi开发者_开发技巧th Mobile
, but I might have something like a barrier, e.g. class Barrier extends Actor with Simulant
.
What I have not yet been able to do is create the right combination of act()
methods, loops, reacts, and so forth to make this scenario possible. In short, is it possible to "mix in message reactors" or does Scala limit me to choosing Actors with single inheritance or mixins without actors?
Thanks!
What about this?
trait Simulant {
def body: PartialFunction[Any, Unit] = {
case Ping => reply(Pong)
}
def act = loop { react(body) }
}
trait IFF extends Simulant {
override def body = super.body orElse {
case FriendOrFoe => ...
}
}
trait Mobile extends Simulant {
override def body = super.body orElse {
case Move(direction) => ...
}
}
EDIT: I've just tried this and it compiles fine for me:
aromanov@alexey-desktop:~$ scala
Welcome to Scala version 2.9.0.1 (OpenJDK Client VM, Java 1.6.0_22).
Type in expressions to have them evaluated.
Type :help for more information.
scala> object A {
| import scala.actors.Actor
| trait Simulant extends Actor {
| def body: PartialFunction[Any, Unit] = {
| case Ping => reply(Pong)
| }
|
| def act = loop { react(body) }
| }
|
| trait IFF extends Simulant {
| override def body = super.body orElse {
| case FriendOrFoe => {}
| }
| }
|
| trait Mobile extends Simulant {
| override def body = super.body orElse {
| case Move(direction) => {}
| }
| }
|
| class Foo extends Actor with Simulant with IFF with Mobile
|
| object Ping
| object Pong
| object FriendOrFoe
| case class Move(direction: Int)
| }
defined module A
On the other hand, it doesn't seem to actually work: when I replace case Ping => println("pinged")
, I don't see it:
scala> (new A.Foo) ! A.Ping
scala>
I did a blog post up on this problem and the compromise that I've found for solving the problem.
http://www.kotancode.com/2011/07/19/traits-multiple-inheritance-and-actors-in-scala/
精彩评论