plotboilerplate
Version:
A simple javascript plotting boilerplate for 2d stuff.
71 lines (62 loc) • 1.84 kB
text/typescript
/**
* Approach to observe objects from other scripts to be initialized.
*
* @author Ikaros Kappler
* @date 2024-07-08
* @version 1.0.0
*/
interface IAccepptRejectPair<T, E> {
accept: (value: T) => void;
reject: (error: E | null) => void;
}
export class InitializationObserver<T, E> {
private _acceptRejectPairs: Array<IAccepptRejectPair<T, E | null>>;
private _timeoutMessage: E | null;
private _initializedValue: T;
private _isInitialized: boolean;
constructor(timeout: number, timeoutMessage?: E) {
this._acceptRejectPairs = [];
this._timeoutMessage = timeoutMessage ?? null;
globalThis.setTimeout(() => {
if (this._isInitialized) {
return; // NOOP
}
// else
if (!this._timeoutMessage) {
console.warn("Failed to initialize object. Reason unknown.");
}
this._fireReject(this._timeoutMessage ?? null);
}, timeout);
}
public accept(value: T): void {
if (this._isInitialized) {
return;
}
this._isInitialized = true;
this._initializedValue = value;
this._fireAccept(value);
}
private _fireAccept(value: T) {
this._acceptRejectPairs.forEach(pair => {
pair.accept(value);
});
}
private _fireReject(error: E | null) {
this._acceptRejectPairs.forEach(pair => {
pair.reject(error);
});
}
waitForInitialized(): Promise<T> {
const _self = this;
// If the value is already present, then accept immediately
if (_self._isInitialized) {
return new Promise<T>((accept: (value: T) => void, reject: (error: E | null) => void) => {
accept(_self._initializedValue);
});
} else {
return new Promise<T>((accept: (value: T) => void, reject: (error: E | null) => void) => {
_self._acceptRejectPairs.push({ accept, reject });
});
}
}
}