mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
828be28653
The goal is to be able to execute code whenever a root fiber is ready, and before the next animation frame
61 lines
1.6 KiB
TypeScript
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);
|
|
}
|
|
}
|
|
}
|