diff --git a/src/tile.js b/src/tile.js index 8f0a9280..b04dbc61 100644 --- a/src/tile.js +++ b/src/tile.js @@ -258,10 +258,12 @@ $.Tile = function(level, x, y, bounds, exists, url, context2D, loadWithAjax, aja */ this.processing = false; /** - * Remembers last processing time of the tile, 1 if the tile has just been loaded. + * Processing promise, resolves when the tile exits processing, or + * resolves immediatelly if not in the processing state. + * @member {OpenSeadragon.Promise} * @private */ - this.lastProcess = 0; + this.processingPromise = $.Promise.resolve(); }; /** @lends OpenSeadragon.Tile.prototype */ @@ -644,7 +646,6 @@ $.Tile.prototype = { let ref = this._caches[this._cKey]; if (ref) { // make sure we free drawer internal cache if people change cache key externally - // todo make sure this is really needed even after refactoring ref.destroyInternalCache(); } this._cKey = value; diff --git a/src/tilecache.js b/src/tilecache.js index 099e77c8..f23d5e26 100644 --- a/src/tilecache.js +++ b/src/tilecache.js @@ -1069,7 +1069,7 @@ if ( prevTile.level <= cutoff || prevTile.beingDrawn || prevTile.loading || - prevTile.processing ) { //todo exempt from deletion, or block this routine on data updates + prevTile.processing ) { continue; } if ( !worstTile ) { diff --git a/src/tiledimage.js b/src/tiledimage.js index 12bd5f60..163b3088 100644 --- a/src/tiledimage.js +++ b/src/tiledimage.js @@ -2132,9 +2132,6 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag } function markTileAsReady() { - tile.lastProcess = false; - tile.processing = false; - const fallbackCompletion = getCompletionCallback(); /** @@ -2183,8 +2180,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag if (tileCacheCreated) { - const updatePromise = _this.viewer.world.requestTileInvalidateEvent([tile], now, false, true); - updatePromise.then(markTileAsReady); + _this.viewer.world.requestTileInvalidateEvent([tile], now, false, true).then(markTileAsReady); } else { // Tile-invalidated not called on each tile, but only on tiles with new data! Verify we share the main cache const origCache = tile.getCache(tile.originalCacheKey); @@ -2199,15 +2195,12 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag tile.setCache(t.cacheKey, targetMainCache, true, false); break; } else if (t.processing) { - // TODO consider something nicer, now just wait until subsequent routine finishes - let interval = setInterval(() => { - if (!t.processing && t.getCache()) { - const targetMainCache = t.getCache(); - tile.setCache(t.cacheKey, targetMainCache, true, false); - clearInterval(interval); - markTileAsReady(); - } - }, 50); + // Await once processing finishes - mark tile as loaded + t.processingPromise.then(t => { + const targetMainCache = t.getCache(); + tile.setCache(t.cacheKey, targetMainCache, true, false); + markTileAsReady(); + }); return; } } diff --git a/src/world.js b/src/world.js index 737b6760..3530cf05 100644 --- a/src/world.js +++ b/src/world.js @@ -275,7 +275,7 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W } const tileList = [], - markedTiles = []; + tileFinishResolvers = []; for (const tile of tilesToProcess) { // We allow re-execution on tiles that are in process but have too low processing timestamp, // which must be solved by ensuring subsequent data calls in the suddenly outdated processing @@ -289,11 +289,14 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W } for (let t of tileCache._tiles) { - // Mark all related tiles as processing and cache the references to unmark later on, - // last processing is set to old processing (null if finished) - t.lastProcess = t.processing; + // Mark all related tiles as processing and register callback to unmark later on t.processing = tStamp; - markedTiles.push(t); + t.processingPromise = new $.Promise((resolve) => { + tileFinishResolvers.push(() => { + t.processing = false; + resolve(t); + }); + }); } tileCache.__invStamp = tStamp; @@ -350,7 +353,7 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W cache: workingCache, targetKey: newCacheKey, setAsMainCache: true, - tileAllowNotLoaded: false //todo what if called from load event? + tileAllowNotLoaded: tile.loading }); } else if (restoreTiles) { // If we requested restore, perform now @@ -425,9 +428,8 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W }); return $.Promise.all(jobList).then(() => { - for (let tile of markedTiles) { - tile.lastProcess = false; - tile.processing = false; + for (let resolve of tileFinishResolvers) { + resolve(); } this.draw(); });