Grasshopper

algorithmic modeling for Rhino

I was wondering if it's possible to use multiple GH_Timers in a single definition (with different time intervals).  I understand that the GH_Timer component runs on top of Grasshopper (sort of like Galapagos), so I'm not completely sure how the threading/timer works... but I recently wrote a Stop Watch component for Firefly which returns the approximate time interval (in milliseconds) since the last update (it also returns the approx. frames/sec.) 

If I connect one GH_Timer component to this component (with a 1 millisecond update interval) and then connect a second GH_Timer component (with a 2 second update interval) to another Stop Watch component... both Stop Watch components update at the same rate (taking the faster time interval). Is this normal?  Or should the timer connected to each component take precedence (ie. each component would update at different intervals based on the GH_Timer connected to it)?  Sorry if my question is unclear.

Cheers,

Andy

Views: 2749

Replies to This Discussion

Hi Andy,

 

yes, this is normal. It's supposed to work this way, though it's not impossible -and maybe much better- to not make it work this way.

 

Let me try and explain the details. Timers no longer do anything tricky any more, all the time-keeping and triggering is done by GH_Document itself. There is a function on GH_Document called ScheduleSolution(int milliseconds). When this method is called it starts a timer for the specified interval (if the method is called during a solution, the timer doesn't start until the solution is done). When the interval is passed, the object that requested the schedule will be informed that a new solution is about to be kickstarted, and then a new solution will be run. Timers use this callback to expire their targets.

 

When multiple objects request a schedule, the one with the tightest schedule wins. I.e. if you have two timers, one firing at 2s intervals and the other at 5ms intervals, both will request a schedule, but the 5ms one ends up being the real schedule. Both timers will get a callback, and at this stage I again request a schedule for both timers.

 

I could change the timer behaviour so that when a solution happens before its interval has passed, it will ignore this solution, not expire its targets and request a new schedule at T-now. If this makes more sense, I'll be happy to try and change it.

 

--

David Rutten

david@mcneel.com

Poprad, Slovakia

Hey David,

Thanks for the very thorough explanation.  If it were up to me (and maybe others can weigh in here), I would prefer if the timer connected to the target took precedence (regardless of who has the fastest schedule interval).  I think it could be helpful to be able to trigger things at different rates (as long as it didn't slow things down overall).  I also think it makes more sense logically, since it's a little unclear if you think one timer is doing it's thing (at say 2s) but, it is actually getting an override from a faster interval (say 5ms).  Anyway, that would be my preference.

Cheers,

Andy

It definitely makes more sense in the case of 5ms vs. 2s. But what if you have two timers, both running at 5ms? Or one running at 5 and the other at 6? Now you've doubled the amount of solutions that need to run.

 

Should there maybe be a cut-off point? "If the timer is within 10ms of it's real schedule, go with the flow"? Or "If the timer is within 1% of it's real schedule, go with the flow"?

 

Of course it is an option to just ignore this and take the position that if someone has two timers with a slight variance in frequency, they deserve what they get. Which is not an unreasonable position, though not a very friendly one either.

 

--

David Rutten

david@mcneel.com

Poprad, Slovakia

I see your point. I guess the question comes into how accurate the timing mechanism is in your GH_Timer component. I know Form timers don't have nearly the accuracy or precision of say a System timer.  Would a difference of 1ms really even be noticeable? It does seem like roughly 10ms would be a good cutoff (if they're within this range)... I think 1% wouldn't be as reliable if the intervals were really big (say 100s and 99s would yield a 1 second difference and yet it would go unchecked if it used 1%)... although I'm not really sure people ever use that slow of an interval anyway.  Will adding multiple solution intervals (especially if they are really small) slow down GH in general? Or is the call threaded?

I use the System.Threading.Timer, so it runs in a separate thread. That doesn't really matter all that much because it still has to invoke into the UI thread to actually kickstart a new solution, so if the UI thread is busy doing something else, the Invoke will be put on hold for however long it takes for the UI thread to finish doing what it's doing. The timers also only fire once, then commit suicide. New timers are started when the solution ends and there's a schedule present. Otherwise you run the risk of timer events queueing up because they are collected faster than the document can solve itself.

 

What this means though is that a Timer firing at 5ms does not start a new solution every 5ms. Rather, the time between two consecutive solutions will be roughly 5ms, maybe more if the UI thread is otherwise occupied.

 

--

David Rutten

david@mcneel.com

Poprad, Slovakia

RSS

About

Translate

Search

Photos

  • Add Photos
  • View All

Videos

  • Add Videos
  • View All

© 2024   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service