Created
May 6, 2018 10:21
-
-
Save adamgfraser/20d40b3dca6a122f7eca3df2fec6981a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object Reactive { | |
type Signaled[T] = implicit Signal[_] => T | |
class Signal[T](expr: Signaled[T]) { | |
private var myExpr: () => T = _ | |
private var myValue: T = _ | |
private var observers: Set[Signal[_]] = Set() | |
update(expr) | |
protected def update(expr: Signaled[T]): Unit = { | |
myExpr = () => expr(this) | |
computeValue() | |
} | |
protected def computeValue(): Unit = { | |
val newValue = myExpr() | |
if (myValue != newValue) { | |
myValue = newValue | |
val obs = observers | |
observers = Set() | |
obs.foreach(_.computeValue()) | |
} | |
} | |
def apply()(implicit caller: Signal[_] = NoSignal): T = { | |
observers += caller | |
assert(!caller.observers.contains(this), "cyclic signal definition") | |
myValue | |
} | |
} | |
object NoSignal extends Signal(???) { | |
override def computeValue() = () | |
} | |
object Signal { | |
def apply[T](expr: Signaled[T]): Signal[T] = new Signal(expr) | |
} | |
class Var[T](expr: Signaled[T]) extends Signal(expr) { | |
override def update(expr: Signaled[T]): Unit = super.update(expr) | |
} | |
object Var { | |
def apply[T](expr: Signaled[T]): Var[T] = new Var(expr) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment