Atom
type Atom<T> @abstract =
var value : T
let callbacks = StdList.new
def subscribe (f : T * T -> Unit) =
callbacks.add f
Token { callbacks.remove f }
Atom is a container that stores a value and notifies about its changes.
type MutAtom<T> @[mut_of Atom] =
inherit Atom<T>
def set (x : T) =
if x == value then return
let prev_x = value
value = x
for f in callbacks do
f prev_x x
MutAtom
is a mutable version of Atom
. MutAtom
and mut Atom
are synonyms.
type Token =
let f : Unit -> Unit
let mut is_discarded = false
def discard =
assert not is_discarded
is_discarded = true
f ()
The subscribe
method returns Token
that allows to cancel a subscription.
var obs position = Vector3@zero
var obs origin = Vector3@zero
val global_position@obs = origin@obs + position@obs
let token = position@atom
|> subscribe { prev_v v -> println "position changed from $prev_v to $v" }
The position
and origin
bindings are represented by MutAtom<Vector3>
objects. Every change causes recalculation of global_position
.
The @atom
modifier returns a container. Braces define a closure.
let tuple_atom = (position@atom, origin@atom) |> to_atom
let sum@atom = tuple_atom.map { u, v -> u + v }
to_atom
transforms a tuple of atoms into an atom of tuples. The @atom
modifier makes sum
binding have type Vector3
and not Atom<Vector3>
.