Use module-level cache

Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
Mark Tolmacs 2025-05-22 13:49:16 +02:00
parent 68cb5056ac
commit 9c04e22897
No known key found for this signature in database

View File

@ -27,17 +27,16 @@ import type {
type ElementShape = [LineSegment<GlobalPoint>[], Curve<GlobalPoint>[]]; type ElementShape = [LineSegment<GlobalPoint>[], Curve<GlobalPoint>[]];
class ElementShapeCache { const ElementShapesCache = new WeakMap<
private static cache = new WeakMap<
ExcalidrawElement, ExcalidrawElement,
{ version: ExcalidrawElement["version"]; shapes: Map<number, ElementShape> } { version: ExcalidrawElement["version"]; shapes: Map<number, ElementShape> }
>(); >();
public static get = <T extends ExcalidrawElement>( const getElementShapesCacheEntry = <T extends ExcalidrawElement>(
element: T, element: T,
offset: number, offset: number,
): ElementShape | undefined => { ): ElementShape | undefined => {
const record = ElementShapeCache.cache.get(element); const record = ElementShapesCache.get(element);
if (!record) { if (!record) {
return undefined; return undefined;
@ -46,22 +45,22 @@ class ElementShapeCache {
const { version, shapes } = record; const { version, shapes } = record;
if (version !== element.version) { if (version !== element.version) {
ElementShapeCache.cache.delete(element); ElementShapesCache.delete(element);
return undefined; return undefined;
} }
return shapes.get(offset); return shapes.get(offset);
}; };
public static set = <T extends ExcalidrawElement>( const setElementShapesCacheEntry = <T extends ExcalidrawElement>(
element: T, element: T,
shape: ElementShape, shape: ElementShape,
offset: number, offset: number,
) => { ) => {
const record = ElementShapeCache.cache.get(element); const record = ElementShapesCache.get(element);
if (!record) { if (!record) {
ElementShapeCache.cache.set(element, { ElementShapesCache.set(element, {
version: element.version, version: element.version,
shapes: new Map([[offset, shape]]), shapes: new Map([[offset, shape]]),
}); });
@ -72,7 +71,7 @@ class ElementShapeCache {
const { version, shapes } = record; const { version, shapes } = record;
if (version !== element.version) { if (version !== element.version) {
ElementShapeCache.cache.set(element, { ElementShapesCache.set(element, {
version: element.version, version: element.version,
shapes: new Map([[offset, shape]]), shapes: new Map([[offset, shape]]),
}); });
@ -82,12 +81,11 @@ class ElementShapeCache {
shapes.set(offset, shape); shapes.set(offset, shape);
}; };
}
export function deconstructLinearOrFreeDrawElement( export function deconstructLinearOrFreeDrawElement(
element: ExcalidrawLinearElement | ExcalidrawFreeDrawElement, element: ExcalidrawLinearElement | ExcalidrawFreeDrawElement,
): [LineSegment<GlobalPoint>[], Curve<GlobalPoint>[]] { ): [LineSegment<GlobalPoint>[], Curve<GlobalPoint>[]] {
const cachedShape = ElementShapeCache.get(element, 0); const cachedShape = getElementShapesCacheEntry(element, 0);
if (cachedShape) { if (cachedShape) {
return cachedShape; return cachedShape;
@ -158,7 +156,7 @@ export function deconstructLinearOrFreeDrawElement(
} }
const shape = [lines, curves] as ElementShape; const shape = [lines, curves] as ElementShape;
ElementShapeCache.set(element, shape, 0); setElementShapesCacheEntry(element, shape, 0);
return shape; return shape;
} }
@ -175,7 +173,7 @@ export function deconstructRectanguloidElement(
element: ExcalidrawRectanguloidElement, element: ExcalidrawRectanguloidElement,
offset: number = 0, offset: number = 0,
): [LineSegment<GlobalPoint>[], Curve<GlobalPoint>[]] { ): [LineSegment<GlobalPoint>[], Curve<GlobalPoint>[]] {
const cachedShape = ElementShapeCache.get(element, offset); const cachedShape = getElementShapesCacheEntry(element, offset);
if (cachedShape) { if (cachedShape) {
return cachedShape; return cachedShape;
@ -298,7 +296,7 @@ export function deconstructRectanguloidElement(
]; ];
const shape = [sides, corners.flat()] as ElementShape; const shape = [sides, corners.flat()] as ElementShape;
ElementShapeCache.set(element, shape, offset); setElementShapesCacheEntry(element, shape, offset);
return shape; return shape;
} }
@ -315,7 +313,7 @@ export function deconstructDiamondElement(
element: ExcalidrawDiamondElement, element: ExcalidrawDiamondElement,
offset: number = 0, offset: number = 0,
): [LineSegment<GlobalPoint>[], Curve<GlobalPoint>[]] { ): [LineSegment<GlobalPoint>[], Curve<GlobalPoint>[]] {
const cachedShape = ElementShapeCache.get(element, offset); const cachedShape = getElementShapesCacheEntry(element, offset);
if (cachedShape) { if (cachedShape) {
return cachedShape; return cachedShape;
@ -424,7 +422,7 @@ export function deconstructDiamondElement(
const shape = [sides, corners.flat()] as ElementShape; const shape = [sides, corners.flat()] as ElementShape;
ElementShapeCache.set(element, shape, offset); setElementShapesCacheEntry(element, shape, offset);
return shape; return shape;
} }