use crate::{Input, Node, Output, Register};
use num_traits::{Float, FloatConst, One, Zero};
use std::{cmp, ops};
macro_rules! bin_op_node {
($name:tt, $identity:tt, $name_fn:tt, $identity_fn:tt) => {
pub struct $name<L, R>
where
L: ops::$name<R>,
{
left: Input<L>,
right: Input<R>,
result: Output<L::Output>,
}
impl<L, R> Default for $name<L, R>
where
L: ops::$name<R>,
{
fn default() -> Self {
Self {
left: Input::default(),
right: Input::default(),
result: Output::default(),
}
}
}
impl<L, R> $name<L, R>
where
L: ops::$name<R>,
{
pub fn new() -> Self {
Default::default()
}
}
impl<L, R> Node for $name<L, R>
where
L: 'static + Clone + $identity,
R: 'static + Clone + $identity,
L: ops::$name<R>,
<L as ops::$name<R>>::Output: 'static,
{
fn register(&self, r: &mut Register) {
r.input("left", &self.left);
r.input("right", &self.right);
r.output("result", &self.result);
}
fn process(&mut self) {
let left = self.left.get().unwrap_or_else($identity::$identity_fn);
let right = self.right.get().unwrap_or_else($identity::$identity_fn);
self.result.set(ops::$name::$name_fn(left, right))
}
fn reset(&mut self) {}
}
};
}
bin_op_node!(Add, Zero, add, zero);
bin_op_node!(Sub, Zero, sub, zero);
bin_op_node!(Mul, One, mul, one);
bin_op_node!(Div, One, div, one);
pub struct Neg<T: ops::Neg> {
input: Input<T>,
result: Output<T::Output>,
}
impl<T: ops::Neg> Default for Neg<T> {
fn default() -> Self {
Self {
input: Input::default(),
result: Output::default(),
}
}
}
impl<T: ops::Neg> Neg<T> {
pub fn new() -> Self {
Default::default()
}
}
impl<T> Node for Neg<T>
where
T: 'static + Clone + Zero + ops::Neg,
<T as ops::Neg>::Output: 'static,
{
fn register(&self, r: &mut Register) {
r.input("input", &self.input);
r.output("result", &self.result);
}
fn process(&mut self) {
let value = self.input.get().unwrap_or_else(Zero::zero);
self.result.set(ops::Neg::neg(value))
}
fn reset(&mut self) {}
}
macro_rules! bin_op_node_checked {
($name:tt, $identity:tt, $name_fn:tt, $identity_fn:tt) => {
pub struct $name<T> {
left: Input<T>,
right: Input<T>,
result: Output<Option<T>>,
}
impl<T> Default for $name<T> {
fn default() -> Self {
Self {
left: Input::default(),
right: Input::default(),
result: Output::default(),
}
}
}
impl<T> $name<T> {
pub fn new() -> Self {
Self::default()
}
}
impl<T> Node for $name<T>
where
T: 'static + Clone + $identity,
T: num_traits::$name,
{
fn register(&self, r: &mut Register) {
r.input("left", &self.left);
r.input("right", &self.right);
r.output("result", &self.result);
}
fn process(&mut self) {
let left = self.left.get().unwrap_or_else($identity::$identity_fn);
let right = self.right.get().unwrap_or_else($identity::$identity_fn);
self.result.set(num_traits::$name::$name_fn(&left, &right))
}
fn reset(&mut self) {}
}
};
}
bin_op_node_checked!(CheckedAdd, Zero, checked_add, zero);
bin_op_node_checked!(CheckedSub, Zero, checked_sub, zero);
bin_op_node_checked!(CheckedMul, One, checked_mul, one);
bin_op_node_checked!(CheckedDiv, One, checked_div, one);
macro_rules! bin_op_node_wrapping {
($name:tt, $identity:tt, $name_fn:tt, $identity_fn:tt) => {
pub struct $name<T> {
left: Input<T>,
right: Input<T>,
result: Output<T>,
}
impl<T> Default for $name<T> {
fn default() -> Self {
Self {
left: Input::default(),
right: Input::default(),
result: Output::default(),
}
}
}
impl<T> $name<T> {
pub fn new() -> Self {
Self::default()
}
}
impl<T> Node for $name<T>
where
T: 'static + Clone + $identity,
T: num_traits::$name,
{
fn register(&self, r: &mut Register) {
r.input("left", &self.left);
r.input("right", &self.right);
r.output("result", &self.result);
}
fn process(&mut self) {
let left = self.left.get().unwrap_or_else($identity::$identity_fn);
let right = self.right.get().unwrap_or_else($identity::$identity_fn);
self.result.set(num_traits::$name::$name_fn(&left, &right))
}
fn reset(&mut self) {}
}
};
}
bin_op_node_wrapping!(WrappingAdd, Zero, wrapping_add, zero);
bin_op_node_wrapping!(WrappingSub, Zero, wrapping_sub, zero);
bin_op_node_wrapping!(WrappingMul, One, wrapping_mul, one);
bin_op_node_wrapping!(SaturatingAdd, Zero, saturating_add, zero);
bin_op_node_wrapping!(SaturatingSub, Zero, saturating_sub, zero);
bin_op_node_wrapping!(SaturatingMul, One, saturating_mul, one);
pub struct Inv<T: num_traits::Inv> {
input: Input<T>,
result: Output<T::Output>,
}
impl<T: num_traits::Inv> Default for Inv<T> {
fn default() -> Self {
Self {
input: Input::default(),
result: Output::default(),
}
}
}
impl<T: num_traits::Inv> Inv<T> {
pub fn new() -> Self {
Default::default()
}
}
impl<T> Node for Inv<T>
where
T: 'static + Clone + One + num_traits::Inv,
<T as num_traits::Inv>::Output: 'static,
{
fn register(&self, r: &mut Register) {
r.input("input", &self.input);
r.output("result", &self.result);
}
fn process(&mut self) {
let value = self.input.get().unwrap_or_else(One::one);
self.result.set(num_traits::Inv::inv(value))
}
fn reset(&mut self) {}
}
pub struct Oscillator<T, W, F>
where
W: FnMut(F) -> T,
{
waveform: W,
phase: F,
delta_time: Input<F>,
freq: Input<F>,
output: Output<T>,
}
impl<T, W, F> Oscillator<T, W, F>
where
W: FnMut(F) -> T,
{
pub fn with_phase(waveform: W, phase: F) -> Self {
Self {
waveform,
phase,
freq: Input::default(),
delta_time: Input::default(),
output: Output::default(),
}
}
pub fn new(waveform: W) -> Self
where
F: Zero,
{
Self::with_phase(waveform, F::zero())
}
}
impl<F: Float + FloatConst> Oscillator<F, fn(F) -> F, F> {
pub fn sine() -> Self {
Self::new(|f| (f * F::TAU()).sin())
}
pub fn square() -> Self {
Self::new(|f| {
let one = F::one();
if f + f > one {
one
} else {
-one
}
})
}
pub fn reverse_sawtooth() -> Self {
Self::new(|f| f + f - F::one())
}
pub fn sawtooth() -> Self {
Self::new(|f| -f - f + F::one())
}
pub fn triangle() -> Self {
Self::new(|f| {
let one = F::one();
let a = (f + f - one).abs();
(a + a) - one
})
}
}
impl<T, W, F> Node for Oscillator<T, W, F>
where
W: FnMut(F) -> T,
T: 'static,
F: 'static + Clone + ops::Add<Output = F> + ops::Rem<Output = F> + One + Zero,
{
fn register(&self, r: &mut Register) {
r.input("frequency", &self.freq);
r.output("output", &self.output);
}
fn process(&mut self) {
if self.output.is_used() {
self.output.set((self.waveform)(self.phase.clone()));
}
self.phase = (self.phase.clone()
+ self.delta_time.get().unwrap_or(One::one()) * self.freq.get().unwrap_or(One::one()))
% F::one();
}
fn reset(&mut self) {
self.phase = F::zero();
}
}
pub struct Min<T> {
a: Input<T>,
b: Input<T>,
output: Output<T>,
}
impl<T> Default for Min<T> {
fn default() -> Self {
Self {
a: Input::default(),
b: Input::default(),
output: Output::default(),
}
}
}
impl<T> Min<T> {
pub fn new() -> Self {
Self::default()
}
}
impl<T> Node for Min<T>
where
T: 'static + Clone + cmp::Ord,
{
fn register(&self, r: &mut Register) {
r.input("a", &self.a);
r.input("b", &self.b);
r.output("output", &self.output);
}
fn process(&mut self) {
if let Some(a) = self.a.get() {
if let Some(b) = self.b.get() {
self.output.set(Ord::min(a, b))
} else {
self.output.set(a);
}
} else {
if let Some(b) = self.b.get() {
self.output.set(b);
} else {
self.output.set(None);
}
};
}
fn reset(&mut self) {}
}
pub struct Max<T> {
a: Input<T>,
b: Input<T>,
output: Output<T>,
}
impl<T> Default for Max<T> {
fn default() -> Self {
Self {
a: Input::default(),
b: Input::default(),
output: Output::default(),
}
}
}
impl<T> Max<T> {
pub fn new() -> Self {
Self::default()
}
}
impl<T> Node for Max<T>
where
T: 'static + Clone + cmp::Ord,
{
fn register(&self, r: &mut Register) {
r.input("a", &self.a);
r.input("b", &self.b);
r.output("output", &self.output);
}
fn process(&mut self) {
if let Some(a) = self.a.get() {
if let Some(b) = self.b.get() {
self.output.set(Ord::max(a, b))
} else {
self.output.set(a);
}
} else {
if let Some(b) = self.b.get() {
self.output.set(b);
} else {
self.output.set(None);
}
};
}
fn reset(&mut self) {}
}
pub struct Clamp<T> {
min: Input<T>,
max: Input<T>,
input: Input<T>,
output: Output<T>,
}
impl<T> Default for Clamp<T> {
fn default() -> Self {
Self {
min: Input::default(),
max: Input::default(),
input: Input::default(),
output: Output::default(),
}
}
}
impl<T> Clamp<T> {
pub fn new() -> Self {
Self::default()
}
}
impl<T> Node for Clamp<T>
where
T: 'static + Clone + cmp::Ord,
{
fn register(&self, r: &mut Register) {
r.input("min", &self.min);
r.input("max", &self.max);
r.input("input", &self.input);
r.output("output", &self.output);
}
fn process(&mut self) {
let max = self.max.get();
let min = self.min.get();
let val = self.input.get();
if let Some(val) = val {
if let Some(max) = max {
if let Some(min) = min {
if val < min {
self.output.set(min);
} else if val > max {
self.output.set(max);
} else {
self.output.set(val);
}
} else {
if val > max {
self.output.set(max);
} else {
self.output.set(val);
}
}
} else {
if let Some(min) = min {
if val < min {
self.output.set(min);
} else {
self.output.set(val);
}
}
}
} else {
self.output.set(None);
}
}
fn reset(&mut self) {}
}