playcanvas
Version:
PlayCanvas WebGL game engine
195 lines (192 loc) • 5.68 kB
JavaScript
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 };