The problem is I want to create a random number on every update and if that number is smaller or greater than a certain value I want to change the domain of the randomizer. In a way mimic Galapagos functionality.
Since this updates the whole script I always get the same values for min and max of the domain (the initial values) because the script is always run from the beginning from the Timer.
I tried to use two components one generating random values, and other one defining the min and max values, but that leads to a cycle error.
Edit: @piac, @DavidRutten is this even possible without compiling or maybe using Timer is the wrong way in this case?
but that one relies on the Garbage Collector, and may happen in a very remote time from apparent deletion of the component (use with extreme caution: throwing exceptions in a Garbage Collector call will immediately close the program, and bugs are hard to debug).
Do not rely on what happens in the external scope when using the SKD-mode (object-oriented mode). It’s an implementation detail.
That’ll simply pause the Python interpreter, you probably want to set a higher interval on the ghDoc.ScheduleSolution() call instead. Also, I find that recording (using the standard GH recorder) the GHPython output parameter is a good way of debugging dynamic/iterative/time-dependent components.
Btw I found out that using time.sleep in fact makes grasshopper to stutter.
If my definition is running and self-updating and has time.sleep in the update when zooming in grasshopper it does so every second at a time.
Another strange thing is, if Timer component is apparent and active on the canvas, the interval of ghDoc.ScheduleSolution() is ignored.
The scheduling works as designed. Everyone is allowed to schedule a solution, but only the earliest schedule is remembered. So if you tell GH you want a solution one second from now, and then some other component requests a solution 10 milliseconds from now, there will be another solution 10ms from now and that’s it. You either have to do the work you were planning to do right there and then (earlier than expected, but maybe that doesn’t matter?), or you must schedule another solution 990ms from now. Keep doing that until a solution starts that is close enough to your desired time.
10ms will fire first. And then nothing will fire unless another solution is scheduled during or after that 10ms solution.
Here, in a nutshell, is the scheduling logic:
private TimeSpan _schedule;
private List<delegate> _callbacks = new List<delegate>();
public void ScheduleSolution(TimeSpan delay, delegate callback)
if (delay < _schedule)
_schedule = delay;
public void RunSolution()
SolutionRunning = true;
_schedule = TimeSpan.Zero;
foreach (delegate callback in _callbacks)
// Iterate over all expired objects and solve them.
// Some of them may schedule solutions while running.
SolutionRunning = false;
if (_schedule != TimeSpan.Zero)