mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-25 14:46:10 +03:00
Fix issues with tile reference in cache: keep the 'most fresh' ref.
This commit is contained in:
parent
d91df0126b
commit
63f0adbc15
@ -513,12 +513,14 @@ $.Tile.prototype = {
|
||||
* @return {OpenSeadragon.CacheRecord}
|
||||
*/
|
||||
getCache: function(key = this.cacheKey) {
|
||||
return this._caches[key];
|
||||
const cache = this._caches[key];
|
||||
if (cache) {
|
||||
cache.withTileReference(this);
|
||||
}
|
||||
return cache;
|
||||
},
|
||||
|
||||
/**
|
||||
* TODO: set cache might be misleading name since we do not update data,
|
||||
* this should be either changed or method renamed...
|
||||
* Set tile cache, possibly multiple with custom key
|
||||
* @param {string} key cache key, must be unique (we recommend re-using this.cacheTile
|
||||
* value and extend it with some another unique content, by default overrides the existing
|
||||
@ -600,6 +602,7 @@ $.Tile.prototype = {
|
||||
/**
|
||||
* Get the ratio between current and original size.
|
||||
* @function
|
||||
* @deprecated
|
||||
* @returns {number}
|
||||
*/
|
||||
getScaleForEdgeSmoothing: function() {
|
||||
|
@ -128,14 +128,13 @@
|
||||
* @returns {OpenSeadragon.Promise<?>} desired data type in promise, undefined if the cache was destroyed
|
||||
*/
|
||||
getDataAs(type = this._type, copy = true) {
|
||||
const referenceTile = this._tiles[0];
|
||||
if (this.loaded) {
|
||||
if (type === this._type) {
|
||||
return copy ? $.convertor.copy(referenceTile, this._data, type) : this._promise;
|
||||
return copy ? $.convertor.copy(this._tRef, this._data, type) : this._promise;
|
||||
}
|
||||
return this._getDataAsUnsafe(referenceTile, this._data, type, copy);
|
||||
return this._getDataAsUnsafe(this._tRef, this._data, type, copy);
|
||||
}
|
||||
return this._promise.then(data => this._getDataAsUnsafe(referenceTile, data, type, copy));
|
||||
return this._promise.then(data => this._getDataAsUnsafe(this._tRef, data, type, copy));
|
||||
}
|
||||
|
||||
_getDataAsUnsafe(referenceTile, data, type, copy) {
|
||||
@ -161,7 +160,6 @@
|
||||
* @param {Array<string>} supportedTypes required data (or one of) type(s)
|
||||
* @param {boolean} keepInternalCopy if true, the cache keeps internally the drawer data
|
||||
* until 'setData' is called
|
||||
* todo: keep internal copy is not configurable and always enforced -> set as option for osd?
|
||||
* @returns {any|undefined} desired data if available, undefined if conversion must be done
|
||||
*/
|
||||
getDataForRendering(supportedTypes, keepInternalCopy = true) {
|
||||
@ -176,7 +174,7 @@
|
||||
}
|
||||
|
||||
if (internalCache) {
|
||||
internalCache.withTemporaryTileRef(this._tiles[0]);
|
||||
internalCache.withTileReference(this._tRef);
|
||||
} else {
|
||||
internalCache = this;
|
||||
}
|
||||
@ -201,7 +199,6 @@
|
||||
* @return {OpenSeadragon.Promise<OpenSeadragon.SimpleCacheRecord|OpenSeadragon.CacheRecord>}
|
||||
*/
|
||||
prepareForRendering(supportedTypes, keepInternalCopy = true) {
|
||||
const referenceTile = this._tiles[0];
|
||||
// if not internal copy and we have no data, bypass rendering
|
||||
if (!this.loaded) {
|
||||
return $.Promise.resolve(this);
|
||||
@ -214,9 +211,9 @@
|
||||
$.console.error(`[getDataForRendering] Conversion conversion ${this.type} ---> ${supportedTypes} cannot be done!`);
|
||||
return $.Promise.resolve(this);
|
||||
}
|
||||
internalCache.withTemporaryTileRef(referenceTile);
|
||||
internalCache.withTileReference(this._tRef);
|
||||
const selectedFormat = conversionPath[conversionPath.length - 1].target.value;
|
||||
return $.convertor.convert(referenceTile, this.data, this.type, selectedFormat).then(data => {
|
||||
return $.convertor.convert(this._tRef, this.data, this.type, selectedFormat).then(data => {
|
||||
internalCache.setDataAs(data, selectedFormat);
|
||||
return internalCache;
|
||||
});
|
||||
@ -276,6 +273,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversion requires tile references:
|
||||
* keep the most 'up to date' ref here. It is called and managed automatically.
|
||||
* @param {OpenSeadragon.Tile} ref
|
||||
* @private
|
||||
*/
|
||||
withTileReference(ref) {
|
||||
this._tRef = ref;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set initial state, prepare for usage.
|
||||
* Must not be called on active cache, e.g. first call destroy().
|
||||
@ -318,6 +325,7 @@
|
||||
this._tiles = null;
|
||||
this._data = null;
|
||||
this._type = null;
|
||||
this._tRef = null;
|
||||
this._promise = null;
|
||||
}
|
||||
|
||||
@ -359,6 +367,10 @@
|
||||
for (let i = 0; i < this._tiles.length; i++) {
|
||||
if (this._tiles[i] === tile) {
|
||||
this._tiles.splice(i, 1);
|
||||
if (this._tRef === tile) {
|
||||
// keep fresh ref
|
||||
this._tRef = this._tiles[i - 1];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -422,7 +434,7 @@
|
||||
const internal = this[DRAWER_INTERNAL_CACHE];
|
||||
if (internal) {
|
||||
// TODO: if update will be greedy uncomment (see below)
|
||||
//internal.withTemporaryTileRef(this._tiles[0]);
|
||||
//internal.withTileReference(this._tRef);
|
||||
internal.setDataAs(data, type);
|
||||
}
|
||||
this._triggerNeedsDraw();
|
||||
@ -436,7 +448,7 @@
|
||||
const internal = this[DRAWER_INTERNAL_CACHE];
|
||||
if (internal) {
|
||||
// TODO: if update will be greedy uncomment (see below)
|
||||
//internal.withTemporaryTileRef(this._tiles[0]);
|
||||
//internal.withTileReference(this._tRef);
|
||||
internal.setDataAs(data, type);
|
||||
}
|
||||
this._triggerNeedsDraw();
|
||||
@ -452,7 +464,6 @@
|
||||
*/
|
||||
_convert(from, to) {
|
||||
const convertor = $.convertor,
|
||||
referenceTile = this._tiles[0],
|
||||
conversionPath = convertor.getConversionPath(from, to);
|
||||
if (!conversionPath) {
|
||||
$.console.error(`[CacheRecord._convert] Conversion conversion ${from} ---> ${to} cannot be done!`);
|
||||
@ -470,7 +481,7 @@
|
||||
return $.Promise.resolve(x);
|
||||
}
|
||||
let edge = conversionPath[i];
|
||||
let y = edge.transform(referenceTile, x);
|
||||
let y = edge.transform(_this._tRef, x);
|
||||
if (y === undefined) {
|
||||
_this.loaded = false;
|
||||
throw `[CacheRecord._convert] data mid result undefined value (while converting using ${edge}})`;
|
||||
@ -530,7 +541,7 @@
|
||||
* compatible api with CacheRecord where tile refs are known.
|
||||
* @param {OpenSeadragon.Tile} referenceTile reference tile for conversion
|
||||
*/
|
||||
withTemporaryTileRef(referenceTile) {
|
||||
withTileReference(referenceTile) {
|
||||
this._temporaryTileRef = referenceTile;
|
||||
}
|
||||
|
||||
@ -727,9 +738,12 @@
|
||||
for ( let i = this._tilesLoaded.length - 1; i >= 0; i-- ) {
|
||||
prevTile = this._tilesLoaded[ i ];
|
||||
|
||||
if ( prevTile.level <= cutoff || prevTile.beingDrawn ) {
|
||||
if ( prevTile.level <= cutoff ||
|
||||
prevTile.beingDrawn ||
|
||||
prevTile.loading ) {
|
||||
continue;
|
||||
} else if ( !worstTile ) {
|
||||
}
|
||||
if ( !worstTile ) {
|
||||
worstTile = prevTile;
|
||||
worstTileIndex = i;
|
||||
continue;
|
||||
|
@ -2045,7 +2045,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
||||
*/
|
||||
_onTileLoad: function( tile, time, data, errorMsg, tileRequest, dataType ) {
|
||||
//data is set to null on error by image loader, allow custom falsey values (e.g. 0)
|
||||
if ( data === null ) {
|
||||
if ( data === null || data === undefined ) {
|
||||
$.console.error( "Tile %s failed to load: %s - error: %s", tile, tile.getUrl(), errorMsg );
|
||||
/**
|
||||
* Triggered when a tile fails to load.
|
||||
@ -2095,6 +2095,11 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
||||
* @param {?Boolean} [withEvent=true] do not trigger event if true
|
||||
*/
|
||||
_setTileLoaded: function(tile, data, cutoff, tileRequest, dataType, withEvent = true) {
|
||||
const originalDelete = tile.unload;
|
||||
tile.unload = (function () {
|
||||
throw `Cannot unload tile while being loaded!`;
|
||||
});
|
||||
|
||||
tile.tiledImage = this; //unloaded with tile.unload(), so we need to set it back
|
||||
// does nothing if tile.cacheKey already present
|
||||
tile.addCache(tile.cacheKey, data, dataType, false);
|
||||
@ -2124,17 +2129,19 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
||||
resolver(tile);
|
||||
} else if (!requiredTypes.includes(cache.type)) {
|
||||
//initiate conversion as soon as possible if incompatible with the drawer
|
||||
cache.prepareForRendering(requiredTypes).then(cacheRef => {
|
||||
cache.prepareForRendering(requiredTypes, _this.viewer.drawer.options.detachedCache).then(cacheRef => {
|
||||
if (!cacheRef) {
|
||||
return cache.transformTo(requiredTypes);
|
||||
}
|
||||
return cacheRef;
|
||||
}).then(_ => {
|
||||
tile.unload = originalDelete;
|
||||
tile.loading = false;
|
||||
tile.loaded = true;
|
||||
resolver(tile);
|
||||
});
|
||||
} else {
|
||||
tile.unload = originalDelete;
|
||||
tile.loading = false;
|
||||
tile.loaded = true;
|
||||
resolver(tile);
|
||||
|
Loading…
Reference in New Issue
Block a user