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

de.sciss.mellite.impl.proc.InputAttrTimeline.scala Maven / Gradle / Ivy

/*
 *  InputAttrTimeline.scala
 *  (Mellite)
 *
 *  Copyright (c) 2012-2023 Hanns Holger Rutz. All rights reserved.
 *
 *  This software is published under the GNU Affero General Public License v3+
 *
 *
 *  For further information, please contact Hanns Holger Rutz at
 *  [email protected]
 */

package de.sciss.mellite.impl.proc

import de.sciss.fingertree.RangedSeq
import de.sciss.lucre.{Disposable, IdentMap}
import de.sciss.lucre.synth.Txn
import de.sciss.mellite.impl.proc.ProcObjView.LinkTarget
import de.sciss.proc

final class InputAttrTimeline[T <: Txn[T]](val parent: ProcObjView.Timeline[T], val key: String,
                                           tl: proc.Timeline[T], tx0: T)
  extends InputAttrImpl[T] {

  override def toString: String = s"InputAttrTimeline(parent = $parent, key = $key)"

  type Entry = proc.Timeline.Timed[T]

  protected def mkTarget(entry: Entry)(implicit tx: T): LinkTarget[T] =
    new LinkTargetTimeline[T](this, tx.newHandle(entry.span), tx.newHandle(entry.value))

  private[this] val tlH = tx0.newHandle(tl)

  def timeline(implicit tx: T): proc.Timeline[T] = tlH()

  protected val viewMap: IdentMap[T, Elem] = tx0.newIdentMap

  // EDT
  private[this] var edtRange = RangedSeq.empty[Elem, Long](_.point, Ordering.Long)

  protected def elemOverlappingEDT(start: Long, stop: Long): Iterator[Elem] =
    edtRange.filterOverlaps((start, stop))

  protected def elemAddedEDT  (elem: Elem): Unit = edtRange += elem
  protected def elemRemovedEDT(elem: Elem): Unit = edtRange -= elem

  private[this] val observer: Disposable[T] =
    tl.changed.react { implicit tx => upd => upd.changes.foreach {
      case proc.Timeline.Added  (span  , entry) =>
        addAttrIn(span, entry = entry, value = entry.value, fire = true)
      case proc.Timeline.Removed(_ /* span */, entry) => removeAttrIn(/* span, */ entryId = entry.id)
      case proc.Timeline.Moved  (spanCh, entry) =>
        removeAttrIn(/* spanCh.before, */ entryId = entry.id)
        addAttrIn   (spanCh.now, entry = entry, value = entry.value, fire = true)
    }} (tx0)

  override def dispose()(implicit tx: T): Unit = {
    super.dispose()
    observer.dispose()
  }

  // ---- init ----
  tl.iterator(tx0).foreach { case (span, xs) =>
    xs.foreach(entry => addAttrIn(span, entry = entry, value = entry.value, fire = false)(tx0))
  }
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy