@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 9.52 kB
JavaScript
/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.32/esri/copyright.txt for details.
*/
import{_ as e}from"../chunks/tslib.es6.js";import r from"../core/Accessor.js";import i from"../core/Error.js";import t from"../core/Logger.js";import{someMap as s}from"../core/MapUtils.js";import{removeMaybe as a}from"../core/maybe.js";import{createResolver as o,createAbortError as l,isAbortError as n,onAbort as y,throwIfAborted as h}from"../core/promiseUtils.js";import{on as c,watch as p,syncAndInitial as w}from"../core/reactiveUtils.js";import{schedule as d}from"../core/scheduling.js";import{property as m}from"../core/accessorSupport/decorators/property.js";import"../core/has.js";import"../core/RandomLCG.js";import{subclass as f}from"../core/accessorSupport/decorators/subclass.js";import{get as u}from"../core/accessorSupport/get.js";import{UpdatingHandles as _}from"../core/support/UpdatingHandles.js";import g from"../layers/Layer.js";import{destroyMap as V}from"../support/collectionUtils.js";function v(e){return"tryRecycleWith"in e}function L(e){return null!=e&&"object"==typeof e&&"layerViews"in e}class M{constructor(e,r,t){this.layer=e,this.view=r,this.layerViewImporter=t,this._controller=new AbortController,this._deferred=o(),this._started=!1,this.done=!1,this.promise=this._deferred.promise,y(this._controller.signal,(()=>{const r=new i("cancelled:layerview-create","layerview creation cancelled",{layer:e});this._deferred.reject(r)}))}tryRecycle(e){if(!this.done||!this.layerView||!v(this.layerView))return null;const r=this.layer.type,i=this._controller.signal;for(let t=0;t<e.length;t++){const s=e[t];if(s.type!==r)continue;const a=this.layerView.tryRecycleWith(s,{signal:i});if(a){e.splice(t,1),this.layer=s;const r=this.layerView,i=r.view;return this.promise=Promise.race([a.then((()=>(h(this._controller.signal),s.emit("layerview-destroy",{view:i,layerView:r}),i.emit("layerview-destroy",{view:i,layerView:r}),s.emit("layerview-create",{view:i,layerView:r}),i.emit("layerview-create",{view:i,layerView:r}),r))),new Promise(((e,r)=>y(this._controller.signal,(()=>r(l())))))]),this.promise}}return null}destroy(){this._controller.abort();const{layerView:e}=this;if(e){const{layer:r,view:i}=this;r.emit("layerview-destroy",{view:i,layerView:e}),i.emit("layerview-destroy",{layer:r,layerView:e})}this.done=!0,this.layer=null,this.layerView=null,this.view=null,this.layerViewImporter=null,this._map=null}async start(){if(this._started)return;this._started=!0;const{_controller:{signal:e},layer:r,view:t}=this;this._map=t.map;try{let o,l;if(await r.load({signal:e}),r.prefetchResources&&await r.prefetchResources({signal:e}),C(r))o=await r.createLayerView(t,{signal:e});else{if(!this.layerViewImporter.hasLayerViewModule(r))throw new i("layer:view-not-supported","No layerview implementation was found");const s=await this.layerViewImporter.importLayerView(r);h(e),o="default"in s?new s.default({layer:r,view:t}):new s({layer:r,view:t})}const n=()=>{l=a(l),o.destroyed||o.destroy(),o.layer=null,o.parent=null,o.view=null,this.done=!0};l=y(e,n),h(e);try{await o.when()}catch(s){throw n(),s}const c=this._map?.allLayers?.includes(r);if(!c)return n(),void this._deferred.reject(new i("view:no-layerview-for-layer","The layer has been removed from the map",{layer:r}));this.layerView=o,r.emit("layerview-create",{view:t,layerView:o}),t.emit("layerview-create",{layer:r,layerView:o}),this.done=!0,this._deferred.resolve(o)}catch(s){r.emit("layerview-create-error",{view:t,error:s}),t.emit("layerview-create-error",{layer:r,error:s}),this.done=!0,this._deferred.reject(new i("layerview:create-error","layerview creation failed",{layer:r,error:s}))}}}let I=class extends r{constructor(e){super(e),this._layerLayerViewInfoMap=new Map,this._recyclingInfoMap=new Map,this._watchUpdatingTracking=new _,this.supportsGround=!0,this._preloadLayerViewModules=()=>{const e=this.view.map?.allLayers;if(e)for(const r of e)this.layerViewImporter.hasLayerViewModule(r)&&this.layerViewImporter.importLayerView(r)},this._reschedule=()=>this.destroyed?Promise.reject():(null==this._workPromise&&(this._workPromise=o(),this._workPromise.promise.catch((()=>{}))),this.removeHandles("reschedule"),this.addHandles(d(this._doWork),"reschedule"),this._workPromise.promise),this._doWork=()=>{if(this.destroyed)return;const e=this.view.map;if(this._map!==e&&(this.clear(),this._map=e),null==this._workPromise)return void this.notifyChange("updating");this.removeHandles("reschedule"),this.removeHandles("collection-change");const r=new Set,i=[],t=this.view.ready,s=e=>{if(null!=e)for(const a of e)if(a){r.add(a);const e=this._layerLayerViewInfoMap.get(a);e&&t?e.start():e||this._recyclingInfoMap.has(a)||i.push(a),"layers"in a&&a.layers&&s(a.layers)}};for(const o of this._rootCollectionNames)s(u(this,o));for(const[o,l]of this._layerLayerViewInfoMap)if(!r.has(o)){this._layerLayerViewInfoMap.delete(l.layer);const e=l.tryRecycle(i);e?(this.notifyChange("updating"),this._recyclingInfoMap.set(l.layer,l),e.then((()=>{this.notifyChange("updating"),this._recyclingInfoMap.delete(l.layer),this._layerLayerViewInfoMap.set(l.layer,l),this._reschedule()})).catch((()=>{this.notifyChange("updating"),this._recyclingInfoMap.delete(l.layer),l.destroy(),this._reschedule()}))):l.destroy()}for(const[o,l]of this._recyclingInfoMap)r.has(o)||(this.notifyChange("updating"),this._recyclingInfoMap.delete(l.layer),l.destroy());for(const o of i)this._createLayerView(o);this._refreshCollections();const a=[e?.ground?.layers,e?.basemap?.baseLayers,e?.basemap?.referenceLayers,e?.layers].filter((e=>!!e));r.forEach((e=>"layers"in e&&a.push(e.layers))),this.addHandles(a.map((e=>this._watchUpdatingTracking.addOnCollectionChange((()=>e),this._reschedule))),"collection-change"),this._workPromise.resolve(),this._workPromise=null}}initialize(){this.addHandles([c((()=>this.view?.map?.allLayers),"change",this._preloadLayerViewModules,{onListenerAdd:this._preloadLayerViewModules}),p((()=>{const e=this.view,r=e?.map;return[r?.basemap,r?.ground,r?.layers,e?.ready]}),(()=>this._reschedule()),w)]),this._preloadLayerViewModules(),this._reschedule()}destroy(){this.clear(),V(this._recyclingInfoMap),V(this._layerLayerViewInfoMap),this._watchUpdatingTracking.destroy(),this._map=null,null!=this._workPromise&&(this._workPromise.reject(l()),this._workPromise=null)}get _layersToLayerViews(){const e=[["view.map.basemap.baseLayers","view.basemapView.baseLayerViews"],["view.map.layers","view.layerViews"],["view.map.basemap.referenceLayers","view.basemapView.referenceLayerViews"]];return this.supportsGround&&e.push(["view.map.ground.layers","view.groundView.layerViews"]),new Map(e)}get _rootCollectionNames(){return Array.from(this._layersToLayerViews.keys())}get updating(){return null!=this._workPromise||this._watchUpdatingTracking.updating||s(this._layerLayerViewInfoMap,(e=>!e.done))||this._recyclingInfoMap.size>0}get updatingRemaining(){let e=0;for(const r of this._layerLayerViewInfoMap.values())r.done||++e;return e}clear(){this.destroyed||(V(this._layerLayerViewInfoMap),this._refreshCollections())}async whenLayerView(e){if(await this._reschedule(),!this._layerLayerViewInfoMap.has(e)){if(this._recyclingInfoMap.has(e))return this._recyclingInfoMap.get(e).promise;throw new i("view:no-layerview-for-layer","No layerview has been found for the layer",{layer:e})}return this._layerLayerViewInfoMap.get(e).promise}isCreatingLayerViewsForLayer(e,r){this.commitProperty("updatingRemaining");const i=this._layerLayerViewInfoMap.get(e);if(!i?.done)return!0;const t=i.layerView;return!(!t||!r||t.parent===r)||!!(i.done&&t&&"layers"in e&&e.layers?.length)&&e.layers.some((e=>this.isCreatingLayerViewsForLayer(e,t)))}_refreshCollections(){for(const[e,r]of this._layersToLayerViews)this._populateLayerViewsOwners(u(this,e),u(this,r),this.view);this.notifyChange("updating"),this.notifyChange("updatingRemaining")}_populateLayerViewsOwners(e,r,i){if(!e||!r)return void(r&&r.removeAll());let t=0;for(const s of e){const e=this._layerLayerViewInfoMap.get(s);if(!e?.layerView)continue;const a=e.layerView;a.layer=s,a.parent=i,r.at(t)!==a&&r.splice(t,0,a),"layers"in s&&L(a)&&this._populateLayerViewsOwners(s.layers,a.layerViews,a),t+=1}t<r.length&&r.splice(t,r.length)}_createLayerView(e){e.load().catch((()=>{})),this.layerViewImporter.hasLayerViewModule(e)&&this.layerViewImporter.importLayerView(e);const r=new M(e,this.view,this.layerViewImporter);r.promise.then((()=>this._refreshCollections()),(r=>{r&&(n(r)||"cancelled:layerview-create"===r.name)||t.getLogger(this).error(`Failed to create layerview for layer title:'${e.title??"no title"}', id:'${e.id??"no id"}' of type '${e.type}'.`,{layer:e,error:r}),this._refreshCollections()})),this._layerLayerViewInfoMap.set(e,r),this.view.ready&&r.start(),this.notifyChange("updating"),this.notifyChange("updatingRemaining")}};e([m()],I.prototype,"_workPromise",void 0),e([m({readOnly:!0})],I.prototype,"_watchUpdatingTracking",void 0),e([m({readOnly:!0})],I.prototype,"_layersToLayerViews",null),e([m({readOnly:!0})],I.prototype,"_rootCollectionNames",null),e([m()],I.prototype,"layerViewImporter",void 0),e([m()],I.prototype,"supportsGround",void 0),e([m({readOnly:!0})],I.prototype,"updating",null),e([m({readOnly:!0})],I.prototype,"updatingRemaining",null),e([m({constructOnly:!0})],I.prototype,"view",void 0),I=e([f("esri.views.LayerViewManager")],I);const j=I;function C(e){return e.createLayerView!==g.prototype.createLayerView}export{j as default};