OSDN Git Service

Version 0.6.3
[pettanr/clientJs.git] / 0.6.x / js / core / 06_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         var clearTimeout   = window.clearTimeout;\r
8         var INTERVAL_TIME  = 16;\r
9         var TICKET_LIST    = [];\r
10         var timerId        = -1;\r
11         var next           = 0;\r
12         /* const */\r
13         var INDEX_TIME     = 0,\r
14                 INDEX_LAST     = 1,\r
15                 INDEX_COUNT    = 2,\r
16                 INDEX_CALLBACK = 3;\r
17         \r
18         function loop(){\r
19                 var i    = 0,\r
20                         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 === false || ret === X.Cancel.UN_LISTEN || c === 1 ){\r
31                                 list.splice( i, 1 );\r
32                                 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                         i    = list.length,\r
45                         n    = 99999999,\r
46                         last;\r
47                 if( i === 0 ){\r
48                         timerId !== -1 && clearTimeout( timerId );\r
49                         timerId = -1;\r
50                         return;\r
51                 };\r
52             for( ; i; ){\r
53                 last = list[ --i ][ INDEX_LAST ];\r
54                 if( last < n ) n = last;\r
55             };\r
56             if( n < next || timerId === -1 ){\r
57                 timerId !== -1 && clearTimeout( timerId );\r
58                 timerId = setTimeout( loop, INTERVAL_TIME * n );\r
59                 next = n;\r
60             };\r
61         };\r
62         \r
63         return {\r
64                 add : function( time, opt_count, args1, args2, args3 ){\r
65                         time = time < INTERVAL_TIME ? 1 : ( time / INTERVAL_TIME ) | 0; // 正の数で使える「Math.floor(x)」を「(x | 0)」に;\r
66 \r
67                         if( typeof opt_count !== 'number' ){\r
68                                 args3 = args2;\r
69                                 args2 = args1;\r
70                                 args1 = opt_count;\r
71                                 opt_count = 0;\r
72                         };\r
73 \r
74                         TICKET_LIST[ TICKET_LIST.length ] = [ time, time, opt_count, X.Callback.create( args1, args2, args3 ) ];\r
75                     update();\r
76                 },\r
77                 once : function( time, args1, args2, args3 ){\r
78                         X.Timer.add( time, 1, args1, args2, args3 );\r
79                 },\r
80                 remove : function( args1, args2 ){\r
81                         var queue,\r
82                                 i    = 0,\r
83                                 list = TICKET_LIST;\r
84                         if( !callback ) return;\r
85                         while( queue = list[ i ] ){\r
86                                 if( queue[ INDEX_CALLBACK ].same( args1, args2 ) === true ){\r
87                                         callback.kill();\r
88                                         list.splice( i, 1 );\r
89                                         break;\r
90                                 } else {\r
91                                         ++i;\r
92                                 };\r
93                         };\r
94                     update();\r
95                 }\r
96         };\r
97 })();