Guest User

Untitled

a guest
Sep 26th, 2018
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.44 KB | None | 0 0
  1. object Actor {
  2. import java.util.concurrent.{ConcurrentLinkedQueue, Executor}
  3. import java.util.concurrent.atomic.{AtomicBoolean}
  4.  
  5. sealed trait Instr
  6. case object Continue extends Instr
  7. case class Become(b: Any => Instr) extends Instr
  8. case object Dead extends Instr
  9.  
  10. trait Address {
  11. def !(msg: Any): Unit
  12. }
  13.  
  14. def apply(initial: Any => Instr)(implicit e: Executor): Address = {
  15. val a: Address = new Address with Runnable {
  16. private final val mbox = new ConcurrentLinkedQueue[Any]
  17. private final val on = new AtomicBoolean(false)
  18. private var behavior: Any => Instr = {
  19. case i: Instr => i
  20. case _ => println("Unknown message"); Continue
  21. }
  22.  
  23. final def trySchedule(): Unit = if(!mbox.isEmpty && on.compareAndSet(false, true)) {
  24. try e.execute(this) catch {
  25. case anything => assert(on.getAndSet(false)); throw anything
  26. }
  27. }
  28.  
  29. final def reactTo(msg: Any): Unit = behavior(msg) match {
  30. case Become(newBeh) => behavior = newBeh
  31. case Dead => println("Dead, cannot deal with: " + msg)
  32. case Continue => //Just remain as you were
  33. }
  34.  
  35. final def run() = try reactTo(mbox.poll()) finally {
  36. assert(on.getAndSet(false))
  37. trySchedule()
  38. }
  39.  
  40. final override def !(msg: Any): Unit = {
  41. assert(mbox.offer(msg))
  42. trySchedule()
  43. }
  44. }
  45. a ! Become(initial)
  46. a
  47. }
  48. }
Add Comment
Please, Sign In to add comment