import { EventEmitter } from 'eventemitter3'; interface DisposableEvent { active: [value: T]; dispose: [value: T]; destroy: []; } export class Disposable extends EventEmitter> { protected _data?: T; set data(value: T | null) { if (this.destroyed) { throw new Error( `Cannot set value of destroyed disposable variable.` ); } if (value !== null) this._data = value; } get data(): T | null { if (this.destroyed) { throw new Error( `Cannot get value of destroyed disposable variable.` ); } if (!this.activated) { return null; } return this._data!; } protected activated: boolean = false; protected destroyed: boolean = false; constructor(data: T) { super(); this._data = data; } active() { if (this.activated) return; this.activated = true; this.emit('active', this._data!); } dispose() { if (!this.activated) return; this.activated = false; this.emit('dispose', this._data!); } destroy() { if (this.destroyed) return; this.destroyed = true; this.emit('destroy'); delete this._data; } }