VirtualTimeScheduler.js 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import { AsyncAction } from './AsyncAction';
  2. import { Subscription } from '../Subscription';
  3. import { AsyncScheduler } from './AsyncScheduler';
  4. export class VirtualTimeScheduler extends AsyncScheduler {
  5. constructor(schedulerActionCtor = VirtualAction, maxFrames = Infinity) {
  6. super(schedulerActionCtor, () => this.frame);
  7. this.maxFrames = maxFrames;
  8. this.frame = 0;
  9. this.index = -1;
  10. }
  11. flush() {
  12. const { actions, maxFrames } = this;
  13. let error;
  14. let action;
  15. while ((action = actions[0]) && action.delay <= maxFrames) {
  16. actions.shift();
  17. this.frame = action.delay;
  18. if ((error = action.execute(action.state, action.delay))) {
  19. break;
  20. }
  21. }
  22. if (error) {
  23. while ((action = actions.shift())) {
  24. action.unsubscribe();
  25. }
  26. throw error;
  27. }
  28. }
  29. }
  30. VirtualTimeScheduler.frameTimeFactor = 10;
  31. export class VirtualAction extends AsyncAction {
  32. constructor(scheduler, work, index = (scheduler.index += 1)) {
  33. super(scheduler, work);
  34. this.scheduler = scheduler;
  35. this.work = work;
  36. this.index = index;
  37. this.active = true;
  38. this.index = scheduler.index = index;
  39. }
  40. schedule(state, delay = 0) {
  41. if (Number.isFinite(delay)) {
  42. if (!this.id) {
  43. return super.schedule(state, delay);
  44. }
  45. this.active = false;
  46. const action = new VirtualAction(this.scheduler, this.work);
  47. this.add(action);
  48. return action.schedule(state, delay);
  49. }
  50. else {
  51. return Subscription.EMPTY;
  52. }
  53. }
  54. requestAsyncId(scheduler, id, delay = 0) {
  55. this.delay = scheduler.frame + delay;
  56. const { actions } = scheduler;
  57. actions.push(this);
  58. actions.sort(VirtualAction.sortActions);
  59. return 1;
  60. }
  61. recycleAsyncId(scheduler, id, delay = 0) {
  62. return undefined;
  63. }
  64. _execute(state, delay) {
  65. if (this.active === true) {
  66. return super._execute(state, delay);
  67. }
  68. }
  69. static sortActions(a, b) {
  70. if (a.delay === b.delay) {
  71. if (a.index === b.index) {
  72. return 0;
  73. }
  74. else if (a.index > b.index) {
  75. return 1;
  76. }
  77. else {
  78. return -1;
  79. }
  80. }
  81. else if (a.delay > b.delay) {
  82. return 1;
  83. }
  84. else {
  85. return -1;
  86. }
  87. }
  88. }
  89. //# sourceMappingURL=VirtualTimeScheduler.js.map