From 520d97726f5ec607aecc5c97c14a2d488b8d8a6f Mon Sep 17 00:00:00 2001 From: Albin Chaboissier Date: Mon, 16 Mar 2026 09:16:33 +0100 Subject: [PATCH] Reverting tuple/arrays macros --- example/src/main.rs | 18 +- .../oxydsp-flowgraph-macros/src/block_io.rs | 279 ------------------ .../oxydsp-flowgraph-macros/src/lib.rs | 202 ++++++++++++- 3 files changed, 203 insertions(+), 296 deletions(-) delete mode 100644 oxydsp-flowgraph/oxydsp-flowgraph-macros/src/block_io.rs diff --git a/example/src/main.rs b/example/src/main.rs index 5db951e..dbfd3d1 100644 --- a/example/src/main.rs +++ b/example/src/main.rs @@ -8,17 +8,15 @@ use oxydsp_flowgraph::BlockIO; use oxydsp_flowgraph::block::Block; use oxydsp_flowgraph::block::BlockResult; use oxydsp_flowgraph::edge::In; -use oxydsp_flowgraph::edge::PopIter; use oxydsp_flowgraph::edge::PopIterable; use oxydsp_flowgraph::flowgraph; use oxydsp_flowgraph::graph::FlowGraph; -use oxydsp_flowgraph::stream::StreamReader; -//#[derive(BlockIO)] +#[derive(BlockIO)] pub struct Printer { - //#[input] - input: [In; 3], + #[input] + input: In, n: usize, } @@ -27,8 +25,7 @@ impl Printer { pub fn new(input: In) -> Self { - todo!() - //Self { input, n: 0 } + Self { input, n: 0 } } } @@ -38,12 +35,7 @@ where { fn work(&mut self) -> oxydsp_flowgraph::block::BlockResult { - let mut k: Vec<_> = self.input.iter_mut().map(|x| x.read()).collect(); - - k[0].pop(); - k[1].next(); - - for x in self.input[0].pop_iter() + for x in self.input.pop_iter() { if self.n.is_multiple_of(2usize.pow(20)) { diff --git a/oxydsp-flowgraph/oxydsp-flowgraph-macros/src/block_io.rs b/oxydsp-flowgraph/oxydsp-flowgraph-macros/src/block_io.rs deleted file mode 100644 index f8176e3..0000000 --- a/oxydsp-flowgraph/oxydsp-flowgraph-macros/src/block_io.rs +++ /dev/null @@ -1,279 +0,0 @@ -use proc_macro::TokenStream; -use zyn::ToTokens; -use zyn::ext::AttrExt; -use zyn::ext::FieldsExt; -use zyn::syn::Attribute; -use zyn::syn::Index; -use zyn::syn::spanned::Spanned; - -pub enum BlockIOPort -{ - Field(TokenStream), - Array(TokenStream, TokenStream), -} - -pub struct BlockIOPorts -{ - inputs: Vec, - outputs: Vec, -} - -pub fn parse_ports(fields: zyn::syn::Fields, attribute: &str) -> Vec -{ - let mut ports = vec![]; - let fields = fields.as_named().unwrap(); - - for field in fields.named.iter() - { - if field.attrs.iter().any(|attr| attr.is(attribute)) - { - ports.append(&mut parse_port(field.clone())); - } - } - - ports.iter().for_each(|x| match x - { - BlockIOPort::Field(token_stream) => println!("field: {}", token_stream), - BlockIOPort::Array(token_stream, token_stream1) => - { - println!("array: {} [{}]", token_stream, token_stream1) - } - }); - - ports -} - -pub fn parse_port(field: zyn::syn::Field) -> Vec -{ - match field.ty - { - zyn::syn::Type::Path(type_path) => - { - println!("{:?}", type_path.path); - assert!(type_path.path.is_ident("In") || type_path.path.is_ident("Out")); - vec![BlockIOPort::Field( - field.ident.unwrap().to_token_stream().into(), - )] - } - zyn::syn::Type::Tuple(type_tuple) => - { - let mut output = vec![]; - for (i, _) in type_tuple.elems.iter().enumerate() - { - output.push(BlockIOPort::Field( - zyn::zyn!({{field.ident.clone().unwrap()}}.{{ Index::from(i) }}) - .to_token_stream() - .into(), - )); - } - output - } - zyn::syn::Type::Array(type_array) => - { - let b = BlockIOPort::Array( - field.ident.clone().unwrap().to_token_stream().into(), - type_array.len.to_token_stream().into(), - ); - vec![b] - } - _ => panic!("Unsupported port type."), - } -} - -#[zyn::element] -pub fn block_io_set_index(fields: zyn::syn::Fields) -> zyn::TokenStream -{ - let fields = fields.as_named().unwrap().named.clone(); - zyn::zyn!( - fn set_index(&self, block_index: usize) - { - 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 }} }); - } - } - ) -} - -#[zyn::element] -pub fn block_io_get_successors(fields: zyn::syn::Fields) -> zyn::TokenStream -{ - let fields = fields.as_named().unwrap().named.clone(); - zyn::zyn!( - fn get_successors(&self) -> Vec - { - let mut output = vec![]; - @for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("output"))).enumerate()) - { - if let Some(block_index) = self.{{ field.1.ident }}.get_consumer_block() - { - output.push(block_index); - } - } - output - } - ) -} - -#[zyn::element] -pub fn block_io_get_meta(ident: zyn::syn::Ident, fields: zyn::syn::Fields) -> zyn::TokenStream -{ - let fields = fields.as_named().unwrap().named.clone(); - zyn::zyn!( - fn get_block_name(&self) -> &'static str - { - return {{ ident.to_string() }}; - } - - fn get_input_names(&self) -> Vec<&'static str> - { - let mut output = Vec::new(); - @for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("input"))).enumerate()) - { - output.push({{ field.1.ident.clone().unwrap().to_string() }}); - } - return output; - } - fn get_output_names(&self) -> Vec<&'static str> - { - let mut output = Vec::new(); - @for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("output"))).enumerate()) - { - output.push({{ field.1.ident.clone().unwrap().to_string() }}); - } - return output; - } - - fn get_output_type_names(&self) -> Vec<&'static str> - { - let mut output = Vec::new(); - @for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("output"))).enumerate()) - { - output.push(self.{{ field.1.ident.clone() }}.get_type_name()); - } - return output; - } - ) -} - -#[zyn::element] -pub 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 - { - return { { input_count } }; - } - - fn output_count(&self) -> usize - { - return { { output_count } }; - } - ) -} - -#[zyn::element(debug = "pretty")] -pub fn block_io_set_streams(fields: zyn::syn::Fields) -> zyn::TokenStream -{ - zyn::zyn!( - #[allow(unreachable_code)] - fn set_anonymous_out_stream( - &mut self, - output_index: usize, - producer: oxydsp_flowgraph::edge::AnonymousStreamProducer, - ) - { - match output_index - { - @for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("output"))).enumerate()) - { - {{ field.0 }} => self.{{field.1.ident}}.set_anonymous_stream(producer), - } - _ => panic!("output_index out of bounds.") - }; - } - - #[allow(unreachable_code)] - fn set_anonymous_in_stream(&mut self, input_index: usize, consumer: oxydsp_flowgraph::edge::AnonymousStreamConsumer) - { - match input_index - { - @for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("input"))).enumerate()) - { - {{ field.0 }} => self.{{field.1.ident}}.set_anonymous_stream(consumer), - } - _ => panic!("output_index out of bounds.") - }; - } - ) -} - -#[zyn::element] -pub fn block_io_create_stream(fields: zyn::syn::Fields) -> zyn::TokenStream -{ - zyn::zyn!( - #[allow(unreachable_code)] - fn create_anonymous_stream_for( - &mut self, - output_index: usize, - capacity: usize - ) -> (oxydsp_flowgraph::edge::AnonymousStreamProducer, oxydsp_flowgraph::edge::AnonymousStreamConsumer) - { - let (tx, rx): (oxydsp_flowgraph::edge::AnonymousStreamProducer, oxydsp_flowgraph::edge::AnonymousStreamConsumer) - = match output_index - { - @for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("output"))).enumerate()) - { - {{ field.0 }} => - { - let (tx, rx) = oxydsp_flowgraph::stream::bounded_queue::<@out_inner_type(ty = field.1.ty.clone())>(capacity); - (tx.into(), rx.into()) - }, - } - _ => panic!("output_index out of bounds.") - }; - - (tx, rx) - } - ) -} - -#[zyn::element] -pub fn out_inner_type(ty: zyn::syn::Type) -> zyn::TokenStream -{ - let out_ty = match ty - { - zyn::syn::Type::Path(type_path) => match &type_path.path.segments.last().unwrap().arguments - { - zyn::syn::PathArguments::AngleBracketed(args) => match args.args.first().unwrap() - { - zyn::syn::GenericArgument::Type(x) => Some(x.clone().to_token_stream()), - _ => None, - }, - _ => None, - }, - _ => None, - }; - - if out_ty.is_none() - { - bail!("Output type must be a Out type."; span = ty.span()); - } - - out_ty.unwrap() -} diff --git a/oxydsp-flowgraph/oxydsp-flowgraph-macros/src/lib.rs b/oxydsp-flowgraph/oxydsp-flowgraph-macros/src/lib.rs index 434f031..cbe97db 100644 --- a/oxydsp-flowgraph/oxydsp-flowgraph-macros/src/lib.rs +++ b/oxydsp-flowgraph/oxydsp-flowgraph-macros/src/lib.rs @@ -8,9 +8,6 @@ use zyn::syn::Index; use zyn::syn::Lit; use zyn::syn::spanned::Spanned; -mod block_io; -use crate::block_io::*; - #[zyn::derive("BlockIO", attributes(input, output), debug = "pretty")] pub fn block_io( #[zyn(input)] ident: zyn::Extract, @@ -18,7 +15,6 @@ pub fn block_io( #[zyn(input)] fields: zyn::Fields, ) -> zyn::TokenStream { - //parse_ports(fields.clone(), "input"); let ident = ident.inner(); let (impl_generics, type_generics, where_clause) = generics.split_for_impl(); zyn::zyn!( @@ -35,6 +31,204 @@ pub fn block_io( ) } +#[zyn::element] +fn block_io_set_index(fields: zyn::syn::Fields) -> zyn::TokenStream +{ + let fields = fields.as_named().unwrap().named.clone(); + zyn::zyn!( + fn set_index(&self, block_index: usize) + { + 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 }} }); + } + } + ) +} + +#[zyn::element] +fn block_io_get_successors(fields: zyn::syn::Fields) -> zyn::TokenStream +{ + let fields = fields.as_named().unwrap().named.clone(); + zyn::zyn!( + fn get_successors(&self) -> Vec + { + let mut output = vec![]; + @for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("output"))).enumerate()) + { + if let Some(block_index) = self.{{ field.1.ident }}.get_consumer_block() + { + output.push(block_index); + } + } + output + } + ) +} + +#[zyn::element] +fn block_io_get_meta(ident: zyn::syn::Ident, fields: zyn::syn::Fields) -> zyn::TokenStream +{ + let fields = fields.as_named().unwrap().named.clone(); + zyn::zyn!( + fn get_block_name(&self) -> &'static str + { + return {{ ident.to_string() }}; + } + + fn get_input_names(&self) -> Vec<&'static str> + { + let mut output = Vec::new(); + @for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("input"))).enumerate()) + { + output.push({{ field.1.ident.clone().unwrap().to_string() }}); + } + return output; + } + fn get_output_names(&self) -> Vec<&'static str> + { + let mut output = Vec::new(); + @for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("output"))).enumerate()) + { + output.push({{ field.1.ident.clone().unwrap().to_string() }}); + } + return output; + } + + fn get_output_type_names(&self) -> Vec<&'static str> + { + let mut output = Vec::new(); + @for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("output"))).enumerate()) + { + output.push(self.{{ field.1.ident.clone() }}.get_type_name()); + } + return 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 + { + return { { input_count } }; + } + + fn output_count(&self) -> usize + { + return { { output_count } }; + } + ) +} + +#[zyn::element(debug = "pretty")] +fn block_io_set_streams(fields: zyn::syn::Fields) -> zyn::TokenStream +{ + zyn::zyn!( + #[allow(unreachable_code)] + fn set_anonymous_out_stream( + &mut self, + output_index: usize, + producer: oxydsp_flowgraph::edge::AnonymousStreamProducer, + ) + { + match output_index + { + @for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("output"))).enumerate()) + { + {{ field.0 }} => self.{{field.1.ident}}.set_anonymous_stream(producer), + } + _ => panic!("output_index out of bounds.") + }; + } + + #[allow(unreachable_code)] + fn set_anonymous_in_stream(&mut self, input_index: usize, consumer: oxydsp_flowgraph::edge::AnonymousStreamConsumer) + { + match input_index + { + @for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("input"))).enumerate()) + { + {{ field.0 }} => self.{{field.1.ident}}.set_anonymous_stream(consumer), + } + _ => panic!("output_index out of bounds.") + }; + } + ) +} + +#[zyn::element] +fn block_io_create_stream(fields: zyn::syn::Fields) -> zyn::TokenStream +{ + zyn::zyn!( + #[allow(unreachable_code)] + fn create_anonymous_stream_for( + &mut self, + output_index: usize, + capacity: usize + ) -> (oxydsp_flowgraph::edge::AnonymousStreamProducer, oxydsp_flowgraph::edge::AnonymousStreamConsumer) + { + let (tx, rx): (oxydsp_flowgraph::edge::AnonymousStreamProducer, oxydsp_flowgraph::edge::AnonymousStreamConsumer) + = match output_index + { + @for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("output"))).enumerate()) + { + {{ field.0 }} => + { + let (tx, rx) = oxydsp_flowgraph::stream::bounded_queue::<@out_inner_type(ty = field.1.ty.clone())>(capacity); + (tx.into(), rx.into()) + }, + } + _ => panic!("output_index out of bounds.") + }; + + (tx, rx) + } + ) +} + +#[zyn::element] +fn out_inner_type(ty: zyn::syn::Type) -> zyn::TokenStream +{ + let out_ty = match ty + { + zyn::syn::Type::Path(type_path) => match &type_path.path.segments.last().unwrap().arguments + { + zyn::syn::PathArguments::AngleBracketed(args) => match args.args.first().unwrap() + { + zyn::syn::GenericArgument::Type(x) => Some(x.clone().to_token_stream()), + _ => None, + }, + _ => None, + }, + _ => None, + }; + + if out_ty.is_none() + { + bail!("Output type must be a Out type."; span = ty.span()); + } + + out_ty.unwrap() +} + // Sync block #[zyn::attribute]