From 1c69ce4b2fedec5607d29a15f434c38c2a4f45ff Mon Sep 17 00:00:00 2001 From: Jeeves Date: Tue, 29 Apr 2025 14:47:13 -0600 Subject: [PATCH] add Selector --- src/main.zig | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/src/main.zig b/src/main.zig index 26057fa..75b0654 100644 --- a/src/main.zig +++ b/src/main.zig @@ -596,4 +596,75 @@ test "max" { try std.testing.expectEqual(-0.5, or1.component.getOutput(0).analog); } +pub const Selector = struct { + component: Component, + + current_output: usize = 0, + invert_output: bool = false, + + pub fn init(allocator: std.mem.Allocator) !*Selector { + var self = try allocator.create(Selector); + errdefer allocator.destroy(self); + self.* = .{ .component = undefined }; + try Component.init(&self.component, allocator, "Selector", 2, 2, &update, &deinit); + return self; + } + + pub fn deinit(component: *Component, allocator: std.mem.Allocator) void { + const self: *Selector = @fieldParentPtr("component", component); + allocator.destroy(self); + } + + // TODO check implementation + pub fn update(component: *Component) AllocatorError!void { + const self: *Selector = @fieldParentPtr("component", component); + var last_idx: ?usize = null; + for (component.inputs.items, 0..) |input, idx| { + if (input.signal) |signal| { + if (signal.digital == 1) last_idx = idx; + } + } + if (last_idx) |lidx| { + for (component.outputs.items, 0..) |*output, idx| { + output.signal = if (if (self.invert_output) idx != lidx else idx == lidx) + .{ .digital = 1, .analog = 1.0 } + else + .{ .digital = 0, .analog = 0.0 }; + } + } + } +}; + +test "selector" { + var a = Signal{ .digital = 0 }; + var b = Signal{ .digital = 1 }; + + var selector = try Selector.init(std.testing.allocator); + defer selector.component.deinit(std.testing.allocator); + selector.component.inputs.items[0].signal = &a; + selector.component.inputs.items[1].signal = &b; + + try selector.component.update(); + try std.testing.expectEqual(Signal{ .digital = 0, .analog = 0.0 }, selector.component.getOutput(0).*); + try std.testing.expectEqual(Signal{ .digital = 1, .analog = 1.0 }, selector.component.getOutput(1).*); + + a.digital = 0; + b.digital = 0; + try selector.component.update(); + try selector.component.update(); + try std.testing.expectEqual(Signal{ .digital = 0, .analog = 0.0 }, selector.component.getOutput(0).*); + try std.testing.expectEqual(Signal{ .digital = 1, .analog = 1.0 }, selector.component.getOutput(1).*); + + a.digital = 1; + b.digital = 0; + try selector.component.update(); + try std.testing.expectEqual(Signal{ .digital = 1, .analog = 1.0 }, selector.component.getOutput(0).*); + try std.testing.expectEqual(Signal{ .digital = 0, .analog = 0.0 }, selector.component.getOutput(1).*); + + selector.invert_output = true; + try selector.component.update(); + try std.testing.expectEqual(Signal{ .digital = 0, .analog = 0.0 }, selector.component.getOutput(0).*); + try std.testing.expectEqual(Signal{ .digital = 1, .analog = 1.0 }, selector.component.getOutput(1).*); +} + const AllocatorError = std.mem.Allocator.Error;