I am trying to stop the flow of data to the rest of the definition from a C# component until a condition is satisfied. Is there a way to stop the C# component from updating downstream operations until the condition is met? I remember something about flags notifying which components need to be updated, I’d love to be able to control when they are triggered - my apologies if this has been answered, I wasn’t even sure what to search for.
Essentially I need it to act like a data dam, but instead of clicking the data dam, I need it to refresh when a separate condition is satisfied.
Currently I am able to stop the new values from being output until the condition is satisfied, however while I’m changing the inputs for the C# component, the whole definition is recalculating with values that aren’t actually changing.
this recalculates your solution only if a parameter relevant for the calculation changes, but not if the condition is true. note that it will return 0 if the condition is never false. and this makes only sence if your x+y calculations are that heavy that you need to wait several seconds to calculate them. in any other case this is more like a source of difficult to detect errors later on.
That’s basically what I have now - the problem is that if I adjust X or Y, even if the Condition remains false, grasshopper still treats the component as having changed - and though the outputs remain the same it recalculates the rest of the definition - the part I’m struggling with is how to only trigger downstream recalculation when the Condition is true, and disregard any changes that might be happening until then
Unless I’m being dense and yours is somehow doing that already?
I maybe missunderstand your description but in this case this would be the thing to go:
if(condition)
{
A=x+y;
}
this should calculate only when condition true and give out, but not recalculate when x or y are changed. if condition false, null is output.
if you want the value to stay the same without calculating unless its again true:
if(condition)
{
d=x+y;
}
A= d
<<additional code>>
public double d;
however, if you want to absolutely stop it from being calculated, i guess you need to go with something like expireSolution, but I personally would not fiddle around with that, unless you have really good reasons to do so.
C# is happy to not recalculate anything, but it still expires the component, that was the word I was looking for, ExpireSolution, hopefully the documentation won’t be too Greek.
if we put A = x+y inside the condition, it sends out loads of nulls, when you adjust the input slider, so no go.
Having a public variable outside the scope of the main program is crucial to retain the data during changes - however if I adjust the inputs then data recorder is getting flooded with the same value, triggering the rest of the script.
While I am in full agreement I’d rather not be touching stuff under the hood, sadly it’s crucial. Using the sketch the ideal scenario is to actually control the expiration of the outputs individually not even as a component. So for example if “out1” is changed, then the whole definition recalculates, but if only “out2” has changed, than I would ideally not recalculate Operation1, and only recalculate Operation2.
I mean if there is a simpler way to do this, that would be great, I might be making a mountain out of an anthill here
ah ok, I see. thanks for the drawing, I got it better like this.
in this case you can save the value and check if it has changed before calculating:
this calculates the value only if x has changed, but y can be changed and it will keep its value.
this logic should be in operation#1. then
if out1 changes, op1 and op2 recalculate.
if out2 changes, op1: value didn’t change, outputs saved data used for op2 recalculated.
That’s a great check for if a value has changed, but it still sends an output any time I change x or y, this allows us to dam the data coming into the component, but it still sends the output out every time, even it hasn’t changed, triggering the recalculation again
ExpireSolution sadly triggers a document wide recalculation - I can see that IGH_Component.Locked - could potentially stop data from being sent, but I can only lock it once with a boolean before it becomes unresponsive, though there must be a way to activate one component out of another
this data needs to be resent that grasshopper stays synchronious for operation2, that must be calculated in both your cases… op1 is not recalculated though. but resent yes. I guessed your goal would be to save time. Obviously I don’t understand what you want then. This makes exactly what you described below. that it technically resends the data, makes no difference.
if really you want to “clean” some recorded data, it’s easy to make a recorder that records only changed values in c#
if it is to save calculating time, this code will perfectly do fine.
Yes, the resending is the issue, it triggers a load of intersection components etc. and I am waiting for a calculation even when the value hasn’t changed, so the fact that it is resending is the problem I am trying to solve. If I can stop it sending values when they haven’t changed I don’t have to wait for the recalculation of intersections that have already been calculated.
The data recorder will again trigger downstream components to expire even if the value is the same - so not a solution either.
ah ok, I didn’t see any other elements in your drawing and thought this would be a good workaround. sorry if I missunderstood.
well, I think it is really hard to override the refreshing mechanics of grasshopper without breaking it. I guess you need to stick with the idea of a workaround.
I think you need define a zone to be recalculated ( between the red and black “onChange” elements) and keep the value in onChangeDataRecorder just before recalculating OP#2. sorry my horrible child style of drawing with the mouse only;) and I hope I got the idea of your real problem correctly this time.
OP#1’s filter must be inside the solveInstance, else the data will be resend and not nulls. nulls will cause zero calculaton time in the additional operations and the value will be saved on change only and given to the elements that needs the info just in time.
If I understand correctly, you can only achieve what you are looking for in a compiled component as explained here.
As a workaround, you can expire a floating parameter instead of the main component: