Skip to content

Commit

Permalink
format generics in Label derive
Browse files Browse the repository at this point in the history
  • Loading branch information
JoJoJet committed Jul 26, 2022
1 parent a88293c commit 1118a6b
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 14 deletions.
8 changes: 8 additions & 0 deletions crates/bevy_ecs/examples/derive_label.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ fn main() {
GenericLabel::<f64>::One.as_label(),
GenericLabel::<char>::One.as_label(),
);

assert_eq!(format!("{:?}", UnitLabel.as_label()), "UnitLabel");
assert_eq!(format!("{:?}", WeirdLabel(1).as_label()), "WeirdLabel");
assert_eq!(format!("{:?}", WeirdLabel(2).as_label()), "WeirdLabel");
assert_eq!(
format!("{:?}", GenericLabel::<f64>::One.as_label()),
"GenericLabel::One::<f64>"
);
}

#[derive(SystemLabel)]
Expand Down
16 changes: 3 additions & 13 deletions crates/bevy_ecs/src/schedule/state.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::{
self as bevy_ecs,
schedule::{
RunCriteriaDescriptor, RunCriteriaDescriptorCoercion, RunCriteriaLabel, ShouldRun,
SystemSet,
Expand Down Expand Up @@ -52,20 +53,9 @@ enum ScheduledOperation<T: StateData> {
Push(T),
}

#[derive(RunCriteriaLabel)]
#[run_criteria_label(ignore_fields)]
struct DriverLabel<T: StateData>(PhantomData<fn() -> T>);
impl<T: StateData> RunCriteriaLabel for DriverLabel<T> {
#[inline]
fn type_id(&self) -> std::any::TypeId {
std::any::TypeId::of::<T>()
}
#[inline]
fn data(&self) -> u64 {
0
}
fn fmt(data: u64, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", std::any::type_name::<T>())
}
}

fn driver_label<T: StateData>() -> DriverLabel<T> {
DriverLabel(PhantomData)
Expand Down
23 changes: 22 additions & 1 deletion crates/bevy_macro_utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ pub fn derive_label(
.predicates
.push(syn::parse2(quote! { Self: 'static }).unwrap());

let (data, fmt) = match input.data {
let (data, mut fmt) = match input.data {
syn::Data::Struct(d) => {
// see if the user tried to ignore fields incorrectly
if let Some(attr) = d
Expand Down Expand Up @@ -226,6 +226,27 @@ pub fn derive_label(
}
};

// Formatting for generics
let mut ty_args = input.generics.params.iter().filter_map(|p| match p {
syn::GenericParam::Type(ty) => Some({
let ty = &ty.ident;
quote! { ::std::any::type_name::<#ty>() }
}),
_ => None,
});
if let Some(first_arg) = ty_args.next() {
// Note: We're doing this manually instead of using magic `syn` methods,
// because those methods insert ugly whitespace everywhere.
// Those are for codegen, not user-facing formatting.
fmt = quote! {
( #fmt )?;
write!(f, "::<")?;
write!(f, "{}", #first_arg)?;
#( write!(f, ", {}", #ty_args)?; )*
write!(f, ">")
}
}

(quote! {
impl #impl_generics #trait_path for #ident #ty_generics #where_clause {
#[inline]
Expand Down

0 comments on commit 1118a6b

Please sign in to comment.