Signals provides a multi-paradigm fast functional reactive programing for julia. It supports both pull and push operations and async(default) and non-async modes.
S = Signal(val;strict_push = false)
Create a source Signal
with initial value val
, setting
strict_push
to true
guarantees that every push to this Signal
will be carried out independently. otherwise if updates occur faster than what the eventloop
can process, then only the last value before the eventloop
kicks in will be used(default)
S = Signal(f,args...)
Creates a derived Signal
who's value is f(args...)
, args can be of any type,
Signal
args get replaced by their value before calling f(args...)
. reads best with
with do
notation(see example).
S[] = val
sets the value of S
to val
without propagating the change to the rest of the signal graph,
useful in pull based paradigm
S()
pull!
Signal, pulling any changes in the Signal graph that affects S
S(val)
sets the value of S
to val
and pushes the changes along the Signal graph
S[]
gets the current value stored in S
without pulling changes from the graph
julia> A = Signal(1) # source Signal
Signal
value: 1
julia> B = 2 # non-Signal input
2
julia> C = Signal(A,B) do a,b # derived Signal
a+b
end
Signal
value: 3
julia> A[] = 10 # set value without propagation
10
julia> C[] # read current value
3
julia> C() # pull latest changes from the Signal graph
12
julia> A(100) # set value to a signal and propagate this change
100
julia> C[]
102
Signals supports several reactive operators
droprepeats
when
filter
sampleon
foldp
count
previous
merge
async_signal
remote_signal
bind!
unbind!
individual documentation files are available from within julia
Signals supports several operators that takes time into consideration, for example debounce
which executes only after a set amount of time has passed since the inputs were updated or throttle
which creates a Signal
that is guaranteed not to
be executed more than set amount of times per second.
debounce
throttle
for_signal
fps
every
buffer
By default Signals run asynchronically in a dedicated eventloop
, this behavior can be changed using
Signals.async_mode(false)
or by individual non-async pushes to the signal graph using:
push!(s,val,false)
Signals is dynamic , one can push values of any type to a source signal
julia> using Signals
julia> A = Signal(1)
Signal
value: 1
julia> B = Signal(A,A) do a,b
a*b
end
Signal
value: 1
julia> A(rand(3,3));
julia> B()
3×3 Array{Float64,2}:
0.753217 0.796031 0.265298
0.28489 0.209641 0.249161
0.980177 0.810512 0.571937
Signals package was rigorously optimized for speed of execution and minimal recalculation of signal graph updates.