Reverting tuple/arrays macros

This commit is contained in:
2026-03-16 09:16:33 +01:00
parent 10e4509e8c
commit 520d97726f
3 changed files with 203 additions and 296 deletions

View File

@ -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<T: 'static>
{
//#[input]
input: [In<T>; 3],
#[input]
input: In<T>,
n: usize,
}
@ -27,8 +25,7 @@ impl<T: 'static> Printer<T>
{
pub fn new(input: In<T>) -> 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))
{

View File

@ -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<BlockIOPort>,
outputs: Vec<BlockIOPort>,
}
pub fn parse_ports(fields: zyn::syn::Fields, attribute: &str) -> Vec<BlockIOPort>
{
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<BlockIOPort>
{
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<oxydsp_flowgraph::edge::BlockIOIndex>
{
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<T> type."; span = ty.span());
}
out_ty.unwrap()
}

View File

@ -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<zyn::syn::Ident>,
@ -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<oxydsp_flowgraph::edge::BlockIOIndex>
{
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<T> type."; span = ty.span());
}
out_ty.unwrap()
}
// Sync block
#[zyn::attribute]