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
65 _obj._ = X_Callback_proxyCallback;
\r
67 ret = X_Closure_actualClosure( obj );
\r
68 obj._ = X_Callback_proxyCallback;
\r
70 X_Callback_LIVE_LIST[ X_Callback_LIVE_LIST.length ] = ret;
\r
75 function X_Callback_classifyCallbackArgs( arg1, arg2, arg3, alt_context ){
\r
78 if( arg1 && X.Type.isFunction( arg2 ) ){
\r
79 obj = { x : arg1, f : arg2, k : X_Callback_THIS_FUNC };
\r
81 if( arg1 && X.Type.isFunction( arg1[ 'handleEvent' ] ) ){
\r
82 obj = { x : arg1, k : X_Callback_HANDLEEVENT };
\r
85 if( X.Type.isFunction( arg1 ) ){
\r
88 obj = { x : alt_context, f : arg1, k : X_Callback_THIS_FUNC };
\r
90 obj = { f : arg1, k : X_Callback_FUNC_ONLY };
\r
93 if( X.Type.isFunction( arg2 ) ){
\r
94 //console.log( 'X_Callback_classifyCallbackArgs : arg1 が ' + arg1 + 'です' ); ie4 で error
\r
96 obj = { x : alt_context, f : arg2, k : X_Callback_THIS_FUNC };
\r
98 obj = { f : arg2, k : X_Callback_FUNC_ONLY };
\r
102 obj = { x : alt_context, k : X_Callback_HANDLEEVENT };
\r
105 console.log( '不正 ' + arg1 );
\r
106 console.dir( arg1 );
\r
110 if( X.Type.isArray( arg3 )){
\r
113 return ( obj.x || obj.s ) ? obj : arg1;
\r
116 function X_Closure_actualClosure( obj ){
\r
118 if( arguments[ 0 ] === X_Closure_COMMAND_BACK ) return obj;
\r
119 if( arguments[ 0 ] !== X_Closure_COMMAND_DROP ) return obj._( obj, arguments );
\r
123 function X_Callback_proxyCallback( xfunc, _args ){
\r
124 var args = _args || [],
\r
130 if( supp && supp.length ){
\r
134 args.length === 1 ?
\r
135 ( temp[ 0 ] = args[ 0 ] ) :
\r
136 temp.push.apply( temp, args )
\r
138 supp.length === 1 ?
\r
139 ( temp[ temp.length ] = supp[ 0 ] ) :
\r
140 temp.push.apply( temp, supp );
\r
146 case X_Callback_THIS_FUNC :
\r
147 return args.length === 0 ? func.call( thisObj ) : func.apply( thisObj, args );
\r
149 case X_Callback_HANDLEEVENT :
\r
150 temp = thisObj[ 'handleEvent' ];
\r
151 if( X.Type.isFunction( temp ) ){
\r
152 return args.length === 0 ? thisObj[ 'handleEvent' ]() :
\r
153 args.length === 1 ? thisObj[ 'handleEvent' ]( args[ 0 ] ) : temp.apply( thisObj, args );
\r
157 if( temp !== func && X.Type.isFunction( temp ) ){
\r
158 return args.length === 0 ? thisObj[ 'handleEvent' ]() : temp.apply( thisObj, args );
\r
160 if( X.Type.isFunction( thisObj ) ){
\r
161 return args.length === 0 ? thisObj.call( thisObj ) : thisObj.apply( thisObj, args );
\r
163 return args.length === 0 ? func.call( thisObj ) : func.apply( thisObj, args );*/
\r
165 case X_Callback_FUNC_ONLY :
\r
166 return args.length === 0 ?
\r
168 args.length === 1 ?
\r
169 func( args[ 0 ] ) :
\r
170 func.apply( null, args );
\r
172 return X_Callback_NONE;
\r
175 function X_Callback_correct( f ){
\r
176 var i = X_Callback_LIVE_LIST.indexOf( f ),
\r
179 X_Callback_LIVE_LIST.splice( i, 1 );
\r
180 X_Callback_POOL_LIST[ X_Callback_POOL_LIST.length ] = f;
\r
181 obj = f( X_Closure_COMMAND_BACK );
\r
183 if( obj.f ) delete obj.f;
\r
184 if( obj.x ) delete obj.x;
\r
185 if( obj.s ) delete obj.s;
\r
194 X_TEMP.X_Callback_onSystemReady = function( sys ){
\r
195 delete X_TEMP.X_Callback_onSystemReady;
\r
196 sys.monitor( X_Callback_monitor );
\r
197 sys.gc( X_Callback_gc );
\r
200 function X_Callback_monitor(){
\r
202 'Callback:Live' : X_Callback_LIVE_LIST.length,
\r
203 'Callback:Pool' : X_Callback_POOL_LIST.length
\r
206 function X_Callback_gc(){
\r
207 X_Callback_POOL_LIST.length = 0; // ?
\r
210 X_TEMP.onSystemReady.push( X_TEMP.X_Callback_onSystemReady );
\r
213 console.log( 'X.Core.Callback' );
\r