package snapfit.events { import flash.events.Event; import flash.events.EventDispatcher; import flash.events.IEventDispatcher; import flash.utils.Proxy; import flash.utils.flash_proxy; /** * FAdapter * @author nutsu * @version 0.2 */ dynamic public class FAdapter extends Proxy { private var _dispatcher:IEventDispatcher; private var _listeners:Object; private var _useCapture:Boolean = false; private var _priority:int = 0; private var _useWeakReference:Boolean = false; public function FAdapter( dispatcher_:IEventDispatcher=null ) { _dispatcher = (dispatcher_) ? dispatcher_ : new EventDispatcher(); _listeners = {}; } public function get dispatcher():IEventDispatcher { return _dispatcher; } public function set dispatcher(value:IEventDispatcher):void { abort(); _dispatcher = value; resume(); } public function setDefaultProps( useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false ):void { _useCapture = useCapture; _priority = priority; _useWeakReference = useWeakReference; } public function addEventListener( type:String, handler:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false ):void { this[type] = new $listener( type, handler, useCapture, priority, useWeakReference ); } public function removeEventListener( type:String ):void { delete this[type]; } public function dispatchEvent( e:Event ):Boolean { return _dispatcher.dispatchEvent( e ); } //------------------------------------------------------------------------------------UTIL public static const NOT_EXISTS :int = 0; public static const ACTIVE :int = 1; public static const NOT_ACTIVE :int = 2; public static const NOT_HAS_BUT_ACTIVE :int = -1; public static const HAS_BUT_NOT_ACTIVE :int = -2; public static const HAS_UNKNOWN :int = -10; /** * @param eventType * @return result code. * @see NOT_EXISTS * @see ACTIVE * @see NOT_ACTIVE * @see NOT_HAS_BUT_ACTIVE * @see HAS_BUT_NOT_ACTIVE * @see HAS_UNKNOWN */ public function check( eventType:String ):int { if ( _listeners[eventType] ) if ( _dispatcher.hasEventListener(eventType) ) if ( _listeners[eventType].active ) return ACTIVE; else return HAS_BUT_NOT_ACTIVE; else if( !_listeners[eventType].active ) return NOT_ACTIVE; else return NOT_HAS_BUT_ACTIVE; else if ( _dispatcher.hasEventListener(eventType) ) return HAS_UNKNOWN; else return NOT_EXISTS; } /** * @param eventType default:abort all */ public function abort( eventType:String=null ):void { if ( eventType==null ) { for each ( var obj:$listener in _listeners ) _remove( obj ); } else if( check(eventType)==ACTIVE ) { _remove( _listeners[eventType] ); } } /** * @param eventType default:resume all */ public function resume( eventType:String=null ):void { if ( eventType==null ) { for each ( var obj:$listener in _listeners ) _add( obj ); } else if( check(eventType)==NOT_ACTIVE ) { _add( _listeners[eventType] ); } } /** * @param active_kind 1:active, 0:not active, default:all * @return String[] */ public function getTypes( active_kind:int=-1 ):Array { var res:Array = []; var obj:$listener; if ( active_kind == 1 ) { for each ( obj in _listeners ) if( obj.active ) res.push( obj.type ); } else if ( active_kind == 0 ) { for each ( obj in _listeners ) if( !obj.active ) res.push( obj.type ); } else { for each ( obj in _listeners ) res.push( obj.type ); } return res; } public function removeAll():void { for ( var eventType in _listeners ) delete this[eventType]; } //------------------------------------------------------------------------------------ADD_REMOVE private function _add( lo:$listener ):void { if ( !lo.active ) { _dispatcher.addEventListener( lo._type, lo._handler, lo._useCapture, lo._priority, lo._useWeakReference ); lo._active = true; } } private function _remove( lo:$listener ):void { if ( _dispatcher.hasEventListener( lo._type ) ) { _dispatcher.removeEventListener( lo._type, lo._handler, lo._useCapture ); lo._active = false; } } //------------------------------------------------------------------------------------PROXY override flash_proxy function callProperty(name:*, ... args):* { var err:Boolean = false; if ( args.length == 0 || args.length > 4 ) err = true; if ( !( args[0] is Function ) ) err = true; if ( args.length > 1 && !(args[1] is Boolean ) ) err = true; if ( args.length > 2 && !(args[2] is int ) ) err = true; if ( args.length == 4 && !(args[3] is Boolean ) ) err = true; if( err ) { throw new Error( "usage: eventName(handler:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false)" ); } args.unshift( String(name) ); addEventListener.apply( this, args ); } override flash_proxy function hasProperty(name:*):Boolean { if ( _listeners[name] ) return true; else return false; } override flash_proxy function deleteProperty( name:* ):Boolean { if ( !_listeners[name] ) return false; _remove( _listeners[name] ); return delete _listeners[name]; } override flash_proxy function getProperty( name:* ):* { if ( _listeners[name] ) return _listeners[name]; else return undefined; } override flash_proxy function setProperty( name:*, value:* ):void { if ( value is Function ) { delete this[name]; _listeners[name] = new $listener( name, value, _useCapture, _priority, _useWeakReference ); } else if ( value is $listener ) { delete this[name]; _listeners[name] = new $listener( name, value._handler, value._useCapture, value._priority, value._useWeakReference ); } else if ( value == null || value==undefined ) { delete this[name]; return; } else { throw new TypeError("FAdapter:type error." ); } _add( _listeners[name] ); } } } class $listener { internal var _type:String; internal var _handler:Function; internal var _useCapture:Boolean; internal var _priority:int; internal var _useWeakReference:Boolean; internal var _active:Boolean; public function $listener( type_:String, handler_:Function, useCapture_:Boolean, priority_:int, useWeakReference_:Boolean ) { _type = type_; _handler = handler_; _useCapture = useCapture_; _priority = priority_; _useWeakReference = useWeakReference_; _active = false; } public function get type():String { return _type; } public function get handler():Function { return _handler; } public function get useCapture():Boolean { return _useCapture; } public function get priority():int { return _priority; } public function get useWeakReference():Boolean { return _useWeakReference; } public function get active():Boolean { return _active; } }