OSDN Git Service

Version 0.6.6
[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                 timerId        = -1,\r
11                 next           = 0,\r
12                 INDEX_TIME     = 0,\r
13                 INDEX_LAST     = 1,\r
14                 INDEX_COUNT    = 2,\r
15                 INDEX_CALLBACK = 3;\r
16         \r
17         function loop(){\r
18                 var c    = next,\r
19                         list = TICKET_LIST,\r
20                         i    = list.length,\r
21                         queue, f, ret;\r
22             for( ; i; ){\r
23                 queue = list[ --i ];\r
24                         if( 0 < ( queue[ INDEX_LAST ] -= c ) ) continue;\r
25                         f   = queue[ INDEX_CALLBACK ];\r
26                         c   = queue[ INDEX_COUNT ];\r
27                         ret = f();\r
28                         if( ret === false || ret & X.Callback.UN_LISTEN || c === 1 ){\r
29                                 list.splice( i, 1 );\r
30                                 f.kill();\r
31                                 queue.length = 0;\r
32                                 continue;\r
33                         } else\r
34                         if( 1 < c ) --queue[ INDEX_COUNT ];\r
35                         queue[ INDEX_LAST ] = queue[ INDEX_TIME ];\r
36             };\r
37             timerId = -1;\r
38             update();\r
39         };\r
40         function update(){\r
41                 var list = TICKET_LIST,\r
42                         i    = list.length,\r
43                         n    = 99999999,\r
44                         last;\r
45                 if( i === 0 ){\r
46                         timerId !== -1 && clearTimeout( timerId );\r
47                         timerId = -1;\r
48                         return;\r
49                 };\r
50             for( ; i; ){\r
51                 last = list[ --i ][ INDEX_LAST ];\r
52                 if( last < n ) n = last;\r
53             };\r
54             if( n < next || timerId === -1 ){\r
55                 timerId !== -1 && clearTimeout( timerId );\r
56                 timerId = setTimeout( loop, INTERVAL_TIME * n );\r
57                 next = n;\r
58             };\r
59         };\r
60         \r
61         return {\r
62                 add : function( time, opt_count, args1, args2, args3 ){\r
63                         time = time < INTERVAL_TIME ? 1 : ( time / INTERVAL_TIME ) | 0; // 正の数で使える「Math.floor(x)」を「(x | 0)」に;\r
64 \r
65                         if( typeof opt_count !== 'number' ){\r
66                                 args3 = args2;\r
67                                 args2 = args1;\r
68                                 args1 = opt_count;\r
69                                 opt_count = 0;\r
70                         };\r
71 \r
72                         TICKET_LIST[ TICKET_LIST.length ] = [ time, time, opt_count, X.Callback.create( args1, args2, args3 ) ];\r
73                     update();\r
74                 },\r
75                 once : function( time, args1, args2, args3 ){\r
76                         X.Timer.add( time, 1, args1, args2, args3 );\r
77                 },\r
78                 remove : function( args1, args2 ){\r
79                         var queue,\r
80                                 i    = 0,\r
81                                 list = TICKET_LIST;\r
82                         if( !callback ) return;\r
83                         while( queue = list[ i ] ){\r
84                                 if( queue[ INDEX_CALLBACK ].same( args1, args2 ) === true ){\r
85                                         callback.kill();\r
86                                         list.splice( i, 1 );\r
87                                         break;\r
88                                 } else {\r
89                                         ++i;\r
90                                 };\r
91                         };\r
92                     update();\r
93                 }\r
94         };\r
95 })();