OSDN Git Service

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