Simplified tile queue; using the tile's beforedraw listener.
Since draw is the only tile operation that we defer, the tile queue can be an array of tiles and queue handling can be simplified. We now use the beforedraw event to defer drawing, and remove all occurrences of a tile from the tile queue when we draw it. Instead of layers that want to defer tile drawing having to override the tile's draw method, layers can now abort drawing by returning false from a beforedraw listener, and later call draw(true) to draw the tile directly, without clearing it first.
This commit is contained in:
@@ -105,16 +105,16 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
||||
serverResolutions: null,
|
||||
|
||||
/**
|
||||
* Property: tileLoopId
|
||||
* {Number} - The id of the <doTileOperation> animation.
|
||||
* Property: tileQueueId
|
||||
* {Number} - The id of the <drawTileFromQueue> animation.
|
||||
*/
|
||||
tileLoopId: null,
|
||||
tileQueueId: null,
|
||||
|
||||
/**
|
||||
* Property: tileOperations
|
||||
* {Array(Object)} Pending tile operations.
|
||||
* Property: tileQueue
|
||||
* {Array(<OpenLayers.Tile>)} 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 - {<OpenLayers.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<len; iRow++) {
|
||||
var row = this.grid[iRow];
|
||||
@@ -294,7 +294,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
||||
var forceReTile = !this.grid.length || zoomChanged;
|
||||
|
||||
if (forceReTile) {
|
||||
this.abortTileOperations();
|
||||
this.clearTileQueue();
|
||||
}
|
||||
|
||||
// total bounds of the tiles
|
||||
@@ -375,44 +375,60 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: addTileOperation
|
||||
* Adds a tile operation to the animation queue.
|
||||
* Method: queueTileDraw
|
||||
* Adds a tile to the animation queue that will draw it.
|
||||
*
|
||||
* Parameters:
|
||||
* fn - {Function} The function to execute
|
||||
* scope - {Object} The execution scope for the function
|
||||
* evt - {Object} Listener argument of the tile's beforedraw event
|
||||
*/
|
||||
addTileOperation: function(fn, scope) {
|
||||
this.tileOperations.push({fn: fn, scope: scope});
|
||||
if (!this.tileLoopId) {
|
||||
this.tileLoopId = OpenLayers.Animation.start(
|
||||
OpenLayers.Function.bind(this.doTileOperation, this),
|
||||
queueTileDraw: function(evt) {
|
||||
this.tileQueue.push(evt.object);
|
||||
if (!this.tileQueueId) {
|
||||
this.tileQueueId = OpenLayers.Animation.start(
|
||||
OpenLayers.Function.bind(this.drawTileFromQueue, this),
|
||||
null, this.div
|
||||
);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: doTileOperation
|
||||
* Executes the first tile operation from the animation queue.
|
||||
* Method: drawTileFromQueue
|
||||
* Draws the first tile from the tileQueue, and unqueues that tile
|
||||
*/
|
||||
doTileOperation: function() {
|
||||
if (this.tileOperations.length === 0) {
|
||||
this.abortTileOperations();
|
||||
drawTileFromQueue: function() {
|
||||
if (this.tileQueue.length === 0) {
|
||||
this.clearTileQueue();
|
||||
} else {
|
||||
var operation = this.tileOperations.shift();
|
||||
operation.fn.call(operation.scope);
|
||||
var tile = this.tileQueue.shift();
|
||||
this.unqueueTile(tile);
|
||||
tile.draw(true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: abortTileOperations
|
||||
* Stops the animation queue and removes all pending operations
|
||||
* Method: unqueueTile
|
||||
* Removes all occurrences of a tile from the <tileQueue>.
|
||||
*
|
||||
* Parameters:
|
||||
* tile - {<OpenLayers.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 - {<OpenLayers.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, {
|
||||
* {<OpenLayers.Tile>} 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);
|
||||
|
||||
Reference in New Issue
Block a user