Added support for keeping a limited set of tile textures.
This commit is contained in:
+143
-20
@@ -1,19 +1,90 @@
|
||||
|
||||
export const deepZoomTileCache = new Map()
|
||||
|
||||
const registeredTiles = new Map()
|
||||
const pendingTiles = new Map()
|
||||
/** Implements a baseTexture cache. The last textures are kept for reuse */
|
||||
const keepTextures = 0
|
||||
const keptTextures = []
|
||||
|
||||
/** The current Tile implementation simply uses PIXI.Sprites.
|
||||
*
|
||||
* BTW: PIXI.extras.TilingSprite is not appropriate. It should be used for
|
||||
* repeating patterns.
|
||||
**/
|
||||
export class Tile extends PIXI.Sprite {
|
||||
export default class Tile extends PIXI.Sprite {
|
||||
constructor(texture, url) {
|
||||
super(texture)
|
||||
this.url = url
|
||||
this.register(url)
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method to enable keeping of base textures
|
||||
*
|
||||
* @static
|
||||
* @param {*} value
|
||||
* @memberof Tile
|
||||
*/
|
||||
static enableKeepTextures(value = 1000) {
|
||||
keepTextures = 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)
|
||||
}
|
||||
@@ -26,13 +97,14 @@ export class Tile extends PIXI.Sprite {
|
||||
* @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)
|
||||
}
|
||||
}
|
||||
@@ -44,10 +116,10 @@ export class Tile extends PIXI.Sprite {
|
||||
* @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
|
||||
}
|
||||
@@ -58,22 +130,73 @@ export class Tile extends PIXI.Sprite {
|
||||
* @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 (keepTextures > 0) {
|
||||
keptTextures.push({ url: this.url, texture: this.texture})
|
||||
|
||||
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(keptTextures.length > keepTextures) {
|
||||
let {url, texture} = keptTextures.shift()
|
||||
let tiles = registeredTiles.get(url)
|
||||
if (tiles.size > 0 && !Tile.isPending(url)) {
|
||||
texture.destroy(true) // Destroy base as well
|
||||
if (debug) console.log("Destroying texture and baseTexture", url)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
let opts = { children: true, texture: false, baseTexture: false }
|
||||
if (debug) console.log("Tile.destroy", deepZoomTileCache.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
|
||||
// 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 })
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user