Files
owl/src/component/scheduler.ts
T
Géry Debongnie 828be28653 [REF] component: introduce RootFiber.setCounter and update scheduler
The goal is to be able to execute code whenever a root fiber is ready,
and before the next animation frame
2022-03-29 15:45:27 +02:00

61 lines
1.6 KiB
TypeScript

import { fibersInError } from "./error_handling";
import { Fiber, RootFiber } from "./fibers";
import { STATUS } from "./status";
// -----------------------------------------------------------------------------
// Scheduler
// -----------------------------------------------------------------------------
export class Scheduler {
// capture the value of requestAnimationFrame as soon as possible, to avoid
// interactions with other code, such as test frameworks that override them
static requestAnimationFrame = window.requestAnimationFrame.bind(window);
tasks: Set<RootFiber> = new Set();
requestAnimationFrame: Window["requestAnimationFrame"];
frame: number = 0;
constructor() {
this.requestAnimationFrame = Scheduler.requestAnimationFrame;
}
addFiber(fiber: Fiber) {
this.tasks.add(fiber.root!);
}
/**
* Process all current tasks. This only applies to the fibers that are ready.
* Other tasks are left unchanged.
*/
flush() {
if (this.frame === 0) {
this.frame = this.requestAnimationFrame(() => {
this.frame = 0;
this.tasks.forEach((fiber) => this.processFiber(fiber));
});
}
}
processFiber(fiber: RootFiber) {
if (fiber.root !== fiber) {
this.tasks.delete(fiber);
return;
}
const hasError = fibersInError.has(fiber);
if (hasError && fiber.counter !== 0) {
this.tasks.delete(fiber);
return;
}
if (fiber.node.status === STATUS.DESTROYED) {
this.tasks.delete(fiber);
return;
}
if (fiber.counter === 0) {
if (!hasError) {
fiber.complete();
}
this.tasks.delete(fiber);
}
}
}