Permalink
Browse files

Added Actor-based chatserver with some decent poking code to figure o…

…ut how messages are put in the mailbox and how they're fetched out, along with a dynamic creation of the partial function that does the dispatching
  • Loading branch information...
1 parent 968e3d7 commit e5c0f5c458af1c52e1f8717d6bf3d92321df5a2c @derekwyatt committed Oct 27, 2010
Showing with 105 additions and 7 deletions.
  1. +80 −0 beginning-scala/ChatServer3.scala
  2. +14 −7 beginning-scala/MList.scala
  3. +10 −0 beginning-scala/Patterns.scala
  4. +1 −0 beginning-scala/build.sh
@@ -0,0 +1,80 @@
+
+import scala.actors.Actor
+import Actor._
+
+case object GetMessages
+case object Stop
+case object UnknownThing
+case class Messages(msg: List[String])
+case class Remove(who: Listener)
+case class Add(who: Listener)
+
+object ChatServer3 extends Actor {
+ private var chats: List[String] = Nil
+ private var listeners: List[Listener] = Nil
+
+ def act = loop {
+ react(calcReact)
+ }
+
+ private def calcReact = {
+ val handle: PartialFunction[Any, Unit] = {
+ case s: String => {
+ chats = chats ::: List(s)
+ notifyListeners()
+ }
+ case GetMessages => reply(Messages(chats))
+ case Stop => reply(None); exit()
+ }
+ val mgt: PartialFunction[Any, Unit] = {
+ if (chats.length < 3) {
+ Map.empty
+ } else {
+ case Add(who) => {
+ listeners = who :: listeners
+ who ! Messages(chats)
+ }
+ case Remove(who) => listeners.filterNot(_ == who)
+ case s => println("ChatServer3 received unknown message: [" + s + "]")
+ }
+ }
+ handle orElse mgt
+ }
+
+ private def notifyListeners() {
+ listeners.foreach(a => a ! Messages(chats))
+ }
+
+ this.start()
+}
+
+class Listener(val me: String) extends Actor {
+ def act {
+ loop {
+ react {
+ case Messages(chats) => chats.indices.foreach(n => println(me + "[" + n + "]: " + chats(n)))
+ case Stop => reply(None); exit()
+ }
+ }
+ }
+}
+
+object Main {
+ def main(args: Array[String]) {
+ val one = new Listener("one"); one.start(); ChatServer3 ! Add(one)
+ val two = new Listener("two"); two.start(); ChatServer3 ! Add(two)
+ val three = new Listener("three"); three.start(); ChatServer3 ! Add(three)
+ ChatServer3 ! "Hi!"
+ ChatServer3 ! "Hey!"
+ ChatServer3 ! "What's up dood?"
+ ChatServer3 ! "Not much... just feeling a bit drunk"
+ ChatServer3 ! "Cool. I'm high."
+ ChatServer3 ! UnknownThing
+ ChatServer3 ! 12345
+
+ ChatServer3 !? Stop
+ one !? Stop
+ two !? Stop
+ three !? Stop
+ }
+}
@@ -5,14 +5,21 @@ class MList[+T] {
def ?:[B >: T](x: B): MList[B] = new ?:(x, this)
}
-case object MNil extends MList[Nothing]
+case object MNil extends MList[Nothing]
case class ?:[T](hd: T, tail: MList[T]) extends MList[T]
-def tryMList(in: MList[Any]) = in match {
- case 1 ?: MNil => "foo"
- case 1 ?: _ => "bar"
- case _ => "baz"
-}
+object Main {
+
+ def tryMList(in: MList[Any]) = in match {
+ case 1 ?: MNil => "foo"
+ case 1 ?: _ => "bar"
+ case _ => "baz"
+ }
-println(tryMList(1 ?: 2 ?: MNil))
+ def main(args: Array[String]) {
+ println(tryMList(1 ?: "Two" ?: MNil))
+ println(tryMList(1 ?: MNil))
+ println(tryMList(MNil))
+ }
+}
@@ -17,3 +17,13 @@ def noPairs[T](in: List[T]): List[T] = in match {
val m = ((1 to 10).toList ::: (1 to 10).toList).sorted
println(m)
println(noPairs(m))
+
+def ignore(in: List[String]): List[String] = in match {
+ case Nil => Nil
+ case _ :: "ignore" :: rest => ignore(rest)
+ case x :: rest => x :: ignore(rest)
+}
+
+val n = List("a", "b", "ignore", "c", "d", "e", "ignore", "f", "g")
+println(n)
+println(ignore(n))
View
@@ -1,3 +1,4 @@
#!/bin/sh
+mkdir -p out
scalac -d out -deprecation $*

0 comments on commit e5c0f5c

Please sign in to comment.