OSDN Git Service

Version 0.6.42, bugfix for tree update event.
[pettanr/clientJs.git] / 0.6.x / js / core / 05_XTimer.js
index 85aa903..058b8c4 100644 (file)
  * use X.Callback\r
  */\r
 \r
-X.Timer = ( function(){\r
-       var setTimeout     = window.setTimeout,\r
-               clearTimeout   = window.clearTimeout,\r
-               INTERVAL_TIME  = 16,\r
-               TICKET_LIST    = [],\r
-               uid            = 0,\r
-               timerId        = -1,\r
-               next           = 0,\r
-               INDEX_TIME     = 0,\r
-               INDEX_LAST     = 1,\r
-               INDEX_COUNT    = 2,\r
-               INDEX_CALLBACK = 3,\r
-               INDEX_UID      = 4;\r
+var _enterFrame =\r
+               window.requestAnimationFrame ||\r
+               window.webkitRequestAnimationFrame ||\r
+               window.mozRequestAnimationFrame ||\r
+               window.oRequestAnimationFrame ||\r
+               window.msRequestAnimationFrame ||\r
+               false,\r
+       _cancelFrame =\r
+               window.cancelRequestAnimationFrame ||\r
+               window.webkitCancelAnimationFrame ||\r
+               window.webkitCancelRequestAnimationFrame ||\r
+               window.mozCancelRequestAnimationFrame ||\r
+               window.oCancelRequestAnimationFrame ||\r
+               window.msCancelRequestAnimationFrame ||\r
+               false;\r
+\r
+X.Timer = {\r
+       INTERVAL_TIME  : 16,\r
+       TICKET_LIST    : [],\r
+       uid            : 0,\r
+       timerId        : 0,\r
+       endTime        : 0, // iOS\r
+       next           : 0,\r
+\r
+       REQUEST_FRAME_LIST : [],\r
+       requestID : 0,\r
        \r
-       function loop(){\r
-               var c    = next,\r
-                       list = TICKET_LIST,\r
+       _loop : function(){\r
+               var next = X.Timer.next,\r
+                       list = X.Timer.TICKET_LIST,\r
                        i    = list.length,\r
-                       queue, f, ret;\r
+                       q, f, c;\r
            for( ; i; ){\r
-               queue = list[ --i ];\r
-                       if( 0 < ( queue[ INDEX_LAST ] -= c ) ) continue;\r
-                       f   = queue[ INDEX_CALLBACK ];\r
-                       c   = queue[ INDEX_COUNT ];\r
-                       ret = f();\r
-                       if( ret & X.Callback.UN_LISTEN || c === 1 ){\r
+               q = list[ --i ];\r
+                       if( 0 < ( q.l -= next ) ) continue;\r
+                       f = q.f;\r
+                       c = q.c;\r
+                       if( f() & X.Callback.UN_LISTEN || c === 1 ){\r
                                list.splice( i, 1 );\r
-                               f.kill();\r
-                               queue.length = 0;\r
+                               f.kill && f.kill();\r
+                               //queue.length = 0;\r
                                continue;\r
                        } else\r
-                       if( 1 < c ) --queue[ INDEX_COUNT ];\r
-                       queue[ INDEX_LAST ] = queue[ INDEX_TIME ];\r
+                       if( 1 < c ) --q.c;\r
+                       q.l = q.t;\r
            };\r
-           timerId = -1;\r
-           update();\r
-       };\r
-       function update(){\r
-               var list = TICKET_LIST,\r
-                       l    = list.length,\r
-                       n    = 99999999,\r
-                       last;\r
-               if( l === 0 ){\r
-                       timerId !== -1 && clearTimeout( timerId );\r
-                       timerId = -1;\r
+           X.Timer.timerId = 0;\r
+           X.Timer._update();\r
+       },\r
+       _update : function(){\r
+               var list = X.Timer.TICKET_LIST,\r
+                       i    = list.length,\r
+                       n    = Infinity,\r
+                       l;\r
+               if( i === 0 ){\r
+                       X.Timer.timerId && window.clearTimeout( X.Timer.timerId );\r
+                       X.Timer.timerId = 0;\r
                        return;\r
                };\r
-           for( ; l; ){\r
-               ( last = list[ --l ][ INDEX_LAST ] ) < n && ( n = last );\r
+           for( ; i; ){\r
+               ( l = list[ --i ].l ) < n && ( n = l );\r
            };\r
-           if( n < next || timerId === -1 ){\r
-               timerId !== -1 && clearTimeout( timerId );\r
-               timerId = setTimeout( loop, INTERVAL_TIME * n );\r
-               next = n;\r
+           if( n < X.Timer.next || X.Timer.timerId === 0 ){\r
+               X.Timer.timerId && window.clearTimeout( X.Timer.timerId );\r
+               X.Timer.timerId = window.setTimeout( X.Timer._loop, X.Timer.INTERVAL_TIME * n );\r
+               X.Timer.endTime = X.getTime() + X.Timer.INTERVAL_TIME * n; // iOS\r
+               X.Timer.next = n;\r
            };\r
-       };\r
+       },\r
        \r
-       var enterFrame =\r
-                       window.requestAnimationFrame ||\r
-                       window.webkitRequestAnimationFrame ||\r
-                       window.mozRequestAnimationFrame ||\r
-                       window.oRequestAnimationFrame ||\r
-                       window.msRequestAnimationFrame ||\r
-                       0,\r
-               cancelFrame =\r
-                       window.cancelRequestAnimationFrame ||\r
-                       window.webkitCancelAnimationFrame ||\r
-                       window.webkitCancelRequestAnimationFrame ||\r
-                       window.mozCancelRequestAnimationFrame ||\r
-                       window.oCancelRequestAnimationFrame ||\r
-                       window.msCancelRequestAnimationFrame ||\r
-                       0,\r
-               REQUEST_FRAME_LIST = [],\r
-               requestID;\r
-       \r
-       function onEnterFrame( time ){\r
-               var list = REQUEST_FRAME_LIST,\r
+       _onEnterFrame : function ( time ){\r
+               var list = X.Timer.REQUEST_FRAME_LIST,\r
                        i    = list.length,\r
                        f;\r
                time = time || ( Date.now ? Date.now() : +new Date );\r
            for( ; i; ){\r
                ( f = list[ --i ] )( time );\r
                delete f.uid;\r
-               f.kill();\r
+               f.kill && f.kill();\r
            };\r
            list.length = 0;\r
-       };\r
+       },\r
        \r
-       return {\r
-               add : function( time, opt_count, args1, args2, args3 ){\r
-                       time = time < INTERVAL_TIME ? 1 : ( time / INTERVAL_TIME ) | 0; // 正の数で使える「Math.floor(x)」を「(x | 0)」に;\r
+       add : function( time, opt_count, args1, args2, args3 ){\r
+               var list = X.Timer.TICKET_LIST;\r
+               time = time < X.Timer.INTERVAL_TIME ? 1 : ( time / X.Timer.INTERVAL_TIME ) | 0; // 正の数で使える「Math.floor(x)」を「(x | 0)」に;\r
 \r
-                       if( typeof opt_count !== 'number' ){\r
-                               args3 = args2;\r
-                               args2 = args1;\r
-                               args1 = opt_count;\r
-                               opt_count = 0;\r
-                       };\r
+               if( typeof opt_count !== 'number' ){\r
+                       args3 = args2;\r
+                       args2 = args1;\r
+                       args1 = opt_count;\r
+                       opt_count = 0;\r
+               };\r
 \r
-                       TICKET_LIST[ TICKET_LIST.length ] = [ time, time, opt_count, X.Callback.create( args1, args2, args3 ), ++uid ];\r
-                   update();\r
-                   return uid;\r
-               },\r
-               once : function( time, args1, args2, args3 ){\r
-                       X.Timer.add( time, 1, args1, args2, args3 );\r
-               },\r
-               remove : function( uid ){\r
-                       var queue,\r
-                               list = TICKET_LIST,\r
-                               i    = list.length,\r
-                               l    = i;\r
+               list[ list.length ] = {\r
+                       t : time,\r
+                       l : time,\r
+                       c : opt_count,\r
+                       f : X.Callback.create( args1, args2, args3 ),\r
+                       u : ++X.Timer.uid\r
+               };\r
+           X.Timer._update();\r
+           return X.Timer.uid;\r
+       },\r
+       once : function( time, args1, args2, args3 ){\r
+               return X.Timer.add( time, 1, args1, args2, args3 );\r
+       },\r
+       remove : function( uid ){\r
+               var list = X.Timer.TICKET_LIST,\r
+                       i    = list.length,\r
+                       l    = i,\r
+                       f, q;\r
+               for( ; i; ){\r
+                       // TODO\r
+                       // fire 中の cancel\r
+                       if( ( q = list[ --i ] ).u === uid ){\r
+                               list.splice( i, 1 );\r
+                               f = q.f;\r
+                               f.kill && f.kill();\r
+                               ( /* q[ INDEX_COUNT ] <= next  || */ l === 1 ) && X.Timer._update();\r
+                               //q.length = 0;\r
+                               break;\r
+                       };\r
+               };\r
+       },\r
+       \r
+       requestFrame : _enterFrame ?\r
+               (function( args1, args2, args3 ){\r
+                       var i = X.Timer.REQUEST_FRAME_LIST.length,\r
+                               f;\r
+                       i === 0 && ( X.Timer.requestID = _enterFrame( X.Timer._onEnterFrame ) );\r
+                       f = X.Timer.REQUEST_FRAME_LIST[ i ] = X.Callback.create( args1, args2, args3 );\r
+                       return f.uid = ++X.Timer.uid;\r
+               }) :\r
+               (function( args1, args2, args3 ){\r
+                       var i = X.Timer.REQUEST_FRAME_LIST.length,\r
+                               f;\r
+                       i === 0 && ( X.Timer.requestID = X.Timer.add( 0, 1, X.Timer._onEnterFrame ) );\r
+                       f = X.Timer.REQUEST_FRAME_LIST[ i ] = X.Callback.create( args1, args2, args3 );\r
+                       return f.uid = ++X.Timer.uid;\r
+               }),\r
+       \r
+       cancelFrame : _cancelFrame ?\r
+               (function( uid ){\r
+                       var list = X.Timer.REQUEST_FRAME_LIST,\r
+                               l    = list.length,\r
+                               i    = l,\r
+                               f;\r
                        for( ; i; ){\r
-                               if( ( queue = list[ --i ] )[ INDEX_UID ] === uid ){\r
+                               if( ( f = list[ --i ] ).uid < uid ) break;\r
+                               if( f.uid === uid ){\r
+                                       // TODO\r
+                                       // fire 中の cancel\r
                                        list.splice( i, 1 );\r
-                                       X.Callback._correct( queue[ INDEX_CALLBACK ] );\r
-                                       ( /* queue[ INDEX_COUNT ] <= next  || */ l === 1 ) && update();\r
-                                       queue.length = 0;\r
+                                       delete f.uid;\r
+                                       f.kill && f.kill();\r
+                                       l === 1 && _cancelFrame( X.Timer.requestID );\r
                                        break;\r
                                };\r
                        };\r
-               }\r
-               \r
-               // string only ie4-\r
-               ,_loop : X.UA.IE && X.UA.IE < 5 && (function(){\r
-                       var _loop = loop;\r
-                       loop = 'X.Timer._loop()';\r
-                       return _loop;\r
-               })()\r
-               \r
-               ,requestFrame : function( args1, args2, args3 ){\r
-                       var i = REQUEST_FRAME_LIST.length,\r
-                               f;\r
-                       i === 0 && ( requestID = ( enterFrame ? enterFrame( onEnterFrame ) : X.Timer.add( 16, 1, onEnterFrame ) ) );\r
-                       f = REQUEST_FRAME_LIST[ i ] = X.Callback.create( args1, args2, args3 );\r
-                       return f.uid = ++uid;\r
-               },\r
-               cancelFrame : function( uid ){\r
-                       var list = REQUEST_FRAME_LIST,\r
-                               i    = list.length,\r
-                               l    = i,\r
+               }) :\r
+               (function( uid ){\r
+                       var list = X.Timer.REQUEST_FRAME_LIST,\r
+                               l    = list.length,\r
+                               i    = l,\r
                                f;\r
                        for( ; i; ){\r
                                if( ( f = list[ --i ] ).uid < uid ) break;\r
                                if( f.uid === uid ){\r
                                        list.splice( i, 1 );\r
                                        delete f.uid;\r
-                                       X.Callback._correct( f );\r
-                                       l === 1 && cancelFrame ? cancelFrame( requestID ) : X.Timer.remove( requestID );\r
-                                       break;                                  \r
+                                       f.kill && f.kill();\r
+                                       l === 1 && X.Timer.remove( X.Timer.requestID );\r
+                                       break;\r
                                };\r
                        };\r
-               }\r
-       };\r
-})();
\ No newline at end of file
+               })\r
+       \r
+};\r
+\r
+// http://havelog.ayumusato.com/develop/javascript/e528-ios6_scrolling_timer_notcall.html\r
+// iOS6 スクロール中のタイマー発火絡みのバグ備忘\r
+if( X.UA.iOS ){\r
+        window.addEventListener( 'scroll', function(){\r
+               if( X.Timer.timerId ){\r
+                       X.Timer.clearTimeout( X.Timer.timerId );\r
+                       X.Timer.timerId = window.setTimeout( X.Timer._loop, Math.max( 0, X.Timer.endTime - X.getTime() ) );\r
+               };\r
+        } );\r
+};\r
+\r
+if( X.UA.IE && X.UA.IE < 5 ){\r
+       X.Timer[ '_ie4_loop' ] = X.Timer._loop;\r
+       X.Timer._loop = 'X.Timer._ie4_loop()';\r
+};\r