Initial commit

This commit is contained in:
2026-03-05 23:03:21 +01:00
commit ed9027d12c
14 changed files with 867 additions and 0 deletions

1
ntw_flowgraph/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

172
ntw_flowgraph/Cargo.lock generated Normal file
View File

@ -0,0 +1,172 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "crossbeam-utils"
version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "fixedbitset"
version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99"
[[package]]
name = "foldhash"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "hashbrown"
version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
dependencies = [
"foldhash",
]
[[package]]
name = "hashbrown"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
[[package]]
name = "indexmap"
version = "2.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
dependencies = [
"equivalent",
"hashbrown 0.16.1",
]
[[package]]
name = "ntw_flowgraph"
version = "0.1.0"
dependencies = [
"ntw_flowgraph_macros",
"petgraph",
"ringbuf",
]
[[package]]
name = "ntw_flowgraph_macros"
version = "0.1.0"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "petgraph"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455"
dependencies = [
"fixedbitset",
"hashbrown 0.15.5",
"indexmap",
"serde",
]
[[package]]
name = "portable-atomic"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
[[package]]
name = "portable-atomic-util"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a9db96d7fa8782dd8c15ce32ffe8680bbd1e978a43bf51a34d39483540495f5"
dependencies = [
"portable-atomic",
]
[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [
"proc-macro2",
]
[[package]]
name = "ringbuf"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe47b720588c8702e34b5979cb3271a8b1842c7cb6f57408efa70c779363488c"
dependencies = [
"crossbeam-utils",
"portable-atomic",
"portable-atomic-util",
]
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "syn"
version = "2.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"

9
ntw_flowgraph/Cargo.toml Normal file
View File

@ -0,0 +1,9 @@
[package]
name = "ntw_flowgraph"
version = "0.1.0"
edition = "2024"
[dependencies]
petgraph = "0.8.3"
ringbuf = "0.4.8"
ntw_flowgraph_macros = {path = "../ntw_flowgraph_macros/"}

View File

@ -0,0 +1,86 @@
use petgraph::graph::DiGraph;
use petgraph::graph::NodeIndex;
use crate::Block;
pub struct Graph
{
blocks: Vec<Box<dyn Block>>,
}
impl Graph
{
pub fn new() -> Graph
{
Graph { blocks: vec![] }
}
pub fn add_block(&mut self, block: impl Block + 'static)
{
block.set_block_index(self.blocks.len());
self.blocks.push(Box::new(block));
}
pub fn run(&mut self)
{
// Compute the topo_order
let mut digraph = DiGraph::<(), (), usize>::with_capacity(self.blocks.len(), 1);
for block in self.blocks.iter()
{
let node = digraph.add_node(());
for next in block.get_successors()
{
digraph.add_edge(node, next.into(), ());
}
}
let topo_order = petgraph::algo::toposort(&digraph, None)
.expect("Graph cannot be cylic")
.into_iter()
.map(|x| x.index())
.collect::<Vec<_>>();
// Dumbass round robin
loop
{
let mut one_ready = false;
for x in topo_order.iter()
{
let block = &mut self.blocks[*x];
if block.ready()
{
block.work();
one_ready = true;
}
}
if !one_ready
{
break;
}
}
}
pub fn print_deps(&self)
{
for (i, e) in self.blocks.iter().enumerate()
{
print!("{}: ", i);
for x in e.get_successors()
{
print!("{}, ", x);
}
println!();
}
}
}
impl Default for Graph
{
fn default() -> Self
{
Self::new()
}
}

View File

@ -0,0 +1,65 @@
use ringbuf::HeapRb;
use ringbuf::SharedRb;
use ringbuf::storage::Heap;
use ringbuf::traits::Producer;
use ringbuf::traits::Split;
use ringbuf::wrap::caching::Caching;
use std::cell::Cell;
use std::rc::Rc;
use std::sync::Arc;
// Represent a block input, of which data is popped
pub struct In<T>
{
block: Rc<Cell<Option<usize>>>,
pub rb: Caching<Arc<SharedRb<Heap<T>>>, false, true>,
}
// Represent a block input, in which data is pushed
pub struct Out<T>
{
to: Rc<Cell<Option<usize>>>,
pub rb: Caching<Arc<SharedRb<Heap<T>>>, true, false>,
}
pub struct Stream;
impl Stream
{
pub fn make<T>(length: usize) -> (Out<T>, In<T>)
{
let (prod, cons) = HeapRb::<T>::new(length).split();
let to = Rc::new(Cell::new(None));
(
Out {
to: to.clone(),
rb: prod,
},
In {
block: to.clone(),
rb: cons,
},
)
}
}
impl<T> In<T>
{
pub fn set_index(&self, index: usize)
{
self.block.set(Some(index))
}
}
impl<T> Out<T>
{
pub fn get_successor(&self) -> Option<usize>
{
self.to.get()
}
pub fn try_push(&mut self, data: T) -> Result<(), T>
{
self.rb.try_push(data)
}
}

14
ntw_flowgraph/src/lib.rs Normal file
View File

@ -0,0 +1,14 @@
pub mod graph;
pub mod inout;
pub trait BlockWork
{
fn work(&mut self);
fn ready(&self) -> bool;
}
pub trait Block: BlockWork
{
fn set_block_index(&self, index: usize);
fn get_successors(&self) -> Vec<usize>;
}