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>.