From 2e7cd91748aebcb0fd40e8afab685b9d6d4c26bf Mon Sep 17 00:00:00 2001 From: Christian Hughes <9044780+ItsDoot@users.noreply.github.com> Date: Sat, 30 Sep 2023 17:32:39 -0500 Subject: [PATCH] Remove States::variants and remove enum-only restriction its derive (#9945) # Objective The `States::variants` method was once used to construct `OnExit` and `OnEnter` schedules for every possible value of a given `States` type. [Since the switch to lazily initialized schedules](https://github.com/bevyengine/bevy/pull/8028/files#diff-b2fba3a0c86e496085ce7f0e3f1de5960cb754c7d215ed0f087aa556e529f97f), we no longer need to track every possible value. This also opens the door to `States` types that aren't enums. ## Solution - Remove the unused `States::variants` method and its associated type. - Remove the enum-only restriction on derived States types. --- ## Changelog - Removed `States::variants` and its associated type. - Derived `States` can now be datatypes other than enums. ## Migration Guide - `States::variants` no longer exists. If you relied on this function, consider using a library that provides enum iterators. --- crates/bevy_ecs/macros/src/states.rs | 29 +++-------------------- crates/bevy_ecs/src/schedule/condition.rs | 2 +- crates/bevy_ecs/src/schedule/state.rs | 8 +------ 3 files changed, 5 insertions(+), 34 deletions(-) diff --git a/crates/bevy_ecs/macros/src/states.rs b/crates/bevy_ecs/macros/src/states.rs index b80a5b6ff1503c..0eb516c31563da 100644 --- a/crates/bevy_ecs/macros/src/states.rs +++ b/crates/bevy_ecs/macros/src/states.rs @@ -1,26 +1,11 @@ -use proc_macro::{Span, TokenStream}; +use proc_macro::TokenStream; use quote::{format_ident, quote}; -use syn::{parse_macro_input, Data::Enum, DeriveInput}; +use syn::{parse_macro_input, DeriveInput}; use crate::bevy_ecs_path; pub fn derive_states(input: TokenStream) -> TokenStream { let ast = parse_macro_input!(input as DeriveInput); - let error = || { - syn::Error::new( - Span::call_site().into(), - "derive(States) only supports fieldless enums", - ) - .into_compile_error() - .into() - }; - let Enum(enumeration) = ast.data else { - return error(); - }; - if enumeration.variants.iter().any(|v| !v.fields.is_empty()) { - return error(); - } - let generics = ast.generics; let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); @@ -28,17 +13,9 @@ pub fn derive_states(input: TokenStream) -> TokenStream { trait_path.segments.push(format_ident!("schedule").into()); trait_path.segments.push(format_ident!("States").into()); let struct_name = &ast.ident; - let idents = enumeration.variants.iter().map(|v| &v.ident); - let len = idents.len(); quote! { - impl #impl_generics #trait_path for #struct_name #ty_generics #where_clause { - type Iter = std::array::IntoIter; - - fn variants() -> Self::Iter { - [#(Self::#idents,)*].into_iter() - } - } + impl #impl_generics #trait_path for #struct_name #ty_generics #where_clause {} } .into() } diff --git a/crates/bevy_ecs/src/schedule/condition.rs b/crates/bevy_ecs/src/schedule/condition.rs index 819dfe448fec66..92bd4163000124 100644 --- a/crates/bevy_ecs/src/schedule/condition.rs +++ b/crates/bevy_ecs/src/schedule/condition.rs @@ -1190,7 +1190,7 @@ mod tests { .distributive_run_if(resource_changed_or_removed::>()) .distributive_run_if(resource_removed::>()) .distributive_run_if(state_exists::()) - .distributive_run_if(in_state(TestState::A)) + .distributive_run_if(in_state(TestState::A).or_else(in_state(TestState::B))) .distributive_run_if(state_changed::()) .distributive_run_if(on_event::()) .distributive_run_if(any_with_component::()) diff --git a/crates/bevy_ecs/src/schedule/state.rs b/crates/bevy_ecs/src/schedule/state.rs index a60bffdb82ee4e..a39f8cc036d1d8 100644 --- a/crates/bevy_ecs/src/schedule/state.rs +++ b/crates/bevy_ecs/src/schedule/state.rs @@ -40,13 +40,7 @@ pub use bevy_ecs_macros::States; /// } /// /// ``` -pub trait States: 'static + Send + Sync + Clone + PartialEq + Eq + Hash + Debug + Default { - /// The type returned when iterating over all [`variants`](States::variants) of this type. - type Iter: Iterator; - - /// Returns an iterator over all the state variants. - fn variants() -> Self::Iter; -} +pub trait States: 'static + Send + Sync + Clone + PartialEq + Eq + Hash + Debug + Default {} /// The label of a [`Schedule`](super::Schedule) that runs whenever [`State`] /// enters this state.