OSDN Git Service

Version 0.6.42, bugfix for tree update event.
[pettanr/clientJs.git] / 0.6.x / js / core / 03_XCallback.js
1 \r
2 \r
3 X.Callback = {\r
4         \r
5         NONE             :  0,\r
6         UN_LISTEN        :  1,\r
7         STOP_PROPAGATION :  2,  // 上位階層への伝播のキャンセル\r
8         STOP_NOW         :  4 | 2,  // 同一階層のリスナーのキャンセル(上位へもキャンセル)\r
9         PREVENT_DEFAULT  :  8,  // 結果動作のキャンセル,\r
10         MONOPOLY         : 16,  // move event を独占する\r
11         SYS_CANCEL       : 32 | 4 | 2,\r
12         \r
13         _LIVE_LIST       : [],\r
14         _POOL_LIST       : [],\r
15         \r
16         create : function( arg0, arg1, arg2 /* [ listener || ( context + function ) || function ][ args... ] */ ){\r
17                 var self  = X.Callback,\r
18                         live  = self._LIVE_LIST,\r
19                         f, listener, context, callback;\r
20                 \r
21                 if( typeof arg1 === 'function' ){\r
22                         context  = arg0;\r
23                         callback = arg1;\r
24                 } else\r
25                 if( typeof arg0 === 'function' ){\r
26                         callback = arg0;\r
27                         if( !( arg2 = arg1 ) ) return callback; // function のみの場合 callback オブジェクトを作らない\r
28                 } else\r
29                 if( arg0 && typeof arg0.handleEvent === 'function' ){\r
30                         listener = arg0;\r
31                         arg2     = arg1;\r
32                 } else {\r
33                         var v = '';\r
34                         for( var k in  arg0 ){\r
35                                 v += k + '=' + arg0[ k ] + ' ';\r
36                         };\r
37                         alert( 'Callback.create() fail! ' + v );\r
38                 };\r
39                 \r
40                 f = self._POOL_LIST.pop();\r
41                 if( !f ){\r
42                         f = new Function( 'var a=arguments,f=a.callee;f.a=a;return f.c()' ); // f.t=this;\r
43                         f.kill = self._kill;\r
44                         f.same = self._same;\r
45                 };\r
46                 live[ live.length ] = f;\r
47                 if( listener ){\r
48                         f.c        = self._contextCallback;\r
49                         f.listener = listener;\r
50                         f.context  = listener;\r
51                         f.callback = listener.handleEvent;\r
52                 } else\r
53                 if( context ){\r
54                         f.c        = self._contextCallback;\r
55                         f.context  = context;\r
56                         f.callback = callback;\r
57                 } else {\r
58                         f.c        = self._generalCallback;\r
59                         f.callback = callback;\r
60                 };\r
61 \r
62                 if( X.Type.isArray( arg2 ) ){\r
63                         f.add = arg2;\r
64                 };\r
65                 return f;\r
66         },\r
67         \r
68         _contextCallback : function(){\r
69                 var f = this,\r
70                         a = f.a,\r
71                         s = f.add,\r
72                         c = f.callback,\r
73                         x = f.context,\r
74                         i = 0,\r
75                         ary, r;\r
76                 //s && s.push.apply( a, s );\r
77                 if( s && s.length ){\r
78                         ary = [];\r
79                         a.length &&\r
80                                 (\r
81                                         a.length === 1 ?\r
82                                                 ( ary[ 0 ] = a[ 0 ] ) :\r
83                                                 ary.push.apply( ary, a )\r
84                                 );\r
85                         s.length === 1 ?\r
86                                 ( ary[ ary.length ] = s[ 0 ] ) :\r
87                                 ary.push.apply( ary, s );\r
88                         a = ary;\r
89                 };\r
90                 r = a.length === 0 ? c.call( x ) : c.apply( x, a );\r
91                 delete f.a;\r
92                 //delete f.t;\r
93                 return r;\r
94         },\r
95         _generalCallback : function(){\r
96                 var f = this,\r
97                         a = f.a,\r
98                         s = f.add,\r
99                         c = f.callback,\r
100                         i = 0,\r
101                         ary, r;\r
102                 //s && s.push.apply( a, s );\r
103                 if( s && s.length ){\r
104                         ary = [];\r
105                         a.length &&\r
106                                 (\r
107                                         a.length === 1 ?\r
108                                                 ( ary[ 0 ] = a[ 0 ] ) :\r
109                                                 ary.push.apply( ary, a )\r
110                                 );\r
111                         s.length === 1 ?\r
112                                 ( ary[ ary.length ] = s[ 0 ] ) :\r
113                                 ary.push.apply( ary, s );\r
114                         a = ary;\r
115                 };\r
116                 r = a.length === 0 ?\r
117                                 c() :\r
118                         a.length === 1 ?\r
119                                 c( a[ 0 ] ) :\r
120                                 c.apply( null, a );\r
121                 delete f.a;\r
122                 //delete f.t;\r
123                 return r;\r
124         },\r
125         _kill : function(){\r
126                 X.Callback._correct( this );\r
127         },\r
128         _same : function( arg0, arg1, arg2 ){\r
129                 var listener, context, callback,\r
130                         f = this;\r
131                         \r
132                 if( arg0.kill === X.Callback._kill ){ // arg0 === X.Callback toString() で判定は?\r
133                         return this === arg0;\r
134                 } else\r
135                 if( typeof arg1 === 'function' ){\r
136                         context  = arg0;\r
137                         callback = arg1;\r
138                 } else\r
139                 if( typeof arg0 === 'function' ){\r
140                         callback = arg0;\r
141                         arg2     = arg1;\r
142                 } else\r
143                 if( arg0 && typeof arg0.handleEvent === 'function' ){\r
144                         listener = arg0;\r
145                         arg2     = arg1;\r
146                 };\r
147                 \r
148                 if( arg2 && f.add !== arg2 ){\r
149                         return false;\r
150                 };\r
151                 \r
152                 if( listener && f.listener === listener ){\r
153                         return true;\r
154                 } else\r
155                 if( context && f.context === context && f.callback === callback ){\r
156                         return true;\r
157                 } else          \r
158                 if( f.callback === callback ){\r
159                         return true;\r
160                 };\r
161                 return false;\r
162         },\r
163         _correct : function( f ){\r
164                 var self = X.Callback,\r
165                         i    = self._LIVE_LIST.indexOf( f );\r
166                 if( f.c ) delete f.c;\r
167                 if( f.listener ) delete f.listener;\r
168                 if( f.context  ) delete f.context;\r
169                 if( f.callback ) delete f.callback;\r
170                 if( f.add      ) delete f.add;\r
171                 if( i === -1 ) return;\r
172                 self._LIVE_LIST.splice( i, 1 );\r
173                 self._POOL_LIST.push( f );\r
174         },\r
175         sys_monitor : function(){\r
176                 return {\r
177                         'Live callback' : X.Callback._LIVE_LIST.length,\r
178                         'Pool callback' : X.Callback._POOL_LIST.length\r
179                 };\r
180         },\r
181         sys_gc : function(){\r
182                 var self = X.Callback,\r
183                         list = self._POOL_LIST, f;\r
184                 while( 0 < list.length ){\r
185                         f = list.shift();\r
186                         self._correct( f );\r
187                         delete f.kill;\r
188                         delete f.same;\r
189                 };\r
190         }\r
191 };\r