WIP-ish, batch visible range requests, allow setting empty ranges and...

don't try to notify when the tile becomes invisible again,
we don't need it currently
This commit is contained in:
Bruno Windels 2021-09-09 17:14:16 +02:00
parent 98678b991b
commit d0f122a2be
4 changed files with 44 additions and 32 deletions

View File

@ -46,36 +46,51 @@ export class TimelineViewModel extends ViewModel {
this._endTile = null; this._endTile = null;
this._topLoadingPromise = null; this._topLoadingPromise = null;
this._bottomLoadingPromise = null; this._bottomLoadingPromise = null;
this._requestedStartTile = null;
this._requestedEndTile = null;
this._requestScheduled = false;
} }
setVisibleTileRange(startTile, endTile, isViewportFilled) { /** if this.tiles is empty, call this with undefined for both startTile and endTile */
// we should async batch things here? setVisibleTileRange(startTile, endTile) {
this._requestedStartTile = startTile;
// this will prevent a (small) inserted tile from being marked visible, won't it? this._requestedEndTile = endTile;
if (this._startTile === startTile && this._endTile === endTile) { if (!this._requestScheduled) {
return; Promise.resolve().then(() => {
this._setVisibleTileRange(this._requestedStartTile, this._requestedEndTile);
this._requestScheduled = false;
});
this._requestScheduled = true;
}
} }
/** if this.tiles is empty, call this with undefined for both startTile and endTile */
_setVisibleTileRange(startTile, endTile) {
let loadTop;
if (startTile && endTile) {
// old tiles could have been removed from tilescollection once we support unloading // old tiles could have been removed from tilescollection once we support unloading
const oldStartIndex = this._startTile ? this._tiles.getTileIndex(this._startTile) : Number.MAX_SAFE_INTEGER; this._startTile = startTile;
const oldEndIndex = this._endTile ? this._tiles.getTileIndex(this._endTile) : Number.MIN_SAFE_INTEGER; this._endTile = endTile;
const newStartIndex = this._tiles.getTileIndex(startTile); const startIndex = this._tiles.getTileIndex(this._startTile);
const newEndIndex = this._tiles.getTileIndex(endTile); const endIndex = this._tiles.getTileIndex(this._endTile);
for (const tile of this._tiles.sliceIterator(startIndex, endIndex)) {
const minIndex = Math.min(oldStartIndex, newStartIndex); tile.notifyVisible();
const maxIndex = Math.max(oldEndIndex, newEndIndex); }
loadTop = startIndex < 5;
let index = minIndex; console.log("got tiles", startIndex, endIndex, loadTop);
for (const tile of this._tiles.sliceIterator(minIndex, maxIndex)) { } else {
const isVisible = index >= newStartIndex && index <= newEndIndex; loadTop = true;
tile.setVisible(isVisible); console.log("no tiles, load more at top");
index += 1;
} }
if (!isViewportFilled || (newStartIndex < 5 && !this._topLoadingPromise)) { if (loadTop && !this._topLoadingPromise) {
this._topLoadingPromise = this._timeline.loadAtTop(10).then(() => { this._topLoadingPromise = this._timeline.loadAtTop(10).then(() => {
this._topLoadingPromise = null; this._topLoadingPromise = null;
// check if more items need to be loaded by recursing
this.setVisibleTileRange(this._startTile, this._endTile);
}); });
} else if (loadTop) {
console.log("loadTop is true but already loading");
} }
} }

View File

@ -44,11 +44,9 @@ export class GapTile extends SimpleTile {
} }
} }
setVisible(isVisible) { notifyVisible() {
if (isVisible) {
this.fill(); this.fill();
} }
}
updateEntry(entry, params) { updateEntry(entry, params) {
super.updateEntry(entry, params); super.updateEntry(entry, params);

View File

@ -123,9 +123,7 @@ export class SimpleTile extends ViewModel {
} }
setVisible(isVisible) { notifyVisible() {}
}
dispose() { dispose() {
this.setUpdateEmit(null); this.setUpdateEmit(null);

View File

@ -132,11 +132,12 @@ export class TimelineView extends TemplateView<TimelineViewModel> {
} }
private updateVisibleRange(startIndex: number, endIndex: number, isViewportFilled: boolean) { private updateVisibleRange(startIndex: number, endIndex: number, isViewportFilled: boolean) {
// can be undefined, meaning the tiles collection is still empty
const firstVisibleChild = this.tilesView!.getChildInstanceByIndex(startIndex); const firstVisibleChild = this.tilesView!.getChildInstanceByIndex(startIndex);
const lastVisibleChild = this.tilesView!.getChildInstanceByIndex(endIndex); const lastVisibleChild = this.tilesView!.getChildInstanceByIndex(endIndex);
if (firstVisibleChild && lastVisibleChild) { //if (firstVisibleChild && lastVisibleChild) {
this.value.setVisibleTileRange(firstVisibleChild.value, lastVisibleChild.value, isViewportFilled); this.value.setVisibleTileRange(firstVisibleChild?.value, lastVisibleChild?.value, isViewportFilled);
} //}
} }
} }