Source: components/AppResourcePoolComponent.js

import { Utils } from '../common/Utils';
import { BaseComponent } from './BaseComponent';
import { MixLoader } from '../loaders/MixLoader';

const __ = {
	private: Symbol('private'),
}

/**
 * @class AppResourcePoolComponent
 * The application resource pool component.
 * @memberof THING
 * @extends THING.BaseComponent
 * @public
 */
class AppResourcePoolComponent extends BaseComponent {

	/**
	 * The resource manager to use duplicate resources, prevent to create multiple times.
	 */
	constructor() {
		super();

		this[__.private] = {};
		let _private = this[__.private];

		_private.loaders = {
			'mix': MixLoader
		};

		_private.loadingList = [];

		_private.getLoader = (type) => {
			return _private.loaders[type];
		}
	}

	registerLoader(type, cls) {
		let _private = this[__.private];
		_private.loaders[type] = cls;
	}

	/**
	 * Load image texture from URL.
	 * @param {String} url The resource url.
	 * @param {LoadTextureResourceSamplerInfo} sampler The sampler info.
	 * @returns {THING.ImageTexture}
	 * @example
	 * 	let image = THING.App.current.loadImageTexture('./flower.png');
	 * 	await image.waitForComplete();
	 * 	console.log(image);
	 * @public
	 */
	loadImageTexture(url, sampler) {
		return this.object.resourceManager.getTextureManager().load(url, sampler);
	}

	/**
	 * Load image texture from URL in async mode.
	 * @param {String} url The resource url.
	 * @param {LoadTextureResourceSamplerInfo} sampler The sampler info.
	 * @returns {Promise<any>}
	 * @example
	 * 	let image = await THING.App.current.loadImageTextureAsync('./flower.png');
	 * 	console.log(image);
	 */
	loadImageTextureAsync(url, sampler) {
		return this.object.resourceManager.getTextureManager().loadAsync(url, sampler);
	}

	/**
	 * Load scene file
	 * @param {String|Object} url - The load URL or options.
	 * @param {Object} options - The load options.
	 * @param {String} options.url - The resource URL.
	 * @param {Boolean} options.dynamic - Dynamic loading scene.
	 * @param {Boolean} options.hidden - Hidden loading.
	 * @param {Boolean} options.useDefaultTheme - Use defalt theme for scene. (The last registered theme is used by default)
	 * @param {Boolean} options.useDefaultViewpoint - Use default viewpoint for scene file.
	 * @param {Boolean} options.useDefaultRenderSettings - Use default render settings for scene file.
	 * @param {Array} options.position - Set the scene position.
	 * @param {Array} options.rotation - Set the scene rotation.
	 * @param {Function} options.onComplete - The load complete callback function.
	 * @param {Function} options.onProgress - The progress callback function.
	 * @param {Function} options.onError - The error callback function.
	 * @returns {Promise} - A Promise that resolves when the loading is complete.
	 * @public
	 */
	load(url, options) {
		let _private = this[__.private];
		let loaderCls = _private.getLoader('mix');
		let loader = new loaderCls(this.app);
		_private.loadingList.push(loader);
		let promise = loader.load(url, options);

		promise.then(() => {
			for (let i = 0; i < _private.loadingList.length; i++) {
				const loader = _private.loadingList[i];
				if (loader.loaded) {
					_private.loadingList._removeAt(i);
					break;
				}
			}
		})

		return promise;
	}

	/**
	 * Load TSF (ThingJS Scene File)
	 * @param {String|Object} url - The load URL or options.
	 * @param {Object} options - The load options.
	 * @param {String} options.url - The resource URL.
	 * @param {Function} options.onComplete - The load complete callback function.
	 * @param {Function} options.onProgress - The progress callback function.
	 * @param {Function} options.onError - The error callback function.
	 * @returns {Promise} - A Promise that resolves when the loading is complete.
	 * @private
	 * @example
	 * app.load('./myScene.json').then((ev) => {
	 *     console.log('Load completed');
	 * });
	 */
	loadTSF(url, options) {
		Utils.warn(`Please call 'app.load()' instead`);
		return this.load(url, options);
	}

	/**
	 * Load model scene (Currently only supports glTF)
	 * @param {String|Object} url - The load URL or options.
	 * @param {Object} options - The load options.
	 * @param {String} options.url - The resource URL.
	 * @param {Function} options.onComplete - The load complete callback function.
	 * @param {Function} options.onProgress - The progress callback function.
	 * @param {Function} options.onError - The error callback function.
	 * @returns {Promise} - A Promise that resolves when the loading is complete.
	 * @private
	 * @example
	 * app.loadGLTF('./myScene.gltf').then(() => {
	 *     console.log('Load completed');
	 * });
	 */
	loadGLTF(url, options) {
		Utils.warn(`Please call 'app.load()' instead`);
		return this.load(url, options);
	}

	/**
	 * Load plugin
	 * @param {String|Object} url - The load URL or options.
	 * @param {Object} options - The load options.
	 * @param {String} options.url The plugin URL.
	 * @param {String} options.name The plugin name.
	 * @param {Function} options.onComplete - The load complete callback function.
	 * @param {Function} options.onError - The error callback function.
	 * @return {Promise}
	 * @public
	 */
	loadPlugin(url, options) {
		let _private = this[__.private];
		let loaderCls = _private.getLoader('mix');
		return new loaderCls(this.app).loadPlugin(url, options);
	}

	onRemove() {
		let _private = this[__.private];

		_private.loadingList.forEach(loader => {
			loader.dispose();
		});

		_private.loadingList = null;
	}

}

AppResourcePoolComponent.exportFunctions = [
	'loadImageTexture',
	'loadImageTextureAsync',
	'loadScene',
	'loadSceneAsync',
	'load',
	'loadGLTF',
	'loadPlugin'
];

export { AppResourcePoolComponent }