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

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

/*
 *  InputAttrFolder.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.lucre.{Disposable, Folder, IdentMap, Obj}
import de.sciss.lucre.synth.Txn
import de.sciss.mellite.impl.proc.ProcObjView.LinkTarget
import de.sciss.span.Span

final class InputAttrFolder[T <: Txn[T]](val parent: ProcObjView.Timeline[T], val key: String,
                                         f: Folder[T], tx0: T)
  extends InputAttrImpl[T] {

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

  type Entry = Obj[T]

  protected def mkTarget(entry: Obj[T])(implicit tx: T): LinkTarget[T] =
    new LinkTargetFolder[T](this, tx.newHandle(entry))

  private[this] val fH = tx0.newHandle(f)

  def folder(implicit tx: T): Folder[T] = fH()

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

  // EDT
  private[this] var edtSet = Set.empty[Elem]  // XXX TODO --- do we need a multi-set in theory?

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

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

  private[this] val observer: Disposable[T] =
    f.changed.react { implicit tx => upd => upd.changes.foreach {
      case Folder.Added  (_ /* index */, child) =>
        addAttrIn(Span.From(0L), entry = child, value = child, fire = true)
      case Folder.Removed(_ /* index */, child) => removeAttrIn(entryId = child.id)
    }} (tx0)

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

  // ---- init ----
  f.iterator(tx0).foreach { child =>
    addAttrIn(Span.From(0L), entry = child, value = child, fire = false)(tx0)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy