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

de.sciss.lucre.edit.EditGrapheme.scala Maven / Gradle / Ivy

/*
 *  EditGrapheme.scala
 *  (SoundProcesses)
 *
 *  Copyright (c) 2010-2024 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.lucre
package edit

import de.sciss.lucre.edit.UndoManager.{CannotRedoException, CannotUndoException}
import de.sciss.lucre.edit.impl.BasicUndoableEdit
import de.sciss.proc.Grapheme

object EditGrapheme {
  def add[T <: Txn[T]](gr: Grapheme.Modifiable[T], time: LongObj[T], elem: Obj[T])
                      (implicit tx: T): Unit =
    UndoManager.find[T].fold(
      addDo  (gr, time, elem)
    ) { implicit undo =>
      addUndo(gr, time, elem)
    }

  def addUndo[T <: Txn[T]](gr: Grapheme.Modifiable[T], time: LongObj[T], elem: Obj[T])
                          (implicit tx: T, undo: UndoManager[T]): Unit = {
    val edit = new Add(gr, time, elem, tx)
    undo.addEdit(edit)
  }

  def remove[T <: Txn[T]](gr: Grapheme.Modifiable[T], time: LongObj[T], elem: Obj[T])
                         (implicit tx: T): Unit =
    UndoManager.find[T].fold[Unit] {
      removeDo(gr, time, elem)
      ()
    } { implicit undo =>
      removeUndo(gr, time, elem)
      ()
    }

  def removeUndo[T <: Txn[T]](gr: Grapheme.Modifiable[T], time: LongObj[T], elem: Obj[T])
                             (implicit tx: T, undo: UndoManager[T]): Unit = {
    val edit = new Remove(gr, time, elem, tx)
    undo.addEdit(edit)
  }

  // ---- private: add ----

  private def addDo[T <: Txn[T]](gr: Grapheme.Modifiable[T], time: LongObj[T], elem: Obj[T])
                                (implicit tx: T): Unit = {
    gr.add(time, elem)
    ()
  }

  private final class Add[T <: Txn[T]](gr0: Grapheme.Modifiable[T], time0: LongObj[T], elem0: Obj[T], tx0: T)
    extends BasicUndoableEdit[T] {

    private[this] val grH     = tx0.newHandle(gr0)
    private[this] val timeH   = tx0.newHandle(time0)
    private[this] val elemH   = tx0.newHandle(elem0)

    addDo(gr0, time0, elem0)(tx0)

    protected def undoImpl()(implicit tx: T): Unit = {
      val gr    = grH()
      val time  = timeH()
      val elem  = elemH()
      val found = gr.remove(time, elem)
      if (!found) throw new CannotUndoException(s"$name: element was not found")
    }

    protected def redoImpl()(implicit tx: T): Unit =
      addDo(grH(), timeH(), elemH())

    def name: String = "Add to Grapheme"
  }

  // ---- private: remove ----

  private def removeDo[T <: Txn[T]](gr: Grapheme.Modifiable[T], time: LongObj[T], elem: Obj[T])
                                   (implicit tx: T): Boolean =
    gr.remove(time, elem)

  //  protected def any2stringadd: Any = ()

  private final class Remove[T <: Txn[T]](tl0: Grapheme.Modifiable[T], time0: LongObj[T], elem0: Obj[T], tx0: T)
    extends BasicUndoableEdit[T] {

    private[this] val grH     = tx0.newHandle(tl0)
    private[this] val timeH   = tx0.newHandle(time0)
    private[this] val elemH   = tx0.newHandle(elem0)
    private[this] val valid   = removeDo(tl0, time0, elem0)(tx0)

    protected def undoImpl()(implicit tx: T): Unit = {
      if (!valid) return // cannotUndo()

      val gr    = grH()
      val time  = timeH()
      val elem  = elemH()
      gr.add(time, elem)
      ()
    }

    private def invalidMessage = s"$name: element was not found"

    //    private def cannotUndo(): Nothing =
    //      throw new CannotUndoException(invalidMessage)

    private def cannotRedo(): Nothing =
      throw new CannotRedoException(invalidMessage)

    protected def redoImpl()(implicit tx: T): Unit = {
      val found = removeDo(grH(), timeH(), elemH())
      if (!found) cannotRedo()
    }

    def name: String = "Remove from Grapheme"
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy