OSDN Git Service

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