PageRenderTime 25ms CodeModel.GetById 11ms app.highlight 12ms RepoModel.GetById 0ms app.codeStats 0ms

/src/aerys/minko/type/loader/SceneLoader.as

https://bitbucket.org/HopeSky/mars_nd2d
ActionScript | 208 lines | 165 code | 42 blank | 1 comment | 27 complexity | b1e436a2cacbb53a3e19cca68c94fdbf MD5 | raw file
  1package aerys.minko.type.loader
  2{
  3	import aerys.minko.render.resource.texture.TextureResource;
  4	import aerys.minko.scene.node.AbstractSceneNode;
  5	import aerys.minko.scene.node.Group;
  6	import aerys.minko.scene.node.ISceneNode;
  7	import aerys.minko.type.Signal;
  8	import aerys.minko.type.loader.parser.IParser;
  9	import aerys.minko.type.loader.parser.ParserOptions;
 10	
 11	import flash.events.Event;
 12	import flash.events.ProgressEvent;
 13	import flash.net.URLLoader;
 14	import flash.net.URLLoaderDataFormat;
 15	import flash.net.URLRequest;
 16	import flash.utils.ByteArray;
 17	import flash.utils.getQualifiedClassName;
 18	
 19	public class SceneLoader implements ILoader
 20	{
 21		private static const REGISTERED_PARSERS : Vector.<Class> = new <Class>[];
 22		
 23		private static const STATE_IDLE		: uint = 0;
 24		private static const STATE_LOADING	: uint = 1;
 25		private static const STATE_PARSING	: uint = 2;
 26		private static const STATE_COMPLETE	: uint = 3;
 27		
 28		private var _currentState			: int; 
 29		
 30		private var _progress				: Signal;
 31		private var _complete				: Signal;
 32		private var _error					: Signal;
 33		
 34		private var _data					: ISceneNode;
 35		private var _parser					: IParser;
 36		private var _numDependencies		: uint;
 37		private var _dependencies			: Vector.<ILoader>;
 38		private var _parserOptions			: ParserOptions;
 39		
 40		private var _currentProgress		: Number;
 41		private var _currentProgressChanged : Boolean;
 42		private var _isComplete				: Boolean;
 43		
 44		public function get error() : Signal
 45		{
 46			return _error;
 47		}
 48		
 49		public function get progress() : Signal
 50		{
 51			return _progress;
 52		}
 53		
 54		public function get complete() : Signal
 55		{
 56			return _complete;
 57		}
 58		
 59		public function get isComplete() : Boolean
 60		{
 61			return _isComplete;
 62		}
 63		
 64		public function get data() : ISceneNode
 65		{
 66			return _data;
 67		}
 68		
 69		public static function registerParser(parserClass : Class) : void
 70		{
 71			if (REGISTERED_PARSERS.indexOf(parserClass) != -1)
 72				return;
 73			
 74			if (!(new parserClass(new ParserOptions()) is IParser))
 75				throw new Error('Parsers must implement the IParser interface.');
 76			
 77			REGISTERED_PARSERS.push(parserClass);
 78		}
 79		
 80		public function SceneLoader(parserOptions : ParserOptions = null)
 81		{
 82			_currentState	= STATE_IDLE;
 83			
 84			_progress		= new Signal('SceneLoader.progress');
 85			_complete		= new Signal('SceneLoader.complete');
 86			_data			= null;
 87			_isComplete		= false;
 88			
 89			_parserOptions	= parserOptions || new ParserOptions();
 90		}
 91		
 92		public function load(urlRequest : URLRequest) : void
 93		{
 94			if (_currentState != STATE_IDLE)
 95				throw new Error('This controller is already loading an asset.');
 96			
 97			_currentState = STATE_LOADING;
 98			
 99			var urlLoader : URLLoader = new URLLoader();
100			urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
101			urlLoader.addEventListener(ProgressEvent.PROGRESS, loadProgressHandler);
102			urlLoader.addEventListener(Event.COMPLETE, loadCompleteHandler);
103			urlLoader.load(urlRequest);
104		}
105		
106		private function loadProgressHandler(e : ProgressEvent) : void
107		{
108			_progress.execute(this, 0.5 * e.bytesLoaded / e.bytesTotal);
109		}
110		
111		private function loadCompleteHandler(e : Event) : void
112		{
113			_currentState = STATE_IDLE;
114			
115			loadBytes(URLLoader(e.currentTarget).data);
116		}
117		
118		public function loadClass(classObject : Class) : void
119		{
120			loadBytes(new classObject());
121		}
122		
123		public function loadBytes(byteArray : ByteArray) : void
124		{
125			var startPosition : uint = byteArray.position;
126			
127			if (_currentState != STATE_IDLE)
128				throw new Error('This loader is already loading an asset.');
129			
130			_currentState = STATE_PARSING;
131			_progress.execute(this, 0.5);
132			
133			if (_parserOptions != null && _parserOptions.parser != null)
134			{
135				_parser = new (_parserOptions.parser)(_parserOptions);
136				
137				if (!_parser.isParsable(byteArray))
138					throw new Error('Invalid datatype for this parser.');
139			}
140			else
141			{
142				// search a parser by testing registered parsers.
143				var numRegisteredParser : uint = REGISTERED_PARSERS.length;
144				for (var parserId : uint = 0; parserId < numRegisteredParser; ++parserId)
145				{
146					_parser = new REGISTERED_PARSERS[parserId](_parserOptions);
147					byteArray.position = startPosition;
148					if (_parser.isParsable(byteArray))
149						break;
150				}
151				
152				if (parserId == numRegisteredParser)
153					throw new Error('No parser could be found for this datatype.');
154			}
155
156			byteArray.position = startPosition;
157			
158			_dependencies	 = _parser.getDependencies(byteArray);
159			_numDependencies = 0;
160			
161			if (_dependencies != null)
162				for each (var dependency : ILoader in _dependencies)
163					if (!dependency.isComplete)
164					{
165						dependency.error.add(decrementDependencyCounter);
166						dependency.complete.add(decrementDependencyCounter);
167						
168						_numDependencies++;
169					}
170			
171			if (_numDependencies == 0)
172				parse();
173		}
174		
175		private function decrementDependencyCounter(...args) : void
176		{
177			--_numDependencies;
178			
179			if (_numDependencies == 0)
180				parse();
181		}
182		
183		private function parse() : void
184		{
185			_parser.error.add(onParseError);
186			_parser.progress.add(onParseProgress);
187			_parser.complete.add(onParseComplete);
188			_parser.parse();
189		}
190		
191		private function onParseError(parser : IParser) : void
192		{
193			_isComplete = true;
194		}
195		
196		private function onParseProgress(parser : IParser, progress : Number) : void
197		{
198			_progress.execute(this, 0.5 * (1 + progress));
199		}
200		
201		private function onParseComplete(parser : IParser, loadedData : ISceneNode) : void
202		{
203			_isComplete = true;
204			_data = loadedData;
205			_complete.execute(this, loadedData);
206		}
207	}
208}