From dde9fb5bc42c6a5e9fd3e97dbfbd1b91f77456de Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Thu, 7 Sep 2017 20:32:12 +0200 Subject: [PATCH] Fix abort handling of tileload events --- src/ol/source/tileeventtype.js | 3 +- src/ol/source/urltile.js | 35 ++++++++------- test/spec/ol/source/tileimage.test.js | 64 +++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 16 deletions(-) diff --git a/src/ol/source/tileeventtype.js b/src/ol/source/tileeventtype.js index 273fe96dd0..c62ea14bc1 100644 --- a/src/ol/source/tileeventtype.js +++ b/src/ol/source/tileeventtype.js @@ -13,7 +13,8 @@ ol.source.TileEventType = { TILELOADSTART: 'tileloadstart', /** - * Triggered when a tile finishes loading. + * Triggered when a tile finishes loading, either when its data is loaded, + * or when loading was aborted because the tile is no longer needed. * @event ol.source.Tile.Event#tileloadend * @api */ diff --git a/src/ol/source/urltile.js b/src/ol/source/urltile.js index bb1d73c7aa..c66d78d515 100644 --- a/src/ol/source/urltile.js +++ b/src/ol/source/urltile.js @@ -61,6 +61,12 @@ ol.source.UrlTile = function(options) { this.setTileUrlFunction(options.tileUrlFunction); } + /** + * @private + * @type {Object.} + */ + this.tileLoadingKeys_ = {}; + }; ol.inherits(ol.source.UrlTile, ol.source.Tile); @@ -110,21 +116,20 @@ ol.source.UrlTile.prototype.getUrls = function() { */ ol.source.UrlTile.prototype.handleTileChange = function(event) { var tile = /** @type {ol.Tile} */ (event.target); - switch (tile.getState()) { - case ol.TileState.LOADING: - this.dispatchEvent( - new ol.source.Tile.Event(ol.source.TileEventType.TILELOADSTART, tile)); - break; - case ol.TileState.LOADED: - this.dispatchEvent( - new ol.source.Tile.Event(ol.source.TileEventType.TILELOADEND, tile)); - break; - case ol.TileState.ERROR: - this.dispatchEvent( - new ol.source.Tile.Event(ol.source.TileEventType.TILELOADERROR, tile)); - break; - default: - // pass + var uid = ol.getUid(tile); + var tileState = tile.getState(); + var type; + if (tileState == ol.TileState.LOADING) { + this.tileLoadingKeys_[uid] = true; + type = ol.source.TileEventType.TILELOADSTART; + } else if (uid in this.tileLoadingKeys_) { + delete this.tileLoadingKeys_[uid]; + type = tileState == ol.TileState.ERROR ? ol.source.TileEventType.TILELOADERROR : + (tileState == ol.TileState.LOADED || tileState == ol.TileState.ABORT) ? + ol.source.TileEventType.TILELOADEND : undefined; + } + if (type != undefined) { + this.dispatchEvent(new ol.source.Tile.Event(type, tile)); } }; diff --git a/test/spec/ol/source/tileimage.test.js b/test/spec/ol/source/tileimage.test.js index 878bb61899..4f4c549417 100644 --- a/test/spec/ol/source/tileimage.test.js +++ b/test/spec/ol/source/tileimage.test.js @@ -1,6 +1,7 @@ goog.require('ol.ImageTile'); +goog.require('ol.TileState'); goog.require('ol.TileUrlFunction'); goog.require('ol.events'); goog.require('ol.proj'); @@ -172,4 +173,67 @@ describe('ol.source.TileImage', function() { tile.load(); }); }); + + describe('tile load events', function() { + + var source; + + beforeEach(function() { + source = new ol.source.TileImage({ + url: '{z}/{x}/{y}' + }); + }); + + it('dispatches tileloadstart and tileloadend events', function() { + source.setTileLoadFunction(function(tile) { + tile.setState(ol.TileState.LOADED); + }); + var startSpy = sinon.spy(); + source.on('tileloadstart', startSpy); + var endSpy = sinon.spy(); + source.on('tileloadend', endSpy); + var tile = source.getTile(0, 0, -1, 1, ol.proj.get('EPSG:3857')); + tile.load(); + expect(startSpy.callCount).to.be(1); + expect(endSpy.callCount).to.be(1); + }); + + it('works for loading-error-loading-loaded sequences', function(done) { + source.setTileLoadFunction(function(tile) { + tile.setState( + tile.state == ol.TileState.ERROR ? ol.TileState.LOADED : ol.TileState.ERROR); + }); + var startSpy = sinon.spy(); + source.on('tileloadstart', startSpy); + var errorSpy = sinon.spy(); + source.on('tileloaderror', function(e) { + setTimeout(function() { + e.tile.setState(ol.TileState.LOADING); + e.tile.setState(ol.TileState.LOADED); + }, 0); + errorSpy(); + }); + source.on('tileloadend', function() { + expect(startSpy.callCount).to.be(2); + expect(errorSpy.callCount).to.be(1); + done(); + }); + var tile = source.getTile(0, 0, -1, 1, ol.proj.get('EPSG:3857')); + tile.load(); + }); + + it('dispatches tileloadend events for aborted tiles', function() { + source.setTileLoadFunction(function() {}); + var startSpy = sinon.spy(); + source.on('tileloadstart', startSpy); + var endSpy = sinon.spy(); + source.on('tileloadend', endSpy); + var tile = source.getTile(0, 0, -1, 1, ol.proj.get('EPSG:3857')); + tile.load(); + tile.dispose(); + expect(startSpy.callCount).to.be(1); + expect(endSpy.callCount).to.be(1); + }); + }); + });