Component send data multiple times, how to avoid it?

Hello

I am trying to create a simple component that allows me to go step-by-step through a process of 3D model generation, database confirmation and value reset. The idea is simple. Write down a number representing order ID, click “Generate” button to get the model, when satisfied with the result, click “Export” button to upload to the folder, “Confirm” the export to the database and “Reset” to clear memory and start over.

My code partially works, but I have noticed that it sends these values each time when component is updated. This causes to run the whole script on each button click, not just the part that I want (e.g. my model has been already generated and I wanna export it, but that click causes re-generation of the entire model once again). The reason is visible when I record outputs from the C# component.

Could someone help me, please? I tried also Python sc.sticky, but with no success… There probably could a solution using Metahopper (Using boolean toggles for each task instead of button and set them “false” using reset button)

if (G & !var_G) {
      var_G = true;
      var_ID = ID;
      message.Add("Created 3D model and PDF of ID# " + ID + ".");
    }

    if (E & var_G & !var_E) {
      var_E = true;
      message.Add("Exporting STL and PDF to given destination.");
    }

    if (C & var_G & var_E & !var_C) {
      var_C = true;
      message.Add("Sending exports confirmation to the database.");
    }

    if (R) {
      var_ID = string.Empty;
      var_G = false;
      var_E = false;
      var_C = false;
      message.Clear();
    }

    generate_ID = var_ID;
    toggle_E = var_E;
    toggle_C = var_C;
    info = message;

Custom additiona code:

List<string> message = new List<string>();
  bool var_G = false;
  bool var_E = false;
  bool var_C = false;
  string var_ID = string.Empty;

GH_DataGenerationOneTime.gh (28.8 KB)

Normal button returns a bool, false/true, no other state are possible.
Using normal buttons will always result in your c# script (or anything else) and its recipients to update twice:

  • when you press the button
  • when you release the button

There are other thread talking about this.


You can make the code in your script to execute actions only at release of the button, like this:

private void RunScript(double num, bool A, bool B, ref object result)
  {
    if(A)oldA = A;
    else if(oldA & !A){
      UpdateValue(num);
      oldA = A;
    }
    if(B)oldB = B;
    else if(oldB & !B){
      Compute();
      oldB = B;
    }
    result = val;
  }

  // <Custom additional code> 
  bool oldA;
  bool oldB;
  double val;

  void UpdateValue(double x){
    val = x;
  }

  void Compute(){
    val = val + 1;
  }

GH_DataGenerationOneTime_re.gh (13.1 KB)

“Compute()” will happen only at release of button B;

Note that “result=val;” code will still execute at button press, triggering the c# recipients twice (press and release).
If you replace that with “if(!(A||B))result = val;” it will output a null when a button is pressed, hopefully preventing recipients to execute heavy code.

1 Like

Thanks for your advice. It sounds promising, but the component still sends all data from all outputs. Maybe the best way to prevent this would be a component that sends data once only if input changes. I tried many ways but most of them still send “True” or “False” two times. Is there a way to prevent a component to recompute / update if incoming input is the same as previous value (stored within the component)? I could try to write something in Visual Studio but am not sure what to look for to prevent recomputing. Could @DavidRutten give me a hint, please?

Relevant:

That “smartlazy.gh” update a panel only when the value is really changed…


A method could be to send volatile data to a lone parameter only when you want to. Easy from c#.


I just thought about this:
button


Are you searching for an elegant and clean solution? :sweat_smile: :rofl:
button2
GH_DataGenerationOneTime_re2.gh (8.5 KB)

 private void RunScript(bool A, bool B, ref object result)
  {
    if(A) result = "A";
    if(B) result = "B";
  }
2 Likes

Very interesting! Thanks for sharing. I actually found a component that does what I needed - Heteroptera’s Evant Gate. But I am still curious how that works, because it could be very useful when building large heavy scripts…

2 Likes

You may use True-only Button from Pancake. It only triggers once.

Hi @PetrVacek, and yes Heteroptera’s Event Gate and Event Switch works pretty fine for this kind of work, I would like to see your code in action.

I also have that curiosity. :grin:

I am afraid that I can’t share more than joyseat.com … Check it out :rofl:
The script is actually not that heavy but rather complex: accessing online database, geometry generation, pdf generation, confirmation to the database, data upload…

2 Likes