Adding sync block macro
This commit is contained in:
@ -7,4 +7,4 @@ edition = "2024"
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
zyn = {version = "0.4.2", features = ["ext"]}
|
||||
zyn = {version = "0.5", features = ["ext", "pretty"]}
|
||||
|
||||
@ -1,5 +1,11 @@
|
||||
use core::panic;
|
||||
|
||||
use proc_macro::Ident;
|
||||
use proc_macro::Spacing;
|
||||
use zyn::ToTokens;
|
||||
use zyn::ext::AttrExt;
|
||||
use zyn::ext::FieldsExt;
|
||||
use zyn::syn::spanned::Spanned;
|
||||
|
||||
#[zyn::derive("BlockIO", attributes(input, output))]
|
||||
pub fn block_io(
|
||||
@ -16,6 +22,8 @@ pub fn block_io(
|
||||
@block_io_set_index(fields = fields.clone())
|
||||
@block_io_get_successors(fields = fields.clone())
|
||||
@block_io_counts(fields = fields.clone())
|
||||
@block_io_set_streams(fields = fields.clone())
|
||||
@block_io_create_stream(fields = fields.clone())
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -46,12 +54,15 @@ 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, block_index: usize) -> Vec<oxydsp_flowgraph::edge::BlockIOIndex>
|
||||
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())
|
||||
{
|
||||
output.push(self.{{ field.1.ident }}.get_consumer_block());
|
||||
if let Some(block_index) = self.{{ field.1.ident }}.get_consumer_block()
|
||||
{
|
||||
output.push(block_index);
|
||||
}
|
||||
}
|
||||
output
|
||||
}
|
||||
@ -82,3 +93,132 @@ fn block_io_counts(fields: zyn::syn::Fields) -> zyn::TokenStream
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
#[zyn::element]
|
||||
fn block_io_set_streams(fields: zyn::syn::Fields) -> zyn::TokenStream
|
||||
{
|
||||
zyn::zyn!(
|
||||
fn set_anonymous_out_stream(
|
||||
&mut self,
|
||||
output_index: usize,
|
||||
producer: oxydsp_flowgraph::edge::AnonymousStreamProducer,
|
||||
)
|
||||
{
|
||||
@for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("output"))).enumerate())
|
||||
{
|
||||
self.{{field.1.ident}}.set_anonymous_stream(producer);
|
||||
}
|
||||
}
|
||||
|
||||
fn set_anonymous_in_stream(&mut self, input_index: usize, consumer: oxydsp_flowgraph::edge::AnonymousStreamConsumer)
|
||||
{
|
||||
@for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("input"))).enumerate())
|
||||
{
|
||||
self.{{field.1.ident}}.set_anonymous_stream(consumer);
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
#[zyn::element]
|
||||
fn block_io_create_stream(fields: zyn::syn::Fields) -> zyn::TokenStream
|
||||
{
|
||||
zyn::zyn!(
|
||||
fn create_anonymous_stream_for(
|
||||
&mut self,
|
||||
output_index: usize,
|
||||
capacity: usize
|
||||
) -> (oxydsp_flowgraph::edge::AnonymousStreamProducer, oxydsp_flowgraph::edge::AnonymousStreamConsumer)
|
||||
{
|
||||
let (tx, rx) = match output_index
|
||||
{
|
||||
@for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("output"))).enumerate())
|
||||
{
|
||||
{{ field.0 }} => oxydsp_flowgraph::stream::bounded_queue::<@out_inner_type(ty = field.1.ty.clone())>(capacity),
|
||||
}
|
||||
_ => panic!("output_index out of bounds.")
|
||||
};
|
||||
|
||||
(tx.into(), rx.into())
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
#[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]
|
||||
pub fn sync_block(#[zyn(input)] item: zyn::syn::ItemStruct) -> zyn::TokenStream
|
||||
{
|
||||
let strcut_item = item.clone();
|
||||
let (impl_generics, type_generics, where_clause) = item.generics.split_for_impl();
|
||||
let fields = &item.fields.as_named().unwrap().named;
|
||||
zyn::zyn!(
|
||||
{{ strcut_item }}
|
||||
|
||||
impl {{ impl_generics }} oxydsp_flowgraph::block::Block for {{ strcut_item.ident }} {{ type_generics }}
|
||||
where {{ where_clause }}
|
||||
{
|
||||
fn work(&mut self) -> oxydsp_flowgraph::block::BlockResult
|
||||
{
|
||||
let mut len = usize::MAX;
|
||||
@for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("input"))).enumerate())
|
||||
{
|
||||
let mut {{ field.1.ident.clone().unwrap() | ident:"{}_reader" }} = self.{{field.1.ident}}.read();
|
||||
len = len.min({{ field.1.ident.clone().unwrap() | ident:"{}_reader" }}.len());
|
||||
|
||||
}
|
||||
|
||||
@for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("output"))).enumerate())
|
||||
{
|
||||
let mut {{ field.1.ident.clone().unwrap() | ident: "{}_writer" }} = self.{{field.1.ident}}.write();
|
||||
len = len.min({{ field.1.ident.clone().unwrap() | ident: "{}_writer" }}.len());
|
||||
}
|
||||
|
||||
for _ in 0..len
|
||||
{
|
||||
let (
|
||||
@for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("output"))).enumerate())
|
||||
{
|
||||
{{ field.1.ident.clone().unwrap() | ident: "{}_out" }},
|
||||
}
|
||||
) = self.sync_work((
|
||||
@for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("input"))).enumerate())
|
||||
{
|
||||
{{ field.1.ident.clone().unwrap() | ident: "{}_reader" }}.pop().unwrap(),
|
||||
}
|
||||
));
|
||||
@for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("output"))).enumerate())
|
||||
{
|
||||
{{ field.1.ident.clone().unwrap() | ident: "{}_writer" }}.push({{ field.1.ident.clone().unwrap() | ident: "{}_out" }}).unwrap();
|
||||
}
|
||||
}
|
||||
oxydsp_flowgraph::block::BlockResult::Ok
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user