diff --git a/CHANGES.md b/CHANGES.md index b006a8406260..a40ecbeeb53a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -20,6 +20,7 @@ Change Log ##### Fixes :wrench: * Fixed a bug causing custom TilingScheme classes to not be able to use a GeographicProjection. [#6524](https://github.com/AnalyticalGraphicsInc/cesium/pull/6524) +* Fixed incorrect 3D Tiles statistics when a tile fails during processing. [#6558](https://github.com/AnalyticalGraphicsInc/cesium/pull/6558) * Fixed race condition causing intermittent crash when changing geometry show value [#3061](https://github.com/AnalyticalGraphicsInc/cesium/issues/3061) * `ProviderViewModel`s with no category are displayed in an untitled group in `BaseLayerPicker` instead of being labeled as `'Other'` [#6574](https://github.com/AnalyticalGraphicsInc/cesium/pull/6574) diff --git a/Source/Scene/Cesium3DTileset.js b/Source/Scene/Cesium3DTileset.js index 4135bdc83490..5ef76da10c92 100644 --- a/Source/Scene/Cesium3DTileset.js +++ b/Source/Scene/Cesium3DTileset.js @@ -1435,25 +1435,8 @@ define([ ++statistics.numberOfPendingRequests; - var removeFunction = removeFromProcessingQueue(tileset, tile); tile.contentReadyToProcessPromise.then(addToProcessingQueue(tileset, tile)); - tile.contentReadyPromise.then(function() { - removeFunction(); - tileset.tileLoad.raiseEvent(tile); - }).otherwise(function(error) { - removeFunction(); - var url = tile._contentResource.url; - var message = defined(error.message) ? error.message : error.toString(); - if (tileset.tileFailed.numberOfListeners > 0) { - tileset.tileFailed.raiseEvent({ - url : url, - message : message - }); - } else { - console.log('A 3D tile failed to load: ' + url); - console.log('Error: ' + message); - } - }); + tile.contentReadyPromise.then(handleTileSuccess(tileset, tile)).otherwise(handleTileFailure(tileset, tile)); } function requestTiles(tileset, outOfCore) { @@ -1476,15 +1459,32 @@ define([ }; } - function removeFromProcessingQueue(tileset, tile) { - return function() { - if (tile._contentState === Cesium3DTileContentState.FAILED) { - // Not in processing queue - // For example, when a url request fails and the ready promise is rejected + function handleTileFailure(tileset, tile) { + return function(error) { + if (tileset._processingQueue.indexOf(tile) >= 0) { + // Failed during processing + --tileset._statistics.numberOfTilesProcessing; + } else { + // Failed when making request --tileset._statistics.numberOfPendingRequests; - return; } + var url = tile._contentResource.url; + var message = defined(error.message) ? error.message : error.toString(); + if (tileset.tileFailed.numberOfListeners > 0) { + tileset.tileFailed.raiseEvent({ + url : url, + message : message + }); + } else { + console.log('A 3D tile failed to load: ' + url); + console.log('Error: ' + message); + } + }; + } + + function handleTileSuccess(tileset, tile) { + return function() { --tileset._statistics.numberOfTilesProcessing; if (tile.hasRenderableContent) { @@ -1498,6 +1498,8 @@ define([ tile.replacementNode = tileset._replacementList.add(tile); } } + + tileset.tileLoad.raiseEvent(tile); }; } diff --git a/Specs/Scene/Cesium3DTilesetSpec.js b/Specs/Scene/Cesium3DTilesetSpec.js index 8f6985c0870b..e6c71724ed90 100644 --- a/Specs/Scene/Cesium3DTilesetSpec.js +++ b/Specs/Scene/Cesium3DTilesetSpec.js @@ -480,6 +480,38 @@ defineSuite([ fail('should not resolve'); }).otherwise(function(error) { expect(root._contentState).toEqual(Cesium3DTileContentState.FAILED); + var statistics = tileset.statistics; + expect(statistics.numberOfAttemptedRequests).toBe(0); + expect(statistics.numberOfPendingRequests).toBe(0); + expect(statistics.numberOfTilesProcessing).toBe(0); + expect(statistics.numberOfTilesWithContentReady).toBe(0); + }); + }); + }); + + it('handles failed tile processing', function() { + viewRootOnly(); + var tileset = scene.primitives.add(new Cesium3DTileset({ + url : tilesetUrl + })); + return tileset.readyPromise.then(function(tileset) { + // Start spying after the tileset json has been loaded + spyOn(Resource._Implementations, 'loadWithXhr').and.callFake(function(url, responseType, method, data, headers, deferred, overrideMimeType) { + deferred.resolve(Cesium3DTilesTester.generateBatchedTileBuffer({ + version : 0 // Invalid version + })); + }); + scene.renderForSpecs(); // Request root + var root = tileset._root; + return root.contentReadyPromise.then(function() { + fail('should not resolve'); + }).otherwise(function(error) { + expect(root._contentState).toEqual(Cesium3DTileContentState.FAILED); + var statistics = tileset.statistics; + expect(statistics.numberOfAttemptedRequests).toBe(0); + expect(statistics.numberOfPendingRequests).toBe(0); + expect(statistics.numberOfTilesProcessing).toBe(0); + expect(statistics.numberOfTilesWithContentReady).toBe(0); }); }); });