6 window.requestAnimationFrame ||
\r
7 window.webkitRequestAnimationFrame ||
\r
8 window.mozRequestAnimationFrame ||
\r
9 window.oRequestAnimationFrame ||
\r
10 window.msRequestAnimationFrame ||
\r
13 window.cancelRequestAnimationFrame ||
\r
14 window.webkitCancelAnimationFrame ||
\r
15 window.webkitCancelRequestAnimationFrame ||
\r
16 window.mozCancelRequestAnimationFrame ||
\r
17 window.oCancelRequestAnimationFrame ||
\r
18 window.msCancelRequestAnimationFrame ||
\r
23 * http://please-sleep.cou929.nu/script-yielding-with-setimmediate.html
\r
24 * setImmediate での script yielding
\r
26 * http://ie.microsoft.com/testdrive/Performance/setImmediateSorting/Default.html
\r
29 * if( timer < 4ms ) useSetImmediate
\r
31 * if (window.msSetImmediate)
\r
33 this.timer = msSetImmediate(function () { t.stepper(); });
\r
35 else if (window.MozSetImmediate)
\r
37 this.timer = MozSetImmediate(function () { t.stepper(); });
\r
39 else if (window.WebkitSetImmediate) {
\r
40 this.timer = WebkitSetImmediate(function () { t.stepper(); });
\r
42 else if (window.OSetImmediate)
\r
44 this.timer = OSetImmediate(function () { t.stepper(); });
\r
55 busy : false, // for Opera7
\r
57 REQ_FRAME_LIST : [],
\r
61 var next = X.Timer.next,
\r
62 list = X.Timer.TICKET_LIST,
\r
65 limit = X.getTime() + X.Timer.INTERVAL_TIME / 2,
\r
73 X.Timer.busy = true;
\r
75 for( ; i < l; ++i ){
\r
77 if( 0 < ( q.last -= next ) ) continue;
\r
79 if( q.last <= 0 ) q.last = 1;
\r
86 r = X.Callback._proxyCallback( q );
\r
91 console.log( 'fire....' );
\r
93 if( limit <= X.getTime() ){
\r
94 console.log( 'heavy' );
\r
95 // 関数の実行に時間が係る場合、次のタイミングに
\r
99 if( r & X.Callback.UN_LISTEN || c === 1 ){
\r
100 list.splice( i, 1 );
\r
105 if( 1 < c ) --q.count;
\r
108 X.Timer.timerId = 0;
\r
109 X.Timer.busy = false;
\r
112 _update : function(){
\r
113 var list = X.Timer.TICKET_LIST,
\r
117 X.Timer.timerId && window.clearTimeout( X.Timer.timerId );
\r
118 X.Timer.timerId = 0;
\r
122 1 < i && list.sort( x_timer_compareQueue );
\r
124 n = list[ i - 1 ].last;
\r
126 if( n < X.Timer.next || X.Timer.timerId === 0 ){
\r
127 X.Timer.timerId && window.clearTimeout( X.Timer.timerId );
\r
128 X.Timer.timerId = window.setTimeout( X.Timer._loop, X.Timer.INTERVAL_TIME * n );
\r
129 X.Timer.endTime = X.getTime() + X.Timer.INTERVAL_TIME * n; // iOS
\r
135 _onEnterFrame : function ( time ){
\r
136 var list = X.Timer.REQ_FRAME_LIST,
\r
140 time = time || X.getTime();
\r
141 // console.log( X.getTime() + ' , ' + time );
\r
142 for( ; i < l; ++i ){
\r
147 X.Callback._proxyCallback( q );
\r
153 list.splice( 0, l );
\r
155 X.Timer.requestID = _enterFrame ? _enterFrame( X.Timer._onEnterFrame ) : X.Timer.add( 0, 1, X.Timer._onEnterFrame );
\r
159 add : function( time, opt_count, args1, args2, args3 ){
\r
160 var list = X.Timer.TICKET_LIST,
\r
162 time = time < X.Timer.INTERVAL_TIME ? 1 : time / X.Timer.INTERVAL_TIME | 0; // 正の数で使える「Math.floor(x)」を「(x | 0)」に;
\r
164 if( !X.Type.isNumber( opt_count ) ){
\r
171 hash = X.Callback._classifyCallbackArgs( args1, args2, args3 );
\r
172 if( !hash ) return -1; // dev only
\r
174 if( !hash.k ) hash = { f : hash };
\r
177 hash.count = opt_count;
\r
178 hash.uid = ++X.Timer.uid;
\r
179 list[ list.length ] = hash;
\r
181 !X.Timer.busy && X.Timer._update();
\r
182 return X.Timer.uid;
\r
184 once : function( time, args1, args2, args3 ){
\r
185 return X.Timer.add( time, 1, args1, args2, args3 );
\r
187 remove : function( uid ){
\r
188 var list = X.Timer.TICKET_LIST,
\r
195 if( ( q = list[ --i ] ).uid === uid ){
\r
196 list.splice( i, 1 );
\r
197 !X.Timer.busy && ( /* q[ INDEX_COUNT ] <= next || */ l === 1 ) && X.Timer._update();
\r
203 requestFrame : _enterFrame ?
\r
204 (function( args1, args2, args3 ){
\r
205 var i = X.Timer.REQ_FRAME_LIST.length,
\r
207 i === 0 && ( X.Timer.requestID = _enterFrame( X.Timer._onEnterFrame ) );
\r
208 f = X.Timer.REQ_FRAME_LIST[ i ] = X.Callback._classifyCallbackArgs( args1, args2, args3 );
\r
209 return f.uid = ++X.Timer.uid;
\r
211 (function( args1, args2, args3 ){
\r
212 var i = X.Timer.REQ_FRAME_LIST.length,
\r
214 i === 0 && ( X.Timer.requestID = X.Timer.add( 0, 1, X.Timer._onEnterFrame ) );
\r
215 f = X.Timer.REQ_FRAME_LIST[ i ] = X.Callback._classifyCallbackArgs( args1, args2, args3 );
\r
216 return f.uid = ++X.Timer.uid;
\r
219 cancelFrame : _cancelFrame ?
\r
221 var list = X.Timer.REQ_FRAME_LIST,
\r
226 if( ( f = list[ --i ] ).uid < uid ) break;
\r
227 if( f.uid === uid ){
\r
230 list.splice( i, 1 );
\r
231 l === 1 && _cancelFrame( X.Timer.requestID );
\r
237 var list = X.Timer.REQ_FRAME_LIST,
\r
242 if( ( f = list[ --i ] ).uid < uid ) break;
\r
243 if( f.uid === uid ){
\r
244 list.splice( i, 1 );
\r
245 l === 1 && X.Timer.remove( X.Timer.requestID );
\r
254 function x_timer_compareQueue( a, b ){
\r
255 return a.last < b.last ? 1 : a.last === b.last ? 0 : -1;
\r
259 // http://havelog.ayumusato.com/develop/javascript/e528-ios6_scrolling_timer_notcall.html
\r
260 // iOS6 スクロール中のタイマー発火絡みのバグ備忘
\r
262 window.addEventListener( 'scroll', function(){
\r
263 if( X.Timer.timerId ){
\r
264 window.clearTimeout( X.Timer.timerId );
\r
265 X.Timer.timerId = window.setTimeout( X.Timer._loop, Math.max( 0, X.Timer.endTime - X.getTime() ) );
\r
270 if( X.UA.IE < 5 || X.UA.MacIE ){
\r
271 X.Timer[ '_ie_loop' ] = X.Timer._loop;
\r
272 X.Timer._loop = 'X.Timer._ie_loop()';
\r
275 console.log( 'X.Core.Timer' );
\r