Use example of Scala ObservableSet Trait
Asked Answered
S

2

4

Could anyone help me telling me how to use scala's ObservableSet trait?

Thank you very much in advance

Sky answered 31/5, 2010 at 15:53 Comment(0)
D
2

It's a bit of an eyesore with all the typing information, but this is how I was able to get it to work. I welcome suggestions on how to make the typing more concise. various edits including type aliases:

import collection.mutable._
import collection.script._

val set = new HashSet[String] with ObservableSet[String] { }

type Msg = Message[String] with Undoable
type Sub = Subscriber[Msg, ObservableSet[String]]

val sub = new Sub() {
  def notify(pub: ObservableSet[String], event: Msg): Unit = {
    println("%s sent %s".format(pub, event))
    event match {
      case r:Remove[_] => println("undo!"); event.undo()
      case _ => 
    }
  }
}

set.subscribe(sub)

set += "foo"
set += "bar"
set -= "bar"

That prints:

Set(foo) sent Include(NoLo,foo)
Set(bar, foo) sent Include(NoLo,bar)
Set(foo) sent Remove(NoLo,bar)
undo!
Set(bar, foo) sent Include(NoLo,bar)

Interestingly, undo caused another message to be published...

Dachi answered 31/5, 2010 at 21:54 Comment(0)
C
8

ObservableSet is a trait extending from the Publisher trait, giving some basic publish subscribe behaviour. A simple example of using this would be:

scala> class Counter(var count: Int) extends Publisher[String] {
          def inc(): Unit = {
              count += 1
              super.publish("updated count to: " + count)
          }
     }

scala> class S[Evt, Pub] extends Subscriber[Evt, Pub] {
         def notify(pub: Pub, event: Evt): Unit = println("got event: " + event)
      }
defined class S

scala> val s = new S[String, Counter#Pub]     
s: S[String,Counter#Pub] = S@7c27a30c

scala> val c = new Counter(1)
c: Counter = Counter@44ba70c

scala> c.subscribe(s)

scala> c.inc
got event: updated count to: 2

ObservableSet does something similar, it calls the publish method when elements are added or removed with the += or +- method, see the following example (with class S defined as above):

scala> class MySet extends HashSet[Int] with ObservableSet[Int] {       
     override def +=(elem: Int): this.type = super.+=(elem);
     override def -=(elem: Int): this.type = super.-=(elem);
     override def clear: Unit = super.clear;      
}

defined class MySet

scala> val set = new MySet
set: MySet = Set()

scala> val subS = new S[Any, Any]
subCol: S[Any,Any] = S@3e898802

scala> set.subscribe(subS)

scala> set += 1
got event: Include(NoLo,1)
res: set.type = Set(1)

I've beem lazy by defining S with types Any, but I couldn't get the typing right immediately, and haven't spend too long trying to figure it out.

Cleres answered 31/5, 2010 at 18:22 Comment(1)
Nice example. Missing 'val c = Counter(0)' in the first one though.Knothole
D
2

It's a bit of an eyesore with all the typing information, but this is how I was able to get it to work. I welcome suggestions on how to make the typing more concise. various edits including type aliases:

import collection.mutable._
import collection.script._

val set = new HashSet[String] with ObservableSet[String] { }

type Msg = Message[String] with Undoable
type Sub = Subscriber[Msg, ObservableSet[String]]

val sub = new Sub() {
  def notify(pub: ObservableSet[String], event: Msg): Unit = {
    println("%s sent %s".format(pub, event))
    event match {
      case r:Remove[_] => println("undo!"); event.undo()
      case _ => 
    }
  }
}

set.subscribe(sub)

set += "foo"
set += "bar"
set -= "bar"

That prints:

Set(foo) sent Include(NoLo,foo)
Set(bar, foo) sent Include(NoLo,bar)
Set(foo) sent Remove(NoLo,bar)
undo!
Set(bar, foo) sent Include(NoLo,bar)

Interestingly, undo caused another message to be published...

Dachi answered 31/5, 2010 at 21:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.