/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

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