Added support for keeping a limited set of tile textures.

This commit is contained in:
2019-06-01 09:56:29 +02:00
parent 67c6a6c95c
commit 895ec55a46
7 changed files with 327 additions and 86 deletions
+8 -1
View File
@@ -2336,6 +2336,8 @@
onMouseWheel(event) {
if (this.capture(event) && this.target.onMouseWheel) {
this.target.onMouseWheel(event);
} else {
//console.warn('Target has no onMouseWheel callback')
}
}
@@ -2529,6 +2531,8 @@
}
if (this.target.onMouseWheel) {
this.target.onMouseWheel(event);
} else {
//console.warn('Target has no onMouseWheel callback', this.target)
}
}
}
@@ -4202,7 +4206,10 @@
let event = new ResizeEvent(this, { width: w, height: h });
this.onResize(event);
}
if (this.resizeButton != null) ;
if (this.resizeButton != null) {
// this.resizeButton.style.width = 50/this.scale+"px"
// this.resizeButton.style.height = 50/this.scale+"px"
}
}
startResize(e) {
+161 -40
View File
@@ -5500,6 +5500,8 @@
onMouseWheel(event) {
if (this.capture(event) && this.target.onMouseWheel) {
this.target.onMouseWheel(event);
} else {
//console.warn('Target has no onMouseWheel callback')
}
}
@@ -5693,6 +5695,8 @@
}
if (this.target.onMouseWheel) {
this.target.onMouseWheel(event);
} else {
//console.warn('Target has no onMouseWheel callback', this.target)
}
}
}
@@ -7204,7 +7208,10 @@
let event = new ResizeEvent(this, { width: w, height: h });
this.onResize(event);
}
if (this.resizeButton != null) ;
if (this.resizeButton != null) {
// this.resizeButton.style.width = 50/this.scale+"px"
// this.resizeButton.style.height = 50/this.scale+"px"
}
}
startResize(e) {
@@ -7796,8 +7803,11 @@
}
}
const deepZoomTileCache = new Map();
const registeredTiles = new Map();
const pendingTiles = new Map();
/** Implements a baseTexture cache. The last textures are kept for reuse */
const keepBaseTextures = 0;
const keptBaseTextures = [];
/** The current Tile implementation simply uses PIXI.Sprites.
*
@@ -7811,6 +7821,74 @@
this.register(url);
}
/**
* Static method to enable keeping of base textures
*
* @static
* @param {*} value
* @memberof Tile
*/
static enableKeepBaseTextures(value = 1000) {
keepBaseTextures = value;
}
/**
* Marks the given url as pending. Pending tiles should not be destroyed
*
* @static
* @param {*} url
* @memberof Tile
*/
static schedule(url) {
let count = 0;
if (pendingTiles.has(url)) {
count = pendingTiles.get(url);
}
pendingTiles.set(url, count + 1);
// console.log("Tile.scheduled", url, pendingTiles.size)
}
/**
* Returns true iff the url is pending
*
* @static
* @returns
* @memberof Tile
*/
static isPending() {
return pendingTiles.has(url) && pendingTiles.get(url) > 0
}
/**
* Removes the given url from pending urls.
*
* @static
* @param {*} url
* @memberof Tile
*/
static unschedule(url) {
if (pendingTiles.has(url)) {
let count = pendingTiles.get(url);
if (count > 1) {
pendingTiles.set(url, count - 1);
}
else {
pendingTiles.clear(url);
}
}
// console.log("Tile.unscheduled", url, pendingTiles.size)
}
/**
* Loads a tile from image using the PIXI.Texture.fromImage method.
*
* @static
* @param {*} imageId
* @param {*} crossorigin
* @param {*} scaleMode
* @returns
* @memberof Tile
*/
static fromImage(imageId, crossorigin, scaleMode) {
return new Tile(PIXI.Texture.fromImage(imageId, crossorigin, scaleMode), imageId)
}
@@ -7823,13 +7901,14 @@
* @memberof Tile
*/
register(url, debug = false) {
if (deepZoomTileCache.has(url)) {
let tiles = deepZoomTileCache.get(url);
Tile.unschedule(url);
if (registeredTiles.has(url)) {
let tiles = registeredTiles.get(url);
tiles.add(this);
if (debug) console.log("Tile.register", url, tiles.size);
}
else {
deepZoomTileCache.set(url, new Set([this]));
registeredTiles.set(url, new Set([this]));
if (debug) console.log("Tile.register", url, 1);
}
}
@@ -7841,10 +7920,10 @@
* @memberof Tile
*/
unregister() {
let tiles = deepZoomTileCache.get(this.url);
let tiles = registeredTiles.get(this.url);
tiles.delete(this);
if (tiles.size == 0) {
deepZoomTileCache.delete(this.url);
registeredTiles.delete(this.url);
}
return tiles.size
}
@@ -7855,23 +7934,75 @@
* @param {*} options Part of the PIXI API, but ignored in the implementation
* @memberof Tile
*/
destroy(options, debug = false) {
destroy(options, debug = true) {
let count = this.unregister();
if (count <= 0) {
let opts = { children: true, texture: true, baseTexture: true };
if (keepBaseTextures > 0) {
keptBaseTextures.push({ url: this.url, texture: this.texture.baseTexture});
let opts = { children: true, texture: false, baseTexture: false };
if (debug) console.log("Tile.destroy", registeredTiles.size, opts);
super.destroy(opts);
if (debug) console.log("Tile.destroy", deepZoomTileCache.size, opts);
while(keptBaseTextures.length > keepBaseTextures) {
let {url, texture} = keptBaseTextures.shift();
let tiles = registeredTiles.get(url);
if (tiles.size > 0 && !Tile.isPending(url)) {
texture.destroy();
if (debug) console.log("Destroying baseTexture", url);
}
}
}
else {
let opts = { children: true, texture: false, baseTexture: false };
if (debug) console.log("Tile.destroy", deepZoomTileCache.size, opts);
super.destroy(opts);
// No longer registered and not pending
if (count <= 0 && !Tile.isPending(url)) {
let opts = { children: true, texture: true, baseTexture: true };
super.destroy(opts);
if (debug) console.log("Tile.destroy", registeredTiles.size, opts);
}
else {
let opts = { children: true, texture: false, baseTexture: false };
if (debug) console.log("Tile.destroy", registeredTiles.size, opts);
super.destroy(opts);
}
if (this.parent != null) {
// UO: Emit warning and remove
console.warn("Destroying tile with parent. Hiding instead");
this.visible = false;
}
}
if (this.parent != null) {
// UO: Emit warning and remove
console.warn("Destroying tile with parent. Hiding instead");
this.visible = false;
}
/**
* Returns an available texture that can be reused
*
* @param {*} url
* @returns
* @memberof Tile
*/
static textureAvailable(url) {
if (registeredTiles.has(url)) {
let tiles = registeredTiles.get(url);
for (let tile of tiles.values()) {
//console.log("Reusing cached texture", tile.parent)
return tile.texture
}
}
return null
}
static printInfos() {
let references = new Map();
let multiples = 0;
for (let [url, tiles] of registeredTiles.entries()) {
let count = tiles.size;
references.set(url, count);
if (count > 1) {
multiples += 1;
}
}
console.log({ multiples, references });
}
}
@@ -7903,6 +8034,8 @@
schedule(url, col, row) {
if (this.loaded.has(url)) return false
if (this.loading.has(url)) return false
Tile.schedule(url);
this.map.set(url, [col, row]);
this.loading.add(url);
this.loadQueue.push(url);
@@ -7912,6 +8045,7 @@
unschedule(url) {
if (this.loaded.has(url)) this.loaded.delete(url);
if (this.loading.has(url)) this.loading.delete(url);
Tile.unschedule(url);
this.loadQueue = this.loadQueue.filter(item => item != url);
}
@@ -7971,16 +8105,13 @@
if (this.loaded.has(url)) return false
if (this.loading.has(url)) return false
if (deepZoomTileCache.has(url)) {
let tiles = deepZoomTileCache.get(url);
for (let tile of tiles.values()) {
//console.log("Reusing cached texture", tile.parent)
let texture = tile.texture;
this._textureAvailable(url, col, row, texture);
return false
}
Tile.schedule(url);
let reusableTexture = Tile.textureAvailable(url);
if (reusableTexture) {
if (this.debug) console.log('Texture reusable', reusableTexture);
this._textureAvailable(url, col, row, reusableTexture);
return false
}
let texture = PIXI.utils.TextureCache[url];
if (texture) {
if (this.debug) console.log('Texture already loaded', texture);
@@ -8497,18 +8628,8 @@
return n % 2 == 0
}
function printTileCacheInfos() {
let references = new Map();
let multiples = 0;
for (let [url, tiles] of deepZoomTileCache.entries()) {
let count = tiles.size;
references.set(url, count);
if (count > 1) {
multiples += 1;
}
}
console.log({ multiples, references });
Tile.printInfos();
}
/**
* A utility class that holds information typically provided by DZI files, i.e.
@@ -8914,7 +9035,7 @@
this.minimumLevel = deepZoomInfo.baseLevel;
}
this.currentLevel = Math.max(this.minimumLevel, deepZoomInfo.baseLevel);
console.log("autoLoadTiles", this.autoLoadTiles);
//console.log("autoLoadTiles", this.autoLoadTiles)
if (this.autoLoadTiles) {
this.setupTiles(center);
}