Zyn
This commit is contained in:
34
Cargo.lock
generated
34
Cargo.lock
generated
@ -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",
|
||||
]
|
||||
|
||||
@ -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"]}
|
||||
|
||||
@ -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
|
||||
)
|
||||
}
|
||||
|
||||
@ -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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user