import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; import DeveloperError from "../Core/DeveloperError.js"; import ResourceLoader from "./ResourceLoader.js"; import ResourceLoaderState from "./ResourceLoaderState.js"; /** * Loads an embedded or external buffer. *

* Implements the {@link ResourceLoader} interface. *

* * @alias BufferLoader * @constructor * @augments ResourceLoader * * @param {object} options Object with the following properties: * @param {Uint8Array} [options.typedArray] The typed array containing the embedded buffer contents. Mutually exclusive with options.resource. * @param {Resource} [options.resource] The {@link Resource} pointing to the external buffer. Mutually exclusive with options.typedArray. * @param {string} [options.cacheKey] The cache key of the resource. * * @exception {DeveloperError} One of options.typedArray and options.resource must be defined. * * @private */ function BufferLoader(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); const typedArray = options.typedArray; const resource = options.resource; const cacheKey = options.cacheKey; //>>includeStart('debug', pragmas.debug); if (defined(typedArray) === defined(resource)) { throw new DeveloperError( "One of options.typedArray and options.resource must be defined." ); } //>>includeEnd('debug'); this._typedArray = typedArray; this._resource = resource; this._cacheKey = cacheKey; this._state = ResourceLoaderState.UNLOADED; this._promise = undefined; } if (defined(Object.create)) { BufferLoader.prototype = Object.create(ResourceLoader.prototype); BufferLoader.prototype.constructor = BufferLoader; } Object.defineProperties(BufferLoader.prototype, { /** * The cache key of the resource. * * @memberof BufferLoader.prototype * * @type {string} * @readonly * @private */ cacheKey: { get: function () { return this._cacheKey; }, }, /** * The typed array containing the embedded buffer contents. * * @memberof BufferLoader.prototype * * @type {Uint8Array} * @readonly * @private */ typedArray: { get: function () { return this._typedArray; }, }, }); /** * Loads the resource. * @returns {Promise} A promise which resolves to the loader when the resource loading is completed. * @private */ BufferLoader.prototype.load = async function () { if (defined(this._promise)) { return this._promise; } if (defined(this._typedArray)) { this._promise = Promise.resolve(this); return this._promise; } this._promise = loadExternalBuffer(this); return this._promise; }; async function loadExternalBuffer(bufferLoader) { const resource = bufferLoader._resource; bufferLoader._state = ResourceLoaderState.LOADING; try { const arrayBuffer = await BufferLoader._fetchArrayBuffer(resource); if (bufferLoader.isDestroyed()) { return; } bufferLoader._typedArray = new Uint8Array(arrayBuffer); bufferLoader._state = ResourceLoaderState.READY; return bufferLoader; } catch (error) { if (bufferLoader.isDestroyed()) { return; } bufferLoader._state = ResourceLoaderState.FAILED; const errorMessage = `Failed to load external buffer: ${resource.url}`; throw bufferLoader.getError(errorMessage, error); } } /** * Exposed for testing * @private */ BufferLoader._fetchArrayBuffer = function (resource) { return resource.fetchArrayBuffer(); }; /** * Unloads the resource. * @private */ BufferLoader.prototype.unload = function () { this._typedArray = undefined; }; export default BufferLoader;