start of Microchip

This commit is contained in:
Jeeves 2025-04-29 10:49:07 -06:00
parent 38e140a16e
commit 4e7c8a8989

View file

@ -12,19 +12,16 @@ pub fn main() !void {
var circuit = Circuit.init(allocator);
defer circuit.deinit();
var not1 = try circuit.addComponent(Not);
var not2 = try circuit.addComponent(Not);
not2.invert_output = false;
try circuit.connectComponents(&not1.component, 0, &not2.component, 0);
try circuit.connectComponents(&not2.component, 0, &not1.component, 0);
var microchip = try circuit.addComponent(Microchip);
try microchip.component.resizeOutputs(allocator, 1);
std.debug.print("before {}\n", .{not2.component.outputs.items[0].signal});
try circuit.tick();
std.debug.print("after {}\n", .{not2.component.outputs.items[0].signal});
try circuit.tick();
std.debug.print("after {}\n", .{not2.component.outputs.items[0].signal});
try circuit.tick();
std.debug.print("after {}\n", .{not2.component.outputs.items[0].signal});
var not1 = try microchip.circuit.addComponent(Not);
var not2 = try microchip.circuit.addComponent(Not);
not2.invert_output = false;
try microchip.circuit.connectComponents(&not1.component, 0, &not2.component, 0);
try microchip.circuit.connectComponents(&not2.component, 0, &not1.component, 0);
try microchip.connectOutput(&not2.component, 0, 0);
}
test "basic circuit" {
@ -150,7 +147,7 @@ pub const Circuit = struct {
if (self.update_order == null) try self.calculateUpdateOrder();
for (self.update_order.?) |component| {
std.log.debug("updating {}@{d}", .{ component, self.componentIndex(component).? });
component.process();
try component.process();
}
}
@ -244,7 +241,7 @@ pub const Component = struct {
inputs: Inputs,
outputs: Outputs,
processFn: *const fn (*Component) void,
processFn: *const fn (*Component) AllocatorError!void,
deinitFn: *const fn (*Component, std.mem.Allocator) void,
pub const Input = struct {
@ -273,7 +270,7 @@ pub const Component = struct {
name: []const u8,
inputs_len: usize,
outputs_len: usize,
processFn: *const fn (*Component) void,
processFn: *const fn (*Component) AllocatorError!void,
deinitFn: *const fn (*Component, std.mem.Allocator) void,
) !void {
var inputs = Inputs.empty;
@ -301,8 +298,8 @@ pub const Component = struct {
self.deinitFn(self, allocator);
}
pub inline fn process(self: *Component) void {
self.processFn(self);
pub inline fn process(self: *Component) AllocatorError!void {
try self.processFn(self);
}
// TODO allow inserting the new elements at an arbitrary index
@ -373,6 +370,37 @@ pub const Signal = struct {
}
};
pub const Microchip = struct {
component: Component,
circuit: Circuit,
pub fn init(allocator: std.mem.Allocator) !*Microchip {
var self = try allocator.create(Microchip);
errdefer allocator.destroy(self);
self.circuit = Circuit.init(allocator);
errdefer self.circuit.deinit();
try Component.init(&self.component, allocator, "Microchip", 0, 0, &process, &deinit);
return self;
}
pub fn deinit(component: *Component, allocator: std.mem.Allocator) void {
const self: *Microchip = @fieldParentPtr("component", component);
self.circuit.deinit();
allocator.destroy(self);
}
pub fn process(component: *Component) AllocatorError!void {
const self: *Microchip = @fieldParentPtr("component", component);
try self.circuit.tick();
}
pub fn connectOutput(self: *Microchip, inner: *Component, inner_idx: usize, outer_idx: usize) !void {
_ = .{ self, inner, inner_idx, outer_idx };
@compileError("TODO");
}
};
pub const Battery = struct {
component: Component,
@ -390,7 +418,7 @@ pub const Battery = struct {
allocator.destroy(self);
}
pub fn process(component: *Component) void {
pub fn process(component: *Component) AllocatorError!void {
const self: *Battery = @fieldParentPtr("component", component);
component.outputs.items[0].signal.digital = @intFromFloat(std.math.sign(self.value));
component.outputs.items[0].signal.analog = self.value;
@ -415,7 +443,7 @@ pub const Not = struct {
allocator.destroy(self);
}
pub fn process(component: *Component) void {
pub fn process(component: *Component) AllocatorError!void {
const self: *Not = @fieldParentPtr("component", component);
if (self.invert_output) {
component.outputs.items[0].signal.digital = 1 - @as(i2, @intCast(@abs(component.inputs.items[0].signal.digital)));
@ -449,7 +477,7 @@ pub const And = struct {
}
// TODO check implementation
pub fn process(component: *Component) void {
pub fn process(component: *Component) AllocatorError!void {
const self: *And = @fieldParentPtr("component", component);
if (self.arithmetic_mode) {
component.outputs.items[0].signal.digital = component.inputs.items[0].signal.digital;
@ -512,7 +540,7 @@ pub const Or = struct {
}
// TODO check implementation
pub fn process(component: *Component) void {
pub fn process(component: *Component) AllocatorError!void {
const self: *Or = @fieldParentPtr("component", component);
if (self.arithmetic_mode) {
component.outputs.items[0].signal.digital = component.inputs.items[0].signal.digital;
@ -553,3 +581,5 @@ pub const Or = struct {
// or1.process();
// try std.testing.expectEqual(-0.5, or1.output.analog);
// }
const AllocatorError = std.mem.Allocator.Error;