Tone.js/Tone/core/util/StateTimeline.ts

97 lines
2.7 KiB
TypeScript
Raw Normal View History

import { Seconds } from "../type/Units";
import { Timeline, TimelineEvent } from "./Timeline";
2019-11-21 16:04:00 +00:00
import { assertRange } from "./Debug";
export type BasicPlaybackState = "started" | "stopped";
export type PlaybackState = BasicPlaybackState | "paused";
export interface StateTimelineEvent extends TimelineEvent {
state: PlaybackState;
}
/**
2019-09-14 20:39:18 +00:00
* 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<AdditionalOptions extends {} = {}> extends Timeline<StateTimelineEvent & AdditionalOptions> {
2019-09-04 23:18:44 +00:00
readonly name: string = "StateTimeline";
2019-08-27 17:02:31 +00:00
/**
2019-09-14 20:39:18 +00:00
* The initial state
*/
private _initial: PlaybackState;
constructor(initial: PlaybackState = "stopped") {
super();
this._initial = initial;
2019-12-14 21:11:56 +00:00
this.setStateAtTime(this._initial, 0);
}
/**
2019-09-14 20:39:18 +00:00
* 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;
}
}
/**
2019-09-14 20:39:18 +00:00
* Add a state to the timeline.
* @param state The name of the state to set.
* @param time The time to query.
* @param options Any additional options that are needed in the timeline.
*/
setStateAtTime(state: PlaybackState, time: Seconds, options?: AdditionalOptions): this {
2019-11-21 16:04:00 +00:00
assertRange(time, 0);
this.add(Object.assign({}, options, {
state,
time,
}));
return this;
}
/**
2019-09-14 20:39:18 +00:00
* 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 & AdditionalOptions | 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;
}
}
}
/**
2019-09-14 20:39:18 +00:00
* 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 & AdditionalOptions | 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;
}
}
}
}
}