import { CONTEXT_STORE } from '../globals'; import { IAudioDestinationNode, IAudioListener, IMinimalBaseAudioContext, IMinimalBaseAudioContextEventMap } from '../interfaces'; import { TAudioContextState, TContext, TEventHandler, TMinimalBaseAudioContextConstructorFactory, TNativeContext } from '../types'; export const createMinimalBaseAudioContextConstructor: TMinimalBaseAudioContextConstructorFactory = ( audioDestinationNodeConstructor, createAudioListener, eventTargetConstructor, isNativeOfflineAudioContext, unrenderedAudioWorkletNodeStore, wrapEventListener ) => { return class MinimalBaseAudioContext extends eventTargetConstructor implements IMinimalBaseAudioContext { private _destination: IAudioDestinationNode; private _listener: IAudioListener; private _onstatechange: null | TEventHandler; constructor(private _nativeContext: TNativeContext, numberOfChannels: number) { super(_nativeContext); CONTEXT_STORE.set((this), _nativeContext); if (isNativeOfflineAudioContext(_nativeContext)) { unrenderedAudioWorkletNodeStore.set(_nativeContext, new Set()); } this._destination = new audioDestinationNodeConstructor((this), numberOfChannels); this._listener = createAudioListener((this), _nativeContext); this._onstatechange = null; } get currentTime(): number { return this._nativeContext.currentTime; } get destination(): IAudioDestinationNode { return this._destination; } get listener(): IAudioListener { return this._listener; } get onstatechange(): null | TEventHandler { return this._onstatechange; } set onstatechange(value) { const wrappedListener = typeof value === 'function' ? wrapEventListener(this, value) : null; this._nativeContext.onstatechange = wrappedListener; const nativeOnStateChange = this._nativeContext.onstatechange; this._onstatechange = nativeOnStateChange !== null && nativeOnStateChange === wrappedListener ? value : nativeOnStateChange; } get sampleRate(): number { return this._nativeContext.sampleRate; } get state(): TAudioContextState { return this._nativeContext.state; } }; };