UNPKG

@awayjs/core

Version:
291 lines (290 loc) 11.3 kB
import { __extends } from "tslib"; import { AbstractMethodError } from '../errors/AbstractMethodError'; import { AssetEvent } from '../events/AssetEvent'; import { EventDispatcher } from '../events/EventDispatcher'; import { ParserEvent } from '../events/ParserEvent'; import { ParserUtils } from '../parsers/ParserUtils'; import { ResourceDependency } from '../parsers/ResourceDependency'; import { getTimer } from '../utils/getTimer'; import { RequestAnimationFrame } from '../utils/RequestAnimationFrame'; /** * <code>ParserBase</code> provides an abstract base export class for objects * that convert blocks of data to data structures supported by away. * * If used by <code>Loader</code> to automatically determine the parser type, * two public static methods should be implemented, with the following * signatures: * * <code>public static supportsType(extension : string) : boolean</code> * Indicates whether or not a given file extension is supported by the parser. * * <code>public static supportsData(data : *) : boolean</code> Tests whether a * data block can be parsed by the parser. * * Furthermore, for any concrete subtype, the method <code>initHandle</code> * should be overridden to immediately create the object that will contain the * parsed data. This allows <code>ResourceManager</code> to return an object * handle regardless of whether the object was loaded or not. * * @see Loader */ var ParserBase = /** @class */ (function (_super) { __extends(ParserBase, _super); /** * Creates a new ParserBase object * @param format The data format of the file data to be parsed. Can be * either <code>ParserDataFormat.BINARY</code> or * <code>ParserDataFormat.PLAIN_TEXT</code>, and should be provided by the * concrete subtype. * * @see away.loading.parsers.ParserDataFormat */ function ParserBase(format) { var _this = _super.call(this) || this; _this.materialMode = 0; _this._dataFormat = format; _this._dependencies = new Array(); _this._onIntervalDelegate = function (event) { return _this._onInterval(event); }; _this._timer = new RequestAnimationFrame(_this._onIntervalDelegate, _this); return _this; } //------------------------------------------------------------------------------------------------------------------ // TODO: add error checking for the following ( could cause a problem if // this function is not implemented ) //------------------------------------------------------------------------------------------------------------------ // Needs to be implemented in all Parsers (<code>public static //supportsType(extension : string) : boolean</code> //* Indicates whether or not a given file extension is supported by the // parser. // ---------------------------------------------------------------------------------------------------------------- ParserBase.supportsType = function (extension) { throw new AbstractMethodError(); }; Object.defineProperty(ParserBase.prototype, "content", { get: function () { return this._content; }, enumerable: false, configurable: true }); Object.defineProperty(ParserBase.prototype, "parsingFailure", { get: function () { return this._parsingFailure; }, set: function (b) { this._parsingFailure = b; }, enumerable: false, configurable: true }); Object.defineProperty(ParserBase.prototype, "parsingPaused", { get: function () { return this._parsingPaused; }, enumerable: false, configurable: true }); Object.defineProperty(ParserBase.prototype, "parsingComplete", { get: function () { return this._parsingComplete; }, enumerable: false, configurable: true }); Object.defineProperty(ParserBase.prototype, "data", { get: function () { return this._data; }, enumerable: false, configurable: true }); Object.defineProperty(ParserBase.prototype, "dataFormat", { /** * The data format of the file data to be parsed. Options are * <code>URLLoaderDataFormat.BINARY</code>, * <code>URLLoaderDataFormat.ARRAY_BUFFER</code>, * <code>URLLoaderDataFormat.BLOB</code>, * <code>URLLoaderDataFormat.VARIABLES</code> or * <code>URLLoaderDataFormat.TEXT</code>. */ get: function () { return this._dataFormat; }, enumerable: false, configurable: true }); /** * Parse data (possibly containing bytearry, plain text or BitmapAsset) * asynchronously, meaning that the parser will periodically stop parsing so * that the AVM may proceed to the next frame. * * @param data The untyped data object in which the loaded data resides. * @param frameLimit number of milliseconds of parsing allowed per frame. * The actual time spent on a frame can exceed this number since time-checks * can only be performed between logical sections of the parsing procedure. */ ParserBase.prototype.parseAsync = function (data, frameLimit) { if (frameLimit === void 0) { frameLimit = 30; } this._data = data; this.startParsing(frameLimit); }; Object.defineProperty(ParserBase.prototype, "dependencies", { // public parseSync(data: any): IAsset { // this._data = data; // let state = ParserBase.MORE_TO_PARSE; // while (state == ParserBase.MORE_TO_PARSE) { // state = this._pProceedParsing(); // } // return this._pContent; // } /** * A list of dependencies that need to be loaded and resolved for the object * being parsed. */ get: function () { return this._dependencies; }, enumerable: false, configurable: true }); /** * Resolve a dependency when it's loaded. For example, a dependency * containing an ImageResource would be assigned to a Mesh instance as a * BitmapMaterial, a scene graph object would be added to its intended * parent. The dependency should be a member of the dependencies property. * * @param resourceDependency The dependency to be resolved. */ ParserBase.prototype.resolveDependency = function (resourceDependency) { throw new AbstractMethodError(); }; /** * Resolve a dependency loading failure. Used by parser to eventually * provide a default map * * @param resourceDependency The dependency to be resolved. */ ParserBase.prototype.resolveDependencyFailure = function (resourceDependency) { throw new AbstractMethodError(); }; /** * Resolve a dependency name * * @param resourceDependency The dependency to be resolved. */ ParserBase.prototype.resolveDependencyName = function (resourceDependency, asset) { return asset.name; }; ParserBase.prototype.resumeParsing = function () { this._parsingPaused = false; //get started! if (this.hasTime()) this.proceedParsing(); }; ParserBase.prototype.finalizeAsset = function (asset, name) { if (name === void 0) { name = null; } // If the asset has no name, give it a per-type default name. asset.name = name || asset.name || asset.assetType; this.dispatchEvent(new AssetEvent(AssetEvent.ASSET_COMPLETE, asset)); }; /** * Parse the next block of data. * @return Whether or not more data needs to be parsed. Can be * <code>ParserBase.ParserBase.PARSING_DONE</code> or * <code>ParserBase.ParserBase.MORE_TO_PARSE</code>. */ ParserBase.prototype.proceedParsing = function () { throw new AbstractMethodError(); }; ParserBase.prototype.dieWithError = function (message) { if (message === void 0) { message = 'Unknown parsing error'; } this._parsingFailure = true; this.dispatchEvent(new ParserEvent(ParserEvent.PARSE_ERROR, message)); }; ParserBase.prototype.addDependency = function (id, req, parser, data, retrieveAsRawData, suppressErrorEvents, sub_id) { if (parser === void 0) { parser = null; } if (data === void 0) { data = null; } if (retrieveAsRawData === void 0) { retrieveAsRawData = false; } if (suppressErrorEvents === void 0) { suppressErrorEvents = false; } if (sub_id === void 0) { sub_id = 0; } var dependency = new ResourceDependency(id, req, data, parser, this, retrieveAsRawData, suppressErrorEvents, sub_id); this._dependencies.push(dependency); return dependency; }; ParserBase.prototype.pauseAndRetrieveDependencies = function () { this._parsingPaused = true; this.dispatchEvent(new ParserEvent(ParserEvent.READY_FOR_DEPENDENCIES)); }; /** * Tests whether or not there is still time left for parsing within the * maximum allowed time frame per session. * @return True if there is still time left, false if the maximum allotted * time was exceeded and parsing should be interrupted. */ ParserBase.prototype.hasTime = function () { this._isParsing = ((getTimer() - ParserBase._lastFrameTime) < this._frameLimit); //If parsing has stopped due to framelimit, start RAF and wait for next animation frame if (!this._isParsing) this._timer.start(); return this._isParsing; }; /** * Called when the parsing pause interval has passed and parsing can * proceed. */ ParserBase.prototype._onInterval = function (event) { if (event === void 0) { event = null; } ParserBase._lastFrameTime = getTimer(); this._isParsing = true; //stop RAF to continue parsing this._timer.stop(); this.proceedParsing(); }; /**# * Initializes the parsing of data. * @param frameLimit The maximum duration of a parsing session. */ ParserBase.prototype.startParsing = function (frameLimit) { this._frameLimit = frameLimit; //get started! if (this.hasTime()) this.proceedParsing(); }; /** * Finish parsing the data. */ ParserBase.prototype.finishParsing = function () { if (this._parsingFailure) return; this._parsingComplete = true; this._isParsing = false; this.dispatchEvent(new ParserEvent(ParserEvent.PARSE_COMPLETE)); }; /** * * @returns {string} * @private */ ParserBase.prototype.getTextData = function () { return ParserUtils.toString(this._data); }; /** * * @returns {ByteArray} * @private */ ParserBase.prototype.getByteData = function () { return ParserUtils.toByteArray(this._data); }; /** * * @returns {any} * @private */ ParserBase.prototype.getData = function () { return this._data; }; ParserBase._lastFrameTime = 0; return ParserBase; }(EventDispatcher)); export { ParserBase };