basic Microchip functionality

This commit is contained in:
Jeeves 2025-04-30 11:45:09 -06:00
parent ee3b09191a
commit 332dffa975

View file

@ -11,6 +11,23 @@ pub fn main() !void {
var circuit = Circuit.init(allocator);
defer circuit.deinit();
var microchip = try circuit.addComponent(Microchip);
var not1 = try circuit.addComponent(Not);
var not2 = try microchip.circuit.addComponent(Not);
not1.invert_output = false;
try microchip.resizeInputs(1);
try microchip.resizeOutputs(1);
try microchip.connectInput(0, &not2.component, 0);
try microchip.connectOutput(&not2.component, 0, 0);
try circuit.tick();
std.log.info("{}", .{microchip.component.getOutput(0)});
try circuit.tick();
std.log.info("{}", .{microchip.component.getOutput(0)});
try circuit.tick();
std.log.info("{}", .{microchip.component.getOutput(0)});
}
test "basic circuit" {
@ -234,22 +251,18 @@ pub const Component = struct {
pub const Input = struct {
signal: ?*Signal = null,
connection: ?Connection = null,
pub const Connection = struct {
component: *Component,
idx: usize,
};
};
pub const Output = struct {
signal: Signal = .{},
connections: Connections = .empty,
pub const Connections = std.ArrayListUnmanaged(Connection);
pub const Connection = struct {
component: *Component,
idx: usize,
};
};
pub const Connection = struct {
component: *Component,
idx: usize,
};
// TODO wouldn't this need to be a list of ?Connection since an
pub const Connections = std.ArrayListUnmanaged(Connection);
const Inputs = std.ArrayListUnmanaged(Input);
const Outputs = std.ArrayListUnmanaged(Output);
@ -373,11 +386,15 @@ pub const Microchip = struct {
component: Component,
circuit: Circuit,
outer_to_inner: std.ArrayListUnmanaged(?Component.Connection),
inner_to_outer: std.ArrayListUnmanaged(?Component.Connection),
pub fn init(allocator: std.mem.Allocator) !*Microchip {
var self = try allocator.create(Microchip);
errdefer allocator.destroy(self);
self.circuit = Circuit.init(allocator);
self.outer_to_inner = .empty;
self.inner_to_outer = .empty;
errdefer self.circuit.deinit();
try Component.init(&self.component, allocator, "Microchip", 0, 0, &update, &deinit);
return self;
@ -385,18 +402,56 @@ pub const Microchip = struct {
pub fn deinit(component: *Component, allocator: std.mem.Allocator) void {
const self: *Microchip = @fieldParentPtr("component", component);
self.outer_to_inner.deinit(self.circuit.allocator);
self.inner_to_outer.deinit(self.circuit.allocator);
self.circuit.deinit();
allocator.destroy(self);
}
pub fn update(component: *Component) AllocatorError!void {
const self: *Microchip = @fieldParentPtr("component", component);
for (self.outer_to_inner.items, 0..) |connection_opt, idx| {
if (connection_opt) |connection| {
const outer = component.getInput(idx);
const inner = &connection.component.inputs.items[connection.idx];
inner.signal = outer;
}
}
try self.circuit.tick();
for (self.inner_to_outer.items, 0..) |connection_opt, idx| {
if (connection_opt) |connection| {
const outer = component.getOutput(idx);
const inner = connection.component.getOutput(connection.idx);
outer.* = inner.*;
}
}
}
pub fn resizeInputs(self: *Microchip, new_len: usize) !void {
try self.component.resizeInputs(self.circuit.allocator, new_len);
try self.outer_to_inner.resize(self.circuit.allocator, new_len);
}
pub fn resizeOutputs(self: *Microchip, new_len: usize) !void {
try self.component.resizeOutputs(self.circuit.allocator, new_len);
try self.inner_to_outer.resize(self.circuit.allocator, new_len);
}
pub fn connectInput(self: *Microchip, outer_idx: usize, inner: *Component, inner_idx: usize) !void {
self.outer_to_inner.items[outer_idx] = .{
.component = inner,
.idx = inner_idx,
};
}
pub fn connectOutput(self: *Microchip, inner: *Component, inner_idx: usize, outer_idx: usize) !void {
_ = .{ self, inner, inner_idx, outer_idx };
@compileError("TODO");
self.inner_to_outer.items[outer_idx] = .{
.component = inner,
.idx = inner_idx,
};
}
};