Bind does not work with mapNonAdaptive
hyazinthh opened this issue · comments
Currently, combining AVal.bind
and AVal.mapNonAdaptive
will lead to updates being lost, due to how the BindVal
type detects if its input changed. The following unit test demonstrates this behavior:
[<Test>]
let ``[AVal] Map non-adaptive and bind``() =
let v = AVal.init true
let a = AVal.constant 0
let b = AVal.constant 1
let output = v |> AVal.mapNonAdaptive id |> AVal.bind (fun flag -> if flag then a else b)
output |> AVal.force |> should equal 0
transact (fun () -> v.Value <- false)
output |> AVal.force |> should equal 1
I just made 3 different attempts to fix this, but it seems this sort of decorator node is not easy to integrate s.t. no-one can notice...
However I think with enough thought it will be fixable in a few lines of code...
For interested readers: it's related to the MapNonAdaptiveVal
not being part of the dependency tree and some dirty-checks failing due to this..
Hey @hyazinthh I finally found a fix for this and the change is pretty small, basically we need to smuggle a tuple of IAdaptiveObjects
around in evaluate/transact.
I did it via a custom DecoratedObject
that sadly also had to implement IAdaptiveObject
(hence the ugliness)
Nonetheless it solves the issue in such a way that InputChanged
will be called with the MapNonAdaptiveVal
instead of the actual cell causing the marking. Of course this only happens when the evaluation used the decorated thing.
@haraldsteinlechner @luithefirst @aszabo314 could someone think this through and check if i missed something?
Sorry for the force push (the latest commit is even more condensed)