<commit_before>package rescala.core

import rescala.operator.RExceptions

import scala.annotation.implicitNotFound
import scala.util.DynamicVariable

trait Core {
  type State[_]

  /** Source of (reactive) values, the [[Struct]] defines how the state is stored internally,
    * and how dependencies are managed.
    * State can only be accessed with a correct [[InnerTicket]].
    *
    * @tparam S [[Struct]] defining the internal state
    */
  trait ReSource {
    type Value
    protected[rescala] def state: State[Value]
    protected[rescala] def name: ReName
    protected[rescala] def commit(base: Value): Value
  }

  /** A reactive value is something that can be reevaluated */
  trait Derived extends ReSource {

    final type ReIn = ReevTicket[Value]
    final type Rout = Result[Value]

    /** called if any of the dependencies ([[ReSource]]s) changed in the current update turn,
      * after all (known) dependencies are updated
      */
    protected[rescala] def reevaluate(input: ReIn): Rout
  }

  /** Base implementation for reactives, with [[Derived]] for scheduling,
    * together with a [[ReName]] and asking for a [[Struct.State]]
    *
    * @param state the initial state passed by the scheduler
    * @param name  the name of the reactive, useful for debugging as it often contains positional information
    */
  abstract class Base[V](override protected[rescala] val state: State[V], override val name: ReName)
      extends ReSource {
    override type Value = V
    override def toString: String = s"${name.str}($state)"
  }

  /** Common macro accessors for [[rescala.operator.Signal]] and [[rescala.operator.Event]]
    *
    * @tparam A return type of the accessor
    * @groupname accessor Accessor and observers
    */
  trait Interp[+A] extends ReSource {

    /** Interprets the internal type to the external type
      *
      * @group internal
      */
    def interpret(v: Value): A
  }

  trait Initializer {

    /** Creates and correctly initializes new [[rescala.core.Derived]]s */
    final private[rescala] def create[V, T <: Derived](
        incoming: Set[ReSource],
        initv: V,
        inite: Boolean,
        creationTicket: CreationTicket
    )(instantiateReactive: State[V] => T): T = {
      val state    = makeDerivedStructState[V](initv)
      val reactive = instantiateReactive(state)
      register(reactive)
      ignite(reactive, incoming, inite)
      reactive
    }

    def accessTicket(): AccessTicket

    protected[this] def register(reactive: ReSource): Unit = ()

    /** Correctly initializes [[ReSource]]s */
    final private[rescala] def createSource[V, T <: ReSource](
        intv: V,
        creationTicket: CreationTicket
    )(instantiateReactive: State[V] => T): T = {
      val state    = makeSourceStructState[V](intv)
      val reactive = instantiateReactive(state)
      register(reactive)
      reactive
    }

    /** Creates the internal state of [[Derived]]s */
    protected[this] def makeDerivedStructState[V](valuePersistency: V): State[V]

    /** Creates the internal state of [[ReSource]]s */
    protected[this] def makeSourceStructState[V](valuePersistency: V): State[V] =
      makeDerivedStructState[V](valuePersistency)

    /** to be implemented by the propagation algorithm, called when a new reactive has been instantiated and needs to be connected to the graph and potentially reevaluated.
      *
      * @param reactive                     the newly instantiated reactive
      * @param incoming                     a set of incoming dependencies
      * @param ignitionRequiresReevaluation true if the reactive must be reevaluated at creation even if none of its dependencies change in the creating turn.
      */
    protected[this] def ignite(
        reactive: Derived,<commit_msg>add documentation<commit_after>package rescala.core

import rescala.operator.RExceptions

import scala.annotation.implicitNotFound
import scala.util.DynamicVariable

trait Core {
  type State[_]

  /** Source of (reactive) values, the [[Struct]] defines how the state is stored internally,
    * and how dependencies are managed.
    * State can only be accessed with a correct [[InnerTicket]].
    *
    * @tparam S [[Struct]] defining the internal state
    */
  trait ReSource {
    type Value
    protected[rescala] def state: State[Value]
    protected[rescala] def name: ReName
    protected[rescala] def commit(base: Value): Value
  }

  /** A reactive value is something that can be reevaluated */
  trait Derived extends ReSource {

    final type ReIn = ReevTicket[Value]
    final type Rout = Result[Value]

    /** called if any of the dependencies ([[ReSource]]s) changed in the current update turn,
      * after all (known) dependencies are updated
      */
    protected[rescala] def reevaluate(input: ReIn): Rout
  }

  /** Base implementation for reactives, with [[Derived]] for scheduling,
    * together with a [[ReName]] and asking for a [[Struct.State]]
    *
    * @param state the initial state passed by the scheduler
    * @param name  the name of the reactive, useful for debugging as it often contains positional information
    */
  abstract class Base[V](override protected[rescala] val state: State[V], override val name: ReName)
      extends ReSource {
    override type Value = V
    override def toString: String = s"${name.str}($state)"
  }

  /** Common macro accessors for [[rescala.operator.Signal]] and [[rescala.operator.Event]]
    *
    * @tparam A return type of the accessor
    * @groupname accessor Accessor and observers
    */
  trait Interp[+A] extends ReSource {

    /** Interprets the internal type to the external type
      *
      * @group internal
      */
    def interpret(v: Value): A
  }

  trait Initializer {

    /** Creates and correctly initializes new [[rescala.core.Derived]]s */
    final private[rescala] def create[V, T <: Derived](
        incoming: Set[ReSource],
        initv: V,
        inite: Boolean,
        creationTicket: CreationTicket
    )(instantiateReactive: State[V] => T): T = {
      val state    = makeDerivedStructState[V](initv)
      val reactive = instantiateReactive(state)
      register(reactive)
      ignite(reactive, incoming, inite)
      reactive
    }

    def accessTicket(): AccessTicket

    /** hook for schedulers to globally collect all created resources,
      * usually does nothing */
    protected[this] def register(reactive: ReSource): Unit = ()

    /** Correctly initializes [[ReSource]]s */
    final private[rescala] def createSource[V, T <: ReSource](
        intv: V,
        creationTicket: CreationTicket
    )(instantiateReactive: State[V] => T): T = {
      val state    = makeSourceStructState[V](intv)
      val reactive = instantiateReactive(state)
      register(reactive)
      reactive
    }

    /** Creates the internal state of [[Derived]]s */
    protected[this] def makeDerivedStructState[V](valuePersistency: V): State[V]

    /** Creates the internal state of [[ReSource]]s */
    protected[this] def makeSourceStructState[V](valuePersistency: V): State[V] =
      makeDerivedStructState[V](valuePersistency)

    /** to be implemented by the propagation algorithm, called when a new reactive has been instantiated and needs to be connected to the graph and potentially reevaluated.
      *
      * @param reactive                     the newly instantiated reactive
      * @param incoming                     a set of incoming dependencies
      * @param ignitionRequiresReevaluation true if the reactive must be reevaluated at creation even if none of its dependencies change in the creating turn.
      */
    protected[this] def ignite(
        reactive: Derived,
{'fraction_non_alphanumeric': 0.0927968851395198, 'fraction_numerical': 0.0, 'mean_word_length': 3.1142552055525896, 'pattern_counts': {'":': 0, '<': 7, '<?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': '4115764', 'n_tokens_mistral': 2198, 'n_tokens_neox': 2085, 'n_words': 748}