ActionScript 3 AS3 |的ArrayCollection

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ActionScript 3 AS3 |的ArrayCollection相关的知识,希望对你有一定的参考价值。

package kc.tda {
	import kc.api.ICollection;
	import kc.api.IIterator;
	import kc.events.CollectionEvent;

	import flash.errors.IllegalOperationError;
	import flash.events.EventDispatcher;

	[Event( name="add", type="kc.events.CollectionEvent" )]
	[Event( name="addAll", type="kc.events.CollectionEvent" )]
	[Event( name="clear", type="kc.events.CollectionEvent" )]
	[Event( name="remove", type="kc.events.CollectionEvent" )]
	[Event( name="removeAll", type="kc.events.CollectionEvent" )]
	[Event( name="retain", type="kc.events.CollectionEvent" )]
	
	public class ArrayCollection extends EventDispatcher implements ICollection {
		
		// @const

		public static const DEFAULT_CAPACITY:int 		= 1 << 5;
		public static const DEFAULT_MIN_CAPACITY:int 		= 1 << 4;
		public static const DEFAULT_MAX_CAPACITY:int 		= 1 << 30;	
			
		public static const DEFAULT_LOAD_FACTOR:Number 		= .75;
		public static const DEFAULT_MIN_LOAD_FACTOR:Number 	= 0;		
		public static const DEFAULT_MAX_LOAD_FACTOR:Number 	= 1;
		
		public static const NOT_FOUND:int 			= -1;
		public static const MAX_DISPATCH_EVENTS:int 		= 255;
		
		// @protected
		
		protected var _records:Array;
		protected var _capacity:int;
		protected var _events:Array;
		
		protected var _expandableCapacity:Boolean;
		protected var _loadFactor:Number;
		protected var _maxCapacity:int;
		protected var _enableEvents:int;

		// @Cconstructor

		public function ArrayCollection( capacity:int = undefined, expandableCapacity:Boolean = false, loadFactor:Number = NaN ) {
			
			super(this);
			
			_events = [
				CollectionEvent.ADD,
				CollectionEvent.ADD_ALL,
				CollectionEvent.CLEAR,
				CollectionEvent.REMOVE,
				CollectionEvent.REMOVE_ALL,
				CollectionEvent.RETAIN
			];
					
			_capacity = ResolveLimits ( 
				capacity, 
				DEFAULT_MIN_CAPACITY, 
				DEFAULT_MAX_CAPACITY, 
				DEFAULT_CAPACITY 
			);
			
			this.loadFactor = loadFactor;			
			this.expandableCapacity = expandableCapacity;
			clear();
			
		}
		
		// @override

		override public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void {
			ThrowEventsFilter( type );
			super.addEventListener( type, listener, useCapture, priority, useWeakReference );
		}

		// @properties (rw)
		
		public function get eventsReleased():int {
			return _enableEvents;
		}

		public function get enableEvents():Boolean {
			return ( _enableEvents > NOT_FOUND );
		}
		
		public function set enableEvents( value:Boolean ):void {
			_enableEvents = ( ! value ) 
				? NOT_FOUND 
				: 0;
		}

		public function get expandableCapacity():Boolean {
			return _expandableCapacity;
		}

		public function set expandableCapacity( value:Boolean ):void {
			_expandableCapacity = value;
		}

		public function get loadFactor():Number {
			return _loadFactor;
		}
		
		public function set loadFactor( value:Number ):void {
			_loadFactor = ResolveLimits ( 
				value, 
				DEFAULT_MIN_LOAD_FACTOR, 
				DEFAULT_MAX_LOAD_FACTOR, 
				DEFAULT_LOAD_FACTOR 
			);
		}
		
		// @methods
		
		public function add( value:* ):Boolean {
			
			if( ! ResolveStatus() ) {
				return false;
			}
						
			var quantity:int = size();
			_records.push( value ); 
			
			if( size() != quantity ){
				ResolveDispatchEvent( CollectionEvent.ADD ); 
				return true;
			} return false;
						
		}
		
		public function addAll( value:ICollection ):Boolean {
			
			var i:IIterator = value.iterator();
			var quantity:int = size();
			
			enableEvents = false;
			
			while( i.hasNext() ){
				add( i.next() );
			} 
			
			enableEvents = true;
			
			if( size() != quantity ){
				ResolveDispatchEvent( CollectionEvent.ADD_ALL );
				return true;
			} return false;
						
		}

		public function availableCapacity():int {
			return ( _maxCapacity - size() );
		}

		public function capacity():int {
			return _maxCapacity;
		}

		public function clear():void {
			
			if( _records != null ) {
				ResolveDispatchEvent( CollectionEvent.CLEAR );
			}
			
			_records = new Array();
			_maxCapacity = _capacity;
			
		}

		public function compare( value1:*, value2:* ):int {
			ThrowMethodIsNotAvailable( "compare" );
			return NOT_FOUND;
		}

		public function compareTo( value:* ):int {
			ThrowIsNotCollection( value );	
			if( size() > value.size() ) return 1;
			else if( size() < value.size() ) return -1;
			else return 0;			
		}

		public function contains( value:* ):int {
			return _records.indexOf( value );
		}

		public function containsAll( value:ICollection ):Boolean {
			var i:IIterator = value.iterator();
			while( i.hasNext() ){
				if( contains( i.next() ) == NOT_FOUND ) {
					return false;
				}
			} return true;			 
		}
		
		public function copy():ICollection {
			var collection:ArrayCollection = new ArrayCollection( _capacity, _expandableCapacity, _loadFactor );
			collection.addAll( this );
			return collection;
		}		

		public function equals( value:* ):Boolean {
			return ( this == value );
		}
		
		public function isEmpty():Boolean {
			return ( size() == 0 );
		}
		
		public function iteratorWithCopy():IIterator {
			return new ArrayIterator( toArray() );
		}
		
		public function iterator():IIterator {
			return new ArrayIterator( _records );
		}
		
		public function remove( value:* ):Boolean {
			ThrowIsEmpty();
			var index:int = contains( value );
			if( index != NOT_FOUND ) {
				if( _records.splice( index, 1 ).length ){
					ResolveDispatchEvent( CollectionEvent.REMOVE );
					return true;
				}				
			} return false;
		}
		
		public function removeAll( value:ICollection ):Boolean {
			
			var i:IIterator = value.iterator();
			var quantity:int = size();
			
			enableEvents = false;
			
			while( i.hasNext() ){
				remove( i.next() );
			} 
			
			enableEvents = true;
			
			if( size() != quantity ){
				ResolveDispatchEvent( CollectionEvent.REMOVE_ALL );
				return true;
			} return false;
					
		}
		
		public function retainAll( value:ICollection ):Boolean {
			
			var i:IIterator = iterator();
			var quantity:int = size();
			
			enableEvents = false;
			
			while( i.hasNext() ){
				if( value.contains( i.next() ) == NOT_FOUND ) {
					i.remove();
				}
			} 
			
			enableEvents = true;
			
			if( size() != quantity ){
				ResolveDispatchEvent( CollectionEvent.RETAIN );
				return true;
			} return false;
				
		}
		
		public function size():uint {
			return _records.length;
		}
		
		public function toArray():Array {
			return _records.slice();
		}
		
		public function threshold():int {
			return ( _maxCapacity * _loadFactor );
		}
		
		// @purge
		
		public function purge(...rest):void {
			_records = null;
			_events = null;
			_capacity = undefined;	
			_expandableCapacity = undefined;
			_loadFactor = undefined;
			_maxCapacity = undefined;
			_enableEvents = undefined;
		}
				
		// @helpres
		
		protected function ResolveDispatchEvent( value:String ):void {
			if( ! enableEvents || _enableEvents == MAX_DISPATCH_EVENTS ) {
				enableEvents = false;
				return;
			}else if( dispatchEvent( new CollectionEvent( value ) ) ) {
				_enableEvents++;
			}
		}
		
		protected function ResolveLimits( value:Number, min:Number, max:Number, def:Number = undefined ):Number {
			return Math.min ( max, Math.max ( min, value ) ) || def;
		}
		
		protected function ResolveLimitsAndCapacity( value:Number, min:Number, max:Number, def:Number = undefined ):Number {
			return ResolveCapacity ( 
				ResolveLimits( value, min, max, def ) 
			);
		}
		
		protected function ResolveCapacity( value:int ):int {
			if ( ! ( value > 0 && ( ( value & ( value - 1 ) ) == 0 ) ) ) {
				var capacity:int = 1;
				while( capacity < value ) {
					capacity <<= 1;
				} return capacity;
			} return value;
		}
		
		protected function ResolveStatus():Boolean {
			if( ! _expandableCapacity && availableCapacity() == 0 ) {
				return false;
			} ResolveResize();
			return true;
		}
		
		protected function ResolveResize():void {
			if( _expandableCapacity && size() == threshold() ) {
				_maxCapacity += capacity();
			} 
		}
		
		protected function ThrowIsNotExpandibled( type:String = "collection" ):void {
			if( ! _expandableCapacity ) {
				throw new IllegalOperationError("The \"" + type + "\" is not expandibled.");
			}
		}
		
		protected function ThrowIsNotCollection( value:*, param:String = "value" ):void {
			if( ! value is ICollection ) {
				throw new IllegalOperationError("The \"" + param + "\" is not an ICollection.");
			}
		}
		
		protected function ThrowIsEmpty( type:String = "collection" ):void {
			if ( isEmpty() ) {
				throw new IllegalOperationError( "The " + type + " is empty." );
			}
		}
		
		protected function ThrowMethodIsNotAvailable( value:String, replace:String = null ):void {
			var error:String = "The \"" + value + "\" method is not available.";
			if ( replace != null ) {
				error = error.substr( 0, -1 ) + ", use the \"" + replace + "\" method.";
			} throw new IllegalOperationError( error );			
		}
		
		protected function ThrowEventsFilter( value:String, list:Array = null ):void {
			if( ! enableEvents ){
				throw new IllegalOperationError( "The events are not available." );
			} if( list == null ) {
				list = _events;
			} if( list.indexOf( value ) == NOT_FOUND ) {
				throw new IllegalOperationError( "The event \"" + value + "\" is not available." );	
			}			
		}
		
	}
	
}
   
// @INTERFACES

package kc.api {
	import flash.events.IEventDispatcher;

	public interface ICollection extends IEventDispatcher, IIterable, IComparable, IComparator, IPurger {
		
		// @properties (rw)
		
		function get enableEvents():Boolean;
		function set enableEvents( value:Boolean ):void;
		function get expandableCapacity():Boolean;
		function set expandableCapacity( value:Boolean ):void;
		function get loadFactor():Number;
		function set loadFactor( value:Number ):void;
		
		// @properties (r)
		
		function get eventsReleased():int;
		
		// @methods
		
		function add( value:* ):Boolean;
		function addAll( value:ICollection ):Boolean;
		function availableCapacity():int;
		function capacity():int;
		function clear():void;
		function contains( value:* ):int;
		function containsAll( value:ICollection ):Boolean;
		function copy():ICollection;
		function isEmpty():Boolean;
		function remove( value:* ):Boolean;
		function removeAll( value:ICollection ):Boolean;
		function retainAll( value:ICollection ):Boolean;
		function size():uint;
		function toArray():Array;
		function threshold():int;
			
	}
	
} 

package kc.api {

	public interface IComparable {
		
		// @methods
		
		function compareTo( value:* ):int;
		
	}
	
}

package kc.api {

	public interface IComparator {
		
		// @methods
	
		function compare( value1:*, value2:* ):int;
		function equals( value:* ):Boolean;
		
	}
	
} 

package kc.api {

	public interface IIterable {
	
		// @methods
		
		function iterator():IIterator;
		
	}
	
}

package kc.api {

	public interface IIterator {
	
		// @methods
	
		function hasNext():Boolean;
		function next():*;
		function remove():void;
		function index():int;
		function value():*;
		function size():int;
		
	}
	
}

// @EVENTS

package kc.events {
	import flash.events.Event;

	public class CollectionEvent extends Event {

		// @const
		
		public static const ADD:String = "add";
		public static const ADD_ALL:String = "addAll";
		public static const REMOVE:String = "remove";
		public static const REMOVE_ALL:String = "removeAll";
		public static const RETAIN:String = "retain";
		public static const CLEAR:String = "clear";
		
		// @queue
		
		public static const ENQUEUE:String = "enqueue";
		public static const DEQUEUE:String = "dequeue";
		
		// @stack
		
		public static const PUSH:String = "push";
		public static const POP:String = "pop";
		
		// @history
		
		public static const INDEX_CHANGE:String = "indexChange";
			
		// @constructor
		
		public function CollectionEvent( type:String, bubbles:Boolean=false, cancelable:Boolean=false ) {
			super( type, bubbles, cancelable );
		}
		
		// @override
		
		override public function clone():Event {
			return new CollectionEvent( this.type, this.bubbles, this.cancelable );
		} 
		
		override public function toString():String {
			return this.formatToString( "CollectionEvent", "type", "bubbles", "cancelable", "eventPhase" ); 
		} 
		
	}
	
}

以上是关于ActionScript 3 AS3 |的ArrayCollection的主要内容,如果未能解决你的问题,请参考以下文章

ActionScript 3 通过ActionScript 3(和as3corelib)获取美味的JSON提要

ActionScript 3 AS3 TextField和StyleSheet示例(在ActionScript中创建)

[ActionScript 3.0] AS3.0 水面波纹效果

ActionScript 3 AS3中的模糊滤镜

ActionScript 3 跟踪AS3中的对象

ActionScript 3 AS3:弱引用的听众