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 }
Атом это контейнер, хранящий значение и оповещающий о его изменениях.
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 callback in callbacks do
callback prev_x x
MutAtom
это изменяемая версия типа Atom
. Имена MutAtom
и mut Atom
являются синонимами.
type Token =
let f : Unit -> Unit
let mut is_discarded = false
def discard =
assert not is_discarded
is_discarded = true
f ()
Метод subscribe
возвращает объект типа Token
, позволяющий отменить подписку.
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" }
Для привязок position
и origin
создаются объекты MutAtom<Vector3>
. Значение global_position
будет пересчитано при каждом их изменении.
Модификатор @atom
возвращает контейнер. Фигурные скобки определяют анонимную функцию.
let tuple_atom = (position@atom, origin@atom) |> to_atom
let sum@atom = tuple_atom.map { u, v -> u + v }
to_atom
преобразовывает кортеж атомов в атом кортежей. Из-за модификатора @atom
привязка sum
имеет тип Vector3
, а не Atom<Vector3>
.