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
43 NONE : X_Callback_NONE,
\r
44 UN_LISTEN : X_Callback_UN_LISTEN,
\r
45 STOP_PROPAGATION : X_Callback_STOP_PROPAGATION,
\r
46 STOP_NOW : X_Callback_STOP_NOW,
\r
47 PREVENT_DEFAULT : X_Callback_PREVENT_DEFAULT,
\r
48 MONOPOLY : X_Callback_MONOPOLY,
\r
50 create : X_Callback_create,
\r
52 sys_monitor : function(){
\r
54 'Live callback' : X_Callback_LIVE_LIST.length,
\r
55 'Pool callback' : X_Callback_POOL_LIST.length
\r
59 sys_gc : function(){
\r
60 var list = X_Callback_POOL_LIST,
\r
62 while( 0 < list.length ){
\r
64 X_Callback_correct( f );
\r
71 X_TEMP.onSystemReady.push( X_Callback_handleSystemEvent );
\r
73 // ------------------------------------------------------------------------- //
\r
74 // --- implements ---------------------------------------------------------- //
\r
75 // ------------------------------------------------------------------------- //
\r
77 function X_Callback_handleSystemEvent( e ){
\r
83 function X_Callback_create( thisObject, opt_callback, opt_args /* [ listener || ( context + function ) || function ][ args... ] */ ){
\r
84 var obj = X_Callback_classifyCallbackArgs( thisObject, opt_callback, opt_args ),
\r
86 if( !obj.k ) return obj;
\r
87 if( l = X_Callback_POOL_LIST.length ){
\r
88 ret = X_Callback_POOL_LIST[ l - 1 ]; --X_Callback_POOL_LIST.length; // ret = X_Callback_POOL_LIST.pop();
\r
89 _obj = ret( X_Closure_COMMAND_BACK );
\r
95 ret = X_Closure_actualClosure( obj );
\r
96 ret.kill = X_Callback_kill;
\r
97 ret.same = X_Callback_same;
\r
99 X_Callback_LIVE_LIST[ X_Callback_LIVE_LIST.length ] = ret;
\r
103 function X_Closure_actualClosure( obj ){
\r
105 if( arguments[ 0 ] === X_Closure_COMMAND_BACK ) return obj;
\r
106 if( arguments[ 0 ] !== X_Closure_COMMAND_DROP ) return X_Callback_proxyCallback( obj, arguments );
\r
110 function X_Callback_classifyCallbackArgs( arg1, arg2, arg3, alt_context ){
\r
113 if( arg1 && X.Type.isFunction( arg2 ) ){
\r
114 obj = { x : arg1, f : arg2, k : X_Callback_THIS_FUNC };
\r
116 if( arg1 && X.Type.isFunction( arg1[ 'handleEvent' ] ) ){
\r
117 obj = { x : arg1, k : X_Callback_HANDLEEVENT };
\r
120 if( X.Type.isFunction( arg1 ) ){
\r
123 obj = { x : alt_context, f : arg1, k : X_Callback_THIS_FUNC };
\r
125 obj = { f : arg1, k : X_Callback_FUNC_ONLY };
\r
128 if( X.Type.isFunction( arg2 ) ){
\r
129 //console.log( 'X_Callback_classifyCallbackArgs : arg1 が ' + arg1 + 'です' ); ie4 で error
\r
131 obj = { x : alt_context, f : arg2, k : X_Callback_THIS_FUNC };
\r
133 obj = { f : arg2, k : X_Callback_FUNC_ONLY };
\r
137 obj = { x : alt_context, k : X_Callback_HANDLEEVENT };
\r
140 console.log( '不正 ' + arg1 );
\r
141 console.dir( arg1 );
\r
145 if( X.Type.isArray( arg3 )){
\r
148 return ( obj.x || obj.s ) ? obj : arg1;
\r
151 function X_Callback_proxyCallback( xfunc, _args ){
\r
152 var args = _args || [],
\r
158 if( supp && supp.length ){
\r
162 args.length === 1 ?
\r
163 ( temp[ 0 ] = args[ 0 ] ) :
\r
164 temp.push.apply( temp, args )
\r
166 supp.length === 1 ?
\r
167 ( temp[ temp.length ] = supp[ 0 ] ) :
\r
168 temp.push.apply( temp, supp );
\r
174 case X_Callback_THIS_FUNC :
\r
175 return args.length === 0 ? func.call( thisObj ) : func.apply( thisObj, args );
\r
177 case X_Callback_HANDLEEVENT :
\r
178 temp = thisObj[ 'handleEvent' ];
\r
179 if( X.Type.isFunction( temp ) ){
\r
180 return args.length === 0 ? thisObj[ 'handleEvent' ]() :
\r
181 args.length === 1 ? thisObj[ 'handleEvent' ]( args[ 0 ] ) : temp.apply( thisObj, args );
\r
185 if( temp !== func && X.Type.isFunction( temp ) ){
\r
186 return args.length === 0 ? thisObj[ 'handleEvent' ]() : temp.apply( thisObj, args );
\r
188 if( X.Type.isFunction( thisObj ) ){
\r
189 return args.length === 0 ? thisObj.call( thisObj ) : thisObj.apply( thisObj, args );
\r
191 return args.length === 0 ? func.call( thisObj ) : func.apply( thisObj, args );*/
\r
193 case X_Callback_FUNC_ONLY :
\r
194 return args.length === 0 ?
\r
196 args.length === 1 ?
\r
197 func( args[ 0 ] ) :
\r
198 func.apply( null, args );
\r
200 return X_Callback_NONE;
\r
203 function X_Callback_same( arg1, arg2, arg3 ){
\r
206 if( arg1 && arg1[ 'kill' ] === X_Callback_kill ) return this === arg1;
\r
208 hash = X_Callback_classifyCallbackArgs( arg1, arg2, arg3 );
\r
210 return hash && this.k === hash.k && this.x === hash.x && this.f === hash.f && this.s === hash.s;
\r
213 function X_Callback_kill(){
\r
214 X_Callback_correct( this );
\r
217 function X_Callback_correct( f ){
\r
218 var i = X_Callback_LIVE_LIST.indexOf( f ),
\r
221 X_Callback_LIVE_LIST.splice( i, 1 );
\r
222 X_Callback_POOL_LIST[ X_Callback_POOL_LIST.length ] = f;
\r
223 obj = f( X_Closure_COMMAND_BACK );
\r
225 if( obj.f ) delete obj.f;
\r
226 if( obj.x ) delete obj.x;
\r
227 if( obj.s ) delete obj.s;
\r
236 console.log( 'X.Core.Callback' );
\r