mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 20:53:53 +00:00
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.
This commit is contained in:
parent
95813b87f7
commit
9c004439b8
3 changed files with 5 additions and 34 deletions
|
@ -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<Self, #len>;
|
||||
|
||||
fn variants() -> Self::Iter {
|
||||
[#(Self::#idents,)*].into_iter()
|
||||
}
|
||||
}
|
||||
impl #impl_generics #trait_path for #struct_name #ty_generics #where_clause {}
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
|
|
@ -1190,7 +1190,7 @@ mod tests {
|
|||
.distributive_run_if(resource_changed_or_removed::<State<TestState>>())
|
||||
.distributive_run_if(resource_removed::<State<TestState>>())
|
||||
.distributive_run_if(state_exists::<TestState>())
|
||||
.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::<TestState>())
|
||||
.distributive_run_if(on_event::<TestEvent>())
|
||||
.distributive_run_if(any_with_component::<TestComponent>())
|
||||
|
|
|
@ -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<Item = Self>;
|
||||
|
||||
/// 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<S>`]
|
||||
/// enters this state.
|
||||
|
|
Loading…
Reference in a new issue