UNPKG

playcanvas

Version:

PlayCanvas WebGL game engine

195 lines (192 loc) 5.68 kB
import { path } from '../core/path.js'; import { ABSOLUTE_URL } from './asset/constants.js'; import { SceneRegistryItem } from './scene-registry-item.js'; class SceneRegistry { destroy() { this._app = null; } list() { return this._list; } add(name, url) { if (this._index.hasOwnProperty(name)) { return false; } var item = new SceneRegistryItem(name, url); var i = this._list.push(item); this._index[item.name] = i - 1; this._urlIndex[item.url] = i - 1; return true; } find(name) { if (this._index.hasOwnProperty(name)) { return this._list[this._index[name]]; } return null; } findByUrl(url) { if (this._urlIndex.hasOwnProperty(url)) { return this._list[this._urlIndex[url]]; } return null; } remove(name) { if (this._index.hasOwnProperty(name)) { var idx = this._index[name]; var item = this._list[idx]; delete this._urlIndex[item.url]; delete this._index[name]; this._list.splice(idx, 1); for(var i = 0; i < this._list.length; i++){ item = this._list[i]; this._index[item.name] = i; this._urlIndex[item.url] = i; } } } _loadSceneData(sceneItem, storeInCache, callback) { var app = this._app; var url = sceneItem; if (typeof sceneItem === 'string') { sceneItem = this.findByUrl(url) || this.find(url) || new SceneRegistryItem('Untitled', url); } url = sceneItem.url; if (!url) { callback('Cannot find scene to load'); return; } if (sceneItem.loaded) { callback(null, sceneItem); return; } if (app.assets && app.assets.prefix && !ABSOLUTE_URL.test(url)) { url = path.join(app.assets.prefix, url); } sceneItem._onLoadedCallbacks.push(callback); if (!sceneItem._loading) { var handler = app.loader.getHandler('hierarchy'); handler.load(url, (err, data)=>{ sceneItem.data = data; sceneItem._loading = false; for(var i = 0; i < sceneItem._onLoadedCallbacks.length; i++){ sceneItem._onLoadedCallbacks[i](err, sceneItem); } if (!storeInCache) { sceneItem.data = null; } sceneItem._onLoadedCallbacks.length = 0; }); } sceneItem._loading = true; } loadSceneData(sceneItem, callback) { this._loadSceneData(sceneItem, true, callback); } unloadSceneData(sceneItem) { if (typeof sceneItem === 'string') { sceneItem = this.findByUrl(sceneItem); } if (sceneItem) { sceneItem.data = null; } } _loadSceneHierarchy(sceneItem, onBeforeAddHierarchy, callback) { this._loadSceneData(sceneItem, false, (err, sceneItem)=>{ if (err) { if (callback) { callback(err); } return; } if (onBeforeAddHierarchy) { onBeforeAddHierarchy(sceneItem); } var app = this._app; var _loaded = ()=>{ var handler = app.loader.getHandler('hierarchy'); app.systems.script.preloading = true; var entity = handler.open(sceneItem.url, sceneItem.data); app.systems.script.preloading = false; app.loader.clearCache(sceneItem.url, 'hierarchy'); app.root.addChild(entity); app.systems.fire('initialize', entity); app.systems.fire('postInitialize', entity); app.systems.fire('postPostInitialize', entity); if (callback) callback(null, entity); }; app._preloadScripts(sceneItem.data, _loaded); }); } loadSceneHierarchy(sceneItem, callback) { this._loadSceneHierarchy(sceneItem, null, callback); } loadSceneSettings(sceneItem, callback) { this._loadSceneData(sceneItem, false, (err, sceneItem)=>{ if (!err) { this._app.applySceneSettings(sceneItem.data.settings); if (callback) { callback(null); } } else { if (callback) { callback(err); } } }); } changeScene(sceneItem, callback) { var app = this._app; var onBeforeAddHierarchy = (sceneItem)=>{ var { children } = app.root; while(children.length){ children[0].destroy(); } app.applySceneSettings(sceneItem.data.settings); }; this._loadSceneHierarchy(sceneItem, onBeforeAddHierarchy, callback); } loadScene(url, callback) { var app = this._app; var handler = app.loader.getHandler('scene'); if (app.assets && app.assets.prefix && !ABSOLUTE_URL.test(url)) { url = path.join(app.assets.prefix, url); } handler.load(url, (err, data)=>{ if (!err) { var _loaded = ()=>{ app.systems.script.preloading = true; var scene = handler.open(url, data); var sceneItem = this.findByUrl(url); if (sceneItem && !sceneItem.loaded) { sceneItem.data = data; } app.systems.script.preloading = false; app.loader.clearCache(url, 'scene'); app.loader.patch({ resource: scene, type: 'scene' }, app.assets); app.root.addChild(scene.root); if (app.systems.rigidbody && typeof Ammo !== 'undefined') { app.systems.rigidbody.gravity.set(scene._gravity.x, scene._gravity.y, scene._gravity.z); } if (callback) { callback(null, scene); } }; app._preloadScripts(data, _loaded); } else { if (callback) { callback(err); } } }); } constructor(app){ this._list = []; this._index = {}; this._urlIndex = {}; this._app = app; } } export { SceneRegistry };