![]() |
API 0.9.5
|
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 }