UNPKG

mdx-m3-viewer

Version:

A browser WebGL model viewer. Mainly focused on models of the games Warcraft 3 and Starcraft 2.

125 lines (107 loc) 3.24 kB
import EventEmitter from 'events'; /** * A viewer resource. * Generally speaking resources are created via viewer.load(). * Resources include models, textures, or any arbitrary file types that have handlers (e.g. INI). */ export default class Resource extends EventEmitter { /** * @param {Object} resourceData */ constructor({viewer, handler, extension, pathSolver, fetchUrl = ''}) { super(); /** @member {ModelViewer.viewer.ModelViewer} */ this.viewer = viewer; /** @member {Handler} */ this.handler = handler || null; /** @member {string} */ this.extension = extension || ''; /** @member {function(?)} */ this.pathSolver = pathSolver || null; /** @member {string} */ this.fetchUrl = fetchUrl; /** @member {boolean} */ this.ok = false; /** @member {boolean} */ this.loaded = false; // Ignore EventEmitter warnings. // Mostly relevant when loading many models that reference the same texture / event object. this.setMaxListeners(0); } /** * Will be called when the data for this resource is ready. * If it was loaded from memory, it will be called instantly. * Otherwise it will be called when the server fetch finishes, assuming it succeeded. * * @param {string|ArrayBuffer|Image} src * @param {?Object} options */ loadData(src, options) { this.loaded = true; // In case the resource parsing/loading fails, e.g. if the source is not valid. try { this.load(src, options); this.ok = true; this.lateLoad(); this.emit('load', this); this.emit('loadend', this); } catch (e) { this.error('InvalidData', e); } } /** * @param {*} src * @param {?Object} options */ load(src, options) { } /** * Remove this resource from its viewer's cache. * Equivalent to viewer.unload(resource). * * @return {boolean} */ detach() { return this.viewer.unload(this); } /** * This is used by models to finish loading their instances and model views, in case any are added before the model finished loaded. */ lateLoad() { } /** * Called when an error happens while loading the resource. * This includes both fetching and parsing errors. * * @param {string} error * @param {*} reason */ error(error, reason) { this.loaded = true; this.emit('error', this, error, reason); this.emit('loadend', this); } /** * Wait for this resource to load. * Similar to attaching an event listener to the 'loadend' event, but handles the case where the resource already loaded, and code should still run. * If a callback is given, it will be called. * Otherwise a promise is returned. * * @param {?function} callback * @return {?Promise} */ whenLoaded(callback) { let promise = new Promise((resolve, reject) => { if (this.loaded) { resolve(this); } else { this.once('loadend', () => resolve(this)); } }); if (callback) { promise.then(() => callback(this)); } else { return promise; } } }