blob: 98b3edc51721899191f78abd1738e7d34e48cd4f [file]
import { Layout, Context } from "rive/host";
import { Job, Jobs } from "rive/jobs";
import { LaneState } from "rive/lanes";
// Never polls, so only a stop reaching its fuel checks ends it, or on the
// page's thread the page's call budget.
@job export function spin(seed: i32): i32 {
let x = seed;
while (x >= 0) {
x = (x * 1103515245 + 12345) & 0x7fffffff;
}
return x;
}
@job export function square(x: f64): f64 {
return x * x;
}
export class Main extends Layout {
context: Context? = null;
spinners: Array<Job<i32>> = new Array<Job<i32>>();
frames: i32 = 0;
after: Job<f64>? = null;
reported: bool = false;
override init(context: Context): bool {
this.context = context;
// One more than the pool has threads, and every thread holds one
// before init returns, so even a release at once has them to end.
for (let i: u32 = 0; i <= Jobs.threads(); i++) {
this.spinners.push(Jobs.run(spin, <i32>i));
}
while (this.count(LaneState.running) < <i32>Jobs.threads()) {}
return true;
}
count(state: LaneState): i32 {
let found = 0;
for (let i = 0; i < this.spinners.length; i++) {
if (this.spinners[i].state == state) {
found++;
}
}
return found;
}
override advance(seconds: f64): bool {
let context = this.context!;
let spinners = this.spinners;
if (++this.frames == 3) {
for (let i = 0; i < spinners.length; i++) {
spinners[i].stop();
}
}
let after = this.after;
if (after == null) {
let over = 0;
for (let i = 0; i < spinners.length; i++) {
over += spinners[i].running ? 0 : 1;
}
if (this.frames < 3 || over < spinners.length) {
return true;
}
for (let i = 0; i < spinners.length; i++) {
let failed = spinners[i].failed;
if (failed != null) {
context.log("spinner failed: " + failed);
}
}
let stopped = this.count(LaneState.stopped) == spinners.length;
context.log("spinners stopped " + (stopped ? "yes" : "no"));
this.after = Jobs.run(square, 3.0);
} else if (!this.reported && !after.running) {
this.reported = true;
context.log("job after the spinners " + after.peek()!.value.toString());
}
return true;
}
}