mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 08:21:25 +00:00
Add block handling functions to NSTimer
This commit is contained in:
parent
3d6cd160b2
commit
873e4edc47
4 changed files with 128 additions and 50 deletions
|
@ -51,7 +51,7 @@ enum {
|
||||||
};
|
};
|
||||||
typedef NSInteger NSQualityOfService;
|
typedef NSInteger NSQualityOfService;
|
||||||
|
|
||||||
@class NSString;
|
@class NSString, NSTimer;
|
||||||
|
|
||||||
DEFINE_BLOCK_TYPE(NSBackgroundActivityCompletionHandler, void, NSBackgroundActivityResult);
|
DEFINE_BLOCK_TYPE(NSBackgroundActivityCompletionHandler, void, NSBackgroundActivityResult);
|
||||||
DEFINE_BLOCK_TYPE(GSScheduledBlock, void, NSBackgroundActivityCompletionHandler);
|
DEFINE_BLOCK_TYPE(GSScheduledBlock, void, NSBackgroundActivityCompletionHandler);
|
||||||
|
@ -64,6 +64,7 @@ DEFINE_BLOCK_TYPE(GSScheduledBlock, void, NSBackgroundActivityCompletionHandler)
|
||||||
NSTimeInterval _tolerance;
|
NSTimeInterval _tolerance;
|
||||||
BOOL _repeats;
|
BOOL _repeats;
|
||||||
BOOL _shouldDefer;
|
BOOL _shouldDefer;
|
||||||
|
NSTimer *_timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype) initWithIdentifier: (NSString *)identifier;
|
- (instancetype) initWithIdentifier: (NSString *)identifier;
|
||||||
|
@ -81,7 +82,7 @@ DEFINE_BLOCK_TYPE(GSScheduledBlock, void, NSBackgroundActivityCompletionHandler)
|
||||||
- (void) setInterval: (NSTimeInterval)interval;
|
- (void) setInterval: (NSTimeInterval)interval;
|
||||||
|
|
||||||
- (NSTimeInterval) tolerance;
|
- (NSTimeInterval) tolerance;
|
||||||
- (void) setTolerance: (NSTimeInterval)interval;
|
- (void) setTolerance: (NSTimeInterval)tolerance;
|
||||||
|
|
||||||
- (BOOL) shouldDefer;
|
- (BOOL) shouldDefer;
|
||||||
- (void) setShouldDefer: (BOOL)flag;
|
- (void) setShouldDefer: (BOOL)flag;
|
||||||
|
|
|
@ -28,6 +28,9 @@
|
||||||
|
|
||||||
#import <Foundation/NSDate.h>
|
#import <Foundation/NSDate.h>
|
||||||
|
|
||||||
|
@class NSTimer;
|
||||||
|
DEFINE_BLOCK_TYPE(GSTimerBlock, void, NSTimer*);
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -43,13 +46,14 @@ extern "C" {
|
||||||
{
|
{
|
||||||
#if GS_EXPOSE(NSTimer)
|
#if GS_EXPOSE(NSTimer)
|
||||||
@public
|
@public
|
||||||
NSDate *_date; /* Must be first - for NSRunLoop optimisation */
|
NSDate *_date; /* Must be 1st - for NSRunLoop optimisation */
|
||||||
BOOL _invalidated; /* Must be 2nd - for NSRunLoop optimisation */
|
BOOL _invalidated; /* Must be 2nd - for NSRunLoop optimisation */
|
||||||
BOOL _repeats;
|
BOOL _repeats;
|
||||||
NSTimeInterval _interval;
|
NSTimeInterval _interval;
|
||||||
id _target;
|
id _target;
|
||||||
SEL _selector;
|
SEL _selector;
|
||||||
id _info;
|
id _info;
|
||||||
|
GSTimerBlock _block;
|
||||||
#endif
|
#endif
|
||||||
#if GS_NONFRAGILE
|
#if GS_NONFRAGILE
|
||||||
#else
|
#else
|
||||||
|
@ -67,15 +71,21 @@ extern "C" {
|
||||||
+ (NSTimer*) scheduledTimerWithTimeInterval: (NSTimeInterval)ti
|
+ (NSTimer*) scheduledTimerWithTimeInterval: (NSTimeInterval)ti
|
||||||
invocation: (NSInvocation*)invocation
|
invocation: (NSInvocation*)invocation
|
||||||
repeats: (BOOL)f;
|
repeats: (BOOL)f;
|
||||||
|
|
||||||
+ (NSTimer*) scheduledTimerWithTimeInterval: (NSTimeInterval)ti
|
+ (NSTimer*) scheduledTimerWithTimeInterval: (NSTimeInterval)ti
|
||||||
target: (id)object
|
target: (id)object
|
||||||
selector: (SEL)selector
|
selector: (SEL)selector
|
||||||
userInfo: (id)info
|
userInfo: (id)info
|
||||||
repeats: (BOOL)f;
|
repeats: (BOOL)f;
|
||||||
|
|
||||||
|
+ (NSTimer *) scheduledTimerWithTimeInterval: (NSTimeInterval)ti
|
||||||
|
repeats: (BOOL)f
|
||||||
|
block: (GSTimerBlock)block;
|
||||||
|
|
||||||
+ (NSTimer*) timerWithTimeInterval: (NSTimeInterval)ti
|
+ (NSTimer*) timerWithTimeInterval: (NSTimeInterval)ti
|
||||||
invocation: (NSInvocation*)invocation
|
invocation: (NSInvocation*)invocation
|
||||||
repeats: (BOOL)f;
|
repeats: (BOOL)f;
|
||||||
|
|
||||||
+ (NSTimer*) timerWithTimeInterval: (NSTimeInterval)ti
|
+ (NSTimer*) timerWithTimeInterval: (NSTimeInterval)ti
|
||||||
target: (id)object
|
target: (id)object
|
||||||
selector: (SEL)selector
|
selector: (SEL)selector
|
||||||
|
@ -102,6 +112,13 @@ extern "C" {
|
||||||
- (void) setFireDate: (NSDate*)fireDate;
|
- (void) setFireDate: (NSDate*)fireDate;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if OS_API_VERSION(MAC_OS_X_VERSION_10_12, GS_API_LATEST)
|
||||||
|
- (instancetype)initWithFireDate:(NSDate *)date
|
||||||
|
interval:(NSTimeInterval)interval
|
||||||
|
repeats:(BOOL)repeats
|
||||||
|
block:(GSTimerBlock)block;
|
||||||
|
#endif
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
_interval = 0;
|
_interval = 0;
|
||||||
_tolerance = 0;
|
_tolerance = 0;
|
||||||
_shouldDefer = NO;
|
_shouldDefer = NO;
|
||||||
|
_timer = nil;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -103,6 +104,30 @@
|
||||||
|
|
||||||
- (void) scheduleWithBlock: (GSScheduledBlock)block
|
- (void) scheduleWithBlock: (GSScheduledBlock)block
|
||||||
{
|
{
|
||||||
|
NSProcessInfo *pinfo = [NSProcessInfo processInfo];
|
||||||
|
id token = nil;
|
||||||
|
NSActivityOptions opts = 0;
|
||||||
|
|
||||||
|
switch(qualityOfService)
|
||||||
|
{
|
||||||
|
case NSQualityOfServiceUserInteractive:
|
||||||
|
opts = NSActivityUserInitiated | NSActivityIdleDisplaySleepDisabled;
|
||||||
|
break;
|
||||||
|
case NSQualityOfServiceUserInitiated:
|
||||||
|
opts = NSActivityUserInitiated;
|
||||||
|
break;
|
||||||
|
case NSQualityOfServiceUtility:
|
||||||
|
opts = NSActivityUserInitiated | NSActivityIdleDisplaySleepDisabled;
|
||||||
|
break;
|
||||||
|
case NSQualityOfServiceBackground:
|
||||||
|
opts = NSActivityBackground;
|
||||||
|
break;
|
||||||
|
case NSQualityOfServiceDefault:
|
||||||
|
opts = NSActivityLatencyCritical;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
token = [pinfo beginActivityWithOptions:
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) invalidate
|
- (void) invalidate
|
||||||
|
|
117
Source/NSTimer.m
117
Source/NSTimer.m
|
@ -145,6 +145,20 @@ static Class NSDate_class;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithFireDate:(NSDate *)date
|
||||||
|
interval:(NSTimeInterval)interval
|
||||||
|
repeats:(BOOL)repeats
|
||||||
|
block:(GSTimerBlock)block
|
||||||
|
{
|
||||||
|
return [self initWithFireDate: date
|
||||||
|
interval: interval
|
||||||
|
target: nil
|
||||||
|
selector: NULL
|
||||||
|
userInfo: nil
|
||||||
|
repeats: repeats];
|
||||||
|
ASSIGN(_block, block);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a timer which will fire after ti seconds and, if f is YES,
|
* Create a timer which will fire after ti seconds and, if f is YES,
|
||||||
* every ti seconds thereafter. On firing, invocation will be performed.<br />
|
* every ti seconds thereafter. On firing, invocation will be performed.<br />
|
||||||
|
@ -229,6 +243,19 @@ static Class NSDate_class;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (NSTimer *) scheduledTimerWithTimeInterval: (NSTimeInterval)ti
|
||||||
|
repeats: (BOOL)f
|
||||||
|
block: (GSTimerBlock)block
|
||||||
|
{
|
||||||
|
id t = [[self alloc] initWithFireDate: nil
|
||||||
|
interval: ti
|
||||||
|
repeats: f
|
||||||
|
block: block];
|
||||||
|
[[NSRunLoop currentRunLoop] addTimer: t forMode: NSDefaultRunLoopMode];
|
||||||
|
RELEASE(t);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
- (void) dealloc
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
if (_invalidated == NO)
|
if (_invalidated == NO)
|
||||||
|
@ -251,48 +278,56 @@ static Class NSDate_class;
|
||||||
*/
|
*/
|
||||||
if (NO == _invalidated)
|
if (NO == _invalidated)
|
||||||
{
|
{
|
||||||
id target;
|
if(_block != nil)
|
||||||
|
{
|
||||||
/* We retain the target so it won't be deallocated while we are using it
|
CALL_BLOCK(_block, self);
|
||||||
* (if this timer gets invalidated while we are firing).
|
}
|
||||||
*/
|
|
||||||
target = RETAIN(_target);
|
|
||||||
|
|
||||||
if (_selector == 0)
|
|
||||||
{
|
|
||||||
NS_DURING
|
|
||||||
{
|
|
||||||
[(NSInvocation*)target invoke];
|
|
||||||
}
|
|
||||||
NS_HANDLER
|
|
||||||
{
|
|
||||||
NSLog(@"*** NSTimer ignoring exception '%@' (reason '%@') "
|
|
||||||
@"raised during posting of timer with target %s(%s) "
|
|
||||||
@"and selector '%@'",
|
|
||||||
[localException name], [localException reason],
|
|
||||||
GSClassNameFromObject(target),
|
|
||||||
GSObjCIsInstance(target) ? "instance" : "class",
|
|
||||||
NSStringFromSelector([target selector]));
|
|
||||||
}
|
|
||||||
NS_ENDHANDLER
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NS_DURING
|
id target;
|
||||||
{
|
|
||||||
[target performSelector: _selector withObject: self];
|
/* We retain the target so it won't be deallocated while we are using it
|
||||||
}
|
* (if this timer gets invalidated while we are firing).
|
||||||
NS_HANDLER
|
*/
|
||||||
{
|
target = RETAIN(_target);
|
||||||
NSLog(@"*** NSTimer ignoring exception '%@' (reason '%@') "
|
|
||||||
@"raised during posting of timer with target %p and "
|
if (_selector == 0)
|
||||||
@"selector '%@'",
|
{
|
||||||
[localException name], [localException reason], target,
|
NS_DURING
|
||||||
NSStringFromSelector(_selector));
|
{
|
||||||
}
|
[(NSInvocation*)target invoke];
|
||||||
NS_ENDHANDLER
|
}
|
||||||
}
|
NS_HANDLER
|
||||||
RELEASE(target);
|
{
|
||||||
|
NSLog(@"*** NSTimer ignoring exception '%@' (reason '%@') "
|
||||||
|
@"raised during posting of timer with target %s(%s) "
|
||||||
|
@"and selector '%@'",
|
||||||
|
[localException name], [localException reason],
|
||||||
|
GSClassNameFromObject(target),
|
||||||
|
GSObjCIsInstance(target) ? "instance" : "class",
|
||||||
|
NSStringFromSelector([target selector]));
|
||||||
|
}
|
||||||
|
NS_ENDHANDLER
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NS_DURING
|
||||||
|
{
|
||||||
|
[target performSelector: _selector withObject: self];
|
||||||
|
}
|
||||||
|
NS_HANDLER
|
||||||
|
{
|
||||||
|
NSLog(@"*** NSTimer ignoring exception '%@' (reason '%@') "
|
||||||
|
@"raised during posting of timer with target %p and "
|
||||||
|
@"selector '%@'",
|
||||||
|
[localException name], [localException reason], target,
|
||||||
|
NSStringFromSelector(_selector));
|
||||||
|
}
|
||||||
|
NS_ENDHANDLER
|
||||||
|
}
|
||||||
|
RELEASE(target);
|
||||||
|
}
|
||||||
|
|
||||||
if (_repeats == NO)
|
if (_repeats == NO)
|
||||||
{
|
{
|
||||||
[self invalidate];
|
[self invalidate];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue