Open SimonDanisch opened 7 years ago
Doesn't really answer your question, but I've grown to think that Reactive "wants you" to view the signal graph as static. If one buys into that viewpoint, then the answer is presumably "use filterwhen
when you create the graph." Would be interesting to hear other perspectives on this, though.
Hm, but I basically want to reset a signal... I found a work around with binding it to some other signal and then just closing that, and creating a new surrogate... But it's pretty inconvenient!
Hi,
For situations where emptying the actions in the previous design did what you want, I expect that if you remove the parent from child.parents
you should get the same effect. This won't work in the situation of say:
using Reactive, Interact
a = Signal(1)
b1 = map(identity, a)
b2 = map(x->2x, a)
c = map((x,y)->x+y, b1, b2)
c.parents = (b1,) # remove b2 from c.parents
# b2.parents = ()
display.([a, b1, b2, c]);
if you then push!(a, 2)
, b1 and b2 will update, and the map in c
will still use b2's updated value (4). If you push!(b2, 4)
though, c won't update.
I think this behaviour is the same as it would have been if you'd removed all the actions from b2 in the old design though.
(The reason that works the way it does, is that nodes will only run their actions if at least one of their parents is active in the current push - more info here: https://github.com/JuliaGizmos/Reactive.jl/blob/master/doc/Design%20Overview.md)
You could achieve what you want more reliably with a flatten (which is actually implemented using unbind!
and bind!
). E.g.
using Reactive, Interact
a = Signal(1)
b1 = map(identity, a)
b2 = map(x->2x, a)
bcurrent = Signal(b2)
c = map((x,y)->x+y, b1, flatten(bcurrent)) #flatten here
display.([a, b1, flatten(bcurrent), c]);
then when you're finished with b2, you can sub in a new Signal, b3 say:
b3 = map(x->3x, a)
push!(bcurrent, b3)
Of course, that requires you to know what signal is going to be closed in advance, so you can use the flatten.
I'm actually quite curious about your use case. Seems you get up to some pretty tricky stuff in your code @SimonDanisch - what between this, and not running the event loop, etc... 😄
the use case is to connect things to a slider, then reset the scene and connect new stuff. If I don't disconnect the signals, I will update old objects with the slider. Obviously it'd be better if gc would just do this more reliably, but it isn't. Maybe it's even my fault for holding references somewhere :( .... Anyways, I end up having a lot of old objects connected to the slider. Imagine that to be processing a volume, which makes things really slow.
Ok, so the slider stays, but the objects go. Yeah removing the slider's signal from the .parents
of the children should work. You should be able to get all the children of the slider in Reactive.nodes[Reactive.edges[signal(the_slider).id]]
Also, that reminds me, I think there might be an issue with GC and bind!
since _bindings
stores a ref to the Pair src=>dest
here, let me know if you come across it.
edited to add Reactive.nodes
Did that work for you? Are you happy about it? Sad about it?
Haven't tried it yet, but looks good! ;)
Maybe worth offering this as an API (e.g. getchildren
)
In previous Reactive versions, I could just say
empty!(signal.actions)
, to stop a parent signal from sending values to children. Now this seems reversed and parents seem to add an action to their children, so emptying actions makes a signal not receive anything from their parents anymore. What's the best way to do this now?