Evict links from maps when markers are disposed

This commit is contained in:
Daniel Imms
2022-08-07 08:05:42 -07:00
parent 9c9ff2b38c
commit 8191483fbd
+34 -11
View File
@@ -10,12 +10,16 @@ export class OscLinkService implements IOscLinkService {
private _nextId = 1;
// TODO: Evict on marker dispose
private _entriesNoId: IOscLinkEntryNoId[] = [];
/**
* A map of the link key to link entry. This is used to add additional lines to links with ids.
*/
private _entriesWithId: Map<string, IOscLinkEntryWithId> = new Map();
// The "link id" (number) which is the numberic representation of a unique link should not be
// confused with "id" (string) which comes in with "id=" in the OSC link's properties
/**
* A map of the link id to the link entry. The "link id" (number) which is the numberic
* representation of a unique link should not be confused with "id" (string) which comes in with
* `id=` in the OSC link's properties.
*/
private _dataByLinkId: Map<number, IOscLinkEntryNoId | IOscLinkEntryWithId> = new Map();
constructor(
@@ -28,12 +32,13 @@ export class OscLinkService implements IOscLinkService {
// Links with no id will only ever be registered a single time
if (data.id === undefined) {
const marker = buffer.addMarker(buffer.ybase + buffer.y);
const entry: IOscLinkEntryNoId = {
data,
id: this._nextId++,
lines: [buffer.addMarker(buffer.ybase + buffer.y)]
lines: [marker]
};
this._entriesNoId.push(entry);
marker.onDispose(() => this._removeMarkerFromLink(entry, marker));
this._dataByLinkId.set(entry.id, entry);
return entry.id;
}
@@ -48,24 +53,28 @@ export class OscLinkService implements IOscLinkService {
}
// Create the link
const marker = buffer.addMarker(buffer.ybase + buffer.y);
const entry: IOscLinkEntryWithId = {
id: this._nextId++,
key: this._getEntryIdKey(castData),
data: castData,
lines: [buffer.addMarker(buffer.ybase + buffer.y)]
lines: [marker]
};
marker.onDispose(() => this._removeMarkerFromLink(entry, marker));
this._entriesWithId.set(entry.key, entry);
this._dataByLinkId.set(entry.id, entry);
return entry.id;
}
public addLineToLink(linkId: number, y: number): void {
const link = this._dataByLinkId.get(linkId);
if (!link) {
const entry = this._dataByLinkId.get(linkId);
if (!entry) {
return;
}
if (link.lines.every(e => e.line !== y)) {
link.lines.push(this._bufferService.buffer.addMarker(y));
if (entry.lines.every(e => e.line !== y)) {
const marker = this._bufferService.buffer.addMarker(y);
entry.lines.push(marker);
marker.onDispose(() => this._removeMarkerFromLink(entry, marker));
}
}
@@ -76,6 +85,20 @@ export class OscLinkService implements IOscLinkService {
private _getEntryIdKey(linkData: Required<IOscLinkData>): string {
return `${linkData.id};;${linkData.uri}`;
}
private _removeMarkerFromLink(entry: IOscLinkEntryNoId | IOscLinkEntryWithId, marker: IMarker): void {
const index = entry.lines.indexOf(marker);
if (index === -1) {
return;
}
entry.lines.splice(index, 1);
if (entry.lines.length === 0) {
if (entry.data.id !== undefined) {
this._entriesWithId.delete((entry as IOscLinkEntryWithId).key);
}
this._dataByLinkId.delete(entry.id);
}
}
}
interface IOscLinkEntry<T extends IOscLinkData> {