30 function _CPRunLoopPerformCompare(lhs, rhs)
32 return [rhs order] - [lhs order];
35 var _CPRunLoopPerformPool = [],
36 _CPRunLoopPerformPoolCapacity = 5;
39 @implementation _CPRunLoopPerform :
CPObject 46 CPArray _runLoopModes;
50 + (void)_poolPerform:(_CPRunLoopPerform)aPerform
52 if (!aPerform || _CPRunLoopPerformPool.length >= _CPRunLoopPerformPoolCapacity)
55 _CPRunLoopPerformPool.push(aPerform);
58 + (_CPRunLoopPerform)performWithSelector:(
SEL)aSelector target:(id)aTarget argument:(
id)anArgument order:(unsigned)anOrder modes:(CPArray)modes
60 if (_CPRunLoopPerformPool.length)
62 var perform = _CPRunLoopPerformPool.pop();
65 perform._target = aTarget;
66 perform._selector = aSelector;
67 perform._argument = anArgument;
68 perform._order = anOrder;
69 perform._runLoopModes = modes;
70 perform._isValid = YES;
75 return [[
self alloc] initWithSelector:aSelector target:aTarget argument:anArgument order:anOrder modes:modes];
78 + (_CPRunLoopPerform)performWithBlock:(Function)aBlock argument:(id)anArgument order:(
unsigned)anOrder modes:(CPArray)modes
80 if (_CPRunLoopPerformPool.length)
82 var perform = _CPRunLoopPerformPool.pop();
84 perform._target = nil;
85 perform._selector = nil;
86 perform._block = aBlock;
87 perform._argument = anArgument;
88 perform._order = anOrder;
89 perform._runLoopModes = modes;
90 perform._isValid = YES;
95 return [[
self alloc] initWithBlock:aBlock argument:anArgument order:anOrder modes:modes];
98 - (id)initWithSelector:(
SEL)aSelector target:(SEL)aTarget argument:(
id)anArgument order:(unsigned)anOrder modes:(CPArray)modes
104 _selector = aSelector;
106 _argument = anArgument;
108 _runLoopModes = modes;
115 - (id)initWithBlock:(Function)aBlock argument:(id)anArgument order:(
unsigned)anOrder modes:(CPArray)modes
122 _argument = anArgument;
124 _runLoopModes = modes;
151 - (BOOL)fireInMode:(
CPString)aRunLoopMode
156 if ([_runLoopModes containsObject:aRunLoopMode])
161 [_target performSelector:_selector withObject:_argument];
190 Object _timersForModes;
191 Object _nativeTimersForModes;
192 CPDate _nextTimerFireDatesForModes;
196 CPArray _orderedPerforms;
197 int _runLoopInsuranceTimer;
217 _orderedPerforms = [];
219 _timersForModes = {};
220 _nativeTimersForModes = {};
221 _nextTimerFireDatesForModes = {};
232 return CPMainRunLoop;
240 return CPMainRunLoop;
251 - (void)performSelector:(
SEL)aSelector target:(
id)aTarget argument:(
id)anArgument order:(
int)anOrder modes:(CPArray)modes
253 var perform = [_CPRunLoopPerform performWithSelector:aSelector target:aTarget argument:anArgument order:anOrder modes:modes],
254 count = _orderedPerforms.length;
258 if (anOrder < [_orderedPerforms[count] order])
261 _orderedPerforms.splice(count + 1, 0, perform);
268 - (void)performBlock:(Function)aBlock argument:(
id)anArgument order:(
int)anOrder modes:(CPArray)modes
270 var perform = [_CPRunLoopPerform performWithBlock:aBlock argument:anArgument order:anOrder modes:modes],
271 count = _orderedPerforms.length;
275 if (anOrder < [_orderedPerforms[count] order])
278 _orderedPerforms.splice(count + 1, 0, perform);
287 - (void)cancelPerformSelector:(
SEL)aSelector target:(
id)aTarget argument:(
id)anArgument
289 var count = _orderedPerforms.length;
293 var perform = _orderedPerforms[count];
295 if ([perform selector] === aSelector && [perform target] == aTarget && [perform argument] == anArgument)
296 [_orderedPerforms[count] invalidate];
303 - (void)performSelectors
314 if (_timersForModes[aMode])
315 _timersForModes[aMode].push(aTimer);
317 _timersForModes[aMode] = [aTimer];
321 if (!aTimer._lastNativeRunLoopsForModes)
322 aTimer._lastNativeRunLoopsForModes = {};
327 if ([CFBundle.environments() indexOfObject:(
"Browser")] !==
CPNotFound)
329 if (!_runLoopInsuranceTimer)
330 _runLoopInsuranceTimer = window.setNativeTimeout(
function()
349 if ([CFBundle.environments() indexOfObject:(
"Browser")] !==
CPNotFound)
351 if (_runLoopInsuranceTimer)
353 window.clearNativeTimeout(_runLoopInsuranceTimer);
354 _runLoopInsuranceTimer = nil;
360 nextTimerFireDate = _nextTimerFireDatesForModes[aMode];
364 if (_didAddTimer || nextTimerFireDate && nextTimerFireDate <= now)
369 if (_nativeTimersForModes[aMode] !== nil)
371 window.clearNativeTimeout(_nativeTimersForModes[aMode]);
373 _nativeTimersForModes[aMode] = nil;
377 var timers = _timersForModes[aMode],
378 index = timers.length;
380 _timersForModes[aMode] = nil;
384 var hasNativeTimers = [CFBundle.environments() indexOfObject:("Browser")] !==
CPNotFound;
389 var timer = timers[index];
391 if ((!hasNativeTimers || timer._lastNativeRunLoopsForModes[aMode] <
CPRunLoopLastNativeRunLoop) && timer._isValid && timer._fireDate <= now)
396 nextFireDate = (nextFireDate === nil) ? timer._fireDate : [nextFireDate earlierDate:timer._fireDate];
401 timer._lastNativeRunLoopsForModes[aMode] = 0;
403 timers.splice(index, 1);
410 var newTimers = _timersForModes[aMode];
412 if (newTimers && newTimers.length)
414 index = newTimers.length;
418 var timer = newTimers[index];
421 nextFireDate = (nextFireDate === nil) ? timer._fireDate : [nextFireDate earlierDate:timer._fireDate];
423 newTimers.splice(index, 1);
426 _timersForModes[aMode] = newTimers.concat(timers);
429 _timersForModes[aMode] = timers;
431 _nextTimerFireDatesForModes[aMode] = nextFireDate;
434 if (_nextTimerFireDatesForModes[aMode] !== nil)
435 _nativeTimersForModes[aMode] = window.setNativeTimeout(
function()
437 _effectiveDate = nextFireDate;
438 _nativeTimersForModes[aMode] = nil;
441 _effectiveDate = nil;
442 }, MAX(0, [nextFireDate timeIntervalSinceNow] * 1000));
446 var performs = _orderedPerforms,
447 index = performs.length;
449 _orderedPerforms = [];
453 var perform = performs[index];
457 [_CPRunLoopPerform _poolPerform:perform];
459 performs.splice(index, 1);
463 if (_orderedPerforms.length)
465 _orderedPerforms = _orderedPerforms.concat(performs);
466 _orderedPerforms.sort(_CPRunLoopPerformCompare);
469 _orderedPerforms = performs;
var CPRunLoopLastNativeRunLoop
A representation of a single point in time.
The main run loop for the application.
An immutable string (collection of characters).
CPDate limitDateForMode:(CPString aMode)
A timer object that can send a message after the given time interval.