From 51ca904eb3ee1001096133e72f98f63eae84dbea Mon Sep 17 00:00:00 2001 From: Manolo Gouy Date: Fri, 15 Jun 2012 15:08:17 +0000 Subject: Mac OS: improved Fl::repeat_timeout() so the next scheduled timeout is counted from the previous one. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@9611 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- src/Fl_cocoa.mm | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm index ae3efea5d..d0cce3cf5 100644 --- a/src/Fl_cocoa.mm +++ b/src/Fl_cocoa.mm @@ -482,10 +482,12 @@ struct MacTimeout { void* data; CFRunLoopTimerRef timer; char pending; + CFAbsoluteTime next_timeout; // scheduled time for this timer }; static MacTimeout* mac_timers; static int mac_timer_alloc; static int mac_timer_used; +static MacTimeout* current_timer; // the timer that triggered its callback function, or NULL static void realloc_timers() { @@ -519,7 +521,9 @@ static void do_timer(CFRunLoopTimerRef timer, void* data) MacTimeout& t = mac_timers[i]; if (t.timer == timer && t.data == data) { t.pending = 0; + current_timer = &t; (*t.callback)(data); + current_timer = NULL; if (t.pending==0) delete_timer(t); break; @@ -2544,7 +2548,8 @@ void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void* data) MacTimeout& t = mac_timers[i]; // if so, simply change the fire interval if (t.callback == cb && t.data == data) { - CFRunLoopTimerSetNextFireDate(t.timer, CFAbsoluteTimeGetCurrent() + time ); + t.next_timeout = CFAbsoluteTimeGetCurrent() + time; + CFRunLoopTimerSetNextFireDate(t.timer, t.next_timeout ); t.pending = 1; return; } @@ -2585,12 +2590,23 @@ void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void* data) t.data = data; t.timer = timerRef; t.pending = 1; + t.next_timeout = CFRunLoopTimerGetNextFireDate(timerRef); } } void Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void* data) { - // currently, repeat_timeout does not subtract the trigger time of the previous timer event as it should. + if (current_timer) { + // k = how many times 'time' seconds after the last scheduled timeout until the future + double k = ceil( (CFAbsoluteTimeGetCurrent() - current_timer->next_timeout) / time); + if (k < 1) k = 1; + current_timer->next_timeout += k * time; + CFRunLoopTimerSetNextFireDate(current_timer->timer, current_timer->next_timeout ); + current_timer->callback = cb; + current_timer->data = data; + current_timer->pending = 1; + return; + } add_timeout(time, cb, data); } -- cgit v1.2.3