Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_animation/src/animation_event.rs
9367 views
1
pub use bevy_animation_macros::AnimationEvent;
2
3
use bevy_ecs::{
4
entity::Entity,
5
event::{trigger_entity_internal, Event, Trigger},
6
observer::{CachedObservers, TriggerContext},
7
world::DeferredWorld,
8
};
9
10
/// An [`Event`] that an [`AnimationPlayer`](crate::AnimationPlayer) or an [`AnimationTargetId`](crate::AnimationTargetId) can trigger when playing an [`AnimationClip`](crate::AnimationClip).
11
///
12
/// - If you used [`AnimationClip::add_event`](crate::AnimationClip::add_event), this will be triggered by the [`AnimationPlayer`](crate::AnimationPlayer).
13
/// - If you used [`AnimationClip::add_event_to_target`](crate::AnimationClip::add_event_to_target), this will be triggered by the [`AnimationTargetId`](crate::AnimationTargetId).
14
///
15
/// This trait can be derived.
16
pub trait AnimationEvent: Clone + for<'a> Event<Trigger<'a> = AnimationEventTrigger> {}
17
18
/// The [`Trigger`] implementation for [`AnimationEvent`]. This passes in either the [`AnimationPlayer`](crate::AnimationPlayer) or the [`AnimationTargetId`](crate::AnimationTargetId)
19
/// context, and uses that to run any observers that target that entity. See [`AnimationEvent`] for when which entity is used.
20
#[derive(Debug)]
21
pub struct AnimationEventTrigger {
22
/// The [`AnimationPlayer`](crate::AnimationPlayer) or the [`AnimationTargetId`](crate::AnimationTargetId) where this [`AnimationEvent`] occurred.
23
/// See [`AnimationEvent`] for when which entity is used.
24
pub target: Entity,
25
}
26
27
#[expect(
28
unsafe_code,
29
reason = "We must implement this trait to define a custom Trigger, which is required to be unsafe due to safety considerations within bevy_ecs."
30
)]
31
// SAFETY:
32
// - `E`'s [`Event::Trigger`] is constrained to [`AnimationEventTrigger`]
33
// - The implementation abides by the other safety constraints defined in [`Trigger`]
34
unsafe impl<E: AnimationEvent + for<'a> Event<Trigger<'a> = AnimationEventTrigger>> Trigger<E>
35
for AnimationEventTrigger
36
{
37
unsafe fn trigger(
38
&mut self,
39
world: DeferredWorld,
40
observers: &CachedObservers,
41
trigger_context: &TriggerContext,
42
event: &mut E,
43
) {
44
let target = self.target;
45
// SAFETY:
46
// - `observers` come from `world` and match the event type `E`, enforced by the call to `trigger`
47
// - the passed in event pointer comes from `event`, which is an `Event`
48
// - `trigger` is a matching trigger type, as it comes from `self`, which is the Trigger for `E`
49
// - `trigger_context`'s event_key matches `E`, enforced by the call to `trigger`
50
// - this abides by the nuances defined in the `Trigger` safety docs
51
unsafe {
52
trigger_entity_internal(
53
world,
54
observers,
55
event.into(),
56
self.into(),
57
target,
58
trigger_context,
59
);
60
}
61
}
62
}
63
64