Source: managers/BlueprintManager.js

import { ResolvableCachedObject } from '@uino/base-thing';
import { Utils } from '../common/Utils';

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

// #region Private Functions

// #endregion

/**
 * @class BlueprintManager
 * The blueprint manager.
 * @memberof THING
 */
class BlueprintManager {

	constructor(param = {}) {
		this[__.private] = {};
		let _private = this[__.private];

		_private.enable = Utils.parseValue(param['enable'], false);
		_private.caches = new ResolvableCachedObject();
	}

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

		return _private.caches.set(url, { blueprints: [] });
	}

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

		if (!_private.enable) {
			return false;
		}

		return _private.caches.get(url);
	}

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

		_private.caches.clear(object => {
			object.blueprints.forEach(blueprint => {
				blueprint.dispose();
			});
		});
	}

	// Convert the data of the blueprint editor into usable data.
	getBodyData(data) {
		let info = data.info;
		let files = info.files;

		let bodyData = [];
		for (let key in files) {
			let body = files[key].body;
			bodyData.push(body);
		}

		return bodyData;
	}

	loadAsync(url) {
		return new Promise(async (resolve, reject) => {
			let cache = this._getCache(url);
			if (cache) {
				cache.pendingPromise.then(() => {
					resolve(cache.datas);
				});
			}
			else {
				cache = this._createCache(url);

				let data = await Utils.loadJSONFile(url, null, null, reject);

				let datas = [];
				if (data.info) {
					let bodyData = this.getBodyData(data);

					// Load blueprint resource(s)
					bodyData.forEach(body => {
						datas.push(body);
					});

				} else {
					datas.push(data);
				}

				cache.datas = datas;
				cache.pendingPromise.resolve();

				resolve(datas);
			}
		});
	}
}

export { BlueprintManager }