Skip to content

Commit

Permalink
Make reloaders compile hopefully
Browse files Browse the repository at this point in the history
  • Loading branch information
SuperAuguste committed May 4, 2024
1 parent a4f52bc commit 5511356
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 73 deletions.
2 changes: 1 addition & 1 deletion src/watch/Reloader.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion src/watch/watcher/LinuxWatcher.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
154 changes: 84 additions & 70 deletions src/watch/watcher/MacosWatcher.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,97 +8,113 @@ 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,
eventPaths: ?*anyopaque,
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,
Expand All @@ -119,6 +135,4 @@ pub fn listen(
c.FSEventStreamStop(stream);
c.FSEventStreamInvalidate(stream);
c.FSEventStreamRelease(stream);

c.CFRelease(paths_to_watch);
}
2 changes: 1 addition & 1 deletion src/watch/watcher/WindowsWatcher.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down

0 comments on commit 5511356

Please sign in to comment.