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 * @typedef {(funciton|{ _ : function, same : function, kill : function, a : (Array|undefined) })}
\r
42 NONE : X_Callback_NONE,
\r
43 UN_LISTEN : X_Callback_UN_LISTEN,
\r
44 STOP_PROPAGATION : X_Callback_STOP_PROPAGATION,
\r
45 STOP_NOW : X_Callback_STOP_NOW,
\r
46 PREVENT_DEFAULT : X_Callback_PREVENT_DEFAULT,
\r
47 MONOPOLY : X_Callback_MONOPOLY
\r
50 // ------------------------------------------------------------------------- //
\r
51 // --- implements ---------------------------------------------------------- //
\r
52 // ------------------------------------------------------------------------- //
\r
54 function X_Callback_create( thisObject, opt_callback, opt_args /* [ listener || ( context + function ) || function ][ args... ] */ ){
\r
55 var obj = X_Callback_classifyCallbackArgs( thisObject, opt_callback, opt_args ),
\r
57 if( !obj.k ) return obj;
\r
58 if( l = X_Callback_POOL_LIST.length ){
\r
59 ret = X_Callback_POOL_LIST[ l - 1 ]; --X_Callback_POOL_LIST.length; // ret = X_Callback_POOL_LIST.pop();
\r
60 _obj = ret( X_Closure_COMMAND_BACK );
\r
66 ret = X_Closure_actualClosure( obj );
\r
68 X_Callback_LIVE_LIST[ X_Callback_LIVE_LIST.length ] = ret;
\r
72 function X_Closure_actualClosure( obj ){
\r
74 if( arguments[ 0 ] === X_Closure_COMMAND_BACK ) return obj;
\r
75 if( arguments[ 0 ] !== X_Closure_COMMAND_DROP ) return X_Callback_proxyCallback( obj, arguments );
\r
79 function X_Callback_classifyCallbackArgs( arg1, arg2, arg3, alt_context ){
\r
82 if( arg1 && X.Type.isFunction( arg2 ) ){
\r
83 obj = { x : arg1, f : arg2, k : X_Callback_THIS_FUNC };
\r
85 if( arg1 && X.Type.isFunction( arg1[ 'handleEvent' ] ) ){
\r
86 obj = { x : arg1, k : X_Callback_HANDLEEVENT };
\r
89 if( X.Type.isFunction( arg1 ) ){
\r
92 obj = { x : alt_context, f : arg1, k : X_Callback_THIS_FUNC };
\r
94 obj = { f : arg1, k : X_Callback_FUNC_ONLY };
\r
97 if( X.Type.isFunction( arg2 ) ){
\r
98 //console.log( 'X_Callback_classifyCallbackArgs : arg1 が ' + arg1 + 'です' ); ie4 で error
\r
100 obj = { x : alt_context, f : arg2, k : X_Callback_THIS_FUNC };
\r
102 obj = { f : arg2, k : X_Callback_FUNC_ONLY };
\r
106 obj = { x : alt_context, k : X_Callback_HANDLEEVENT };
\r
109 console.log( '不正 ' + arg1 );
\r
110 console.dir( arg1 );
\r
114 if( X.Type.isArray( arg3 )){
\r
117 return ( obj.x || obj.s ) ? obj : arg1;
\r
120 function X_Callback_proxyCallback( xfunc, _args ){
\r
121 var args = _args || [],
\r
127 if( supp && supp.length ){
\r
131 args.length === 1 ?
\r
132 ( temp[ 0 ] = args[ 0 ] ) :
\r
133 temp.push.apply( temp, args )
\r
135 supp.length === 1 ?
\r
136 ( temp[ temp.length ] = supp[ 0 ] ) :
\r
137 temp.push.apply( temp, supp );
\r
143 case X_Callback_THIS_FUNC :
\r
144 return args.length === 0 ? func.call( thisObj ) : func.apply( thisObj, args );
\r
146 case X_Callback_HANDLEEVENT :
\r
147 temp = thisObj[ 'handleEvent' ];
\r
148 if( X.Type.isFunction( temp ) ){
\r
149 return args.length === 0 ? thisObj[ 'handleEvent' ]() :
\r
150 args.length === 1 ? thisObj[ 'handleEvent' ]( args[ 0 ] ) : temp.apply( thisObj, args );
\r
154 if( temp !== func && X.Type.isFunction( temp ) ){
\r
155 return args.length === 0 ? thisObj[ 'handleEvent' ]() : temp.apply( thisObj, args );
\r
157 if( X.Type.isFunction( thisObj ) ){
\r
158 return args.length === 0 ? thisObj.call( thisObj ) : thisObj.apply( thisObj, args );
\r
160 return args.length === 0 ? func.call( thisObj ) : func.apply( thisObj, args );*/
\r
162 case X_Callback_FUNC_ONLY :
\r
163 return args.length === 0 ?
\r
165 args.length === 1 ?
\r
166 func( args[ 0 ] ) :
\r
167 func.apply( null, args );
\r
169 return X_Callback_NONE;
\r
172 function X_Callback_correct( f ){
\r
173 var i = X_Callback_LIVE_LIST.indexOf( f ),
\r
176 X_Callback_LIVE_LIST.splice( i, 1 );
\r
177 X_Callback_POOL_LIST[ X_Callback_POOL_LIST.length ] = f;
\r
178 obj = f( X_Closure_COMMAND_BACK );
\r
180 if( obj.f ) delete obj.f;
\r
181 if( obj.x ) delete obj.x;
\r
182 if( obj.s ) delete obj.s;
\r
190 X_TEMP.X_Callback_onSystemReady = function( sys ){
\r
191 delete X_TEMP.X_Callback_onSystemReady;
\r
192 sys.monitor( X_Callback_monitor );
\r
193 sys.gc( X_Callback_gc );
\r
196 function X_Callback_monitor(){
\r
198 'Callback:Live' : X_Callback_LIVE_LIST.length,
\r
199 'Callback:Pool' : X_Callback_POOL_LIST.length
\r
202 function X_Callback_gc(){
\r
203 X_Callback_POOL_LIST.length = 0; // ?
\r
206 X_TEMP.onSystemReady.push( X_TEMP.X_Callback_onSystemReady );
\r
209 console.log( 'X.Core.Callback' );
\r