1 import { AsyncAction } from './AsyncAction';
2 import { Subscription } from '../Subscription';
3 import { AsyncScheduler } from './AsyncScheduler';
4 import { SchedulerAction } from '../types';
6 export class VirtualTimeScheduler extends AsyncScheduler {
8 protected static frameTimeFactor: number = 10;
10 public frame: number = 0;
11 public index: number = -1;
13 constructor(SchedulerAction: typeof AsyncAction = VirtualAction as any,
14 public maxFrames: number = Number.POSITIVE_INFINITY) {
15 super(SchedulerAction, () => this.frame);
19 * Prompt the Scheduler to execute all of its queued actions, therefore
23 public flush(): void {
25 const {actions, maxFrames} = this;
26 let error: any, action: AsyncAction<any>;
28 while ((action = actions[0]) && action.delay <= maxFrames) {
30 this.frame = action.delay;
32 if (error = action.execute(action.state, action.delay)) {
38 while (action = actions.shift()) {
47 * We need this JSDoc comment for affecting ESDoc.
50 export class VirtualAction<T> extends AsyncAction<T> {
52 protected active: boolean = true;
54 constructor(protected scheduler: VirtualTimeScheduler,
55 protected work: (this: SchedulerAction<T>, state?: T) => void,
56 protected index: number = scheduler.index += 1) {
57 super(scheduler, work);
58 this.index = scheduler.index = index;
61 public schedule(state?: T, delay: number = 0): Subscription {
63 return super.schedule(state, delay);
66 // If an action is rescheduled, we save allocations by mutating its state,
67 // pushing it to the end of the scheduler queue, and recycling the action.
68 // But since the VirtualTimeScheduler is used for testing, VirtualActions
69 // must be immutable so they can be inspected later.
70 const action = new VirtualAction(this.scheduler, this.work);
72 return action.schedule(state, delay);
75 protected requestAsyncId(scheduler: VirtualTimeScheduler, id?: any, delay: number = 0): any {
76 this.delay = scheduler.frame + delay;
77 const {actions} = scheduler;
79 (actions as Array<VirtualAction<T>>).sort(VirtualAction.sortActions);
83 protected recycleAsyncId(scheduler: VirtualTimeScheduler, id?: any, delay: number = 0): any {
87 protected _execute(state: T, delay: number): any {
88 if (this.active === true) {
89 return super._execute(state, delay);
93 public static sortActions<T>(a: VirtualAction<T>, b: VirtualAction<T>) {
94 if (a.delay === b.delay) {
95 if (a.index === b.index) {
97 } else if (a.index > b.index) {
102 } else if (a.delay > b.delay) {