summaryrefslogtreecommitdiff
path: root/docs/examples/actors/Joins.scala
diff options
context:
space:
mode:
Diffstat (limited to 'docs/examples/actors/Joins.scala')
-rw-r--r--docs/examples/actors/Joins.scala60
1 files changed, 60 insertions, 0 deletions
diff --git a/docs/examples/actors/Joins.scala b/docs/examples/actors/Joins.scala
new file mode 100644
index 0000000000..7ea2a50e11
--- /dev/null
+++ b/docs/examples/actors/Joins.scala
@@ -0,0 +1,60 @@
+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 produceValues: unit
+
+ def hasNext: boolean = { setCurrent(); !current.isEmpty }
+ def next: T = {
+ setCurrent()
+ val res = current.get
+ current = (coordinator !? Next()).asInstanceOf[Option[T]]
+ res
+ }
+
+ private var current: Option[T] = null
+ private def setCurrent() = if (current == null) current = (coordinator !? Next()).asInstanceOf[Option[T]]
+
+ private case class HasValue(value: T)
+ private case class Next
+ private case class Done
+ private case class Continue
+
+ /** A thread-based coordinator */
+ private val coordinator = actor {
+ while (true) {
+ receive {
+ case Next() =>
+ reply {
+ receive {
+ case HasValue(v) =>
+ reply()
+ Some(v)
+ case Done() =>
+ None
+ }
+ }
+ }
+ }
+ }
+
+ actor {
+ produceValues
+ coordinator !? Done()
+ }
+}
+
+object Joins 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)
+ while (it.hasNext) {
+ Console.println(it.next)
+ }
+}