Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add posibility of using function to define style category (fill, stroke, point, etc) #2487

Draft
wants to merge 10 commits into
base: master
Choose a base branch
from
34 changes: 20 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
"copc": "^0.0.6",
"earcut": "^3.0.0",
"js-priority-queue": "^0.1.5",
"lru-cache": "^11.0.1",
"pbf": "^4.0.1",
"shpjs": "^6.1.0",
"threads": "^1.7.0"
Expand Down
3 changes: 0 additions & 3 deletions src/Core/MainLoop.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ function updateElements(context, geometryLayer, elements) {
for (const attachedLayer of geometryLayer.attachedLayers) {
if (attachedLayer.ready) {
attachedLayer.update(context, attachedLayer, sub.element, sub.parent);
attachedLayer.cache.flush();
}
}
} else if (sub.elements) {
Expand All @@ -67,7 +66,6 @@ function updateElements(context, geometryLayer, elements) {
for (const attachedLayer of geometryLayer.attachedLayers) {
if (attachedLayer.ready) {
attachedLayer.update(context, attachedLayer, sub.elements[i], sub.parent);
attachedLayer.cache.flush();
}
}
}
Expand Down Expand Up @@ -161,7 +159,6 @@ class MainLoop extends EventDispatcher {
}

// Clear the cache of expired resources
geometryLayer.cache.flush();

view.execFrameRequesters(MAIN_LOOP_EVENTS.AFTER_LAYER_UPDATE, dt, this.#updateLoopRestarted, geometryLayer);
}
Expand Down
9 changes: 5 additions & 4 deletions src/Core/Prefab/TileBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import * as THREE from 'three';
import { TileGeometry } from 'Core/TileGeometry';
import Cache from 'Core/Scheduler/Cache';
import { LRUCache } from 'lru-cache';
import { computeBuffers } from 'Core/Prefab/computeBufferTileGeometry';
import OBB from 'Renderer/OBB';
import type Extent from 'Core/Geographic/Extent';
import Coordinates from 'Core/Geographic/Coordinates';

const cacheBuffer = new Map<string, { [buf: string]: THREE.BufferAttribute }>();
const cacheTile = new Cache();
const cacheTile = new LRUCache<string, Promise<TileGeometry>>({ max: 500 });

export type GpuBufferAttributes = {
index: THREE.BufferAttribute | null;
Expand Down Expand Up @@ -86,13 +86,14 @@ export function newTileGeometry(
const bufferKey =
`${builder.crs}_${params.disableSkirt ? 0 : 1}_${params.segments}`;

let promiseGeometry = cacheTile.get(south, params.level, bufferKey);
const key = `s${south}l${params.level}bK${bufferKey}`;
let promiseGeometry = cacheTile.get(key);

// build geometry if doesn't exist
if (!promiseGeometry) {
let resolve;
promiseGeometry = new Promise((r) => { resolve = r; });
cacheTile.set(promiseGeometry, south, params.level, bufferKey);
cacheTile.set(key, promiseGeometry);

params.extent = shareableExtent;
params.center = builder.center(params.extent).clone();
Expand Down
241 changes: 0 additions & 241 deletions src/Core/Scheduler/Cache.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
let entry;

/**
* Cache policies for flushing. Those policies can be used when something is
* [set]{@link Cache.set} into the Cache, as the lifetime property.
Expand All @@ -17,242 +15,3 @@ export const CACHE_POLICIES = {
TEXTURE: 900000,
GEOMETRY: 900000,
};

/**
* This is a copy of the Map object, except that it also store a value for last
* time used. This value is used for cache expiration mechanism.
*
* @example
* import Cache, { CACHE_POLICIES } from 'Core/Scheduler/Cache';
*
* const cache = new Cache(CACHE_POLICIES.TEXTURE)
* cache.set({ bar: 1 }, 'foo');
* cache.set({ bar: 32 }, 'foo', 'toto');
*
* cache.get('foo');
*
* cache.delete('foo');
*
* cache.clear();
*
* cache.flush();
*/
class Cache {
/**
* @param {number} [lifetime=CACHE_POLICIES.INFINITE] The cache expiration time for all values.
*/
constructor(lifetime = CACHE_POLICIES.INFINITE) {
this.lifeTime = lifetime;
this.lastTimeFlush = Date.now();
this.data = new Map();
}

/**
* Returns the entry related to the specified key, content in array, from the cache.
* The array contents one to three key.
* The last time used property of the entry is updated to extend the longevity of the
* entry.
*
* @param {string[]|number[]} keyArray key array ([key0, key1, key3])
*
* @return {Object}
*/

getByArray(keyArray) {
return this.get(keyArray[0], keyArray[1], keyArray[2]);
}

/**
* Adds or updates an entry with specified keys array ([key0, key1, key3]).
* Caution: it overrides any existing entry already set at this/those key/s.
*
* @param {Object} value to add in cache
* @param {string[]|number[]} keyArray key array ([key0, key1, key3])
*
* @return {Object} the added value
*/
setByArray(value, keyArray) {
return this.set(value, keyArray[0], keyArray[1], keyArray[2]);
}

/**
* Returns the entry related to the specified key from the cache. The last
* time used property of the entry is updated to extend the longevity of the
* entry.
*
* @param {string|number} key1
* @param {string|number} [key2]
* @param {string|number} [key3]
*
* @return {Object}
*/
get(key1, key2, key3) {
const entry_1 = this.data.get(key1);
if (entry_1 == undefined) { return; }

if (entry_1.lastTimeUsed != undefined) {
entry = entry_1;
} else {
const entry_2 = entry_1.get(key2);
if (entry_2 == undefined) { return; }

if (entry_2.lastTimeUsed != undefined) {
entry = entry_2;
} else {
const entry_3 = entry_2.get(key3);
if (entry_3 == undefined) { return; }
entry = entry_3;
}
}

if (entry.value) {
entry.lastTimeUsed = Date.now();
return entry.value;
}
}

/**
* Adds or updates an entry with specified keys (up to 3).
* Caution: it overrides any existing entry already set at this/those key/s.
*
*
* @param {Object} value to add in cache
* @param {string|number} key1
* @param {string|number} [key2]
* @param {string|number} [key3]
*
* @return {Object} the added value
*/
set(value, key1, key2, key3) {
entry = {
value,
lastTimeUsed: Date.now(),
};

if (key2 == undefined) {
this.data.set(key1, entry);
return value;
}

if (!this.data.get(key1)) {
this.data.set(key1, new Map());
}

const entry_map = this.data.get(key1);

if (key3 == undefined) {
entry_map.set(key2, entry);
return value;
}

if (!entry_map.get(key2)) {
entry_map.set(key2, new Map());
}

entry_map.get(key2).set(key3, entry);

return value;
}

/**
* Deletes the specified entry from the cache.
*
* @param {string|number} key1
* @param {string|number} [key2]
* @param {string|number} [key3]
*/
delete(key1, key2, key3) {
const entry_1 = this.data.get(key1);
if (entry_1 === undefined) { return; }

if (entry_1.lastTimeUsed != undefined) {
delete this.data.get(key1);
this.data.delete(key1);
} else {
const entry_2 = entry_1.get(key2);
if (entry_2 === undefined) { return; }
if (entry_2.lastTimeUsed != undefined) {
delete entry_1.get(key2);
entry_1.delete(key2);
if (entry_1.size == 0) {
this.data.delete(key1);
}
} else {
const entry_3 = entry_2.get(key3);
if (entry_3 === undefined) { return; }
delete entry_2.get(key3);
entry_2.delete(key3);
if (entry_2.size == 0) {
entry_1.delete(key2);
if (entry_1.size == 0) {
this.data.delete(key1);
}
}
}
}
}

/**
* Removes all entries of the cache.
*
*/
clear() {
this.data.clear();
}

/**
* Flush the cache: entries that have been present for too long since the
* last time they were used, are removed from the cache. By default, the
* time is the current time, but the interval can be reduced by doing
* something like `Cache.flush(Date.now() - reductionTime)`. If you want to
* clear the whole cache, use {@link Cache.clear} instead.
*
* @param {number} [time=Date.now()]
*/
flush(time = Date.now()) {
if (this.lifeTime == CACHE_POLICIES.INFINITE ||
this.lifeTime > time - this.lastTimeFlush ||
!this.data.size) {
return;
}

this.lastTimeFlush = Infinity;
this.data.forEach((v1, i) => {
if (this.lifeTime < time - v1.lastTimeUsed) {
delete this.data.get(i);
this.data.delete(i);
} else {
v1.forEach((v2, j) => {
if (this.lifeTime < time - v2.lastTimeUsed) {
delete v1.get(j);
v1.delete(j);
} else {
v2.forEach((v3, k) => {
if (this.lifeTime < time - v3.lastTimeUsed) {
delete v2.get(k);
v2.delete(k);
} else {
// Work for the moment because all flushed caches have 3 key!
this.lastTimeFlush = Math.min(this.lastTimeFlush, v3.lastTimeUsed);
}
});
if (!v2.size) {
delete v1.get(j);
v1.delete(j);
}
}
});
if (!v1.size) {
delete this.data.get(i);
this.data.delete(i);
}
}
});

if (this.data.size == 0) {
this.lastTimeFlush = Date.now();
}
}
}

export default Cache;
Loading
Loading