Skip to content

Commit 6aaff1b

Browse files
committed
Expire temp
1 parent 5941ef8 commit 6aaff1b

File tree

3 files changed

+127
-17
lines changed

3 files changed

+127
-17
lines changed

Source/Scene/Cesium3DTile.js

+81-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ define([
1717
'../Core/getStringFromTypedArray',
1818
'../Core/Intersect',
1919
'../Core/joinUrls',
20+
'../Core/JulianDate',
2021
'../Core/loadArrayBuffer',
2122
'../Core/Matrix3',
2223
'../Core/Matrix4',
@@ -60,6 +61,7 @@ define([
6061
getStringFromTypedArray,
6162
Intersect,
6263
joinUrls,
64+
JulianDate,
6365
loadArrayBuffer,
6466
Matrix3,
6567
Matrix4,
@@ -268,6 +270,30 @@ define([
268270
*/
269271
this.replacementNode = undefined;
270272

273+
var expire = header.expire;
274+
var expireDuration;
275+
var expireDate;
276+
if (defined(expire)) {
277+
expireDuration = expire.duration;
278+
if (defined(expire.date)) {
279+
expireDate = JulianDate.fromIso8601(expire.date);
280+
}
281+
}
282+
283+
/**
284+
* The time in seconds after the tile's content is ready when the content expires and new content is requested.
285+
*
286+
* @type {Number}
287+
*/
288+
this.expireDuration = expireDuration;
289+
290+
/**
291+
* The date when the content expires and new content is requested.
292+
*
293+
* @type {JulianDate}
294+
*/
295+
this.expireDate = expireDate;
296+
271297
// Members that are updated every frame for tree traversal and rendering optimizations:
272298

273299
/**
@@ -449,6 +475,21 @@ define([
449475
}
450476
},
451477

478+
/**
479+
* Determines if the tile's content is expired. <code>true</code> if tile's
480+
* content is expired; otherwise, <code>false</code>.
481+
*
482+
* @memberof Cesium3DTile.prototype
483+
*
484+
* @type {Boolean}
485+
* @readonly
486+
*/
487+
contentExpired : {
488+
get : function() {
489+
return this._contentState === Cesium3DTileContentState.EXPIRED;
490+
}
491+
},
492+
452493
/**
453494
* Gets the promise that will be resolved when the tile's content is ready to process.
454495
* This happens after the content is downloaded but before the content is ready
@@ -490,6 +531,32 @@ define([
490531
}
491532
});
492533

534+
var scratchJulianDate = new JulianDate();
535+
536+
function updateExpiration(tile) {
537+
if (defined(tile.expireDate) && tile.contentReady && !tile.hasEmptyContent) {
538+
var now = JulianDate.now(scratchJulianDate);
539+
if (JulianDate.lessThan(tile.expireDate, now)) {
540+
tile._contentState = Cesium3DTileContentState.EXPIRED;
541+
}
542+
}
543+
}
544+
545+
function updateExpireDate(tile) {
546+
if (defined(tile.expireDuration)) {
547+
var expireDurationDate = JulianDate.now(scratchJulianDate);
548+
JulianDate.addSeconds(expireDurationDate, tile.expireDuration, expireDurationDate);
549+
550+
if (defined(tile.expireDate)) {
551+
if (JulianDate.lessThan(tile.expireDate, expireDurationDate)) {
552+
JulianDate.clone(expireDurationDate, tile.expireDate);
553+
}
554+
} else {
555+
tile.expireDate = JulianDate.clone(expireDurationDate);
556+
}
557+
}
558+
}
559+
493560
/**
494561
* Requests the tile's content.
495562
* <p>
@@ -509,9 +576,16 @@ define([
509576
return false;
510577
}
511578

579+
var url = this._contentUrl;
580+
if (defined(this.expireDate)) {
581+
// Append a query parameter of the tile expiration date to prevent caching
582+
var timestampQuery = '?expired=' + this.expireDate.toString();
583+
url = joinUrls(url, timestampQuery, false);
584+
}
585+
512586
var distance = this.distanceToCamera;
513587
var promise = RequestScheduler.schedule(new Request({
514-
url : this._contentUrl,
588+
url : url,
515589
server : this._requestServer,
516590
requestFunction : loadArrayBuffer,
517591
type : RequestType.TILES3D,
@@ -530,6 +604,10 @@ define([
530604
if (that.isDestroyed()) {
531605
return when.reject('tileset is destroyed');
532606
}
607+
608+
// Destroy expired content to make way for the new content
609+
that._content = that._content && that._content.destroy();
610+
533611
var uint8Array = new Uint8Array(arrayBuffer);
534612
var magic = getMagic(uint8Array);
535613
var contentFactory = Cesium3DTileContentFactory[magic];
@@ -549,6 +627,7 @@ define([
549627
that._contentReadyToProcessPromise.resolve(content);
550628

551629
content.readyPromise.then(function(content) {
630+
updateExpireDate(that);
552631
that._contentState = Cesium3DTileContentState.READY;
553632
that._contentReadyPromise.resolve(content);
554633
}).otherwise(function(error) {
@@ -861,6 +940,7 @@ define([
861940
*/
862941
Cesium3DTile.prototype.update = function(tileset, frameState) {
863942
applyDebugSettings(this, tileset, frameState);
943+
updateExpiration(this);
864944
this._content.update(tileset, frameState);
865945
this._transformDirty = false;
866946
};

Source/Scene/Cesium3DTileContentState.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ define([
1313
LOADING : 1, // Is waiting on a pending request
1414
PROCESSING : 2, // Request received. Contents are being processed for rendering. Depending on the content, it might make its own requests for external data.
1515
READY : 3, // Ready to render.
16-
FAILED : 4 // Request failed.
16+
EXPIRED : 4, // Is expired and will be unloaded once new content is loaded.
17+
FAILED : 5 // Request failed.
1718
};
1819

1920
return freezeObject(Cesium3DTileContentState);
20-
});
21+
});

Source/Scene/Cesium3DTileset.js

+43-14
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ define([
450450
this.allTilesLoaded = new Event();
451451

452452
/**
453-
* The event fired to indicate that a tile's content was unloaded from the cache.
453+
* The event fired to indicate that a tile's content was unloaded.
454454
* <p>
455455
* The unloaded {@link Cesium3DTile} is passed to the event listener.
456456
* </p>
@@ -1222,6 +1222,25 @@ define([
12221222

12231223
///////////////////////////////////////////////////////////////////////////
12241224

1225+
function unloadSubtree(tileset, tile) {
1226+
var stats = tileset._statistics;
1227+
var stack = [];
1228+
stack.push(tile);
1229+
while (stack.length > 0) {
1230+
tile = stack.pop();
1231+
unloadTile(tileset, tile);
1232+
var children = tile.children;
1233+
var length = children.length;
1234+
for (var i = 0; i < length; ++i) {
1235+
var child = children[i];
1236+
--stats.numberTotal;
1237+
stack.push(child);
1238+
}
1239+
}
1240+
1241+
tile.children = [];
1242+
}
1243+
12251244
function isVisible(visibilityPlaneMask) {
12261245
return visibilityPlaneMask !== CullingVolume.MASK_OUTSIDE;
12271246
}
@@ -1236,14 +1255,18 @@ define([
12361255
}
12371256

12381257
var stats = tileset._statistics;
1239-
1258+
var expired = tile.contentExpired;
12401259
var requested = tile.requestContent();
12411260

12421261
if (!requested) {
12431262
++stats.numberOfAttemptedRequests;
12441263
return;
12451264
}
12461265

1266+
if (expired && tile.hasTilesetContent) {
1267+
unloadSubtree(tileset, tile);
1268+
}
1269+
12471270
++stats.numberOfPendingRequests;
12481271

12491272
var removeFunction = removeFromProcessingQueue(tileset, tile);
@@ -1551,7 +1574,7 @@ define([
15511574
}
15521575

15531576
function loadTile(tile) {
1554-
if (tile.contentUnloaded) {
1577+
if (tile.contentUnloaded || tile.contentExpired) {
15551578
tile._requestHeap.insert(tile);
15561579
}
15571580
}
@@ -1958,14 +1981,28 @@ define([
19581981
}
19591982
}
19601983

1984+
function unloadTile(tileset, tile) {
1985+
if (!tile.hasRenderableContent) {
1986+
return;
1987+
}
1988+
1989+
var stats = tileset._statistics;
1990+
var replacementList = tileset._replacementList;
1991+
var tileUnload = tileset.tileUnload;
1992+
1993+
tileUnload.raiseEvent(tile);
1994+
replacementList.remove(tile.replacementNode);
1995+
decrementPointAndFeatureLoadCounts(tileset, tile.content);
1996+
--stats.numberContentReady;
1997+
tile.unloadContent();
1998+
}
1999+
19612000
function unloadTiles(tileset, frameState) {
19622001
var trimTiles = tileset._trimTiles;
19632002
tileset._trimTiles = false;
19642003

1965-
var stats = tileset._statistics;
19662004
var maximumNumberOfLoadedTiles = tileset._maximumNumberOfLoadedTiles + 1; // + 1 to account for sentinel
19672005
var replacementList = tileset._replacementList;
1968-
var tileUnload = tileset.tileUnload;
19692006

19702007
// Traverse the list only to the sentinel since tiles/nodes to the
19712008
// right of the sentinel were used this frame.
@@ -1975,16 +2012,8 @@ define([
19752012
var node = replacementList.head;
19762013
while ((node !== sentinel) && ((replacementList.length > maximumNumberOfLoadedTiles) || trimTiles)) {
19772014
var tile = node.item;
1978-
1979-
decrementPointAndFeatureLoadCounts(tileset, tile.content);
1980-
tileUnload.raiseEvent(tile);
1981-
tile.unloadContent();
1982-
1983-
var currentNode = node;
19842015
node = node.next;
1985-
replacementList.remove(currentNode);
1986-
1987-
--stats.numberContentReady;
2016+
unloadTile(tileset, tile);
19882017
}
19892018
}
19902019

0 commit comments

Comments
 (0)