diff --git a/src/main.zig b/src/main.zig index 0bc0f18..265996c 100644 --- a/src/main.zig +++ b/src/main.zig @@ -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(¬1.component, 0, ¬2.component, 0); - try circuit.connectComponents(¬2.component, 0, ¬1.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(¬1.component, 0, ¬2.component, 0); + try microchip.circuit.connectComponents(¬2.component, 0, ¬1.component, 0); + + try microchip.connectOutput(¬2.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;