From a5a3d31411921ccd93fb4cf013abb5499c2f39cf Mon Sep 17 00:00:00 2001 From: Stephen Gutekanst Date: Sat, 24 Aug 2024 22:22:49 -0700 Subject: [PATCH] core: remove WASM support Signed-off-by: Stephen Gutekanst --- build.zig | 4 +- src/Core.zig | 4 +- src/core/Wasm.zig | 473 ---------------------------------------------- 3 files changed, 4 insertions(+), 477 deletions(-) delete mode 100644 src/core/Wasm.zig diff --git a/build.zig b/build.zig index cc50cacd..06884b15 100644 --- a/build.zig +++ b/build.zig @@ -286,13 +286,13 @@ pub fn build(b: *std.Build) !void { pub const Platform = enum { x11, wayland, - web, + wasm, win32, darwin, null, pub fn fromTarget(target: std.Target) Platform { - if (target.cpu.arch == .wasm32) return .web; + if (target.cpu.arch == .wasm32) return .wasm; if (target.os.tag.isDarwin()) return .darwin; if (target.os.tag == .windows) return .win32; return .x11; diff --git a/src/Core.zig b/src/Core.zig index ee9c14fb..80db0dbd 100644 --- a/src/Core.zig +++ b/src/Core.zig @@ -15,7 +15,7 @@ const Frequency = @import("core/Frequency.zig"); pub const Platform = switch (build_options.core_platform) { .x11 => @import("core/X11.zig"), .wayland => @import("core/Wayland.zig"), - .web => @panic("TODO: revive wasm backend"), + .wasm => @panic("TODO: support mach.Core WASM platform"), .win32 => @import("core/win32.zig"), .darwin => @import("core/Darwin.zig"), .null => @import("core/Null.zig"), @@ -27,7 +27,7 @@ pub const supports_non_blocking = switch (build_options.core_platform) { .win32 => true, .x11 => true, .wayland => true, - .web => false, + .wasm => false, .darwin => false, .null => false, }; diff --git a/src/core/Wasm.zig b/src/core/Wasm.zig deleted file mode 100644 index 10f38e06..00000000 --- a/src/core/Wasm.zig +++ /dev/null @@ -1,473 +0,0 @@ -const std = @import("std"); -const js = @import("js.zig"); -const Timer = @import("Timer.zig"); -const mach = @import("../../../main.zig"); -const gpu = mach.gpu; -const InitOptions = @import("../../../Core.zig").InitOptions; -const Event = @import("../../../Core.zig").Event; -const KeyEvent = @import("../../../Core.zig").KeyEvent; -const MouseButtonEvent = @import("../../../Core.zig").MouseButtonEvent; -const MouseButton = @import("../../../Core.zig").MouseButton; -const Size = @import("../../../Core.zig").Size; -const Position = @import("../../../Core.zig").Position; -const DisplayMode = @import("../../../Core.zig").DisplayMode; -const SizeLimit = @import("../../../Core.zig").SizeLimit; -const CursorShape = @import("../../../Core.zig").CursorShape; -const VSyncMode = @import("../../../Core.zig").VSyncMode; -const CursorMode = @import("../../../Core.zig").CursorMode; -const Key = @import("../../../Core.zig").Key; -const KeyMods = @import("../../../Core.zig").KeyMods; -const Joystick = @import("../../../Core.zig").Joystick; -const InputState = @import("../../InputState.zig"); -const Frequency = @import("../../Frequency.zig"); - -// Custom std.log implementation which logs to the browser console. -pub fn defaultLog( - comptime message_level: std.log.Level, - comptime scope: @Type(.EnumLiteral), - comptime format: []const u8, - args: anytype, -) void { - const prefix = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): "; - const writer = LogWriter{ .context = {} }; - - writer.print(message_level.asText() ++ prefix ++ format ++ "\n", args) catch return; - machLogFlush(); -} - -// Custom @panic implementation which logs to the browser console. -pub fn defaultPanic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace, ret_addr: ?usize) noreturn { - _ = error_return_trace; - _ = ret_addr; - machPanic(msg.ptr, msg.len); - unreachable; -} - -pub extern "mach" fn machPanic(str: [*]const u8, len: u32) void; -pub extern "mach" fn machLogWrite(str: [*]const u8, len: u32) void; -pub extern "mach" fn machLogFlush() void; - -const LogError = error{}; -const LogWriter = std.io.Writer(void, LogError, writeLog); -fn writeLog(_: void, msg: []const u8) LogError!usize { - machLogWrite(msg.ptr, msg.len); - return msg.len; -} - -pub const Core = @This(); - -allocator: std.mem.Allocator, -frame: *Frequency, -input: *Frequency, -id: js.CanvasId, - -input_state: InputState, -joysticks: [JoystickData.max_joysticks]JoystickData, - -pub const EventIterator = struct { - core: *Core, - - pub inline fn next(self: *EventIterator) ?Event { - while (true) { - const event_int = js.machEventShift(); - if (event_int == -1) return null; - - const event_type = @as(std.meta.Tag(Event), @enumFromInt(event_int)); - return switch (event_type) { - .key_press, .key_repeat, .key_release => blk: { - const key = @as(Key, @enumFromInt(js.machEventShift())); - - switch (event_type) { - .key_press => { - self.core.input_state.keys.set(@intFromEnum(key)); - break :blk Event{ - .key_press = .{ - .key = key, - .mods = self.makeKeyMods(), - }, - }; - }, - .key_repeat => break :blk Event{ - .key_repeat = .{ - .key = key, - .mods = self.makeKeyMods(), - }, - }, - .key_release => { - self.core.input_state.keys.unset(@intFromEnum(key)); - break :blk Event{ - .key_release = .{ - .key = key, - .mods = self.makeKeyMods(), - }, - }; - }, - else => unreachable, - } - - continue; - }, - .mouse_motion => blk: { - const x = @as(f64, @floatFromInt(js.machEventShift())); - const y = @as(f64, @floatFromInt(js.machEventShift())); - - self.core.input_state.mouse_position = .{ .x = x, .y = y }; - - break :blk Event{ - .mouse_motion = .{ - .pos = .{ - .x = x, - .y = y, - }, - }, - }; - }, - .mouse_press => blk: { - const button = toMachButton(js.machEventShift()); - self.core.input_state.mouse_buttons.set(@intFromEnum(button)); - - break :blk Event{ - .mouse_press = .{ - .button = button, - .pos = self.core.input_state.mouse_position, - .mods = self.makeKeyMods(), - }, - }; - }, - .mouse_release => blk: { - const button = toMachButton(js.machEventShift()); - self.core.input_state.mouse_buttons.unset(@intFromEnum(button)); - - break :blk Event{ - .mouse_release = .{ - .button = button, - .pos = self.core.input_state.mouse_position, - .mods = self.makeKeyMods(), - }, - }; - }, - .mouse_scroll => Event{ - .mouse_scroll = .{ - .xoffset = @as(f32, @floatCast(std.math.sign(js.machEventShiftFloat()))), - .yoffset = @as(f32, @floatCast(std.math.sign(js.machEventShiftFloat()))), - }, - }, - .joystick_connected => blk: { - const idx: u8 = @intCast(js.machEventShift()); - const btn_count: usize = @intCast(js.machEventShift()); - const axis_count: usize = @intCast(js.machEventShift()); - if (idx >= JoystickData.max_joysticks) continue; - - var data = &self.core.joysticks[idx]; - data.present = true; - data.button_count = @min(JoystickData.max_button_count, btn_count); - data.axis_count = @min(JoystickData.max_axis_count, axis_count); - - js.machJoystickName(idx, &data.name, JoystickData.max_name_len); - - break :blk Event{ .joystick_connected = @enumFromInt(idx) }; - }, - .joystick_disconnected => blk: { - const idx: u8 = @intCast(js.machEventShift()); - if (idx >= JoystickData.max_joysticks) continue; - - var data = &self.core.joysticks[idx]; - data.present = false; - data.button_count = 0; - data.axis_count = 0; - - @memset(&data.buttons, false); - @memset(&data.axes, 0); - - break :blk Event{ .joystick_disconnected = @enumFromInt(idx) }; - }, - .framebuffer_resize => blk: { - const width = @as(u32, @intCast(js.machEventShift())); - const height = @as(u32, @intCast(js.machEventShift())); - const pixel_ratio = @as(u32, @intCast(js.machEventShift())); - break :blk Event{ - .framebuffer_resize = .{ - .width = width * pixel_ratio, - .height = height * pixel_ratio, - }, - }; - }, - .focus_gained => Event.focus_gained, - .focus_lost => Event.focus_lost, - else => null, - }; - } - } - - fn makeKeyMods(self: EventIterator) KeyMods { - const is = self.core.input_state; - - return .{ - .shift = is.isKeyPressed(.left_shift) or is.isKeyPressed(.right_shift), - .control = is.isKeyPressed(.left_control) or is.isKeyPressed(.right_control), - .alt = is.isKeyPressed(.left_alt) or is.isKeyPressed(.right_alt), - .super = is.isKeyPressed(.left_super) or is.isKeyPressed(.right_super), - // FIXME(estel): I think the logic for these two are wrong, but unlikely it matters - // in a browser. To correct them we need to actually use `KeyboardEvent.getModifierState` - // in javascript and bring back that info in here. - .caps_lock = is.isKeyPressed(.caps_lock), - .num_lock = is.isKeyPressed(.num_lock), - }; - } -}; - -const JoystickData = struct { - present: bool, - button_count: usize, - axis_count: usize, - - name: [max_name_len:0]u8, - buttons: [max_button_count]bool, - axes: [max_axis_count]f32, - - // 16 as it's the maximum number of joysticks supported by GLFW. - const max_joysticks = 16; - const max_name_len = 64; - const max_button_count = 32; - const max_axis_count = 16; -}; - -pub fn init( - core: *Core, - allocator: std.mem.Allocator, - frame: *Frequency, - input: *Frequency, - options: InitOptions, -) !void { - _ = options; - var selector = [1]u8{0} ** 15; - const id = js.machCanvasInit(&selector[0]); - - core.* = Core{ - .allocator = allocator, - .frame = frame, - .input = input, - .id = id, - .input_state = .{}, - .joysticks = std.mem.zeroes([JoystickData.max_joysticks]JoystickData), - }; - - // TODO(wasm): wgpu support - - try core.frame.start(); - try core.input.start(); -} - -pub fn deinit(self: *Core) void { - js.machCanvasDeinit(self.id); -} - -pub inline fn update(self: *Core, app: anytype) !bool { - self.frame.tick(); - self.input.tick(); - if (try app.update()) return true; - if (@hasDecl(std.meta.Child(@TypeOf(app)), "updateMainThread")) { - if (app.updateMainThread() catch |err| @panic(@errorName(err))) { - return true; - } - } - return false; -} - -pub inline fn pollEvents(self: *Core) EventIterator { - return EventIterator{ - .core = self, - }; -} - -pub fn setTitle(self: *Core, title: [:0]const u8) void { - js.machCanvasSetTitle(self.id, title.ptr, title.len); -} - -pub fn setDisplayMode(self: *Core, _mode: DisplayMode) void { - var mode = _mode; - if (mode == .borderless) { - // borderless fullscreen window has no meaning in web - mode = .fullscreen; - } - js.machCanvasSetDisplayMode(self.id, @intFromEnum(mode)); -} - -pub fn displayMode(self: *Core) DisplayMode { - return @as(DisplayMode, @enumFromInt(js.machDisplayMode(self.id))); -} - -pub fn setBorder(self: *Core, value: bool) void { - _ = self; - _ = value; -} - -pub fn border(self: *Core) bool { - _ = self; - return false; -} - -pub fn setHeadless(self: *Core, value: bool) void { - _ = self; - _ = value; -} - -pub fn headless(self: *Core) bool { - _ = self; - return false; -} - -pub fn setVSync(self: *Core, mode: VSyncMode) void { - _ = mode; - self.frame.target = 0; -} - -// TODO(wasm): https://github.com/gpuweb/gpuweb/issues/1224 -pub fn vsync(self: *Core) VSyncMode { - _ = self; - return .double; -} - -pub fn setSize(self: *Core, value: Size) void { - js.machCanvasSetSize(self.id, value.width, value.height); -} - -pub fn size(self: *Core) Size { - return .{ - .width = js.machCanvasWidth(self.id), - .height = js.machCanvasHeight(self.id), - }; -} - -pub fn setSizeLimit(self: *Core, limit: SizeLimit) void { - js.machCanvasSetSizeLimit( - self.id, - if (limit.min.width) |val| @as(i32, @intCast(val)) else -1, - if (limit.min.height) |val| @as(i32, @intCast(val)) else -1, - if (limit.max.width) |val| @as(i32, @intCast(val)) else -1, - if (limit.max.height) |val| @as(i32, @intCast(val)) else -1, - ); -} - -pub fn sizeLimit(self: *Core) SizeLimit { - return .{ - .min = .{ - .width = js.machCanvasMinWidth(self.id), - .height = js.machCanvasMinHeight(self.id), - }, - .max = .{ - .width = js.machCanvasMaxWidth(self.id), - .height = js.machCanvasMaxHeight(self.id), - }, - }; -} - -pub fn setCursorMode(self: *Core, mode: CursorMode) void { - js.machSetCursorMode(self.id, @intFromEnum(mode)); -} - -pub fn cursorMode(self: *Core) CursorMode { - return @as(CursorMode, @enumFromInt(js.machCursorMode(self.id))); -} - -pub fn setCursorShape(self: *Core, shape: CursorShape) void { - js.machSetCursorShape(self.id, @intFromEnum(shape)); -} - -pub fn cursorShape(self: *Core) CursorShape { - return @as(CursorShape, @enumFromInt(js.machCursorShape(self.id))); -} - -pub fn joystickPresent(core: *Core, joystick: Joystick) bool { - const idx: u8 = @intFromEnum(joystick); - return core.joysticks[idx].present; -} - -pub fn joystickName(core: *Core, joystick: Joystick) ?[:0]const u8 { - const idx: u8 = @intFromEnum(joystick); - var data = &core.joysticks[idx]; - if (!data.present) return null; - - return std.mem.span(&data.name); -} - -pub fn joystickButtons(core: *Core, joystick: Joystick) ?[]const bool { - const idx: u8 = @intFromEnum(joystick); - var data = &core.joysticks[idx]; - if (!data.present) return null; - - js.machJoystickButtons(idx, &data.buttons, JoystickData.max_button_count); - return data.buttons[0..data.button_count]; -} - -pub fn joystickAxes(core: *Core, joystick: Joystick) ?[]const f32 { - const idx: u8 = @intFromEnum(joystick); - var data = &core.joysticks[idx]; - if (!data.present) return null; - - js.machJoystickAxes(idx, &data.axes, JoystickData.max_axis_count); - return data.buttons[0..data.button_count]; -} - -pub fn keyPressed(self: *Core, key: Key) bool { - return self.input_state.isKeyPressed(key); -} - -pub fn keyReleased(self: *Core, key: Key) bool { - return self.input_state.isKeyReleased(key); -} - -pub fn mousePressed(self: *Core, button: MouseButton) bool { - return self.input_state.isMouseButtonPressed(button); -} - -pub fn mouseReleased(self: *Core, button: MouseButton) bool { - return self.input_state.isMouseButtonReleased(button); -} - -pub fn mousePosition(self: *Core) Core.Position { - return self.input_state.mouse_position; -} - -pub inline fn adapter(_: *Core) *gpu.Adapter { - unreachable; -} - -pub inline fn device(_: *Core) *gpu.Device { - unreachable; -} - -pub inline fn swapChain(_: *Core) *gpu.SwapChain { - unreachable; -} - -pub inline fn descriptor(self: *Core) gpu.SwapChain.Descriptor { - return .{ - .label = "main swap chain", - .usage = .{ .render_attachment = true }, - .format = .bgra8_unorm, // TODO(wasm): is this correct? - .width = js.machCanvasFramebufferWidth(self.id), - .height = js.machCanvasFramebufferHeight(self.id), - .present_mode = .fifo, // TODO(wasm): https://github.com/gpuweb/gpuweb/issues/1224 - }; -} - -pub inline fn outOfMemory(self: *Core) bool { - _ = self; - return false; -} - -pub inline fn wakeMainThread(self: *Core) void { - _ = self; -} - -fn toMachButton(button: i32) MouseButton { - return switch (button) { - 0 => .left, - 1 => .middle, - 2 => .right, - 3 => .four, - 4 => .five, - else => unreachable, - }; -}