Picnic Invasion! day 2 postmortem
Even less progress than day 1. I’m considering switching to weekly updates since my main focus right now is school, but doing them daily forces me to get something done, no matter how small.
Anyways, yesterday’s small bit of advancement was working on communication between an actor network and the game loop handling code. Specifically I want to be able to notify an actor about something (user input, a game tick happened, we need renderables, whatever) and wait for it to finish.
To test this I started modifying the pingpong example. A bit of playing around with it gave me this:
import scala.actors.Actor
import scala.actors.Actor._
import scala.actors.OutputChannel
abstract class PingMessage
case object Start extends PingMessage
case object SendPing extends PingMessage
case object Pong extends PingMessage
case object Done extends PingMessage
abstract class PongMessage
case object Ping extends PongMessage
case object Stop extends PongMessage
object pingpong extends Application {
val pong = new Pong
val ping = new Ping(100000, pong)
ping.start
pong.start
val f = ping !! Start
f()
println("This happened after the actors")
}
class Ping(count: Int, pong: Actor) extends Actor {
self.trapExit = true;
var initiator = null : OutputChannel[Any];
def act() {
println("Ping: Initializing with count "+count+": "+pong)
var pingsLeft = count
loop {
react {
case Start =>
initiator = sender;
println("Ping: starting.")
pong ! Ping
pingsLeft = pingsLeft - 1
case SendPing =>
pong ! Ping
pingsLeft = pingsLeft - 1
case Pong =>
if (pingsLeft % 1000 == 0)
println("Ping: pong from: "+sender)
if (pingsLeft > 0)
self ! SendPing
else {
println("Ping: Stop.")
pong ! Stop
self ! Done
}
case Done =>
initiator ! Done
exit('stop)
}
}
}
}
class Pong extends Actor {
def act() {
var pongCount = 0
loop {
react {
case Ping =>
if (pongCount % 1000 == 0)
println("Pong: ping "+pongCount+" from "+sender)
sender ! Pong
pongCount = pongCount + 1
case Stop =>
println("Pong: Stop.")
exit('stop)
}
}
}
}
The original example is largely unmodified, except for the following changes:
- Added an “initiator” variable to the Ping actor, which is set with a reference to the actor that sent the “Start” message.
- Added a “Done” message to the Ping actor, which it sends to itself to call cleanup code and send its reply to the “initiator” saved in Start.
Granted, this would run into some problems if I were to send Start to Ping twice in a row without blocking until it completes, but I don’t plan on doing that.
No commentsNo comments yet. Be the first.
Leave a reply