|
1 | 1 | const builtin = @import("builtin"); |
2 | 2 | const std = @import("../std.zig"); |
3 | | -const Watch = @This(); |
4 | 3 | const Step = std.Build.Step; |
5 | 4 | const Allocator = std.mem.Allocator; |
6 | 5 | const assert = std.debug.assert; |
7 | 6 | const fatal = std.process.fatal; |
| 7 | +const Watch = @This(); |
| 8 | +const FsEvents = @import("Watch/FsEvents.zig"); |
8 | 9 |
|
9 | | -dir_table: DirTable, |
10 | 10 | os: Os, |
| 11 | +/// The number to show as the number of directories being watched. |
| 12 | +dir_count: usize, |
| 13 | +// These fields are common to most implementations so are kept here for simplicity. |
| 14 | +// They are `undefined` on implementations which do not utilize then. |
| 15 | +dir_table: DirTable, |
11 | 16 | generation: Generation, |
12 | 17 |
|
13 | 18 | pub const have_impl = Os != void; |
@@ -97,6 +102,7 @@ const Os = switch (builtin.os.tag) { |
97 | 102 | fn init() !Watch { |
98 | 103 | return .{ |
99 | 104 | .dir_table = .{}, |
| 105 | + .dir_count = 0, |
100 | 106 | .os = switch (builtin.os.tag) { |
101 | 107 | .linux => .{ |
102 | 108 | .handle_table = .{}, |
@@ -273,6 +279,7 @@ const Os = switch (builtin.os.tag) { |
273 | 279 | } |
274 | 280 | w.generation +%= 1; |
275 | 281 | } |
| 282 | + w.dir_count = w.dir_table.count(); |
276 | 283 | } |
277 | 284 |
|
278 | 285 | fn wait(w: *Watch, gpa: Allocator, timeout: Timeout) !WaitResult { |
@@ -408,6 +415,7 @@ const Os = switch (builtin.os.tag) { |
408 | 415 | fn init() !Watch { |
409 | 416 | return .{ |
410 | 417 | .dir_table = .{}, |
| 418 | + .dir_count = 0, |
411 | 419 | .os = switch (builtin.os.tag) { |
412 | 420 | .windows => .{ |
413 | 421 | .handle_table = .{}, |
@@ -572,6 +580,7 @@ const Os = switch (builtin.os.tag) { |
572 | 580 | } |
573 | 581 | w.generation +%= 1; |
574 | 582 | } |
| 583 | + w.dir_count = w.dir_table.count(); |
575 | 584 | } |
576 | 585 |
|
577 | 586 | fn wait(w: *Watch, gpa: Allocator, timeout: Timeout) !WaitResult { |
@@ -605,7 +614,7 @@ const Os = switch (builtin.os.tag) { |
605 | 614 | }; |
606 | 615 | } |
607 | 616 | }, |
608 | | - .dragonfly, .freebsd, .netbsd, .openbsd, .ios, .macos, .tvos, .visionos, .watchos => struct { |
| 617 | + .dragonfly, .freebsd, .netbsd, .openbsd, .ios, .tvos, .visionos, .watchos => struct { |
609 | 618 | const posix = std.posix; |
610 | 619 |
|
611 | 620 | kq_fd: i32, |
@@ -639,6 +648,7 @@ const Os = switch (builtin.os.tag) { |
639 | 648 | errdefer posix.close(kq_fd); |
640 | 649 | return .{ |
641 | 650 | .dir_table = .{}, |
| 651 | + .dir_count = 0, |
642 | 652 | .os = .{ |
643 | 653 | .kq_fd = kq_fd, |
644 | 654 | .handles = .empty, |
@@ -769,6 +779,7 @@ const Os = switch (builtin.os.tag) { |
769 | 779 | } |
770 | 780 | w.generation +%= 1; |
771 | 781 | } |
| 782 | + w.dir_count = w.dir_table.count(); |
772 | 783 | } |
773 | 784 |
|
774 | 785 | fn wait(w: *Watch, gpa: Allocator, timeout: Timeout) !WaitResult { |
@@ -812,6 +823,28 @@ const Os = switch (builtin.os.tag) { |
812 | 823 | return any_dirty; |
813 | 824 | } |
814 | 825 | }, |
| 826 | + .macos => struct { |
| 827 | + fse: FsEvents, |
| 828 | + |
| 829 | + fn init() !Watch { |
| 830 | + return .{ |
| 831 | + .os = .{ .fse = try .init() }, |
| 832 | + .dir_count = 0, |
| 833 | + .dir_table = undefined, |
| 834 | + .generation = undefined, |
| 835 | + }; |
| 836 | + } |
| 837 | + fn update(w: *Watch, gpa: Allocator, steps: []const *Step) !void { |
| 838 | + try w.os.fse.setPaths(gpa, steps); |
| 839 | + w.dir_count = w.os.fse.watch_roots.len; |
| 840 | + } |
| 841 | + fn wait(w: *Watch, gpa: Allocator, timeout: Timeout) !WaitResult { |
| 842 | + return w.os.fse.wait(gpa, switch (timeout) { |
| 843 | + .none => null, |
| 844 | + .ms => |ms| @as(u64, ms) * std.time.ns_per_ms, |
| 845 | + }); |
| 846 | + } |
| 847 | + }, |
815 | 848 | else => void, |
816 | 849 | }; |
817 | 850 |
|
|
0 commit comments