This commit is contained in:
Jeeves 2025-02-11 11:43:39 -07:00
parent fd2b4026e9
commit 01107aece5

View file

@ -88,134 +88,144 @@ pub const Circuit = struct {
components: std.ArrayList(Component),
};
pub const Wire = struct {
digital: bool = false,
analog: f32 = 0.0,
pub fn format(self: Wire, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
_ = .{ fmt, options };
try writer.print("Wire({s} | {d:0>1.4})", .{
if (self.digital) "1" else "0",
self.analog,
});
}
fn analogSet(self: *Wire, value: f32) void {
self.analog = std.math.clamp(value, 0.0, 1.0);
}
};
pub const Battery = struct {
component: Component = .{},
output: *Wire,
value: f32,
invert_output: bool = false,
pub fn process(self: *Battery) void {
if (self.invert_output) {
self.output.digital = self.value != 0.0;
self.output.analogSet(self.value);
} else {
self.output.digital = self.value == 0.0;
self.output.analogSet(1.0 - @abs(self.value));
}
}
pub fn process(component: *Component) Signal {}
};
pub const Not = struct {
component: Component = .{},
input: *Wire,
output: *Wire,
invert_output: bool = true,
pub fn process(self: *Not) void {
if (self.invert_output) {
self.output.digital = !self.input.digital;
self.output.analogSet(1.0 - @abs(self.input.analog));
} else {
self.output.digital = self.input.digital;
self.output.analogSet(self.input.analog); // TODO does the output get clamped here?
}
}
pub const Signal = struct {
digital: i2,
analog: f32,
color: u24,
};
pub const And = struct {
component: Component,
// pub const Wire = struct {
// digital: bool = false,
// analog: f32 = 0.0,
inputs: []*Wire,
output: *Wire,
// pub fn format(self: Wire, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
// _ = .{ fmt, options };
// try writer.print("Wire({s} | {d:0>1.4})", .{
// if (self.digital) "1" else "0",
// self.analog,
// });
// }
// if false, is in Minimum Input mode
// if true, is in Multiply Inputs mode
arithmetic_mode: bool = false,
// TODO check implementation
pub fn process(self: *And) void {
if (self.arithmetic_mode) {
self.output.digital = self.inputs[0].digital;
self.output.analog = self.inputs[0].analog;
for (self.inputs[1..]) |input| {
self.output.digital = self.output.digital and input.digital;
self.output.analog *= input.analog;
}
} else {
self.output.digital = self.inputs[0].digital;
self.output.analog = self.inputs[0].analog;
for (self.inputs[1..]) |input| {
self.output.digital = self.output.digital and input.digital;
self.output.analog = @min(self.output.analog, input.analog);
}
}
self.output.analog = std.math.clamp(self.output.analog, 0.0, 1.0);
// var digital = self.inputs[0].digital;
// if (digital) for (1..self.inputs.len - 1) |i| if (!self.inputs[i].digital) {
// digital = false;
// break;
// fn analogSet(self: *Wire, value: f32) void {
// self.analog = std.math.clamp(value, 0.0, 1.0);
// }
// };
// self.output.digital = digital;
// var best = self.inputs[0].analog;
// for (self.inputs[1..]) |input| best = @min(best, input.analog);
// self.output.analog = best;
}
};
// pub const Battery = struct {
// // component: Component = .{},
pub const Or = struct {
component: Component,
// output: *Wire,
inputs: []*Wire,
output: *Wire,
// value: f32,
// invert_output: bool = false,
// if false, is in Maximum Input mode
// if true, is in Add Inputs mode
arithmetic_mode: bool = false,
// TODO check implementation
pub fn process(self: *Or) void {
if (self.arithmetic_mode) {
self.output.digital = self.inputs[0].digital;
self.output.analog = self.inputs[0].analog;
for (self.inputs[1..]) |input| {
self.output.digital = self.output.digital and input.digital;
self.output.analog += input.analog;
}
} else {
self.output.digital = self.inputs[0].digital;
self.output.analog = self.inputs[0].analog;
for (self.inputs[1..]) |input| {
self.output.digital = self.output.digital and input.digital;
self.output.analog = @max(self.output.analog, input.analog);
}
}
self.output.analog = std.math.clamp(self.output.analog, 0.0, 1.0);
// self.output.digital = 1;
// for (self.inputs) |input| if (input.digital) {
// self.output.digital = true;
// break;
// pub fn process(self: *Battery) void {
// if (self.invert_output) {
// self.output.digital = self.value != 0.0;
// self.output.analogSet(self.value);
// } else {
// self.output.digital = self.value == 0.0;
// self.output.analogSet(1.0 - @abs(self.value));
// }
// }
// };
// pub const Not = struct {
// // component: Component = .{},
// input: *Wire,
// output: *Wire,
// invert_output: bool = true,
// pub fn process(self: *Not) void {
// if (self.invert_output) {
// self.output.digital = !self.input.digital;
// self.output.analogSet(1.0 - @abs(self.input.analog));
// } else {
// self.output.digital = self.input.digital;
// self.output.analogSet(self.input.analog); // TODO does the output get clamped here?
// }
// }
// };
// pub const And = struct {
// // component: Component,
// inputs: []*Wire,
// output: *Wire,
// // if false, is in Minimum Input mode
// // if true, is in Multiply Inputs mode
// arithmetic_mode: bool = false,
// // TODO check implementation
// pub fn process(self: *And) void {
// if (self.arithmetic_mode) {
// self.output.digital = self.inputs[0].digital;
// self.output.analog = self.inputs[0].analog;
// for (self.inputs[1..]) |input| {
// self.output.digital = self.output.digital and input.digital;
// self.output.analog *= input.analog;
// }
// } else {
// self.output.digital = self.inputs[0].digital;
// self.output.analog = self.inputs[0].analog;
// for (self.inputs[1..]) |input| {
// self.output.digital = self.output.digital and input.digital;
// self.output.analog = @min(self.output.analog, input.analog);
// }
// }
// self.output.analog = std.math.clamp(self.output.analog, 0.0, 1.0);
// // var digital = self.inputs[0].digital;
// // if (digital) for (1..self.inputs.len - 1) |i| if (!self.inputs[i].digital) {
// // digital = false;
// // break;
// // };
// // self.output.digital = digital;
// // var best = self.inputs[0].analog;
// // for (self.inputs[1..]) |input| best = @min(best, input.analog);
// // self.output.analog = best;
// }
// };
// pub const Or = struct {
// // component: Component,
// inputs: []*Wire,
// output: *Wire,
// // if false, is in Maximum Input mode
// // if true, is in Add Inputs mode
// arithmetic_mode: bool = false,
// // TODO check implementation
// pub fn process(self: *Or) void {
// if (self.arithmetic_mode) {
// self.output.digital = self.inputs[0].digital;
// self.output.analog = self.inputs[0].analog;
// for (self.inputs[1..]) |input| {
// self.output.digital = self.output.digital and input.digital;
// self.output.analog += input.analog;
// }
// } else {
// self.output.digital = self.inputs[0].digital;
// self.output.analog = self.inputs[0].analog;
// for (self.inputs[1..]) |input| {
// self.output.digital = self.output.digital and input.digital;
// self.output.analog = @max(self.output.analog, input.analog);
// }
// }
// self.output.analog = std.math.clamp(self.output.analog, 0.0, 1.0);
// // self.output.digital = 1;
// // for (self.inputs) |input| if (input.digital) {
// // self.output.digital = true;
// // break;
// // };
// }
// };
}
};