Skip to content

Instantly share code, notes, and snippets.

@mschauer
Last active September 9, 2021 19:18
Show Gist options
  • Select an option

  • Save mschauer/28648114f95b3378bc9d822855ab09b3 to your computer and use it in GitHub Desktop.

Select an option

Save mschauer/28648114f95b3378bc9d822855ab09b3 to your computer and use it in GitHub Desktop.
Static observables
using Observables, BenchmarkTools, Test
struct StaticObservable{T, Listeners} <: Observables.AbstractObservable{T}
listeners::Listeners
val::Base.RefValue{T}
end
StaticObservable(obs::Observable) = StaticObservable(tuple(obs.listeners...), Ref(obs[]))
function StaticObservable(val::Ref, listeners...)
_notify(val, listeners)
StaticObservable(listeners, val)
end
function StaticObservable(val, listeners...)
_notify(val, listeners)
StaticObservable(listeners, Ref(val))
end
Base.getindex(obs::StaticObservable) = obs.val[]
Observables.listeners(obs::StaticObservable) = obs.listeners
_notify(val, funcs::Tuple{}) = nothing
function _notify(val, funcs::Tuple)
f = first(funcs)
f(val)
_notify(val, Base.tail(funcs))
end
function Base.notify(obs::StaticObservable)
val = obs[]
_notify(val, obs.listeners)
return
end
function Base.setindex!(observable::StaticObservable, val)
observable.val[] = val
notify(observable)
return val
end
struct ShallowStaticObservable{T, Listeners} <: Observables.AbstractObservable{T}
listeners::Listeners
ShallowStaticObservable{T}(listeners::F) where {T,F} = new{T,F}(listeners)
end
function ShallowStaticObservable(val::T, listeners...) where {T}
_notify(val, listeners)
ShallowStaticObservable{T}(listeners)
end
Observables.listeners(obs::ShallowStaticObservable) = obs.listeners
function Base.setindex!(observable::ShallowStaticObservable, val)
_notify(val, observable.listeners)
return val
end
function evolve(d = 100)
t = 0.0
x = rand(d)
renew(i) = (_) -> x[i] = rand()
ii = rand(1:d, d)
S = [ShallowStaticObservable(x[i], renew(ii[i]) ) for i in 1:d]
while t < 10000.0
Δ, i = findmin(x)
t += Δ
@. x -= Δ
S[i][] = x[i] # equivalent to x[ii[i]] = rand()
x[i] = rand()
end
S,t
end
S, t = @time evolve();
#using Pkg
using Observables
struct StaticObservable{T, Listeners} <: Observables.AbstractObservable{T}
listeners::Listeners
val::Base.RefValue{T}
end
StaticObservable(obs::Observable) = StaticObservable(tuple(obs.listeners...), Ref(obs[]))
Base.getindex(obs::StaticObservable) = obs.val[]
Observables.listeners(obs::StaticObservable) = obs.listeners
_notify(val, funcs::Tuple{}) = nothing
function _notify(val, funcs::Tuple)
f = first(funcs)
f(val)
@show f, val
_notify(val, Base.tail(funcs))
end
function Base.notify(obs::StaticObservable)
val = obs[]
_notify(val, obs.listeners)
return
end
function Base.setindex!(observable::StaticObservable, val)
observable.val[] = val
notify(observable)
return val
end
A = Observable('A')
B = map(lowercase, A)
on(x->print("\nGot $x\n"), B)
A[] = 'B';
Astatic = StaticObservable(A)
println("Should now get c:")
Astatic[] = 'C'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment