From 58218af2b535b44b8da192c5e852962ca5cb13a4 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 30 Dec 2022 15:56:42 -0800 Subject: [PATCH] app: make apprt agnostic --- src/App.zig | 21 ++++++++++++--------- src/apprt/glfw.zig | 28 ++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/src/App.zig b/src/App.zig index 510bb1a0a..b640d64c9 100644 --- a/src/App.zig +++ b/src/App.zig @@ -6,7 +6,7 @@ const App = @This(); const std = @import("std"); const builtin = @import("builtin"); const Allocator = std.mem.Allocator; -const glfw = @import("glfw"); +const apprt = @import("apprt.zig"); const Window = @import("Window.zig"); const tracy = @import("tracy"); const Config = @import("config.zig").Config; @@ -27,6 +27,9 @@ pub const Mailbox = BlockingQueue(Message, 64); /// General purpose allocator alloc: Allocator, +/// The runtime for this app. +runtime: apprt.runtime.App, + /// The list of windows that are currently open windows: WindowList, @@ -59,9 +62,9 @@ pub const Darwin = struct { /// up the renderer state, compiles the shaders, etc. This is the primary /// "startup" logic. pub fn create(alloc: Allocator, config: *const Config) !*App { - // Initialize glfw - try glfw.init(.{}); - errdefer glfw.terminate(); + // Initialize app runtime + var app_backend = try apprt.runtime.App.init(); + errdefer app_backend.terminate(); // The mailbox for messaging this thread var mailbox = try Mailbox.create(alloc); @@ -74,6 +77,7 @@ pub fn create(alloc: Allocator, config: *const Config) !*App { errdefer alloc.destroy(app); app.* = .{ .alloc = alloc, + .runtime = app_backend, .windows = .{}, .config = config, .mailbox = mailbox, @@ -117,22 +121,21 @@ pub fn destroy(self: *App) void { self.alloc.destroy(self); // Close our windowing runtime - glfw.terminate(); + self.runtime.terminate(); } /// Wake up the app event loop. This should be called after any messages /// are sent to the mailbox. pub fn wakeup(self: App) void { - _ = self; - glfw.postEmptyEvent() catch {}; + self.runtime.wakeup() catch return; } /// Run the main event loop for the application. This blocks until the /// application quits or every window is closed. pub fn run(self: *App) !void { while (!self.quit and self.windows.items.len > 0) { - // Block for any glfw events. - try glfw.waitEvents(); + // Block for any events. + try self.runtime.wait(); // If any windows are closing, destroy them var i: usize = 0; diff --git a/src/apprt/glfw.zig b/src/apprt/glfw.zig index d48939191..9aded5d21 100644 --- a/src/apprt/glfw.zig +++ b/src/apprt/glfw.zig @@ -10,12 +10,12 @@ const Allocator = std.mem.Allocator; const trace = @import("tracy").trace; const glfw = @import("glfw"); const objc = @import("objc"); -const App = @import("../App.zig"); const input = @import("../input.zig"); const internal_os = @import("../os/main.zig"); const renderer = @import("../renderer.zig"); const Renderer = renderer.Renderer; const apprt = @import("../apprt.zig"); +const CoreApp = @import("../App.zig"); const CoreWindow = @import("../Window.zig"); // Get native API access on certain platforms so we can do more customization. @@ -25,6 +25,30 @@ const glfwNative = glfw.Native(.{ const log = std.log.scoped(.glfw); +pub const App = struct { + pub fn init() !App { + try glfw.init(.{}); + return .{}; + } + + pub fn terminate(self: App) void { + _ = self; + glfw.terminate(); + } + + /// Wakeup the event loop. This should be able to be called from any thread. + pub fn wakeup(self: App) !void { + _ = self; + try glfw.postEmptyEvent(); + } + + /// Wait for events in the event loop to process. + pub fn wait(self: App) !void { + _ = self; + try glfw.waitEvents(); + } +}; + pub const Window = struct { /// The glfw window handle window: glfw.Window, @@ -32,7 +56,7 @@ pub const Window = struct { /// The glfw mouse cursor handle. cursor: glfw.Cursor, - pub fn init(app: *const App, core_win: *CoreWindow) !Window { + pub fn init(app: *const CoreApp, core_win: *CoreWindow) !Window { // Create our window const win = try glfw.Window.create( 640,