working graph traversal
This commit is contained in:
parent
9836866ec5
commit
ef86001b04
1 changed files with 27 additions and 81 deletions
108
src/main.zig
108
src/main.zig
|
@ -125,6 +125,7 @@ pub const Circuit = struct {
|
|||
}
|
||||
|
||||
pub fn deinit(self: *Circuit) void {
|
||||
// std.debug.print("process_order.len {d}\n", .{self.process_order.?.len});
|
||||
if (self.process_order) |p| self.allocator.free(p);
|
||||
for (0..self.components.items.len) |i| self.components.items[i].deinit(self.allocator);
|
||||
self.components.deinit(self.allocator);
|
||||
|
@ -144,7 +145,7 @@ pub const Circuit = struct {
|
|||
pub fn tick(self: *Circuit) !void {
|
||||
if (self.process_order == null) try self.updateProcessOrder();
|
||||
for (self.process_order.?) |component| {
|
||||
std.log.debug("processing component: {}", .{component});
|
||||
std.log.debug("processing component: {}@{d}", .{ component, self.componentIndex(component).? });
|
||||
component.process();
|
||||
}
|
||||
}
|
||||
|
@ -178,39 +179,39 @@ pub const Circuit = struct {
|
|||
var component_idx = source_component_idx;
|
||||
|
||||
dfs: while (true) {
|
||||
visited[component_idx] = true;
|
||||
|
||||
// check each output of the current component
|
||||
for (self.components.items[component_idx].outputs.items) |output| {
|
||||
// check each connection of the current output
|
||||
for (output.connections.items) |connection| {
|
||||
std.debug.print("{}\n", .{connection});
|
||||
connections: for (output.connections.items) |connection| {
|
||||
const new_idx = self.componentIndex(connection.component).?;
|
||||
// std.debug.print("{}@{d}\n", .{ connection, new_idx });
|
||||
|
||||
// check if component is "ready"
|
||||
// i.e. it hasn't already been added to the process list, but all its inputs have.
|
||||
if (visited[new_idx]) continue :connections;
|
||||
for (connection.component.inputs.items) |input| {
|
||||
if (input.connection) |input_component| {
|
||||
if (!visited[self.componentIndex(input_component).?]) {
|
||||
continue :connections;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// component is ready, continue the DFS down that branch
|
||||
try process_order.append(connection.component);
|
||||
try stack.append(new_idx);
|
||||
visited[new_idx] = true;
|
||||
component_idx = new_idx;
|
||||
continue :dfs;
|
||||
}
|
||||
}
|
||||
|
||||
// for (self.components.items[source_component_idx].outputs.items) |output| {
|
||||
// if (output.connection) |output_to| {
|
||||
// std.debug.print("checking output {?d}\n", .{self.componentIndex(output_to)});
|
||||
// for (output_to.inputs.items) |other_input| {
|
||||
// const other_idx = self.componentIndex(other_input.connection.?).?;
|
||||
// std.debug.print("other_idx is visited: {}\n", .{visited[other_idx]});
|
||||
// if (!visited[other_idx]) {
|
||||
// try process_order.append(self.components.items[other_idx]);
|
||||
// try stack.append(other_idx);
|
||||
// component_idx = other_idx;
|
||||
// std.debug.print("continue with {}\n", .{component_idx});
|
||||
// continue :dfs;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
component_idx = stack.pop() orelse break :dfs;
|
||||
std.debug.print("backtracking to {}\n", .{component_idx});
|
||||
// std.debug.print("backtracking to {}\n", .{component_idx});
|
||||
}
|
||||
}
|
||||
|
||||
std.debug.print("{any}\n", .{visited});
|
||||
// std.debug.print("{any}\n", .{visited});
|
||||
|
||||
if (self.process_order) |p| self.allocator.free(p);
|
||||
self.process_order = try process_order.toOwnedSlice();
|
||||
|
@ -225,63 +226,6 @@ pub const Circuit = struct {
|
|||
}
|
||||
|
||||
const ProcessOrder = []*Component;
|
||||
// pub fn solve(self: *ProcessOrderSolver) ProcessOrder {
|
||||
// for (self.solved) |*s| s.* = false;
|
||||
// for (self.circuit.source_components.items) |source_component| {
|
||||
// var component = source_component;
|
||||
// while (true) {
|
||||
// // component.process();
|
||||
// // std.debug.print("source component {any}\n\n", .{source_component});
|
||||
// const idx = self.componentIndex(component);
|
||||
// self.solved[idx.?] = true;
|
||||
// std.debug.print("{}\n", .{component});
|
||||
// // std.debug.print("{any}\n", .{component.outputs.items});
|
||||
// _ = &component;
|
||||
// // component = component.outputs.items[0].connection.?;
|
||||
// next: for (component.outputs.items) |output| {
|
||||
// if (output.connection) |connection|
|
||||
// if (self.solved[self.componentIndex(connection).?] == false)
|
||||
// if (self.componentReady(connection)) {
|
||||
// component = connection;
|
||||
// } else {
|
||||
// continue :next;
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return &[_]*Component{};
|
||||
// }
|
||||
|
||||
// /// whether a component is ready to be solved
|
||||
// fn componentReady(self: ProcessOrderSolver, component: *Component) bool {
|
||||
// for (component.inputs.items) |input| {
|
||||
// if (input.connection) |c| {
|
||||
// if (self.solved[self.componentIndex(c).?])
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// // TODO this is probably broken
|
||||
// fn componentIndex(self: ProcessOrderSolver, component: *Component) ?usize {
|
||||
// // for (self.circuit.components.items, 0..) |c, i| {
|
||||
// // // std.debug.print("{any} == {any}\n", .{ component, &c });
|
||||
// // std.debug.print("{*} == {*}\n", .{ component, &c });
|
||||
// // // std.debug.print("{s}\n{s}\n{any}\n\n", .{
|
||||
// // // std.fmt.fmtSliceHexLower(std.mem.asBytes(component)),
|
||||
// // // std.fmt.fmtSliceHexLower(std.mem.asBytes(&c)),
|
||||
// // // std.mem.eql(u8, std.mem.asBytes(component), std.mem.asBytes(&c)),
|
||||
// // // });
|
||||
// // // if (std.mem.eql(u8, std.mem.asBytes(component), std.mem.asBytes(&c))) {
|
||||
// // if (component == c) {
|
||||
// // return i;
|
||||
// // }
|
||||
// // }
|
||||
// // return null;
|
||||
// return std.mem.indexOfScalar(*Component, self.circuit.components.items, component);
|
||||
// }
|
||||
// };
|
||||
};
|
||||
|
||||
var null_signal = Signal{};
|
||||
|
@ -296,7 +240,9 @@ pub const Component = struct {
|
|||
deinitFn: *const fn (*Component, std.mem.Allocator) void,
|
||||
|
||||
pub const Input = struct {
|
||||
// TODO just allow this to be null and handle that codepath in a user-configurable way
|
||||
signal: *Signal = &null_signal,
|
||||
// TODO update this to match the Output.Connection interface (without the ArrayList)
|
||||
connection: ?*Component = null,
|
||||
idx: usize = 0,
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue