use crate::{
bundle::Bundle,
change_detection::MaybeLocation,
event::{Event, EventKey, PropagateEntityTrigger},
prelude::*,
traversal::Traversal,
};
use bevy_ptr::Ptr;
use core::{
fmt::Debug,
marker::PhantomData,
ops::{Deref, DerefMut},
};
pub struct On<'w, 't, E: Event, B: Bundle = ()> {
observer: Entity,
event: &'w mut E,
trigger: &'w mut E::Trigger<'t>,
trigger_context: &'w TriggerContext,
_marker: PhantomData<B>,
}
impl<'w, 't, E: Event, B: Bundle> On<'w, 't, E, B> {
pub fn new(
event: &'w mut E,
observer: Entity,
trigger: &'w mut E::Trigger<'t>,
trigger_context: &'w TriggerContext,
) -> Self {
Self {
event,
observer,
trigger,
trigger_context,
_marker: PhantomData,
}
}
pub fn event_key(&self) -> EventKey {
self.trigger_context.event_key
}
pub fn event(&self) -> &E {
self.event
}
pub fn event_mut(&mut self) -> &mut E {
self.event
}
pub fn event_ptr(&self) -> Ptr<'_> {
Ptr::from(&self.event)
}
pub fn trigger(&self) -> &E::Trigger<'t> {
self.trigger
}
pub fn trigger_mut(&mut self) -> &mut E::Trigger<'t> {
self.trigger
}
pub fn observer(&self) -> Entity {
self.observer
}
pub fn caller(&self) -> MaybeLocation {
self.trigger_context.caller
}
}
impl<
'w,
't,
const AUTO_PROPAGATE: bool,
E: EntityEvent + for<'a> Event<Trigger<'a> = PropagateEntityTrigger<AUTO_PROPAGATE, E, T>>,
B: Bundle,
T: Traversal<E>,
> On<'w, 't, E, B>
{
pub fn original_event_target(&self) -> Entity {
self.trigger.original_event_target
}
pub fn propagate(&mut self, should_propagate: bool) {
self.trigger.propagate = should_propagate;
}
pub fn get_propagate(&self) -> bool {
self.trigger.propagate
}
}
impl<'w, 't, E: for<'a> Event<Trigger<'a>: Debug> + Debug, B: Bundle> Debug for On<'w, 't, E, B> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("On")
.field("event", &self.event)
.field("trigger", &self.trigger)
.field("_marker", &self._marker)
.finish()
}
}
impl<'w, 't, E: Event, B: Bundle> Deref for On<'w, 't, E, B> {
type Target = E;
fn deref(&self) -> &Self::Target {
self.event
}
}
impl<'w, 't, E: Event, B: Bundle> DerefMut for On<'w, 't, E, B> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.event
}
}
pub struct TriggerContext {
pub event_key: EventKey,
pub caller: MaybeLocation,
}