Skip to content

Commit

Permalink
Remove States::variants and remove enum-only restriction its derive (b…
Browse files Browse the repository at this point in the history
…evyengine#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.
  • Loading branch information
ItsDoot authored and Thomas Wilgenbus committed Oct 13, 2023
1 parent b237938 commit 2e7cd91
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 34 deletions.
29 changes: 3 additions & 26 deletions crates/bevy_ecs/macros/src/states.rs
Original file line number Diff line number Diff line change
@@ -1,44 +1,21 @@
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();

let mut trait_path = bevy_ecs_path();
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()
}
2 changes: 1 addition & 1 deletion crates/bevy_ecs/src/schedule/condition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>())
Expand Down
8 changes: 1 addition & 7 deletions crates/bevy_ecs/src/schedule/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit 2e7cd91

Please sign in to comment.