Merge pull request #702 from ahocevar/smart-queue

New tile image cache and tile queue improvements. r=@bartvde,@elemoine
This commit is contained in:
ahocevar
2013-01-07 06:38:07 -08:00
18 changed files with 656 additions and 237 deletions
-3
View File
@@ -4,9 +4,6 @@
<script type="text/javascript">window.alert = oldAlert;</script>
<script src="../OLLoader.js"></script>
<script type="text/javascript">
// turn off animation frame handling, so we can check img urls in tests
delete OpenLayers.Layer.Grid.prototype.queueTileDraw;
var isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
var layer;
+3 -20
View File
@@ -1,19 +1,5 @@
<html>
<head>
<script>
/**
* Because browsers that implement requestAnimationFrame may not execute
* animation functions while a window is not displayed (e.g. in a hidden
* iframe as in these tests), we mask the native implementations here. The
* native requestAnimationFrame functionality is tested in Util.html and
* in PanZoom.html (where a popup is opened before panning).
*/
window.requestAnimationFrame =
window.webkitRequestAnimationFrame =
window.mozRequestAnimationFrame =
window.oRequestAnimationFrame =
window.msRequestAnimationFrame = null;
</script>
<script src="../OLLoader.js"></script>
<script type="text/javascript">
var map, layer;
@@ -108,10 +94,9 @@
isBaseLayer: false
}, options));
map.addLayer(layer);
var tile = layer.tileQueue[0];
t.delay_call(5, function() {
t.ok(tile.url, "Tile not empty");
t.ok(layer.grid[0][0].url, "Tile not empty");
map.destroy();
});
}
@@ -186,12 +171,11 @@
layer = new OpenLayers.Layer.Bing(options);
map.addLayer(layer);
map.zoomToMaxExtent();
var tile = layer.tileQueue[0];
t.delay_call(5, function() {
t.ok(OpenLayers.Util.indexOf(layer.attribution, '<img src="//') != -1, "Attribution contains a logo with protocol //");
t.ok(OpenLayers.Util.indexOf(layer.attribution, '<img src="http://') == -1, "Attribution logo does not have http:// protocol");
t.ok(tile.url.indexOf('http:') == -1, "Tile url does not contain http:");
t.ok(layer.grid[1][1].url.indexOf('http:') == -1, "Tile url does not contain http:");
map.destroy();
});
@@ -200,11 +184,10 @@
layer_https = new OpenLayers.Layer.Bing(OpenLayers.Util.applyDefaults({protocol: 'https:'}, options));
map2.addLayer(layer_https);
map2.zoomToMaxExtent();
var tile = layer_https.tileQueue[0];
t.delay_call(5, function() {
t.ok(OpenLayers.Util.indexOf(layer_https.attribution, '<img src="https://') != -1, "Attribution logo has https:// protocol");
t.ok(tile.url.indexOf('https:') == 0, "Tile url contains https:");
t.ok(layer_https.grid[1][1].url.indexOf('https:') == 0, "Tile url contains https:");
map2.destroy();
});
}
+2 -51
View File
@@ -2,9 +2,6 @@
<head>
<script src="../OLLoader.js"></script>
<script type="text/javascript">
// turn off animation frame handling, so we can check img urls in tests
var origQueueTileDraw = OpenLayers.Layer.Grid.prototype.queueTileDraw;
delete OpenLayers.Layer.Grid.prototype.queueTileDraw;
var isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
var layer;
@@ -100,26 +97,6 @@
map.destroy();
}
function test_queueTileDraw(t) {
t.plan(3);
OpenLayers.Layer.Grid.prototype.queueTileDraw = origQueueTileDraw;
var map = new OpenLayers.Map('map');
layer = new OpenLayers.Layer.WMS(name, url, params);
map.addLayer(layer);
map.setCenter([0, 0], 3);
var queued = layer.tileQueue.length;
t.ok(layer.tileQueue.length, "Tiles queued for drawing");
map.zoomIn();
t.eq(layer.tileQueue.length, queued, "Tile queue has same length after immediate zoom change");
t.delay_call(1, function() {
t.eq(layer.tileQueue.length, 0, "Tiles from queue processed");
});
map.destroy();
delete OpenLayers.Layer.Grid.prototype.queueTileDraw;
}
function test_Layer_Grid_clearTiles (t) {
t.plan(4);
@@ -258,10 +235,7 @@
function test_Layer_Grid_moveTo(t) {
t.plan(17);
var origIsNative = OpenLayers.Animation.isNative;
OpenLayers.Animation.isNative = false;
t.plan(13);
var map = new OpenLayers.Map('map');
layer = new OpenLayers.Layer.WMS(name, url, params);
@@ -271,23 +245,6 @@
map.setCenter([-10, 0], 5);
var log = [];
var origDeferMoveGriddedTiles = layer.deferMoveGriddedTiles;
layer.deferMoveGriddedTiles = function() {
log.push("deferMoveGriddedTiles");
origDeferMoveGriddedTiles.apply(this, arguments);
};
layer.moveGriddedTiles = function() {
log.push("moveGriddedTiles");
OpenLayers.Layer.WMS.prototype.moveGriddedTiles.apply(this, arguments);
};
map.moveTo([5, 0]);
t.eq(log[0], "moveGriddedTiles", "deferred after moveTo");
map.moveTo([0, 0]);
t.eq(log[1], "moveGriddedTiles", "deferred again after another moveTo");
t.eq(log.length, 2, "no tiles loaded yet");
t.delay_call(1, function() {
t.eq(log[2], "deferMoveGriddedTiles", "tiles moved after tileLoadingDelay");
});
//make sure null bounds doesnt cause script error.
// no test necessary, just action
@@ -309,9 +266,6 @@
g_WhichFunc = "MoveGridded";
g_Bounds = layer.map.getExtent();
};
layer.deferMoveGriddedTiles = function() {
g_WhichFunc = "DeferMoveGridded";
}
var clearTestBounds = function() {
g_WhichFunc = null;
g_Bounds = null;
@@ -418,8 +372,6 @@
layer.moveTo(null, zoomChanged);
t.ok(g_WhichFunc == "InitGridded", "if tiles drastically out of bounds, we call initGriddedTile()");
t.ok(g_Bounds.equals(b), "if tiles drastically out of bounds, we call initGriddedTile() with correct bounds");
OpenLayers.Animation.isNative = origIsNative;
}
/** THIS WOULD BE WHERE THE TESTS WOULD GO FOR
@@ -438,7 +390,7 @@
*/
function test_Layer_Grid_clone(t) {
t.plan(7);
t.plan(6);
var options = {tileSize: new OpenLayers.Size(500,50)};
var map = new OpenLayers.Map('map', options);
@@ -453,7 +405,6 @@
t.ok( clone.grid != layer.grid, "clone does not copy grid");
t.ok( clone.grid.length == 0, "clone creates a new array instead");
t.ok(clone.tileQueue !== layer.tileQueue, "new tileQueue for clone");
t.eq(clone.backBuffer, null, "no backbuffer from original");
t.ok( clone.tileSize.equals(layer.tileSize), "tileSize correctly cloned");
-4
View File
@@ -555,9 +555,6 @@
}
function test_tileBounds(t) {
// do not defer moveGriddedTiles
var isNative = OpenLayers.Animation.isNative;
OpenLayers.Animation.isNative = true;
t.plan(3);
var map = new OpenLayers.Map("map", {projection: "EPSG:3857"});
@@ -575,7 +572,6 @@
t.eq(bounds.right, 0, "0 is 0, and not some super small number");
map.destroy();
OpenLayers.Animation.isNative = isNative;
}
+1 -1
View File
@@ -85,7 +85,7 @@
var drawn = tile.draw();
t.eq(log[0], "clear", "tile cleared");
t.eq(log[1], "beforedraw", "beforedraw event fired");
t.eq(drawn, false, "tile not drawn when beforedraw listener returns false");
t.eq(drawn, null, "tile not drawn when beforedraw listener returns false");
drawn = tile.draw(true);
t.eq(log.length, 2, "no beforedraw event fired and tile not cleared when draw called with 'deferred' argument set to true");
t.eq(drawn, true, "tile drawn when draw called with 'deferred' argument set to true");
+125
View File
@@ -0,0 +1,125 @@
<html>
<head>
<script src="OLLoader.js"></script>
<script type="text/javascript">
function test_initialize(t) {
t.plan(4);
var tileManager = new OpenLayers.TileManager();
var map = new OpenLayers.Map('map', {
tileManager: tileManager
});
var layer = new OpenLayers.Layer.WMS('WMS1', '../img/blank.gif');
map.addLayer(layer);
map.setCenter([16, 48], 9);
t.ok(tileManager.tileQueue[map.id].length, "Tiles queued from layer");
map.removeLayer(layer);
t.eq(tileManager.tileQueue[map.id].length, 0, "Tiles unqueued when layer is removed");
map.addLayer(new OpenLayers.Layer.WMS('WMS2', '../img/blank.gif'));
map.zoomIn();
t.ok(tileManager.tileQueue[map.id].length, "Tiles queued from added layer");
map.destroy();
t.eq(tileManager.tileQueue[map.id], undefined, "Tile queue removed when map was destroyed");
}
function test_destroy(t) {
t.plan(3);
var tileManager = new OpenLayers.TileManager();
var map = new OpenLayers.Map('map', {tileManager: tileManager});
var layer = new OpenLayers.Layer.WMS('WMS', '../img/blank.gif');
map.addLayer(layer);
map.setCenter([16, 48], 9);
var numTileListeners = layer.grid[0][0].events.listeners.beforeload.length;
var numLayerListeners = layer.events.listeners.retile.length;
var numMapListeners = map.events.listeners.preremovelayer.length;
tileManager.destroy();
t.eq(layer.grid[0][0].events.listeners.beforeload.length, numTileListeners - 1, "no listener on tile after destroy");
t.eq(layer.events.listeners.retile.length, numLayerListeners - 1, "no listeners on layer after destroy");
t.eq(map.events.listeners.preremovelayer.length, numMapListeners - 1, "no listeners on map after destroy");
map.destroy();
}
function test_manageTileCache(t) {
t.plan(10);
var tileManager = new OpenLayers.TileManager({
cacheSize: 12
});
var map = new OpenLayers.Map('map', {tileManager: tileManager});
layer = new OpenLayers.Layer.WMS('WMS', '../img/blank.gif');
map.addLayer(layer);
map.setCenter([16, 48], 9);
var gridSize;
var firstInCache, sharedTile;
t.delay_call(2, function() {
t.eq(tileManager.tileCacheIndex.length, 12, "tiles cached");
t.ok(~OpenLayers.Util.indexOf(tileManager.tileCacheIndex, layer.grid[1][2].url), "tile found in cache");
t.ok(tileManager.tileCache[layer.grid[1][2].url] === layer.grid[1][2].imgDiv, "correct object cached");
firstInCache = tileManager.tileCache[tileManager.tileCacheIndex[0]];
sharedTile = tileManager.tileCache[tileManager.tileCacheIndex[11]];
gridSize = layer.div.childNodes.length;
map.setCenter([17, 47]);
});
t.delay_call(4, function() {
t.eq(tileManager.tileCacheIndex.length, 12, "tiles cached");
t.ok(tileManager.tileCache[layer.grid[1][2].url] === layer.grid[1][2].imgDiv, "correct object cached");
t.ok(!(firstInCache.getAttribute("src") in tileManager.tileCache), "old tile discarded");
t.ok(sharedTile.getAttribute("src") in tileManager.tileCache, "shared tile still in cache");
firstInCache = tileManager.tileCache[tileManager.tileCacheIndex[0]];
map.setCenter([16, 48]);
});
t.delay_call(6, function() {
t.ok(!(firstInCache.getAttribute("src") in tileManager.tileCache), "old tile discarded");
t.ok(sharedTile.getAttribute("src") in tileManager.tileCache, "shared tile still in cache");
t.eq(layer.div.childNodes.length, gridSize, 'no unused images left in dom');
map.destroy();
});
}
function test_queueTileDraw(t) {
t.plan(3);
var tileManager = new OpenLayers.TileManager();
var map = new OpenLayers.Map('map', {tileManager: tileManager});
layer = new OpenLayers.Layer.WMS('WMS', '../img/blank.gif');
map.addLayer(layer);
map.setCenter([0, 0], 3);
var queued = tileManager.tileQueue[map.id].length;
t.ok(tileManager.tileQueue[map.id].length, "Tiles queued for drawing");
map.zoomIn();
t.eq(tileManager.tileQueue[map.id].length, queued, "Tile queue has same length after immediate zoom change");
t.delay_call(1, function() {
t.eq(tileManager.tileQueue[map.id].length, 0, "Tiles from queue processed");
map.destroy();
});
}
function test_deferTileDraw(t) {
t.plan(3);
var tileManager = new OpenLayers.TileManager();
var map = new OpenLayers.Map('map', {tileManager: tileManager});
layer = new OpenLayers.Layer.WMS('WMS', '../img/blank.gif');
layer.destroy = function() {}; //we're going to do funky things with the grid
layer.applyBackBuffer = function() {}; // backbuffering isn't under test here
map.addLayer(layer);
map.setCenter([-10, 0], 5);
map.moveTo([5, 0]);
t.ok(tileManager.tileQueue[map.id].length, "tile loading deferred after moveTo");
map.moveTo([0, 0]);
t.ok(tileManager.tileQueue[map.id].length, "deferred again after another moveTo");
t.delay_call(1, function() {
t.eq(tileManager.tileQueue[map.id].length, 0, "tiles loaded after moveDelay");
});
}
</script>
</head>
<body>
<div id="map" style="width:499px;height:549px;display:none"></div>
</body>
</html>
@@ -5,9 +5,6 @@
<script src="../../../../lib/deprecated.js"></script>
<script type="text/javascript">
// turn off animation frame handling, so we can check img urls in tests
delete OpenLayers.Layer.Grid.prototype.queueTileDraw;
var isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
var layer;
+1
View File
@@ -231,6 +231,7 @@
<li>Tile/Image.html</li>
<li>Tile/Image/IFrame.html</li>
<li>Tile/UTFGrid.html</li>
<li>TileManager.html</li>
<li>Tween.html</li>
<li>Kinetic.html</li>
<li>Util.html</li>