 684f07595f
			
		
	
	
		684f07595f
		
	
	
	
	
		
			
			# Objective Complete the first part of the migration detailed in bevyengine/rfcs#45. ## Solution Add all the new stuff. ### TODO - [x] Impl tuple methods. - [x] Impl chaining. - [x] Port ambiguity detection. - [x] Write docs. - [x] ~~Write more tests.~~(will do later) - [ ] Write changelog and examples here? - [x] ~~Replace `petgraph`.~~ (will do later) Co-authored-by: james7132 <contact@jamessliu.com> Co-authored-by: Michael Hsu <mike.hsu@gmail.com> Co-authored-by: Mike Hsu <mike.hsu@gmail.com>
		
			
				
	
	
		
			65 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			65 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| use std::fmt::Debug;
 | |
| use std::hash::Hash;
 | |
| use std::mem;
 | |
| 
 | |
| use crate as bevy_ecs;
 | |
| use crate::schedule_v3::{ScheduleLabel, SystemSet, WorldExt};
 | |
| use crate::system::Resource;
 | |
| use crate::world::World;
 | |
| 
 | |
| /// Types that can define states in a finite-state machine.
 | |
| pub trait States: 'static + Send + Sync + Clone + PartialEq + Eq + Hash + Debug {
 | |
|     type Iter: Iterator<Item = Self>;
 | |
| 
 | |
|     /// Returns an iterator over all the state variants.
 | |
|     fn states() -> Self::Iter;
 | |
| }
 | |
| 
 | |
| /// The label of a [`Schedule`](super::Schedule) that runs whenever [`State<S>`]
 | |
| /// enters this state.
 | |
| #[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)]
 | |
| pub struct OnEnter<S: States>(pub S);
 | |
| 
 | |
| /// The label of a [`Schedule`](super::Schedule) that runs whenever [`State<S>`]
 | |
| /// exits this state.
 | |
| #[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)]
 | |
| pub struct OnExit<S: States>(pub S);
 | |
| 
 | |
| /// A [`SystemSet`] that will run within \<insert-`bevy_core`-set-name\> when this state is active.
 | |
| ///
 | |
| /// This is provided for convenience. A more general [`state_equals`](super::state_equals)
 | |
| /// [condition](super::Condition) also exists for systems that need to run elsewhere.
 | |
| #[derive(SystemSet, Clone, Debug, PartialEq, Eq, Hash)]
 | |
| pub struct OnUpdate<S: States>(pub S);
 | |
| 
 | |
| /// A finite-state machine whose transitions have associated schedules
 | |
| /// ([`OnEnter(state)`] and [`OnExit(state)`]).
 | |
| ///
 | |
| /// The current state value can be accessed through this resource. To *change* the state,
 | |
| /// queue a transition in the [`NextState<S>`] resource, and it will be applied by the next
 | |
| /// [`apply_state_transition::<S>`] system.
 | |
| #[derive(Resource)]
 | |
| pub struct State<S: States>(pub S);
 | |
| 
 | |
| /// The next state of [`State<S>`].
 | |
| ///
 | |
| /// To queue a transition, just set the contained value to `Some(next_state)`.
 | |
| #[derive(Resource)]
 | |
| pub struct NextState<S: States>(pub Option<S>);
 | |
| 
 | |
| /// If a new state is queued in [`NextState<S>`], this system:
 | |
| /// - Takes the new state value from [`NextState<S>`] and updates [`State<S>`].
 | |
| /// - Runs the [`OnExit(exited_state)`] schedule.
 | |
| /// - Runs the [`OnEnter(entered_state)`] schedule.
 | |
| pub fn apply_state_transition<S: States>(world: &mut World) {
 | |
|     if world.resource::<NextState<S>>().0.is_some() {
 | |
|         let entered_state = world.resource_mut::<NextState<S>>().0.take().unwrap();
 | |
|         let exited_state = mem::replace(
 | |
|             &mut world.resource_mut::<State<S>>().0,
 | |
|             entered_state.clone(),
 | |
|         );
 | |
|         world.run_schedule(OnExit(exited_state));
 | |
|         world.run_schedule(OnEnter(entered_state));
 | |
|     }
 | |
| }
 |