ListSeq - laforge49/Asynchronous-Functional-Programming GitHub Wiki
The implementation of a sequence actor over a list is pretty straight forward.
class ListSeq[V](list: java.util.List[V])
extends Sequence(mailbox, factory) {
var outdated = false
override def first(msg: AnyRef, rf: Any => Unit) {
if (list.isEmpty) rf(null)
else rf(KVPair(0, list.get(0)))
}
override def current(msg: AnyRef, rf: Any => Unit) {
if (outdated) throw new IllegalStateException("underlying list has been updated")
var key = msg.asInstanceOf[Current[Int]].key
if (key < 0) key = 0
if (key >= list.size) rf(null)
else rf(KVPair(key, list.get(key)))
}
override def next(msg: AnyRef, rf: Any => Unit) {
if (outdated) throw new IllegalStateException("underlying list has been updated")
var key = msg.asInstanceOf[Next[Int]].key
if (key < 0) key = 0
else key = key + 1
if (key >= list.size) rf(null)
else rf(KVPair(key, list.get(key)))
}
}
The keys of the sequence range from 0 through list.size - 1.
Here's the test code for synchronous operation.
val fact = new java.util.ArrayList[Int]
fact.add(0)
fact.add(1)
fact.add(2)
fact.add(6)
fact.add(24)
val factSeq = new ListSeq(fact)
println(Future(factSeq, First()))
println(Future(factSeq, Current(3)))
println(Future(factSeq, Next(3)))
println(Future(factSeq, Next(4)))
And the output.
KVPair(0,0)
KVPair(3,6)
KVPair(4,24)
null
Here's the test code for asynchronous operation.
val fact = new java.util.ArrayList[Int]
fact.add(0)
fact.add(1)
fact.add(2)
fact.add(6)
fact.add(24)
val factSeq = new ListSeq(fact)
factSeq.setMailbox(new ReactorMailbox)
println(Future(factSeq, Next(4)))
fact.add(120)
println(Future(factSeq, Next(4)))
And here's the output for the second test.
null
KVPair(5,120)