<commit_before>package rescala.core

import scala.language.existentials // stupid Disconnectable implementation requires stupid self-type stupid!

/**
  * Indicator for the result of a re-evaluation of a reactive value.
  */
sealed trait ReevaluationResult[S <: Struct]{
  val node: Reactive[S]
  val valueChanged: Boolean
  val indepsChanged: Boolean
  val indepsAfter: Set[Reactive[S]]

  def commitDependencyDiff(): Unit

  // superior design option, but sadly incompatible with fullMV, need to figure out a solution still..
//  def commitValueChange(): Set[Reactive[S]]
  def commitTuple: (WriteableReactive[Pulse.Change[P], S], Pulse.Change[P]) forSome { type P }
}

final case class ReevaluationResultImpl[P, S <: Struct](turn: ReevaluationStateAccess[S], node: WriteableReactive[Pulse.Change[P], S] with Reactive[S], value: Pulse[P], indepsChanged: Boolean, indepsAfter: Set[Reactive[S]], indepsAdded: Set[Reactive[S]], indepsRemoved: Set[Reactive[S]]) extends ReevaluationResult[S] {
  override val valueChanged: Boolean = value.isChange
  override def commitDependencyDiff(): Unit = {
    if(indepsChanged) {
      indepsRemoved.foreach(turn.drop(_, node))
      indepsAdded.foreach(turn.discover(_, node))
      turn.writeIndeps(node, indepsAfter)
    }
  }

  // yes there's an instanceOf, but that is no different than Option.get because it is/should be called only if valueChanged.
  // But, as no equivalent method exists here and I'd get shouted at if I added it, it's an instanceOf :P
//  override def commitValueChange(): Set[Reactive[S]] = {
//    if(valueChanged) {
//      turn.reevOutChanged(node, value.asInstanceOf[Pulse.Change[P]])
//    } else {
//      turn.reevOutUnchanged(node)
//    }
//  }
  override def commitTuple: (WriteableReactive[Pulse.Change[P], S], Pulse.Change[P]) = (node, value.asInstanceOf[Pulse.Change[P]])
}

object ReevaluationResult {

  /**
    * Result of the static re-evaluation of a reactive value.
    */
  def Static[P, S <: Struct](turn: ReevaluationStateAccess[S], node: WriteableReactive[Pulse[P], S] with Reactive[S], value: Pulse[P], unchangedIndeps: Set[Reactive[S]]): ReevaluationResultImpl[P, S] =  ReevaluationResultImpl(turn, node, value, indepsChanged = false, unchangedIndeps, Set.empty, Set.empty)

  /**
    * Result of the dynamic re-evaluation of a reactive value.
    * When using a dynamic dependency model, the dependencies of a value may change at runtime if it is re-evaluated
    */
  def Dynamic[P, S <: Struct](turn: ReevaluationStateAccess[S], node: WriteableReactive[Pulse[P], S] with Reactive[S], value: Pulse[P], indepsAfter: Set[Reactive[S]], indepsAdded: Set[Reactive[S]], indepsRemoved: Set[Reactive[S]]): ReevaluationResultImpl[P, S] = ReevaluationResultImpl(turn, node, value, indepsAdded.nonEmpty || indepsRemoved.nonEmpty, indepsAfter, indepsAdded, indepsRemoved)
}


trait Disconnectable[S <: Struct] extends Reactive[S] {
  self: RENamed with WriteableReactive[Pulse[Nothing], S] =>
  @volatile private var disconnected = false

  final def disconnect()(implicit engine: Engine[S]): Unit = {
    engine.transaction(this) { turn =>
      disconnected = true
    }
  }


  abstract final override protected[rescala] def reevaluate(turn: Turn[S], before: Value, indeps: Set[Reactive[S]]): ReevaluationResult[S] = {
    if (disconnected) {
      ReevaluationResult.Dynamic[Nothing, S](turn, this, Pulse.NoChange, Set.empty, Set.empty, indeps)
    }
    else {
      super.reevaluate(turn, before, indeps)
    }
  }

}<commit_msg>remove one more RENamed<commit_after>package rescala.core

import scala.language.existentials // stupid Disconnectable implementation requires stupid self-type stupid!

/**
  * Indicator for the result of a re-evaluation of a reactive value.
  */
sealed trait ReevaluationResult[S <: Struct]{
  val node: Reactive[S]
  val valueChanged: Boolean
  val indepsChanged: Boolean
  val indepsAfter: Set[Reactive[S]]

  def commitDependencyDiff(): Unit

  // superior design option, but sadly incompatible with fullMV, need to figure out a solution still..
//  def commitValueChange(): Set[Reactive[S]]
  def commitTuple: (WriteableReactive[Pulse.Change[P], S], Pulse.Change[P]) forSome { type P }
}

final case class ReevaluationResultImpl[P, S <: Struct](turn: ReevaluationStateAccess[S], node: WriteableReactive[Pulse.Change[P], S] with Reactive[S], value: Pulse[P], indepsChanged: Boolean, indepsAfter: Set[Reactive[S]], indepsAdded: Set[Reactive[S]], indepsRemoved: Set[Reactive[S]]) extends ReevaluationResult[S] {
  override val valueChanged: Boolean = value.isChange
  override def commitDependencyDiff(): Unit = {
    if(indepsChanged) {
      indepsRemoved.foreach(turn.drop(_, node))
      indepsAdded.foreach(turn.discover(_, node))
      turn.writeIndeps(node, indepsAfter)
    }
  }

  // yes there's an instanceOf, but that is no different than Option.get because it is/should be called only if valueChanged.
  // But, as no equivalent method exists here and I'd get shouted at if I added it, it's an instanceOf :P
//  override def commitValueChange(): Set[Reactive[S]] = {
//    if(valueChanged) {
//      turn.reevOutChanged(node, value.asInstanceOf[Pulse.Change[P]])
//    } else {
//      turn.reevOutUnchanged(node)
//    }
//  }
  override def commitTuple: (WriteableReactive[Pulse.Change[P], S], Pulse.Change[P]) = (node, value.asInstanceOf[Pulse.Change[P]])
}

object ReevaluationResult {

  /**
    * Result of the static re-evaluation of a reactive value.
    */
  def Static[P, S <: Struct](turn: ReevaluationStateAccess[S], node: WriteableReactive[Pulse[P], S] with Reactive[S], value: Pulse[P], unchangedIndeps: Set[Reactive[S]]): ReevaluationResultImpl[P, S] =  ReevaluationResultImpl(turn, node, value, indepsChanged = false, unchangedIndeps, Set.empty, Set.empty)

  /**
    * Result of the dynamic re-evaluation of a reactive value.
    * When using a dynamic dependency model, the dependencies of a value may change at runtime if it is re-evaluated
    */
  def Dynamic[P, S <: Struct](turn: ReevaluationStateAccess[S], node: WriteableReactive[Pulse[P], S] with Reactive[S], value: Pulse[P], indepsAfter: Set[Reactive[S]], indepsAdded: Set[Reactive[S]], indepsRemoved: Set[Reactive[S]]): ReevaluationResultImpl[P, S] = ReevaluationResultImpl(turn, node, value, indepsAdded.nonEmpty || indepsRemoved.nonEmpty, indepsAfter, indepsAdded, indepsRemoved)
}


trait Disconnectable[S <: Struct] extends Reactive[S] {
  self: WriteableReactive[Pulse[Nothing], S] =>
  @volatile private var disconnected = false
  final def disconnect()(implicit engine: Engine[S]): Unit = {
    engine.transaction(this) { turn =>
      disconnected = true
    }
  }


  abstract final override protected[rescala] def reevaluate(turn: Turn[S], before: Value, indeps: Set[Reactive[S]]): ReevaluationResult[S] = {
    if (disconnected) {
      ReevaluationResult.Dynamic[Nothing, S](turn, this, Pulse.NoChange, Set.empty, Set.empty, indeps)
    }
    else {
      super.reevaluate(turn, before, indeps)
    }
  }

}
{'fraction_non_alphanumeric': 0.12318634423897581, 'fraction_numerical': 0.0, 'mean_word_length': 4.647389558232931, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '675028', 'n_tokens_mistral': 2253, 'n_tokens_neox': 2206, 'n_words': 609}