Skip to content

Commit

Permalink
Tween event
Browse files Browse the repository at this point in the history
  • Loading branch information
Multirious committed Mar 29, 2024
1 parent 0e5b384 commit aa71b5a
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 1 deletion.
6 changes: 5 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@ pub use tween::resource_tween_system;
#[allow(deprecated)]
pub use tween::resource_tween_system_full;

pub use tween::tween_event_system;
pub use tween::tween_event_taking_system;

/// Default plugins for using crate.
///
/// Plugins:
Expand All @@ -193,7 +196,8 @@ impl PluginGroup for DefaultTweenPlugins {
.add(TweenCorePlugin::default())
.add(interpolate::DefaultInterpolatorsPlugin)
.add(interpolate::DefaultDynInterpolatorsPlugin)
.add(interpolation::EaseFunctionPlugin);
.add(interpolation::EaseFunctionPlugin)
.add(tween::TweenEventPlugin);
#[cfg(feature = "span_tween")]
let p = p.add(span_tween::SpanTweenPlugin);
p
Expand Down
47 changes: 47 additions & 0 deletions src/tween.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ use bevy::prelude::*;

use crate::interpolate::Interpolator;
use crate::tween_timer::AnimationDirection;
use crate::BevyTweenRegisterSystems;

mod systems;
#[allow(deprecated)]
Expand All @@ -252,6 +253,7 @@ pub use systems::{
resource_dyn_tween_system, resource_tween_system,
resource_tween_system_full,
};
pub use systems::{tween_event_system, tween_event_taking_system};

/// Skip a tween from tweening.
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Component, Reflect)]
Expand Down Expand Up @@ -614,3 +616,48 @@ impl<A: Asset, const N: usize> From<&[Handle<A>; N]> for TargetAsset<A> {
TargetAsset::assets(value.iter().cloned())
}
}

/// Currently only just registers `tween_event_system::<()>`
pub struct TweenEventPlugin;

impl Plugin for TweenEventPlugin {
fn build(&self, app: &mut App) {
app.add_tween_systems(systems::tween_event_system::<()>);
}
}

/// Fires [`TweenEvent`] whenever [`TweenProgressed`] and [`TweenEventData`] exist in the same entity.
#[derive(Default, Debug, Clone, PartialEq, Eq, Hash, Component, Reflect)]
#[reflect(Component)]
pub struct TweenEventData<Data = ()>(pub Option<Data>)
where
Data: Send + Sync + 'static;

impl<Data: Send + Sync + 'static> TweenEventData<Data> {
/// Create new [`TweenEventData`] with custom user data.
pub fn new(data: Data) -> Self {
TweenEventData(Some(data))
}
}

impl TweenEventData<()> {
/// Create new [`TweenEventData`] with no custom user data.
pub fn no_data() -> Self {
TweenEventData(Some(()))
}
}

/// Fires whenever [`TweenProgressed`] and [`TweenEventData`] exist in the same entity.
#[derive(Debug, Clone, PartialEq, Event, Reflect)]
pub struct TweenEvent<Data = ()> {
/// Custom user data
pub data: Data,
/// Progress percentage of the tween
pub progressed: f32,
/// Sampled value of an interpolation.
pub interpolation_value: Option<f32>,
/// Direction
pub direction: AnimationDirection,
/// The entity
pub entity: Entity,
}
66 changes: 66 additions & 0 deletions src/tween/systems.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,3 +272,69 @@ where
{
asset_tween_system::<Box<dyn Interpolator<Item = A>>>.into_configs()
}

/// Fires [`TweenEvent`] with optional user data whenever [`TweenProgressed`]
/// and [`TweenEventData`] exist in the same entity and data is `Some`,
/// cloning the data.
#[allow(clippy::type_complexity)]
pub fn tween_event_system<Data>(
q_tween_event_data: Query<
(
Entity,
&TweenEventData<Data>,
&TweenProgressed,
Option<&TweenInterpolationValue>,
),
Without<SkipTween>,
>,
mut event_writer: EventWriter<TweenEvent<Data>>,
) where
Data: Clone + Send + Sync + 'static,
{
q_tween_event_data.iter().for_each(
|(entity, event_data, progressed, interpolation_value)| {
if let Some(data) = event_data.0.as_ref() {
event_writer.send(TweenEvent {
data: data.clone(),
progressed: progressed.0,
interpolation_value: interpolation_value.map(|v| v.0),
direction: progressed.1,
entity,
});
}
},
);
}

/// Fires [`TweenEvent`] with optional user data whenever [`TweenProgressed`]
/// and [`TweenEventData`] exist in the same entity and data is `Some`,
/// taking the data and leaves the value `None`.
#[allow(clippy::type_complexity)]
pub fn tween_event_taking_system<Data>(
mut q_tween_event_data: Query<
(
Entity,
&mut TweenEventData<Data>,
&TweenProgressed,
Option<&TweenInterpolationValue>,
),
Without<SkipTween>,
>,
mut event_writer: EventWriter<TweenEvent<Data>>,
) where
Data: Send + Sync + 'static,
{
q_tween_event_data.iter_mut().for_each(
|(entity, mut event_data, progressed, interpolation_value)| {
if let Some(data) = event_data.0.take() {
event_writer.send(TweenEvent {
data,
progressed: progressed.0,
interpolation_value: interpolation_value.map(|v| v.0),
direction: progressed.1,
entity,
});
}
},
);
}

0 comments on commit aa71b5a

Please sign in to comment.