Progress on osc link service

This commit is contained in:
Daniel Imms
2022-08-07 07:02:42 -07:00
parent fd79100d95
commit ace99d125d
5 changed files with 105 additions and 20 deletions
+77 -8
View File
@@ -1,23 +1,92 @@
/**
* Copyright (c) 2022 The xterm.js authors. All rights reserved.
* @license MIT
*/
import { IBufferService, IOscLinkService } from 'common/services/Services';
import { IOscLinkData } from 'common/Types';
import { IMarker, IOscLinkData } from 'common/Types';
export class OscLinkService implements IOscLinkService {
public serviceBrand: any;
private _nextId = 1;
// TODO: Evict on marker dispose
private _entriesNoId: IOscLinkEntryNoId[] = [];
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
private _dataByLinkId: Map<number, IOscLinkEntryNoId | IOscLinkEntryWithId> = new Map();
constructor(
@IBufferService private readonly _bufferService: IBufferService
) {
}
public registerLink(linkData: IOscLinkData): number {
console.log('register link');
// TODO: Add and return properly
return 1;
public registerLink(data: IOscLinkData): number {
// TODO: Extend range where appropriate
const buffer = this._bufferService.buffer;
// Links with no id will only ever be registered a single time
if (data.id === undefined) {
const entry: IOscLinkEntryNoId = {
data,
id: this._nextId++,
lines: [buffer.addMarker(buffer.ybase + buffer.y)]
};
this._entriesNoId.push(entry);
this._dataByLinkId.set(entry.id, entry);
return entry.id;
}
const castData = data as Required<IOscLinkData>;
const key = this._getEntryIdKey(castData);
const match = this._entriesWithId.get(key);
if (match) {
this.addLineToLink(match.id, buffer.ybase + buffer.y);
return match.id;
}
const entry: IOscLinkEntryWithId = {
id: this._nextId++,
key: this._getEntryIdKey(castData),
data: castData,
lines: [buffer.addMarker(buffer.ybase + buffer.y)]
};
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) {
return;
}
if (link.lines.every(e => e.line !== y)) {
console.log(' add new line', y);
link.lines.push(this._bufferService.buffer.addMarker(y));
}
}
public getLinkData(linkId: number): IOscLinkData | undefined {
return {
uri: 'https://github.com'
};
return this._dataByLinkId.get(linkId)?.data;
}
private _getEntryIdKey(linkData: Required<IOscLinkData>): string {
return `${linkData.id};;${linkData.uri}`;
}
}
interface IOscLinkEntry<T extends IOscLinkData> {
data: T;
id: number;
lines: IMarker[];
}
interface IOscLinkEntryNoId extends IOscLinkEntry<IOscLinkData> {
}
interface IOscLinkEntryWithId extends IOscLinkEntry<Required<IOscLinkData>> {
key: string;
}
+4
View File
@@ -280,6 +280,10 @@ export interface IOscLinkService {
* service and will be freed when this current cursor position is trimmed off the buffer.
*/
registerLink(linkData: IOscLinkData): number;
/**
* Adds a line to a link if needed.
*/
addLineToLink(linkId: number, y: number): void;
/** Get the link data associated with a link ID. */
getLinkData(linkId: number): IOscLinkData | undefined;
}