OSDN Git Service

Version 0.6.17, X.Dom.Query work a little.
[pettanr/clientJs.git] / 0.6.x / js / core / 05_XTimer.js
1 /**\r
2  * use X.Callback\r
3  */\r
4 \r
5 X.Timer = ( function(){\r
6         var setTimeout     = window.setTimeout,\r
7                 clearTimeout   = window.clearTimeout,\r
8                 INTERVAL_TIME  = 16,\r
9                 TICKET_LIST    = [],\r
10                 uid            = 0,\r
11                 timerId        = -1,\r
12                 next           = 0,\r
13                 INDEX_TIME     = 0,\r
14                 INDEX_LAST     = 1,\r
15                 INDEX_COUNT    = 2,\r
16                 INDEX_CALLBACK = 3,\r
17                 INDEX_UID      = 4;\r
18         \r
19         function loop(){\r
20                 var c    = next,\r
21                         list = TICKET_LIST,\r
22                         i    = list.length,\r
23                         queue, f, ret;\r
24             for( ; i; ){\r
25                 queue = list[ --i ];\r
26                         if( 0 < ( queue[ INDEX_LAST ] -= c ) ) continue;\r
27                         f   = queue[ INDEX_CALLBACK ];\r
28                         c   = queue[ INDEX_COUNT ];\r
29                         ret = f();\r
30                         if( ret & X.Callback.UN_LISTEN || c === 1 ){\r
31                                 list.splice( i, 1 );\r
32                                 f.kill && f.kill();\r
33                                 queue.length = 0;\r
34                                 continue;\r
35                         } else\r
36                         if( 1 < c ) --queue[ INDEX_COUNT ];\r
37                         queue[ INDEX_LAST ] = queue[ INDEX_TIME ];\r
38             };\r
39             timerId = -1;\r
40             update();\r
41         };\r
42         function update(){\r
43                 var list = TICKET_LIST,\r
44                         l    = list.length,\r
45                         n    = 99999999,\r
46                         last;\r
47                 if( l === 0 ){\r
48                         timerId !== -1 && clearTimeout( timerId );\r
49                         timerId = -1;\r
50                         return;\r
51                 };\r
52             for( ; l; ){\r
53                 ( last = list[ --l ][ INDEX_LAST ] ) < n && ( n = last );\r
54             };\r
55             if( n < next || timerId === -1 ){\r
56                 timerId !== -1 && clearTimeout( timerId );\r
57                 timerId = setTimeout( loop, INTERVAL_TIME * n );\r
58                 next = n;\r
59             };\r
60         };\r
61         \r
62         var enterFrame =\r
63                         window.requestAnimationFrame ||\r
64                         window.webkitRequestAnimationFrame ||\r
65                         window.mozRequestAnimationFrame ||\r
66                         window.oRequestAnimationFrame ||\r
67                         window.msRequestAnimationFrame ||\r
68                         0,\r
69                 cancelFrame =\r
70                         window.cancelRequestAnimationFrame ||\r
71                         window.webkitCancelAnimationFrame ||\r
72                         window.webkitCancelRequestAnimationFrame ||\r
73                         window.mozCancelRequestAnimationFrame ||\r
74                         window.oCancelRequestAnimationFrame ||\r
75                         window.msCancelRequestAnimationFrame ||\r
76                         0,\r
77                 REQUEST_FRAME_LIST = [],\r
78                 requestID;\r
79         \r
80         function onEnterFrame( time ){\r
81                 var list = REQUEST_FRAME_LIST,\r
82                         i    = list.length,\r
83                         f;\r
84                 time = time || ( Date.now ? Date.now() : +new Date );\r
85             for( ; i; ){\r
86                 ( f = list[ --i ] )( time );\r
87                 delete f.uid;\r
88                 f.kill && f.kill();\r
89             };\r
90             list.length = 0;\r
91         };\r
92         \r
93         return {\r
94                 add : function( time, opt_count, args1, args2, args3 ){\r
95                         time = time < INTERVAL_TIME ? 1 : ( time / INTERVAL_TIME ) | 0; // 正の数で使える「Math.floor(x)」を「(x | 0)」に;\r
96 \r
97                         if( typeof opt_count !== 'number' ){\r
98                                 args3 = args2;\r
99                                 args2 = args1;\r
100                                 args1 = opt_count;\r
101                                 opt_count = 0;\r
102                         };\r
103 \r
104                         TICKET_LIST[ TICKET_LIST.length ] = [ time, time, opt_count, X.Callback.create( args1, args2, args3 ), ++uid ];\r
105                     update();\r
106                     return uid;\r
107                 },\r
108                 once : function( time, args1, args2, args3 ){\r
109                         return X.Timer.add( time, 1, args1, args2, args3 );\r
110                 },\r
111                 remove : function( uid ){\r
112                         var list = TICKET_LIST,\r
113                                 i    = list.length,\r
114                                 l    = i,\r
115                                 f, q;\r
116                         for( ; i; ){\r
117                                 if( ( q = list[ --i ] )[ INDEX_UID ] === uid ){\r
118                                         list.splice( i, 1 );\r
119                                         f = q[ INDEX_CALLBACK ];\r
120                                         f.kill && f.kill();\r
121                                         ( /* q[ INDEX_COUNT ] <= next  || */ l === 1 ) && update();\r
122                                         q.length = 0;\r
123                                         break;\r
124                                 };\r
125                         };\r
126                 },\r
127                 \r
128                 // string only ie4-\r
129                 _loop : X.UA.IE && X.UA.IE < 5 && (function( r ){\r
130                         loop = 'X.Timer._loop()';\r
131                         return r;\r
132                 })( loop ),\r
133                 \r
134                 requestFrame : function( args1, args2, args3 ){\r
135                         var i = REQUEST_FRAME_LIST.length,\r
136                                 f;\r
137                         i === 0 && ( requestID = ( enterFrame ? enterFrame( onEnterFrame ) : X.Timer.add( 16, 1, onEnterFrame ) ) );\r
138                         f = REQUEST_FRAME_LIST[ i ] = X.Callback.create( args1, args2, args3 );\r
139                         return f.uid = ++uid;\r
140                 },\r
141                 cancelFrame : function( uid ){\r
142                         var list = REQUEST_FRAME_LIST,\r
143                                 l    = list.length,\r
144                                 i    = l,\r
145                                 f;\r
146                         for( ; i; ){\r
147                                 if( ( f = list[ --i ] ).uid < uid ) break;\r
148                                 if( f.uid === uid ){\r
149                                         list.splice( i, 1 );\r
150                                         delete f.uid;\r
151                                         f.kill && f.kill();\r
152                                         l === 1 && ( cancelFrame ? cancelFrame( requestID ) : X.Timer.remove( requestID ) );\r
153                                         break;\r
154                                 };\r
155                         };\r
156                 }\r
157         };\r
158 })();