-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(VirtualTimeScheduler): add VirtualTimeScheduler
- Refactors Action to be an interface - Adds VirtualTimeScheduler - Refactors Scheduler interface to include actions list related to #151 closes #269
- Loading branch information
Showing
12 changed files
with
214 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* globals describe, it, expect */ | ||
var Rx = require('../../dist/cjs/Rx'); | ||
var VirtualTimeScheduler = Rx.VirtualTimeScheduler; | ||
|
||
describe('VirtualTimeScheduler', function() { | ||
it('should exist', function () { | ||
expect(typeof VirtualTimeScheduler).toBe('function'); | ||
}); | ||
|
||
it('should schedule things in order when flushed if each this is scheduled synchrously', function () { | ||
var v = new VirtualTimeScheduler(); | ||
var invoked = []; | ||
var invoke = function (state) { | ||
invoked.push(state); | ||
}; | ||
v.schedule(invoke, 0, 1); | ||
v.schedule(invoke, 0, 2); | ||
v.schedule(invoke, 0, 3); | ||
v.schedule(invoke, 0, 4); | ||
v.schedule(invoke, 0, 5); | ||
|
||
v.flush(); | ||
|
||
expect(invoked).toEqual([1, 2, 3, 4, 5]); | ||
}); | ||
|
||
|
||
|
||
it('should schedule things in order when flushed if each this is scheduled at random', function () { | ||
var v = new VirtualTimeScheduler(); | ||
var invoked = []; | ||
var invoke = function (state) { | ||
invoked.push(state); | ||
}; | ||
v.schedule(invoke, 0, 1); | ||
v.schedule(invoke, 100, 2); | ||
v.schedule(invoke, 0, 3); | ||
v.schedule(invoke, 500, 4); | ||
v.schedule(invoke, 0, 5); | ||
v.schedule(invoke, 100, 6); | ||
|
||
v.flush(); | ||
|
||
expect(invoked).toEqual([1, 3, 5, 2, 6, 4]); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,18 @@ | ||
import Subscription from './Subscription'; | ||
import Action from './schedulers/Action'; | ||
|
||
interface Scheduler { | ||
now(): number; | ||
|
||
schedule<T>(work: (state?: any) => Subscription<T>|void, delay?: number, state?: any): Subscription<T>; | ||
|
||
flush(): void; | ||
|
||
actions: Action[]; | ||
|
||
scheduled: boolean; | ||
|
||
active: boolean; | ||
} | ||
|
||
export default Scheduler; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,11 @@ | ||
import Subscription from '../Subscription'; | ||
import ImmediateScheduler from './ImmediateScheduler'; | ||
|
||
export default class Action<T> extends Subscription<T> { | ||
|
||
interface Action extends Subscription<any> { | ||
work: (state?: any) => void|Subscription<any> | ||
state: any; | ||
delay?: number; | ||
schedule(state: any); | ||
execute(): void; | ||
} | ||
|
||
constructor(public scheduler: ImmediateScheduler, | ||
public work: (x?: any) => Subscription<T> | void) { | ||
super(); | ||
} | ||
|
||
schedule(state?: any): Action<T> { | ||
if (this.isUnsubscribed) { | ||
return this; | ||
} | ||
|
||
this.state = state; | ||
const scheduler = this.scheduler; | ||
scheduler.actions.push(this); | ||
scheduler.flush(); | ||
return this; | ||
} | ||
|
||
execute() { | ||
if (this.isUnsubscribed) { | ||
throw new Error("How did did we execute a canceled Action?"); | ||
} | ||
this.work(this.state); | ||
} | ||
|
||
unsubscribe() { | ||
|
||
const scheduler = this.scheduler; | ||
const actions = scheduler.actions; | ||
const index = actions.indexOf(this); | ||
|
||
this.work = void 0; | ||
this.state = void 0; | ||
this.scheduler = void 0; | ||
|
||
if (index !== -1) { | ||
actions.splice(index, 1); | ||
} | ||
|
||
super.unsubscribe(); | ||
} | ||
} | ||
export default Action; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import Subscription from '../Subscription'; | ||
import Scheduler from '../Scheduler'; | ||
import Action from './Action'; | ||
|
||
export default class ImmediateAction<T> extends Subscription<T> implements Action { | ||
|
||
state: any; | ||
|
||
constructor(public scheduler: Scheduler, | ||
public work: (x?: any) => Subscription<T> | void) { | ||
super(); | ||
} | ||
|
||
schedule(state?: any): Action { | ||
if (this.isUnsubscribed) { | ||
return this; | ||
} | ||
|
||
this.state = state; | ||
const scheduler = this.scheduler; | ||
scheduler.actions.push(this); | ||
scheduler.flush(); | ||
return this; | ||
} | ||
|
||
execute() { | ||
if (this.isUnsubscribed) { | ||
throw new Error("How did did we execute a canceled Action?"); | ||
} | ||
this.work(this.state); | ||
} | ||
|
||
unsubscribe() { | ||
|
||
const scheduler = this.scheduler; | ||
const actions = scheduler.actions; | ||
const index = actions.indexOf(this); | ||
|
||
this.work = void 0; | ||
this.state = void 0; | ||
this.scheduler = void 0; | ||
|
||
if (index !== -1) { | ||
actions.splice(index, 1); | ||
} | ||
|
||
super.unsubscribe(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import Scheduler from '../Scheduler'; | ||
import Subscription from '../Subscription'; | ||
import Action from './Action'; | ||
|
||
export default class VirtualTimeScheduler implements Scheduler { | ||
actions: Action[] = []; | ||
active: boolean = false; | ||
scheduled: boolean = false; | ||
index: number = 0; | ||
sorted: boolean = false; | ||
|
||
now() { | ||
return 0; | ||
} | ||
|
||
sortActions() { | ||
if (!this.sorted) { | ||
(<VirtualAction<any>[]>this.actions).sort((a, b) => { | ||
return a.delay === b.delay ? (a.index > b.index ? 1 : -1) : (a.delay > b.delay ? 1 : -1); | ||
}); | ||
this.sorted = true; | ||
} | ||
} | ||
|
||
flush() { | ||
this.sortActions(); | ||
this.actions.forEach(action => { | ||
action.execute(); | ||
}); | ||
this.actions.length = 0; | ||
} | ||
|
||
schedule<T>(work: (x?: any) => Subscription<T> | void, delay: number = 0, state?: any): Subscription<T> { | ||
this.sorted = false; | ||
return new VirtualAction(this, work, delay, this.index++).schedule(state); | ||
} | ||
} | ||
|
||
class VirtualAction<T> extends Subscription<T> implements Action { | ||
state: any; | ||
|
||
constructor(public scheduler: VirtualTimeScheduler, | ||
public work: (x?: any) => Subscription<T> | void, | ||
public delay: number, | ||
public index: number) { | ||
super(); | ||
} | ||
|
||
schedule(state?: any): VirtualAction<T> { | ||
if (this.isUnsubscribed) { | ||
return this; | ||
} | ||
|
||
this.state = state; | ||
const scheduler = this.scheduler; | ||
scheduler.actions.push(this); | ||
return this; | ||
} | ||
|
||
execute() { | ||
if (this.isUnsubscribed) { | ||
throw new Error("How did did we execute a canceled Action?"); | ||
} | ||
this.work(this.state); | ||
} | ||
|
||
unsubscribe() { | ||
const scheduler = this.scheduler; | ||
const actions = scheduler.actions; | ||
const index = actions.indexOf(this); | ||
|
||
this.work = void 0; | ||
this.state = void 0; | ||
this.scheduler = void 0; | ||
|
||
if (index !== -1) { | ||
actions.splice(index, 1); | ||
} | ||
|
||
super.unsubscribe(); | ||
} | ||
} |