API 0.9.5
Foundation/CPTimer.j
Go to the documentation of this file.
00001 /*
00002  * CPTimer.j
00003  * Foundation
00004  *
00005  * Created by Nick Takayama.
00006  * Copyright 2008.
00007  *
00008  * This library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00021  */
00022 
00023 
00030 @implementation CPTimer : CPObject
00031 {
00032     CPTimeInterval      _timeInterval;
00033     CPInvocation        _invocation;
00034     Function            _callback;
00035 
00036     BOOL                _repeats;
00037     BOOL                _isValid;
00038     CPDate              _fireDate;
00039     id                  _userInfo;
00040 }
00041 
00045 + (CPTimer)scheduledTimerWithTimeInterval:(CPTimeInterval)seconds invocation:(CPInvocation)anInvocation repeats:(BOOL)shouldRepeat
00046 {
00047     var timer = [[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds invocation:anInvocation repeats:shouldRepeat];
00048 
00049     [[CPRunLoop currentRunLoop] addTimer:timer forMode:CPDefaultRunLoopMode];
00050 
00051     return timer;
00052 }
00053 
00057 + (CPTimer)scheduledTimerWithTimeInterval:(CPTimeInterval)seconds target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)shouldRepeat
00058 {
00059     var timer =  [[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds target:aTarget selector:aSelector userInfo:userInfo repeats:shouldRepeat];
00060 
00061     [[CPRunLoop currentRunLoop] addTimer:timer forMode:CPDefaultRunLoopMode];
00062 
00063     return timer;
00064 }
00065 
00069 + (CPTimer)scheduledTimerWithTimeInterval:(CPTimeInterval)seconds callback:(Function)aFunction repeats:(BOOL)shouldRepeat
00070 {
00071     var timer = [[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds callback:aFunction repeats:shouldRepeat];
00072 
00073     [[CPRunLoop currentRunLoop] addTimer:timer forMode:CPDefaultRunLoopMode];
00074 
00075     return timer;
00076 }
00077 
00081 + (CPTimer)timerWithTimeInterval:(CPTimeInterval)seconds invocation:(CPInvocation)anInvocation repeats:(BOOL)shouldRepeat
00082 {
00083     return [[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds invocation:anInvocation repeats:shouldRepeat];
00084 }
00085 
00089 + (CPTimer)timerWithTimeInterval:(CPTimeInterval)seconds target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)shouldRepeat
00090 {
00091     return [[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds target:aTarget selector:aSelector userInfo:userInfo repeats:shouldRepeat];
00092 }
00093 
00097 + (CPTimer)timerWithTimeInterval:(CPTimeInterval)seconds callback:(Function)aFunction repeats:(BOOL)shouldRepeat
00098 {
00099     return [[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds callback:aFunction repeats:shouldRepeat];
00100 }
00101 
00105 - (id)initWithFireDate:(CPDate)aDate interval:(CPTimeInterval)seconds invocation:(CPInvocation)anInvocation repeats:(BOOL)shouldRepeat
00106 {
00107     self = [super init];
00108 
00109     if (self)
00110     {
00111         _timeInterval = seconds;
00112         _invocation = anInvocation;
00113         _repeats = shouldRepeat;
00114         _isValid = YES;
00115         _fireDate = aDate;
00116     }
00117 
00118     return self;
00119 }
00120 
00124 - (id)initWithFireDate:(CPDate)aDate interval:(CPTimeInterval)seconds target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)shouldRepeat
00125 {
00126     var invocation = [CPInvocation invocationWithMethodSignature:1];
00127 
00128     [invocation setTarget:aTarget];
00129     [invocation setSelector:aSelector];
00130     [invocation setArgument:self atIndex:2];
00131 
00132     self = [self initWithFireDate:aDate interval:seconds invocation:invocation repeats:shouldRepeat];
00133 
00134     if (self)
00135         _userInfo = userInfo;
00136 
00137     return self;
00138 }
00139 
00143 - (id)initWithFireDate:(CPDate)aDate interval:(CPTimeInterval)seconds callback:(Function)aFunction repeats:(BOOL)shouldRepeat
00144 {
00145     self = [super init];
00146 
00147     if (self)
00148     {
00149         _timeInterval = seconds;
00150         _callback = aFunction;
00151         _repeats = shouldRepeat;
00152         _isValid = YES;
00153         _fireDate = aDate;
00154     }
00155 
00156     return self;
00157 }
00158 
00162 - (CPTimeInterval)timeInterval
00163 {
00164    return _timeInterval;
00165 }
00166 
00170 - (CPDate)fireDate
00171 {
00172    return _fireDate;
00173 }
00174 
00178 - (void)setFireDate:(CPDate)aDate
00179 {
00180     _fireDate = aDate;
00181 }
00182 
00186 - (void)fire
00187 {
00188     if (!_isValid)
00189         return;
00190 
00191     if (_callback)
00192         _callback();
00193     else
00194         [_invocation invoke];
00195 
00196     if (!_isValid)
00197         return;
00198 
00199     if (_repeats)
00200         _fireDate = [CPDate dateWithTimeIntervalSinceNow:_timeInterval];
00201 
00202     else
00203         [self invalidate];
00204 }
00205 
00209 - (BOOL)isValid
00210 {
00211    return _isValid;
00212 }
00213 
00217 - (void)invalidate
00218 {
00219    _isValid = NO;
00220    _userInfo = nil;
00221    _invocation = nil;
00222    _callback = nil;
00223 }
00224 
00228 - (id)userInfo
00229 {
00230    return _userInfo;
00231 }
00232 
00233 @end
00234 
00235 var CPTimersTimeoutID       = 1000,
00236     CPTimersForTimeoutIDs   = {};
00237 
00238 var _CPTimerBridgeTimer = function(codeOrFunction, aDelay, shouldRepeat, functionArgs)
00239 {
00240     var timeoutID = CPTimersTimeoutID++,
00241         theFunction = nil;
00242 
00243     if (typeof codeOrFunction === "string")
00244         theFunction = function() { new Function(codeOrFunction)(); if (!shouldRepeat) CPTimersForTimeoutIDs[timeoutID] = nil; }
00245     else
00246     {
00247         if (!functionArgs)
00248             functionArgs = [];
00249 
00250         theFunction = function() { codeOrFunction.apply(window, functionArgs); if (!shouldRepeat) CPTimersForTimeoutIDs[timeoutID] = nil; }
00251     }
00252 
00253     CPTimersForTimeoutIDs[timeoutID] = [CPTimer scheduledTimerWithTimeInterval:aDelay / 1000 callback:theFunction repeats:shouldRepeat];
00254 
00255     return timeoutID;
00256 }
00257 
00258 // Avoid "TypeError: Result of expression 'window' [undefined] is not an object" when running unit tests.
00259 // We can't use a regular PLATFORM(DOM) check because that platform constant is not defined in Foundation.
00260 if (typeof(window) !== 'undefined')
00261 {
00262     window.setTimeout = function(codeOrFunction, aDelay)
00263     {
00264         return _CPTimerBridgeTimer(codeOrFunction, aDelay, NO, Array.prototype.slice.apply(arguments, [2]));
00265     }
00266 
00267     window.clearTimeout = function(aTimeoutID)
00268     {
00269         var timer = CPTimersForTimeoutIDs[aTimeoutID];
00270 
00271         if (timer)
00272             [timer invalidate];
00273 
00274         CPTimersForTimeoutIDs[aTimeoutID] = nil;
00275     }
00276 
00277     window.setInterval = function(codeOrFunction, aDelay, functionArgs)
00278     {
00279         return _CPTimerBridgeTimer(codeOrFunction, aDelay, YES, Array.prototype.slice.apply(arguments, [2]));
00280     }
00281 
00282     window.clearInterval = function(aTimeoutID)
00283     {
00284         window.clearTimeout(aTimeoutID);
00285     }
00286 }
 All Classes Files Functions Variables Defines