Why is an InputMapping required to isolate properties inside a SelectMany from subsequent inputs? #2447
-
|
I'm not sure how to phrase the question, so an example is probably the simplest. If I have a SelectMany with a sequence of inputs (here a ParameterRange of locations for some visual stimulus) like that: I want to have a grating per value of the ParameterRange. If I simply use a PropertyMapping after externalising LocationX, all gratings end up at the last value of the range. If I use a WithLatestFrom and an InputMapping, things work as expected. So on this screenshot the top version works, the bottom version doesn't. I have no clue why and I keep on having bugs in my workflows that are probably related to the fact that I don't understand this. I read the part about property and input mappings on the website but that didn't make it clear. I expected each input to the SelectMany to create one observable which will get exactly 1 notification out of the Source1 (the current value of the ParameterRange). It seems to be true, as I can publish the input in an AsyncSubject and use it, which means the observable completed after this single element (I think). Yet when the subsequent input reaches the SelectMany the new grating shows as expected in the new position but the previous grating, which had been created with this now completed AsyncSubject get its LocationX property magically updated and moves to the same place 🤯 . Is the subject (X in this case) somehow shared between all observables created by the SelectMany? And if so, why does the InputMapping avoid the issue? The full test workflow I used: property_magic.bonsai.zip |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
|
Heya
How do we get around this? We force the property to update on EVERY I should say that this behavior can be substantially different across Bonsai operators depending on the underlying implementation of the operator. For instance, in some nodes, the initial property will get used forever (e.g., DueTime in Timer) despite how many times you try to change it, and you would not observe the sort of behavior you are describing. Others, like "Multiply", will take the new property and update their internal computation. These are two extreme cases, but since properties are updated asynchronously from the Observable Anyway, hope it helps :) |
Beta Was this translation helpful? Give feedback.
Heya
DrawGratingsuses a shader to draw stuff on the screen. Even if you create N parallel observables (viaSelectMany) this shader will still be shared across all calls. The way you update a variable in the shaders (say, color) is by writing touniforms that can be changed fromUpdateUniformanywhere in your workflow (you will find some insideDrawGratings).The externalized property "bug" you are describing is expected under the default scenario where each
SelectManysets its own value in the property when they start (i.e. in the first frame), but once they are done setting, the last value of the property will be the one that "stays" in the shader for all subsequentRenderFrameevents.H…