From aeb29ddfbb4ed2000c6e8ed2bc80619e2c157aff Mon Sep 17 00:00:00 2001 From: Philipp Haller Date: Fri, 18 Jul 2008 16:11:46 +0000 Subject: Made mailbox in Actor protected (this is necess... Made mailbox in Actor protected (this is necessary for JoinActor). Added get and remove methods to MessageQueue. --- src/actors/scala/actors/Actor.scala | 2 +- src/actors/scala/actors/MessageQueue.scala | 83 +++++++++++++++++++++++++++++- 2 files changed, 83 insertions(+), 2 deletions(-) (limited to 'src/actors') diff --git a/src/actors/scala/actors/Actor.scala b/src/actors/scala/actors/Actor.scala index a5eb0a7422..de64880847 100644 --- a/src/actors/scala/actors/Actor.scala +++ b/src/actors/scala/actors/Actor.scala @@ -362,7 +362,7 @@ trait Actor extends OutputChannel[Any] { private var waitingFor: Any => Boolean = waitingForNone private var isSuspended = false - private val mailbox = new MessageQueue + protected val mailbox = new MessageQueue private var sessions: List[OutputChannel[Any]] = Nil /** diff --git a/src/actors/scala/actors/MessageQueue.scala b/src/actors/scala/actors/MessageQueue.scala index 8f2f6c72cc..66555b3a7f 100644 --- a/src/actors/scala/actors/MessageQueue.scala +++ b/src/actors/scala/actors/MessageQueue.scala @@ -30,7 +30,7 @@ class MessageQueueElement { * library. Classes in this package are supposed to be the only * clients of this class. * - * @version 0.9.8 + * @version 0.9.9 * @author Philipp Haller */ @serializable @@ -67,6 +67,87 @@ class MessageQueue { } } + def foldLeft[B](z: B)(f: (B, Any) => B): B = { + var acc = z + var curr = first + while (curr != null) { + acc = f(acc, curr.msg) + curr = curr.next + } + acc + } + + /** Returns the n-th msg that satisfies the predicate + * without removing it. + */ + def get(n: Int)(p: Any => Boolean): Option[Any] = { + var pos = 0 + val msg = if (null eq last) None + else { + // test first element + if (n == 0 && p(first.msg)) + Some(first.msg) + else { + var curr = first + while(curr.next != null) { + curr = curr.next + if (p(curr.msg)) { + pos += 1 + if (pos == n) + return Some(curr.msg) + } + } + None + } + } + msg + } + + /** Removes the n-th msg that satisfies the predicate. + */ + def remove(n: Int)(p: Any => Boolean): Option[(Any, OutputChannel[Any])] = { + var pos = 0 + val msg = if (null eq last) None + else { + // test first element + if (n == 0 && p(first.msg)) { + val tmp = first + // remove first element + first = first.next + + // might have to update last + if (tmp eq last) { + last = null + } + + Some((tmp.msg, tmp.session)) + } else { + var curr = first + var prev = curr + while(curr.next != null) { + prev = curr + curr = curr.next + if (p(curr.msg)) { + pos += 1 + if (pos == n) { + // remove curr + prev.next = curr.next + + // might have to update last + if (curr eq last) { + last = prev + } + + return Some((curr.msg, curr.session)) + } + } + } + None + } + } + msg + } + def extractFirst(p: Any => Boolean): MessageQueueElement = { changeSize(-1) // assume size decreases by 1 -- cgit v1.2.3