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``.
This commit is contained in:
parent
e5050e856e
commit
f3e2b8b74c
5 changed files with 74 additions and 77 deletions
|
|
@ -3,6 +3,7 @@ const Allocator = std.mem.Allocator;
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const glfw = @import("glfw");
|
const glfw = @import("glfw");
|
||||||
const gpu = @import("gpu");
|
const gpu = @import("gpu");
|
||||||
|
const platform = @import("platform.zig");
|
||||||
const structs = @import("structs.zig");
|
const structs = @import("structs.zig");
|
||||||
const enums = @import("enums.zig");
|
const enums = @import("enums.zig");
|
||||||
const Timer = @import("Timer.zig");
|
const Timer = @import("Timer.zig");
|
||||||
|
|
@ -29,7 +30,7 @@ delta_time_ns: u64 = 0,
|
||||||
timer: Timer,
|
timer: Timer,
|
||||||
|
|
||||||
pub const Core = struct {
|
pub const Core = struct {
|
||||||
internal: GetCoreInternalType(),
|
internal: platform.CoreType,
|
||||||
|
|
||||||
pub fn setShouldClose(core: *Core, value: bool) void {
|
pub fn setShouldClose(core: *Core, value: bool) void {
|
||||||
core.internal.setShouldClose(value);
|
core.internal.setShouldClose(value);
|
||||||
|
|
@ -59,7 +60,7 @@ pub const Core = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const GpuDriver = struct {
|
pub const GpuDriver = struct {
|
||||||
internal: GetGpuDriverInternalType(),
|
internal: platform.GpuDriverType,
|
||||||
|
|
||||||
device: gpu.Device,
|
device: gpu.Device,
|
||||||
backend_type: gpu.Adapter.BackendType,
|
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,
|
// 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
|
// 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.core.internal = try platform.CoreType.init(allocator, &engine);
|
||||||
engine.gpu_driver.internal = try GetGpuDriverInternalType().init(allocator, &engine);
|
engine.gpu_driver.internal = try platform.GpuDriverType.init(allocator, &engine);
|
||||||
|
|
||||||
return 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;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,48 +1,14 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const platform = @import("platform.zig");
|
||||||
|
|
||||||
const Timer = @This();
|
const Timer = @This();
|
||||||
|
|
||||||
backing_timer: BackingTimerType = undefined,
|
backing_timer: platform.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;
|
|
||||||
|
|
||||||
/// Initialize the timer.
|
/// Initialize the timer.
|
||||||
pub fn start() !Timer {
|
pub fn start() !Timer {
|
||||||
return Timer{
|
return Timer{
|
||||||
.backing_timer = try BackingTimerType.start(),
|
.backing_timer = try platform.BackingTimerType.start(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ const enums = @import("enums.zig");
|
||||||
const util = @import("util.zig");
|
const util = @import("util.zig");
|
||||||
const c = @import("c.zig").c;
|
const c = @import("c.zig").c;
|
||||||
|
|
||||||
pub const CoreGlfw = struct {
|
pub const Core = struct {
|
||||||
window: glfw.Window,
|
window: glfw.Window,
|
||||||
backend_type: gpu.Adapter.BackendType,
|
backend_type: gpu.Adapter.BackendType,
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
|
|
@ -19,14 +19,14 @@ pub const CoreGlfw = struct {
|
||||||
const EventNode = EventQueue.Node;
|
const EventNode = EventQueue.Node;
|
||||||
|
|
||||||
const UserPtr = struct {
|
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 options = engine.options;
|
||||||
const backend_type = try util.detectBackendType(allocator);
|
const backend_type = try util.detectBackendType(allocator);
|
||||||
|
|
||||||
glfw.setErrorCallback(CoreGlfw.errorCallback);
|
glfw.setErrorCallback(Core.errorCallback);
|
||||||
try glfw.init(.{});
|
try glfw.init(.{});
|
||||||
|
|
||||||
// Create the test window and discover adapters using it (esp. for OpenGL)
|
// Create the test window and discover adapters using it (esp. for OpenGL)
|
||||||
|
|
@ -41,20 +41,20 @@ pub const CoreGlfw = struct {
|
||||||
hints,
|
hints,
|
||||||
);
|
);
|
||||||
|
|
||||||
return CoreGlfw{
|
return Core{
|
||||||
.window = window,
|
.window = window,
|
||||||
.backend_type = backend_type,
|
.backend_type = backend_type,
|
||||||
.allocator = engine.allocator,
|
.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;
|
const node = self.allocator.create(EventNode) catch unreachable;
|
||||||
node.* = .{ .data = event };
|
node.* = .{ .data = event };
|
||||||
self.events.append(node);
|
self.events.append(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initCallback(self: *CoreGlfw) void {
|
fn initCallback(self: *Core) void {
|
||||||
self.user_ptr = UserPtr{ .core = self };
|
self.user_ptr = UserPtr{ .core = self };
|
||||||
|
|
||||||
self.window.setUserPointer(&self.user_ptr);
|
self.window.setUserPointer(&self.user_ptr);
|
||||||
|
|
@ -84,28 +84,28 @@ pub const CoreGlfw = struct {
|
||||||
self.window.setKeyCallback(callback);
|
self.window.setKeyCallback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setShouldClose(self: *CoreGlfw, value: bool) void {
|
pub fn setShouldClose(self: *Core, value: bool) void {
|
||||||
self.window.setShouldClose(value);
|
self.window.setShouldClose(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getFramebufferSize(self: *CoreGlfw) !structs.Size {
|
pub fn getFramebufferSize(self: *Core) !structs.Size {
|
||||||
const size = try self.window.getFramebufferSize();
|
const size = try self.window.getFramebufferSize();
|
||||||
return @bitCast(structs.Size, size);
|
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();
|
const size = try self.window.getSize();
|
||||||
return @bitCast(structs.Size, size);
|
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(
|
try self.window.setSizeLimits(
|
||||||
@bitCast(glfw.Window.SizeOptional, min),
|
@bitCast(glfw.Window.SizeOptional, min),
|
||||||
@bitCast(glfw.Window.SizeOptional, max),
|
@bitCast(glfw.Window.SizeOptional, max),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pollEvent(self: *CoreGlfw) ?structs.Event {
|
pub fn pollEvent(self: *Core) ?structs.Event {
|
||||||
if (self.events.popFirst()) |n| {
|
if (self.events.popFirst()) |n| {
|
||||||
defer self.allocator.destroy(n);
|
defer self.allocator.destroy(n);
|
||||||
return n.data;
|
return n.data;
|
||||||
|
|
@ -250,10 +250,10 @@ pub const CoreGlfw = struct {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const GpuDriverNative = struct {
|
pub const GpuDriver = struct {
|
||||||
native_instance: gpu.NativeInstance,
|
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 options = engine.options;
|
||||||
const window = engine.core.internal.window;
|
const window = engine.core.internal.window;
|
||||||
const backend_type = engine.core.internal.backend_type;
|
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.current_desc = descriptor;
|
||||||
engine.gpu_driver.target_desc = descriptor;
|
engine.gpu_driver.target_desc = descriptor;
|
||||||
|
|
||||||
return GpuDriverNative{
|
return GpuDriver{
|
||||||
.native_instance = native_instance,
|
.native_instance = native_instance,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const BackingTimer = std.time.Timer;
|
||||||
|
|
||||||
// TODO: check signatures
|
// TODO: check signatures
|
||||||
comptime {
|
comptime {
|
||||||
if (!@hasDecl(App, "init")) @compileError("App must export 'pub fn init(app: *App, engine: *mach.Engine) !void'");
|
if (!@hasDecl(App, "init")) @compileError("App must export 'pub fn init(app: *App, engine: *mach.Engine) !void'");
|
||||||
|
|
|
||||||
8
src/platform.zig
Normal file
8
src/platform.zig
Normal file
|
|
@ -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;
|
||||||
52
src/wasm.zig
52
src/wasm.zig
|
|
@ -12,6 +12,7 @@ const js = struct {
|
||||||
extern fn machCanvasGetWidth(canvas: CanvasId) u32;
|
extern fn machCanvasGetWidth(canvas: CanvasId) u32;
|
||||||
extern fn machCanvasGetHeight(canvas: CanvasId) u32;
|
extern fn machCanvasGetHeight(canvas: CanvasId) u32;
|
||||||
|
|
||||||
|
extern fn machPerfNow() f64;
|
||||||
extern fn machLog(str: [*]const u8, len: u32) void;
|
extern fn machLog(str: [*]const u8, len: u32) void;
|
||||||
extern fn machLogWrite(str: [*]const u8, len: u32) void;
|
extern fn machLogWrite(str: [*]const u8, len: u32) void;
|
||||||
extern fn machLogFlush() void;
|
extern fn machLogFlush() void;
|
||||||
|
|
@ -20,11 +21,11 @@ const js = struct {
|
||||||
|
|
||||||
pub const CanvasId = u32;
|
pub const CanvasId = u32;
|
||||||
|
|
||||||
pub const CoreWasm = struct {
|
pub const Core = struct {
|
||||||
id: CanvasId,
|
id: CanvasId,
|
||||||
selector_id: []const u8,
|
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;
|
const options = eng.options;
|
||||||
var selector = [1]u8{0} ** 15;
|
var selector = [1]u8{0} ** 15;
|
||||||
const id = js.machCanvasInit(options.width, options.height, &selector[0]);
|
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);
|
const title = std.mem.span(options.title);
|
||||||
js.machCanvasSetTitle(id, title.ptr, title.len);
|
js.machCanvasSetTitle(id, title.ptr, title.len);
|
||||||
|
|
||||||
return CoreWasm{
|
return Core{
|
||||||
.id = id,
|
.id = id,
|
||||||
.selector_id = try allocator.dupe(u8, selector[0 .. selector.len - @as(u32, if (selector[selector.len - 1] == 0) 1 else 0)]),
|
.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 };
|
return structs.Size{ .width = 0, .height = 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getWindowSize(core: *CoreWasm) !structs.Size {
|
pub fn getWindowSize(core: *Core) !structs.Size {
|
||||||
return structs.Size{
|
return structs.Size{
|
||||||
.width = js.machCanvasGetWidth(core.id),
|
.width = js.machCanvasGetWidth(core.id),
|
||||||
.height = js.machCanvasGetHeight(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;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const GpuDriverWeb = struct {
|
pub const GpuDriver = struct {
|
||||||
pub fn init(_: std.mem.Allocator, _: *Engine) !GpuDriverWeb {
|
pub fn init(_: std.mem.Allocator, _: *Engine) !GpuDriver {
|
||||||
return GpuDriverWeb{};
|
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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue