moonshine_behavior/
plugin.rs

1use std::marker::PhantomData;
2
3use bevy_app::prelude::*;
4use bevy_reflect::{prelude::*, GetTypeRegistration, Typed};
5
6use crate::{Behavior, Memory, Transition, TransitionSequence};
7
8/// A [`Plugin`] for any [`Behavior`] type.
9///
10/// This plugin must be added to the [`App`] for behavior [`Transitions`](Transition) to work correctly.
11/// You must also add the [`transition`](crate::transition::transition) system separately somewhere in your schedule.
12///
13/// # Example
14/// ```rust
15/// use bevy::prelude::*;
16/// use moonshine_behavior::prelude::*;
17///
18/// #[derive(Component, Debug, Reflect)]
19/// #[reflect(Component)]
20/// struct B;
21///
22/// impl Behavior for B {}
23///
24/// fn main() {
25///     App::new()
26///         /* ... */
27///         .add_plugins(BehaviorPlugin::<B>::default())
28///         .add_systems(Update, transition::<B>)
29///         /* ... */;
30/// }
31/// ```
32pub struct BehaviorPlugin<T: Behavior>(PhantomData<T>);
33
34impl<T: Behavior> Default for BehaviorPlugin<T> {
35    fn default() -> Self {
36        Self(PhantomData)
37    }
38}
39
40impl<T: RegisterableBehavior> Plugin for BehaviorPlugin<T> {
41    fn build(&self, app: &mut App) {
42        app.register_type::<Transition<T>>()
43            .register_type::<Memory<T>>()
44            .register_type::<TransitionSequence<T>>()
45            .register_required_components::<T, Transition<T>>();
46    }
47}
48
49#[doc(hidden)]
50pub trait RegisterableBehavior: Behavior + FromReflect + GetTypeRegistration + Typed {}
51
52impl<T: Behavior + FromReflect + GetTypeRegistration + Typed> RegisterableBehavior for T {}