diff --git a/benches/common/serialize_text.rs b/benches/common/serialize_text.rs index dda1dbf..269c96d 100644 --- a/benches/common/serialize_text.rs +++ b/benches/common/serialize_text.rs @@ -75,7 +75,7 @@ impl Benchmark { pub fn run_row(&mut self) { let Self(world) = self; - let (serializer, deserializer) = SerdeBuilder::new() + let (serializer, deserializer) = SerializationContextBuilder::new() .with(transform()) .with(position()) .with(rotation()) diff --git a/flax-derive/src/system.rs b/flax-derive/src/system.rs index 5ef1a82..f8782d5 100644 --- a/flax-derive/src/system.rs +++ b/flax-derive/src/system.rs @@ -206,30 +206,43 @@ fn component_ctor_from_type( path: Path { segments, .. }, .. }) => { - if segments.len() == 1 && segments[0].ident == "Option" { - let inner = match &segments[0].arguments { - syn::PathArguments::AngleBracketed(args) => { - let GenericArgument::Type(ty) = &args.args[0] else { + match segments.last().map(|v| v.ident.to_string()).as_deref() { + Some("Option") => { + let inner = match &segments[0].arguments { + syn::PathArguments::AngleBracketed(args) => { + let GenericArgument::Type(ty) = &args.args[0] else { + return Err(syn::Error::new( + ident.span(), + "Malformed option generic argument list", + )); + }; + + component_ctor_from_type(crate_name, ident, ty)? + } + _ => { return Err(syn::Error::new( ident.span(), - "Malformed option generic argument list", - )); - }; + "Expected a single angle bracketed type", + )) + } + }; - component_ctor_from_type(crate_name, ident, ty)? - } - _ => { - return Err(syn::Error::new( - ident.span(), - "Expected a single angle bracketed type", - )) - } - }; - - quote!(#crate_name::fetch::FetchExt::opt(#inner)) - } else { - quote!(#crate_name::fetch::FetchExt::copied(#ident())) + quote!(#crate_name::fetch::FetchExt::opt(#inner)) + } + Some("Entity") => { + quote!(#crate_name::entity_ids()) + } + Some("EntityRef") => { + quote!(#crate_name::fetch::entity_refs()) + } + _ => { + quote!(#crate_name::fetch::FetchExt::copied(#ident())) + } } + + // if segments.len() == 1 && segments[0].ident == "Option" { + // } else { + // } } _ => return Err(syn::Error::new(ident.span(), "Unsupported type")), }; diff --git a/src/fetch/ext.rs b/src/fetch/ext.rs index 47661f0..862ab1e 100644 --- a/src/fetch/ext.rs +++ b/src/fetch/ext.rs @@ -2,7 +2,7 @@ use alloc::borrow::Cow; use crate::{ component::ComponentValue, - filter::{Cmp, Equal, Filtered, Greater, GreaterEq, Less, LessEq}, + filter::{Cmp, Equal, Filtered, Greater, GreaterEq, Less, LessEq, NotEqual}, relation::RelationExt, Fetch, FetchItem, }; @@ -120,6 +120,14 @@ pub trait FetchExt: Sized { Cmp::new(self, Equal(other)) } + /// Filter any component equal to `other`. + fn neq(self, other: T) -> Cmp> + where + for<'x> Cmp>: Fetch<'x>, + { + Cmp::new(self, NotEqual(other)) + } + /// Set the source entity for the fetch. /// /// This allows fetching or joining queries diff --git a/src/filter/cmp.rs b/src/filter/cmp.rs index 4d78c7d..ead6474 100644 --- a/src/filter/cmp.rs +++ b/src/filter/cmp.rs @@ -30,15 +30,23 @@ trait CmpMethod { #[doc(hidden)] #[derive(Debug, Clone)] pub struct Less(pub R); + #[doc(hidden)] #[derive(Debug, Clone)] pub struct Greater(pub R); + #[doc(hidden)] #[derive(Debug, Clone)] pub struct Equal(pub R); + +#[doc(hidden)] +#[derive(Debug, Clone)] +pub struct NotEqual(pub R); + #[doc(hidden)] #[derive(Debug, Clone)] pub struct LessEq(pub R); + #[doc(hidden)] #[derive(Debug, Clone)] pub struct GreaterEq(pub R); @@ -94,6 +102,15 @@ where } } +impl CmpMethod for NotEqual +where + L: for<'x> PartialEq<&'x R>, +{ + fn compare(&self, lhs: L) -> bool { + !lhs.eq(&&self.0) + } +} + impl CmpMethod for F where F: Fn(T) -> bool, diff --git a/src/filter/mod.rs b/src/filter/mod.rs index ebabff7..60821f8 100644 --- a/src/filter/mod.rs +++ b/src/filter/mod.rs @@ -21,7 +21,7 @@ use crate::{ }; pub use change::ChangeFilter; -pub use cmp::{Cmp, Equal, Greater, GreaterEq, Less, LessEq}; +pub use cmp::{Cmp, Equal, Greater, GreaterEq, Less, LessEq, NotEqual}; pub(crate) use constant::NoEntities; pub use constant::{All, Nothing}; pub use set::{And, Not, Or, Union};