From b0984070dbaf3b5cc025acb0bdbaf2f0726b766b Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Tue, 15 Mar 2016 17:05:02 +0100 Subject: [PATCH 1/3] Don't load an already loading tile --- src/ol/tilequeue.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/ol/tilequeue.js b/src/ol/tilequeue.js index 62743a5f99..b383b95bbf 100644 --- a/src/ol/tilequeue.js +++ b/src/ol/tilequeue.js @@ -1,6 +1,7 @@ goog.provide('ol.TilePriorityFunction'); goog.provide('ol.TileQueue'); +goog.require('goog.asserts'); goog.require('ol.events'); goog.require('ol.events.EventType'); goog.require('ol.Coordinate'); @@ -56,7 +57,7 @@ ol.TileQueue = function(tilePriorityFunction, tileChangeCallback) { /** * @private - * @type {Object.} + * @type {!Object.} */ this.tilesLoadingKeys_ = {}; @@ -104,6 +105,7 @@ ol.TileQueue.prototype.handleTileChange = function(event) { } this.tileChangeCallback_(); } + goog.asserts.assert(Object.keys(this.tilesLoadingKeys_).length === this.tilesLoading_); }; @@ -113,15 +115,17 @@ ol.TileQueue.prototype.handleTileChange = function(event) { */ ol.TileQueue.prototype.loadMoreTiles = function(maxTotalLoading, maxNewLoads) { var newLoads = 0; - var tile; + var tile, tileKey; while (this.tilesLoading_ < maxTotalLoading && newLoads < maxNewLoads && this.getCount() > 0) { tile = /** @type {ol.Tile} */ (this.dequeue()[0]); - if (tile.getState() === ol.TileState.IDLE) { - this.tilesLoadingKeys_[tile.getKey()] = true; + tileKey = tile.getKey(); + if (tile.getState() === ol.TileState.IDLE && !(tileKey in this.tilesLoadingKeys_)) { + this.tilesLoadingKeys_[tileKey] = true; ++this.tilesLoading_; ++newLoads; tile.load(); } + goog.asserts.assert(Object.keys(this.tilesLoadingKeys_).length === this.tilesLoading_); } }; From c30ecace752f9e2b6d0dbca4d4103e500df38bac Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Tue, 15 Mar 2016 17:08:39 +0100 Subject: [PATCH 2/3] Handle aborted tiles in ol.TileQueue --- src/ol/imagetile.js | 2 ++ src/ol/tile.js | 3 ++- src/ol/tilequeue.js | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ol/imagetile.js b/src/ol/imagetile.js index b440e908ad..9aae36da74 100644 --- a/src/ol/imagetile.js +++ b/src/ol/imagetile.js @@ -72,6 +72,8 @@ ol.ImageTile.prototype.disposeInternal = function() { if (this.interimTile) { this.interimTile.dispose(); } + this.state = ol.TileState.ABORT; + this.changed(); goog.base(this, 'disposeInternal'); }; diff --git a/src/ol/tile.js b/src/ol/tile.js index aa59502afc..db8dc95563 100644 --- a/src/ol/tile.js +++ b/src/ol/tile.js @@ -15,7 +15,8 @@ ol.TileState = { LOADING: 1, LOADED: 2, ERROR: 3, - EMPTY: 4 + EMPTY: 4, + ABORT: 5 }; diff --git a/src/ol/tilequeue.js b/src/ol/tilequeue.js index b383b95bbf..141f54bd6c 100644 --- a/src/ol/tilequeue.js +++ b/src/ol/tilequeue.js @@ -95,7 +95,7 @@ ol.TileQueue.prototype.handleTileChange = function(event) { var tile = /** @type {ol.Tile} */ (event.target); var state = tile.getState(); if (state === ol.TileState.LOADED || state === ol.TileState.ERROR || - state === ol.TileState.EMPTY) { + state === ol.TileState.EMPTY || state === ol.TileState.ABORT) { ol.events.unlisten(tile, ol.events.EventType.CHANGE, this.handleTileChange, this); var tileKey = tile.getKey(); From 24886f2710b8e7fbdb1bbed0725cfc1f12e902e0 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Wed, 16 Mar 2016 09:39:37 +0100 Subject: [PATCH 3/3] Add more ol.TileQueue tests --- test/spec/ol/tilequeue.test.js | 43 +++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/test/spec/ol/tilequeue.test.js b/test/spec/ol/tilequeue.test.js index 5d9067bd36..8a8c517292 100644 --- a/test/spec/ol/tilequeue.test.js +++ b/test/spec/ol/tilequeue.test.js @@ -14,15 +14,16 @@ describe('ol.TileQueue', function() { } var tileId = 0; - function createImageTile() { + function createImageTile(opt_tileLoadFunction) { ++tileId; var tileCoord = [tileId, tileId, tileId]; var state = ol.TileState.IDLE; var src = 'data:image/gif;base64,R0lGODlhAQABAPAAAP8AAP///' + 'yH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==#' + tileId; - return new ol.ImageTile(tileCoord, state, src, null, - ol.source.Image.defaultImageLoadFunction); + var tileLoadFunction = opt_tileLoadFunction ? + opt_tileLoadFunction : ol.source.Image.defaultImageLoadFunction; + return new ol.ImageTile(tileCoord, state, src, null, tileLoadFunction); } describe('#loadMoreTiles()', function() { @@ -121,11 +122,47 @@ describe('ol.TileQueue', function() { }); }); + + describe('tile change event', function() { + var noop = function() {}; + + it('abort queued tiles', function() { + var tq = new ol.TileQueue(noop, noop); + var tile = createImageTile(); + expect(tile.hasListener(ol.events.EventType.CHANGE)).to.be(false); + + tq.enqueue([tile]); + expect(tile.hasListener(ol.events.EventType.CHANGE)).to.be(true); + + tile.dispose(); + expect(tile.hasListener(ol.events.EventType.CHANGE)).to.be(false); + expect(tile.getState()).to.eql(ol.TileState.ABORT); + }); + + it('abort loading tiles', function() { + var tq = new ol.TileQueue(noop, noop); + var tile = createImageTile(noop); + + tq.enqueue([tile]); + tq.loadMoreTiles(Infinity, Infinity); + expect(tq.getTilesLoading()).to.eql(1); + expect(tile.getState()).to.eql(ol.TileState.LOADING); + + tile.dispose(); + expect(tq.getTilesLoading()).to.eql(0); + expect(tile.hasListener(ol.events.EventType.CHANGE)).to.be(false); + expect(tile.getState()).to.eql(ol.TileState.ABORT); + + }); + + }); + }); goog.require('ol.ImageTile'); goog.require('ol.Tile'); goog.require('ol.TileState'); goog.require('ol.TileQueue'); +goog.require('ol.events.EventType'); goog.require('ol.source.Image'); goog.require('ol.structs.PriorityQueue');