114 lines
2.6 KiB
TypeScript
114 lines
2.6 KiB
TypeScript
/**
|
|
* Copyright (c) 2024-2026 The xterm.js authors. All rights reserved.
|
|
* @license MIT
|
|
*
|
|
* Minimal lifecycle utilities for xterm.js core.
|
|
* Simplified from VS Code's lifecycle.ts - no tracking/leak detection.
|
|
*/
|
|
|
|
export interface IDisposable {
|
|
dispose(): void;
|
|
}
|
|
|
|
export function toDisposable(fn: () => void): IDisposable {
|
|
return { dispose: fn };
|
|
}
|
|
|
|
export function dispose<T extends IDisposable>(disposable: T): T;
|
|
export function dispose<T extends IDisposable>(disposable: T | undefined): T | undefined;
|
|
export function dispose<T extends IDisposable>(disposables: T[]): T[];
|
|
export function dispose<T extends IDisposable>(arg: T | T[] | undefined): T | T[] | undefined {
|
|
if (!arg) {
|
|
return arg;
|
|
}
|
|
if (Array.isArray(arg)) {
|
|
for (const d of arg) {
|
|
d.dispose();
|
|
}
|
|
return [];
|
|
}
|
|
arg.dispose();
|
|
return arg;
|
|
}
|
|
|
|
export function combinedDisposable(...disposables: IDisposable[]): IDisposable {
|
|
return toDisposable(() => dispose(disposables));
|
|
}
|
|
|
|
export class DisposableStore implements IDisposable {
|
|
private readonly _disposables = new Set<IDisposable>();
|
|
private _isDisposed = false;
|
|
|
|
public get isDisposed(): boolean {
|
|
return this._isDisposed;
|
|
}
|
|
|
|
public add<T extends IDisposable>(o: T): T {
|
|
if (this._isDisposed) {
|
|
o.dispose();
|
|
} else {
|
|
this._disposables.add(o);
|
|
}
|
|
return o;
|
|
}
|
|
|
|
public dispose(): void {
|
|
if (this._isDisposed) {
|
|
return;
|
|
}
|
|
this._isDisposed = true;
|
|
for (const d of this._disposables) {
|
|
d.dispose();
|
|
}
|
|
this._disposables.clear();
|
|
}
|
|
|
|
public clear(): void {
|
|
for (const d of this._disposables) {
|
|
d.dispose();
|
|
}
|
|
this._disposables.clear();
|
|
}
|
|
}
|
|
|
|
export abstract class Disposable implements IDisposable {
|
|
public static readonly None: IDisposable = Object.freeze({ dispose() { } });
|
|
|
|
protected readonly _store = new DisposableStore();
|
|
|
|
public dispose(): void {
|
|
this._store.dispose();
|
|
}
|
|
|
|
protected _register<T extends IDisposable>(o: T): T {
|
|
return this._store.add(o);
|
|
}
|
|
}
|
|
|
|
export class MutableDisposable<T extends IDisposable> implements IDisposable {
|
|
private _value: T | undefined;
|
|
private _isDisposed = false;
|
|
|
|
public get value(): T | undefined {
|
|
return this._isDisposed ? undefined : this._value;
|
|
}
|
|
|
|
public set value(value: T | undefined) {
|
|
if (this._isDisposed || value === this._value) {
|
|
return;
|
|
}
|
|
this._value?.dispose();
|
|
this._value = value;
|
|
}
|
|
|
|
public clear(): void {
|
|
this.value = undefined;
|
|
}
|
|
|
|
public dispose(): void {
|
|
this._isDisposed = true;
|
|
this._value?.dispose();
|
|
this._value = undefined;
|
|
}
|
|
}
|