Skip to content

Instantly share code, notes, and snippets.

@rsms
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rsms/fd0d017385dd34f31cf6 to your computer and use it in GitHub Desktop.
Save rsms/fd0d017385dd34f31cf6 to your computer and use it in GitHub Desktop.
struct Timer {
dispatch_source_t source;
dispatch_time_t interval = DISPATCH_TIME_FOREVER;
dispatch_time_t delay = DISPATCH_TIME_FOREVER; // == same as interval
dispatch_time_t tolerance = DISPATCH_TIME_FOREVER; // == 10% of interval
Timer(dispatch_queue_t queue, dispatch_time_t interval, dispatch_block_t block) : source{dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue)} {
dispatch_source_set_event_handler(source, block);
}
Timer(dispatch_time_t interval, dispatch_block_t block) : Timer{dispatch_get_main_queue(), interval, block} {}
Timer(dispatch_block_t block) : Timer{dispatch_get_main_queue(), 0, block} {}
void resume() {
uint64_t leeway = (tolerance == DISPATCH_TIME_FOREVER) ? (interval / 10) : tolerance;
if (delay == DISPATCH_TIME_FOREVER) {
if (interval == DISPATCH_TIME_FOREVER) {
// TODO: Error: Neither `delay` nor `interval` is defined
} else {
dispatch_source_set_timer(source, dispatch_time(DISPATCH_TIME_NOW, interval), interval, leeway);
dispatch_resume(source);
}
} else if (interval == DISPATCH_TIME_FOREVER) {
// TODO: One-shot timer based off of `delay`
} else {
dispatch_source_set_timer(source, dispatch_time(DISPATCH_TIME_NOW, delay), interval, leeway);
dispatch_resume(source);
}
}
void suspend() {
dispatch_suspend(source);
}
};
- (void)applicationDidFinishLaunching:(NSNotification*)notification {
static auto timer = Timer{dispatch_get_main_queue(), ^{
NSLog(@"timer fired");
}};
timer.delay = 1 * NSEC_PER_SEC;
timer.interval = 5 * NSEC_PER_SEC;
timer.tolerance = 1 * NSEC_PER_SEC;
timer.resume();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment