@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 5.71 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 t}from"../../../../../chunks/tslib.es6.js";import e from"../../../../../core/Accessor.js";import{isSome as i}from"../../../../../core/arrayUtils.js";import has from"../../../../../core/has.js";import{createAbortError as o,isAbortError as n}from"../../../../../core/promiseUtils.js";import s from"../../../../../core/ReactiveMap.js";import{signal as r}from"../../../../../core/signal.js";import{property as l}from"../../../../../core/accessorSupport/decorators/property.js";import"../../../../../core/Logger.js";import{subclass as a}from"../../../../../core/accessorSupport/decorators/subclass.js";import{fromExtent as d,intersects as c}from"../../../../../geometry/support/aaBoundingRect.js";let u=class extends e{constructor(t){super(t),this._updatingCount=0,this._tileHandles=new s,this._wanted=new s}destroy(){for(const t of this._tileHandles.values())t.abort();this._tileHandles.clear(),this._wanted.clear()}get updating(){return this._updatingCount>0}get _boundingRect(){const{extent:t}=this;return null==t?null:d(t)}get _missingTiles(){const t=new Array,e=this._wanted;for(const i of this._tileHandles.values())e.has(i.id)&&!h(i)&&t.push(i);return t}async onTileTreeChange(t){++this._updatingCount;try{const{added:e,removed:i}=t,o=this._tileHandles,{_boundingRect:n}=this,s=null!=n?e.filter((t=>c(n,t.extent))):e,r=this._wanted,l=new Array;for(const t of i){const{id:i}=t;r.delete(i);if(e.some((e=>m(e,t)||m(t,e))))continue;const n=o.get(i);null!=n&&l.push(this._removeTile(n))}for(const t of s)r.set(t.id,t),l.push(this._addTile(t));await Promise.allSettled(l)}finally{--this._updatingCount}}async _removeTile(t){this._tileHandles.delete(t.id),t.abort(),this._validate();const{tile:e}=t,i=new g(t.untilSettled(),null!=e?this.createRemoveTileCommand(e):null);t.nextEvent=null;const{command:o}=await i.getCommand();o?.execute()}async _addTile(t){const{_tileHandles:e}=this,i=e.get(t.id);if(null!=i)return!h(i)||i.tile.isComplete||(i.tile=i.tile.reset(),i.nextEvent=this._onTileLoad(i)),void await i.untilSettled();const n=new p(t);this._tileHandles.set(n.id,n);const s=this.loadTile(t,n.signal);n.nextEvent=s;const r=await s;if(n.aborted)throw o();n.tile=r,f(n),n.nextEvent=this._onTileLoad(n),await n.untilSettled()}async _onTileLoad(t){const{_wanted:e,_tileHandles:i,_missingTiles:o}=this,n=t.descriptor,s=new Array,r=new Array,l=new Set;for(const d of i.values()){if(d===t)continue;const{descriptor:a,id:c}=d;if(e.has(c)||o.some((({descriptor:t})=>m(t,a)||m(a,t)))){if(h(d)){if(m(n,a)){const t=d.tile;for(const e of t.objectIds())l.add(e)}if(m(a,n)){const e=t.tile,i=new Set(e.objectIds()),o=d.tile,n=o.exclude(i);d.tile=n;const l=AbortSignal.any([d.signal,t.signal]),a=d.untilSettled();s.push(new g(a,this.createRemoveTileCommand(o))),s.push(new g(a,this.createAddTileCommand(n,l),l)),r.push(d),this._validateRemoval(n,i)}}}else{d.abort(),i.delete(c);const{tile:t}=d;null!=t&&s.push(new g(d.untilSettled(),this.createRemoveTileCommand(t))),d.nextEvent=null}}l.size>0&&(t.tile=t.tile.exclude(l),this._validateRemoval(t.tile,l)),s.push(new g(t.untilSettled(),this.createAddTileCommand(t.tile,t.signal),t.signal)),r.push(t),this._validate();const a=this._joinCommands(s);for(const d of r)d.nextEvent=a;await a}async _joinCommands(t){const e=(await Promise.allSettled(t.map((async t=>t.getCommand())))).map((t=>"fulfilled"!==t.status||t.value.signal?.aborted?null:t.value.command)).filter(i);if(0===e.length)return;e.reduce(((t,e)=>(t.append(e),t))).execute()}_validate(){if(!has("feature-pipeline-3d-test-validation"))return;const t=new Array;for(const e of this._tileHandles.values()){if(!h(e))continue;const{tile:i}=e,o=i.featureCount,n=new Uint32Array(o);i.readObjectIds(n),t.push({tile:i,objectIds:new Set(n)})}for(let e=0;e<t.length;++e){const{tile:i,objectIds:o}=t[e];for(let n=e+1;n<t.length;++n){const{tile:e,objectIds:s}=t[n];for(const t of s)if(o.has(t)){const o=m(e.descriptor,i.descriptor),n=m(i.descriptor,e.descriptor);throw new Error(`${i.descriptor.id} and ${e.descriptor.id} both contain ${t}. aInB: ${o}; bInA: ${n}`)}}}}_validateRemoval(t,e){if(has("feature-pipeline-3d-test-validation"))for(const i of t.objectIds())if(e.has(i))throw new Error(`Failed to remove ${i} from ${t.descriptor.id}!`)}};function m({lij:[t,e,i]},{lij:[o,n,s]}){const r=o-t;return r>=0&&e===n>>r&&i===s>>r}t([l()],u.prototype,"updating",null),t([l({constructOnly:!0})],u.prototype,"loadTile",void 0),t([l({constructOnly:!0})],u.prototype,"createAddTileCommand",void 0),t([l({constructOnly:!0})],u.prototype,"createRemoveTileCommand",void 0),t([l()],u.prototype,"_updatingCount",void 0),t([l()],u.prototype,"extent",void 0),t([l()],u.prototype,"_boundingRect",null),t([l()],u.prototype,"_missingTiles",null),u=t([a("esri.views.3d.layers.graphics.pipeline.Tile3DManager")],u);class p{constructor(t){this.descriptor=t,this._controller=new AbortController,this._tile=r(null),this.nextEvent=null}get id(){return this.descriptor.id}get tile(){return this._tile.value}set tile(t){this._tile.value=t}get signal(){return this._controller.signal}abort(){this._controller.abort()}get aborted(){return this._controller.signal.aborted}async untilSettled(){try{await this.nextEvent}catch(t){n(t)||console.error(t)}}}function h(t){return null!=t.tile}function f(t){if(!h(t))throw new Error}class g{constructor(t,e,i){this.previousEventSettled=t,this.commandPromise=e,this.signal=i}async getCommand(){const{previousEventSettled:t,commandPromise:e,signal:i}=this,[n]=await Promise.all([e,t]);if(i?.aborted)throw o();return{command:n,signal:i}}}export{u as Tile3DManager};