2 // ------------------------------------------------------------------------- //
\r
3 // ------------ local variables -------------------------------------------- //
\r
4 // ------------------------------------------------------------------------- //
\r
6 var XCallback_USE_CLOSURE = false,
\r
8 XCallback_LIVE_LIST = [],
\r
9 XCallback_POOL_LIST = [],
\r
11 XCallback_THIS_FUNC = 1,
\r
12 XCallback_HANDLEEVENT = 2,
\r
13 XCallback_FUNC_ONLY = 3;
\r
17 * handleEvent という関数のメンバーを持つオブジェクト
\r
18 * @typedef {{ handleEvent : function }}
\r
23 * コールバックに thisObject や、追加の引数を設定するための情報を収めたハッシュ
\r
24 * @typedef {{ k : number, f : (function|undefined), x : (listener|undefined), s : (Array|undefined) }}
\r
30 * @typedef {funciton}
\r
38 STOP_PROPAGATION : 2, // 上位階層への伝播のキャンセル
\r
39 STOP_NOW : 4 | 2, // 同一階層のリスナーのキャンセル(上位へもキャンセル)
\r
40 PREVENT_DEFAULT : 8, // 結果動作のキャンセル,
\r
41 MONOPOLY : 16, // move event を独占する
\r
42 SYS_CANCEL : 32 | 4 | 2,
\r
44 _USE_CLOSURE : false,
\r
53 create : function( arg1, arg2, arg3 /* [ listener || ( context + function ) || function ][ args... ] */ ){
\r
54 var live = X.Callback._LIVE_LIST,
\r
55 hash = X.Callback._classifyCallbackArgs( arg1, arg2, arg3 ),
\r
58 if( !hash.k ) return hash;
\r
60 f = X.Callback._POOL_LIST.pop();
\r
62 f = new Function( 'var a=arguments,f=a.callee;f.a=a;return f._(f)' ); // f.x=this;
\r
63 f[ 'kill' ] = X.Callback._kill;
\r
64 f[ 'same' ] = X.Callback._same;
\r
65 f._ = X.Callback._proxyCallback;
\r
68 live[ live.length ] = f;
\r
70 switch( f.k = hash.k ){
\r
71 case X.Callback._THIS_FUNC :
\r
75 case X.Callback._HANDLEEVENT :
\r
78 case X.Callback._FUNC_ONLY :
\r
83 if( hash.s ) f.s = hash.s;
\r
87 _createClosure : function( obj ){
\r
90 return obj._( obj );
\r
94 _classifyCallbackArgs : function( arg1, arg2, arg3, alt_context ){
\r
97 if( arg1 && X.Type.isFunction( arg2 ) ){
\r
98 obj = { x : arg1, f : arg2, k : X.Callback._THIS_FUNC };
\r
100 if( arg1 && X.Type.isFunction( arg1[ 'handleEvent' ] ) ){
\r
101 obj = { x : arg1, k : X.Callback._HANDLEEVENT };
\r
104 if( X.Type.isFunction( arg1 ) ){
\r
107 obj = { x : alt_context, f : arg1, k : X.Callback._THIS_FUNC };
\r
109 obj = { f : arg1, k : X.Callback._FUNC_ONLY };
\r
112 if( X.Type.isFunction( arg2 ) ){
\r
113 //console.log( 'X.Callback._classifyCallbackArgs : arg1 が ' + arg1 + 'です' ); ie4 で error
\r
115 obj = { x : alt_context, f : arg2, k : X.Callback._THIS_FUNC };
\r
117 obj = { f : arg2, k : X.Callback._FUNC_ONLY };
\r
121 obj = { x : alt_context, k : X.Callback._HANDLEEVENT };
\r
124 console.log( '不正 ' + arg1 );
\r
125 console.dir( arg1 );
\r
129 if( X.Type.isArray( arg3 )){
\r
132 return ( obj.x || obj.s ) ? obj : arg1;
\r
135 _proxyCallback : function( xfunc ){
\r
136 var args = xfunc.a || [],
\r
144 if( supp && supp.length ){
\r
148 args.length === 1 ?
\r
149 ( temp[ 0 ] = args[ 0 ] ) :
\r
150 temp.push.apply( temp, args )
\r
152 supp.length === 1 ?
\r
153 ( temp[ temp.length ] = supp[ 0 ] ) :
\r
154 temp.push.apply( temp, supp );
\r
160 case X.Callback._THIS_FUNC :
\r
161 return args.length === 0 ? func.call( thisObj ) : func.apply( thisObj, args );
\r
163 case X.Callback._HANDLEEVENT :
\r
164 temp = thisObj[ 'handleEvent' ];
\r
165 if( X.Type.isFunction( temp ) ){
\r
166 return args.length === 0 ? thisObj[ 'handleEvent' ]() :
\r
167 args.length === 1 ? thisObj[ 'handleEvent' ]( args[ 0 ] ) : temp.apply( thisObj, args );
\r
171 if( temp !== func && X.Type.isFunction( temp ) ){
\r
172 return args.length === 0 ? thisObj[ 'handleEvent' ]() : temp.apply( thisObj, args );
\r
174 if( X.Type.isFunction( thisObj ) ){
\r
175 return args.length === 0 ? thisObj.call( thisObj ) : thisObj.apply( thisObj, args );
\r
177 return args.length === 0 ? func.call( thisObj ) : func.apply( thisObj, args );*/
\r
179 case X.Callback._FUNC_ONLY :
\r
180 return args.length === 0 ?
\r
182 args.length === 1 ?
\r
183 func( args[ 0 ] ) :
\r
184 func.apply( null, args );
\r
186 return X.Callback.NONE;
\r
189 _kill : function(){
\r
190 X.Callback._correct( this );
\r
192 _same : function( arg1, arg2, arg3 ){
\r
195 if( arg1 && arg1[ 'kill' ] === X.Callback._kill ) return this === arg1;
\r
197 hash = X.Callback._classifyCallbackArgs( arg1, arg2, arg3 );
\r
199 return hash && this.k === hash.k && this.x === hash.x && this.f === hash.f && this.s === hash.s;
\r
201 _correct : function( f ){
\r
202 var i = X.Callback._LIVE_LIST.indexOf( f );
\r
205 if( f.x ) delete f.x;
\r
206 if( f.f ) delete f.f;
\r
207 if( f.s ) delete f.s;
\r
208 if( i === -1 ) return;
\r
209 X.Callback._LIVE_LIST.splice( i, 1 );
\r
210 X.Callback._POOL_LIST.push( f );
\r
213 sys_monitor : function(){
\r
215 'Live callback' : X.Callback._LIVE_LIST.length,
\r
216 'Pool callback' : X.Callback._POOL_LIST.length
\r
219 sys_gc : function(){
\r
220 var list = X.Callback._POOL_LIST,
\r
222 while( 0 < list.length ){
\r
224 X.Callback._correct( f );
\r
226 delete f[ 'kill' ];
\r
227 delete f[ 'same' ];
\r
232 // ------------------------------------------------------------------------- //
\r
233 // --- implements ---------------------------------------------------------- //
\r
234 // ------------------------------------------------------------------------- //
\r
240 console.log( 'X.Core.Callback' );
\r