From bce3c6001fa9b361cae9019d5a4d96aaf6d7e103 Mon Sep 17 00:00:00 2001 From: Philipp Haller Date: Fri, 3 Nov 2006 16:32:58 +0000 Subject: Added new actor example. --- docs/examples/actors/Joins.scala | 16 +++-- docs/examples/actors/joins5.scala | 121 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+), 9 deletions(-) create mode 100644 docs/examples/actors/joins5.scala (limited to 'docs/examples') diff --git a/docs/examples/actors/Joins.scala b/docs/examples/actors/Joins.scala index 29ff220709..85105ec178 100644 --- a/docs/examples/actors/Joins.scala +++ b/docs/examples/actors/Joins.scala @@ -3,11 +3,11 @@ package examples.actors import scala.actors.Actor._ abstract class Producer[T] extends Iterator[T] { - - protected def produce(x: T): unit = coordinator !? HasValue(x) + protected def produce(x: T): unit = coordinator ! HasValue(x) protected def produceValues: unit - def hasNext: boolean = { setCurrent(); !current.isEmpty } + def hasNext = { setCurrent(); !current.isEmpty } + def next: T = { setCurrent() val res = current.get @@ -16,7 +16,8 @@ abstract class Producer[T] extends Iterator[T] { } private var current: Option[T] = null - private def setCurrent() = if (current == null) current = (coordinator !? Next).asInstanceOf[Option[T]] + private def setCurrent() = + if (current == null) current = (coordinator !? Next).asInstanceOf[Option[T]] private case class HasValue(value: T) private case object Next @@ -24,26 +25,23 @@ abstract class Producer[T] extends Iterator[T] { private case object Continue private val coordinator = actor { - while (true) { + while (true) receive { case Next => reply { receive { case HasValue(v) => - reply() Some(v) case Done => None } } } - } } actor { produceValues - coordinator !? Done - () + coordinator ! Done } } diff --git a/docs/examples/actors/joins5.scala b/docs/examples/actors/joins5.scala new file mode 100644 index 0000000000..fcf7d2390e --- /dev/null +++ b/docs/examples/actors/joins5.scala @@ -0,0 +1,121 @@ +import scala.actors._ +import scala.actors.Actor._ + +abstract class Producer[T] { + + /** A signal that the next value should be produced. */ + private val Next = new Object + + /** A label for an undefined state of the iterators. */ + private val Undefined = new Object + + protected def produce(x: T): unit = { + coordinator ! Some(x) + receive { case Next => } + } + protected def produceValues: unit + + def iterator = new Iterator[T] { + private var current: Any = Undefined + private def lookAhead = { + if (current == Undefined) current = coordinator !? Next + current + } + + def hasNext: boolean = lookAhead match { + case Some(x) => true + case None => false + } + + def next: T = lookAhead match { + case Some(x) => current = Undefined; x.asInstanceOf[T] + } + } + + /** A thread-based coordinator */ + private val coordinator: Actor = actor { + while (true) { + receive { + case Next => + producer ! Next + reply { + receive { case x: Option[_] => x } + } + } + } + } + + private val producer: Actor = actor { + receive { + case Next => + produceValues + coordinator ! None + } + } +} + +object Test extends Application { + + def from(m: int, n: int) = new Producer[int] { + def produceValues = for (val i <- m until n) produce(i) + } + + // note that it works from the main thread + val it = from(1, 10).iterator + while (it.hasNext) { + Console.println(it.next) + } + System.exit(0) +} + +object Test2 extends Application { + + class Tree(val left: Tree, val elem: int, val right: Tree) + def node(left: Tree, elem: int, right: Tree): Tree = new Tree(left, elem, right) + def node(elem: int): Tree = node(null, elem, null) + + def tree = node(node(node(3), 4, node(6)), 8, node(node(9), 10, node(11))) + + class PreOrder(n: Tree) extends Producer[int] { + def produceValues = traverse(n) + def traverse(n: Tree) { + if (n != null) { + produce(n.elem) + traverse(n.left) + traverse(n.right) + } + } + } + + class PostOrder(n: Tree) extends Producer[int] { + def produceValues = traverse(n) + def traverse(n: Tree) { + if (n != null) { + traverse(n.left) + traverse(n.right) + produce(n.elem) + } + } + } + + class InOrder(n: Tree) extends Producer[int] { + def produceValues = traverse(n) + def traverse(n: Tree) { + if (n != null) { + traverse(n.left) + produce(n.elem) + traverse(n.right) + } + } + } + + // note that it works from the main thread + Console.print("PreOrder:") + for (val x <- new PreOrder(tree).iterator) Console.print(" "+x) + Console.print("\nPostOrder:") + for (val x <- new PostOrder(tree).iterator) Console.print(" "+x) + Console.print("\nInOrder:") + for (val x <- new InOrder(tree).iterator) Console.print(" "+x) + Console.print("\n") + System.exit(0) +} -- cgit v1.2.3