// import "../type/Type"; import { Timeline, TimelineEvent } from "./Timeline"; export type PlaybackState = "started" | "stopped" | "paused"; export interface StateTimelineEvent extends TimelineEvent { state: PlaybackState; duration?: Seconds; offset?: Seconds; /** * Either the buffer is explicitly scheduled to end using the stop method, * or it's implicitly ended when the buffer is over. */ implicitEnd?: boolean; } /** * A Timeline State. Provides the methods: `setStateAtTime("state", time)` and `getValueAtTime(time)` * @param initial The initial state of the StateTimeline. Defaults to `undefined` */ export class StateTimeline extends Timeline { /** * The initial state */ private _initial: PlaybackState; constructor(initial: PlaybackState = "stopped") { super(); this._initial = initial; } /** * Returns the scheduled state scheduled before or at * the given time. * @param time The time to query. * @return The name of the state input in setStateAtTime. */ getValueAtTime(time: Seconds): PlaybackState { const event = this.get(time); if (event !== null) { return event.state; } else { return this._initial; } } /** * Add a state to the timeline. * @param state The name of the state to set. * @param time The time to query. */ setStateAtTime(state: PlaybackState, time: Seconds): this { // all state changes need to be >= the previous state time // TODO throw error if time < the previous event time this.add({ state, time, }); return this; } /** * Return the event before the time with the given state * @param state The state to look for * @param time When to check before * @return The event with the given state before the time */ getLastState(state: PlaybackState, time: number): StateTimelineEvent | undefined { // time = this.toSeconds(time); const index = this._search(time); for (let i = index; i >= 0; i--) { const event = this._timeline[i]; if (event.state === state) { return event; } } } /** * Return the event after the time with the given state * @param state The state to look for * @param time When to check from * @return The event with the given state after the time */ getNextState(state: PlaybackState, time: number): StateTimelineEvent | undefined { // time = this.toSeconds(time); const index = this._search(time); if (index !== -1) { for (let i = index; i < this._timeline.length; i++) { const event = this._timeline[i]; if (event.state === state) { return event; } } } } }