Skip to content

Commit

Permalink
feat: TriggerOnTrigger
Browse files Browse the repository at this point in the history
  • Loading branch information
mrchantey committed Jul 9, 2024
1 parent 696ecf6 commit 0e36c00
Show file tree
Hide file tree
Showing 12 changed files with 110 additions and 38 deletions.
28 changes: 10 additions & 18 deletions crates/beet_ecs/src/actions/leaf/end_on_run.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,18 @@
use crate::prelude::*;
use bevy::prelude::*;

/// Immediately end the run with the provided result
pub type EndOnRun = TriggerOnTrigger<OnRun, OnRunResult>;


/// Trigger `OnRunResult` immediately when this action runs
#[derive(Default, Action, Deref, DerefMut, Reflect)]
#[reflect(Default, Component)]
#[observers(end_on_run)]
pub struct EndOnRun(pub RunResult);
// #[derive(Default, Action, Deref, DerefMut, Reflect)]
// #[reflect(Default, Component)]
// #[observers(end_on_run)]
// pub struct EndOnRun(pub RunResult);

impl EndOnRun {
pub fn success() -> Self { Self(RunResult::Success) }
pub fn failure() -> Self { Self(RunResult::Failure) }
}

fn end_on_run(
trigger: Trigger<OnRun>,
mut commands: Commands,
query: Query<&EndOnRun>,
) {
if let Ok(end_on_run) = query.get(trigger.entity()) {
commands
.trigger_targets(OnRunResult::new(**end_on_run), trigger.entity());
}
pub fn success() -> Self { Self::new(OnRunResult::success()) }
pub fn failure() -> Self { Self::new(OnRunResult::failure()) }
}


Expand Down
9 changes: 4 additions & 5 deletions crates/beet_ecs/src/actions/leaf/insert_while_running.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@ fn on_start_running<T: Default + GenericActionComponent>(
query: Query<&InsertWhileRunning<T>>,
mut commands: Commands,
) {
if let Ok(insert_while_running) = query.get(trigger.entity()) {
commands
.entity(trigger.entity())
.insert(insert_while_running.0.clone());
}
let action = query
.get(trigger.entity())
.expect(expect_action::NO_ACTION_COMP);
commands.entity(trigger.entity()).insert(action.0.clone());
}
fn on_stop_running<T: Default + GenericActionComponent>(
trigger: Trigger<OnRunResult>,
Expand Down
3 changes: 3 additions & 0 deletions crates/beet_ecs/src/actions/leaf/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ pub use self::insert_while_running::*;
pub mod run_on_spawn;
#[allow(unused_imports)]
pub use self::run_on_spawn::*;
pub mod trigger_on_trigger;
#[allow(unused_imports)]
pub use self::trigger_on_trigger::*;
53 changes: 53 additions & 0 deletions crates/beet_ecs/src/actions/leaf/trigger_on_trigger.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use crate::prelude::*;
use bevy::prelude::*;
use std::marker::PhantomData;

pub type TriggerOnRun<T> = TriggerOnTrigger<OnRun, T>;

/// when [`<In>`] is called, trigger [`<Out>`]
#[derive(Action, Reflect)]
#[reflect(Default, Component)]
#[observers(on_trigger::<In,Out>)]
pub struct TriggerOnTrigger<
In: GenericActionEvent,
Out: Default + GenericActionEvent,
> {
pub out: Out,
#[reflect(ignore)]
phantom: PhantomData<In>,
}

impl<In: GenericActionEvent, Out: Default + GenericActionEvent>
TriggerOnTrigger<In, Out>
{
pub fn new(out: Out) -> Self {
Self {
out,
phantom: PhantomData,
}
}
}

fn on_trigger<In: GenericActionEvent, Out: Default + GenericActionEvent>(
trigger: Trigger<In>,
query: Query<&TriggerOnTrigger<In, Out>>,
mut commands: Commands,
) {
let action = query
.get(trigger.entity())
.expect(expect_action::NO_ACTION_COMP);
commands.trigger_targets(action.out.clone(), trigger.entity());
}

impl<In: GenericActionEvent, Out: Default + GenericActionEvent> Default
for TriggerOnTrigger<In, Out>
{
fn default() -> Self {
Self {
out: Out::default(),
phantom: PhantomData,
}
}
}

// see `end_on_run` for tests
6 changes: 4 additions & 2 deletions crates/beet_ecs/src/events/on_run.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// use crate::prelude::*;
use bevy::prelude::*;

#[derive(Debug, Default, Clone, Event)]
pub struct OnRun;

/// Signifies an action has started running.
#[derive(Debug, Default, Clone, Event, Reflect)]
#[reflect(Default)]
pub struct OnRun;
5 changes: 3 additions & 2 deletions crates/beet_ecs/src/events/on_run_result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ pub mod child_expect {
}


#[derive(Debug, Default, Clone, Event, PartialEq, Deref)]
#[derive(Debug, Default, Clone, Copy, Event, PartialEq, Deref, Reflect)]
#[reflect(Default)]
pub struct OnRunResult(RunResult);
impl OnRunResult {
pub fn new(result: RunResult) -> Self { Self(result) }
Expand All @@ -19,7 +20,7 @@ impl OnRunResult {
pub fn result(&self) -> RunResult { **self }
}

#[derive(Event)]
#[derive(Debug, Clone, Copy, Event, Reflect)]
pub struct OnChildResult {
child: Entity,
result: RunResult,
Expand Down
6 changes: 3 additions & 3 deletions crates/beet_ecs/src/lifecycle/actions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ pub use self::remove_agent_on_run::*;
pub mod repeat;
#[allow(unused_imports)]
pub use self::repeat::*;
pub mod send_on_run;
#[allow(unused_imports)]
pub use self::send_on_run::*;
pub mod set_agent_on_run;
#[allow(unused_imports)]
pub use self::set_agent_on_run::*;
Expand All @@ -34,6 +37,3 @@ pub use self::set_on_run::*;
pub mod set_on_spawn;
#[allow(unused_imports)]
pub use self::set_on_spawn::*;
pub mod send_on_run;
#[allow(unused_imports)]
pub use self::send_on_run::*;
12 changes: 7 additions & 5 deletions crates/beet_ecs/src/lifecycle/actions/send_on_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use bevy::prelude::*;
/// Sends the given event when this behavior starts running.
#[derive(Debug, Clone, PartialEq, Deref, DerefMut, Action, Reflect)]
#[reflect(Component, ActionMeta)]
#[systems(send_on_run::<T>.in_set(TickSet))]
#[observers(send_on_run::<T>)]
pub struct SendOnRun<T: GenericActionEvent>(pub T);

impl<T: Default + GenericActionEvent> Default for SendOnRun<T> {
Expand All @@ -16,10 +16,12 @@ impl<T: GenericActionEvent> SendOnRun<T> {
}

fn send_on_run<T: GenericActionEvent>(
trigger: Trigger<OnRun>,
mut writer: EventWriter<T>,
query: Query<&SendOnRun<T>, Added<Running>>,
query: Query<&SendOnRun<T>>,
) {
for trigger in query.iter() {
writer.send(trigger.0.clone());
}
let action = query
.get(trigger.entity())
.expect(expect_action::NO_ACTION_COMP);
writer.send(action.0.clone());
}
11 changes: 11 additions & 0 deletions crates/beet_ecs/src/observers/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@



#[rustfmt::skip]
pub mod expect_action{
/// Action observers are removed when the component is so
/// we always expect the component to exist.
pub const NO_ACTION_COMP: &str =
"Action component missing from observer query";

}
3 changes: 3 additions & 0 deletions crates/beet_ecs/src/observers/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
pub mod errors;
#[allow(unused_imports)]
pub use self::errors::*;
pub mod observer_utils;
10 changes: 8 additions & 2 deletions crates/beet_examples/src/scenes/hello_net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@ use bevy::prelude::*;

pub fn hello_net(mut commands: Commands) {
commands
.spawn((SequenceSelector::default(), Running))
.spawn((
Name::new("Hello Net Sequence"),
SequenceSelector::default(),
Running
// SequenceFlow::default(),
// RunOnSpawn,
))
.with_children(|parent| {
parent.spawn((Name::new("Send - AppReady"), SendOnRun(AppReady)));
});
commands.spawn((
Name::new("Recv - Player Message"),
Name::new("Recv - OnUserMessage"),
InsertOnTrigger::<OnUserMessage, Running>::new(Running),
));
}
2 changes: 1 addition & 1 deletion examples/hello_net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub fn main() {
(
scenes::beet_debug,
scenes::camera_2d,
scenes::ui_terminal,
scenes::ui_terminal_input,
scenes::hello_net,
),
)
Expand Down

0 comments on commit 0e36c00

Please sign in to comment.