spread new implementation

This commit is contained in:
Halil Durak
2026-02-02 13:36:24 +03:00
parent 12fe119d6b
commit a4595f58b8
4 changed files with 72 additions and 55 deletions

View File

@@ -379,13 +379,18 @@ fn registerBackgroundTasks(self: *Page) !void {
const Browser = @import("Browser.zig"); const Browser = @import("Browser.zig");
try self.scheduler.add(self._session.browser, struct { return self.scheduler.after(
fn runMessageLoop(ctx: *anyopaque) !?u32 { .{ .name = "runMessageLoop", .priority = .high },
const b: *Browser = @ptrCast(@alignCast(ctx)); Browser,
b.runMessageLoop(); self._session.browser,
return 250; 250,
} struct {
}.runMessageLoop, 250, .{ .name = "page.messageLoop" }); fn runMessageLoop(_: *Scheduler, browser: *Browser) !Scheduler.AfterAction {
browser.runMessageLoop();
return .repeat(250);
}
}.runMessageLoop,
);
} }
pub fn getTitle(self: *Page) !?[]const u8 { pub fn getTitle(self: *Page) !?[]const u8 {
@@ -1262,25 +1267,22 @@ pub fn notifyPerformanceObservers(self: *Page, entry: *Performance.Entry) !void
} }
self._performance_delivery_scheduled = true; self._performance_delivery_scheduled = true;
return self.scheduler.add( return self.scheduler.once(
.{ .priority = .low },
Page,
self, self,
struct { struct {
fn run(_page: *anyopaque) anyerror!?u32 { fn run(_: *Scheduler, page: *Page) !void {
const page: *Page = @ptrCast(@alignCast(_page));
page._performance_delivery_scheduled = false; page._performance_delivery_scheduled = false;
// Dispatch performance observer events. // Dispatch performance observers.
for (page._performance_observers.items) |observer| { for (page._performance_observers.items) |observer| {
if (observer.hasRecords()) { if (observer.hasRecords()) {
try observer.dispatch(page); try observer.dispatch(page);
} }
} }
return null;
} }
}.run, }.run,
0,
.{ .low_priority = true },
); );
} }

View File

@@ -21,6 +21,7 @@ const js = @import("../js/js.zig");
const log = @import("../../log.zig"); const log = @import("../../log.zig");
const Page = @import("../Page.zig"); const Page = @import("../Page.zig");
const Scheduler = @import("../Scheduler.zig");
const Event = @import("Event.zig"); const Event = @import("Event.zig");
const EventTarget = @import("EventTarget.zig"); const EventTarget = @import("EventTarget.zig");
@@ -99,9 +100,17 @@ pub fn createTimeout(delay: u32, page: *Page) !*AbortSignal {
.signal = try init(page), .signal = try init(page),
}; };
try page.scheduler.add(callback, TimeoutCallback.run, delay, .{ //try page.scheduler.add(callback, TimeoutCallback.run, delay, .{
.name = "AbortSignal.timeout", // .name = "AbortSignal.timeout",
}); //});
try page.scheduler.after(
.{ .name = "AbortSignal.timeout", .priority = .high },
TimeoutCallback,
callback,
delay,
TimeoutCallback.run,
);
return callback.signal; return callback.signal;
} }
@@ -134,8 +143,7 @@ const TimeoutCallback = struct {
page: *Page, page: *Page,
signal: *AbortSignal, signal: *AbortSignal,
fn run(ctx: *anyopaque) !?u32 { fn run(_: *Scheduler, self: *TimeoutCallback) !Scheduler.AfterAction {
const self: *TimeoutCallback = @ptrCast(@alignCast(ctx));
var ls: js.Local.Scope = undefined; var ls: js.Local.Scope = undefined;
self.page.js.localScope(&ls); self.page.js.localScope(&ls);
defer ls.deinit(); defer ls.deinit();
@@ -143,7 +151,8 @@ const TimeoutCallback = struct {
self.signal.abort(.{ .string = "TimeoutError" }, &ls.local, self.page) catch |err| { self.signal.abort(.{ .string = "TimeoutError" }, &ls.local, self.page) catch |err| {
log.warn(.app, "abort signal timeout", .{ .err = err }); log.warn(.app, "abort signal timeout", .{ .err = err });
}; };
return null;
return .dont_repeat;
} }
}; };

View File

@@ -21,6 +21,7 @@ const js = @import("../js/js.zig");
const log = @import("../../log.zig"); const log = @import("../../log.zig");
const Page = @import("../Page.zig"); const Page = @import("../Page.zig");
const Scheduler = @import("../Scheduler.zig");
const EventTarget = @import("EventTarget.zig"); const EventTarget = @import("EventTarget.zig");
const MessageEvent = @import("event/MessageEvent.zig"); const MessageEvent = @import("event/MessageEvent.zig");
@@ -65,10 +66,12 @@ pub fn postMessage(self: *MessagePort, message: js.Value.Global, page: *Page) !v
.message = message, .message = message,
}); });
try page.scheduler.add(callback, PostMessageCallback.run, 0, .{ try page.scheduler.once(
.name = "MessagePort.postMessage", .{ .name = "MessagePort.postMessage", .priority = .high },
.low_priority = false, PostMessageCallback,
}); callback,
PostMessageCallback.run,
);
} }
pub fn start(self: *MessagePort) void { pub fn start(self: *MessagePort) void {
@@ -113,13 +116,12 @@ const PostMessageCallback = struct {
self.page._factory.destroy(self); self.page._factory.destroy(self);
} }
fn run(ctx: *anyopaque) !?u32 { fn run(_: *Scheduler, self: *PostMessageCallback) !void {
const self: *PostMessageCallback = @ptrCast(@alignCast(ctx));
defer self.deinit(); defer self.deinit();
const page = self.page; const page = self.page;
if (self.port._closed) { if (self.port._closed) {
return null; return;
} }
const event = MessageEvent.initTrusted("message", .{ const event = MessageEvent.initTrusted("message", .{
@@ -128,7 +130,7 @@ const PostMessageCallback = struct {
.source = null, .source = null,
}, page) catch |err| { }, page) catch |err| {
log.err(.dom, "MessagePort.postMessage", .{ .err = err }); log.err(.dom, "MessagePort.postMessage", .{ .err = err });
return null; return;
}; };
var ls: js.Local.Scope = undefined; var ls: js.Local.Scope = undefined;
@@ -143,8 +145,6 @@ const PostMessageCallback = struct {
) catch |err| { ) catch |err| {
log.err(.dom, "MessagePort.postMessage", .{ .err = err }); log.err(.dom, "MessagePort.postMessage", .{ .err = err });
}; };
return null;
} }
}; };

View File

@@ -22,6 +22,7 @@ const builtin = @import("builtin");
const log = @import("../../log.zig"); const log = @import("../../log.zig");
const Page = @import("../Page.zig"); const Page = @import("../Page.zig");
const Scheduler = @import("../Scheduler.zig");
const Console = @import("Console.zig"); const Console = @import("Console.zig");
const History = @import("History.zig"); const History = @import("History.zig");
const Navigation = @import("navigation/Navigation.zig"); const Navigation = @import("navigation/Navigation.zig");
@@ -366,11 +367,19 @@ pub fn postMessage(self: *Window, message: js.Value.Global, target_origin: ?[]co
.message = message, .message = message,
.origin = try arena.dupe(u8, origin), .origin = try arena.dupe(u8, origin),
}; };
try page.scheduler.add(callback, PostMessageCallback.run, 0, .{
.name = "postMessage", //try page.scheduler.add(callback, PostMessageCallback.run, 0, .{
.low_priority = false, // .name = "postMessage",
.finalizer = PostMessageCallback.cancelled, // .low_priority = false,
}); // .finalizer = PostMessageCallback.cancelled,
//});
return page.scheduler.once(
.{ .name = "postMessage", .priority = .high },
PostMessageCallback,
callback,
PostMessageCallback.run,
);
} }
pub fn btoa(_: *const Window, input: []const u8, page: *Page) ![]const u8 { pub fn btoa(_: *const Window, input: []const u8, page: *Page) ![]const u8 {
@@ -447,16 +456,17 @@ pub fn scrollTo(self: *Window, opts: ScrollToOpts, y: ?i32, page: *Page) !void {
// We dispatch scroll event asynchronously after 10ms. So we can throttle // We dispatch scroll event asynchronously after 10ms. So we can throttle
// them. // them.
try page.scheduler.add( try page.scheduler.once(
.{ .priority = .low },
Page,
page, page,
struct { struct {
fn dispatch(_page: *anyopaque) anyerror!?u32 { fn dispatch(_: *Scheduler, p: *Page) !void {
const p: *Page = @ptrCast(@alignCast(_page));
const pos = &p.window._scroll_pos; const pos = &p.window._scroll_pos;
// If the state isn't scroll, we can ignore safely to throttle // If the state isn't scroll, we can ignore safely to throttle
// the events. // the events.
if (pos.state != .scroll) { if (pos.state != .scroll) {
return null; return;
} }
const event = try Event.initTrusted("scroll", .{ .bubbles = true }, p); const event = try Event.initTrusted("scroll", .{ .bubbles = true }, p);
@@ -464,38 +474,37 @@ pub fn scrollTo(self: *Window, opts: ScrollToOpts, y: ?i32, page: *Page) !void {
pos.state = .end; pos.state = .end;
return null; return;
} }
}.dispatch, }.dispatch,
10,
.{ .low_priority = true },
); );
// We dispatch scrollend event asynchronously after 20ms. // We dispatch scrollend event asynchronously after 20ms.
try page.scheduler.add( try page.scheduler.after(
.{ .priority = .low },
Page,
page, page,
20,
struct { struct {
fn dispatch(_page: *anyopaque) anyerror!?u32 { fn dispatch(_: *Scheduler, p: *Page) !Scheduler.AfterAction {
const p: *Page = @ptrCast(@alignCast(_page));
const pos = &p.window._scroll_pos; const pos = &p.window._scroll_pos;
// Dispatch only if the state is .end. // Dispatch only if the state is .end.
// If a scroll is pending, retry in 10ms. // If a scroll is pending, retry in 10ms.
// If the state is .end, the event has been dispatched, so // If the state is .end, the event has been dispatched, so
// ignore safely. // ignore safely.
switch (pos.state) { switch (pos.state) {
.scroll => return 10, .scroll => return .repeat(10),
.end => {}, .end => {},
.done => return null, .done => return .dont_repeat,
} }
const event = try Event.initTrusted("scrollend", .{ .bubbles = true }, p); const event = try Event.initTrusted("scrollend", .{ .bubbles = true }, p);
try p._event_manager.dispatch(p.document.asEventTarget(), event); try p._event_manager.dispatch(p.document.asEventTarget(), event);
pos.state = .done; pos.state = .done;
return null; return .dont_repeat;
} }
}.dispatch, }.dispatch,
20,
.{ .low_priority = true },
); );
} }
@@ -656,8 +665,7 @@ const PostMessageCallback = struct {
self.page.releaseArena(self.arena); self.page.releaseArena(self.arena);
} }
fn run(ctx: *anyopaque) !?u32 { fn run(_: *Scheduler, self: *PostMessageCallback) !void {
const self: *PostMessageCallback = @ptrCast(@alignCast(ctx));
defer self.deinit(); defer self.deinit();
const page = self.page; const page = self.page;
@@ -673,8 +681,6 @@ const PostMessageCallback = struct {
const event = message_event.asEvent(); const event = message_event.asEvent();
try page._event_manager.dispatch(window.asEventTarget(), event); try page._event_manager.dispatch(window.asEventTarget(), event);
return null;
} }
}; };