2 // ------------------------------------------------------------------------- //
\r
3 // ------------ local variables -------------------------------------------- //
\r
4 // ------------------------------------------------------------------------- //
\r
6 var X_Callback_LIVE_LIST = [],
\r
7 X_Callback_POOL_LIST = [],
\r
8 X_Closure_COMMAND_BACK = X_Callback_LIVE_LIST,
\r
9 X_Closure_COMMAND_DROP = X_Callback_POOL_LIST,
\r
11 X_Callback_THIS_FUNC = 1,
\r
12 X_Callback_HANDLEEVENT = 2,
\r
13 X_Callback_FUNC_ONLY = 3,
\r
15 X_Callback_NONE = 0,
\r
16 X_Callback_UN_LISTEN = 1,
\r
17 X_Callback_STOP_PROPAGATION = 2, // 上位階層への伝播のキャンセル
\r
18 X_Callback_STOP_NOW = 4 | 2, // 同一階層のリスナーのキャンセル(上位へもキャンセル)
\r
19 X_Callback_PREVENT_DEFAULT = 8, // 結果動作のキャンセル,
\r
20 X_Callback_MONOPOLY = 16, // move event を独占する
\r
21 X_Callback_SYS_CANCEL = 32 | 4 | 2;
\r
24 * handleEvent という関数のメンバーを持つオブジェクト
\r
25 * @typedef {{ handleEvent : function }}
\r
30 * コールバックに thisObject や、追加の引数を設定するための情報を収めたハッシュ
\r
31 * @typedef {{ k : number, f : (function|undefined), x : (listener|undefined), s : (Array|undefined) }}
\r
37 NONE : X_Callback_NONE,
\r
38 UN_LISTEN : X_Callback_UN_LISTEN,
\r
39 STOP_PROPAGATION : X_Callback_STOP_PROPAGATION,
\r
40 STOP_NOW : X_Callback_STOP_NOW,
\r
41 PREVENT_DEFAULT : X_Callback_PREVENT_DEFAULT,
\r
42 MONOPOLY : X_Callback_MONOPOLY
\r
45 // ------------------------------------------------------------------------- //
\r
46 // --- implements ---------------------------------------------------------- //
\r
47 // ------------------------------------------------------------------------- //
\r
49 function X_Callback_create( thisObject, opt_callback, opt_args /* [ listener || ( context + function ) || function ][ args... ] */ ){
\r
50 var obj = X_Callback_classifyCallbackArgs( thisObject, opt_callback, opt_args ),
\r
52 if( !obj.k ) return obj;
\r
53 if( l = X_Callback_POOL_LIST.length ){
\r
54 ret = X_Callback_POOL_LIST[ l - 1 ]; --X_Callback_POOL_LIST.length; // ret = X_Callback_POOL_LIST.pop();
\r
55 _obj = ret( X_Closure_COMMAND_BACK );
\r
60 _obj._ = X_Callback_proxyCallback;
\r
62 ret = X_Callback_actualClosure( obj );
\r
63 obj._ = X_Callback_proxyCallback;
\r
65 X_Callback_LIVE_LIST[ X_Callback_LIVE_LIST.length ] = ret;
\r
70 function X_Callback_classifyCallbackArgs( arg1, arg2, arg3, alt_context ){
\r
73 if( arg1 && X.Type.isFunction( arg2 ) ){
\r
74 obj = { x : arg1, f : arg2, k : X_Callback_THIS_FUNC };
\r
76 if( arg1 && X.Type.isFunction( arg1[ 'handleEvent' ] ) ){
\r
77 obj = { x : arg1, k : X_Callback_HANDLEEVENT };
\r
80 if( X.Type.isFunction( arg1 ) ){
\r
83 obj = { x : alt_context, f : arg1, k : X_Callback_THIS_FUNC };
\r
85 obj = { f : arg1, k : X_Callback_FUNC_ONLY };
\r
88 if( X.Type.isFunction( arg2 ) ){
\r
89 //console.log( 'X_Callback_classifyCallbackArgs : arg1 が ' + arg1 + 'です' ); ie4 で error
\r
91 obj = { x : alt_context, f : arg2, k : X_Callback_THIS_FUNC };
\r
93 obj = { f : arg2, k : X_Callback_FUNC_ONLY };
\r
97 obj = { x : alt_context, k : X_Callback_HANDLEEVENT };
\r
100 console.log( '不正 ' + arg1 );
\r
101 console.dir( arg1 );
\r
105 if( X.Type.isArray( arg3 )){
\r
108 return ( obj.x || obj.s ) ? obj : arg1;
\r
111 function X_Callback_actualClosure( obj ){
\r
113 if( arguments[ 0 ] === X_Closure_COMMAND_BACK ) return obj;
\r
114 if( arguments[ 0 ] !== X_Closure_COMMAND_DROP ) return obj._( obj, arguments );
\r
118 function X_Callback_proxyCallback( xfunc, _args ){
\r
119 var args = _args || [],
\r
125 if( supp && supp.length ){
\r
129 args.length === 1 ?
\r
130 ( temp[ 0 ] = args[ 0 ] ) :
\r
131 temp.push.apply( temp, args )
\r
133 supp.length === 1 ?
\r
134 ( temp[ temp.length ] = supp[ 0 ] ) :
\r
135 temp.push.apply( temp, supp );
\r
141 case X_Callback_THIS_FUNC :
\r
142 return args.length === 0 ? func.call( thisObj ) : func.apply( thisObj, args );
\r
144 case X_Callback_HANDLEEVENT :
\r
145 temp = thisObj[ 'handleEvent' ];
\r
146 if( X.Type.isFunction( temp ) ){
\r
147 return args.length === 0 ? thisObj[ 'handleEvent' ]() :
\r
148 args.length === 1 ? thisObj[ 'handleEvent' ]( args[ 0 ] ) : temp.apply( thisObj, args );
\r
152 if( temp !== func && X.Type.isFunction( temp ) ){
\r
153 return args.length === 0 ? thisObj[ 'handleEvent' ]() : temp.apply( thisObj, args );
\r
155 if( X.Type.isFunction( thisObj ) ){
\r
156 return args.length === 0 ? thisObj.call( thisObj ) : thisObj.apply( thisObj, args );
\r
158 return args.length === 0 ? func.call( thisObj ) : func.apply( thisObj, args );*/
\r
160 case X_Callback_FUNC_ONLY :
\r
161 return args.length === 0 ?
\r
163 args.length === 1 ?
\r
164 func( args[ 0 ] ) :
\r
165 func.apply( null, args );
\r
167 return X_Callback_NONE;
\r
170 function X_Callback_correct( f ){
\r
171 var i = X_Callback_LIVE_LIST.indexOf( f ),
\r
174 X_Callback_LIVE_LIST.splice( i, 1 );
\r
175 X_Callback_POOL_LIST[ X_Callback_POOL_LIST.length ] = f;
\r
176 obj = f( X_Closure_COMMAND_BACK );
\r
178 if( obj.f ) delete obj.f;
\r
179 if( obj.x ) delete obj.x;
\r
180 if( obj.s ) delete obj.s;
\r
187 function X_Callback_monitor(){
\r
189 'Callback:Live' : X_Callback_LIVE_LIST.length,
\r
190 'Callback:Pool' : X_Callback_POOL_LIST.length
\r
193 function X_Callback_gc(){
\r
194 X_Callback_POOL_LIST.length = 0; // ?
\r
197 X_TEMP.onSystemReady.push( function( sys ){
\r
198 sys.monitor( X_Callback_monitor );
\r
199 sys.gc( X_Callback_gc );
\r
203 console.log( 'X.Core.Callback' );
\r