From 55113566bf0abb6e45a4f61d17a5d7b9a35ed6ac Mon Sep 17 00:00:00 2001 From: SuperAuguste <19855629+SuperAuguste@users.noreply.github.com> Date: Fri, 3 May 2024 20:06:02 -0400 Subject: [PATCH] Make reloaders compile hopefully --- src/watch/Reloader.zig | 2 +- src/watch/watcher/LinuxWatcher.zig | 2 +- src/watch/watcher/MacosWatcher.zig | 154 +++++++++++++++------------ src/watch/watcher/WindowsWatcher.zig | 2 +- 4 files changed, 87 insertions(+), 73 deletions(-) diff --git a/src/watch/Reloader.zig b/src/watch/Reloader.zig index c753366..2603fb1 100644 --- a/src/watch/Reloader.zig +++ b/src/watch/Reloader.zig @@ -37,7 +37,7 @@ pub fn init( } pub fn listen(reloader: *Reloader) !void { - try reloader.watcher.listen(reloader.gpa, reloader, onChange); + try reloader.watcher.listen(reloader.gpa, reloader, &onChange); } pub fn onChange(reloader: *Reloader, dir_that_changed: usize) void { diff --git a/src/watch/watcher/LinuxWatcher.zig b/src/watch/watcher/LinuxWatcher.zig index e4bb522..90c3ed1 100644 --- a/src/watch/watcher/LinuxWatcher.zig +++ b/src/watch/watcher/LinuxWatcher.zig @@ -270,7 +270,7 @@ pub fn listen( self: *LinuxWatcher, gpa: std.mem.Allocator, context: anytype, - callback: fn (@TypeOf(context), changed_handle: usize) void, + callback: *const fn (@TypeOf(context), changed_handle: usize) void, ) (std.posix.INotifyAddWatchError || std.fs.File.ReadError || std.fs.Dir.OpenError || std.mem.Allocator.Error)!void { const Event = std.os.linux.inotify_event; const event_size = @sizeOf(Event); diff --git a/src/watch/watcher/MacosWatcher.zig b/src/watch/watcher/MacosWatcher.zig index ac8e7ec..352019e 100644 --- a/src/watch/watcher/MacosWatcher.zig +++ b/src/watch/watcher/MacosWatcher.zig @@ -8,22 +8,41 @@ const c = @cImport({ const log = std.log.scoped(.watcher); -out_dir_path: []const u8, -in_dir_paths: []const []const u8, +paths: []const []const u8, +macos_paths: []const c.CFStringRef, +paths_to_watch: c.CFArrayRef, + +pub fn init(gpa: std.mem.Allocator, paths: []const []const u8) !MacosWatcher { + const macos_paths = try gpa.alloc(c.CFStringRef, paths.len); + + for (paths, macos_paths) |str, *ref| { + ref.* = c.CFStringCreateWithCString( + null, + str.ptr, + c.kCFStringEncodingUTF8, + ); + } + + const paths_to_watch: c.CFArrayRef = c.CFArrayCreate( + null, + @ptrCast(macos_paths.ptr), + @intCast(macos_paths.len), + null, + ); -pub fn init( - gpa: std.mem.Allocator, - out_dir_path: []const u8, - in_dir_paths: []const []const u8, -) !MacosWatcher { - _ = gpa; return .{ - .out_dir_path = out_dir_path, - .in_dir_paths = in_dir_paths, + .paths = paths, + .macos_paths = macos_paths, + .paths_to_watch = paths_to_watch, }; } -pub fn callback( +pub fn deinit(watcher: *MacosWatcher, gpa: std.mem.Allocator) void { + gpa.free(watcher.macos_paths); + c.CFRelease(watcher.paths_to_watch); +} + +fn eventStreamCallback(comptime ContextType: type) fn ( streamRef: c.ConstFSEventStreamRef, clientCallBackInfo: ?*anyopaque, numEvents: usize, @@ -31,74 +50,71 @@ pub fn callback( eventFlags: ?[*]const c.FSEventStreamEventFlags, eventIds: ?[*]const c.FSEventStreamEventId, ) callconv(.C) void { - _ = eventIds; - _ = eventFlags; - _ = streamRef; - const ctx: *Context = @alignCast(@ptrCast(clientCallBackInfo)); - - const paths: [*][*:0]u8 = @alignCast(@ptrCast(eventPaths)); - for (paths[0..numEvents]) |p| { - const path = std.mem.span(p); - log.debug("Changed: {s}\n", .{path}); - - const basename = std.fs.path.basename(path); - var base_path = path[0 .. path.len - basename.len]; - if (std.mem.endsWith(u8, base_path, "/")) - base_path = base_path[0 .. base_path.len - 1]; - - const is_out = std.mem.startsWith(u8, path, ctx.out_dir_path); - if (is_out) { - ctx.reloader.onOutputChange(base_path, basename); - } else { - ctx.reloader.onInputChange(base_path, basename); + return struct { + fn call( + streamRef: c.ConstFSEventStreamRef, + clientCallBackInfo: ?*anyopaque, + numEvents: usize, + eventPaths: ?*anyopaque, + eventFlags: ?[*]const c.FSEventStreamEventFlags, + eventIds: ?[*]const c.FSEventStreamEventId, + ) callconv(.C) void { + _ = eventIds; + _ = eventFlags; + _ = streamRef; + const ctx: *Context(ContextType) = @alignCast(@ptrCast(clientCallBackInfo)); + + const watcher = ctx.watcher; + const callback = ctx.callback; + + const paths: [*][*:0]u8 = @alignCast(@ptrCast(eventPaths)); + for (paths[0..numEvents]) |p| { + const path = std.mem.span(p); + log.debug("Changed: {s}\n", .{path}); + + const basename = std.fs.path.basename(path); + var base_path = path[0 .. path.len - basename.len]; + if (std.mem.endsWith(u8, base_path, "/")) + base_path = base_path[0 .. base_path.len - 1]; + + for (watcher.paths, 0..) |target_path, idx| { + if (std.mem.startsWith(u8, path, target_path)) { + callback(ctx.context, idx); + break; + } + } + } } - } + }.call; +} + +pub fn Context(comptime ContextType: type) type { + return struct { + watcher: *const MacosWatcher, + context: ContextType, + callback: *const fn (ContextType, changed_handle: usize) void, + }; } -const Context = struct { - reloader: *Reloader, - out_dir_path: []const u8, -}; pub fn listen( - self: *MacosWatcher, + watcher: *MacosWatcher, gpa: std.mem.Allocator, - reloader: *Reloader, + context: anytype, + callback: *const fn (@TypeOf(context), changed_handle: usize) void, ) !void { - var macos_paths = try gpa.alloc(c.CFStringRef, self.in_dir_paths.len + 1); - defer gpa.free(macos_paths); - - macos_paths[0] = c.CFStringCreateWithCString( - null, - self.out_dir_path.ptr, - c.kCFStringEncodingUTF8, - ); - - for (self.in_dir_paths, macos_paths[1..]) |str, *ref| { - ref.* = c.CFStringCreateWithCString( - null, - str.ptr, - c.kCFStringEncodingUTF8, - ); - } - - const paths_to_watch: c.CFArrayRef = c.CFArrayCreate( - null, - @ptrCast(macos_paths.ptr), - @intCast(macos_paths.len), - null, - ); - - var ctx: Context = .{ - .reloader = reloader, - .out_dir_path = self.out_dir_path, + _ = gpa; // autofix + var stream_context_context = Context(@TypeOf(context)){ + .watcher = watcher, + .callback = callback, + .context = context, }; - var stream_context: c.FSEventStreamContext = .{ .info = &ctx }; + var stream_context: c.FSEventStreamContext = .{ .info = &stream_context_context }; const stream: c.FSEventStreamRef = c.FSEventStreamCreate( null, - &callback, + &eventStreamCallback(@TypeOf(callback)), &stream_context, - paths_to_watch, + watcher.paths_to_watch, c.kFSEventStreamEventIdSinceNow, 0.05, c.kFSEventStreamCreateFlagFileEvents, @@ -119,6 +135,4 @@ pub fn listen( c.FSEventStreamStop(stream); c.FSEventStreamInvalidate(stream); c.FSEventStreamRelease(stream); - - c.CFRelease(paths_to_watch); } diff --git a/src/watch/watcher/WindowsWatcher.zig b/src/watch/watcher/WindowsWatcher.zig index ea1037a..c92e421 100644 --- a/src/watch/watcher/WindowsWatcher.zig +++ b/src/watch/watcher/WindowsWatcher.zig @@ -43,7 +43,7 @@ pub fn listen( watcher: *WindowsWatcher, gpa: std.mem.Allocator, context: anytype, - callback: fn (@TypeOf(context), changed_handle: usize) void, + callback: *const fn (@TypeOf(context), changed_handle: usize) void, ) error{ UnknownWaitStatus, NextChangeFailed, WaitAbandoned, Unexpected }!void { _ = gpa;