misc
This commit is contained in:
parent
8eb7a769b3
commit
579fe85f02
1 changed files with 143 additions and 57 deletions
200
src/main.zig
200
src/main.zig
|
@ -12,7 +12,7 @@ pub fn main() !void {
|
|||
|
||||
var not1 = try circuit.addComponent(Not);
|
||||
not1.invert_output = false;
|
||||
not1.component.inputs.items[0] = &input; // manually set the input here
|
||||
not1.component.inputs.items[0] = .{ .signal = &input }; // manually set the input here
|
||||
|
||||
var battery1 = try circuit.addComponent(Battery);
|
||||
var battery2 = try circuit.addComponent(Battery);
|
||||
|
@ -72,25 +72,40 @@ pub fn main() !void {
|
|||
or7.component.connect(0, &and2.component, 1);
|
||||
and2.component.connect(0, &or2.component, 2);
|
||||
|
||||
battery1.component.process();
|
||||
battery2.component.process();
|
||||
battery3.component.process();
|
||||
not1.component.process();
|
||||
or3.component.process();
|
||||
or6.component.process();
|
||||
and1.component.process();
|
||||
or1.component.process();
|
||||
or4.component.process();
|
||||
or7.component.process();
|
||||
and2.component.process();
|
||||
or2.component.process();
|
||||
or5.component.process();
|
||||
or8.component.process();
|
||||
try circuit.tick();
|
||||
|
||||
std.debug.print("Input:\n{}\n\n", .{input});
|
||||
std.debug.print("{}\n{}\n\n", .{ or1.component.outputs.items[0], or2.component.outputs.items[0] });
|
||||
std.debug.print("{}\n{}\n{}\n\n", .{ or3.component.outputs.items[0], or4.component.outputs.items[0], or5.component.outputs.items[0] });
|
||||
std.debug.print("{}\n{}\n{}\n{}\n{}\n\n", .{ or6.component.outputs.items[0], and1.component.outputs.items[0], or7.component.outputs.items[0], and2.component.outputs.items[0], or8.component.outputs.items[0] });
|
||||
// battery1.component.process();
|
||||
// battery2.component.process();
|
||||
// battery3.component.process();
|
||||
// not1.component.process();
|
||||
// or3.component.process();
|
||||
// or6.component.process();
|
||||
// and1.component.process();
|
||||
// or1.component.process();
|
||||
// or4.component.process();
|
||||
// or7.component.process();
|
||||
// and2.component.process();
|
||||
// or2.component.process();
|
||||
// or5.component.process();
|
||||
// or8.component.process();
|
||||
|
||||
// std.debug.print("Input:\n{}\n\n", .{input});
|
||||
// std.debug.print("{}\n{}\n\n", .{
|
||||
// or1.component.outputs.items[0].signal,
|
||||
// or2.component.outputs.items[0].signal,
|
||||
// });
|
||||
// std.debug.print("{}\n{}\n{}\n\n", .{
|
||||
// or3.component.outputs.items[0].signal,
|
||||
// or4.component.outputs.items[0].signal,
|
||||
// or5.component.outputs.items[0].signal,
|
||||
// });
|
||||
// std.debug.print("{}\n{}\n{}\n{}\n{}\n\n", .{
|
||||
// or6.component.outputs.items[0].signal,
|
||||
// and1.component.outputs.items[0].signal,
|
||||
// or7.component.outputs.items[0].signal,
|
||||
// and2.component.outputs.items[0].signal,
|
||||
// or8.component.outputs.items[0].signal,
|
||||
// });
|
||||
}
|
||||
|
||||
pub const Circuit = struct {
|
||||
|
@ -116,11 +131,61 @@ pub const Circuit = struct {
|
|||
var c = try T.init(self.allocator);
|
||||
errdefer c.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;
|
||||
}
|
||||
|
||||
pub fn tick(self: *Circuit) !void {
|
||||
var process_order_solver = try ProcessOrderSolver.init(self);
|
||||
defer process_order_solver.deinit();
|
||||
const process_order = process_order_solver.solve();
|
||||
_ = process_order;
|
||||
}
|
||||
|
||||
const Components = std.ArrayListUnmanaged(Component);
|
||||
const SourceComponents = std.ArrayListUnmanaged(*Component);
|
||||
|
||||
const ProcessOrder = []*Component;
|
||||
const ProcessOrderSolver = struct {
|
||||
circuit: *Circuit,
|
||||
solved: []bool,
|
||||
|
||||
pub fn init(circuit: *Circuit) !ProcessOrderSolver {
|
||||
return .{
|
||||
.circuit = circuit,
|
||||
.solved = try circuit.allocator.alloc(bool, circuit.components.items.len),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *ProcessOrderSolver) void {
|
||||
self.circuit.allocator.free(self.solved);
|
||||
}
|
||||
|
||||
pub fn solve(self: *ProcessOrderSolver) ProcessOrder {
|
||||
for (self.circuit.source_components.items) |source_component| {
|
||||
var component = source_component;
|
||||
// while (true) blk: {
|
||||
// component.process();
|
||||
self.solved[self.componentIndex(component).?] = true;
|
||||
component = component.outputs.items[0].connection.?;
|
||||
std.debug.print("{any}\n", .{component});
|
||||
// }
|
||||
}
|
||||
return &[_]*Component{};
|
||||
}
|
||||
|
||||
fn componentIndex(self: ProcessOrderSolver, component: *Component) ?usize {
|
||||
for (self.circuit.components.items, 0..) |c, i| {
|
||||
std.debug.print("{any} == {any}\n", .{ component, &c });
|
||||
if (component == &c) {
|
||||
std.debug.print("component index {d}\n", .{i});
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
// return std.mem.indexOfScalar(Component, self.circuit.components.items, component.*);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
var null_signal = Signal{};
|
||||
|
@ -135,12 +200,12 @@ pub const Component = struct {
|
|||
var inputs = Inputs.empty;
|
||||
errdefer inputs.deinit(allocator);
|
||||
try inputs.resize(allocator, inputs_len);
|
||||
for (0..inputs.items.len) |i| inputs.items[i] = &null_signal;
|
||||
for (0..inputs.items.len) |i| inputs.items[i] = .{};
|
||||
|
||||
var outputs = Outputs.empty;
|
||||
errdefer outputs.deinit(allocator);
|
||||
try outputs.resize(allocator, outputs_len);
|
||||
for (0..outputs.items.len) |i| outputs.items[i] = Signal{};
|
||||
for (0..outputs.items.len) |i| outputs.items[i] = .{};
|
||||
|
||||
return .{
|
||||
.inputs = inputs,
|
||||
|
@ -159,32 +224,53 @@ pub const Component = struct {
|
|||
}
|
||||
|
||||
// TODO allow inserting the new elements at an arbitrary index
|
||||
// TODO ensure this won't break the opposide side's connections
|
||||
pub fn setNumInputs(self: *Component, allocator: std.mem.Allocator, new_len: usize) !void {
|
||||
const old_len = self.inputs.items.len;
|
||||
try self.inputs.resize(allocator, new_len);
|
||||
if (new_len > old_len) for (old_len..new_len) |i| {
|
||||
self.inputs.items[i] = &null_signal;
|
||||
self.inputs.items[i] = .{};
|
||||
};
|
||||
}
|
||||
|
||||
// TODO allow inserting the new elements at an arbitrary index
|
||||
// TODO is this allocating the new output Signals on the stack or dumbthing?
|
||||
// TODO ensure this won't break the opposide side's connections
|
||||
pub fn setNumOutputs(self: *Component, allocator: std.mem.Allocator, new_len: usize) !void {
|
||||
const old_len = self.outputs.items.len;
|
||||
try self.outputs.resize(allocator, new_len);
|
||||
if (new_len > old_len) for (old_len..new_len) |i| {
|
||||
self.outputs.items[i] = Signal{};
|
||||
self.outputs.items[i] = .{};
|
||||
};
|
||||
}
|
||||
|
||||
pub fn connect(self: *Component, self_idx: usize, to: *Component, to_idx: usize) void {
|
||||
to.inputs.items[to_idx] = &self.outputs.items[self_idx];
|
||||
to.inputs.items[to_idx] = .{
|
||||
.signal = &self.outputs.items[self_idx].signal,
|
||||
.connection = self,
|
||||
.idx = self_idx,
|
||||
};
|
||||
}
|
||||
|
||||
pub const Input = *Signal;
|
||||
pub const Output = Signal;
|
||||
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);
|
||||
|
||||
// const Connection = struct {
|
||||
// from: *Component,
|
||||
// from_idx: usize,
|
||||
// to: *Component,
|
||||
// to_idx: usize,
|
||||
// };
|
||||
};
|
||||
|
||||
pub const Signal = struct {
|
||||
|
@ -225,8 +311,8 @@ pub const Battery = struct {
|
|||
|
||||
pub fn process(component: *Component) void {
|
||||
const self: *Battery = @fieldParentPtr("component", component);
|
||||
component.outputs.items[0].digital = @intFromFloat(std.math.sign(self.value));
|
||||
component.outputs.items[0].analog = self.value;
|
||||
component.outputs.items[0].signal.digital = @intFromFloat(std.math.sign(self.value));
|
||||
component.outputs.items[0].signal.analog = self.value;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -248,13 +334,13 @@ pub const Not = struct {
|
|||
pub fn process(component: *Component) void {
|
||||
const self: *Not = @fieldParentPtr("component", component);
|
||||
if (self.invert_output) {
|
||||
component.outputs.items[0].digital = 1 - @as(i2, @intCast(@abs(component.inputs.items[0].digital)));
|
||||
component.outputs.items[0].analog = 1.0 - @abs(component.inputs.items[0].analog);
|
||||
component.outputs.items[0].signal.digital = 1 - @as(i2, @intCast(@abs(component.inputs.items[0].signal.digital)));
|
||||
component.outputs.items[0].signal.analog = 1.0 - @abs(component.inputs.items[0].signal.analog);
|
||||
} else {
|
||||
component.outputs.items[0].digital = component.inputs.items[0].digital;
|
||||
component.outputs.items[0].analog = component.inputs.items[0].analog;
|
||||
component.outputs.items[0].signal.digital = component.inputs.items[0].signal.digital;
|
||||
component.outputs.items[0].signal.analog = component.inputs.items[0].signal.analog;
|
||||
}
|
||||
component.outputs.items[0].analog = std.math.clamp(component.outputs.items[0].analog, -1.0, 1.0);
|
||||
component.outputs.items[0].signal.analog = std.math.clamp(component.outputs.items[0].signal.analog, -1.0, 1.0);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -279,25 +365,25 @@ pub const And = struct {
|
|||
pub fn process(component: *Component) void {
|
||||
const self: *And = @fieldParentPtr("component", component);
|
||||
if (self.arithmetic_mode) {
|
||||
component.outputs.items[0].digital = component.inputs.items[0].digital;
|
||||
component.outputs.items[0].analog = component.inputs.items[0].analog;
|
||||
component.outputs.items[0].signal.digital = component.inputs.items[0].signal.digital;
|
||||
component.outputs.items[0].signal.analog = component.inputs.items[0].signal.analog;
|
||||
for (component.inputs.items[1..]) |input| {
|
||||
component.outputs.items[0].digital = 0; // TODO
|
||||
component.outputs.items[0].analog *= input.analog;
|
||||
component.outputs.items[0].signal.digital = 0; // TODO
|
||||
component.outputs.items[0].signal.analog *= input.signal.analog;
|
||||
}
|
||||
} else {
|
||||
component.outputs.items[0].digital = component.inputs.items[0].digital;
|
||||
component.outputs.items[0].analog = component.inputs.items[0].analog;
|
||||
component.outputs.items[0].signal.digital = component.inputs.items[0].signal.digital;
|
||||
component.outputs.items[0].signal.analog = component.inputs.items[0].signal.analog;
|
||||
for (component.inputs.items[1..]) |input| {
|
||||
component.outputs.items[0].digital = 0; // TODO
|
||||
component.outputs.items[0].analog = switch (std.math.order(@abs(component.outputs.items[0].analog), @abs(input.analog))) {
|
||||
.lt => component.outputs.items[0].analog,
|
||||
.eq => @min(component.outputs.items[0].analog, input.analog), // TODO what does this *actually* do?
|
||||
.gt => input.analog,
|
||||
component.outputs.items[0].signal.digital = 0; // TODO
|
||||
component.outputs.items[0].signal.analog = switch (std.math.order(@abs(component.outputs.items[0].signal.analog), @abs(input.signal.analog))) {
|
||||
.lt => component.outputs.items[0].signal.analog,
|
||||
.eq => @min(component.outputs.items[0].signal.analog, input.signal.analog), // TODO what does this *actually* do?
|
||||
.gt => input.signal.analog,
|
||||
};
|
||||
}
|
||||
}
|
||||
component.outputs.items[0].analog = std.math.clamp(component.outputs.items[0].analog, -1.0, 1.0);
|
||||
component.outputs.items[0].signal.analog = std.math.clamp(component.outputs.items[0].signal.analog, -1.0, 1.0);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -339,25 +425,25 @@ pub const Or = struct {
|
|||
pub fn process(component: *Component) void {
|
||||
const self: *Or = @fieldParentPtr("component", component);
|
||||
if (self.arithmetic_mode) {
|
||||
component.outputs.items[0].digital = component.inputs.items[0].digital;
|
||||
component.outputs.items[0].analog = component.inputs.items[0].analog;
|
||||
component.outputs.items[0].signal.digital = component.inputs.items[0].signal.digital;
|
||||
component.outputs.items[0].signal.analog = component.inputs.items[0].signal.analog;
|
||||
for (component.inputs.items[1..]) |input| {
|
||||
component.outputs.items[0].digital = 0; // TODO
|
||||
component.outputs.items[0].analog += input.analog;
|
||||
component.outputs.items[0].signal.digital = 0; // TODO
|
||||
component.outputs.items[0].signal.analog += input.signal.analog;
|
||||
}
|
||||
} else {
|
||||
component.outputs.items[0].digital = component.inputs.items[0].digital;
|
||||
component.outputs.items[0].analog = component.inputs.items[0].analog;
|
||||
component.outputs.items[0].signal.digital = component.inputs.items[0].signal.digital;
|
||||
component.outputs.items[0].signal.analog = component.inputs.items[0].signal.analog;
|
||||
for (component.inputs.items[1..]) |input| {
|
||||
component.outputs.items[0].digital = 0; // TODO
|
||||
component.outputs.items[0].analog = switch (std.math.order(@abs(component.outputs.items[0].analog), @abs(input.analog))) {
|
||||
.lt => input.analog,
|
||||
.eq => @max(component.outputs.items[0].analog, input.analog), // TODO what does this *actually* do?
|
||||
.gt => component.outputs.items[0].analog,
|
||||
component.outputs.items[0].signal.digital = 0; // TODO
|
||||
component.outputs.items[0].signal.analog = switch (std.math.order(@abs(component.outputs.items[0].signal.analog), @abs(input.signal.analog))) {
|
||||
.lt => input.signal.analog,
|
||||
.eq => @max(component.outputs.items[0].signal.analog, input.signal.analog), // TODO what does this *actually* do?
|
||||
.gt => component.outputs.items[0].signal.analog,
|
||||
};
|
||||
}
|
||||
}
|
||||
component.outputs.items[0].analog = std.math.clamp(component.outputs.items[0].analog, -1.0, 1.0);
|
||||
component.outputs.items[0].signal.analog = std.math.clamp(component.outputs.items[0].signal.analog, -1.0, 1.0);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue