2019-05-22 04:14:43 +00:00
|
|
|
// import "../type/Type";
|
|
|
|
import { Timeline, TimelineEvent } from "./Timeline";
|
|
|
|
|
|
|
|
export type PlaybackState = "started" | "stopped" | "paused";
|
|
|
|
|
|
|
|
export interface StateTimelineEvent extends TimelineEvent {
|
|
|
|
state: PlaybackState;
|
2019-06-19 13:55:08 +00:00
|
|
|
duration?: Seconds;
|
|
|
|
offset?: Seconds;
|
2019-07-23 15:26:41 +00:00
|
|
|
/**
|
|
|
|
* Either the buffer is explicitly scheduled to end using the stop method,
|
|
|
|
* or it's implicitly ended when the buffer is over.
|
|
|
|
*/
|
|
|
|
implicitEnd?: boolean;
|
2019-05-22 04:14:43 +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 extends Timeline<StateTimelineEvent> {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2019-06-19 13:55:08 +00:00
|
|
|
getValueAtTime(time: Seconds): PlaybackState {
|
2019-05-22 04:14:43 +00:00
|
|
|
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.
|
|
|
|
*/
|
2019-06-19 13:55:08 +00:00
|
|
|
setStateAtTime(state: PlaybackState, time: Seconds): this {
|
2019-05-22 04:14:43 +00:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|