Initial commit
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
||||
181
Cargo.lock
generated
Normal file
181
Cargo.lock
generated
Normal file
@ -0,0 +1,181 @@
|
||||
# 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"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ntw_flowgraph",
|
||||
"ntw_flowgraph_macros",
|
||||
"ringbuf",
|
||||
]
|
||||
|
||||
[[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
Cargo.toml
Normal file
9
Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "ntw"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
ntw_flowgraph = {path = "ntw_flowgraph"}
|
||||
ntw_flowgraph_macros = {path = "ntw_flowgraph_macros"}
|
||||
ringbuf = "0.4.8"
|
||||
1
ntw_flowgraph/.gitignore
vendored
Normal file
1
ntw_flowgraph/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
||||
172
ntw_flowgraph/Cargo.lock
generated
Normal file
172
ntw_flowgraph/Cargo.lock
generated
Normal 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
9
ntw_flowgraph/Cargo.toml
Normal 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/"}
|
||||
86
ntw_flowgraph/src/graph.rs
Normal file
86
ntw_flowgraph/src/graph.rs
Normal 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()
|
||||
}
|
||||
}
|
||||
65
ntw_flowgraph/src/inout.rs
Normal file
65
ntw_flowgraph/src/inout.rs
Normal 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
14
ntw_flowgraph/src/lib.rs
Normal 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>;
|
||||
}
|
||||
1
ntw_flowgraph_macros/.gitignore
vendored
Normal file
1
ntw_flowgraph_macros/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
||||
47
ntw_flowgraph_macros/Cargo.lock
generated
Normal file
47
ntw_flowgraph_macros/Cargo.lock
generated
Normal file
@ -0,0 +1,47 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[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 = "streams_macros"
|
||||
version = "0.1.0"
|
||||
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"
|
||||
12
ntw_flowgraph_macros/Cargo.toml
Normal file
12
ntw_flowgraph_macros/Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "ntw_flowgraph_macros"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1.0.106"
|
||||
quote = "1.0.45"
|
||||
syn = {version = "2.0.117", features = ["extra-traits"]}
|
||||
126
ntw_flowgraph_macros/src/lib.rs
Normal file
126
ntw_flowgraph_macros/src/lib.rs
Normal file
@ -0,0 +1,126 @@
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::DeriveInput;
|
||||
use syn::Ident;
|
||||
use syn::parse_macro_input;
|
||||
|
||||
struct BlockDerive
|
||||
{
|
||||
input_fields: Vec<Ident>,
|
||||
output_fields: Vec<Ident>,
|
||||
}
|
||||
|
||||
fn set_block_index_func(ctx: &BlockDerive) -> proc_macro2::TokenStream
|
||||
{
|
||||
let inputs = ctx.input_fields.clone();
|
||||
quote! {
|
||||
fn set_block_index(&self, index: usize)
|
||||
{
|
||||
#({
|
||||
self.#inputs.set_index(index);
|
||||
})*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_successors_func(ctx: &BlockDerive) -> proc_macro2::TokenStream
|
||||
{
|
||||
let outputs = ctx.output_fields.clone();
|
||||
quote! {
|
||||
fn get_successors(&self) -> Vec<usize>
|
||||
{
|
||||
let mut output = vec![];
|
||||
#(
|
||||
match self.#outputs.get_successor()
|
||||
{
|
||||
None => {},
|
||||
Some(x) => output.push(x)
|
||||
}
|
||||
)*
|
||||
|
||||
output
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[proc_macro_derive(Block, attributes(input, output))]
|
||||
pub fn block_derive(item: TokenStream) -> TokenStream
|
||||
{
|
||||
let cloned = item.clone();
|
||||
let input = parse_macro_input!(cloned as DeriveInput);
|
||||
|
||||
let data_struct = match input.data
|
||||
{
|
||||
syn::Data::Struct(data_struct) => data_struct,
|
||||
syn::Data::Enum(_) | syn::Data::Union(_) => panic!(),
|
||||
};
|
||||
|
||||
let struct_fields = match data_struct.fields
|
||||
{
|
||||
syn::Fields::Named(fields_named) => fields_named,
|
||||
syn::Fields::Unnamed(_) | syn::Fields::Unit => panic!(),
|
||||
};
|
||||
|
||||
let input_fields = struct_fields
|
||||
.named
|
||||
.iter()
|
||||
.filter_map(|f| {
|
||||
if f.ident.is_some()
|
||||
&& f.attrs.iter().any(|attr| {
|
||||
attr.meta
|
||||
.path()
|
||||
.segments
|
||||
.last()
|
||||
.is_some_and(|s| s.ident == "input")
|
||||
})
|
||||
{
|
||||
Some(f.ident.clone().unwrap())
|
||||
}
|
||||
else
|
||||
{
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let output_fields = struct_fields
|
||||
.named
|
||||
.iter()
|
||||
.filter_map(|f| {
|
||||
if f.ident.is_some()
|
||||
&& f.attrs.iter().any(|attr| {
|
||||
attr.meta
|
||||
.path()
|
||||
.segments
|
||||
.last()
|
||||
.is_some_and(|s| s.ident == "output")
|
||||
})
|
||||
{
|
||||
Some(f.ident.clone().unwrap())
|
||||
}
|
||||
else
|
||||
{
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let derive = BlockDerive {
|
||||
input_fields,
|
||||
output_fields,
|
||||
};
|
||||
|
||||
let set_index_func = set_block_index_func(&derive);
|
||||
let get_successors_func = get_successors_func(&derive);
|
||||
let struct_path = input.ident;
|
||||
|
||||
//item
|
||||
quote! {
|
||||
impl Block for #struct_path
|
||||
{
|
||||
#set_index_func
|
||||
#get_successors_func
|
||||
}
|
||||
}
|
||||
.into()
|
||||
}
|
||||
143
src/main.rs
Normal file
143
src/main.rs
Normal file
@ -0,0 +1,143 @@
|
||||
use ntw_flowgraph::Block;
|
||||
use ntw_flowgraph::BlockWork;
|
||||
use ntw_flowgraph::graph::Graph;
|
||||
use ntw_flowgraph::inout::In;
|
||||
use ntw_flowgraph::inout::Out;
|
||||
use ntw_flowgraph::inout::Stream;
|
||||
use ntw_flowgraph_macros::Block;
|
||||
use ringbuf::traits::Consumer;
|
||||
use ringbuf::traits::Observer;
|
||||
use ringbuf::traits::Producer;
|
||||
|
||||
#[derive(Block)]
|
||||
pub struct VecSource
|
||||
{
|
||||
vector: Vec<u32>,
|
||||
|
||||
#[output]
|
||||
out: Out<u32>,
|
||||
}
|
||||
|
||||
impl BlockWork for VecSource
|
||||
{
|
||||
fn work(&mut self)
|
||||
{
|
||||
while let Some(element) = self.vector.pop()
|
||||
{
|
||||
match self.out.rb.try_push(element)
|
||||
{
|
||||
Ok(()) =>
|
||||
{}
|
||||
Err(x) =>
|
||||
{
|
||||
self.vector.push(x);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn ready(&self) -> bool
|
||||
{
|
||||
self.vector.len() > 0 && self.out.rb.vacant_len() > 0
|
||||
}
|
||||
}
|
||||
|
||||
impl VecSource
|
||||
{
|
||||
pub fn new(vector: Vec<u32>) -> (VecSource, In<u32>)
|
||||
{
|
||||
let (out, stream) = Stream::make(16);
|
||||
(VecSource { vector, out }, stream)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Block)]
|
||||
pub struct Adder
|
||||
{
|
||||
#[input]
|
||||
in_a: In<u32>,
|
||||
|
||||
#[input]
|
||||
in_b: In<u32>,
|
||||
|
||||
#[output]
|
||||
out: Out<u32>,
|
||||
}
|
||||
|
||||
impl BlockWork for Adder
|
||||
{
|
||||
fn work(&mut self)
|
||||
{
|
||||
while let Some(a) = self.in_a.rb.try_pop()
|
||||
&& let Some(b) = self.in_b.rb.try_pop()
|
||||
&& self.out.rb.vacant_len() > 0
|
||||
{
|
||||
let _ = self.out.rb.try_push(a + b);
|
||||
}
|
||||
}
|
||||
|
||||
fn ready(&self) -> bool
|
||||
{
|
||||
self.in_a.rb.occupied_len() > 0
|
||||
&& self.in_b.rb.occupied_len() > 0
|
||||
&& self.out.rb.vacant_len() > 0
|
||||
}
|
||||
}
|
||||
|
||||
impl Adder
|
||||
{
|
||||
pub fn new(in_a: In<u32>, in_b: In<u32>) -> (Adder, In<u32>)
|
||||
{
|
||||
let (out, stream) = Stream::make(16);
|
||||
(Adder { in_a, in_b, out }, stream)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Block)]
|
||||
pub struct PrintSink
|
||||
{
|
||||
#[input]
|
||||
stream: In<u32>,
|
||||
}
|
||||
|
||||
impl BlockWork for PrintSink
|
||||
{
|
||||
fn work(&mut self)
|
||||
{
|
||||
if let Some(x) = self.stream.rb.try_pop()
|
||||
{
|
||||
println!("{x}");
|
||||
}
|
||||
}
|
||||
|
||||
fn ready(&self) -> bool
|
||||
{
|
||||
self.stream.rb.occupied_len() > 0
|
||||
}
|
||||
}
|
||||
|
||||
impl PrintSink
|
||||
{
|
||||
pub fn new(stream: In<u32>) -> PrintSink
|
||||
{
|
||||
PrintSink { stream }
|
||||
}
|
||||
}
|
||||
|
||||
fn main()
|
||||
{
|
||||
let (vector_a, a) = VecSource::new((0..15).collect());
|
||||
let (vector_b, b) = VecSource::new((0..15).collect());
|
||||
let (adder, sum) = Adder::new(a, b);
|
||||
let printer = PrintSink::new(sum);
|
||||
|
||||
let mut graph = Graph::new();
|
||||
|
||||
graph.add_block(printer);
|
||||
graph.add_block(adder);
|
||||
graph.add_block(vector_a);
|
||||
graph.add_block(vector_b);
|
||||
|
||||
graph.run();
|
||||
}
|
||||
Reference in New Issue
Block a user