sound_flow 0.3.0

Execute graphs of functions in real time
Documentation
use sound_flow::{Node, SocketDescription, Sockets};

#[enum_delegate::implement_conversions]
enum Data {
    Number(i64),
}

struct Value(i64);
impl Node for Value {
    type Config = ();
    type Context = ();
    type Data = Data;

    fn sockets(&self, config: &Self::Config) -> SocketDescription<Self::Data> {
        let mut s = SocketDescription::new();
        s.push_output::<i64>();
        s
    }

    fn rt_process(&mut self, _context: &Self::Context, mut sockets: Sockets<Self::Data>) {
        *sockets.output_mut::<i64>(0) = self.0
    }
}

struct Add;
impl Node for Add {
    type Config = ();
    type Context = ();
    type Data = Data;

    fn sockets(&self, config: &Self::Config) -> SocketDescription<Self::Data> {
        let mut s = SocketDescription::new();
        s.push_input::<i64>();
        s.push_input::<i64>();
        s.push_output::<i64>();
        s
    }

    fn rt_process(&mut self, _context: &Self::Context, mut sockets: Sockets<Self::Data>) {
        let a = *sockets.input::<i64>(0);
        let b = *sockets.input::<i64>(1);
        *sockets.output_mut::<i64>(0) = a + b;
    }
}

struct Output(i64);
impl Node for Output {
    type Config = ();
    type Context = ();
    type Data = Data;

    fn sockets(&self, config: &Self::Config) -> SocketDescription<Self::Data> {
        let mut s = SocketDescription::new();
        s.push_input::<i64>();
        s
    }

    fn rt_process(&mut self, _context: &Self::Context, sockets: Sockets<Self::Data>) {
        self.0 = *sockets.input::<i64>(0);
    }
}

#[enum_delegate::implement(Node)]
enum AnyNode {
    Value(Value),
    Add(Add),
    Output(Output),
}

#[cfg(test)]
mod tests {
    use super::*;
    use sound_flow::{Connection, GraphBuilder};

    #[test]
    fn adder_graph() {
        let mut b = GraphBuilder::<u32, AnyNode>::new();

        b.add_node(0, Value(0)).unwrap();
        b.add_connection(Connection {
            from_node: 0,
            from_output_socket: 0,
            to_node: 2,
            to_input_socket: 0,
        });

        b.add_node(1, Value(0)).unwrap();
        b.add_connection(Connection {
            from_node: 1,
            from_output_socket: 0,
            to_node: 2,
            to_input_socket: 1,
        });

        b.add_node(2, Add).unwrap();
        b.add_connection(Connection {
            from_node: 2,
            from_output_socket: 0,
            to_node: 3,
            to_input_socket: 0,
        });

        b.add_node(3, Output(0)).unwrap();

        let mut g = b.build().unwrap();
        let a_index = g.node_index(0).unwrap();
        let b_index = g.node_index(1).unwrap();
        let output_index = g.node_index(3).unwrap();

        let a: &mut Value = g.node_mut(a_index).try_into().unwrap();
        a.0 = 10;
        let b: &mut Value = g.node_mut(b_index).try_into().unwrap();
        b.0 = 20;
        g.rt_compute(&());
        let output: &Output = g.node(output_index).try_into().unwrap();
        assert_eq!(output.0, 30);
    }
}