From caf297512cfb97ae63dd315b982bab6f417df627 Mon Sep 17 00:00:00 2001 From: Joshua Holmes Date: Fri, 3 Jan 2025 07:21:29 +0000 Subject: [PATCH] core: remove option to support non-blocking and only allow platform to control main loop --- examples/core-custom-entrypoint/main.zig | 23 +--------- src/Core.zig | 53 +++--------------------- src/core/Linux.zig | 4 ++ src/core/Windows.zig | 4 ++ 4 files changed, 15 insertions(+), 69 deletions(-) diff --git a/examples/core-custom-entrypoint/main.zig b/examples/core-custom-entrypoint/main.zig index 9b069ab9..5bc2883a 100644 --- a/examples/core-custom-entrypoint/main.zig +++ b/examples/core-custom-entrypoint/main.zig @@ -14,25 +14,6 @@ pub fn main() !void { var mods: Modules = undefined; try mods.init(allocator); - // On some platforms, you can drive the mach.Core main loop yourself - but this isn't possible - // on all platforms. If mach.Core.non_blocking is set to true, and the platform supports - // non-blocking mode, then .mach_core.main will return without blocking. Otherwise it will block - // forever and app.run(.main) will never return. - if (mach.Core.supports_non_blocking) { - defer mods.deinit(allocator); - - mach.Core.non_blocking = true; - - const app = mods.get(.app); - app.run(.main); - - // If you are driving the main loop yourself, you should call tick until exit. - const core = mods.get(.mach_core); - while (mods.mods.mach_core.state != .exited) { - core.run(.tick); - } - } else { - const app = mods.get(.app); - app.run(.main); - } + const app = mods.get(.app); + app.run(.main); } diff --git a/src/Core.zig b/src/Core.zig index b1ad641e..192004db 100644 --- a/src/Core.zig +++ b/src/Core.zig @@ -8,26 +8,8 @@ const log = std.log.scoped(.mach); const Core = @This(); -// Whether or not you can drive the main loop in a non-blocking fashion, or if the underlying -// platform must take control and drive the main loop itself. -pub const supports_non_blocking = switch (build_options.core_platform) { - // Platforms that support non-blocking mode. - .linux => true, - .windows => true, - .null => true, - - // Platforms which take control of the main loop. - .wasm => false, - .darwin => false, -}; - const EventQueue = std.fifo.LinearFifo(Event, .Dynamic); -/// Set this to true if you intend to drive the main loop yourself. -/// -/// A panic will occur if `supports_non_blocking == false` for the platform. -pub var non_blocking = false; - pub const mach_module = .mach_core; pub const mach_systems = .{ .main, .init, .tick, .presentFrame, .deinit }; @@ -277,37 +259,12 @@ pub fn main(core: *Core, core_mod: mach.Mod(Core)) !void { core_mod.run(core.on_tick.?); core_mod.call(.presentFrame); - // If the user doesn't want mach.Core to take control of the main loop, we bail out - the next - // app tick is already scheduled to run in the future and they'll .present_frame to return - // control to us later. - if (non_blocking) { - if (!supports_non_blocking) std.debug.panic( - "mach.Core: platform {s} does not support non_blocking=true mode.", - .{@tagName(build_options.core_platform)}, - ); - return; - } + // Platform drives the main loop. + Platform.run(platform_update_callback, .{ core, core_mod }); - // The user wants mach.Core to take control of the main loop. - if (supports_non_blocking) { - while (core.state != .exited) { - try Platform.tick(core); - core_mod.run(core.on_tick.?); - core_mod.call(.presentFrame); - } - - // Don't return, because Platform.run wouldn't either (marked noreturn due to underlying - // platform APIs never returning.) - std.process.exit(0); - } else { - // Platform drives the main loop. - Platform.run(platform_update_callback, .{ core, core_mod }); - - // Platform.run should be marked noreturn, so this shouldn't ever run. But just in case we - // accidentally introduce a different Platform.run in the future, we put an exit here for - // good measure. - std.process.exit(0); - } + // Platform.run is marked noreturn on some platforms, but not all, so this is here for the + // platforms that do return + std.process.exit(0); } fn platform_update_callback(core: *Core, core_mod: mach.Mod(Core)) !bool { diff --git a/src/core/Linux.zig b/src/core/Linux.zig index 4908f02d..cf78908e 100644 --- a/src/core/Linux.zig +++ b/src/core/Linux.zig @@ -58,6 +58,10 @@ backend: Backend, const MISSING_FEATURES_X11 = [_][]const u8{ "Resizing window", "Changing display mode", "VSync", "Setting window border/cursor" }; const MISSING_FEATURES_WAYLAND = [_][]const u8{ "Resizing window", "Changing display mode", "VSync", "Setting window border/cursor" }; +pub fn run(comptime on_each_update_fn: anytype, args_tuple: std.meta.ArgsTuple(@TypeOf(on_each_update_fn))) void { + while (@call(.auto, on_each_update_fn, args_tuple) catch false) {} +} + pub fn tick(core: *Core) !void { var windows = core.windows.slice(); while (windows.next()) |window_id| { diff --git a/src/core/Windows.zig b/src/core/Windows.zig index 8559ea37..76cbf191 100644 --- a/src/core/Windows.zig +++ b/src/core/Windows.zig @@ -33,6 +33,10 @@ pub const Context = struct { window_id: mach.ObjectID, }; +pub fn run(comptime on_each_update_fn: anytype, args_tuple: std.meta.ArgsTuple(@TypeOf(on_each_update_fn))) void { + while (@call(.auto, on_each_update_fn, args_tuple) catch false) {} +} + pub fn tick(core: *Core) !void { var windows = core.windows.slice(); while (windows.next()) |window_id| {