UNPKG

playcanvas

Version:

PlayCanvas WebGL game engine

214 lines (212 loc) 6.57 kB
class BundleRegistry { _onAssetAdd(asset) { if (asset.type === 'bundle') { this._idToBundle.set(asset.id, asset); this._assets.on("load:start:" + asset.id, this._onBundleLoadStart, this); this._assets.on("load:" + asset.id, this._onBundleLoad, this); this._assets.on("error:" + asset.id, this._onBundleError, this); var assetIds = asset.data.assets; for(var i = 0; i < assetIds.length; i++){ this._indexAssetInBundle(assetIds[i], asset); } } else { if (this._assetToBundles.has(asset.id)) { this._indexAssetFileUrls(asset); } } } _unbindAssetEvents(id) { this._assets.off("load:start:" + id, this._onBundleLoadStart, this); this._assets.off("load:" + id, this._onBundleLoad, this); this._assets.off("error:" + id, this._onBundleError, this); } _indexAssetInBundle(id, bundle) { var bundles = this._assetToBundles.get(id); if (!bundles) { bundles = new Set(); this._assetToBundles.set(id, bundles); } bundles.add(bundle); var asset = this._assets.get(id); if (asset) this._indexAssetFileUrls(asset); } _indexAssetFileUrls(asset) { var urls = this._getAssetFileUrls(asset); if (!urls) return; for(var i = 0; i < urls.length; i++){ var bundles = this._assetToBundles.get(asset.id); if (!bundles) continue; this._urlsToBundles.set(urls[i], bundles); } } _getAssetFileUrls(asset) { var url = asset.getFileUrl(); if (!url) return null; url = url.split('?')[0]; var urls = [ url ]; if (asset.type === 'font') { var numFiles = asset.data.info.maps.length; for(var i = 1; i < numFiles; i++){ urls.push(url.replace('.png', "" + i + ".png")); } } return urls; } _onAssetRemove(asset) { if (asset.type === 'bundle') { this._idToBundle.delete(asset.id); this._unbindAssetEvents(asset.id); var assetIds = asset.data.assets; for(var i = 0; i < assetIds.length; i++){ var bundles = this._assetToBundles.get(assetIds[i]); if (!bundles) continue; bundles.delete(asset); if (bundles.size === 0) { this._assetToBundles.delete(assetIds[i]); for (var [url, otherBundles] of this._urlsToBundles){ if (otherBundles !== bundles) { continue; } this._urlsToBundles.delete(url); } } } this._onBundleError("Bundle " + asset.id + " was removed"); } else { var bundles1 = this._assetToBundles.get(asset.id); if (!bundles1) return; this._assetToBundles.delete(asset.id); var urls = this._getAssetFileUrls(asset); if (!urls) return; for(var i1 = 0; i1 < urls.length; i1++){ this._urlsToBundles.delete(urls[i1]); } } } _onBundleLoadStart(asset) { asset.resource.on('add', (url, data)=>{ var callbacks = this._fileRequests.get(url); if (!callbacks) return; for(var i = 0; i < callbacks.length; i++){ callbacks[i](null, data); } this._fileRequests.delete(url); }); } _onBundleLoad(asset) { if (!asset.resource) { this._onBundleError("Bundle " + asset.id + " failed to load"); return; } if (!this._fileRequests) { return; } for (var [url, requests] of this._fileRequests){ var bundles = this._urlsToBundles.get(url); if (!bundles || !bundles.has(asset)) continue; var decodedUrl = decodeURIComponent(url); var err = void 0, data = void 0; if (asset.resource.has(decodedUrl)) { data = asset.resource.get(decodedUrl); } else if (asset.resource.loaded) { err = "Bundle " + asset.id + " does not contain URL " + url; } else { continue; } for(var i = 0; i < requests.length; i++){ requests[i](err, err || data); } this._fileRequests.delete(url); } } _onBundleError(err) { for (var [url, requests] of this._fileRequests){ var bundle = this._findLoadedOrLoadingBundleForUrl(url); if (!bundle) { for(var i = 0; i < requests.length; i++){ requests[i](err); } this._fileRequests.delete(url); } } } _findLoadedOrLoadingBundleForUrl(url) { var bundles = this._urlsToBundles.get(url); if (!bundles) return null; var candidate = null; for (var bundle of bundles){ if (bundle.loaded && bundle.resource) { return bundle; } else if (bundle.loading) { candidate = bundle; } } return candidate; } listBundlesForAsset(asset) { var bundles = this._assetToBundles.get(asset.id); if (bundles) return Array.from(bundles); return null; } list() { return Array.from(this._idToBundle.values()); } hasUrl(url) { return this._urlsToBundles.has(url); } urlIsLoadedOrLoading(url) { return !!this._findLoadedOrLoadingBundleForUrl(url); } loadUrl(url, callback) { var bundle = this._findLoadedOrLoadingBundleForUrl(url); if (!bundle) { callback("URL " + url + " not found in any bundles"); return; } if (bundle.loaded) { var decodedUrl = decodeURIComponent(url); if (bundle.resource.has(decodedUrl)) { callback(null, bundle.resource.get(decodedUrl)); return; } else if (bundle.resource.loaded) { callback("Bundle " + bundle.id + " does not contain URL " + url); return; } } var callbacks = this._fileRequests.get(url); if (!callbacks) { callbacks = []; this._fileRequests.set(url, callbacks); } callbacks.push(callback); } destroy() { this._assets.off('add', this._onAssetAdd, this); this._assets.off('remove', this._onAssetRemove, this); for (var id of this._idToBundle.keys()){ this._unbindAssetEvents(id); } this._assets = null; this._idToBundle.clear(); this._idToBundle = null; this._assetToBundles.clear(); this._assetToBundles = null; this._urlsToBundles.clear(); this._urlsToBundles = null; this._fileRequests.clear(); this._fileRequests = null; } constructor(assets){ this._idToBundle = new Map(); this._assetToBundles = new Map(); this._urlsToBundles = new Map(); this._fileRequests = new Map(); this._assets = assets; this._assets.bundles = this; this._assets.on('add', this._onAssetAdd, this); this._assets.on('remove', this._onAssetRemove, this); } } export { BundleRegistry };