Repositorio del curso CCOM4030 el semestre B91 del proyecto Artesanías con el Instituto de Cultura

VirtualTimeScheduler.ts 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import { AsyncAction } from './AsyncAction';
  2. import { Subscription } from '../Subscription';
  3. import { AsyncScheduler } from './AsyncScheduler';
  4. import { SchedulerAction } from '../types';
  5. export class VirtualTimeScheduler extends AsyncScheduler {
  6. protected static frameTimeFactor: number = 10;
  7. public frame: number = 0;
  8. public index: number = -1;
  9. constructor(SchedulerAction: typeof AsyncAction = VirtualAction as any,
  10. public maxFrames: number = Number.POSITIVE_INFINITY) {
  11. super(SchedulerAction, () => this.frame);
  12. }
  13. /**
  14. * Prompt the Scheduler to execute all of its queued actions, therefore
  15. * clearing its queue.
  16. * @return {void}
  17. */
  18. public flush(): void {
  19. const {actions, maxFrames} = this;
  20. let error: any, action: AsyncAction<any>;
  21. while ((action = actions[0]) && action.delay <= maxFrames) {
  22. actions.shift();
  23. this.frame = action.delay;
  24. if (error = action.execute(action.state, action.delay)) {
  25. break;
  26. }
  27. }
  28. if (error) {
  29. while (action = actions.shift()) {
  30. action.unsubscribe();
  31. }
  32. throw error;
  33. }
  34. }
  35. }
  36. /**
  37. * We need this JSDoc comment for affecting ESDoc.
  38. * @nodoc
  39. */
  40. export class VirtualAction<T> extends AsyncAction<T> {
  41. protected active: boolean = true;
  42. constructor(protected scheduler: VirtualTimeScheduler,
  43. protected work: (this: SchedulerAction<T>, state?: T) => void,
  44. protected index: number = scheduler.index += 1) {
  45. super(scheduler, work);
  46. this.index = scheduler.index = index;
  47. }
  48. public schedule(state?: T, delay: number = 0): Subscription {
  49. if (!this.id) {
  50. return super.schedule(state, delay);
  51. }
  52. this.active = false;
  53. // If an action is rescheduled, we save allocations by mutating its state,
  54. // pushing it to the end of the scheduler queue, and recycling the action.
  55. // But since the VirtualTimeScheduler is used for testing, VirtualActions
  56. // must be immutable so they can be inspected later.
  57. const action = new VirtualAction(this.scheduler, this.work);
  58. this.add(action);
  59. return action.schedule(state, delay);
  60. }
  61. protected requestAsyncId(scheduler: VirtualTimeScheduler, id?: any, delay: number = 0): any {
  62. this.delay = scheduler.frame + delay;
  63. const {actions} = scheduler;
  64. actions.push(this);
  65. (actions as Array<VirtualAction<T>>).sort(VirtualAction.sortActions);
  66. return true;
  67. }
  68. protected recycleAsyncId(scheduler: VirtualTimeScheduler, id?: any, delay: number = 0): any {
  69. return undefined;
  70. }
  71. protected _execute(state: T, delay: number): any {
  72. if (this.active === true) {
  73. return super._execute(state, delay);
  74. }
  75. }
  76. public static sortActions<T>(a: VirtualAction<T>, b: VirtualAction<T>) {
  77. if (a.delay === b.delay) {
  78. if (a.index === b.index) {
  79. return 0;
  80. } else if (a.index > b.index) {
  81. return 1;
  82. } else {
  83. return -1;
  84. }
  85. } else if (a.delay > b.delay) {
  86. return 1;
  87. } else {
  88. return -1;
  89. }
  90. }
  91. }