All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scala.reactive.container.AbelianCatamorph.scala Maven / Gradle / Ivy

The newest version!
package scala.reactive
package container



import scala.collection._



class AbelianCatamorph[@spec(Int, Long, Double) T, @spec(Int, Long, Double) S]
  (val get: S => T, val zero: T, val op: (T, T) => T, val inv: (T, T) => T)
  (implicit val canT: Arrayable[T], val canS: Arrayable[S])
extends ReactCatamorph[T, S] with ReactBuilder[S, AbelianCatamorph[T, S]] {
  import AbelianCatamorph._

  private[reactive] var elements: ReactHashValMap[S, T] = null
  private var insertsEmitter: Reactive.Emitter[S] = null
  private var removesEmitter: Reactive.Emitter[S] = null
  private var value: ReactCell[T] = null

  def inserts: Reactive[S] = insertsEmitter

  def removes: Reactive[S] = removesEmitter

  def init(z: T) {
    elements = ReactHashValMap[S, T]
    insertsEmitter = new Reactive.Emitter[S]
    removesEmitter = new Reactive.Emitter[S]
    value = ReactCell[T](zero)
  }

  init(zero)

  def signal = value

  def +=(v: S): Boolean = {
    if (!elements.contains(v)) {
      val x = get(v)
      elements(v) = x
      value := op(value(), x)
      insertsEmitter += v
      true
    } else false
  }

  def -=(v: S): Boolean = {
    if (elements.contains(v)) {
      val y = elements(v)
      elements.remove(v)
      value := inv(value(), y)
      removesEmitter += v
      true
    } else false
  }

  def container = this

  def push(v: S): Boolean = {
    if (elements.contains(v)) {
      val y = elements(v)
      val x = get(v)
      elements(v) = x
      value := op(inv(value(), y), x)
      true
    } else false
  }

  def size = elements.size

  def foreach(f: S => Unit) = elements.foreachPair((k, v) => f(k))
}


object AbelianCatamorph {

  def apply[@spec(Int, Long, Double) T](implicit g: Abelian[T], can: Arrayable[T]) = {
    new AbelianCatamorph[T, T](v => v, g.zero, g.operator, g.inverse)
  }

  implicit def factory[@spec(Int, Long, Double) T: Abelian: Arrayable] =
    new ReactBuilder.Factory[T, AbelianCatamorph[T, T]] {
      def apply() = AbelianCatamorph[T]
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy