##// END OF EJS Templates
sync
sync

File last commit:

r15:3985e8405319 tip default
r15:3985e8405319 tip default
Show More
LifetimeSlot.ts
60 lines | 1.6 KiB | video/mp2t | TypeScriptLexer
import { ILifetimeSlot } from "../typings/interfaces";
import { isDestroyable } from "./traits";
const _destroy = (item: unknown) => () => isDestroyable(item) && item.destroy();
enum State {
New,
Initialized,
Destroyed
}
export class LifetimeSlot<T> implements ILifetimeSlot<T> {
private _value: NonNullable<T> | undefined = undefined;
private _state = State.New;
cleanup: () => void;
readonly remove: () => void;
constructor(remove: () => void) {
this.remove = this._finalizer(remove);
this.cleanup = this._finalizer(() => { });
}
has(): boolean {
this._assertNotDisposed();
return this._value !== undefined;
}
get(): NonNullable<T> {
this._assertNotDisposed();
if (this._value === undefined)
throw new Error("The slot doesn't have a value");
return this._value;
}
initialize(): boolean {
return this._state === State.New ?
(this._state = State.Initialized, true) :
false;
}
store(item: NonNullable<T>, cleanup: ((item: NonNullable<T>) => void) | undefined = _destroy): void {
this._assertNotDisposed();
this._value = item;
if (cleanup)
this.cleanup = this._finalizer(() => cleanup(item));
}
private _finalizer(cb: () => void) {
return () => this._state !== State.Destroyed ? (this._state = State.Destroyed, cb()) : void (0);
}
private _assertNotDisposed() {
if (this._state === State.Destroyed)
throw new Error("The slot is disposed");
}
}