mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
Make setFireDate: be usable from within a timeout handler method.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@25695 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
cbb3df3248
commit
849f4a8478
3 changed files with 58 additions and 43 deletions
|
@ -5,6 +5,8 @@
|
|||
than one run loop mode and firing in one mode could result in badly
|
||||
ordered timers in another mode.
|
||||
Handle resetting of time for repeating timers.
|
||||
Allow timeout handler callbacks to use ([-setFireDate:]) and have
|
||||
it honoured.
|
||||
* Source/NSTimer.m: Remove resetting of fire date from ([-fire])
|
||||
and move it to the run loop for MacOS-X compatibility.
|
||||
|
||||
|
|
|
@ -26,9 +26,6 @@
|
|||
#define __NSTimer_h_GNUSTEP_BASE_INCLUDE
|
||||
#import <GNUstepBase/GSVersionMacros.h>
|
||||
|
||||
/* This class is currently thrown together. When it is cleaned up, it
|
||||
may no longer be concrete. */
|
||||
|
||||
#import <Foundation/NSDate.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
@ -39,9 +36,12 @@ extern "C" {
|
|||
* NB. NSRunLoop is optimised using a hack that knows about the
|
||||
* class layout for the fire date and invialidation flag in NSTimer.
|
||||
* These MUST remain the first two items in the class.
|
||||
* Other classes must not attempt to use instance variables as
|
||||
* they are subject to change.
|
||||
*/
|
||||
@interface NSTimer : NSObject
|
||||
{
|
||||
@private
|
||||
NSDate *_date; /* Must be first - for NSRunLoop optimisation */
|
||||
BOOL _invalidated; /* Must be 2nd - for NSRunLoop optimisation */
|
||||
BOOL _repeats;
|
||||
|
@ -76,17 +76,19 @@ extern "C" {
|
|||
- (void) invalidate;
|
||||
- (id) userInfo;
|
||||
|
||||
|
||||
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
|
||||
- (BOOL) isValid;
|
||||
- (NSTimeInterval) timeInterval;
|
||||
#endif
|
||||
|
||||
#if OS_API_VERSION(100200, GS_API_LATEST)
|
||||
- (id) initWithFireDate: (NSDate*)fd
|
||||
interval: (NSTimeInterval)ti
|
||||
target: (id)object
|
||||
selector: (SEL)selector
|
||||
userInfo: (id)info
|
||||
repeats: (BOOL)f;
|
||||
- (BOOL) isValid;
|
||||
- (void) setFireDate: (NSDate*)fireDate;
|
||||
- (NSTimeInterval) timeInterval;
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
|
|
@ -253,11 +253,6 @@ static inline BOOL timerInvalidated(NSTimer *t)
|
|||
return ((tvars)t)->_invalidated;
|
||||
}
|
||||
|
||||
static NSComparisonResult tSort(GSIArrayItem i0, GSIArrayItem i1)
|
||||
{
|
||||
return [timerDate(i0.obj) compare: timerDate(i1.obj)];
|
||||
}
|
||||
|
||||
|
||||
|
||||
@implementation NSObject (TimedPerformers)
|
||||
|
@ -816,19 +811,34 @@ static NSComparisonResult tSort(GSIArrayItem i0, GSIArrayItem i1)
|
|||
/*
|
||||
* Fire housekeeping timer as necessary
|
||||
*/
|
||||
if ((t = context->housekeeper) != nil
|
||||
&& ([timerDate(t) timeIntervalSinceReferenceDate] <= now))
|
||||
{
|
||||
NSDate *next;
|
||||
if ((t = context->housekeeper) != nil)
|
||||
{
|
||||
if (timerInvalidated(t))
|
||||
{
|
||||
DESTROY(context->housekeeper);
|
||||
}
|
||||
else if ([timerDate(t) timeIntervalSinceReferenceDate] <= now)
|
||||
{
|
||||
NSDate *d = timerDate(t);
|
||||
|
||||
[t fire];
|
||||
IF_NO_GC([arp emptyPool]);
|
||||
now = GSTimeNow();
|
||||
next = [[NSDate alloc] initWithTimeIntervalSinceReferenceDate:
|
||||
now + [t timeInterval]];
|
||||
[t setFireDate: next];
|
||||
RELEASE(next);
|
||||
}
|
||||
[t fire];
|
||||
GSPrivateNotifyASAP();
|
||||
IF_NO_GC([arp emptyPool]);
|
||||
now = GSTimeNow();
|
||||
|
||||
/* Increment fire date unless timer is invalidated or the
|
||||
* timeout handler has already updated it.
|
||||
*/
|
||||
if (timerInvalidated(t) == NO && timerDate(t) == d)
|
||||
{
|
||||
d = [[NSDate alloc]
|
||||
initWithTimeIntervalSinceReferenceDate:
|
||||
now + [t timeInterval]];
|
||||
[t setFireDate: d];
|
||||
RELEASE(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle normal timers ... remove invalidated timers and fire any
|
||||
|
@ -837,39 +847,40 @@ static NSComparisonResult tSort(GSIArrayItem i0, GSIArrayItem i1)
|
|||
i = GSIArrayCount(timers);
|
||||
while (i-- > 0)
|
||||
{
|
||||
NSTimer *min_timer = GSIArrayItemAtIndex(timers, i).obj;
|
||||
NSDate *d;
|
||||
|
||||
if (timerInvalidated(min_timer) == YES)
|
||||
t = GSIArrayItemAtIndex(timers, i).obj;
|
||||
if (timerInvalidated(t) == YES)
|
||||
{
|
||||
GSIArrayRemoveItemAtIndex(timers, i);
|
||||
min_timer = nil;
|
||||
t = nil;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ([timerDate(min_timer) timeIntervalSinceReferenceDate] > now)
|
||||
d = timerDate(t);
|
||||
if ([d timeIntervalSinceReferenceDate] > now)
|
||||
{
|
||||
when = [timerDate(min_timer) copy];
|
||||
when = [timerDate(t) copy];
|
||||
break;
|
||||
}
|
||||
|
||||
/* Firing will also increment its fireDate, if it is repeating. */
|
||||
[min_timer fire];
|
||||
now = GSTimeNow();
|
||||
if (timerInvalidated(min_timer) == NO)
|
||||
{
|
||||
NSDate *next;
|
||||
|
||||
next = [[NSDate alloc] initWithTimeIntervalSinceReferenceDate:
|
||||
now + [min_timer timeInterval]];
|
||||
[min_timer setFireDate: next];
|
||||
RELEASE(next);
|
||||
}
|
||||
else
|
||||
{
|
||||
GSIArrayRemoveItemAtIndex(timers, i);
|
||||
}
|
||||
[t fire];
|
||||
GSPrivateNotifyASAP(); /* Post notifications. */
|
||||
IF_NO_GC([arp emptyPool]);
|
||||
now = GSTimeNow();
|
||||
|
||||
/* Increment fire date unless timer is invalidated or the
|
||||
* timeout handler has already updated it.
|
||||
*/
|
||||
if (timerInvalidated(t) == NO && timerDate(t) == d)
|
||||
{
|
||||
d = [[NSDate alloc]
|
||||
initWithTimeIntervalSinceReferenceDate:
|
||||
now + [t timeInterval]];
|
||||
[t setFireDate: d];
|
||||
RELEASE(d);
|
||||
}
|
||||
}
|
||||
_currentMode = savedMode;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue