注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

阿弥陀佛

街树飘影未见尘 潭月潜水了无声 般若观照心空静...

 
 
 

日志

 
 
关于我

一直从事气象预报、服务建模实践应用。 注重气象物理场、实况场、地理信息、本体知识库、分布式气象内容管理系统建立。 对Barnes客观分析, 小波,计算神经网络、信任传播、贝叶斯推理、专家系统、网络本体语言有一定体会。 一直使用Java、Delphi、Prolog、SQL编程。

网易考拉推荐

Observable from scala in depth  

2013-10-07 00:31:37|  分类: Scala |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
/** Defines a trait that marks a class as allowing external
* viewers to be notified of changes.
*/
trait Observable {
  // Defines a type returned when registering a callback.
  type Handle <: {
    def remove() : Unit
  }
  /** registered callbacks for this observable */
  protected var callbacks = Map[Handle, this.type => Unit]()

  /** Registers a new observer on this class.
* Observers are simple functions that take the class and
* return nothing. A handle is returned that allows
* the observer to deregister from this observable.
*/
  def observe(callback : this.type => Unit) : Handle = {
    val handle = createHandle(callback)
    callbacks += (handle -> callback)
    handle
  }
  /** Removes an observer from this class. */
  def unobserve(handle : Handle) : Unit = {
    callbacks -= handle
  }
  /** This method is called by subclasses upon state change to
* notify listeners of the change.
*/
  protected def notifyListeners() : Unit =
    for(callback <- callbacks.values) callback(this)

  /**
* Subclasses override this to provide their own callback disambiguation scheme.
*/
  protected def createHandle(callback : this.type => Unit) : Handle
}

/** This trait provides a default implementation
* for the handlers type. */
trait DefaultHandles extends Observable {
  /** A simple handle implementation */
  class HandleClass {
    def remove() {
      DefaultHandles.this.unobserve(this)
    }
  }
  type Handle = HandleClass
  /** Every callback is assigned a new handle. */
  protected def createHandle(callback : this.type => Unit) : Handle = new HandleClass
}


/** This defines a basic store or cache of a single value type.
* This store is observable and will notify listeners when the stored
* value is changed.
*/
class VariableStore[X](private var value : X) extends Observable with DefaultHandles {
  /** Retreive the stored value */
  def get : X = value
  /** Sets the stored value. Will notify observers */
  def set(newValue : X) : Unit = {
    value = newValue
    notifyListeners()
  }
  // Overridden for pretty REPL usage.
  override def toString : String = "VariableStore(" + value + ")"
}

/** This trait defines a mechanism for managing handles from
* observerables such that they can all be unregistered when
* the current class is 'finished'
*/
trait Dependencies {
  // This type allows us to refer to any handle from any
  // observable. Because handle is defined inside the Observable
  // we use an existential for the actual Observable.
  type Ref = x.Handle forSome { val x: Observable }
  /** The current registered observers. */
  private var handles = List[Ref]()
  /** Adds a new handle to manage */
  protected def addHandle(handle : Ref) : Unit = {
    handles :+= handle
  }
  /** Removes all observers using the registrered handles */
  protected def removeDependencies() {
    for(h <- handles) h.remove()
    handles = List()
  }
  /** This method mimics Observable.observe except that it registers
* an observer *and* adds it to the dependency list.
*/
  protected def observe[T <: Observable](obj : T)(handler : T => Unit) : Ref = {
    val ref = obj.observe(handler)
    addHandle(ref)
    ref
  }
}


/*

scala> val x = new VariableStore(12)
x: VariableStore[Int] = VariableStore(12)

scala> val d = new Dependencies {}
d: java.lang.Object with Dependencies = $anon$1@153e6f83


Note: Scala 2.8.x has a bug that causes the below to fail.

scala> d.addHandle(x.observe(println))
<console>:8: error: type mismatch;
found : x.Handle
required: d.Ref
d.addHandle(x.observe(println))
^
// The following does work.

scala> val t = x.observe(println)
t: x.Handle = DefaultHandles$HandleClass@662fe032

scala> d.addHandle(t)

scala> val t2 = x.observe(println)
t2: x.Handle = DefaultHandles$HandleClass@57530551

scala> d.addHandle(t2)

scala> x.set(1)
VariableStore(1)
VariableStore(1)

scala> d.removeDependencies()

scala> x.set(2)

*/
  评论这张
 
阅读(596)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017