add Selector

This commit is contained in:
Jeeves 2025-04-29 14:47:13 -06:00
parent 222a89addf
commit 1c69ce4b2f

View file

@ -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;