fix memory leaks by holding a deinitFn pointer in Component
This commit is contained in:
parent
47acb64e25
commit
24479e0fe7
1 changed files with 83 additions and 48 deletions
131
src/main.zig
131
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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue