import { Utils } from '../common/Utils';
import { ImageTexture } from '../resources/ImageTexture';
import { EmptyTexture } from '../resources/EmptyTexture';
import water_normal_image from '../../assets/images/water_normal.jpg';
const __ = {
private: Symbol('private'),
}
/**
* @class Global
* The global.
* @memberof THING
*/
class Global {
/**
* The global information.
* @param {Object} param The initial parameters.
*/
constructor(param = {}) {
this[__.private] = {};
let _private = this[__.private];
_private.readyPromise = null;
_private.cache = {
classes: new Map(),
models: {},
images: {},
ready: false,
};
_private.gc = _DEBUG ? Utils.createObject('GarbageCollector', (key) => {
Utils.log(`GC destroy {${key}} object`);
}) : null;
this._setupMacros(param);
this._setupFactory(param);
this._setupCache();
}
// #region Private
_loadImages() {
let _private = this[__.private];
let images = _private.cache.images;
// Create empty texture
images['empty_image_texture'] = new EmptyTexture();
// Create images cache
return [
{ name: 'water_normal_image', resource: water_normal_image },
].map(info => {
return new Promise((resolve, reject) => {
let image = Utils.loadImageFileFromBase64(info.resource);
let imageTexture = new ImageTexture({ resource: image });
images[info.name] = imageTexture;
resolve();
});
});
}
_loadModels(resourceManager) {
let _private = this[__.private];
let models = _private.cache.models;
// Create nodes cache
let box = resourceManager.parseModel('Box');
box.setVisible(false);
let plane = resourceManager.parseModel('Plane');
plane.setVisible(false);
// Save nodes cache
models['box'] = box;
models['plane'] = plane;
}
_setupMacros(param) {
let macros = Utils.getMacros();
macros['PRO'] = typeof _PRO_ !== 'undefined' ? _PRO_ : false;
macros['VERSION'] = typeof _VERSION !== 'undefined' ? _VERSION : '';
macros['COMPILETIME'] = typeof _COMPILETIME !== 'undefined' ? _COMPILETIME : '';
macros['GITCOMMITHASH'] = typeof _GITCOMMITHASH !== 'undefined' ? _GITCOMMITHASH : '';
macros['GITBRANCH'] = typeof _GITBRANCH !== 'undefined' ? _GITBRANCH : '';
macros['DEBUG'] = Utils.parseValue(param['debugMode'], typeof _DEBUG !== 'undefined' ? _DEBUG : false);
macros['VERBOSE'] = Utils.parseValue(param['verboseMode'], typeof _VERBOSE !== 'undefined' ? _VERBOSE : false);
}
_setupFactory(param) {
// Get factories
let factories = param['factory'] || [];
if (!Utils.isArray(factories)) {
factories = [factories];
}
// Add factories
factories.forEach(factory => {
Utils.addFactory(factory);
});
}
_setupCache() {
let _private = this[__.private];
let cache = _private.cache;
// Get resource from cache.
cache.getResource = function (classType) {
let resource = cache[classType];
if (resource === undefined) {
resource = this.createObject(classType);
cache[classType] = resource;
}
return resource;
}
}
// #endregion
// #region Cache
/**
* Load resource.
* @param {Object} resourceManager The resource manager.
* @private
*/
loadResource(resourceManager) {
let _private = this[__.private];
let cache = _private.cache;
// Load models
this._loadModels(resourceManager);
// Load textures
let promises = [];
promises.push(...this._loadImages());
// Wait for all resources loaded
_private.readyPromise = Promise.all(promises).then(() => {
cache['ready'] = true;
if (cache['resolves']) {
cache['resolves'].forEach(resolve => {
resolve();
});
cache['resolves'] = [];
}
});
}
/**
* Get the class names of object.
* @param {Object} object The class object.
* @returns {Array<String>}
* @private
*/
getClassNamesFromObject(object) {
let _private = this[__.private];
let proto = object.__proto__;
let className = Utils.getClassNameFromProto(proto);
let classes = _private.cache.classes;
let classNames = classes.get(className);
if (!classNames) {
classNames = Utils.getClassNamesFromProto(object.__proto__);
classes.set(className, classNames);
}
return classNames;
}
get cache() {
return this[__.private].cache;
}
get gc() {
return this[__.private].gc;
}
// #endregion
dispose() {
let _private = this[__.private];
let cache = _private.cache;
cache.classes.clear();
for (let key in cache.models) {
cache.models[key].dispose();
}
cache.models = {};
for (let key in cache.images) {
cache.images[key].dispose();
}
cache.images = {};
}
waitForComplete() {
let _private = this[__.private];
return _private.readyPromise;
}
/**
* Get/Set global http request headers.
* @type {Object}
* @private
*/
get httpRequestHeaders() {
return Utils._system.getHttpRequestHeaders();
}
set httpRequestHeaders(value) {
Utils._system.setHttpRequestHeaders(value);
}
/**
* Get/Set the callback function when get resource type in ajax/fetch hook.
* @type {Function}
* @private
*/
get onGetResourceTypeFromUrl() {
return Utils._system.onGetResourceTypeFromUrl;
}
set onGetResourceTypeFromUrl(value) {
Utils._system.onGetResourceTypeFromUrl = value;
}
/**
* Get the macros.
* @type {Object}
* @private
*/
get macros() {
return this[__.private].macros;
}
}
export { Global }