finish some TODOs
This commit is contained in:
parent
4e7c8a8989
commit
49a0f86e44
1 changed files with 72 additions and 59 deletions
131
src/main.zig
131
src/main.zig
|
@ -198,8 +198,8 @@ pub const Circuit = struct {
|
||||||
// i.e. it hasn't already been added to the process list, but all its inputs have.
|
// i.e. it hasn't already been added to the process list, but all its inputs have.
|
||||||
if (visited[new_idx]) continue :connections;
|
if (visited[new_idx]) continue :connections;
|
||||||
for (connection.component.inputs.items) |input| {
|
for (connection.component.inputs.items) |input| {
|
||||||
if (input.connection) |input_component| {
|
if (input.connection) |input_connection| {
|
||||||
if (!visited[self.componentIndex(input_component).?]) {
|
if (!visited[self.componentIndex(input_connection.component).?]) {
|
||||||
continue :connections;
|
continue :connections;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,11 +245,13 @@ pub const Component = struct {
|
||||||
deinitFn: *const fn (*Component, std.mem.Allocator) void,
|
deinitFn: *const fn (*Component, std.mem.Allocator) void,
|
||||||
|
|
||||||
pub const Input = struct {
|
pub const Input = struct {
|
||||||
// TODO just allow this to be null and handle that codepath in a user-configurable way
|
signal: ?*Signal = null,
|
||||||
signal: *Signal = &null_signal,
|
connection: ?Connection = null,
|
||||||
// TODO update this to match the Output.Connection interface (without the ArrayList)
|
|
||||||
connection: ?*Component = null,
|
pub const Connection = struct {
|
||||||
idx: usize = 0,
|
component: *Component,
|
||||||
|
idx: usize,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
pub const Output = struct {
|
pub const Output = struct {
|
||||||
signal: Signal = .{},
|
signal: Signal = .{},
|
||||||
|
@ -325,8 +327,10 @@ pub const Component = struct {
|
||||||
fn connect(self: *Component, allocator: std.mem.Allocator, self_idx: usize, to: *Component, to_idx: usize) !void {
|
fn connect(self: *Component, allocator: std.mem.Allocator, self_idx: usize, to: *Component, to_idx: usize) !void {
|
||||||
const input = &to.inputs.items[to_idx];
|
const input = &to.inputs.items[to_idx];
|
||||||
input.signal = &self.outputs.items[self_idx].signal;
|
input.signal = &self.outputs.items[self_idx].signal;
|
||||||
input.connection = self;
|
input.connection = .{
|
||||||
input.idx = self_idx;
|
.component = self,
|
||||||
|
.idx = self_idx,
|
||||||
|
};
|
||||||
|
|
||||||
const output = &self.outputs.items[self_idx];
|
const output = &self.outputs.items[self_idx];
|
||||||
try output.connections.append(allocator, .{
|
try output.connections.append(allocator, .{
|
||||||
|
@ -445,12 +449,13 @@ pub const Not = struct {
|
||||||
|
|
||||||
pub fn process(component: *Component) AllocatorError!void {
|
pub fn process(component: *Component) AllocatorError!void {
|
||||||
const self: *Not = @fieldParentPtr("component", component);
|
const self: *Not = @fieldParentPtr("component", component);
|
||||||
|
const input = if (component.inputs.items[0].signal) |s| s else &Signal{};
|
||||||
if (self.invert_output) {
|
if (self.invert_output) {
|
||||||
component.outputs.items[0].signal.digital = 1 - @as(i2, @intCast(@abs(component.inputs.items[0].signal.digital)));
|
component.outputs.items[0].signal.digital = 1 - @as(i2, @intCast(@abs(input.digital)));
|
||||||
component.outputs.items[0].signal.analog = 1.0 - @abs(component.inputs.items[0].signal.analog);
|
component.outputs.items[0].signal.analog = 1.0 - @abs(input.analog);
|
||||||
} else {
|
} else {
|
||||||
component.outputs.items[0].signal.digital = component.inputs.items[0].signal.digital;
|
component.outputs.items[0].signal.digital = input.digital;
|
||||||
component.outputs.items[0].signal.analog = component.inputs.items[0].signal.analog;
|
component.outputs.items[0].signal.analog = input.analog;
|
||||||
}
|
}
|
||||||
component.outputs.items[0].signal.analog = std.math.clamp(component.outputs.items[0].signal.analog, -1.0, 1.0);
|
component.outputs.items[0].signal.analog = std.math.clamp(component.outputs.items[0].signal.analog, -1.0, 1.0);
|
||||||
}
|
}
|
||||||
|
@ -479,22 +484,25 @@ pub const And = struct {
|
||||||
// TODO check implementation
|
// TODO check implementation
|
||||||
pub fn process(component: *Component) AllocatorError!void {
|
pub fn process(component: *Component) AllocatorError!void {
|
||||||
const self: *And = @fieldParentPtr("component", component);
|
const self: *And = @fieldParentPtr("component", component);
|
||||||
|
const input0 = if (component.inputs.items[0].signal) |s| s else &Signal{};
|
||||||
if (self.arithmetic_mode) {
|
if (self.arithmetic_mode) {
|
||||||
component.outputs.items[0].signal.digital = component.inputs.items[0].signal.digital;
|
component.outputs.items[0].signal.digital = input0.digital;
|
||||||
component.outputs.items[0].signal.analog = component.inputs.items[0].signal.analog;
|
component.outputs.items[0].signal.analog = input0.analog;
|
||||||
for (component.inputs.items[1..]) |input| {
|
for (component.inputs.items[1..]) |opt_input| {
|
||||||
|
const input = if (opt_input.signal) |s| s else &Signal{};
|
||||||
component.outputs.items[0].signal.digital = 0; // TODO
|
component.outputs.items[0].signal.digital = 0; // TODO
|
||||||
component.outputs.items[0].signal.analog *= input.signal.analog;
|
component.outputs.items[0].signal.analog *= input.analog;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
component.outputs.items[0].signal.digital = component.inputs.items[0].signal.digital;
|
component.outputs.items[0].signal.digital = input0.digital;
|
||||||
component.outputs.items[0].signal.analog = component.inputs.items[0].signal.analog;
|
component.outputs.items[0].signal.analog = input0.analog;
|
||||||
for (component.inputs.items[1..]) |input| {
|
for (component.inputs.items[1..]) |opt_input| {
|
||||||
|
const input = if (opt_input.signal) |s| s else &Signal{};
|
||||||
component.outputs.items[0].signal.digital = 0; // TODO
|
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))) {
|
component.outputs.items[0].signal.analog = switch (std.math.order(@abs(component.outputs.items[0].signal.analog), @abs(input.analog))) {
|
||||||
.lt => component.outputs.items[0].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?
|
.eq => @min(component.outputs.items[0].signal.analog, input.analog), // TODO what does this *actually* do?
|
||||||
.gt => input.signal.analog,
|
.gt => input.analog,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -502,22 +510,23 @@ pub const And = struct {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO update test to use new Component interface
|
test "min" {
|
||||||
// test "min" {
|
var a = Signal{ .analog = 0.0 };
|
||||||
// var a = Signal{ .analog = 0.0 };
|
var b = Signal{ .analog = 1.0 };
|
||||||
// var b = Signal{ .analog = 1.0 };
|
|
||||||
|
|
||||||
// var inputs = [_]*Signal{ &a, &b };
|
var and1 = try And.init(std.testing.allocator);
|
||||||
// var and1 = And{ .inputs = &inputs };
|
defer and1.component.deinit(std.testing.allocator);
|
||||||
|
and1.component.inputs.items[0].signal = &a;
|
||||||
|
and1.component.inputs.items[1].signal = &b;
|
||||||
|
|
||||||
// and1.process();
|
try and1.component.process();
|
||||||
// try std.testing.expectEqual(0.0, and1.output.analog);
|
try std.testing.expectEqual(0.0, and1.component.outputs.items[0].signal.analog);
|
||||||
|
|
||||||
// a.analog = -0.5;
|
a.analog = -0.5;
|
||||||
// b.analog = -0.2;
|
b.analog = -0.2;
|
||||||
// and1.process();
|
try and1.component.process();
|
||||||
// try std.testing.expectEqual(-0.2, and1.output.analog);
|
try std.testing.expectEqual(-0.2, and1.component.outputs.items[0].signal.analog);
|
||||||
// }
|
}
|
||||||
|
|
||||||
pub const Or = struct {
|
pub const Or = struct {
|
||||||
component: Component,
|
component: Component,
|
||||||
|
@ -542,21 +551,24 @@ pub const Or = struct {
|
||||||
// TODO check implementation
|
// TODO check implementation
|
||||||
pub fn process(component: *Component) AllocatorError!void {
|
pub fn process(component: *Component) AllocatorError!void {
|
||||||
const self: *Or = @fieldParentPtr("component", component);
|
const self: *Or = @fieldParentPtr("component", component);
|
||||||
|
const input0 = if (component.inputs.items[0].signal) |s| s else &Signal{};
|
||||||
if (self.arithmetic_mode) {
|
if (self.arithmetic_mode) {
|
||||||
component.outputs.items[0].signal.digital = component.inputs.items[0].signal.digital;
|
component.outputs.items[0].signal.digital = input0.digital;
|
||||||
component.outputs.items[0].signal.analog = component.inputs.items[0].signal.analog;
|
component.outputs.items[0].signal.analog = input0.analog;
|
||||||
for (component.inputs.items[1..]) |input| {
|
for (component.inputs.items[1..]) |opt_input| {
|
||||||
|
const input = if (opt_input.signal) |s| s else &Signal{};
|
||||||
component.outputs.items[0].signal.digital = 0; // TODO
|
component.outputs.items[0].signal.digital = 0; // TODO
|
||||||
component.outputs.items[0].signal.analog += input.signal.analog;
|
component.outputs.items[0].signal.analog += input.analog;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
component.outputs.items[0].signal.digital = component.inputs.items[0].signal.digital;
|
component.outputs.items[0].signal.digital = input0.digital;
|
||||||
component.outputs.items[0].signal.analog = component.inputs.items[0].signal.analog;
|
component.outputs.items[0].signal.analog = input0.analog;
|
||||||
for (component.inputs.items[1..]) |input| {
|
for (component.inputs.items[1..]) |opt_input| {
|
||||||
|
const input = if (opt_input.signal) |s| s else &Signal{};
|
||||||
component.outputs.items[0].signal.digital = 0; // TODO
|
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))) {
|
component.outputs.items[0].signal.analog = switch (std.math.order(@abs(component.outputs.items[0].signal.analog), @abs(input.analog))) {
|
||||||
.lt => input.signal.analog,
|
.lt => input.analog,
|
||||||
.eq => @max(component.outputs.items[0].signal.analog, input.signal.analog), // TODO what does this *actually* do?
|
.eq => @max(component.outputs.items[0].signal.analog, input.analog), // TODO what does this *actually* do?
|
||||||
.gt => component.outputs.items[0].signal.analog,
|
.gt => component.outputs.items[0].signal.analog,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -565,21 +577,22 @@ pub const Or = struct {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO update test to use new Component interface
|
test "max" {
|
||||||
// test "max" {
|
var a = Signal{ .analog = 0.0 };
|
||||||
// var a = Signal{ .analog = 0.0 };
|
var b = Signal{ .analog = 1.0 };
|
||||||
// var b = Signal{ .analog = 1.0 };
|
|
||||||
|
|
||||||
// var inputs = [_]*Signal{ &a, &b };
|
var or1 = try Or.init(std.testing.allocator);
|
||||||
// var or1 = Or{ .inputs = &inputs };
|
defer or1.component.deinit(std.testing.allocator);
|
||||||
|
or1.component.inputs.items[0].signal = &a;
|
||||||
|
or1.component.inputs.items[1].signal = &b;
|
||||||
|
|
||||||
// or1.process();
|
try or1.component.process();
|
||||||
// try std.testing.expectEqual(1.0, or1.output.analog);
|
try std.testing.expectEqual(1.0, or1.component.outputs.items[0].signal.analog);
|
||||||
|
|
||||||
// a.analog = -0.5;
|
a.analog = -0.5;
|
||||||
// b.analog = -0.2;
|
b.analog = -0.2;
|
||||||
// or1.process();
|
try or1.component.process();
|
||||||
// try std.testing.expectEqual(-0.5, or1.output.analog);
|
try std.testing.expectEqual(-0.5, or1.component.outputs.items[0].signal.analog);
|
||||||
// }
|
}
|
||||||
|
|
||||||
const AllocatorError = std.mem.Allocator.Error;
|
const AllocatorError = std.mem.Allocator.Error;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue