This commit is contained in:
2026-03-11 21:49:02 +01:00
parent 6d99d54f4a
commit 008a765fe3
4 changed files with 100 additions and 112 deletions

34
Cargo.lock generated
View File

@ -17,9 +17,7 @@ dependencies = [
name = "oxydsp-flowgraph-macros"
version = "0.1.0"
dependencies = [
"proc-macro2",
"quote",
"syn",
"zyn",
]
[[package]]
@ -56,3 +54,33 @@ name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "zyn"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1821d8c02040d27b081b0e3552933622411b5fdd62d3529ee1e693e37084afe"
dependencies = [
"zyn-core",
"zyn-derive",
]
[[package]]
name = "zyn-core"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "718adc314c1f0745d0c54a38226285338a7b800848c49529e282ee41cdbcdb31"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "zyn-derive"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e592b35728519732b11b0b26d4c6feb9756dc1b805fc204a75c4348ef331ff3"
dependencies = [
"zyn-core",
]

View File

@ -7,6 +7,4 @@ edition = "2024"
proc-macro = true
[dependencies]
proc-macro2 = "1.0.106"
quote = "1.0.45"
syn = "2.0.117"
zyn = {version = "0.4.2", features = ["ext"]}

View File

@ -1,124 +1,84 @@
use proc_macro::TokenStream;
use quote::quote;
use syn::{DeriveInput, Fields, Ident, parse_macro_input};
use zyn::ext::AttrExt;
use zyn::ext::FieldsExt;
#[proc_macro_derive(BlockIO, attributes(input, output))]
pub fn derive_block_io(item: TokenStream) -> TokenStream
#[zyn::derive("BlockIO", attributes(input, output))]
pub fn block_io(
#[zyn(input)] ident: zyn::Extract<zyn::syn::Ident>,
#[zyn(input)] generics: zyn::Extract<zyn::syn::Generics>,
#[zyn(input)] fields: zyn::Fields,
) -> zyn::TokenStream
{
let input = parse_macro_input!(item as DeriveInput);
let inputs;
let outputs;
match input.data
{
syn::Data::Struct(data_struct) =>
let (impl_generics, type_generics, where_clause) = generics.split_for_impl();
zyn::zyn!(
impl {{impl_generics}} oxydsp_flowgraph::block::BlockIO for {{ ident.inner() }} {{ type_generics }}
where {{ where_clause }}
{
inputs = derive_block_get_marked_idents(&data_struct.fields, "input");
outputs = derive_block_get_marked_idents(&data_struct.fields, "output");
@block_io_set_index(fields = fields.clone())
@block_io_get_successors(fields = fields.clone())
@block_io_counts(fields = fields.clone())
}
syn::Data::Enum(_) | syn::Data::Union(_) => unimplemented!("Enum/Unions not supported"),
}
let struct_name = input.ident;
let func_set_index = derive_block_set_index(&inputs, &outputs);
let func_get_successors = derive_block_get_successors(&outputs);
let (impl_generics, type_generics, where_clause) = input.generics.split_for_impl();
quote! {
impl #impl_generics oxydsp_flowgraph::block::BlockIO for #struct_name #type_generics
#where_clause
{
#func_set_index
#func_get_successors
}
}
.into()
)
}
fn derive_block_get_successors(outputs: &Vec<Ident>) -> proc_macro2::TokenStream
#[zyn::element]
fn block_io_set_index(fields: zyn::syn::Fields) -> zyn::TokenStream
{
quote! {
fn get_successors(&self) -> Vec<oxydsp_flowgraph::edge::BlockIOIndex>
let fields = fields.as_named().unwrap().named.clone();
zyn::zyn!(
fn set_index(&self, block_index: usize)
{
let mut successors = Vec::new();
#(
if let Some(next) = self.#outputs.get_consumer_block()
{
successors.push(next);
}
)*
successors
use oxydsp_flowgraph::edge::BlockIOIndex;
@for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("input"))).enumerate())
{
self.{{field.1.ident}}.set_block_index(BlockIOIndex {block_index, port_index: {{ field.0 }} });
}
@for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("output"))).enumerate())
{
self.{{field.1.ident}}.set_block_index(BlockIOIndex {block_index, port_index: {{ field.0 }} });
}
}
}
)
}
fn derive_block_io_count(inputs: &Vec<Ident>, outputs: &Vec<Ident>) -> proc_macro2::TokenStream
#[zyn::element]
fn block_io_get_successors(fields: zyn::syn::Fields) -> zyn::TokenStream
{
let input_count = inputs.len();
let output_count = outputs.len();
quote! {
let fields = fields.as_named().unwrap().named.clone();
zyn::zyn!(
fn get_successors(&self, block_index: usize) -> Vec<oxydsp_flowgraph::edge::BlockIOIndex>
{
let mut output = vec![];
@for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("output"))).enumerate())
{
output.push(self.{{ field.1.ident }}.get_consumer_block());
}
output
}
)
}
#[zyn::element]
fn block_io_counts(fields: zyn::syn::Fields) -> zyn::TokenStream
{
let fields = fields.as_named().unwrap().named.clone();
let input_count = fields
.iter()
.filter(|x| x.attrs.iter().any(|x| x.is("input")))
.count();
let output_count = fields
.iter()
.filter(|x| x.attrs.iter().any(|x| x.is("output")))
.count();
zyn::zyn!(
fn input_count(&self) -> usize
{
#input_count
return { { input_count } };
}
fn output_count(&self) -> usize
{
#output_count
return { { output_count } };
}
}
}
fn derive_block_set_index(inputs: &Vec<Ident>, outputs: &Vec<Ident>) -> proc_macro2::TokenStream
{
quote! {
fn set_index(&self, block_index: usize)
{
use oxydsp_flowgraph::edge::BlockIOIndex;
let mut counter = 0;
#(
self.#inputs.set_block_index(
BlockIOIndex
{
block_index,
port_index: counter,
}
);
counter += 1;
)*
counter = 0;
#(
self.#outputs.set_block_index(
BlockIOIndex
{
block_index,
port_index: counter,
}
);
counter += 1;
)*
}
}
}
fn derive_block_get_marked_idents<S: AsRef<str>>(
fields: &Fields,
required_attribute: S,
) -> Vec<Ident>
{
let mut idents = vec![];
for field in fields
{
'inner: for attribute in field.attrs.iter()
{
if let Some(name) = attribute.meta.path().segments.first()
&& name.ident == required_attribute.as_ref()
{
idents.push(field.ident.clone().unwrap());
break 'inner;
}
}
}
idents
)
}

View File

@ -1,6 +1,8 @@
use std::sync::{Arc, Mutex};
use std::sync::Arc;
use std::sync::Mutex;
use crate::stream::{StreamConsumer, StreamProducer};
use crate::stream::StreamConsumer;
use crate::stream::StreamProducer;
pub struct Edge
{