darling-corefoundation/NSTimer.m
Andrew Hyatt 1c6ea502b7 Revert "Fix all warnings in CoreFoundation"
This reverts commit 3cf877c00d.

The issue with this commit is that it adds stubs for some methods
which are actually implemeneted in categories in Foundation. The good
parts of this commit will be later committed once those are removed.
2019-04-30 16:59:58 -04:00

216 lines
4.2 KiB
Objective-C

//
// NSTimer.m
// CoreFoundation
//
// Copyright (c) 2014 Apportable. All rights reserved.
//
#import <Foundation/NSTimer.h>
#import <Foundation/NSInvocation.h>
#import <Foundation/NSMethodSignature.h>
#import <Foundation/NSRunLoop.h>
#import <objc/message.h>
#import "NSObjectInternal.h"
@implementation NSTimer
@end
CF_PRIVATE
@interface _NSTimerInfo : NSObject {
@package
id target;
SEL selector;
id userInfo;
}
@end
@implementation _NSTimerInfo
- (id)initWithTarget:(id)aTarget selector:(SEL)aSelector userInfo:(id)info
{
self = [super init];
if (self)
{
target = [aTarget retain];
userInfo = [info retain];
selector = aSelector;
}
return self;
}
- (void)dealloc
{
[target release];
[userInfo release];
[super dealloc];
}
@end
CF_PRIVATE
@interface __NSCFTimer : NSTimer
@end
@implementation __NSCFTimer
+ (id)allocWithZone:(NSZone *)zone
{
static __NSCFTimer *sharedTimer = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedTimer = [super allocWithZone:zone];
});
return sharedTimer;
}
+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key
{
return NO;
}
- (id)init
{
return nil;
}
static void __NSFireTimer(__NSCFTimer *timer, _NSTimerInfo *info)
{
@autoreleasepool
{
[timer retain];
[info->target retain];
[timer fire];
[info->target release];
[timer release];
}
}
- (id)initWithFireDate:(NSDate *)fireDate interval:(NSTimeInterval)ti target:(id)target selector:(SEL)selector userInfo:(id)userInfo repeats:(BOOL)repeats
{
_NSTimerInfo *timerInfo = [[_NSTimerInfo alloc] initWithTarget:target selector:selector userInfo:userInfo];
CFRunLoopTimerContext ctx = {
.version = 0,
.info = timerInfo,
.retain = &_NSCFRetain,
.release = &_NSCFRelease,
};
if (repeats == NO)
{
ti = 0;
}
else if (ti < 0.0)
{
ti = 0.0001; // If [ti] is less than or equal to 0.0, this method chooses the nonnegative value of 0.1 milliseconds instead.
}
id timer = (id)CFRunLoopTimerCreate(kCFAllocatorDefault, [fireDate timeIntervalSinceReferenceDate], ti, 0, 0, (void (*)(CFRunLoopTimerRef, void *))&__NSFireTimer, &ctx);
[timerInfo release];
return timer;
}
- (void)fire
{
CFRunLoopTimerContext ctx = {0};
CFRunLoopTimerGetContext((CFRunLoopTimerRef)self, &ctx);
((void (*)(id, SEL, id))objc_msgSend)(((_NSTimerInfo *)ctx.info)->target, ((_NSTimerInfo *)ctx.info)->selector, self);
if (CFRunLoopTimerDoesRepeat((CFRunLoopTimerRef)self) == NO)
{
CFRunLoopTimerInvalidate((CFRunLoopTimerRef)self);
}
}
- (id)userInfo
{
CFRunLoopTimerContext ctx = {0};
CFRunLoopTimerGetContext((CFRunLoopTimerRef)self, &ctx);
_NSTimerInfo *timerInfo = (_NSTimerInfo *)ctx.info;
return timerInfo->userInfo;
}
- (void)setFireDate:(NSDate *)date
{
CFRunLoopTimerSetNextFireDate((CFRunLoopTimerRef)self, [date timeIntervalSinceReferenceDate]);
}
- (NSDate *)fireDate
{
CFAbsoluteTime t = CFRunLoopTimerGetNextFireDate((CFRunLoopTimerRef)self);
return [NSDate dateWithTimeIntervalSinceReferenceDate:t];
}
- (void)invalidate
{
CFRunLoopTimerInvalidate((CFRunLoopTimerRef)self);
}
- (NSTimeInterval)timeInterval
{
return CFRunLoopTimerGetInterval((CFRunLoopTimerRef)self);
}
- (BOOL)isValid
{
return CFRunLoopTimerIsValid((CFRunLoopTimerRef)self);
}
- (NSUInteger)retainCount
{
return CFGetRetainCount((CFTypeRef)self);
}
- (BOOL)_isDeallocating
{
return _CFIsDeallocating((CFTypeRef)self);
}
- (BOOL)_tryRetain
{
return _CFTryRetain((CFTypeRef)self) != NULL;
}
- (oneway void)release
{
CFRelease((CFTypeRef)self);
}
- (id)retain
{
return (id)CFRetain((CFTypeRef)self);
}
- (NSUInteger)hash
{
return CFHash((CFTypeRef)self);
}
- (BOOL)isEqual:(id)other
{
if (other == nil)
{
return NO;
}
return CFEqual((CFTypeRef)self, (CFTypeRef)other);
}
- (NSTimeInterval)tolerance
{
return CFRunLoopTimerGetTolerance((CFRunLoopTimerRef)self);
}
- (void)setTolerance:(NSTimeInterval)tolerance
{
CFRunLoopTimerSetTolerance((CFRunLoopTimerRef)self, tolerance);
}
@end