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
JavaScript
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;
}
}
}