From c81e9aba81086ae011e47b83a70673ffeecb0201 Mon Sep 17 00:00:00 2001 From: Shashi Gowda Date: Mon, 16 Jun 2014 14:53:23 +0530 Subject: [PATCH] Raise error if push is called from inside a lifted function --- src/React.jl | 73 +++++++++++++++++++++++++------------------- tests/basics.jl | 2 +- tests/concurrency.jl | 2 +- 3 files changed, 43 insertions(+), 34 deletions(-) diff --git a/src/React.jl b/src/React.jl index 9cf0822..8df4a12 100644 --- a/src/React.jl +++ b/src/React.jl @@ -156,52 +156,61 @@ function update{T, U}(node :: SampleOn{T, U}, parent :: Signal{T}) return true end -function push!{T}(inp :: Input{T}, val :: T) - inp.value = val +begin + local isupdating = false + function push!{T}(inp :: Input{T}, val :: T) + if isupdating + error("calling push! inside a lift is prohibited.") + end + isupdating = true + inp.value = val - heap = (Signal, Signal)[] # a min-heap of (child, parent) - ord = By(a -> a[1].rank) # ordered topologically by child.rank + heap = (Signal, Signal)[] # a min-heap of (child, parent) + ord = By(a -> a[1].rank) # ordered topologically by child.rank - # first dirty parent - merge_parent = Dict{Merge, Signal}() - for c in inp.children - if isa(c, Merge) - merge_parent[c] = inp + # first dirty parent + merge_parent = Dict{Merge, Signal}() + for c in inp.children + if isa(c, Merge) + merge_parent[c] = inp + end + heappush!(heap, (c, inp), ord) end - heappush!(heap, (c, inp), ord) - end - prev = nothing - while !isempty(heap) - (n, parent) = heappop!(heap, ord) - if n == prev - continue # already processed - end + prev = nothing + while !isempty(heap) + (n, parent) = heappop!(heap, ord) + if n == prev + continue # already processed + end - # Merge is a special case! - if isa(n, Merge) && haskey(merge_parent, n) - propagate = update(n, merge_parent[n]) - else - propagate = update(n, parent) - end + # Merge is a special case! + if isa(n, Merge) && haskey(merge_parent, n) + propagate = update(n, merge_parent[n]) + else + propagate = update(n, parent) + end - if propagate - for c in n.children - if isa(c, Merge) - if haskey(merge_parent, c) - if c.ranks[n] < c.ranks[merge_parent[c]] + if propagate + for c in n.children + if isa(c, Merge) + if haskey(merge_parent, c) + if c.ranks[n] < c.ranks[merge_parent[c]] + merge_parent[c] = n + end + else merge_parent[c] = n end - else - merge_parent[c] = n end + heappush!(heap, (c, n), ord) end - heappush!(heap, (c, n), ord) end + prev = n end - prev = n + isupdating = false end end + push!{T}(inp :: Input{T}, val) = push!(inp, convert(T, val)) lift(f :: Function, output_type :: Type, inputs :: Signal...) = diff --git a/tests/basics.jl b/tests/basics.jl index 3fc4415..034153a 100644 --- a/tests/basics.jl +++ b/tests/basics.jl @@ -11,7 +11,7 @@ b = lift(x -> x*x, Int, a) # type conversion push!(a, 1.0) @test b.value == 1 -@test_throws push!(a, 1.1) # inexact error +@test_throws InexactError push!(a, 1.1) # inexact error push!(a, number()) @test b.value == a.value*a.value diff --git a/tests/concurrency.jl b/tests/concurrency.jl index 23fd798..6618921 100644 --- a/tests/concurrency.jl +++ b/tests/concurrency.jl @@ -8,4 +8,4 @@ function crash(x) end b = lift(crash, a) -@test_throws push!(a, 1) +@test_throws ErrorException push!(a, 1)