From f3e2b8b74c38f829e5717a75f6a07017ab6b8872 Mon Sep 17 00:00:00 2001 From: iddev5 Date: Mon, 23 May 2022 13:23:26 +0530 Subject: [PATCH] mach: add a standard way to access platform specific structs This is done by adding platform.zig which is a file providing types like ``CoreType``, ``GpuDriverType`` and ``BackingTimerType``. --- src/Engine.zig | 19 +++++------------- src/Timer.zig | 40 +++---------------------------------- src/native.zig | 32 +++++++++++++++-------------- src/platform.zig | 8 ++++++++ src/wasm.zig | 52 ++++++++++++++++++++++++++++++++++++++---------- 5 files changed, 74 insertions(+), 77 deletions(-) create mode 100644 src/platform.zig diff --git a/src/Engine.zig b/src/Engine.zig index c31f04c5..516a4251 100644 --- a/src/Engine.zig +++ b/src/Engine.zig @@ -3,6 +3,7 @@ const Allocator = std.mem.Allocator; const builtin = @import("builtin"); const glfw = @import("glfw"); const gpu = @import("gpu"); +const platform = @import("platform.zig"); const structs = @import("structs.zig"); const enums = @import("enums.zig"); const Timer = @import("Timer.zig"); @@ -29,7 +30,7 @@ delta_time_ns: u64 = 0, timer: Timer, pub const Core = struct { - internal: GetCoreInternalType(), + internal: platform.CoreType, pub fn setShouldClose(core: *Core, value: bool) void { core.internal.setShouldClose(value); @@ -59,7 +60,7 @@ pub const Core = struct { }; pub const GpuDriver = struct { - internal: GetGpuDriverInternalType(), + internal: platform.GpuDriverType, device: gpu.Device, backend_type: gpu.Adapter.BackendType, @@ -82,18 +83,8 @@ pub fn init(allocator: std.mem.Allocator, options: structs.Options) !Engine { // Note: if in future, there is a conflict in init() signature of different backends, // move these calls to the entry point file, which is native.zig for Glfw, for example - engine.core.internal = try GetCoreInternalType().init(allocator, &engine); - engine.gpu_driver.internal = try GetGpuDriverInternalType().init(allocator, &engine); + engine.core.internal = try platform.CoreType.init(allocator, &engine); + engine.gpu_driver.internal = try platform.GpuDriverType.init(allocator, &engine); return engine; } - -fn GetCoreInternalType() type { - if (builtin.cpu.arch == .wasm32) return @import("wasm.zig").CoreWasm; - return @import("native.zig").CoreGlfw; -} - -fn GetGpuDriverInternalType() type { - if (builtin.cpu.arch == .wasm32) return @import("wasm.zig").GpuDriverWeb; - return @import("native.zig").GpuDriverNative; -} diff --git a/src/Timer.zig b/src/Timer.zig index 16d58e15..28b3b99a 100644 --- a/src/Timer.zig +++ b/src/Timer.zig @@ -1,48 +1,14 @@ const std = @import("std"); -const builtin = @import("builtin"); +const platform = @import("platform.zig"); const Timer = @This(); -backing_timer: BackingTimerType = undefined, - -// TODO: verify declarations and its signatures -const BackingTimerType = if (builtin.cpu.arch == .wasm32) struct { - initial: f64 = undefined, - - const js = struct { - extern fn machPerfNow() f64; - }; - - const WasmTimer = @This(); - - fn start() !WasmTimer { - return WasmTimer{ .initial = js.machPerfNow() }; - } - - fn read(timer: *WasmTimer) u64 { - return timeToNs(js.machPerfNow() - timer.initial); - } - - fn reset(timer: *WasmTimer) void { - timer.initial = js.machPerfNow(); - } - - fn lap(timer: *WasmTimer) u64 { - const now = js.machPerfNow(); - const initial = timer.initial; - timer.initial = now; - return timeToNs(now - initial); - } - - fn timeToNs(t: f64) u64 { - return @floatToInt(u64, t) * 1000000; - } -} else std.time.Timer; +backing_timer: platform.BackingTimerType = undefined, /// Initialize the timer. pub fn start() !Timer { return Timer{ - .backing_timer = try BackingTimerType.start(), + .backing_timer = try platform.BackingTimerType.start(), }; } diff --git a/src/native.zig b/src/native.zig index 5ac5c8e1..8807cb6b 100644 --- a/src/native.zig +++ b/src/native.zig @@ -8,7 +8,7 @@ const enums = @import("enums.zig"); const util = @import("util.zig"); const c = @import("c.zig").c; -pub const CoreGlfw = struct { +pub const Core = struct { window: glfw.Window, backend_type: gpu.Adapter.BackendType, allocator: std.mem.Allocator, @@ -19,14 +19,14 @@ pub const CoreGlfw = struct { const EventNode = EventQueue.Node; const UserPtr = struct { - core: *CoreGlfw, + core: *Core, }; - pub fn init(allocator: std.mem.Allocator, engine: *Engine) !CoreGlfw { + pub fn init(allocator: std.mem.Allocator, engine: *Engine) !Core { const options = engine.options; const backend_type = try util.detectBackendType(allocator); - glfw.setErrorCallback(CoreGlfw.errorCallback); + glfw.setErrorCallback(Core.errorCallback); try glfw.init(.{}); // Create the test window and discover adapters using it (esp. for OpenGL) @@ -41,20 +41,20 @@ pub const CoreGlfw = struct { hints, ); - return CoreGlfw{ + return Core{ .window = window, .backend_type = backend_type, .allocator = engine.allocator, }; } - fn pushEvent(self: *CoreGlfw, event: structs.Event) void { + fn pushEvent(self: *Core, event: structs.Event) void { const node = self.allocator.create(EventNode) catch unreachable; node.* = .{ .data = event }; self.events.append(node); } - fn initCallback(self: *CoreGlfw) void { + fn initCallback(self: *Core) void { self.user_ptr = UserPtr{ .core = self }; self.window.setUserPointer(&self.user_ptr); @@ -84,28 +84,28 @@ pub const CoreGlfw = struct { self.window.setKeyCallback(callback); } - pub fn setShouldClose(self: *CoreGlfw, value: bool) void { + pub fn setShouldClose(self: *Core, value: bool) void { self.window.setShouldClose(value); } - pub fn getFramebufferSize(self: *CoreGlfw) !structs.Size { + pub fn getFramebufferSize(self: *Core) !structs.Size { const size = try self.window.getFramebufferSize(); return @bitCast(structs.Size, size); } - pub fn getWindowSize(self: *CoreGlfw) !structs.Size { + pub fn getWindowSize(self: *Core) !structs.Size { const size = try self.window.getSize(); return @bitCast(structs.Size, size); } - pub fn setSizeLimits(self: *CoreGlfw, min: structs.SizeOptional, max: structs.SizeOptional) !void { + pub fn setSizeLimits(self: *Core, min: structs.SizeOptional, max: structs.SizeOptional) !void { try self.window.setSizeLimits( @bitCast(glfw.Window.SizeOptional, min), @bitCast(glfw.Window.SizeOptional, max), ); } - pub fn pollEvent(self: *CoreGlfw) ?structs.Event { + pub fn pollEvent(self: *Core) ?structs.Event { if (self.events.popFirst()) |n| { defer self.allocator.destroy(n); return n.data; @@ -250,10 +250,10 @@ pub const CoreGlfw = struct { } }; -pub const GpuDriverNative = struct { +pub const GpuDriver = struct { native_instance: gpu.NativeInstance, - pub fn init(_: std.mem.Allocator, engine: *Engine) !GpuDriverNative { + pub fn init(_: std.mem.Allocator, engine: *Engine) !GpuDriver { const options = engine.options; const window = engine.core.internal.window; const backend_type = engine.core.internal.backend_type; @@ -382,12 +382,14 @@ pub const GpuDriverNative = struct { engine.gpu_driver.current_desc = descriptor; engine.gpu_driver.target_desc = descriptor; - return GpuDriverNative{ + return GpuDriver{ .native_instance = native_instance, }; } }; +pub const BackingTimer = std.time.Timer; + // TODO: check signatures comptime { if (!@hasDecl(App, "init")) @compileError("App must export 'pub fn init(app: *App, engine: *mach.Engine) !void'"); diff --git a/src/platform.zig b/src/platform.zig new file mode 100644 index 00000000..18fecde5 --- /dev/null +++ b/src/platform.zig @@ -0,0 +1,8 @@ +const builtin = @import("builtin"); + +const Platform = if (builtin.cpu.arch == .wasm32) @import("wasm.zig") else @import("native.zig"); + +// TODO: verify declarations and its signatures +pub const CoreType = Platform.Core; +pub const GpuDriverType = Platform.GpuDriver; +pub const BackingTimerType = Platform.BackingTimer; diff --git a/src/wasm.zig b/src/wasm.zig index 18b6531d..7fd3a43a 100644 --- a/src/wasm.zig +++ b/src/wasm.zig @@ -12,6 +12,7 @@ const js = struct { extern fn machCanvasGetWidth(canvas: CanvasId) u32; extern fn machCanvasGetHeight(canvas: CanvasId) u32; + extern fn machPerfNow() f64; extern fn machLog(str: [*]const u8, len: u32) void; extern fn machLogWrite(str: [*]const u8, len: u32) void; extern fn machLogFlush() void; @@ -20,11 +21,11 @@ const js = struct { pub const CanvasId = u32; -pub const CoreWasm = struct { +pub const Core = struct { id: CanvasId, selector_id: []const u8, - pub fn init(allocator: std.mem.Allocator, eng: *Engine) !CoreWasm { + pub fn init(allocator: std.mem.Allocator, eng: *Engine) !Core { const options = eng.options; var selector = [1]u8{0} ** 15; const id = js.machCanvasInit(options.width, options.height, &selector[0]); @@ -32,35 +33,64 @@ pub const CoreWasm = struct { const title = std.mem.span(options.title); js.machCanvasSetTitle(id, title.ptr, title.len); - return CoreWasm{ + return Core{ .id = id, .selector_id = try allocator.dupe(u8, selector[0 .. selector.len - @as(u32, if (selector[selector.len - 1] == 0) 1 else 0)]), }; } - pub fn setShouldClose(_: *CoreWasm, _: bool) void {} + pub fn setShouldClose(_: *Core, _: bool) void {} - pub fn getFramebufferSize(_: *CoreWasm) !structs.Size { + pub fn getFramebufferSize(_: *Core) !structs.Size { return structs.Size{ .width = 0, .height = 0 }; } - pub fn getWindowSize(core: *CoreWasm) !structs.Size { + pub fn getWindowSize(core: *Core) !structs.Size { return structs.Size{ .width = js.machCanvasGetWidth(core.id), .height = js.machCanvasGetHeight(core.id), }; } - pub fn setSizeLimits(_: *CoreWasm, _: structs.SizeOptional, _: structs.SizeOptional) !void {} + pub fn setSizeLimits(_: *Core, _: structs.SizeOptional, _: structs.SizeOptional) !void {} - pub fn pollEvent(_: *CoreWasm) ?structs.Event { + pub fn pollEvent(_: *Core) ?structs.Event { return null; } }; -pub const GpuDriverWeb = struct { - pub fn init(_: std.mem.Allocator, _: *Engine) !GpuDriverWeb { - return GpuDriverWeb{}; +pub const GpuDriver = struct { + pub fn init(_: std.mem.Allocator, _: *Engine) !GpuDriver { + return GpuDriver{}; + } +}; + +pub const BackingTimer = struct { + initial: f64 = undefined, + + const WasmTimer = @This(); + + pub fn start() !WasmTimer { + return WasmTimer{ .initial = js.machPerfNow() }; + } + + pub fn read(timer: *WasmTimer) u64 { + return timeToNs(js.machPerfNow() - timer.initial); + } + + pub fn reset(timer: *WasmTimer) void { + timer.initial = js.machPerfNow(); + } + + pub fn lap(timer: *WasmTimer) u64 { + const now = js.machPerfNow(); + const initial = timer.initial; + timer.initial = now; + return timeToNs(now - initial); + } + + fn timeToNs(t: f64) u64 { + return @floatToInt(u64, t) * 1000000; } };