mach: Listen to resize event for canvas and thus store window and

framebuffer size
This commit is contained in:
iddev5 2022-06-06 00:08:09 +05:30 committed by Stephen Gutekanst
parent 99dc10e58a
commit db377459c4
2 changed files with 66 additions and 8 deletions

View file

@ -137,10 +137,21 @@ function convertKeyCode(code) {
const mach = {
canvases: [],
wasm: undefined,
observer: undefined,
events: [],
changes: [],
init(wasm) {
this.wasm = wasm;
this.observer = new MutationObserver((mutables) => {
mutables.forEach((mutable) => {
if (mutable.type === 'attributes') {
if (mutable.attributeName === "width" || mutable.attributeName === "height") {
mutable.target.dispatchEvent(new Event("mach-canvas-resize"));
}
}
})
})
},
getString(str, len) {
@ -179,6 +190,8 @@ const mach = {
canvas.height = Math.floor(height * window.devicePixelRatio);
canvas.tabIndex = 1;
mach.observer.observe(canvas, { attributes: true });
mach.setString(canvas.id, id);
canvas.addEventListener("contextmenu", (ev) => ev.preventDefault());
@ -207,6 +220,12 @@ const mach = {
mach.events.push(...[6, ev.deltaX, ev.deltaY]);
});
canvas.addEventListener("mach-canvas-resize", (ev) => {
const cv_index = mach.canvases.findIndex((el) => el.canvas === ev.currentTarget);
const cv = mach.canvases[cv_index];
mach.changes.push(...[1, cv.canvas.width, cv.canvas.height, window.devicePixelRatio]);
});
document.body.appendChild(canvas);
return mach.canvases.push({ canvas: canvas, title: undefined }) - 1;
},
@ -266,6 +285,13 @@ const mach = {
return mach.machEventShift();
},
machChangeShift() {
if (mach.changes.length < 0)
return 0;
return mach.changes.shift();
},
machPerfNow() {
return performance.now();
},

View file

@ -15,6 +15,7 @@ const js = struct {
extern fn machCanvasGetFramebufferHeight(canvas: CanvasId) u32;
extern fn machEventShift() i32;
extern fn machEventShiftFloat() f64;
extern fn machChangeShift() u32;
extern fn machPerfNow() f64;
extern fn machLog(str: [*]const u8, len: u32) void;
@ -29,6 +30,9 @@ pub const Platform = struct {
id: CanvasId,
selector_id: []const u8,
last_window_size: structs.Size,
last_framebuffer_size: structs.Size,
pub fn init(allocator: std.mem.Allocator, eng: *Engine) !Platform {
const options = eng.options;
var selector = [1]u8{0} ** 15;
@ -40,6 +44,14 @@ pub const Platform = struct {
return Platform{
.id = id,
.selector_id = try allocator.dupe(u8, selector[0 .. selector.len - @as(u32, if (selector[selector.len - 1] == 0) 1 else 0)]),
.last_window_size = .{
.width = js.machCanvasGetWindowWidth(id),
.height = js.machCanvasGetWindowHeight(id),
},
.last_framebuffer_size = .{
.width = js.machCanvasGetFramebufferWidth(id),
.height = js.machCanvasGetFramebufferHeight(id),
},
};
}
@ -54,17 +66,34 @@ pub const Platform = struct {
pub fn setShouldClose(_: *Platform, _: bool) void {}
pub fn getFramebufferSize(platform: *Platform) structs.Size {
return structs.Size{
.width = js.machCanvasGetFramebufferWidth(platform.id),
.height = js.machCanvasGetFramebufferHeight(platform.id),
};
return platform.last_framebuffer_size;
}
pub fn getWindowSize(platform: *Platform) structs.Size {
return structs.Size{
.width = js.machCanvasGetWindowWidth(platform.id),
.height = js.machCanvasGetWindowHeight(platform.id),
};
return platform.last_window_size;
}
fn pollChanges(platform: *Platform) void {
const change_type = js.machChangeShift();
switch (change_type) {
1 => {
const width = js.machChangeShift();
const height = js.machChangeShift();
const device_pixel_ratio = js.machChangeShift();
platform.last_window_size = .{
.width = @divFloor(width, device_pixel_ratio),
.height = @divFloor(height, device_pixel_ratio),
};
platform.last_framebuffer_size = .{
.width = width,
.height = height,
};
},
else => {},
}
}
pub fn pollEvent(_: *Platform) ?structs.Event {
@ -168,6 +197,9 @@ export fn wasmInit() void {
}
export fn wasmUpdate() bool {
// Poll internal events, like resize
engine.internal.pollChanges();
engine.delta_time_ns = engine.timer.lapPrecise();
engine.delta_time = @intToFloat(f32, engine.delta_time_ns) / @intToFloat(f32, std.time.ns_per_s);