From 53cbe35a97e1bdf3ef1872f09705003f10858b1c Mon Sep 17 00:00:00 2001 From: David Allemang Date: Wed, 10 Jul 2024 14:32:37 -0400 Subject: [PATCH] clean up hook implementation --- src/nu/hooks.zig | 102 ++++++++++++++++++++++++++++------------------- 1 file changed, 61 insertions(+), 41 deletions(-) diff --git a/src/nu/hooks.zig b/src/nu/hooks.zig index 79debaf..ca8fef8 100644 --- a/src/nu/hooks.zig +++ b/src/nu/hooks.zig @@ -4,51 +4,74 @@ pub fn Hook(ftype: type) type { const F: std.builtin.Type.Fn = @typeInfo(ftype).Fn; const Result: type = F.return_type.?; - return struct { - const Self = @This(); + return switch (@typeInfo(Result)) { + .Void => struct { + const Self = @This(); - handlers: std.AutoArrayHashMap(*const ftype, void), + handlers: std.AutoArrayHashMap(*const ftype, void), - pub fn init(alloc: std.mem.Allocator) Self { - return Self{ - .handlers = std.AutoArrayHashMap(*const ftype, void).init(alloc), - }; - } - - pub fn deinit(self: *Self) void { - self.handlers.deinit(); - } - - pub fn register(self: *Self, f: ftype) !void { - try self.handlers.putNoClobber(f, {}); - } - - pub fn unregister(self: *Self, f: ftype) void { - _ = self.handlers.orderedRemove(f); - } - - fn invoke_alloc_results(self: Self, alloc: std.mem.Allocator, args: anytype) ![]Result { - const results = try alloc.alloc(Result, self.handlers.count()); - for (self.handlers.keys(), results) |handler, *result| { - result.* = @call(.auto, handler, args); + pub fn init(alloc: std.mem.Allocator) Self { + return Self{ + .handlers = std.AutoArrayHashMap(*const ftype, void).init(alloc), + }; } - return results; - } - fn invoke_void(self: Self, args: anytype) void { - for (self.handlers.keys()) |handler| { - @call(.auto, handler, args); + pub fn deinit(self: *Self) void { + self.handlers.deinit(); } - } - pub const invoke = switch (@typeInfo(Result)) { - .Void => invoke_void, - else => invoke_alloc_results, - }; + pub fn register(self: *Self, f: ftype) !void { + try self.handlers.putNoClobber(f, {}); + } + + pub fn unregister(self: *Self, f: ftype) void { + _ = self.handlers.orderedRemove(f); + } + + fn invoke(self: Self, args: anytype) void { + for (self.handlers.keys()) |handler| { + @call(.auto, handler, args); + } + } + }, + else => struct { + const Self = @This(); + + handlers: std.AutoArrayHashMap(*const ftype, void), + + pub fn init(alloc: std.mem.Allocator) Self { + return Self{ + .handlers = std.AutoArrayHashMap(*const ftype, void).init(alloc), + }; + } + + pub fn deinit(self: *Self) void { + self.handlers.deinit(); + } + + pub fn register(self: *Self, f: ftype) !void { + try self.handlers.putNoClobber(f, {}); + } + + pub fn unregister(self: *Self, f: ftype) void { + _ = self.handlers.orderedRemove(f); + } + + fn invoke(self: Self, alloc: std.mem.Allocator, args: anytype) ![]Result { + const results = try alloc.alloc(Result, self.handlers.count()); + for (self.handlers.keys(), results) |handler, *result| { + result.* = @call(.auto, handler, args); + } + return results; + } + }, }; } test "void hooks" { + var set_flags = Hook(fn (*usize) void).init(std.testing.allocator); + defer set_flags.deinit(); + const hooks = struct { pub fn set_one(f: *usize) void { f.* |= 0b01; @@ -59,9 +82,6 @@ test "void hooks" { } }; - var set_flags = Hook(fn (*usize) void).init(std.testing.allocator); - defer set_flags.deinit(); - var flag: usize = undefined; flag = 0; @@ -94,6 +114,9 @@ test "void hooks" { } test "collect hooks" { + var collect = Hook(fn (usize) usize).init(std.testing.allocator); + defer collect.deinit(); + const hooks = struct { pub fn double(f: usize) usize { return f * 2; @@ -104,9 +127,6 @@ test "collect hooks" { } }; - var collect = Hook(fn (usize) usize).init(std.testing.allocator); - defer collect.deinit(); - { const result = try collect.invoke(std.testing.allocator, .{3}); defer std.testing.allocator.free(result);