From dc464a0b7b0cfbbb1d693dc038691c575bee6b46 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 7 Mar 2019 22:04:29 -0500 Subject: [PATCH] Introduces a wrapper class for high-precision timers. --- .../CSHighPrecisionTimer.h | 27 ++++++++++++++ .../CSHighPrecisionTimer.m | 37 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 OSBindings/Mac/Clock Signal/High Precision Timer/CSHighPrecisionTimer.h create mode 100644 OSBindings/Mac/Clock Signal/High Precision Timer/CSHighPrecisionTimer.m diff --git a/OSBindings/Mac/Clock Signal/High Precision Timer/CSHighPrecisionTimer.h b/OSBindings/Mac/Clock Signal/High Precision Timer/CSHighPrecisionTimer.h new file mode 100644 index 000000000..9ceeded01 --- /dev/null +++ b/OSBindings/Mac/Clock Signal/High Precision Timer/CSHighPrecisionTimer.h @@ -0,0 +1,27 @@ +// +// CSHighPrecisionTimer.h +// Clock Signal +// +// Created by Thomas Harte on 07/03/2019. +// Copyright © 2019 Thomas Harte. All rights reserved. +// + +#import + +/*! + Provides a high-precision timer; provide it with a block and an + interval, and it will ensure the block is performed as regularly + as the system will allow at the specified intervals. + + The block will be executed on an arbitrary thread. +*/ +@interface CSHighPrecisionTimer: NSObject + +/// Initialises a new instance of the high precision timer; the timer will begin +/// ticking immediately. +- (instancetype)initWithTask:(dispatch_block_t)task interval:(uint64_t)interval; + +/// Stops the timer. +- (void)invalidate; + +@end diff --git a/OSBindings/Mac/Clock Signal/High Precision Timer/CSHighPrecisionTimer.m b/OSBindings/Mac/Clock Signal/High Precision Timer/CSHighPrecisionTimer.m new file mode 100644 index 000000000..0947e5620 --- /dev/null +++ b/OSBindings/Mac/Clock Signal/High Precision Timer/CSHighPrecisionTimer.m @@ -0,0 +1,37 @@ +// +// CSHighPrecisionTimer.m +// Clock Signal +// +// Created by Thomas Harte on 07/03/2019. +// Copyright © 2019 Thomas Harte. All rights reserved. +// + +#import "CSHighPrecisionTimer.h" + +@implementation CSHighPrecisionTimer { + dispatch_source_t _timer; + dispatch_queue_t _queue; +} + +- (instancetype)initWithTask:(dispatch_block_t)task interval:(uint64_t)interval { + self = [super init]; + if(self) { + _queue = dispatch_queue_create("High precision timer queue", DISPATCH_QUEUE_SERIAL); + _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _queue); + if(_timer) { + dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), interval, 0); + dispatch_source_set_event_handler(_timer, task); + + // TODO: dispatch_activate is preferred to dispatch_resume, but arrives only + // as of macOS 10.12. So switch if/when upping the OS requirements. + dispatch_resume(_timer); + } + } + return self; +} + +- (void)invalidate { + dispatch_suspend(_timer); +} + +@end