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