diff --git a/src/main.zig b/src/main.zig index bb8b380..d31c910 100644 --- a/src/main.zig +++ b/src/main.zig @@ -113,6 +113,8 @@ pub const Circuit = struct { components: Components, source_components: Components, + const Components = std.ArrayListUnmanaged(*Component); + pub fn init(allocator: std.mem.Allocator) Circuit { return .{ .allocator = allocator, @@ -127,9 +129,9 @@ pub const Circuit = struct { self.components.deinit(self.allocator); } - pub fn addComponent(self: *Circuit, comptime T: type) !T { + pub fn addComponent(self: *Circuit, comptime T: type) !*T { var c = try T.init(self.allocator); - errdefer c.deinit(self.allocator); + errdefer c.component.deinit(self.allocator); try self.components.append(self.allocator, &c.component); if (T == Battery) try self.source_components.append(self.allocator, &c.component); return c; @@ -142,8 +144,6 @@ pub const Circuit = struct { _ = process_order; } - const Components = std.ArrayListUnmanaged(*Component); - const ProcessOrder = []*Component; const ProcessOrderSolver = struct { circuit: *Circuit, @@ -168,8 +168,10 @@ pub const Circuit = struct { // std.debug.print("source component {any}\n\n", .{source_component}); const idx = self.componentIndex(component); self.solved[idx.?] = true; - std.debug.print("{any}\n", .{component}); - component = component.outputs.items[0].connection.?; + std.debug.print("{}\n", .{component}); + std.debug.print("{any}\n", .{component.outputs.items}); + _ = &component; + // component = component.outputs.items[0].connection.?; // } } return &[_]*Component{}; @@ -198,12 +200,36 @@ pub const Circuit = struct { var null_signal = Signal{}; pub const Component = struct { + name: []const u8, + inputs: Inputs, outputs: Outputs, processFn: *const fn (*Component) void, + deinitFn: *const fn (*Component, std.mem.Allocator) void, - pub fn init(allocator: std.mem.Allocator, inputs_len: usize, outputs_len: usize, processFn: *const fn (*Component) void) !Component { + pub const Input = struct { + signal: *Signal = &null_signal, + connection: ?*Component = null, + idx: usize = 0, + }; + pub const Output = struct { + signal: Signal = .{}, + connection: ?*Component = null, + idx: usize = 0, + }; + const Inputs = std.ArrayListUnmanaged(Input); + const Outputs = std.ArrayListUnmanaged(Output); + + pub fn init( + self: *Component, + allocator: std.mem.Allocator, + name: []const u8, + inputs_len: usize, + outputs_len: usize, + processFn: *const fn (*Component) void, + deinitFn: *const fn (*Component, std.mem.Allocator) void, + ) !void { var inputs = Inputs.empty; errdefer inputs.deinit(allocator); try inputs.resize(allocator, inputs_len); @@ -214,16 +240,17 @@ pub const Component = struct { try outputs.resize(allocator, outputs_len); for (0..outputs.items.len) |i| outputs.items[i] = .{}; - return .{ - .inputs = inputs, - .outputs = outputs, - .processFn = processFn, - }; + self.name = name; + self.inputs = inputs; + self.outputs = outputs; + self.processFn = processFn; + self.deinitFn = deinitFn; } pub fn deinit(self: *Component, allocator: std.mem.Allocator) void { self.inputs.deinit(allocator); self.outputs.deinit(allocator); + self.deinitFn(self, allocator); } pub fn process(self: *Component) void { @@ -258,18 +285,18 @@ pub const Component = struct { }; } - pub const Input = struct { - signal: *Signal = &null_signal, - connection: ?*Component = null, - idx: usize = 0, - }; - pub const Output = struct { - signal: Signal = .{}, - connection: ?*Component = null, - idx: usize = 0, - }; - const Inputs = std.ArrayListUnmanaged(Input); - const Outputs = std.ArrayListUnmanaged(Output); + pub fn format( + self: *Component, + comptime _: []const u8, + _: std.fmt.FormatOptions, + writer: anytype, + ) !void { + try writer.print("Component{{ .name = \"{s}\", .inputs.items.len = {d}, .outputs.items.len = {d} }}", .{ + self.name, + self.inputs.items.len, + self.outputs.items.len, + }); + } }; pub const Signal = struct { @@ -298,14 +325,16 @@ pub const Battery = struct { value: f32 = 1.0, - pub fn init(allocator: std.mem.Allocator) !Battery { - return .{ - .component = try Component.init(allocator, 0, 1, &process), - }; + pub fn init(allocator: std.mem.Allocator) !*Battery { + var self = try allocator.create(Battery); + errdefer allocator.destroy(self); + try Component.init(&self.component, allocator, "Battery", 0, 1, &process, &deinit); + return self; } - pub fn deinit(self: *Battery, allocator: std.mem.Allocator) void { - self.component.deinit(allocator); + pub fn deinit(component: *Component, allocator: std.mem.Allocator) void { + const self: *Battery = @fieldParentPtr("component", component); + allocator.destroy(self); } pub fn process(component: *Component) void { @@ -320,14 +349,16 @@ pub const Not = struct { invert_output: bool = true, - pub fn init(allocator: std.mem.Allocator) !Not { - return .{ - .component = try Component.init(allocator, 1, 1, &process), - }; + pub fn init(allocator: std.mem.Allocator) !*Not { + var self = try allocator.create(Not); + errdefer allocator.destroy(self); + try Component.init(&self.component, allocator, "NOT", 1, 1, &process, &deinit); + return self; } - pub fn deinit(self: *Not, allocator: std.mem.Allocator) void { - self.component.deinit(allocator); + pub fn deinit(component: *Component, allocator: std.mem.Allocator) void { + const self: *Not = @fieldParentPtr("component", component); + allocator.destroy(self); } pub fn process(component: *Component) void { @@ -350,14 +381,16 @@ pub const And = struct { // if true, is in Multiply Inputs mode arithmetic_mode: bool = false, - pub fn init(allocator: std.mem.Allocator) !And { - return .{ - .component = try Component.init(allocator, 2, 1, &process), - }; + pub fn init(allocator: std.mem.Allocator) !*And { + var self = try allocator.create(And); + errdefer allocator.destroy(self); + try Component.init(&self.component, allocator, "AND", 2, 1, &process, &deinit); + return self; } - pub fn deinit(self: *And, allocator: std.mem.Allocator) void { - self.component.deinit(allocator); + pub fn deinit(component: *Component, allocator: std.mem.Allocator) void { + const self: *And = @fieldParentPtr("component", component); + allocator.destroy(self); } // TODO check implementation @@ -410,14 +443,16 @@ pub const Or = struct { // if true, is in Add Inputs mode arithmetic_mode: bool = false, - pub fn init(allocator: std.mem.Allocator) !Or { - return .{ - .component = try Component.init(allocator, 2, 1, &process), - }; + pub fn init(allocator: std.mem.Allocator) !*Or { + var self = try allocator.create(Or); + errdefer allocator.destroy(self); + try Component.init(&self.component, allocator, "OR", 2, 1, &process, &deinit); + return self; } - pub fn deinit(self: *Or, allocator: std.mem.Allocator) void { - self.component.deinit(allocator); + pub fn deinit(component: *Component, allocator: std.mem.Allocator) void { + const self: *Or = @fieldParentPtr("component", component); + allocator.destroy(self); } // TODO check implementation