diff --git a/lib/OpenLayers/Layer/Grid.js b/lib/OpenLayers/Layer/Grid.js index 0355f2b7d4..4a8fdf79bc 100644 --- a/lib/OpenLayers/Layer/Grid.js +++ b/lib/OpenLayers/Layer/Grid.js @@ -105,16 +105,16 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { serverResolutions: null, /** - * Property: tileLoopId - * {Number} - The id of the animation. + * Property: tileQueueId + * {Number} - The id of the animation. */ - tileLoopId: null, + tileQueueId: null, /** - * Property: tileOperations - * {Array(Object)} Pending tile operations. + * Property: tileQueue + * {Array()} Tiles queued for drawing. */ - tileOperations: null, + tileQueue: null, /** * Property: backBuffer @@ -186,7 +186,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { OpenLayers.Layer.HTTPRequest.prototype.initialize.apply(this, arguments); this.grid = []; - this.tileOperations = []; + this.tileQueue = []; }, /** @@ -197,7 +197,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { * map - {} The map. */ removeMap: function(map) { - this.abortTileOperations(); + this.clearTileQueue(); if(this.backBufferTimerId !== null) { window.clearTimeout(this.backBufferTimerId); this.backBufferTimerId = null; @@ -223,7 +223,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { * destroy() on each of them to kill circular references */ clearGrid:function() { - this.abortTileOperations(); + this.clearTileQueue(); if (this.grid) { for(var iRow=0, len=this.grid.length; iRow. + * + * Parameters: + * tile - {} The tile to remove from the queue */ - abortTileOperations: function() { - OpenLayers.Animation.stop(this.tileLoopId); - this.tileLoopId = null; - this.tileOperations = []; + unqueueTile: function(tile) { + for (var i=this.tileQueue.length-1; i>=0; --i) { + if (this.tileQueue[i].tile === tile) { + this.tileQueue.splice(i, 1); + } + } + }, + + /** + * Method: clearTileQueue + * Clears the animation queue + */ + clearTileQueue: function() { + OpenLayers.Animation.stop(this.tileQueueId); + this.tileQueueId = null; + this.tileQueue = []; }, /** @@ -422,11 +438,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { * tile - {} */ destroyTile: function(tile) { - for (var i=this.tileOperations.length-1; i>=0; --i) { - if (this.tileOperations[i].scope === tile) { - this.tileOperations.splice(i, 1); - } - } + this.unqueueTile(tile); this.removeTileMonitoringHooks(tile); tile.destroy(); }, @@ -906,17 +918,11 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { * {} The added OpenLayers.Tile */ addTile: function(bounds, position) { - var that = this; - var options = OpenLayers.Util.extend({ - draw: function() { - // clear immediately - this.clear(); - // draw in an animation frame - can be aborted - that.addTileOperation(that.tileClass.prototype.draw, this); - } - }, this.tileOptions); - return new this.tileClass(this, position, bounds, null, - this.tileSize, options); + var tile = new this.tileClass( + this, position, bounds, null, this.tileSize, this.tileOptions + ); + tile.events.register("beforedraw", this, this.queueTileDraw); + return tile; }, /** @@ -942,7 +948,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { this.numLoadingTiles--; this.events.triggerEvent("tileloaded"); //if that was the last tile, then trigger a 'loadend' on the layer - if (this.numLoadingTiles == 0) { + if (this.tileQueue.length === 0 && this.numLoadingTiles === 0) { this.events.triggerEvent("loadend"); if(this.backBuffer) { // the removal of the back buffer is delayed to prevent flash @@ -952,7 +958,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { 2500 ); } - } + } }; tile.events.register("loadend", this, tile.onLoadEnd); tile.events.register("unload", this, tile.onLoadEnd); diff --git a/lib/OpenLayers/Tile.js b/lib/OpenLayers/Tile.js index 81f6cb4e54..559e65d711 100644 --- a/lib/OpenLayers/Tile.js +++ b/lib/OpenLayers/Tile.js @@ -25,6 +25,10 @@ OpenLayers.Tile = OpenLayers.Class({ /** * Supported event types: + * - *beforedraw* Triggered before the tile is drawn. Used to defer + * drawing to an animation queue. To defer drawing, listeners need + * to return false, which will abort drawing. The queue handler needs + * to call (true) to actually draw the tile. * - *loadstart* Triggered when tile loading starts. * - *loadend* Triggered when tile loading ends. * - *reload* Triggered when an already loading tile is reloaded. @@ -83,7 +87,7 @@ OpenLayers.Tile = OpenLayers.Class({ * {Boolean} Is the tile loading? */ isLoading: false, - + /** TBD 3.0 -- remove 'url' from the list of parameters to the constructor. * there is no need for the base tile class to have a url. * @@ -149,15 +153,26 @@ OpenLayers.Tile = OpenLayers.Class({ * it should actually be re-drawn. This is an example implementation * that can be overridden by subclasses. The minimum thing to do here * is to call and return the result from . + * + * Parameters: + * deferred - {Boolean} When drawing was aborted by returning false from a + * *beforedraw* listener, the queue manager needs to pass true, so the + * tile will not be cleared and immediately be drawn. Otherwise, the + * tile will be cleared and a *beforedraw* event will be fired. * * Returns: * {Boolean} Whether or not the tile should actually be drawn. */ - draw: function() { - //clear tile's contents and mark as not drawn - this.clear(); - - return this.shouldDraw(); + draw: function(deferred) { + if (!deferred) { + //clear tile's contents and mark as not drawn + this.clear(); + } + var draw = this.shouldDraw(); + if (draw && !deferred) { + draw = this.events.triggerEvent("beforedraw") !== false; + } + return draw; }, /** @@ -228,10 +243,10 @@ OpenLayers.Tile = OpenLayers.Class({ /** * Method: clear * Clear the tile of any bounds/position-related data so that it can - * be reused in a new location. To be implemented by subclasses. + * be reused in a new location. */ clear: function(draw) { - // to be implemented by subclasses + // to be extended by subclasses }, CLASS_NAME: "OpenLayers.Tile" diff --git a/lib/OpenLayers/Tile/Image.js b/lib/OpenLayers/Tile/Image.js index d863d7dece..54e869a191 100644 --- a/lib/OpenLayers/Tile/Image.js +++ b/lib/OpenLayers/Tile/Image.js @@ -204,6 +204,7 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, { * it can be reused in a new location. */ clear: function() { + OpenLayers.Tile.prototype.clear.apply(this, arguments); var img = this.imgDiv; if (img) { OpenLayers.Event.stopObservingElement(img); diff --git a/tests/Layer/ArcGIS93Rest.html b/tests/Layer/ArcGIS93Rest.html index b63d164dd7..0e11ad70fc 100644 --- a/tests/Layer/ArcGIS93Rest.html +++ b/tests/Layer/ArcGIS93Rest.html @@ -5,9 +5,7 @@