bruce-cesium 7.3.1 → 7.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import * as Cesium from 'cesium';
2
- import { Cartographic, Entity, DistanceDisplayCondition, ColorMaterialProperty, Color, Math as Math$1, Cartesian3, JulianDate, Quaternion, Transforms, HeadingPitchRoll, Matrix4, ConstantProperty, CallbackProperty, Primitive, Cesium3DTileFeature, ShaderSource, Ellipsoid, Geometry, GeometryAttribute, ComponentDatatype, PrimitiveType, BoundingSphere, GeometryPipeline, sampleTerrain, Texture, PixelFormat, Sampler, TextureWrap, TextureMinificationFilter, TextureMagnificationFilter, VertexArray, BufferUsage, ShaderProgram, RenderState, BlendingState, DrawCommand, Pass, Cartesian2, Cartesian4, HeightReference, ColorBlendMode, ShadowMode, ClassificationType, Model, ArcType, CornerType, ConstantPositionProperty, HorizontalOrigin, VerticalOrigin, ImageMaterialProperty, PolygonHierarchy, PolylineGraphics, Rectangle, SceneTransforms, NearFarScalar, Matrix3, KmlDataSource, GeoJsonDataSource, SceneMode, Cesium3DTileStyle, HeadingPitchRange, Ion, IonResource, Cesium3DTileColorBlendMode, Cesium3DTileset, OrthographicFrustum, EasingFunction, EllipsoidTerrainProvider, IonImageryProvider, createWorldImagery, createWorldImageryAsync, BingMapsImageryProvider, BingMapsStyle, MapboxImageryProvider, MapboxStyleImageryProvider, ArcGisMapServerImageryProvider, OpenStreetMapImageryProvider, UrlTemplateImageryProvider, GridImageryProvider, GeographicTilingScheme, ImageryLayer, TileMapServiceImageryProvider, CesiumTerrainProvider, Intersect, ModelGraphics, PolygonGraphics, CorridorGraphics, PointGraphics, BillboardGraphics, EllipseGraphics, PolylineDashMaterialProperty, EllipsoidGeodesic, sampleTerrainMostDetailed, defined, PolygonPipeline, CesiumInspector, ClockRange, DynamicEnvironmentMapManager, CustomDataSource, GeometryInstance, ScreenSpaceEventHandler, ScreenSpaceEventType, Fullscreen, CzmlDataSource } from 'cesium';
3
- import { Cartes, Entity as Entity$1, ProjectViewTile, ENVIRONMENT, Calculator, ClientFile, EntityLod, EntityTag, EntityType, LRUCache, ObjectUtils, Style, Carto, Geometry as Geometry$1, Api, MenuItem, ProjectView, ProjectViewBookmark, Tileset, ZoomControl, ClientFileValueMap, Color as Color$1, Bounds, BruceEvent, EntityCoords, DelayQueue, DataLab, AccountConcept, RecordChangeFeed, BruceApi, EntityRelation, EntitySource, Camera, ProgramKey, ProjectViewLegacyTile, Account, AccountLimits, Session, UrlUtils, ProjectViewBookmarkGroup, EntityAttachment, EntityAttachmentType, EntityAttribute, MathUtils, EntityRelationType, EntityHistoricData } from 'bruce-models';
2
+ import { Cartographic, ColorMaterialProperty, Entity, Color, ConstantProperty, CallbackProperty, Primitive, Cesium3DTileFeature, DistanceDisplayCondition, ShaderSource, Cartesian3, Math as Math$1, Ellipsoid, Transforms, Matrix4, Geometry, GeometryAttribute, ComponentDatatype, PrimitiveType, BoundingSphere, GeometryPipeline, sampleTerrain, Texture, PixelFormat, Sampler, TextureWrap, TextureMinificationFilter, TextureMagnificationFilter, VertexArray, BufferUsage, ShaderProgram, RenderState, BlendingState, DrawCommand, Pass, Cartesian2, Cartesian4, JulianDate, Quaternion, HeadingPitchRoll, ClassificationType, ArcType, HeightReference, CornerType, ShadowMode, ConstantPositionProperty, HorizontalOrigin, VerticalOrigin, ColorBlendMode, Model, SceneTransforms, ImageMaterialProperty, PolygonHierarchy, PolylineGraphics, Rectangle, NearFarScalar, Matrix3, KmlDataSource, GeoJsonDataSource, SceneMode, Cesium3DTileStyle, HeadingPitchRange, Cesium3DTileColorBlendMode, Ion, IonResource, Cesium3DTileset, EllipsoidTerrainProvider, IonImageryProvider, createWorldImagery, createWorldImageryAsync, BingMapsImageryProvider, BingMapsStyle, MapboxImageryProvider, MapboxStyleImageryProvider, ArcGisMapServerImageryProvider, OpenStreetMapImageryProvider, UrlTemplateImageryProvider, GridImageryProvider, GeographicTilingScheme, ImageryLayer, TileMapServiceImageryProvider, CesiumTerrainProvider, Intersect, OrthographicFrustum, EasingFunction, ModelGraphics, PolygonGraphics, CorridorGraphics, PointGraphics, BillboardGraphics, EllipseGraphics, PolylineDashMaterialProperty, EllipsoidGeodesic, sampleTerrainMostDetailed, defined, PolygonPipeline, CustomDataSource, CesiumInspector, ClockRange, DynamicEnvironmentMapManager, GeometryInstance, ScreenSpaceEventHandler, ScreenSpaceEventType, Fullscreen, CzmlDataSource } from 'cesium';
3
+ import { Cartes, Entity as Entity$1, ProjectViewTile, ENVIRONMENT, Calculator, Carto, EntityTag, EntityType, Geometry as Geometry$1, ObjectUtils, Style, Api, ClientFile, LRUCache, EntityLod, ClientFileValueMap, Color as Color$1, Bounds, MenuItem, ProjectView, ProjectViewBookmark, Tileset, ZoomControl, BruceEvent, EntityCoords, DataLab, DelayQueue, BruceApi, AccountConcept, RecordChangeFeed, EntityRelation, EntitySource, ProgramKey, ProjectViewLegacyTile, Camera, Account, AccountLimits, Session, UrlUtils, ProjectViewBookmarkGroup, EntityAttachment, EntityAttachmentType, EntityAttribute, MathUtils, EntityRelationType, EntityHistoricData } from 'bruce-models';
4
4
 
5
5
  /**
6
6
  * Ensures a number is returned from a given value.
@@ -9135,12 +9135,13 @@ var VisualsRegister;
9135
9135
  ReassignMenuItem(params) {
9136
9136
  var _a;
9137
9137
  const { fromMenuItemId, toMenuItemId, toMenuItemType, toPriority, requestRender, source, lazy, onBatch, onComplete } = params;
9138
+ const noop = () => { };
9138
9139
  if (!fromMenuItemId || !toMenuItemId || fromMenuItemId === toMenuItemId) {
9139
- return;
9140
+ return noop;
9140
9141
  }
9141
9142
  const entityIds = this.entityIdsByMenuItem[fromMenuItemId];
9142
9143
  if (!entityIds) {
9143
- return;
9144
+ return noop;
9144
9145
  }
9145
9146
  const idsSnapshot = Array.from(entityIds);
9146
9147
  const regoSnapshot = new Map();
@@ -9151,7 +9152,7 @@ var VisualsRegister;
9151
9152
  }
9152
9153
  }
9153
9154
  const reassignOne = (entityId) => {
9154
- var _a, _b;
9155
+ var _a, _b, _c;
9155
9156
  const regos = this.rego[entityId];
9156
9157
  if (!regos) {
9157
9158
  return null;
@@ -9170,6 +9171,7 @@ var VisualsRegister;
9170
9171
  }
9171
9172
  rego.menuItemId = toMenuItemId;
9172
9173
  rego.menuItemType = toMenuItemType;
9174
+ const priorityChanged = toPriority != null && rego.priority !== toPriority;
9173
9175
  if (toPriority != null) {
9174
9176
  rego.priority = toPriority;
9175
9177
  }
@@ -9195,15 +9197,17 @@ var VisualsRegister;
9195
9197
  }
9196
9198
  this.unindexMenuItemEntityIfAbsent(fromMenuItemId, entityId);
9197
9199
  this.indexMenuItemEntity(toMenuItemId, entityId);
9198
- this.queueUpdate({
9199
- entityId,
9200
- refresh: true
9201
- });
9200
+ // Don't queue if no register-level visual changes are required.
9201
+ if (priorityChanged || ((_c = this.states[entityId]) === null || _c === void 0 ? void 0 : _c[toMenuItemId])) {
9202
+ this.queueUpdate({
9203
+ entityId,
9204
+ refresh: true
9205
+ });
9206
+ }
9202
9207
  return rego;
9203
9208
  };
9204
9209
  if (lazy) {
9205
- this.startLazyReassign(idsSnapshot, reassignOne, requestRender, onBatch, onComplete);
9206
- return;
9210
+ return this.startLazyReassign(idsSnapshot, reassignOne, requestRender, onBatch, onComplete);
9207
9211
  }
9208
9212
  for (const entityId of idsSnapshot) {
9209
9213
  reassignOne(entityId);
@@ -9211,17 +9215,12 @@ var VisualsRegister;
9211
9215
  if (requestRender != false) {
9212
9216
  this.viewer.scene.requestRender();
9213
9217
  }
9218
+ return noop;
9214
9219
  }
9215
9220
  startLazyReassign(entityIds, reassignOne, requestRender, onBatch, onComplete) {
9216
9221
  const BATCH_SIZE = 5000;
9217
9222
  let index = 0;
9218
- const interval = setInterval(() => {
9219
- if (this.Disposed) {
9220
- clearInterval(interval);
9221
- this.activeChunkedIntervals.delete(interval);
9222
- return;
9223
- }
9224
- const end = Math.min(index + BATCH_SIZE, entityIds.length);
9223
+ const runTo = (end) => {
9225
9224
  const batch = [];
9226
9225
  for (; index < end; index++) {
9227
9226
  const rego = reassignOne(entityIds[index]);
@@ -9235,6 +9234,14 @@ var VisualsRegister;
9235
9234
  if (requestRender != false) {
9236
9235
  this.viewer.scene.requestRender();
9237
9236
  }
9237
+ };
9238
+ const interval = setInterval(() => {
9239
+ if (this.Disposed) {
9240
+ clearInterval(interval);
9241
+ this.activeChunkedIntervals.delete(interval);
9242
+ return;
9243
+ }
9244
+ runTo(Math.min(index + BATCH_SIZE, entityIds.length));
9238
9245
  if (index >= entityIds.length) {
9239
9246
  clearInterval(interval);
9240
9247
  this.activeChunkedIntervals.delete(interval);
@@ -9242,6 +9249,14 @@ var VisualsRegister;
9242
9249
  }
9243
9250
  }, 10);
9244
9251
  this.activeChunkedIntervals.add(interval);
9252
+ return (finishRemaining) => {
9253
+ clearInterval(interval);
9254
+ this.activeChunkedIntervals.delete(interval);
9255
+ if (finishRemaining && !this.Disposed) {
9256
+ runTo(entityIds.length);
9257
+ onComplete === null || onComplete === void 0 ? void 0 : onComplete();
9258
+ }
9259
+ };
9245
9260
  }
9246
9261
  /**
9247
9262
  * Locates a visual corresponding to a given entity id.
@@ -9364,7 +9379,7 @@ var VisualsRegister;
9364
9379
  }
9365
9380
  }
9366
9381
  const removeOne = (entityId) => {
9367
- var _a;
9382
+ var _a, _b;
9368
9383
  const entityRegos = this.rego[entityId];
9369
9384
  if (!entityRegos) {
9370
9385
  return;
@@ -9403,15 +9418,24 @@ var VisualsRegister;
9403
9418
  if (source !== EUpdateSource.TREE_CASCADE) {
9404
9419
  (_a = this.onUpdate) === null || _a === void 0 ? void 0 : _a.Trigger(update);
9405
9420
  }
9406
- if (doesInclude) {
9421
+ // Only worth refreshing while the Entity is still drawn by something else, since
9422
+ // losing this rego can change which of the survivors wins. With none left there is
9423
+ // nothing to restyle, and queueing one per removed Entity is what turns disabling a
9424
+ // large menu item into minutes of scheduled work.
9425
+ if (doesInclude && ((_b = this.rego[entityId]) === null || _b === void 0 ? void 0 : _b.length)) {
9407
9426
  this.queueUpdate({
9408
9427
  entityId: entityId,
9409
9428
  refresh: false
9410
9429
  });
9411
9430
  }
9412
9431
  };
9432
+ const finish = () => {
9433
+ this.releaseMenuItemCollection(menuItemId);
9434
+ this.RemoveTilesetsByMenuItem(menuItemId);
9435
+ onComplete === null || onComplete === void 0 ? void 0 : onComplete();
9436
+ };
9413
9437
  if (lazy) {
9414
- this.startLazyRemoval(entityIds, removeOne, onComplete);
9438
+ this.startLazyRemoval(entityIds, removeOne, finish);
9415
9439
  return;
9416
9440
  }
9417
9441
  WithSuspendedCCollections(this.allSceneCollections(), () => {
@@ -9419,8 +9443,7 @@ var VisualsRegister;
9419
9443
  removeOne(entityId);
9420
9444
  }
9421
9445
  });
9422
- this.releaseMenuItemCollection(menuItemId);
9423
- this.RemoveTilesetsByMenuItem(menuItemId);
9446
+ finish();
9424
9447
  }
9425
9448
  else if (entityId) {
9426
9449
  const entityRegos = this.rego[entityId];
@@ -14412,6 +14435,14 @@ class EntityGatherer {
14412
14435
  this.disposed = true;
14413
14436
  this.hDisposals.forEach((d) => d());
14414
14437
  this.hDisposals = [];
14438
+ // A tick still awaiting a response resumes after this, and anything left here would have it
14439
+ // ask for the whole set again on the way out.
14440
+ this.eIdQueue = [];
14441
+ this.eIdQueued.clear();
14442
+ this.priorityCount = 0;
14443
+ this.allEIds.clear();
14444
+ this.lastFoundDateTimes.clear();
14445
+ this.entityDataOverrides.clear();
14415
14446
  }
14416
14447
  checkRange(force) {
14417
14448
  const min = this.viewer.clock.startTime.toString();
@@ -14424,7 +14455,7 @@ class EntityGatherer {
14424
14455
  }
14425
14456
  }
14426
14457
  onTick(force) {
14427
- if (this.runningTick) {
14458
+ if (this.runningTick || this.disposed) {
14428
14459
  return;
14429
14460
  }
14430
14461
  const rTime = this.viewer.clock.currentTime.toString();
@@ -16229,9 +16260,12 @@ var TilesetCadRenderManager;
16229
16260
  // Removal callbacks for this instance's own tile stream listeners.
16230
16261
  this.tileLoadRemoval = null;
16231
16262
  this.tileUnloadRemoval = null;
16232
- // Chunks AdoptHandoff()'s restyle of handed-off content across ticks instead of one
16233
- // synchronous pass over potentially millions of regos.
16234
- this.handoffRestyleInterval = null;
16263
+ // Cancels AdoptHandoff()'s chunked re-parent of handed-off content, which runs across ticks
16264
+ // instead of one synchronous pass over potentially millions of regos.
16265
+ this.handoffReassignCancel = null;
16266
+ // Menu item the in-flight re-parent is still pulling regos off, so a teardown mid-swap can
16267
+ // clear both sides rather than orphaning whatever had not moved yet.
16268
+ this.handoffSourceMenuItemId = null;
16235
16269
  this.styler = new TilesetRenderEngine.Styler();
16236
16270
  this.modelTreeUpdate = new BruceEvent();
16237
16271
  // Quick look-up of the model tree nodes by entity/geomId.
@@ -16560,7 +16594,7 @@ var TilesetCadRenderManager;
16560
16594
  }
16561
16595
  // Returns null (fall back to a normal Dispose()) if the tileset hasn't finished loading yet.
16562
16596
  PrepareHandoff() {
16563
- var _a, _b, _c;
16597
+ var _a, _b, _c, _d;
16564
16598
  if (this.disposed || !this.cTileset || this.cTileset.isDestroyed()) {
16565
16599
  return null;
16566
16600
  }
@@ -16572,15 +16606,15 @@ var TilesetCadRenderManager;
16572
16606
  clearInterval(this.featureQueueInterval);
16573
16607
  this.featureQueueInterval = null;
16574
16608
  }
16575
- if (this.handoffRestyleInterval) {
16576
- clearInterval(this.handoffRestyleInterval);
16577
- this.handoffRestyleInterval = null;
16578
- }
16609
+ // Settle a re-parent still in flight, so what is handed on is not split across two menu items.
16610
+ (_a = this.handoffReassignCancel) === null || _a === void 0 ? void 0 : _a.call(this, true);
16611
+ this.handoffReassignCancel = null;
16612
+ this.handoffSourceMenuItemId = null;
16579
16613
  // Not transferred, the receiving manager sets up its own fresh copy if needed.
16580
16614
  this.viewerDateTimeDispose();
16581
- (_a = this.styler) === null || _a === void 0 ? void 0 : _a.Dispose();
16582
- (_b = this.tileLoadRemoval) === null || _b === void 0 ? void 0 : _b.call(this);
16583
- (_c = this.tileUnloadRemoval) === null || _c === void 0 ? void 0 : _c.call(this);
16615
+ (_b = this.styler) === null || _b === void 0 ? void 0 : _b.Dispose();
16616
+ (_c = this.tileLoadRemoval) === null || _c === void 0 ? void 0 : _c.call(this);
16617
+ (_d = this.tileUnloadRemoval) === null || _d === void 0 ? void 0 : _d.call(this);
16584
16618
  this.tileLoadRemoval = null;
16585
16619
  this.tileUnloadRemoval = null;
16586
16620
  const payload = {
@@ -16630,13 +16664,6 @@ var TilesetCadRenderManager;
16630
16664
  }
16631
16665
  });
16632
16666
  // Same visuals, same registrations so just re-keyed onto this menu item.
16633
- this.visualsManager.ReassignMenuItem({
16634
- fromMenuItemId: payload.sourceMenuItemId,
16635
- toMenuItemId: this.item.id,
16636
- toMenuItemType: this.item.Type,
16637
- toPriority: this.renderPriority,
16638
- requestRender: false
16639
- });
16640
16667
  this.onCTilesetLoad();
16641
16668
  this.styler.Init({
16642
16669
  viewer: this.viewer,
@@ -16650,33 +16677,32 @@ var TilesetCadRenderManager;
16650
16677
  scenario: (_b = this.item.BruceEntity) === null || _b === void 0 ? void 0 : _b.Scenario,
16651
16678
  historic: (_c = this.item.BruceEntity) === null || _c === void 0 ? void 0 : _c.historic,
16652
16679
  });
16653
- this.queueHandoffRestyle(this.visualsManager.GetRegos({ menuItemId: this.item.id }));
16680
+ // A swap runs inside a render pass, so re-parenting a whole tileset in one go stalls it.
16681
+ // Each batch is restyled as it lands rather than after a second walk of the same set.
16682
+ this.handoffSourceMenuItemId = payload.sourceMenuItemId;
16683
+ this.handoffReassignCancel = this.visualsManager.ReassignMenuItem({
16684
+ fromMenuItemId: payload.sourceMenuItemId,
16685
+ toMenuItemId: this.item.id,
16686
+ toMenuItemType: this.item.Type,
16687
+ toPriority: this.renderPriority,
16688
+ requestRender: false,
16689
+ lazy: true,
16690
+ onBatch: (regos) => {
16691
+ if (this.disposed) {
16692
+ return;
16693
+ }
16694
+ this.styler.QueueEntities(regos, true);
16695
+ },
16696
+ onComplete: () => {
16697
+ this.handoffReassignCancel = null;
16698
+ this.handoffSourceMenuItemId = null;
16699
+ }
16700
+ });
16654
16701
  this.viewer.scene.requestRender();
16655
16702
  if (((_d = this.item.BruceEntity) === null || _d === void 0 ? void 0 : _d.historic) && this.tileset) {
16656
16703
  this.viewerDateTimeSub(this.tileset);
16657
16704
  }
16658
16705
  }
16659
- queueHandoffRestyle(regos) {
16660
- if (!regos.length) {
16661
- return;
16662
- }
16663
- const BATCH_SIZE = 5000;
16664
- let index = 0;
16665
- this.handoffRestyleInterval = setInterval(() => {
16666
- if (this.disposed) {
16667
- clearInterval(this.handoffRestyleInterval);
16668
- this.handoffRestyleInterval = null;
16669
- return;
16670
- }
16671
- const end = Math.min(index + BATCH_SIZE, regos.length);
16672
- this.styler.QueueEntities(regos.slice(index, end), true);
16673
- index = end;
16674
- if (index >= regos.length) {
16675
- clearInterval(this.handoffRestyleInterval);
16676
- this.handoffRestyleInterval = null;
16677
- }
16678
- }, 10);
16679
- }
16680
16706
  /**
16681
16707
  * @param tile
16682
16708
  * @param load indicates if we are loading or unloading the tile.
@@ -17228,33 +17254,40 @@ var TilesetCadRenderManager;
17228
17254
  this.doDispose();
17229
17255
  }
17230
17256
  doDispose() {
17231
- var _a, _b;
17257
+ var _a, _b, _c;
17232
17258
  if (this.featureQueueInterval) {
17233
17259
  clearInterval(this.featureQueueInterval);
17234
17260
  this.featureQueueInterval = null;
17235
17261
  this.featureQueue = [];
17236
17262
  }
17237
- if (this.handoffRestyleInterval) {
17238
- clearInterval(this.handoffRestyleInterval);
17239
- this.handoffRestyleInterval = null;
17240
- }
17263
+ (_a = this.handoffReassignCancel) === null || _a === void 0 ? void 0 : _a.call(this);
17264
+ this.handoffReassignCancel = null;
17241
17265
  if (this.cTileset) {
17242
17266
  const viewer = this.viewer;
17243
17267
  if (!(viewer === null || viewer === void 0 ? void 0 : viewer.isDestroyed()) && this.viewer.scene.primitives.contains(this.cTileset)) {
17244
17268
  this.cTileset.show = false;
17245
17269
  this.viewer.scene.primitives.remove(this.cTileset);
17246
- (_a = TilesetRenderEngine.GetMemoryWatcher(viewer)) === null || _a === void 0 ? void 0 : _a.Unwatch(this.cTileset);
17270
+ (_b = TilesetRenderEngine.GetMemoryWatcher(viewer)) === null || _b === void 0 ? void 0 : _b.Unwatch(this.cTileset);
17247
17271
  this.viewer.scene.requestRender();
17248
17272
  }
17249
17273
  this.cTileset = null;
17250
17274
  }
17251
- (_b = this.styler) === null || _b === void 0 ? void 0 : _b.Dispose();
17275
+ (_c = this.styler) === null || _c === void 0 ? void 0 : _c.Dispose();
17252
17276
  this.visualsManager.RemoveRegos({
17253
17277
  menuItemId: this.item.id,
17254
17278
  doRemove: false,
17255
17279
  source: VisualsRegister.EUpdateSource.TILESET_DISPOSE,
17256
17280
  lazy: true
17257
17281
  });
17282
+ if (this.handoffSourceMenuItemId) {
17283
+ this.visualsManager.RemoveRegos({
17284
+ menuItemId: this.handoffSourceMenuItemId,
17285
+ doRemove: false,
17286
+ source: VisualsRegister.EUpdateSource.TILESET_DISPOSE,
17287
+ lazy: true
17288
+ });
17289
+ this.handoffSourceMenuItemId = null;
17290
+ }
17258
17291
  this.viewerDateTimeDispose();
17259
17292
  }
17260
17293
  async ReRender(params) {
@@ -20013,9 +20046,12 @@ var TilesetEntitiesRenderManager;
20013
20046
  // Removal callbacks for this instance's own tile stream listeners.
20014
20047
  this.tileLoadRemoval = null;
20015
20048
  this.tileUnloadRemoval = null;
20016
- // Chunks AdoptHandoff()'s restyle of handed-off content across ticks instead of one
20017
- // synchronous pass over potentially millions of regos.
20018
- this.handoffRestyleInterval = null;
20049
+ // Cancels AdoptHandoff()'s chunked re-parent of handed-off content, which runs across ticks
20050
+ // instead of one synchronous pass over potentially millions of regos.
20051
+ this.handoffReassignCancel = null;
20052
+ // Menu item the in-flight re-parent is still pulling regos off, so a teardown mid-swap can
20053
+ // clear both sides rather than orphaning whatever had not moved yet.
20054
+ this.handoffSourceMenuItemId = null;
20019
20055
  this.styler = new TilesetRenderEngine.Styler();
20020
20056
  // Entity ID -> rego.
20021
20057
  // We retain this information as a quick look-up on what has been registered.
@@ -20328,31 +20364,36 @@ var TilesetEntitiesRenderManager;
20328
20364
  this.doDispose();
20329
20365
  }
20330
20366
  doDispose() {
20331
- var _a, _b;
20367
+ var _a, _b, _c;
20332
20368
  if (this.featureQueueInterval) {
20333
20369
  clearInterval(this.featureQueueInterval);
20334
20370
  this.featureQueueInterval = null;
20335
20371
  this.featureQueue = [];
20336
20372
  }
20337
- if (this.handoffRestyleInterval) {
20338
- clearInterval(this.handoffRestyleInterval);
20339
- this.handoffRestyleInterval = null;
20340
- }
20373
+ (_a = this.handoffReassignCancel) === null || _a === void 0 ? void 0 : _a.call(this);
20374
+ this.handoffReassignCancel = null;
20341
20375
  if (this.cTileset) {
20342
20376
  const viewer = this.viewer;
20343
20377
  if (!(viewer === null || viewer === void 0 ? void 0 : viewer.isDestroyed()) && this.viewer.scene.primitives.contains(this.cTileset)) {
20344
20378
  this.cTileset.show = false;
20345
20379
  this.viewer.scene.primitives.remove(this.cTileset);
20346
- (_a = TilesetRenderEngine.GetMemoryWatcher(viewer)) === null || _a === void 0 ? void 0 : _a.Unwatch(this.cTileset);
20380
+ (_b = TilesetRenderEngine.GetMemoryWatcher(viewer)) === null || _b === void 0 ? void 0 : _b.Unwatch(this.cTileset);
20347
20381
  this.viewer.scene.requestRender();
20348
20382
  }
20349
20383
  this.cTileset = null;
20350
20384
  }
20351
- (_b = this.styler) === null || _b === void 0 ? void 0 : _b.Dispose();
20385
+ (_c = this.styler) === null || _c === void 0 ? void 0 : _c.Dispose();
20352
20386
  this.visualsManager.RemoveRegos({
20353
20387
  menuItemId: this.item.id,
20354
20388
  lazy: true
20355
20389
  });
20390
+ if (this.handoffSourceMenuItemId) {
20391
+ this.visualsManager.RemoveRegos({
20392
+ menuItemId: this.handoffSourceMenuItemId,
20393
+ lazy: true
20394
+ });
20395
+ this.handoffSourceMenuItemId = null;
20396
+ }
20356
20397
  }
20357
20398
  onCTilesetLoad() {
20358
20399
  if (this.item.FlyTo) {
@@ -20392,7 +20433,7 @@ var TilesetEntitiesRenderManager;
20392
20433
  }
20393
20434
  // Returns null (fall back to a normal Dispose()) if the tileset hasn't finished loading yet.
20394
20435
  PrepareHandoff() {
20395
- var _a, _b, _c;
20436
+ var _a, _b, _c, _d;
20396
20437
  if (this.disposed || !this.cTileset || this.cTileset.isDestroyed()) {
20397
20438
  return null;
20398
20439
  }
@@ -20404,13 +20445,13 @@ var TilesetEntitiesRenderManager;
20404
20445
  clearInterval(this.featureQueueInterval);
20405
20446
  this.featureQueueInterval = null;
20406
20447
  }
20407
- if (this.handoffRestyleInterval) {
20408
- clearInterval(this.handoffRestyleInterval);
20409
- this.handoffRestyleInterval = null;
20410
- }
20411
- (_a = this.styler) === null || _a === void 0 ? void 0 : _a.Dispose();
20412
- (_b = this.tileLoadRemoval) === null || _b === void 0 ? void 0 : _b.call(this);
20413
- (_c = this.tileUnloadRemoval) === null || _c === void 0 ? void 0 : _c.call(this);
20448
+ // Settle a re-parent still in flight, so what is handed on is not split across two menu items.
20449
+ (_a = this.handoffReassignCancel) === null || _a === void 0 ? void 0 : _a.call(this, true);
20450
+ this.handoffReassignCancel = null;
20451
+ this.handoffSourceMenuItemId = null;
20452
+ (_b = this.styler) === null || _b === void 0 ? void 0 : _b.Dispose();
20453
+ (_c = this.tileLoadRemoval) === null || _c === void 0 ? void 0 : _c.call(this);
20454
+ (_d = this.tileUnloadRemoval) === null || _d === void 0 ? void 0 : _d.call(this);
20414
20455
  this.tileLoadRemoval = null;
20415
20456
  this.tileUnloadRemoval = null;
20416
20457
  const payload = {
@@ -20452,14 +20493,8 @@ var TilesetEntitiesRenderManager;
20452
20493
  console.error(e);
20453
20494
  }
20454
20495
  });
20455
- this.visualsManager.ReassignMenuItem({
20456
- fromMenuItemId: payload.sourceMenuItemId,
20457
- toMenuItemId: this.item.id,
20458
- toMenuItemType: this.item.Type,
20459
- toPriority: this.renderPriority,
20460
- requestRender: false
20461
- });
20462
- if (Manager.NeedsStyler(this.item)) {
20496
+ const needsStyler = Manager.NeedsStyler(this.item);
20497
+ if (needsStyler) {
20463
20498
  this.styler.Init({
20464
20499
  viewer: this.viewer,
20465
20500
  api: this.getters.GetBruceApi(),
@@ -20473,8 +20508,28 @@ var TilesetEntitiesRenderManager;
20473
20508
  applyStyles: Boolean(this.item.ApplyStyles),
20474
20509
  monitor: this.monitor
20475
20510
  });
20476
- this.queueHandoffRestyle(this.visualsManager.GetRegos({ menuItemId: this.item.id }));
20477
20511
  }
20512
+ // A swap runs inside a render pass, so re-parenting a whole Entities Set in one go stalls it.
20513
+ // Each batch is restyled as it lands rather than after a second walk of the same set.
20514
+ this.handoffSourceMenuItemId = payload.sourceMenuItemId;
20515
+ this.handoffReassignCancel = this.visualsManager.ReassignMenuItem({
20516
+ fromMenuItemId: payload.sourceMenuItemId,
20517
+ toMenuItemId: this.item.id,
20518
+ toMenuItemType: this.item.Type,
20519
+ toPriority: this.renderPriority,
20520
+ requestRender: false,
20521
+ lazy: true,
20522
+ onBatch: (regos) => {
20523
+ if (this.disposed || !needsStyler) {
20524
+ return;
20525
+ }
20526
+ this.styler.QueueEntities(regos, true);
20527
+ },
20528
+ onComplete: () => {
20529
+ this.handoffReassignCancel = null;
20530
+ this.handoffSourceMenuItemId = null;
20531
+ }
20532
+ });
20478
20533
  this.onCTilesetLoad();
20479
20534
  let attenuation = this.item.attenuation;
20480
20535
  if (!attenuation && attenuation != false) {
@@ -20493,27 +20548,6 @@ var TilesetEntitiesRenderManager;
20493
20548
  });
20494
20549
  this.viewer.scene.requestRender();
20495
20550
  }
20496
- queueHandoffRestyle(regos) {
20497
- if (!regos.length) {
20498
- return;
20499
- }
20500
- const BATCH_SIZE = 5000;
20501
- let index = 0;
20502
- this.handoffRestyleInterval = setInterval(() => {
20503
- if (this.disposed) {
20504
- clearInterval(this.handoffRestyleInterval);
20505
- this.handoffRestyleInterval = null;
20506
- return;
20507
- }
20508
- const end = Math.min(index + BATCH_SIZE, regos.length);
20509
- this.styler.QueueEntities(regos.slice(index, end), true);
20510
- index = end;
20511
- if (index >= regos.length) {
20512
- clearInterval(this.handoffRestyleInterval);
20513
- this.handoffRestyleInterval = null;
20514
- }
20515
- }, 10);
20516
- }
20517
20551
  /*
20518
20552
  * Reads a numeric feature property, returning null for anything that is not one.
20519
20553
  */
@@ -46394,7 +46428,7 @@ var StyleUtils;
46394
46428
  StyleUtils.ApplyTypeStyle = ApplyTypeStyle;
46395
46429
  })(StyleUtils || (StyleUtils = {}));
46396
46430
 
46397
- const VERSION = "7.3.1";
46431
+ const VERSION = "7.3.2";
46398
46432
  /**
46399
46433
  * Updates the environment instance used by bruce-cesium to one specified.
46400
46434
  * This can be used to ensure that the instance a parent is referencing is shared between bruce-cesium, bruce-models, and the parent app.