| crates |
Make the graph own the nodes so that Node::tick can take &mut self
|
|
| examples/audio-loopback |
Make the graph own the nodes so that Node::tick can take &mut self
|
|
| .gitignore | Initial commit | |
| AGENTS.md | Initial commit | |
| Cargo.lock | Initial commit | |
| Cargo.toml | Initial commit | |
| mise.toml | Initial commit | |
| README.md |
Make the graph own the nodes so that Node::tick can take &mut self
|
|
| rustfmt.toml | Initial commit | |
| tombi.toml | Initial commit | |
Rhenus
Rust library for graph processing pipelines.
Usage
Define a node by implementing the Node trait and registering its ports:
userhenus_core::graph::node::Node;userhenus_core::graph::node::NodeRegistrationContext;userhenus_core::graph::ports::{AllocatingProducerPort,BorrowingConsumerPort,NodeIO};#[derive(Clone)]struct MyNodePorts{input: BorrowingConsumerPort<f32>,output: AllocatingProducerPort<f32>,}struct MyNode{ports: MyNodePorts,}implMyNode{pubfn register(ctx: &mutNodeRegistrationContext)-> (MyNode,MyNodePorts){letports=MyNodePorts{input: ctx.register_borrowing_consumer_port("input"),output: ctx.register_allocating_producer_port("output"),};(MyNode{ports: ports.clone()},ports)}}implNodeforMyNode{fn tick(&self,io: &mutNodeIO){letvalue=io.consume_borrowing(&self.ports.input);io.produce_allocating(&self.ports.output,value*2.0);}}Build a graph and run it:
letmutbuilder=GraphBuilder::new();letmy_ports=builder.register_node_with("my_node",MyNode::register)?;letinput_port=builder.register_external_producer_port::<f32>("input");letoutput_port=builder.register_external_consumer_port::<f32>("output");builder.connect(&input_port,&my_ports.input)?;builder.connect(&my_ports.output,&output_port)?;letgraph=builder.build()?;foriin0..10{letmutresult=0.0_f32;graph.run(|io|{io.produce_unmanaged(&input_port,iasf32);io.consume_unmanaged(&output_port,&mutresult);});println!("Input: {i}, Output: {result}");}See examples/audio-loopback for a complete example.
There are multiple port types:
-
allocating producer: receives nothing, returns owned data
-
borrowing producer: receives mutable reference to data, returns nothing
-
unmanaged producer: receives nothing, returns immutable reference to data
-
borrowing consumer: provides nothing, receives immutable reference to data
-
owning consumer: provides nothing, receives data (taking ownership)
-
unmanaged consumer: provides mutable reference to data, receives nothing (because it has a mutable reference already)
-
processor: receives mutable reference to data, returns nothing, counts as both producer and consumer at the same time
The constructed graph must not contain cycles. Each port must be connected to exactly one other port.
Code Style
Many issues are automatically fixed by rustfmt. These following rules need to be upheld manually, though:
- Put
modstatements at the start of the file, before anyusestatements. Separate those two groups by an empty line. - When importing items from child modules or re-exporting module items using
pub use, make sure to prefix the import path withself::. Otherwise, rustfmt will put the statement into the wrong group.