Skip to content
laforge49 edited this page Oct 28, 2011 · 8 revisions

Components are used to extend the capabilities of Actors. For example, if we have an actor which implements getter/setter message processing, it is easy to add a component which doubles the value held by the actor.

The code for getting and setting a value is pretty straight forward.

case class Set(value: Int)
case class Get()

class Saver extends Actor {
  var i = 0

  bind(classOf[Set], setFunc)
  private def setFunc(msg: AnyRef, rf: Any => Unit) {
    i = msg.asInstanceOf[Set].value
    rf(null)
  }

  bind(classOf[Get], getFunc)
  private def getFunc(msg: AnyRef, rf: Any => Unit) {
    rf(i)
  }
}

The code for the component which will double the value is similar.

case class Times2()

class DoubleComponent(saver: Saver) extends Component(saver) {
  bind(classOf[Times2], doubleFunc)
  private def doubleFunc(msg: AnyRef, rf: Any => Unit) {
    saver.i *= 2
    rf(null)
  }
}

Aggregating an actor with one or more components is easily done with a Factory class.

class DoubleFactory extends Factory(null) {
  override protected def instantiate = {
    val saver = new Saver
    val doubleComponent = new DoubleComponent(saver)
    addComponent(doubleComponent)
    saver
  }
}

The test code is also straight forward.

val doubleFactory = new DoubleFactory
val double = doubleFactory.newActor(new ReactorMailbox)
Future(double, Set(21))
Future(double, Times2())
println(Future(double, Get()))

And here's the output.

42

ComponentTest

Tutorial

Clone this wiki locally