diff options
| author | Manolo Gouy <Manolo> | 2012-06-16 08:49:52 +0000 |
|---|---|---|
| committer | Manolo Gouy <Manolo> | 2012-06-16 08:49:52 +0000 |
| commit | 27e406f7512c0e922bc040568331efe30e0838de (patch) | |
| tree | c6ce7b44e81a88d73025c7bc0df617f7fca8f2e7 | |
| parent | 51ca904eb3ee1001096133e72f98f63eae84dbea (diff) | |
Mac OS: some optimization of timer objects + code reordering.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@9618 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
| -rw-r--r-- | src/Fl_cocoa.mm | 197 |
1 files changed, 97 insertions, 100 deletions
diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm index d0cce3cf5..bc7fbb7d3 100644 --- a/src/Fl_cocoa.mm +++ b/src/Fl_cocoa.mm @@ -50,6 +50,7 @@ extern "C" { #include "flstring.h" #include <unistd.h> #include <stdarg.h> +#include <math.h> #import <Cocoa/Cocoa.h> @@ -424,7 +425,7 @@ void Fl::remove_fd(int n) } /* - * Check if there is actually a message pending! + * Check if there is actually a message pending */ int fl_ready() { @@ -512,24 +513,110 @@ static void delete_timer(MacTimeout& t) kCFRunLoopDefaultMode); CFRelease(t.timer); memset(&t, 0, sizeof(MacTimeout)); + if (&t == current_timer) current_timer = NULL; } } static void do_timer(CFRunLoopTimerRef timer, void* data) { - for (int i = 0; i < mac_timer_used; ++i) { + current_timer = (MacTimeout*)data; + current_timer->pending = 0; + (current_timer->callback)(current_timer->data); + if (current_timer && current_timer->pending == 0) + delete_timer(*current_timer); + current_timer = NULL; + + breakMacEventLoop(); +} + +void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void* data) +{ + // check, if this timer slot exists already + for (int i = 0; i < mac_timer_used; ++i) { 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); + // if so, simply change the fire interval + if (t.callback == cb && t.data == data) { + t.next_timeout = CFAbsoluteTimeGetCurrent() + time; + CFRunLoopTimerSetNextFireDate(t.timer, t.next_timeout ); + t.pending = 1; + return; + } + } + // no existing timer to use. Create a new one: + int timer_id = -1; + // find an empty slot in the timer array + for (int i = 0; i < mac_timer_used; ++i) { + if ( !mac_timers[i].timer ) { + timer_id = i; break; } } - breakMacEventLoop(); + // if there was no empty slot, append a new timer + if (timer_id == -1) { + // make space if needed + if (mac_timer_used == mac_timer_alloc) { + realloc_timers(); + } + timer_id = mac_timer_used++; + } + // now install a brand new timer + MacTimeout& t = mac_timers[timer_id]; + CFRunLoopTimerContext context = {0, &t, NULL,NULL,NULL}; + CFRunLoopTimerRef timerRef = CFRunLoopTimerCreate(kCFAllocatorDefault, + CFAbsoluteTimeGetCurrent() + time, + 1E30, + 0, + 0, + do_timer, + &context + ); + if (timerRef) { + CFRunLoopAddTimer(CFRunLoopGetCurrent(), + timerRef, + kCFRunLoopDefaultMode); + t.callback = cb; + 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) +{ + 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); +} + +int Fl::has_timeout(Fl_Timeout_Handler cb, void* data) +{ + for (int i = 0; i < mac_timer_used; ++i) { + MacTimeout& t = mac_timers[i]; + if (t.callback == cb && t.data == data && t.pending) { + return 1; + } + } + return 0; +} + +void Fl::remove_timeout(Fl_Timeout_Handler cb, void* data) +{ + for (int i = 0; i < mac_timer_used; ++i) { + MacTimeout& t = mac_timers[i]; + if (t.callback == cb && ( t.data == data || data == NULL)) { + delete_timer(t); + } + } } @interface FLWindow : NSWindow { @@ -2541,96 +2628,6 @@ void Fl::paste(Fl_Widget &receiver, int clipboard) { receiver.handle(FL_PASTE); } -void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void* data) -{ - // check, if this timer slot exists already - for (int i = 0; i < mac_timer_used; ++i) { - MacTimeout& t = mac_timers[i]; - // if so, simply change the fire interval - if (t.callback == cb && t.data == data) { - t.next_timeout = CFAbsoluteTimeGetCurrent() + time; - CFRunLoopTimerSetNextFireDate(t.timer, t.next_timeout ); - t.pending = 1; - return; - } - } - // no existing timer to use. Create a new one: - int timer_id = -1; - // find an empty slot in the timer array - for (int i = 0; i < mac_timer_used; ++i) { - if ( !mac_timers[i].timer ) { - timer_id = i; - break; - } - } - // if there was no empty slot, append a new timer - if (timer_id == -1) { - // make space if needed - if (mac_timer_used == mac_timer_alloc) { - realloc_timers(); - } - timer_id = mac_timer_used++; - } - // now install a brand new timer - MacTimeout& t = mac_timers[timer_id]; - CFRunLoopTimerContext context = {0, data, NULL,NULL,NULL}; - CFRunLoopTimerRef timerRef = CFRunLoopTimerCreate(kCFAllocatorDefault, - CFAbsoluteTimeGetCurrent() + time, - 1E30, - 0, - 0, - do_timer, - &context - ); - if (timerRef) { - CFRunLoopAddTimer(CFRunLoopGetCurrent(), - timerRef, - kCFRunLoopDefaultMode); - t.callback = cb; - 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) -{ - 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); -} - -int Fl::has_timeout(Fl_Timeout_Handler cb, void* data) -{ - for (int i = 0; i < mac_timer_used; ++i) { - MacTimeout& t = mac_timers[i]; - if (t.callback == cb && t.data == data && t.pending) { - return 1; - } - } - return 0; -} - -void Fl::remove_timeout(Fl_Timeout_Handler cb, void* data) -{ - for (int i = 0; i < mac_timer_used; ++i) { - MacTimeout& t = mac_timers[i]; - if (t.callback == cb && ( t.data == data || data == NULL)) { - delete_timer(t); - } - } -} - int Fl_X::unlink(Fl_X *start) { if (start) { Fl_X *pc = start; |
