71 lines
2 KiB
TypeScript
71 lines
2 KiB
TypeScript
|
import {Tiles} from "../../Models/TileRange";
|
||
|
|
||
|
export default class TileFreshnessCalculator {
|
||
|
|
||
|
/**
|
||
|
* All the freshnesses per tile index
|
||
|
* @private
|
||
|
*/
|
||
|
private readonly freshnesses = new Map<number, Date>();
|
||
|
|
||
|
/**
|
||
|
* Marks that some data got loaded for this layer
|
||
|
* @param tileId
|
||
|
* @param freshness
|
||
|
*/
|
||
|
public addTileLoad(tileId: number, freshness: Date){
|
||
|
const existingFreshness = this.freshnessFor(...Tiles.tile_from_index(tileId))
|
||
|
if(existingFreshness >= freshness){
|
||
|
return;
|
||
|
}
|
||
|
this.freshnesses.set(tileId, freshness)
|
||
|
|
||
|
// Do we have freshness for the neighbouring tiles? If so, we can mark the tile above as loaded too!
|
||
|
let [z, x, y] = Tiles.tile_from_index(tileId)
|
||
|
if(z === 0){
|
||
|
return;
|
||
|
}
|
||
|
x = x - (x % 2) // Make the tiles always even
|
||
|
y = y - (y % 2)
|
||
|
|
||
|
const ul = this.freshnessFor(z, x, y)?.getTime()
|
||
|
if(ul === undefined){
|
||
|
return
|
||
|
}
|
||
|
const ur = this.freshnessFor(z, x + 1, y)?.getTime()
|
||
|
if(ur === undefined){
|
||
|
return
|
||
|
}
|
||
|
const ll = this.freshnessFor(z, x, y + 1)?.getTime()
|
||
|
if(ll === undefined){
|
||
|
return
|
||
|
}
|
||
|
const lr = this.freshnessFor(z, x + 1, y + 1)?.getTime()
|
||
|
if(lr === undefined){
|
||
|
return
|
||
|
}
|
||
|
|
||
|
const leastFresh = Math.min(ul, ur, ll, lr)
|
||
|
const date = new Date()
|
||
|
date.setTime(leastFresh)
|
||
|
this.addTileLoad(
|
||
|
Tiles.tile_index(z - 1, Math.floor(x / 2), Math.floor(y / 2)),
|
||
|
date
|
||
|
)
|
||
|
|
||
|
}
|
||
|
|
||
|
public freshnessFor(z: number, x: number, y:number): Date {
|
||
|
if(z < 0){
|
||
|
return undefined
|
||
|
}
|
||
|
const tileId = Tiles.tile_index(z, x, y)
|
||
|
if(this.freshnesses.has(tileId)) {
|
||
|
return this.freshnesses.get(tileId)
|
||
|
}
|
||
|
// recurse up
|
||
|
return this.freshnessFor(z - 1, Math.floor(x /2), Math.floor(y / 2))
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|