Skip to content

Commit 3f35764

Browse files
authored
Merge pull request #8546 from AnalyticalGraphicsInc/8321/polyline_crash
8321/polyline crash
2 parents 4ac1ae5 + 080a3fa commit 3f35764

File tree

4 files changed

+33
-21
lines changed

4 files changed

+33
-21
lines changed

CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ Change Log
4141
* Fixed a bug where toggling point cloud classification visibility would result in a grey screen on Linux / Nvidia [#8538](https://github.com/AnalyticalGraphicsInc/cesium/pull/8538)
4242
* Fixed a bug where a point in a `PointPrimitiveCollection` is rendered in the middle of the screen instead of being clipped. [#8542](https://github.com/AnalyticalGraphicsInc/cesium/pull/8542)
4343
* Fixed a crash when deleting and re-creating polylines from CZML. `ReferenceProperty` now returns undefined when the target entity or property does not exist, instead of throwing. [#8544](https://github.com/AnalyticalGraphicsInc/cesium/pull/8544)
44+
* Fixed a bug where rapidly updating a PolylineCollection could result in an instanceIndex is out of range error [#8546](https://github.com/AnalyticalGraphicsInc/cesium/pull/8546)
4445

4546
### 1.65.0 - 2020-01-06
4647

Source/Scene/Polyline.js

+13
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,19 @@ import Material from './Material.js';
285285
}
286286
},
287287

288+
/**
289+
* Gets the destruction status of this polyline
290+
* @memberof Polyline.prototype
291+
* @type {Boolean}
292+
* @default false
293+
* @private
294+
*/
295+
isDestroyed : {
296+
get : function() {
297+
return !defined(this._polylineCollection);
298+
}
299+
},
300+
288301
/**
289302
* Gets or sets the condition specifying at what distance from the camera that this polyline will be displayed.
290303
* @memberof Polyline.prototype

Source/Scene/PolylineCollection.js

+14-17
Original file line numberDiff line numberDiff line change
@@ -257,13 +257,6 @@ import SceneMode from './SceneMode.js';
257257
*/
258258
PolylineCollection.prototype.remove = function(polyline) {
259259
if (this.contains(polyline)) {
260-
this._polylines[polyline._index] = undefined; // Removed later
261-
262-
var polylineUpdateIndex = this._polylinesToUpdate.indexOf(polyline);
263-
if (polylineUpdateIndex !== -1) {
264-
this._polylinesToUpdate.splice(polylineUpdateIndex, 1);
265-
}
266-
267260
this._polylinesRemoved = true;
268261
this._createVertexArray = true;
269262
this._createBatchTable = true;
@@ -1049,27 +1042,31 @@ import SceneMode from './SceneMode.js';
10491042
function removePolylines(collection) {
10501043
if (collection._polylinesRemoved) {
10511044
collection._polylinesRemoved = false;
1052-
1053-
var polylines = [];
1045+
var definedPolylines = [];
1046+
var definedPolylinesToUpdate = [];
1047+
var polyIndex = 0;
1048+
var polyline;
10541049

10551050
var length = collection._polylines.length;
1056-
for ( var i = 0, j = 0; i < length; ++i) {
1057-
var polyline = collection._polylines[i];
1058-
if (defined(polyline)) {
1059-
polyline._index = j++;
1060-
polylines.push(polyline);
1051+
for (var i = 0; i < length; ++i) {
1052+
polyline = collection._polylines[i];
1053+
if (!polyline.isDestroyed) {
1054+
polyline._index = polyIndex++;
1055+
definedPolylinesToUpdate.push(polyline);
1056+
definedPolylines.push(polyline);
10611057
}
10621058
}
10631059

1064-
collection._polylines = polylines;
1060+
collection._polylines = definedPolylines;
1061+
collection._polylinesToUpdate = definedPolylinesToUpdate;
10651062
}
10661063
}
10671064

10681065
function releaseShaders(collection) {
10691066
var polylines = collection._polylines;
10701067
var length = polylines.length;
10711068
for ( var i = 0; i < length; ++i) {
1072-
if (defined(polylines[i])) {
1069+
if (!polylines[i].isDestroyed) {
10731070
var bucket = polylines[i]._bucket;
10741071
if (defined(bucket)) {
10751072
bucket.shaderProgram = bucket.shaderProgram && bucket.shaderProgram.destroy();
@@ -1098,7 +1095,7 @@ import SceneMode from './SceneMode.js';
10981095
var polylines = collection._polylines;
10991096
var length = polylines.length;
11001097
for ( var i = 0; i < length; ++i) {
1101-
if (defined(polylines[i])) {
1098+
if (!polylines[i].isDestroyed) {
11021099
polylines[i]._destroy();
11031100
}
11041101
}

Specs/Scene/PolylineCollectionSpec.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -316,31 +316,32 @@ describe('Scene/PolylineCollection', function() {
316316
expect(polylines.length).toEqual(0);
317317
});
318318

319-
it('removes a polyline from the updated list when removed', function() {
319+
it('removal of polyline from polyLinesToUpdate is deferred until scene is updated', function() {
320320
var firstPolyline = polylines.add();
321321
var secondPolyline = polylines.add();
322322

323323
firstPolyline.width = 4;
324324
secondPolyline.width = 5;
325325

326326
expect(polylines._polylinesToUpdate.length).toEqual(2);
327-
328327
polylines.remove(secondPolyline);
328+
polylines.update(scene.frameState);
329329

330330
expect(polylines._polylinesToUpdate.length).toEqual(1);
331331
});
332332

333-
it('only adds polyline to the update list once', function() {
333+
it('removal of polyline from polylinesToUpdate after polyline is made dirty multiple times', function() {
334334
var firstPolyline = polylines.add();
335335
var secondPolyline = polylines.add();
336336

337337
firstPolyline.width = 4;
338338
secondPolyline.width = 5;
339-
secondPolyline.width = 7;
339+
secondPolyline.width = 7; // Making the polyline dirty twice shouldn't affect the length of `_polylinesToUpdate`
340340

341341
expect(polylines._polylinesToUpdate.length).toEqual(2);
342342

343343
polylines.remove(secondPolyline);
344+
polylines.update(scene.frameState);
344345

345346
expect(polylines._polylinesToUpdate.length).toEqual(1);
346347
});

0 commit comments

Comments
 (0)