I wrote some grasshopper components in Visual Studio and the order of them are S->A->B->C. When the gh file is loaded for the first time, this pipeline works correctly. However, if I recompute B (through a boolean switch) and lead the recomputation of C, The final result changes. I debugged the code and find the output value from A changes. I am a bit confused as A did not recompute (with breakpoint inserted but not triggered). Any idea where I could be wrong? Many thanks.
It sounds like there might be some global variables or mutable states being “shared” between the components - Grasshopper’s left-to-right dataflow model is really a sort of illusion which breaks down when you start doing scripted components. There’s nothing at a lower level that which enforces that upstream components cannot be affected by downstream ones, you have to ensure that is the case ( e.g. by not reusing variables between components)
Yes an class instance is shared between components. As a matter of fact, this class instance is modified with each component in the lower stream and eventually the final result is calculated. You stated that “by not reusing variables between componets”, I am afraid this is quite hard to modify on the scripts. Is there anyway to kind of “secure” this dataflow model so the left component will not be affected? Many thanks!
Don’t think there is a “quick fix” for these sort of problems, apart from simply doing a deep copy of your entire class instance (and all its dependencies) in BeforeSolveInstance() of each of your components. (I believe this is how most native GH components treat their input data)
But this is quite a common problem in OOP, you can read up about referential transparency and ways to refactor your code to reduce side effects. If you want each component to be “pure” and fit into GH dataflow model (same inputs always result in same outputs), all their shared values must be immutable.
Will try your suggestion mate.
At the same time, I found another solution just now, which involves a click from user, that the user clicks the menu item linked with this.ExpireSolution(true). Then all the downstream calculation is correct.
In a nutshell, whenever there is a change in the pipeline, refresh the component I was referring to, then do the calculation.
Its not perfect in terms of fully automatic update though.